From 39ba8a640bd178fd732d945760df7eef3e2c1e1a Mon Sep 17 00:00:00 2001 From: "N.N." Date: Tue, 5 Jan 2010 17:50:51 +0000 Subject: no gridflow snapshots in pure-data svn svn path=/trunk/; revision=12888 --- externals/gridflow/src/aalib.cxx | 144 -- externals/gridflow/src/classes1.cxx | 2342 ----------------------------- externals/gridflow/src/classes2.cxx | 1183 --------------- externals/gridflow/src/dc1394.cxx | 287 ---- externals/gridflow/src/fftw.cxx | 114 -- externals/gridflow/src/formats.cxx | 266 ---- externals/gridflow/src/gem.cxx | 202 --- externals/gridflow/src/grid.cxx | 295 ---- externals/gridflow/src/gridflow.cxx | 961 ------------ externals/gridflow/src/gridflow.hxx | 911 ----------- externals/gridflow/src/jpeg.cxx | 118 -- externals/gridflow/src/mmx.rb | 219 --- externals/gridflow/src/mpeg3.cxx | 83 - externals/gridflow/src/netpbm.cxx | 117 -- externals/gridflow/src/number.cxx | 446 ------ externals/gridflow/src/opencv.cxx | 537 ------- externals/gridflow/src/png.cxx | 143 -- externals/gridflow/src/pwc-ioctl.h | 292 ---- externals/gridflow/src/quartz.m | 224 --- externals/gridflow/src/quicktimeapple.cxx | 456 ------ externals/gridflow/src/quicktimehw.cxx | 246 --- externals/gridflow/src/sdl.cxx | 209 --- externals/gridflow/src/source_filter.rb | 311 ---- externals/gridflow/src/videodev.cxx | 793 ---------- externals/gridflow/src/x11.cxx | 664 -------- 25 files changed, 11563 deletions(-) delete mode 100644 externals/gridflow/src/aalib.cxx delete mode 100644 externals/gridflow/src/classes1.cxx delete mode 100644 externals/gridflow/src/classes2.cxx delete mode 100644 externals/gridflow/src/dc1394.cxx delete mode 100644 externals/gridflow/src/fftw.cxx delete mode 100644 externals/gridflow/src/formats.cxx delete mode 100644 externals/gridflow/src/gem.cxx delete mode 100644 externals/gridflow/src/grid.cxx delete mode 100644 externals/gridflow/src/gridflow.cxx delete mode 100644 externals/gridflow/src/gridflow.hxx delete mode 100644 externals/gridflow/src/jpeg.cxx delete mode 100644 externals/gridflow/src/mmx.rb delete mode 100644 externals/gridflow/src/mpeg3.cxx delete mode 100644 externals/gridflow/src/netpbm.cxx delete mode 100644 externals/gridflow/src/number.cxx delete mode 100644 externals/gridflow/src/opencv.cxx delete mode 100644 externals/gridflow/src/png.cxx delete mode 100644 externals/gridflow/src/pwc-ioctl.h delete mode 100644 externals/gridflow/src/quartz.m delete mode 100644 externals/gridflow/src/quicktimeapple.cxx delete mode 100644 externals/gridflow/src/quicktimehw.cxx delete mode 100644 externals/gridflow/src/sdl.cxx delete mode 100644 externals/gridflow/src/source_filter.rb delete mode 100644 externals/gridflow/src/videodev.cxx delete mode 100644 externals/gridflow/src/x11.cxx (limited to 'externals/gridflow/src') diff --git a/externals/gridflow/src/aalib.cxx b/externals/gridflow/src/aalib.cxx deleted file mode 100644 index 771c5eab..00000000 --- a/externals/gridflow/src/aalib.cxx +++ /dev/null @@ -1,144 +0,0 @@ -/* - $Id: aalib.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#define aa_hardwareparams aa_hardware_params -#include -#include - -/* MINNOR is a typo in aalib.h, sorry */ -typedef -#if AA_LIB_MINNOR == 2 - int -#else - enum aa_attribute -#endif -AAAttr; - -static std::map drivers; - -\class FormatAALib : Format { - aa_context *context; - aa_renderparams *rparams; - \attr bool autodraw; - bool raw_mode; - /* !@#$ varargs missing here */ - \constructor (t_symbol *mode, string target) { - context=0; autodraw=1; - argc-=2; argv+=2; - char *argv2[argc]; - for (int i=0; iimgheight,context->imgwidth,1}; - post("aalib image size: %s",(new Dim(3,v))->to_s()); - } - ~FormatAALib () {if (context) aa_close(context);} - \decl 0 hidecursor (); - \decl 0 print (int y, int x, int a, string text); - \decl 0 draw (); - \decl 0 dump (); - \grin 0 int -}; - -GRID_INLET(0) { - if (!context) RAISE("boo"); - if (in->dim->n != 3) - RAISE("expecting 3 dimensions: rows,columns,channels"); - switch (in->dim->get(2)) { - case 1: raw_mode = false; break; - case 2: raw_mode = true; break; - default: - RAISE("expecting 1 greyscale channel (got %d)",in->dim->get(2)); - } - in->set_chunk(1); -} GRID_FLOW { - int f = in->dim->prod(1); - if (raw_mode) { - int sx = min(f,aa_scrwidth(context)); - int y = dex/f; - while (n) { - if (y>=aa_scrheight(context)) return; - for (int x=0; xtextbuffer[y*aa_scrwidth(context)+x]=data[x*2+0]; - context->attrbuffer[y*aa_scrwidth(context)+x]=data[x*2+1]; - } - y++; - n-=f; - data+=f; - } - } else { - int sx = min(f,context->imgwidth); - int y = dex/f; - while (n) { - if (y>=context->imgheight) return; - for (int x=0; xtextbuffer[y*aa_scrwidth(context)+x]; - data[1] = context->attrbuffer[y*aa_scrwidth(context)+x]; - out.send(2,data); - } - } -} - -\end class FormatAALib { - const aa_driver *const *p = aa_drivers; - for (; *p; p++) drivers[(*p)->shortname] = *p; - install_format("#io.aalib",2,""); -} -void startup_aalib () { - \startall -} diff --git a/externals/gridflow/src/classes1.cxx b/externals/gridflow/src/classes1.cxx deleted file mode 100644 index 07031e30..00000000 --- a/externals/gridflow/src/classes1.cxx +++ /dev/null @@ -1,2342 +0,0 @@ -/* - $Id: flow_objects.c 4548 2009-10-31 20:26:25Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "gridflow.hxx.fcs" -#ifdef DESIRE -#include "desire.h" -#else -extern "C" { -#include "bundled/g_canvas.h" -}; -extern "C" t_canvas *canvas_getrootfor(t_canvas *x); -#endif - -//using namespace std; // can't - -//#undef GRID_INPUT -//#define GRID_INPUT(I,V) GRID_INLET(I) {in->buf=V=new Grid(in->dim,NumberTypeE_type_of(data));} GRID_FINISH - -/* ---------------------------------------------------------------- */ - -// BAD HACK: GCC complains: unimplemented (--debug mode only) (i don't remember which GCC this was) -#ifdef HAVE_DEBUG -#define SCOPY(a,b,n) COPY(a,b,n) -#else -#define SCOPY(a,b,n) SCopy::f(a,b) -#endif - -template class SCopy { -public: template static inline void __attribute__((always_inline)) f(T *a, T *b) { - *a=*b; SCopy::f(a+1,b+1);}}; -template <> class SCopy<0> { -public: template static inline void __attribute__((always_inline)) f(T *a, T *b) {}}; - -/*template <> class SCopy<4> { -public: template - static inline void __attribute__((always_inline)) f(T *a, T *b) { - *a=*b; SCopy<3>::f(a+1,b+1);} - static inline void __attribute__((always_inline)) f(uint8 *a, uint8 *b) - { *(int32 *)a=*(int32 *)b; } -};*/ - -Numop *op_add, *op_sub, *op_mul, *op_div, *op_mod, *op_shl, *op_and, *op_put; - -static void expect_dim_dim_list (P d) { - if (d->n!=1) RAISE("dimension list should be Dim[n], not %s",d->to_s());} -//static void expect_min_one_dim (P d) { -// if (d->n<1) RAISE("minimum 1 dimension");} -static void expect_max_one_dim (P d) { - if (d->n>1) RAISE("expecting Dim[] or Dim[n], got %s",d->to_s());} -//static void expect_exactly_one_dim (P d) { -// if (d->n!=1) RAISE("expecting Dim[n], got %s",d->to_s());} - -//**************************************************************** -\class GridCast : FObject { - \attr NumberTypeE nt; - \constructor (NumberTypeE nt) {this->nt = nt;} - \grin 0 -}; -GRID_INLET(0) { - out = new GridOutlet(this,0,in->dim,nt); -} GRID_FLOW { - out->send(n,data); -} GRID_END -\end class {install("#cast",1,1); add_creator("@cast");} - -//**************************************************************** - -GridHandler *stromgol; // remove this asap - -//{ ?,Dim[B] -> Dim[*Cs] } -// out0 nt to be specified explicitly -\class GridImport : FObject { - \attr NumberTypeE cast; - \attr P dim; // size of grids to send - PtrGrid dim_grid; - \constructor (...) { - dim_grid.constrain(expect_dim_dim_list); - this->cast = argc>=2 ? NumberTypeE_find(argv[1]) : int32_e; - if (argc>2) RAISE("too many arguments"); - if (argc>0 && argv[0]!=gensym("per_message")) { - dim_grid=new Grid(argv[0]); - dim = dim_grid->to_dim(); - if (!dim->prod()) RAISE("target grid size must not be zero"); - } - } - ~GridImport() {} - \decl 0 reset(); - \decl 0 symbol(t_symbol *x); - \decl 0 to_ascii(...); - \decl 0 bang(); - //\decl 0 list(...); - \decl 1 per_message(); - \grin 0 - \grin 1 int32 - template void process (long n, T *data) { - if (in.size()<=0) in.resize(1); - if (!in[0]) in[0]=new GridInlet((FObject *)this,stromgol); - while (n) { - if (!out || !out->dim) out = new GridOutlet(this,0,dim?dim:in[0]->dim,cast); - long n2 = min((long)n,out->dim->prod()-out->dex); - out->send(n2,data); - n-=n2; data+=n2; - } - } -}; - -GRID_INLET(0) {} GRID_FLOW {process(n,data);} GRID_END -GRID_INPUT(1,dim_grid) { - P d = dim_grid->to_dim(); - if (!d->prod()) RAISE("target grid size must not be zero"); - dim = d; -} GRID_END - -\def 0 symbol(t_symbol *x) { - const char *name = x->s_name; - long n = strlen(name); - if (!dim) out=new GridOutlet(this,0,new Dim(n)); - process(n,(uint8 *)name); -} -\def 0 to_ascii(...) { - std::ostringstream os; - pd_oprint(os,argc,argv); - string s = os.str(); - long n = s.length(); - if (!dim) out=new GridOutlet(this,0,new Dim(n),cast); - process(n,(uint8 *)s.data()); -} - -\def 0 bang() {_0_list(0,0);} -\def 0 list(...) {//first two lines are there until grins become strictly initialized. - if (in.size()<=0) in.resize(1); - if (!in[0]) in[0]=new GridInlet((FObject *)this,stromgol); - in[0]->from_list(argc,argv,cast); - if (!argc && !dim) out = new GridOutlet(this,0,new Dim(0),cast); -} -\def 1 per_message() {dim=0; dim_grid=0;} - -\def 0 reset() {int32 foo[1]={0}; if (out) while (out->dim) out->send(1,foo);} -\end class {install("#import",2,1); add_creator("@import"); stromgol = &GridImport_grid_0_hand;} - -//**************************************************************** -/*{ Dim[*As] -> ? }*/ -/* in0: integer nt */ -\class GridToFloat : FObject { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { -} GRID_FLOW { - for (int i=0; ioutlets[0],data[i]); -} GRID_END -\end class {install("#to_float",1,1); add_creator("#export"); add_creator("@export");} - -\class GridToSymbol : FObject { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - char c[n+1]; - for (int i=0; ioutlets[0],gensym(c)); -} GRID_END -\end class {install("#to_symbol",1,1); add_creator("#export_symbol"); add_creator("@export_symbol");} - -/*{ Dim[*As] -> ? }*/ -/* in0: integer nt */ -\class GridExportList : FObject { - \constructor () {} - int n; - \grin 0 -}; - -GRID_INLET(0) { - long n = in->dim->prod(); - if (n>1000000) RAISE("list too big (%ld elements, max 1000000)", n); - this->n = n; - in->set_chunk(0); -} GRID_FLOW { - send_out(0,n,data); -} GRID_FINISH { - if (in->dim->prod()==0) send_out(0,0,data); -} GRID_END - -\end class {install("#to_list",1,1); add_creator("#export_list"); add_creator("@export_list");} - -/* **************************************************************** */ -\class GridPrint : FObject { - \constructor (t_symbol *name=0) { - this->dest = 0; - this->name = name; - base=10; trunc=70; maxrows=50; - } - \attr t_symbol *name; - \grin 0 - int base; - uint32 trunc; - int maxrows; - int columns; - t_pd *dest; - \decl 0 dest (void *p); - \decl void end_hook (); - \decl 0 base (int x); - \decl 0 trunc (int x); - \decl 0 maxrows (int y); - void puts (const char *s) { - if (!dest) post("%s",s); - else { - int n = strlen(s); - t_atom a[n]; - for (int i=0; i void make_columns (int n, T *data); - template void dump(std::ostream &s, int n, T *data, char sep=' ', int trunc=-1) { - if (trunc<0) trunc=this->trunc; - std::string f = format(NumberTypeE_type_of(data)); - for (int i=0; i=0; j--) s<<' '; - if (data[i]!=x) s<<'-'; - for (int j=ndigits-1; j>=0; j--) { - s<>j)&1)); - } - } - if (itrunc) return; - } - } - void dump_dims(std::ostream &s, GridInlet *in) { - if (name && name!=&s_) s << name->s_name << ": "; - s << "Dim["; - for (int i=0; idim->n; i++) { - s << in->dim->v[i]; - if (idim->n-1) s << ','; - } - s << "]"; - if (in->nt!=int32_e) s << "(" << number_type_table[in->nt].name << ")"; - s << ": "; - } - std::string format (NumberTypeE nt) { - if (nt==float32_e) return "%6.6f"; - if (nt==float64_e) return "%14.14f"; - std::ostringstream r; - r << "%"; - r << columns; - //if (nt==int64_e) r << "l"; - if (base==2) r << "b"; else - if (base==8) r << "o"; else - if (base==10) r << "d"; else - if (base==16) r << "x"; - return r.str(); - } -}; -\def 0 dest (void *p) {dest = (t_pd *)p;} -\def void end_hook () {} -\def 0 base (int x) { if (x==2 || x==8 || x==10 || x==16) base=x; else RAISE("base %d not supported",x); } -\def 0 trunc (int x) { - if (x<0 || x>240) RAISE("out of range (not in 0..240 range)"); - trunc = x; -} -\def 0 maxrows (int y) {maxrows = y;} -template void GridPrint::make_columns (int n, T *data) { - long maxv=0; - long minv=0; - for (int i=0; idata[i]) minv=long(data[i]); - } - int maxd = 1 + (maxv<0) + int(log(max(1.,fabs(maxv)))/log(base)); - int mind = 1 + (minv<0) + int(log(max(1.,fabs(minv)))/log(base)); - //fprintf(stderr,"v=(%d,%d) d=(%d,%d)\n",minv,maxv,mind,maxd); - columns = max(maxd,mind); -} -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - std::ostringstream head; - dump_dims(head,in); - int ndim = in->dim->n; - if (ndim > 3) { - head << " (not printed)"; - puts(head); - } else if (ndim < 2) { - make_columns(n,data); - dump(head,n,data,' ',trunc); - puts(head); - } else if (ndim == 2) { - puts(head); - make_columns(n,data); - long sy = in->dim->v[0]; - long sx = n/sy; - for (int row=0; rowtrunc) body << "..."; - puts(body); - if (row>maxrows) {puts("..."); break;} - } - } else if (ndim == 3) { - puts(head); - make_columns(n,data); - int sy = in->dim->v[0]; - int sx = in->dim->v[1]; - int sz = n/sy; - int sz2 = sz/in->dim->v[1]; - for (int row=0; rowtrunc) {str << "..."; break;} else str << ")"; - } - puts(str); - if (row>maxrows) {puts("..."); break;} - } - } - end_hook(0,0); -} GRID_FINISH { - std::ostringstream head; - dump_dims(head,in); - if (in->dim->prod()==0) puts(head); -} GRID_END -\end class {install("#print",1,1); add_creator("@print");} - -/* **************************************************************** */ -// [#store] is the class for storing a grid and restituting it on demand. -// The right inlet receives the grid. The left inlet receives either a bang -// (which forwards the whole image) or a grid describing what to send. -//{ Dim[*As,B],Dim[*Cs,*Ds] -> Dim[*As,*Ds] } -// in0: integer nt -// in1: whatever nt -// out0: same nt as in1 -\class GridStore : FObject { - - PtrGrid r; // can't be \attr - PtrGrid put_at; // can't be //\attr - \attr Numop *op; - int32 *wdex ; // temporary buffer, copy of put_at - int32 *fromb; - int32 *to2 ; - int lsd; // lsd = Last Same Dimension (for put_at) - int d; // goes with wdex - long cs; // chunksize used in put_at - \constructor (Grid *r=0) { - put_at.constrain(expect_max_one_dim); - this->r = r?r:new Grid(new Dim(),int32_e,true); - op = op_put; - wdex = NEWBUF(int32,Dim::MAX_DIM); // temporary buffer, copy of put_at - fromb = NEWBUF(int32,Dim::MAX_DIM); - to2 = NEWBUF(int32,Dim::MAX_DIM); - } - ~GridStore () { - DELBUF(wdex); - DELBUF(fromb); - DELBUF(to2); - } - \decl 0 bang (); - \decl 1 reassign (); - \decl 1 put_at (...); - \grin 0 int - \grin 1 - template void compute_indices(T *v, long nc, long nd); -}; - -// takes the backstore of a grid and puts it back into place. a backstore -// is a grid that is filled while the grid it would replace has not -// finished being used. -static void snap_backstore (PtrGrid &r) {if (r.next) {r=r.next.p; r.next=0;}} - -template void GridStore::compute_indices(T *v, long nc, long nd) { - for (int i=0; idim->v[i]; - bool fast = lowest_bit(wrap)==highest_bit(wrap); // is power of two? - if (i) { - if (fast) op_shl->map(nd,v,(T)highest_bit(wrap)); - else op_mul->map(nd,v,(T)wrap); - } - if (fast) op_and->map(nd,v+nd*i,(T)(wrap-1)); - else op_mod->map(nd,v+nd*i,(T)(wrap)); - if (i) op_add->zip(nd,v,v+nd*i); - } -} - -// !@#$ i should ensure that n is not exceedingly large -// !@#$ worse: the size of the foo buffer may still be too large -GRID_INLET(0) { - // snap_backstore must be done before *anything* else - snap_backstore(r); - int na = in->dim->n; - int nb = r->dim->n; - int32 v[Dim::MAX_DIM]; - if (na<1) RAISE("must have at least 1 dimension.",na,1,1+nb); - long nc = in->dim->get(na-1); - if (nc>nb) RAISE("got %d elements in last dimension, expecting <= %d", nc, nb); - long nnc = r->dim->prod(nc); - int lastindexable = nnc ? r->dim->prod()/nnc-1 : 0; // SIGFPE happened when r was especially empty (nnc==0) - int ngreatest = nt_greatest((T *)0); - if (lastindexable > ngreatest) RAISE("lastindexable=%d > ngreatest=%d (ask matju)",lastindexable,ngreatest); - int nd = nb-nc+na-1; - COPY(v,in->dim->v,na-1); - COPY(v+na-1,r->dim->v+nc,nb-nc); - out=new GridOutlet(this,0,new Dim(nd,v),r->nt); - if (nc>0) in->set_chunk(na-1); -} GRID_FLOW { - int na = in->dim->n; - int nc = in->dim->get(na-1); - long size = r->dim->prod(nc); - long nd = n/nc; - T w[n]; - T *v=w; - if (sizeof(T)==1 && nc==1 && r->dim->v[0]<=256) { - // bug? shouldn't modulo be done here? - v=data; - } else { - COPY(v,data,n); - for (long k=0,i=0; isend(size*nd,tada); \ - } else { \ - for (int i=0; isend(size,p+size*v[i]); \ - } \ -} - TYPESWITCH(r->nt,FOO,) -#undef FOO -} GRID_FINISH { - if (in->dim->prod()==0) { - long n = in->dim->prod(0,-2); - long size = r->dim->prod(); -#define FOO(T) while (n--) out->send(size,(T *)*r); - TYPESWITCH(r->nt,FOO,) -#undef FOO - } -} GRID_END - -GRID_INLET(1) { - NumberTypeE nt = NumberTypeE_type_of(data); - if (!put_at) { // reassign - if (in[0].dim) r.next = new Grid(in->dim,nt); - else r = new Grid(in->dim,nt); - return; - } - // put_at ( ... ) - snap_backstore(r); - SAME_TYPE(in,r); - //!@#$ should check types. if (r->nt!=in->nt) RAISE("shoo"); - long nn=r->dim->n, na=put_at->dim->v[0], nb=in->dim->n; - int32 sizeb[nn]; - for (int i=0; idim->prod()); - COPY(fromb+nn-na,(int32 *)*put_at ,na); - COPY(sizeb+nn-nb,(int32 *)in->dim->v,nb); - for (int i=0; i=nn-in->dim->n) { - lsd--; - //int cs = in->dim->prod(lsd-nn+in->dim->n); - if (/*cs*(number_type_table[in->nt].size/8)>GridOutlet::MAX_PACKET_SIZE ||*/ - fromb[lsd]!=0 || sizeb[lsd]!=r->dim->v[lsd]) break; - } - lsd++; - long chunk = lsd-nn+in->dim->n; - in->set_chunk( chunk); - cs = in->dim->prod(chunk); -} GRID_FLOW { - //fprintf(stderr,"d=%d\n",d); - if (!put_at) { // reassign - COPY(((T *)*(r.next ? r.next.p : &*r.p))+dex, data, n); - return; - } - // put_at (...) - int32 v[lsd]; - int32 *x = wdex; - while (n) { - // here d is the dim# to reset; d=n for none - for(;dzip(cs,(T *)*r+v[0]*cs,data); - data+=cs; - n-=cs; - // find next set of indices; here d is the dim# to increment - for(;;) {d--; if (d<0) return; x[d]++; if (x[d] -> Dim[*As] } or -//{ Dim[*As],Dim[*Bs] -> Dim[*As] } -\class GridOp : FObject { - \attr Numop *op; - PtrGrid r; - \constructor (Numop *op, Grid *r=0) { - this->op=op; - this->r=r?r:new Grid(new Dim(),int32_e,true); - } - \grin 0 - \grin 1 -}; - -GRID_INLET(0) { - snap_backstore(r); - SAME_TYPE(in,r); - out=new GridOutlet(this,0,in->dim,in->nt); - if (op->size>1 && (in->dim->get(in->dim->n-1)!=op->size || r->dim->get(r->dim->n-1)!=op->size)) - RAISE("using %s requires Dim(...,%d) in both inlets but got: left=%s right=%s", - op->name,op->size,in->dim->to_s(),r->dim->to_s()); - //if (out->inlets.size()==1) post("[#]: 1 receiver with bugger size %s",out->inlets[0]->dim->to_s()); -} GRID_FLOW { - T *rdata = (T *)*r; - long loop = r->dim->prod(); - T tada[n]; - COPY(tada,data,n); - if (loop>1) { - if (dex+n <= loop) { - op->zip(n/op->size,tada,rdata+dex); - } else { - // !@#$ should prebuild and reuse this array when "loop" is small - T data2[n]; - long ii = mod(dex,loop); - long m = min(loop-ii,n); - COPY(data2,rdata+ii,m); - long nn = m+((n-m)/loop)*loop; - for (long i=m; inn) COPY(data2+nn,rdata,n-nn); - op->zip(n/op->size,tada,data2); - } - } else op->map(n,tada,*rdata); - out->send(n,tada); -} GRID_END - -GRID_INPUT2(1,r) {} GRID_END -\end class {install("#",2,1); add_creator("@");} - -//**************************************************************** -\class GridFold : FObject { - \attr Numop *op; - \attr PtrGrid seed; - \constructor (Numop *op) {this->op=op;} - \grin 0 -}; - -GRID_INLET(0) { - //{ Dim[*As,B,*Cs],Dim[*Cs] -> Dim[*As,*Cs] } - if (seed) SAME_TYPE(in,seed); - int an = in->dim->n; - int bn = seed?seed->dim->n:0; - if (an<=bn) RAISE("minimum 1 more dimension than the seed (%d vs %d)",an,bn); - int32 v[an-1]; - int yi = an-bn-1; - COPY(v,in->dim->v,yi); - COPY(v+yi,in->dim->v+an-bn,bn); - if (seed) SAME_DIM(an-(yi+1),in->dim,(yi+1),seed->dim,0); - out=new GridOutlet(this,0,new Dim(an-1,v),in->nt); - in->set_chunk(yi); - if (in->dim->prod(yi)==0) { - long n = out->dim->prod(); - T x=0; op->on(x)->neutral(&x,at_left); - for(long i=0; isend(1,&x); - } -} GRID_FLOW { - int an = in->dim->n; - int bn = seed?seed->dim->n:0; - long yn = in->dim->v[an-bn-1]; - long zn = in->dim->prod(an-bn); - T buf[n/yn]; - long nn=n; - long yzn=yn*zn; - for (long i=0; n; i+=zn, data+=yzn, n-=yzn) { - if (seed) COPY(buf+i,((T *)*seed),zn); - else {T neu; op->on(*buf)->neutral(&neu,at_left); op_put->map(zn,buf+i,neu);} - op->fold(zn,yn,buf+i,data); - } - out->send(nn/yn,buf); -} GRID_FINISH { -} GRID_END - -\end class {install("#fold",1,1);} - -\class GridScan : FObject { - \attr Numop *op; - \attr PtrGrid seed; - \constructor (Numop *op) {this->op = op;} - \grin 0 -}; - -GRID_INLET(0) { - //{ Dim[*As,B,*Cs],Dim[*Cs] -> Dim[*As,B,*Cs] } - if (seed) SAME_TYPE(in,seed); - int an = in->dim->n; - int bn = seed?seed->dim->n:0; - if (an<=bn) RAISE("minimum 1 more dimension than the right hand"); - if (seed) SAME_DIM(bn,in->dim,an-bn,seed->dim,0); - out=new GridOutlet(this,0,in->dim,in->nt); - in->set_chunk(an-bn-1); -} GRID_FLOW { - int an = in->dim->n; - int bn = seed?seed->dim->n:0; - long yn = in->dim->v[an-bn-1]; - long zn = in->dim->prod(an-bn); - long factor = yn*zn; - T buf[n]; - COPY(buf,data,n); - if (seed) { - for (long i=0; iscan(zn,yn,(T *)*seed,buf+i); - } else { - T neu; op->on(*buf)->neutral(&neu,at_left); - T seed[zn]; op_put->map(zn,seed,neu); - for (long i=0; iscan(zn,yn, seed,buf+i); - } - out->send(n,buf); -} GRID_END - -\end class {install("#scan",1,1);} - -//**************************************************************** -// L is a Dim[*si,sj, *ss] -// R is a Dim[ sj,*sk,*ss] -// Seed is a Dim[ *ss] -// result is a Dim[*si, *sk,*ss] -// Currently *ss can only be = Dim[] -\class GridInner : FObject { - \attr Numop *op; - \attr Numop *fold; - \attr PtrGrid seed; - PtrGrid r; - PtrGrid r2; // temporary - bool use_dot; - \constructor (Grid *r=0) { - this->op = op_mul; - this->fold = op_add; - this->seed = new Grid(new Dim(),int32_e,true); - this->r = r ? r : new Grid(new Dim(),int32_e,true); - } - \grin 0 - \grin 1 -}; - -// let's see this as a matrix product like L[i,j]*R[j,k] in Einstein notation -// L: matrix of size si by sj -// R: matrix of size sj by sk -// LR: matrix of size si by sk -template void inner_child_a (T *as, T *bs, int sj, int sk, int chunk) { - for (int j=0; jmap(sk,as,*bs);} -template void inner_child_b (T *as, T *bs, int sj, int chunk) { - for (int j=0; jmap(sk,as,*bs);} - -// Inner product in a Module on the (+,*) Ring -// | BBBBB -// j BBBBB -// | BBBBB -// --j--*---k--- -// AAAAA CCCCC -template void dot_add_mul (long sk, long sj, T *cs, T *as, T *bs) { - for (long k=0; k void dot_add_mul (long sk, T *cs, T *as, T *bs) { - for (long k=0; k void dot_add_mul (T *cs, T *as, T *bs) { - for (long k=0; k a=in->dim, b=r->dim; - if (a->n<1) RAISE("a: minimum 1 dimension"); - if (b->n<1) RAISE("b: minimum 1 dimension"); - if (seed->dim->n != 0) RAISE("seed must be a scalar"); - int n = a->n+b->n-2; - SAME_DIM(1,a,a->n-1,b,0); - int32 v[n]; - COPY(v,a->v,a->n-1); - COPY(v+a->n-1,b->v+1,b->n-1); - out=new GridOutlet(this,0,new Dim(n,v),in->nt); - in->set_chunk(a->n-1); - long sjk=r->dim->prod(), sj=in->dim->prod(a->n-1), sk=sjk/sj; - long chunk = max(1L,GridOutlet::MAX_PACKET_SIZE/sjk); - T *rdata = (T *)*r; - r2=new Grid(new Dim(chunk*sjk),r->nt); - T *buf3 = (T *)*r2; - for (long i=0; idim->n==0 && *(T *)*seed==0; -} GRID_FLOW { - long sjk=r->dim->prod(), sj=in->dim->prod(in->dim->n-1), sk=sjk/sj; - long chunk = max(1L,GridOutlet::MAX_PACKET_SIZE/sjk), off=chunk; - T buf [chunk*sk]; - T buf2[chunk*sk]; - if (use_dot) { - while (n) { - if (chunk*sj>n) chunk=n/sj; - if (sj<=4 && sk<=4) switch ((sj-1)*4+(sk-1)) { -#define DOT_ADD_MUL_3(sj,sk) for (int i=0; i( buf2+sk*i,data+sj*i,(T *)*r); - case 0: DOT_ADD_MUL_3(1,1); break; - case 1: DOT_ADD_MUL_3(1,2); break; - case 2: DOT_ADD_MUL_3(1,3); break; - case 3: DOT_ADD_MUL_3(1,4); break; - case 4: DOT_ADD_MUL_3(2,1); break; - case 5: DOT_ADD_MUL_3(2,2); break; - case 6: DOT_ADD_MUL_3(2,3); break; - case 7: DOT_ADD_MUL_3(2,4); break; - case 8: DOT_ADD_MUL_3(3,1); break; - case 9: DOT_ADD_MUL_3(3,2); break; - case 10: DOT_ADD_MUL_3(3,3); break; - case 11: DOT_ADD_MUL_3(3,4); break; - case 12: DOT_ADD_MUL_3(4,1); break; - case 13: DOT_ADD_MUL_3(4,2); break; - case 14: DOT_ADD_MUL_3(4,3); break; - case 15: DOT_ADD_MUL_3(4,4); break; - } else switch (sj) { -#define DOT_ADD_MUL_2(sj) for (int i=0; i(sk,buf2+sk*i,data+sj*i,(T *)*r); - case 1: DOT_ADD_MUL_2(1); break; - case 2: DOT_ADD_MUL_2(2); break; - case 3: DOT_ADD_MUL_2(3); break; - case 4: DOT_ADD_MUL_2(4); break; - default:for (int i=0; isend(chunk*sk,buf2); - n-=chunk*sj; - data+=chunk*sj; - } - } else { - while (n) { - if (chunk*sj>n) chunk=n/sj; - op_put->map(chunk*sk,buf2,*(T *)*seed); - for (long i=0; i(buf,data+i,sj,chunk); break; - case 2: inner_child_b(buf,data+i,sj,chunk); break; - case 3: inner_child_b(buf,data+i,sj,chunk); break; - case 4: inner_child_b(buf,data+i,sj,chunk); break; - default: inner_child_a(buf,data+i,sj,sk,chunk); - } - op->zip(chunk*sk,buf,(T *)*r2+i*off*sk); - fold->zip(chunk*sk,buf2,buf); - } - out->send(chunk*sk,buf2); - n-=chunk*sj; - data+=chunk*sj; - } - } -} GRID_FINISH { - r2=0; -} GRID_END - -GRID_INPUT(1,r) {} GRID_END - -\end class {install("#inner",2,1);} - -/* **************************************************************** */ -/*{ Dim[*As],Dim[*Bs] -> Dim[*As,*Bs] }*/ -\class GridOuter : FObject { - \attr Numop *op; - PtrGrid r; - \constructor (Numop *op, Grid *r=0) { - this->op = op; - this->r = r ? r : new Grid(new Dim(),int32_e,true); - } - \grin 0 - \grin 1 -}; - -GRID_INLET(0) { - SAME_TYPE(in,r); - P a = in->dim; - P b = r->dim; - int n = a->n+b->n; - int32 v[n]; - COPY(v,a->v,a->n); - COPY(v+a->n,b->v,b->n); - out=new GridOutlet(this,0,new Dim(n,v),in->nt); -} GRID_FLOW { - long b_prod = r->dim->prod(); - if (!b_prod) return; /* nothing to do... and avoid deadly divisions by zero */ - if (b_prod > 4) { - T buf[b_prod]; - while (n) { - for (long j=0; jzip(b_prod,buf,(T *)*r); - out->send(b_prod,buf); - data++; n--; - } - return; - } - n*=b_prod; - T buf[n]; - T buf2[b_prod*64]; - for (int i=0; i<64; i++) COPY(buf2+i*b_prod,(T *)*r,b_prod); - switch (b_prod) { - #define Z buf[k++]=data[i] - case 1: for (long i=0,k=0; kzip(ch,buf+j,buf2); - op->zip(n-nn,buf+nn,buf2); - out->send(n,buf); -} GRID_END - -GRID_INPUT(1,r) {} GRID_END - -\end class {install("#outer",2,1); add_creator("@outer");} - -//**************************************************************** -//{ Dim[],Dim[],Dim[] -> Dim[A] } or -//{ Dim[B],Dim[B],Dim[B] -> Dim[*As,B] } -\class GridFor : FObject { - \attr PtrGrid from; - \attr PtrGrid to; - \attr PtrGrid step; - \constructor (Grid *from, Grid *to, Grid *step) { - this->from.constrain(expect_max_one_dim); - this->to .constrain(expect_max_one_dim); - this->step.constrain(expect_max_one_dim); - this->from=from; - this->to =to; - this->step=step; - } - \decl 0 set (Grid *r=0); - \decl 0 bang (); - \grin 0 int - \grin 1 int - \grin 2 int - template void trigger (T bogus); -}; - -template -void GridFor::trigger (T bogus) { - int n = from->dim->prod(); - int32 nn[n+1]; - T x[64*n]; - T *fromb = (T *)*from; - T * tob = (T *)*to ; - T *stepb = (T *)*step; - T to2[n]; - - for (int i=step->dim->prod()-1; i>=0; i--) - if (!stepb[i]) RAISE("step must not contain zeroes"); - for (int i=0; i d; - if (from->dim->n==0) { d = new Dim(*nn); } - else { nn[n]=n; d = new Dim(n+1,nn); } - int total = d->prod(); - out=new GridOutlet(this,0,d,from->nt); - if (total==0) return; - int k=0; - for(int d=0;;d++) { - // here d is the dim# to reset; d=n for none - for(;dsend(k,x); k=0; COPY(x,x+63*n,n);} - else { COPY(x+k,x+k-n,n);} - d--; - // here d is the dim# to increment - for(;;d--) { - if (d<0) goto end; - x[k+d]+=stepb[d]; - if (x[k+d]!=to2[d]) break; - } - } - end: if (k) out->send(k,x); -} - -\def 0 bang () { - SAME_TYPE(from,to); - SAME_TYPE(from,step); - if (!from->dim->equal(to->dim) || !to->dim->equal(step->dim)) - RAISE("dimension mismatch: from:%s to:%s step:%s", - from->dim->to_s(),to->dim->to_s(),step->dim->to_s()); -#define FOO(T) trigger((T)0); - TYPESWITCH_JUSTINT(from->nt,FOO,); -#undef FOO -} - -\def 0 set (Grid *r) { from=new Grid(argv[0]); } -GRID_INPUT(2,step) {} GRID_END -GRID_INPUT(1,to) {} GRID_END -GRID_INPUT(0,from) {_0_bang(0,0);} GRID_END -\end class {install("#for",3,1); add_creator("@for");} - -//**************************************************************** -\class GridFinished : FObject { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { - //in->set_mode(0); -} GRID_FINISH { - outlet_bang(bself->outlets[0]); -} GRID_END -\end class {install("#finished",1,1); add_creator("@finished");} -\class GridDim : FObject { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { - GridOutlet out(this,0,new Dim(in->dim->n)); - out.send(in->dim->n,in->dim->v); - //in->set_mode(0); -} GRID_END -\end class {install("#dim",1,1); add_creator("@dim");} -\class GridType : FObject { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { - outlet_symbol(bself->outlets[0],gensym(const_cast(number_type_table[in->nt].name))); - /*in->set_mode(0);*/ -} GRID_END -\end class {install("#type",1,1); add_creator("@type");} - -//**************************************************************** -//{ Dim[*As],Dim[B] -> Dim[*Cs] } -\class GridRedim : FObject { - \attr P dim; - PtrGrid dim_grid; - PtrGrid temp; // temp->dim is not of the same shape as dim - ~GridRedim() {} - \constructor (Grid *d) { - dim_grid.constrain(expect_dim_dim_list); - dim_grid=d; - dim = dim_grid->to_dim(); - // if (!dim->prod()) RAISE("target grid size must not be zero"); - } - \grin 0 - \grin 1 int32 -}; - -GRID_INLET(0) { - long a=in->dim->prod(), b=dim->prod(); - if (ant); - out=new GridOutlet(this,0,dim,in->nt); -} GRID_FLOW { - long i = dex; - if (!temp) { - long n2 = min(n,dim->prod()-i); - if (n2>0) out->send(n2,data); - // discard other values if any - } else { - long n2 = min(n,in->dim->prod()-i); - COPY((T *)*temp+i,data,n2); - if (n2>0) out->send(n2,data); - } -} GRID_FINISH { - if (!!temp) { - long a = in->dim->prod(), b = dim->prod(); - if (a) { - for (long i=a; isend(min(a,b-i),(T *)*temp); - } else { - T foo[1]={0}; for (long i=0; isend(1,foo); - } - } - temp=0; -} GRID_END - -GRID_INPUT(1,dim_grid) { - P d = dim_grid->to_dim(); -// if (!d->prod()) RAISE("target grid size must not be zero"); else post("d->prod=%d",d->prod()); - dim = d; -} GRID_END - -\end class {install("#redim",2,1); add_creator("@redim");} - -//**************************************************************** -\class GridJoin : FObject { - \attr int which_dim; - PtrGrid r; - \grin 0 - \grin 1 - \constructor (int which_dim=-1, Grid *r=0) { - this->which_dim = which_dim; - this->r=r; - } -}; - -GRID_INLET(0) { - NOTEMPTY(r); - SAME_TYPE(in,r); - P d = in->dim; - if (d->n != r->dim->n) RAISE("wrong number of dimensions"); - int w = which_dim; - if (w<0) w+=d->n; - if (w<0 || w>=d->n) - RAISE("can't join on dim number %d on %d-dimensional grids", - which_dim,d->n); - int32 v[d->n]; - for (int i=0; in; i++) { - v[i] = d->get(i); - if (i==w) { - v[i]+=r->dim->v[i]; - } else { - if (v[i]!=r->dim->v[i]) RAISE("dimensions mismatch: dim #%i, left is %d, right is %d",i,v[i],r->dim->v[i]); - } - } - out=new GridOutlet(this,0,new Dim(d->n,v),in->nt); - in->set_chunk(w); -} GRID_FLOW { - int w = which_dim; - if (w<0) w+=in->dim->n; - long a = in->dim->prod(w); - long b = r->dim->prod(w); - T *data2 = (T *)*r + dex*b/a; - if (a==3 && b==1) { - int m = n+n*b/a; - T data3[m]; - T *data4 = data3; - while (n) { - SCOPY(data4,data,3); SCOPY(data4+3,data2,1); - n-=3; data+=3; data2+=1; data4+=4; - } - out->send(m,data3); - } else if (a+b<=16) { - int m = n+n*b/a; - T data3[m]; - int i=0; - while (n) { - COPY(data3+i,data,a); data+=a; i+=a; n-=a; - COPY(data3+i,data2,b); data2+=b; i+=b; - } - out->send(m,data3); - } else { - while (n) { - out->send(a,data); - out->send(b,data2); - data+=a; data2+=b; n-=a; - } - } -} GRID_FINISH { - if (in->dim->prod()==0) out->send(r->dim->prod(),(T *)*r); -} GRID_END - -GRID_INPUT(1,r) {} GRID_END - -\end class {install("#join",2,1); add_creator("@join");} - -//**************************************************************** -\class GridGrade : FObject { - \constructor () {} - \grin 0 -}; - -typedef int (*comparator_t)(const void *, const void *); - -template struct GradeFunction { - static int comparator (T **a, T **b) {return **a-**b;}}; -#define FOO(T) \ -template <> struct GradeFunction { \ - static int comparator (T **a, T **b) {T x = **a-**b; return x<0 ? -1 : x>0;}}; -FOO(int64) -FOO(float32) -FOO(float64) -#undef FOO - -GRID_INLET(0) { - out=new GridOutlet(this,0,in->dim); - in->set_chunk(in->dim->n-1); -} GRID_FLOW { - long m = in->dim->prod(in->dim->n-1); - T *foo[m]; - T bar[m]; - for (; n; n-=m,data+=m) { - for (int i=0; i::comparator); - for (int i=0; isend(m,bar); - } -} GRID_END - -\end class {install("#grade",1,1); add_creator("@grade");} - -//**************************************************************** -//\class GridMedian : FObject -//**************************************************************** - -\class GridTranspose : FObject { - \attr int dim1; - \attr int dim2; - int d1,d2,na,nb,nc,nd; // temporaries - \constructor (int dim1=0, int dim2=1) { - this->dim1 = dim1; - this->dim2 = dim2; - } - \decl 1 float (int dim1); - \decl 2 float (int dim2); - \grin 0 -}; - -\def 1 float (int dim1) { this->dim1=dim1; } -\def 2 float (int dim2) { this->dim2=dim2; } - -GRID_INLET(0) { - int32 v[in->dim->n]; - COPY(v,in->dim->v,in->dim->n); - d1=dim1; d2=dim2; - if (d1<0) d1+=in->dim->n; - if (d2<0) d2+=in->dim->n; - if (d1>=in->dim->n || d2>=in->dim->n || d1<0 || d2<0) - RAISE("would swap dimensions %d and %d but this grid has only %d dimensions", dim1,dim2,in->dim->n); - memswap(v+d1,v+d2,1); - if (d1==d2) { - out=new GridOutlet(this,0,new Dim(in->dim->n,v), in->nt); - } else { - nd = in->dim->prod(1+max(d1,d2)); - nc = in->dim->v[max(d1,d2)]; - nb = nc&&nd ? in->dim->prod(1+min(d1,d2))/nc/nd : 0; - na = in->dim->v[min(d1,d2)]; - out=new GridOutlet(this,0,new Dim(in->dim->n,v), in->nt); - in->set_chunk(min(d1,d2)); - } - // Turns a Grid[*,na,*nb,nc,*nd] into a Grid[*,nc,*nb,na,*nd]. -} GRID_FLOW { - //T res[na*nb*nc*nd]; - T *res = NEWBUF(T,na*nb*nc*nd); - if (dim1==dim2) { out->send(n,data); return; } - int prod = na*nb*nc*nd; - for (; n; n-=prod, data+=prod) { - for (long a=0; asend(na*nb*nc*nd,res); - } - DELBUF(res); //!@#$ if an exception was thrown by out->send, this never gets done -} GRID_END - -\end class {install("#transpose",3,1); add_creator("@transpose");} - -//**************************************************************** -\class GridReverse : FObject { - \attr int dim1; // dimension to act upon - int d; // temporaries - \constructor (int dim1=0) {this->dim1 = dim1;} - \decl 1 float (int dim1); - \grin 0 -}; - -\def 1 float (int dim1) { this->dim1=dim1; } - -GRID_INLET(0) { - d=dim1; - if (d<0) d+=in->dim->n; - if (d>=in->dim->n || d<0) - RAISE("would reverse dimension %d but this grid has only %d dimensions", - dim1,in->dim->n); - out=new GridOutlet(this,0,new Dim(in->dim->n,in->dim->v), in->nt); - in->set_chunk(d); -} GRID_FLOW { - long f1=in->dim->prod(d), f2=in->dim->prod(d+1); - while (n) { - long hf1=f1/2; - T *data2 = data+f1-f2; - for (long i=0; isend(f1,data); - data+=f1; n-=f1; - } -} GRID_END - -\end class {install("#reverse",2,1);} - -//**************************************************************** -\class GridCentroid : FObject { - \constructor () {} - \grin 0 int - int sumx,sumy,sum,y; // temporaries -}; - -GRID_INLET(0) { - if (in->dim->n != 3) RAISE("expecting 3 dims"); - if (in->dim->v[2] != 1) RAISE("expecting 1 channel"); - in->set_chunk(1); - out=new GridOutlet(this,0,new Dim(2), in->nt); - sumx=0; sumy=0; sum=0; y=0; -} GRID_FLOW { - int sx = in->dim->v[1]; - while (n) { - for (int x=0; xsend(2,blah); - outlet_float(bself->outlets[1],blah[0]); - outlet_float(bself->outlets[2],blah[1]); -} GRID_END - -\end class {install("#centroid",1,3);} - -//**************************************************************** -static void expect_pair (P dim) {if (dim->prod()!=2) RAISE("expecting only two numbers. Dim(2)");} - -\class GridMoment : FObject { - \constructor (int order=1) { - offset.constrain(expect_pair); - //t_atom2 a[2] = {t_atom2(0),t_atom2(0)}; - t_atom a[2]; SETFLOAT(a,0); SETFLOAT(a+1,0); - offset=new Grid(2,a,int32_e); - if (order!=1 && order!=2) RAISE("supports only orders 1 and 2 for now"); - this->order=order; - } - \grin 0 int - \grin 1 int - \attr int order; // order - \attr PtrGrid offset; - int64 sumy,sumxy,sumx,sum,y; // temporaries -}; - -GRID_INLET(0) { - if (in->dim->n != 3) RAISE("expecting 3 dims"); - if (in->dim->v[2] != 1) RAISE("expecting 1 channel"); - in->set_chunk(1); - switch (order) { - case 1: out=new GridOutlet(this,0,new Dim(2 ), in->nt); break; - case 2: out=new GridOutlet(this,0,new Dim(2,2), in->nt); break; - default: RAISE("supports only orders 1 and 2 for now"); - } - sumx=0; sumy=0; sumxy=0; sum=0; y=0; -} GRID_FLOW { - int sx = in->dim->v[1]; - int oy = ((int*)*offset)[0]; - int ox = ((int*)*offset)[1]; - while (n) { - switch (order) { - case 1: - for (int x=0; xsend(2,blah); - break; - case 2: /* covariance matrix */ - blah[0] = sum ? sumy/sum : 0; - blah[1] = sum ? sumxy/sum : 0; - blah[2] = sum ? sumxy/sum : 0; - blah[3] = sum ? sumx/sum : 0; - out->send(4,blah); - break; - } -} GRID_END - -GRID_INPUT(1,offset) {} GRID_END - -\end class {install("#moment",2,1);} - -//**************************************************************** -\class GridLabelling : FObject { - \grin 0 - \attr int form(); - \attr int form_val; - \constructor (int form=0) {form_val=form; initialize3();} - void initialize3() {bself->noutlets_set(form_val ? 2 : 4);} -}; -struct Stats { - int64 yy,yx,xx,y,x,area; - int64 x1,x2; - Stats() {yy=yx=xx=y=x=area=0;} -}; -#define AT(y,x) dat[(y)*sx+(x)] -template void flood_fill(T *dat, int sy, int sx, int y, int x, Stats *stat, int label, int form) { - /* find x1,x2 such that all the x of that horizontal segment are x1<=x=0; x1--) if (AT(y,x1)!=1) break; - x1++; - if (form==0) { - for (x=x1; xyy += y*y; stat->y += y; - stat->yx += y*x; stat->area++; - stat->xx += x*x; stat->x += x; - } - for (x=x1; x0 && AT(y-1,x)==1) flood_fill(dat,sy,sx,y-1,x,stat,label,form); - if (yy=y; - stat->x1=x1; - stat->x2=x2; - } -} - -GRID_INLET(0) { - if (in->dim->n<2 || in->dim->prod(2)!=1) RAISE("requires dim (y,x) or (y,x,1)"); - in->set_chunk(0); -} GRID_FLOW { - int sy=in->dim->v[0], sx=in->dim->v[1]; - T *dat = NEWBUF(T,n); - for (int i=0; int); - out->send(n,dat); - DELBUF(dat); -} GRID_END - -\def int form() {return form_val;} -\def 0 form(int form) { - if (form<0 || form>1) RAISE("form must be 0 or 1, not %d",form); - form_val=form; - initialize3(); -} -\end class {install("#labelling",1,0); add_creator("#labeling");} - -//**************************************************************** -\class GridPerspective : FObject { - \attr int32 z; - \grin 0 - \constructor (int32 z=256) {this->z=z;} -}; -GRID_INLET(0) { - int n = in->dim->n; - int32 v[n]; - COPY(v,in->dim->v,n); - v[n-1]--; - in->set_chunk(in->dim->n-1); - out=new GridOutlet(this,0,new Dim(n,v),in->nt); -} GRID_FLOW { - int m = in->dim->prod(in->dim->n-1); - for (; n; n-=m,data+=m) { - op_mul->map(m-1,data,(T)z); - op_div->map(m-1,data,data[m-1]); - out->send(m-1,data); - } -} GRID_END -\end class {install("#perspective",1,1); add_creator("@perspective");} - -//**************************************************************** -\class GridBorder : FObject { - \attr P diml; - \attr P dimr; - PtrGrid diml_grid; - PtrGrid dimr_grid; - \grin 0 - \grin 1 int - \grin 2 int - \constructor (Grid *dl=0, Grid *dr=0) { - t_atom a[2]; SETFLOAT(a+0,1); SETFLOAT(a+1,1); SETFLOAT(a+2,0); - diml_grid=dl?dl:new Grid(3,a,int32_e); - dimr_grid=dr?dr:new Grid(3,a,int32_e); - diml = diml_grid->to_dim(); - dimr = dimr_grid->to_dim(); - } -}; - -GRID_INLET(0) { - int n = in->dim->n; - if (n!=3) RAISE("only 3 dims supported for now"); - if (diml->n != n) RAISE("diml mismatch"); - if (dimr->n != n) RAISE("dimr mismatch"); - if (diml->v[2] || dimr->v[2]) RAISE("can't augment channels (todo)"); - int32 v[n]; - for (int i=0; idim->v[i]+diml->v[i]+dimr->v[i]; - in->set_chunk(0); - out=new GridOutlet(this,0,new Dim(n,v),in->nt); -} GRID_FLOW { - int sy = in->dim->v[0]; - int sx = in->dim->v[1]; int zx = sx+diml->v[1]+dimr->v[1]; - int sc = in->dim->v[2]; int zc = sc+diml->v[2]+dimr->v[2]; - int sxc = sx*sc; int zxc = zx*zc; - int32 duh[zxc]; - for (int x=0; xv[0]; y++) out->send(zxc,duh); - for (int y=0; ysend(diml->v[1]*sc,duh); - out->send(sxc,data+y*sxc); - out->send(dimr->v[1]*sc,duh); - } - for (int i=0; iv[0]; i++) out->send(zxc,duh); -} GRID_END - -GRID_INPUT(1,diml_grid) {diml = diml_grid->to_dim();} GRID_END -GRID_INPUT(2,dimr_grid) {dimr = dimr_grid->to_dim();} GRID_END - -\end class {install("#border",3,1);} - -static void expect_picture (P d) { - if (d->n!=3) RAISE("(height,width,chans) dimensions please");} -static void expect_rgb_picture (P d) { - expect_picture(d); - if (d->get(2)!=3) RAISE("(red,green,blue) channels please");} -static void expect_rgba_picture (P d) { - expect_picture(d); - if (d->get(2)!=4) RAISE("(red,green,blue,alpha) channels please");} - -//**************************************************************** -//{ Dim[A,B,*Cs],Dim[D,E] -> Dim[A,B,*Cs] } - -static void expect_convolution_matrix (P d) { - if (d->n != 2) RAISE("only exactly two dimensions allowed for now (got %d)", - d->n); -} - -// entry in a compiled convolution kernel -struct PlanEntry {long y,x; bool neutral;}; - -\class GridConvolve : FObject { - \attr Numop *op; - \attr Numop *fold; - \attr PtrGrid seed; - \attr PtrGrid b; - \attr bool wrap; - \attr bool anti; - PtrGrid a; - int plann; - PlanEntry *plan; - int margx,margy; // margins - \constructor (Grid *r=0) { - plan=0; - b.constrain(expect_convolution_matrix); plan=0; - this->op = op_mul; - this->fold = op_add; - this->seed = new Grid(new Dim(),int32_e,true); - this->b= r ? r : new Grid(new Dim(1,1),int32_e,true); - this->wrap = true; - this->anti = true; - } - \grin 0 - \grin 1 - template void copy_row (T *buf, long sx, long y, long x); - template void make_plan (T bogus); - ~GridConvolve () {if (plan) delete[] plan;} -}; - -template void GridConvolve::copy_row (T *buf, long sx, long y, long x) { - long day = a->dim->get(0), dax = a->dim->get(1), dac = a->dim->prod(2); - y=mod(y,day); x=mod(x,dax); - T *ap = (T *)*a + y*dax*dac; - while (sx) { - long sx1 = min(sx,dax-x); - COPY(buf,ap+x*dac,sx1*dac); - x=0; - buf += sx1*dac; - sx -= sx1; - } -} - -template void GridConvolve::make_plan (T bogus) { - P da = a->dim, db = b->dim; - long dby = db->get(0); - long dbx = db->get(1); - if (plan) delete[] plan; - plan = new PlanEntry[dbx*dby]; - long i=0; - for (long y=0; yon(rh)->is_neutral( rh,at_right); - bool absorbent = op->on(rh)->is_absorbent(rh,at_right); - T foo[1]={0}; - if (absorbent) { - op->map(1,foo,rh); - absorbent = fold->on(rh)->is_neutral(foo[0],at_right); - } - if (absorbent) continue; - plan[i].y = y; - plan[i].x = x; - plan[i].neutral = neutral; - i++; - } - } - plann = i; -} - -GRID_INLET(0) { - SAME_TYPE(in,b); - SAME_TYPE(in,seed); - P da=in->dim, db=b->dim; - if (!db) RAISE("right inlet has no grid"); - if (!seed) RAISE("seed missing"); - if (db->n != 2) RAISE("right grid must have two dimensions"); - if (da->n < 2) RAISE("left grid has less than two dimensions"); - if (seed->dim->n != 0) RAISE("seed must be scalar"); - if (da->get(0) < db->get(0)) RAISE("grid too small (y): %d < %d", da->get(0), db->get(0)); - if (da->get(1) < db->get(1)) RAISE("grid too small (x): %d < %d", da->get(1), db->get(1)); - margy = (db->get(0)-1)/2; - margx = (db->get(1)-1)/2; - //if (a) post("for %p, a->dim=%s da=%s",this,a->dim->to_s(),da->to_s()); - if (!a || !a->dim->equal(da)) a=new Grid(da,in->nt); // with this condition it's 2% faster on Linux but takes more RAM. - //a=new Grid(da,in->nt); // with this condition it's 2% faster but takes more RAM. - int v[da->n]; COPY(v,da->v,da->n); - if (!wrap) {v[0]-=db->v[0]-1; v[1]-=db->v[1]-1;} - out=new GridOutlet(this,0,new Dim(da->n,v),in->nt); -} GRID_FLOW { - COPY((T *)*a+dex, data, n); -} GRID_FINISH { - make_plan((T)0); - long dbx = b->dim->get(1); - long dby = b->dim->get(0); - long day = out->dim->get(0); - long n = out->dim->prod(1); - long sx = out->dim->get(1)+dbx-1; - long sxc = out->dim->prod(2)*sx; - T buf[n]; - T buf2[sxc]; - T orh=0; - for (long ay=0; aymap(n,buf,*(T *)*seed); - for (long i=0; imap(sxc,buf2,rh); - } - fold->zip(n,buf,buf2+bx*out->dim->prod(2)); - orh=rh; - } - out->send(n,buf); - } - //a=0; // comment this out when trying to recycle a (use the dim->equal above) -} GRID_END - -GRID_INPUT(1,b) {} GRID_END - -\end class {install("#convolve",2,1);} - -/* ---------------------------------------------------------------- */ -/* "#scale_by" does quick scaling of pictures by integer factors */ -/*{ Dim[A,B,3] -> Dim[C,D,3] }*/ - -static void expect_scale_factor (P dim) { - if (dim->prod()!=1 && dim->prod()!=2) - RAISE("expecting only one or two numbers"); -} - -\class GridScaleBy : FObject { - \attr PtrGrid scale; // integer scale factor - int scaley; - int scalex; - \constructor (Grid *factor=0) { - scale.constrain(expect_scale_factor); - t_atom a[1]; SETFLOAT(a,2); - scale = factor?factor:new Grid(1,a,int32_e); - prepare_scale_factor(); - } - \grin 0 - \grin 1 - void prepare_scale_factor () { - scaley = ((int32 *)*scale)[0]; - scalex = ((int32 *)*scale)[scale->dim->prod()==1 ? 0 : 1]; - if (scaley<1) scaley=2; - if (scalex<1) scalex=2; - } -}; - -GRID_INLET(0) { - P a = in->dim; - expect_picture(a); - out=new GridOutlet(this,0,new Dim(a->get(0)*scaley,a->get(1)*scalex,a->get(2)),in->nt); - in->set_chunk(1); -} GRID_FLOW { - int rowsize = in->dim->prod(1); - T buf[rowsize*scalex]; - int chans = in->dim->get(2); - #define Z(z) buf[p+z]=data[i+z] - for (; n>0; data+=rowsize, n-=rowsize) { - int p=0; - #define LOOP(z) \ - for (int i=0; isend(rowsize*scalex,buf); - } - #undef Z -} GRID_END - -GRID_INPUT(1,scale) {prepare_scale_factor();} GRID_END - -\end class {install("#scale_by",2,1); add_creator("@scale_by");} - -// ---------------------------------------------------------------- -//{ Dim[A,B,3] -> Dim[C,D,3] } -\class GridDownscaleBy : FObject { - \attr PtrGrid scale; - \attr bool smoothly; - int scaley; - int scalex; - PtrGrid temp; - \constructor (Grid *factor=0, t_symbol *option=0) { - scale.constrain(expect_scale_factor); - t_atom a[1]; SETFLOAT(a,2); - scale = factor?factor:new Grid(1,a,int32_e); - prepare_scale_factor(); - smoothly = option==gensym("smoothly"); - } - \grin 0 - \grin 1 - void prepare_scale_factor () { - scaley = ((int32 *)*scale)[0]; - scalex = ((int32 *)*scale)[scale->dim->prod()==1 ? 0 : 1]; - if (scaley<1) scaley=2; - if (scalex<1) scalex=2; - } -}; - -GRID_INLET(0) { - P a = in->dim; - if (a->n!=3) RAISE("(height,width,chans) please"); - out=new GridOutlet(this,0,new Dim(a->get(0)/scaley,a->get(1)/scalex,a->get(2)),in->nt); - in->set_chunk(1); - // i don't remember why two rows instead of just one. - temp=new Grid(new Dim(2,in->dim->get(1)/scalex,in->dim->get(2)),in->nt); -} GRID_FLOW { - int rowsize = in->dim->prod(1); - int rowsize2 = temp->dim->prod(1); - T *buf = (T *)*temp; //!@#$ maybe should be something else than T ? - int xinc = in->dim->get(2)*scalex; - int y = dex / rowsize; - int chans=in->dim->get(2); - #define Z(z) buf[p+z]+=data[i+z] - if (smoothly) { - while (n>0) { - if (y%scaley==0) CLEAR(buf,rowsize2); - #define LOOP(z) \ - for (int i=0,p=0; pdim) { - op_div->map(rowsize2,buf,(T)(scalex*scaley)); - out->send(rowsize2,buf); - CLEAR(buf,rowsize2); - } - data+=rowsize; - n-=rowsize; - } - #undef Z - } else { - #define Z(z) buf[p+z]=data[i+z] - for (; n>0 && out->dim; data+=rowsize, n-=rowsize,y++) { - if (y%scaley!=0) continue; - #define LOOP(z) for (int i=0,p=0; pdim->get(2)) { - case 1: LOOP(1) {Z(0);} break; - case 2: LOOP(2) {Z(0);Z(1);} break; - case 3: LOOP(3) {Z(0);Z(1);Z(2);} break; - case 4: LOOP(4) {Z(0);Z(1);Z(2);Z(3);} break; - default:LOOP(chans) {for (int k=0; ksend(rowsize2,buf); - } - } - #undef Z -} GRID_END - -GRID_INPUT(1,scale) {prepare_scale_factor();} GRID_END - -\end class {install("#downscale_by",2,1); add_creator("@downscale_by");} - -//**************************************************************** -\class GridLayer : FObject { - PtrGrid r; - \constructor () {r.constrain(expect_rgb_picture);} - \grin 0 int - \grin 1 int -}; - -GRID_INLET(0) { - NOTEMPTY(r); - SAME_TYPE(in,r); - P a = in->dim; - expect_rgba_picture(a); - if (a->get(1)!=r->dim->get(1)) RAISE("same width please"); - if (a->get(0)!=r->dim->get(0)) RAISE("same height please"); - in->set_chunk(2); - out=new GridOutlet(this,0,r->dim); -} GRID_FLOW { - T *rr = ((T *)*r) + dex*3/4; - T foo[n*3/4]; -#define COMPUTE_ALPHA(c,a) \ - foo[j+c] = (data[i+c]*data[i+a] + rr[j+c]*(256-data[i+a])) >> 8 - for (int i=0,j=0; isend(n*3/4,foo); -} GRID_END - -GRID_INPUT(1,r) {} GRID_END - -\end class {install("#layer",2,1); add_creator("@layer");} - -// **************************************************************** -// pad1,pad2 only are there for 32-byte alignment -struct Line {int32 y1,x1,y2,x2,x,m,ox,pad2;}; - -static void expect_polygon (P d) { - if (d->n!=2 || d->get(1)!=2) RAISE("expecting Dim[n,2] polygon"); -} - -enum DrawMode {DRAW_FILL,DRAW_LINE,DRAW_POINT}; -enum OmitMode {OMIT_NONE,OMIT_LAST,OMIT_ODD}; -DrawMode convert(const t_atom &x, DrawMode *foo) { - t_symbol *s = convert(x,(t_symbol **)0); - if (s==gensym("fill")) return DRAW_FILL; - if (s==gensym("line")) return DRAW_LINE; - if (s==gensym("point")) return DRAW_POINT; - RAISE("unknown DrawMode '%s' (want fill or line)",s->s_name); -} -OmitMode convert(const t_atom &x, OmitMode *foo) { - t_symbol *s = convert(x,(t_symbol **)0); - if (s==gensym("none")) return OMIT_NONE; - if (s==gensym("last")) return OMIT_LAST; - if (s==gensym("odd")) return OMIT_ODD; - RAISE("unknown OmitMode '%s' (want none or last or odd)",s->s_name); -} -\class DrawPolygon : FObject { - \attr Numop *op; - \attr PtrGrid color; - \attr PtrGrid polygon; - \attr DrawMode draw; - \attr OmitMode omit; - PtrGrid color2; - PtrGrid lines; - int lines_start; - int lines_stop; - \constructor (Numop *op=op_put, Grid *color=0, Grid *polygon=0) { - draw=DRAW_FILL; - omit=OMIT_NONE; - this->color.constrain(expect_max_one_dim); - this->polygon.constrain(expect_polygon); - this->op = op; - if (color) this->color=color; - if (polygon) {this->polygon=polygon; init_lines();} - } - \grin 0 - \grin 1 - \grin 2 int32 - void init_lines(); - void changed(t_symbol *s) {init_lines();} -}; -void DrawPolygon::init_lines () { - if (!polygon) return; - int tnl = polygon->dim->get(0); - int nl = omit==OMIT_LAST ? tnl-1 : omit==OMIT_ODD ? (tnl+1)/2 : tnl; - lines=new Grid(new Dim(nl,8), int32_e); - Line *ld = (Line *)(int32 *)*lines; - int32 *pd = *polygon; - for (int i=0,j=0; ild[i].y2) memswap((int32 *)(ld+i)+0,(int32 *)(ld+i)+2,2); - long dy = ld[i].y2-ld[i].y1; - long dx = ld[i].x2-ld[i].x1; - ld[i].m = dy ? (dx<<16)/dy : 0; - } -} - -static int order_by_starting_scanline (const void *a, const void *b) { - return ((Line *)a)->y1 - ((Line *)b)->y1; -} - -static int order_by_column (const void *a, const void *b) { - return ((Line *)a)->x - ((Line *)b)->x; -} - -GRID_INLET(0) { - NOTEMPTY(color); - NOTEMPTY(polygon); - NOTEMPTY(lines); - SAME_TYPE(in,color); - if (in->dim->n!=3) RAISE("expecting 3 dimensions"); - if (in->dim->get(2)!=color->dim->get(0)) RAISE("image does not have same number of channels as stored color"); - out=new GridOutlet(this,0,in->dim,in->nt); - lines_start = lines_stop = 0; - in->set_chunk(1); - int nl = lines->dim->get(0); - qsort((int32 *)*lines,nl,sizeof(Line),order_by_starting_scanline); - int cn = color->dim->prod(); - color2=new Grid(new Dim(cn*16), color->nt); - for (int i=0; i<16; i++) COPY((T *)*color2+cn*i,(T *)*color,cn); -} GRID_FLOW { - int nl = lines->dim->get(0); - Line *ld = (Line *)(int32 *)*lines; - int f = in->dim->prod(1); - int y = dex/f; - int cn = color->dim->prod(); - T *cd = (T *)*color2; - while (n) { - while (lines_stop != nl && ld[lines_stop].y1<=y) { - Line &l = ld[lines_stop]; - l.x = l.x1 + (((y-l.y1)*l.m)>>16); - lines_stop++; - } - if (draw!=DRAW_POINT) { - int fudge = draw==DRAW_FILL?0:1; - for (int i=lines_start; isend(f,data); - } else { - int32 xl = in->dim->get(1); - T data2[f]; - COPY(data2,data,f); - for (int i=lines_start; i>16); - } - if (draw!=DRAW_POINT) qsort(ld+lines_start,lines_stop-lines_start,sizeof(Line),order_by_column); - if (draw==DRAW_FILL) { - for (int i=lines_start; i=xe) continue; /* !@#$ WHAT? */ - while (xe-xs>=16) {op->zip(16*cn,data2+cn*xs,cd); xs+=16;} - op->zip((xe-xs)*cn,data2+cn*xs,cd); - } - } else if (draw==DRAW_LINE) { - for (int i=lines_start; i=xl && xe>=xl)) continue; - xs = max(0,xs); - xe = min(xl,xe); - while (xe-xs>=16) {op->zip(16*cn,data2+cn*xs,cd); xs+=16;} - op->zip((xe-xs)*cn,data2+cn*xs,cd); - } - } else { - for (int i=lines_start; i=xl) continue; - op->zip((xe-xs)*cn,data2+cn*xs,cd); - } - lines_start=lines_stop; - } - out->send(f,data2); - } - n-=f; - data+=f; - y++; - } -} GRID_END - - -GRID_INPUT(1,color) {} GRID_END -GRID_INPUT(2,polygon) {init_lines();} GRID_END - -\end class {install("#draw_polygon",3,1); add_creator("@draw_polygon");} - -//**************************************************************** -static void expect_position(P d) { - if (d->n!=1) RAISE("position should have 1 dimension, not %d", d->n); - if (d->v[0]!=2) RAISE("position dim 0 should have 2 elements, not %d", d->v[0]); -} - -\class DrawImage : FObject { - \attr Numop *op; - \attr PtrGrid image; - \attr PtrGrid position; - \attr bool alpha; - \attr bool tile; - \constructor (Numop *op=op_put, Grid *image=0, Grid *position=0) { - alpha=false; tile=false; - this->op = op; - this->position.constrain(expect_position); - this->image.constrain(expect_picture); - if (image) this->image=image; - if (position) this->position=position; - else this->position=new Grid(new Dim(2),int32_e,true); - } - \grin 0 - \grin 1 - \grin 2 int32 - // draw row # ry of right image in row buffer buf, starting at xs - // overflow on both sides has to be handled automatically by this method - template void draw_segment(T *obuf, T *ibuf, int ry, int x0); -}; - -#define COMPUTE_ALPHA(c,a) obuf[j+(c)] = ibuf[j+(c)] + (rbuf[a])*(obuf[j+(c)]-ibuf[j+(c)])/256; -#define COMPUTE_ALPHA4(b) \ - COMPUTE_ALPHA(b+0,b+3); \ - COMPUTE_ALPHA(b+1,b+3); \ - COMPUTE_ALPHA(b+2,b+3); \ - obuf[b+3] = rbuf[b+3] + (255-rbuf[b+3])*(ibuf[j+b+3])/256; - -template void DrawImage::draw_segment(T *obuf, T *ibuf, int ry, int x0) { - if (ry<0 || ry>=image->dim->get(0)) return; // outside of image - int sx = in[0]->dim->get(1), rsx = image->dim->get(1); - int sc = in[0]->dim->get(2), rsc = image->dim->get(2); - T *rbuf = (T *)*image + ry*rsx*rsc; - if (x0>sx || x0<=-rsx) return; // outside of buffer - int n=rsx; - if (x0+n>sx) n=sx-x0; - if (x0<0) { rbuf-=rsc*x0; n+=x0; x0=0; } - if (alpha && rsc==4 && sc==3) { // RGB by RGBA //!@#$ optimise - int j=sc*x0; - for (; n; n--, rbuf+=4, j+=3) { - op->zip(sc,obuf+j,rbuf); COMPUTE_ALPHA(0,3); COMPUTE_ALPHA(1,3); COMPUTE_ALPHA(2,3); - } - } else if (alpha && rsc==4 && sc==4) { // RGBA by RGBA - op->zip(n*rsc,obuf+x0*rsc,rbuf); - int j=sc*x0; - for (; n>=4; n-=4, rbuf+=16, j+=16) { - COMPUTE_ALPHA4(0);COMPUTE_ALPHA4(4); - COMPUTE_ALPHA4(8);COMPUTE_ALPHA4(12); - } - for (; n; n--, rbuf+=4, j+=4) { - COMPUTE_ALPHA4(0); - } - } else { // RGB by RGB, etc - op->zip(n*rsc,obuf+sc*x0,rbuf); - } -} - -GRID_INLET(0) { - NOTEMPTY(image); - NOTEMPTY(position); - SAME_TYPE(in,image); - if (in->dim->n!=3) RAISE("expecting 3 dimensions"); - if (image->dim->n!=3) RAISE("expecting 3 dimensions in right_hand"); - int lchan = in->dim->get(2); - int rchan = image->dim->get(2); - if (alpha && rchan!=4) { - RAISE("alpha mode works only with 4 channels in right_hand"); - } - if (lchan != rchan-(alpha?1:0) && lchan != rchan) { - RAISE("right_hand has %d channels, alpha=%d, left_hand has %d, expecting %d or %d", - rchan, alpha?1:0, lchan, rchan-(alpha?1:0), rchan); - } - out=new GridOutlet(this,0,in->dim,in->nt); - in->set_chunk(1); -} GRID_FLOW { - int f = in->dim->prod(1); - int y = dex/f; - if (position->nt != int32_e) RAISE("position has to be int32"); - int py = ((int32*)*position)[0], rsy = image->dim->v[0]; - int px = ((int32*)*position)[1], rsx = image->dim->v[1], sx=in->dim->get(1); - for (; n; y++, n-=f, data+=f) { - int ty = div2(y-py,rsy); - if (tile || ty==0) { - T data2[f]; - COPY(data2,data,f); - if (tile) { - for (int x=px-div2(px+rsx-1,rsx)*rsx; xsend(f,data2); - } else { - out->send(f,data); - } - } -} GRID_END - -GRID_INPUT(1,image) {} GRID_END -GRID_INPUT(2,position) {} GRID_END - -\end class {install("#draw_image",3,1); add_creator("@draw_image");} - -//**************************************************************** -// Dim[*A],Dim[*B],Dim[C,size(A)-size(B)] -> Dim[*A] - -/* NOT FINISHED */ -\class GridDrawPoints : FObject { - \attr Numop *op; - \attr PtrGrid color; - \attr PtrGrid points; - \grin 0 - \grin 1 int32 - \grin 2 int32 - \constructor (Numop *op=op_put, Grid *color=0, Grid *points=0) { - this->op = op; - if (color) this->color=color; - if (points) this->points=points; - } -}; - -GRID_INPUT(1,color) {} GRID_END -GRID_INPUT(2,points) {} GRID_END - -GRID_INLET(0) { - NOTEMPTY(color); - NOTEMPTY(points); - SAME_TYPE(in,color); - out=new GridOutlet(this,0,in->dim,in->nt); - if (points->dim->n!=2) RAISE("points should be a 2-D grid"); - if (points->dim->v[1] != in->dim->n - color->dim->n) - RAISE("wrong number of dimensions"); - in->set_chunk(0); -} GRID_FLOW { - long m = points->dim->v[1]; - long cn = in->dim->prod(-color->dim->n); /* size of color (RGB=3, greyscale=1, ...) */ - int32 *pdata = (int32 *)points->data; - T *cdata = (T *)color->data; - for (long i=0; im; k++) off = off*in->dim->v[k] + pdata[i*points->dim->v[1]+k]; - off *= cn; - for (long j=0; jsend(data); -} GRID_END -\end class {install("#draw_points",3,1);} - -//**************************************************************** -\class GridNoiseGateYuvs : FObject { - \grin 0 - int thresh; - \decl 1 float(int v); - \constructor (int v=0) {thresh=v;} -}; - -GRID_INLET(0) { - if (in->dim->n!=3) RAISE("requires 3 dimensions: dim(y,x,3)"); - if (in->dim->v[2]!=3) RAISE("requires 3 channels"); - out=new GridOutlet(this,0,in->dim,in->nt); - in->set_chunk(2); -} GRID_FLOW { - T tada[n]; - for (long i=0; isend(n,tada); -} GRID_END - -\def 1 float(int v) {thresh=v;} -\end class {install("#noise_gate_yuvs",2,1);} - -//**************************************************************** - -\class GridPack : FObject { - int n; - PtrGrid a; - \constructor (int n=2, NumberTypeE nt=int32_e) { - if (n<1) RAISE("n=%d must be at least 1",n); - if (n>32) RAISE("n=%d is too many?",n); - a = new Grid(new Dim(n),nt,true); - this->n=n; - bself->ninlets_set(this->n); - } - \decl void _n_float (int inlet, float f); - \decl void _n_list (int inlet, float f); - \decl 0 bang (); - //\grin 0 -}; -\def void _n_float (int inlet, float f) { -#define FOO(T) ((T *)*a)[inlet] = (T)f; -TYPESWITCH(a->nt,FOO,); -#undef FOO - _0_bang(argc,argv); -} -\def void _n_list (int inlet, float f) {_n_float(argc,argv,inlet,f);} -\def 0 bang () { - out=new GridOutlet(this,0,a->dim,a->nt); -#define FOO(T) out->send(n,(T *)*a); -TYPESWITCH(a->nt,FOO,); -#undef FOO -} -\end class {install("#pack",1,1); add_creator("@pack");} - -\class GridUnpack : FObject { - int n; - \constructor (int n=2) { - if (n<1) RAISE("n=%d must be at least 1",n); - if (n>32) RAISE("n=%d is too many?",n); - this->n=n; - bself->noutlets_set(this->n); - } - \grin 0 -}; -GRID_INLET(0) { - if (in->dim->n!=1) RAISE("expect one dimension"); - if (in->dim->v[0]!=this->n) RAISE("expecting dim(%ld), got dim(%ld)",this->n,in->dim->v[0]); - in->set_chunk(0); -} GRID_FLOW { - for (int i=n-1; i>=0; i--) outlet_float(bself->outlets[i],(t_float)data[i]); -} GRID_END -\end class {install("#unpack",1,0);} - -//**************************************************************** - -\class GridRotatificator : FObject { - int angle; - int from, to, n; - \decl 0 float (int scale); - \decl 0 axis (int from, int to, int n); - \constructor (int from=0, int to=1, int n=2) { - angle=0; - _0_axis(0,0,from,to,n); - } - \decl 1 float(int angle); -}; -\def 0 float (int scale) { - int32 rotator[n*n]; - for (int i=0; i=n) RAISE("from-axis number incorrect"); - if (to <0 || to >=n) RAISE( "to-axis number incorrect"); - this->from = from; - this-> to = to; - this-> n = n; -} -\def 1 float(int angle) {this->angle = angle;} -\end class {install("#rotatificator",2,1);} - -static void expect_min_one_dim (P d) { - if (d->n<1) RAISE("expecting at least one dimension, got %s",d->to_s());} - -#define OP(x) op_dict[string(#x)] -\class GridClusterAvg : FObject { - \attr int numClusters; - \attr PtrGrid r; - \attr PtrGrid sums; - \attr PtrGrid counts; - \constructor (int v) {_1_float(0,0,v); r.constrain(expect_min_one_dim);} - \decl 1 float (int v); - \grin 0 int32 - \grin 2 - template void make_stats (long n, int32 *ldata, T *rdata) { - int32 chans = r->dim->v[r->dim->n-1]; - T *sdata = (T *)*sums; - int32 *cdata = (int32 *)*counts; - for (int i=0; i=numClusters) RAISE("value out of range in left grid"); - OP(+)->zip(chans,sdata+(*ldata)*chans,rdata); - cdata[*ldata]++; - } - for (int i=0; imap(chans,sdata+i*chans,(T)cdata[i]); - out = new GridOutlet(this,1,counts->dim,counts->nt); - out->send(counts->dim->prod(),(int32 *)*counts); - out = new GridOutlet(this,0,sums->dim,sums->nt); - out->send(sums->dim->prod(),(T *)*sums); - } -}; - -GRID_INLET(0) { - NOTEMPTY(r); - int32 v[r->dim->n]; - COPY(v,r->dim->v,r->dim->n-1); - v[r->dim->n-1]=1; - P t = new Dim(r->dim->n,v); - if (!t->equal(in->dim)) RAISE("left %s must be equal to right %s except last dimension should be 1",in->dim->to_s(),r->dim->to_s()); - in->set_chunk(0); - int32 w[2] = {numClusters,r->dim->v[r->dim->n-1]}; - sums = new Grid(new Dim(2,w),r->nt, true); - counts = new Grid(new Dim(1,w),int32_e,true); -} GRID_FLOW { - #define FOO(U) make_stats(n,data,(U *)*r); - TYPESWITCH(r->nt,FOO,) - #undef FOO -} GRID_END -\def 1 float (int v) {numClusters = v;} -GRID_INPUT(2,r) { -} GRID_END - -\end class {install("#cluster_avg",3,2);} - -//**************************************************************** - -void startup_flow_objects () { - op_add = OP(+); - op_sub = OP(-); - op_mul = OP(*); - op_shl = OP(<<); - op_mod = OP(%); - op_and = OP(&); - op_div = OP(/); - op_put = OP(put); - \startall -} diff --git a/externals/gridflow/src/classes2.cxx b/externals/gridflow/src/classes2.cxx deleted file mode 100644 index 6ca9a62a..00000000 --- a/externals/gridflow/src/classes2.cxx +++ /dev/null @@ -1,1183 +0,0 @@ -/* - $Id: flow_objects.c 4097 2008-10-03 19:49:03Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#ifdef DESIRE -#include "desire.h" -#else -extern "C" { -#include "bundled/g_canvas.h" -#include "bundled/m_imp.h" -extern t_class *text_class; -}; -#endif -#include -#include -#include -#include - -typedef int (*comparator_t)(const void *, const void *); - -#ifndef DESIREDATA -struct _outconnect { - struct _outconnect *next; - t_pd *to; -}; -struct _outlet { - t_object *owner; - struct _outlet *next; - t_outconnect *connections; - t_symbol *sym; -}; -#endif - -//**************************************************************** - -struct ArgSpec { - t_symbol *name; - t_symbol *type; - t_atom defaultv; -}; - -\class Args : FObject { - ArgSpec *sargv; - int sargc; - \constructor (...) { - sargc = argc; - sargv = new ArgSpec[argc]; - for (int i=0; inoutlets_set(sargc); - } - ~Args () {delete[] sargv;} - \decl 0 bang (); - \decl 0 loadbang (); - void process_args (int argc, t_atom *argv); -}; -/* get the owner of the result of canvas_getenv */ -static t_canvas *canvas_getabstop(t_canvas *x) { - while (!x->gl_env) if (!(x = x->gl_owner)) bug("t_canvasenvironment", x); - return x; -} -\def 0 bang () {post("%s shouldn't bang [args] anymore.",canvas_getabstop(bself->mom)->gl_name->s_name);} -void outlet_anything2 (t_outlet *o, int argc, t_atom *argv) { - if (!argc) outlet_bang(o); - else if (argv[0].a_type==A_SYMBOL) outlet_anything(o,argv[0].a_symbol,argc-1,argv+1); - else if (argv[0].a_type==A_FLOAT && argc==1) outlet_float(o,argv[0].a_float); - else outlet_anything(o,&s_list,argc,argv); -} -void pd_anything2 (t_pd *o, int argc, t_atom *argv) { - if (!argc) pd_bang(o); - else if (argv[0].a_type==A_SYMBOL) pd_typedmess(o,argv[0].a_symbol,argc-1,argv+1); - else if (argv[0].a_type==A_FLOAT && argc==1) pd_float(o,argv[0].a_float); - else pd_typedmess(o,&s_list,argc,argv); -} -\def 0 loadbang () { - t_canvasenvironment *env = canvas_getenv(bself->mom); - int ac = env->ce_argc; - t_atom av[ac]; - for (int i=0; ice_argv[i]; - //ac = handle_braces(ac,av); - t_symbol *comma = gensym(","); - int j; - for (j=0; joutlets[sargc],j-k,av+k); - t_text *t = (t_text *)canvas_getabstop(bself->mom); - if (!t->te_inlet) RAISE("can't send init-messages, because object has no [inlet]"); - pd_anything2((t_pd *)t->te_inlet,j-k,av+k); - } -} -void Args::process_args (int argc, t_atom *argv) { - t_canvas *canvas = canvas_getrootfor(bself->mom); - t_symbol *wildcard = gensym("*"); - for (int i=sargc-1; i>=0; i--) { - t_atom *v; - if (i>=argc) { - if (sargv[i].defaultv.a_type != A_NULL) { - v = &sargv[i].defaultv; - } else if (sargv[i].name!=wildcard) { - pd_error(canvas,"missing argument $%d named \"%s\"", i+1,sargv[i].name->s_name); - continue; - } - } else v = &argv[i]; - if (sargv[i].name==wildcard) { - if (argc-i>0) outlet_list(bself->outlets[i],&s_list,argc-i,argv+i); - else outlet_bang(bself->outlets[i]); - } else { - if (v->a_type==A_LIST) { - t_binbuf *b = (t_binbuf *)v->a_gpointer; - outlet_list(bself->outlets[i],&s_list,binbuf_getnatom(b),binbuf_getvec(b)); - } else if (v->a_type==A_SYMBOL) outlet_symbol(bself->outlets[i],v->a_symbol); - else outlet_anything2(bself->outlets[i],1,v); - } - } - if (argc>sargc && sargv[sargc-1].name!=wildcard) pd_error(canvas,"warning: too many args (got %d, want %d)", argc, sargc); -} -\end class {install("args",1,1);} - -//**************************************************************** - -namespace { -template void swap (T &a, T &b) {T c; c=a; a=b; b=c;} -}; - -\class ListReverse : FObject { - \constructor () {} - \decl 0 list(...); -}; -\def 0 list (...) { - for (int i=(argc-1)/2; i>=0; i--) swap(argv[i],argv[argc-i-1]); - outlet_list(bself->te_outlet,&s_list,argc,argv); -} -\end class {install("listreverse",1,1);} - -\class ListFlatten : FObject { - std::vector contents; - \constructor () {} - \decl 0 list(...); - void traverse (int argc, t_atom2 *argv) { - for (int i=0; ite_outlet,&s_list,contents.size(),&contents[0]); - contents.clear(); - -} -\end class {install("listflatten",1,1);} - -// does not do recursive comparison of lists. -static bool atom_eq (t_atom &a, t_atom &b) { - if (a.a_type!=b.a_type) return false; - if (a.a_type==A_FLOAT) return a.a_float ==b.a_float; - if (a.a_type==A_SYMBOL) return a.a_symbol ==b.a_symbol; - if (a.a_type==A_POINTER) return a.a_gpointer==b.a_gpointer; - if (a.a_type==A_LIST) return a.a_gpointer==b.a_gpointer; - RAISE("don't know how to compare elements of type %d",a.a_type); -} - -\class ListFind : FObject { - int ac; - t_atom *at; - ~ListFind() {if (at) delete[] at;} - \constructor (...) {ac=0; at=0; _1_list(argc,argv);} - \decl 0 list(...); - \decl 1 list(...); - \decl 0 float(float f); - \decl 0 symbol(t_symbol *s); -}; -\def 1 list (...) { - if (at) delete[] at; - ac = argc; - at = new t_atom[argc]; - for (int i=0; ioutlets[0],i==ac?-1:i); -} -\def 0 float (float f) { - int i=0; for (; ioutlets[0],i==ac?-1:i); -} -\def 0 symbol (t_symbol *s) { - int i=0; for (; ioutlets[0],i==ac?-1:i); -} -//doc:_1_list,"list to search into" -//doc:_0_float,"float to find in that list" -//doc_out:_0_float,"position of the incoming float in the stored list" -\end class {install("listfind",2,1);} - -void outlet_atom (t_outlet *self, t_atom *av) { - if (av->a_type==A_FLOAT) outlet_float( self,av->a_float); else - if (av->a_type==A_SYMBOL) outlet_symbol( self,av->a_symbol); else - if (av->a_type==A_POINTER) outlet_pointer(self,av->a_gpointer); else - outlet_list(self,gensym("list"),1,av); -} - -\class ListRead : FObject { /* sounds like tabread */ - int ac; - t_atom *at; - ~ListRead() {if (at) delete[] at;} - \constructor (...) {ac=0; at=0; _1_list(argc,argv);} - \decl 0 float(float f); - \decl 1 list(...); -}; -\def 0 float(float f) { - int i = int(f); - if (i<0) i+=ac; - if (i<0 || i>=ac) {outlet_bang(bself->outlets[0]); return;} /* out-of-range */ - outlet_atom(bself->outlets[0],&at[i]); -} -\def 1 list (...) { - if (at) delete[] at; - ac = argc; - at = new t_atom[argc]; - for (int i=0; i ninlets_set(1+nmosusses); - bself->noutlets_set(1+nmosusses); - } - ~Range () {delete[] mosusses;} - \decl 0 float(float f); - \decl 0 list(float f); - \decl void _n_float(int i, float f); -}; -\def 0 list(float f) {_0_float(argc,argv,f);} -\def 0 float(float f) { - int i; for (i=0; ioutlets[i],f); -} - // precedence problem in dispatcher... does this problem still exist? -\def void _n_float(int i, float f) {if (!i) _0_float(argc,argv,f); else mosusses[i-1] = f;} -\end class {install("range",1,1);} - -//**************************************************************** - -string ssprintf(const char *fmt, ...) { - std::ostringstream os; - va_list va; - va_start(va,fmt); - voprintf(os,fmt,va); - va_end(va); - return os.str(); -} - -\class GFPrint : FObject { - t_symbol *prefix; - t_pd *gp; - //t_symbol *rsym; - \constructor (t_symbol *s=0) { - //rsym = gensym(const_cast(ssprintf("gf.print:%08x",this).data())); // not in use atm. - prefix=s?s:gensym("print"); - t_atom a[1]; - SETSYMBOL(a,prefix); - pd_typedmess(&pd_objectmaker,gensym("#print"),1,a); - gp = pd_newest(); - SETPOINTER(a,(t_gpointer *)bself); - //pd_typedmess(gp,gensym("dest"),1,a); - } - ~GFPrint () { - //pd_unbind((t_pd *)bself,rsym); - pd_free(gp); - } - \decl 0 grid(...); - \decl void anything (...); -}; -std::ostream &operator << (std::ostream &self, const t_atom &a) { - switch (a.a_type) { - case A_FLOAT: self << a.a_float; break; - case A_SYMBOL: self << a.a_symbol->s_name; break; // i would rather show backslashes here... - case A_DOLLSYM: self << a.a_symbol->s_name; break; // for real, it's the same thing as A_SYMBOL in pd >= 0.40 - case A_POINTER: self << "\\p(0x" << std::hex << a.a_gpointer << std::dec << ")"; break; - case A_COMMA: self << ","; break; - case A_SEMI: self << ";"; break; - case A_DOLLAR: self << "$" << a.a_w.w_index; break; - case A_LIST: { - t_list *b = (t_list *)a.a_gpointer; - int argc = binbuf_getnatom(b); - t_atom *argv = binbuf_getvec(b); - self << "("; - for (int i=0; is_name << ":"; - if (argv[0]==gensym("_0_list") && argc>=2 && argv[1].a_type==A_FLOAT) { - // don't show the selector. - } else if (argv[0]==gensym("_0_list") && argc==2 && argv[1].a_type==A_SYMBOL) { - text << " symbol"; - } else if (argv[0]==gensym("_0_list") && argc==2 && argv[1].a_type==A_POINTER) { - text << " pointer"; - } else if (argv[0]==gensym("_0_list") && argc==1) { - text << " bang"; - } else { - text << " " << argv[0].a_symbol->s_name+3; // as is - } - for (int i=1; i(ssprintf("display:%08x",this).data())); - pd_typedmess(&pd_objectmaker,gensym("#print"),0,0); - gp = pd_newest(); - t_atom a[1]; - SETFLOAT(a,20); - pd_typedmess(gp,gensym("maxrows"),1,a); - text << "..."; - pd_bind((t_pd *)bself,rsym); - SETPOINTER(a,(t_gpointer *)bself); - pd_typedmess(gp,gensym("dest"),1,a); - clock = clock_new((void *)this,(void(*)())display_update); - } - ~Display () { - pd_unbind((t_pd *)bself,rsym); - pd_free(gp); - if (clock) clock_free(clock); - } - \decl void anything (...); - \decl 0 set_size(int sy, int sx); - \decl 0 grid(...); - \decl 0 very_long_name_that_nobody_uses(...); - void show() { - std::ostringstream quoted; - // def quote(text) "\"" + text.gsub(/["\[\]\n\$]/m) {|x| if x=="\n" then "\\n" else "\\"+x end } + "\"" end - std::string ss = text.str(); - const char *s = ss.data(); - int n = ss.length(); - for (int i=0;is_name,bself->te_xpix,bself->te_ypix,selected?"#0000ff":"#000000",canvas,ss.data()); - } -}; -static void display_getrectfn(t_gobj *x, t_glist *glist, int *x1, int *y1, int *x2, int *y2) { - BFObject *bself = (BFObject*)x; Display *self = (Display *)bself->self; self->canvas = glist; - *x1 = bself->te_xpix-1; - *y1 = bself->te_ypix-1; - *x2 = bself->te_xpix+1+self->sx; - *y2 = bself->te_ypix+1+self->sy; -} -static void display_displacefn(t_gobj *x, t_glist *glist, int dx, int dy) { - BFObject *bself = (BFObject*)x; Display *self = (Display *)bself->self; self->canvas = glist; - bself->te_xpix+=dx; - bself->te_ypix+=dy; - self->canvas = glist_getcanvas(glist); - self->show(); - canvas_fixlinesfor(glist, (t_text *)x); -} -static void display_selectfn(t_gobj *x, t_glist *glist, int state) { - BFObject *bself = (BFObject*)x; Display *self = (Display *)bself->self; self->canvas = glist; - self->selected=!!state; - sys_vgui(".x%x.c itemconfigure %s -outline %s\n",glist_getcanvas(glist),self->rsym->s_name,self->selected?"#0000ff":"#000000"); -} -static void display_deletefn(t_gobj *x, t_glist *glist) { - BFObject *bself = (BFObject*)x; Display *self = (Display *)bself->self; self->canvas = glist; - if (self->vis) sys_vgui(".x%x.c delete %s %sTEXT\n",glist_getcanvas(glist),self->rsym->s_name,self->rsym->s_name); - canvas_deletelinesfor(glist, (t_text *)x); -} -static void display_visfn(t_gobj *x, t_glist *glist, int flag) { - BFObject *bself = (BFObject*)x; Display *self = (Display *)bself->self; self->canvas = glist; - self->vis = !!flag; - display_update(self); -} -static void display_update(void *x) { - Display *self = (Display *)x; - if (self->vis) self->show(); -} -\def 0 set_size(int sy, int sx) {this->sy=sy; this->sx=sx;} -\def void anything (...) { - string sel = string(argv[0]).data()+3; - text.str(""); - if (sel != "float") {text << sel; if (argc>1) text << " ";} - long col = text.str().length(); - char buf[MAXPDSTRING]; - for (int i=1; i56) {text << "\\\\\n"; col=0;} - } - } - clock_delay(clock,0); -} -\def 0 grid(...) { - text.str(""); - pd_typedmess(gp,gensym("grid"),argc,argv); - clock_delay(clock,0); -} -\def 0 very_long_name_that_nobody_uses(...) { - if (text.str().length()) text << "\n"; - for (int i=0; ibfclass; - t_widgetbehavior *wb = new t_widgetbehavior; - wb->w_getrectfn = display_getrectfn; - wb->w_displacefn = display_displacefn; - wb->w_selectfn = display_selectfn; - wb->w_activatefn = 0; - wb->w_deletefn = display_deletefn; - wb->w_visfn = display_visfn; - wb->w_clickfn = 0; - class_setwidget(qlass,wb); - sys_gui("proc display_update {self x y fg bg outline font canvas text} { \n\ - $canvas delete ${self}TEXT \n\ - $canvas create text [expr $x+2] [expr $y+2] -fill $fg -font $font -text $text -anchor nw -tag ${self}TEXT \n\ - foreach {x1 y1 x2 y2} [$canvas bbox ${self}TEXT] {} \n\ - incr x -1 \n\ - incr y -1 \n\ - set sx [expr $x2-$x1+2] \n\ - set sy [expr $y2-$y1+4] \n\ - $canvas delete ${self} \n\ - $canvas create rectangle $x $y [expr $x+$sx] [expr $y+$sy] -fill $bg -tags $self -outline $outline \n\ - $canvas create rectangle $x $y [expr $x+7] $y -fill red -tags $self -outline $outline \n\ - $canvas lower $self ${self}TEXT \n\ - pd \"$self set_size $sy $sx;\" \n\ - }\n"); -#endif -} -//#endif // ndef HAVE_DESIREDATA - -//**************************************************************** - -\class UnixTime : FObject { - \constructor () {} - \decl 0 bang (); -}; -\def 0 bang () { - timeval tv; - gettimeofday(&tv,0); - time_t t = time(0); - struct tm *tmp = localtime(&t); - if (!tmp) RAISE("localtime: %s",strerror(errno)); - char tt[MAXPDSTRING]; - strftime(tt,MAXPDSTRING,"%a %b %d %H:%M:%S %Z %Y",tmp); - t_atom a[6]; - SETFLOAT(a+0,tmp->tm_year+1900); - SETFLOAT(a+1,tmp->tm_mon-1); - SETFLOAT(a+2,tmp->tm_mday); - SETFLOAT(a+3,tmp->tm_hour); - SETFLOAT(a+4,tmp->tm_min); - SETFLOAT(a+5,tmp->tm_sec); - t_atom b[3]; - SETFLOAT(b+0,tv.tv_sec/86400); - SETFLOAT(b+1,mod(tv.tv_sec,86400)); - SETFLOAT(b+2,tv.tv_usec); - outlet_anything(bself->outlets[2],&s_list,6,a); - outlet_anything(bself->outlets[1],&s_list,3,b); - send_out(0,strlen(tt),tt); -} - -\end class UnixTime {install("unix_time",1,3);} - - -//**************************************************************** - -/* if using a DB-25 female connector as found on a PC, then the pin numbering is like: - 13 _____ 1 - 25 \___/ 14 - 1 = STROBE = the clock line is a square wave, often at 9600 Hz, - which determines the data rate in usual circumstances. - 2..9 = D0..D7 = the eight ordinary data bits - 10 = -ACK (status bit 6 ?) - 11 = BUSY (status bit 7) - 12 = PAPER_END (status bit 5) - 13 = SELECT (status bit 4 ?) - 14 = -AUTOFD - 15 = -ERROR (status bit 3 ?) - 16 = -INIT - 17 = -SELECT_IN - 18..25 = GROUND -*/ - -//#include -#define LPCHAR 0x0601 -#define LPCAREFUL 0x0609 /* obsoleted??? wtf? */ -#define LPGETSTATUS 0x060b /* return LP_S(minor) */ -#define LPGETFLAGS 0x060e /* get status flags */ - -#include - -struct ParallelPort; -void ParallelPort_call(ParallelPort *self); -\class ParallelPort : FObject { - FILE *f; - int fd; - int status; - int flags; - bool manually; - t_clock *clock; - ~ParallelPort () {if (clock) clock_free(clock); if (f) fclose(f);} - \constructor (string port, bool manually=0) { - f = fopen(port.data(),"r+"); - if (!f) RAISE("open %s: %s",port.data(),strerror(errno)); - fd = fileno(f); - status = 0xdeadbeef; - flags = 0xdeadbeef; - this->manually = manually; - clock = manually ? 0 : clock_new(this,(void(*)())ParallelPort_call); - clock_delay(clock,0); - } - void call (); - \decl 0 float (float x); - \decl 0 bang (); -}; -\def 0 float (float x) { - uint8 foo = (uint8) x; - fwrite(&foo,1,1,f); - fflush(f); -} -void ParallelPort_call(ParallelPort *self) {self->call();} -void ParallelPort::call() { - int flags; - if (ioctl(fd,LPGETFLAGS,&flags)<0) post("ioctl: %s",strerror(errno)); - if (this->flags!=flags) outlet_float(bself->outlets[2],flags); - this->flags = flags; - int status; - if (ioctl(fd,LPGETSTATUS,&status)<0) post("ioctl: %s",strerror(errno)); - if (this->status!=status) outlet_float(bself->outlets[1],status); - this->status = status; - if (clock) clock_delay(clock,2000); -} -\def 0 bang () {status = flags = 0xdeadbeef; call();} -//outlet 0 reserved (future use) -\end class {install("parallel_port",1,3);} - -//**************************************************************** - -\class Route2 : FObject { - int nsels; - t_symbol **sels; - ~Route2() {if (sels) delete[] sels;} - \constructor (...) {nsels=0; sels=0; _1_list(argc,argv); bself->noutlets_set(1+nsels);} - \decl void anything(...); - \decl 1 list(...); -}; -\def void anything(...) { - t_symbol *sel = gensym(argv[0].a_symbol->s_name+3); - int i=0; - for (i=0; ioutlets[i],sel,argc-1,argv+1); -} -\def 1 list(...) { - for (int i=0; i int sgn(T a, T b=0) {return ab;} - -\class Shunt : FObject { - int n; - \attr int index; - \attr int mode; - \attr int hi; - \attr int lo; - \constructor (int n=2, int i=0) { - this->n=n; - this->hi=n-1; - this->lo=0; - this->mode=0; - this->index=i; - bself->noutlets_set(n); - } - \decl void anything(...); - \decl 1 float(int i); -}; -\def void anything(...) { - t_symbol *sel = gensym(argv[0].a_symbol->s_name+3); - outlet_anything(bself->outlets[index],sel,argc-1,argv+1); - if (mode) { - index += sgn(mode); - if (indexhi) { - int k = max(hi-lo+1,0); - int m = gf_abs(mode); - if (m==1) index = mod(index-lo,k)+lo; else {mode=-mode; index+=mode;} - } - } -} -\def 1 float(int i) {index = mod(i,n);} -\end class {install("shunt",2,0);} - -struct Receives; -struct ReceivesProxy { - t_pd x_pd; - Receives *parent; - t_symbol *suffix; -}; -t_class *ReceivesProxy_class; - -\class Receives : FObject { - int ac; - ReceivesProxy **av; - t_symbol *prefix; - t_symbol *local (t_symbol *suffix) {return gensym((string(prefix->s_name) + string(suffix->s_name)).data());} - \constructor (t_symbol *prefix=&s_, ...) { - this->prefix = prefix==gensym("empty") ? &s_ : prefix; - int n = min(1,argc); - do_bind(argc-n,argv+n); - } - \decl 0 bang (); - \decl 0 symbol (t_symbol *s); - \decl 0 list (...); - void do_bind (int argc, t_atom2 *argv) { - ac = argc; - av = new ReceivesProxy *[argc]; - for (int i=0; iparent = this; - av[i]->suffix = argv[i]; - pd_bind( (t_pd *)av[i],local(av[i]->suffix)); - } - } - void do_unbind () { - for (int i=0; isuffix)); - pd_free((t_pd *)av[i]); - } - delete[] av; - } - ~Receives () {do_unbind();} -}; -\def 0 bang () {_0_list(0,0);} -\def 0 symbol (t_symbol *s) {t_atom2 a[1]; SETSYMBOL(a,s); _0_list(1,a);} -\def 0 list (...) { - do_unbind(); - do_bind(argc,argv); -} -void ReceivesProxy_anything (ReceivesProxy *self, t_symbol *s, int argc, t_atom *argv) { - outlet_symbol( self->parent->bself->outlets[1],self->suffix); - outlet_anything(self->parent->bself->outlets[0],s,argc,argv); -} -\end class { - install("receives",1,2); - ReceivesProxy_class = class_new(gensym("receives.proxy"),0,0,sizeof(ReceivesProxy),CLASS_PD|CLASS_NOINLET, A_NULL); - class_addanything(ReceivesProxy_class,(t_method)ReceivesProxy_anything); -} - -/* this can't report on bang,float,symbol,pointer,list because zgetfn can't either */ -\class ClassExists : FObject { - \constructor () {} - \decl void _0_symbol(t_symbol *s); -}; -\def void _0_symbol(t_symbol *s) { - outlet_float(bself->outlets[0],!!zgetfn(&pd_objectmaker,s)); -} -\end class {install("class_exists",1,1);} - -\class ListEqual : FObject { - t_list *list; - \constructor (...) {list=0; _1_list(argc,argv);} - \decl 0 list (...); - \decl 1 list (...); -}; -\def 1 list (...) { - if (list) list_free(list); - list = list_new(argc,argv); -} -\def 0 list (...) { - if (binbuf_getnatom(list) != argc) {outlet_float(bself->outlets[0],0); return;} - t_atom2 *at = (t_atom2 *)binbuf_getvec(list); - for (int i=0; ioutlets[0],0); return;} - outlet_float(bself->outlets[0],1); -} -\end class {install("list.==",2,1);} - -//**************************************************************** -//#ifdef UNISTD -#include -#include -#include -#include -#include -//#endif -#if defined (__APPLE__) || defined (__FreeBSD__) -#define HZ CLK_TCK -#endif - -uint64 cpu_hertz; -int uint64_compare(uint64 &a, uint64 &b) {return ab;} - -\class UserTime : FObject { - clock_t time; - \constructor () {_0_bang(argc,argv);} - \decl 0 bang (); - \decl 1 bang (); -}; -\def 0 bang () {struct tms t; times(&t); time = t.tms_utime;} -\def 1 bang () {struct tms t; times(&t); outlet_float(bself->outlets[0],(t.tms_utime-time)*1000/HZ);} -\end class {install("usertime",2,1);} -\class SystemTime : FObject { - clock_t time; - \constructor () {_0_bang(argc,argv);} - \decl 0 bang (); - \decl 1 bang (); -}; -\def 0 bang () {struct tms t; times(&t); time = t.tms_stime;} -\def 1 bang () {struct tms t; times(&t); outlet_float(bself->outlets[0],(t.tms_stime-time)*1000/HZ);} -\end class {install("systemtime",2,1);} -\class TSCTime : FObject { - uint64 time; - \constructor () {_0_bang(argc,argv);} - \decl 0 bang (); - \decl 1 bang (); -}; -\def 0 bang () {time=rdtsc();} -\def 1 bang () {outlet_float(bself->outlets[0],(rdtsc()-time)*1000.0/cpu_hertz);} -\end class {install("tsctime",2,1); - struct timeval t0,t1; - uint64 u0,u1; - uint64 estimates[3]; - for (int i=0; i<3; i++) { - u0=rdtsc(); gettimeofday(&t0,0); usleep(10000); - u1=rdtsc(); gettimeofday(&t1,0); - uint64 t = (t1.tv_sec-t0.tv_sec)*1000000+(t1.tv_usec-t0.tv_usec); - estimates[i] = (u1-u0)*1000000/t; - } - qsort(estimates,3,sizeof(uint64),(comparator_t)uint64_compare); - cpu_hertz = estimates[1]; -} - -\class GFError : FObject { - string format; - \constructor (...) { - std::ostringstream o; - char buf[MAXPDSTRING]; - for (int i=0; imom); - string s = o.str(); - pd_error(canvas,"%s",s.data()); -} -\end class {install("gf.error",1,0);} - -//**************************************************************** -\class ForEach : FObject { - \constructor () {} - \decl 0 list (...); -}; -\def 0 list (...) { - t_outlet *o = bself->outlets[0]; - for (int i=0; imom; \ - for (int i=0; igl_owner; if (!mom) RAISE("no such canvas");} - -\class GFCanvasFileName : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 bang (); -}; -\def 0 bang () {MOM; outlet_symbol(bself->outlets[0],mom->gl_name ? mom->gl_name : gensym("empty"));} -\end class {install("gf/canvas_filename",1,1);} -\class GFCanvasDollarZero : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 bang (); -}; -\def 0 bang () {MOM; outlet_float(bself->outlets[0],canvas_getenv(mom)->ce_dollarzero);} -\end class {install("gf/canvas_dollarzero",1,1);} -\class GFCanvasGetPos : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 bang (); -}; -\def 0 bang () {MOM; - t_atom a[2]; - SETFLOAT(a+0,mom->gl_obj.te_xpix); - SETFLOAT(a+1,mom->gl_obj.te_ypix); - outlet_list(bself->outlets[0],&s_list,2,a); -} -\end class {install("gf/canvas_getpos",1,1);} -\class GFCanvasSetPos : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 list (...); -}; -\def 0 list (...) { - MOM; - if (argc!=2) RAISE("wrong number of args"); - mom->gl_obj.te_xpix = atom_getfloatarg(0,argc,argv); - mom->gl_obj.te_ypix = atom_getfloatarg(1,argc,argv); - t_canvas *granny = mom->gl_owner; - if (!granny) RAISE("no such canvas"); -#ifdef DESIREDATA - gobj_changed(mom); -#else - gobj_vis((t_gobj *)mom,granny,0); - gobj_vis((t_gobj *)mom,granny,1); - canvas_fixlinesfor(glist_getcanvas(granny), (t_text *)mom); -#endif -} -\end class {install("gf/canvas_setpos",1,0);} -\class GFCanvasEditMode : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 bang (); -}; -\def 0 bang () {MOM; - t_atom a[1]; SETFLOAT(a+0,0); - outlet_float(bself->outlets[0],mom->gl_edit); -} -\end class {install("gf/canvas_edit_mode",1,1);} -extern "C" void canvas_setgraph(t_glist *x, int flag, int nogoprect); -\class GFCanvasSetGOP : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 float (float gop); -}; -\def 0 float (float gop) {MOM; t_atom a[1]; SETFLOAT(a+0,0); canvas_setgraph(mom,gop,0);} -\end class {install("gf/canvas_setgop",1,0);} -\class GFCanvasXID : FObject { - int n; - t_symbol *name; - \constructor (int n_) { - n=n_; - name=symprintf("gf/canvas_xid:%lx",bself); - pd_bind((t_pd *)bself,name); - } - ~GFCanvasXID () {pd_unbind((t_pd *)bself,name);} - \decl 0 bang (); - \decl 0 xid (t_symbol *t, t_symbol *u); -}; -\def 0 bang () { - t_canvas *mom = bself->mom; - for (int i=0; igl_owner; if (!mom) RAISE("no such canvas");} - sys_vgui("pd %s xid [winfo id .x%lx.c] [winfo id .x%lx]\\;\n",name->s_name,long(mom)); -} -\def 0 xid (t_symbol *t, t_symbol *u) { - outlet_symbol(bself->outlets[0],t); - outlet_symbol(bself->outlets[1],u); -} -\end class {install("gf/canvas_xid",1,2);} - -\class GFCanvasHeHeHe : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 float (float y); -}; -\def 0 float (float y) {MOM; - // was 568 - mom->gl_screenx2 = mom->gl_screenx1 + 600; - if (mom->gl_screeny2-mom->gl_screeny1 < y) mom->gl_screeny2 = mom->gl_screeny1+y; - sys_vgui("wm geometry .x%lx %dx%d\n",long(mom), - int(mom->gl_screenx2-mom->gl_screenx1), - int(mom->gl_screeny2-mom->gl_screeny1)); -} -\end class {install("gf/canvas_hehehe",1,1);} - -#define DASHRECT "-outline #80d4b2 -dash {2 6 2 6}" - -\class GFCanvasHoHoHo : FObject { - int n; - t_canvas *last; - \constructor (int n) {this->n=n; last=0;} - void hide () {if (last) sys_vgui(".x%lx.c delete %lxRECT\n",long(last),bself);} - ~GFCanvasHoHoHo () {hide();} - \decl 0 list (int x1, int y1, int x2, int y2); -}; -\def 0 list (int x1, int y1, int x2, int y2) { - hide(); - MOM; - last = mom; - sys_vgui(".x%lx.c create rectangle %d %d %d %d "DASHRECT" -tags %lxRECT\n",long(last),x1,y1,x2,y2,bself); -} -\end class {install("gf/canvas_hohoho",1,0);} - -#define canvas_each(y,x) for (t_gobj *y=x->gl_list; y; y=y->g_next) -\class GFCanvasCount : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 bang (); -}; -\def 0 bang () {MOM; int k=0; canvas_each(y,mom) k++; outlet_float(bself->outlets[0],k);} -\end class {install("gf/canvas_count",1,1);} - -\class GFCanvasLoadbang : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 float (float m); -}; -\def 0 float (float m) {MOM; - int k=0; - canvas_each(y,mom) { - k++; - if (k>=m && pd_class((t_pd *)y)==canvas_class) canvas_loadbang((t_canvas *)y); - } - -} -\end class { - install("gf/canvas_loadbang",1,0); -}; - -\class GFLOL : FObject { - int n; - \constructor (int n) {this->n=n;} - \decl 0 wire_dotted (int r, int g, int b); - \decl 0 wire_hide (); - \decl 0 box_dotted (int r, int g, int b); - \decl 0 box_align (t_symbol *s, int x_start, int y_start, int incr); -}; -#define BEGIN \ - t_outlet *ouch = ((t_object *)bself->mom)->te_outlet; \ - t_canvas *can = bself->mom->gl_owner; \ - if (!can) RAISE("no such canvas"); \ - for (int i=0; inext; if (!ouch) {RAISE("no such outlet");}} -#define wire_each(wire,ouchlet) for (t_outconnect *wire = ouchlet->connections; wire; wire=wire->next) -\def 0 wire_dotted (int r, int g, int b) { -#ifndef DESIREDATA - BEGIN - wire_each(wire,ouch) { - sys_vgui(".x%lx.c itemconfigure l%lx -fill #%02x%02x%02x -dash {3 3 3 3}\n",long(can),long(wire),r,g,b); - } -#else - post("doesn't work with DesireData"); -#endif -} -\def 0 wire_hide () { -#ifndef DESIREDATA - BEGIN - wire_each(wire,ouch) sys_vgui(".x%lx.c delete l%lx\n",long(can),long(wire)); -#else - post("doesn't work with DesireData"); -#endif -} -\def 0 box_dotted (int r, int g, int b) { -#ifndef DESIREDATA - BEGIN - wire_each(wire,ouch) { - t_object *t = (t_object *)wire->to; - int x1,y1,x2,y2; - gobj_getrect((t_gobj *)wire->to,can,&x1,&y1,&x2,&y2); - // was #00aa66 {3 5 3 5} - sys_vgui(".x%lx.c delete %lxRECT; .x%lx.c create rectangle %d %d %d %d "DASHRECT" -tags %lxRECT\n", - long(can),long(t),long(can),x1,y1,x2,y2,long(t)); - } -#else - post("doesn't work with DesireData"); -#endif -} -bool comment_sort_y_lt(t_object * const &a, t_object * const &b) /* is a StrictWeakOrdering */ { - return a->te_ypix < b->te_ypix; -} -#define foreach(ITER,COLL) for(typeof(COLL.begin()) ITER = COLL.begin(); ITER != (COLL).end(); ITER++) -static t_class *inlet_class, *floatinlet_class, *symbolinlet_class, *pointerinlet_class; -static bool ISINLET(t_pd *o) { - t_class *c=pd_class(o); - return c==inlet_class || c==floatinlet_class || c==symbolinlet_class || c==pointerinlet_class; -} -struct _inlet { - t_pd pd; - struct _inlet *next; - t_object *owner; - t_pd *dest; - t_symbol *symfrom; - //union inletunion un; -}; -\def 0 box_align (t_symbol *dir, int x_start, int y_start, int incr) { - int x=x_start, y=y_start; - bool horiz; - if (dir==&s_x) horiz=false; else - if (dir==&s_y) horiz=true; else RAISE("$1 must be x or y"); -#ifndef DESIREDATA - std::vector v; - BEGIN - wire_each(wire,ouch) { - //post("wire to object of class %s ISINLET=%d",pd_class(wire->to)->c_name->s_name,ISINLET(wire->to)); - t_object *to = ISINLET(wire->to) ? ((t_inlet *)wire->to)->owner : (t_object *)wire->to; - v.push_back(to); - } - sort(v.begin(),v.end(),comment_sort_y_lt); - foreach(tt,v) { - t_object *t = *tt; - if (t->te_xpix!=x || t->te_ypix!=y) { - gobj_vis((t_gobj *)t,can,0); - t->te_xpix=x; - t->te_ypix=y; - gobj_vis((t_gobj *)t,can,1); - canvas_fixlinesfor(can,t); - } - int x1,y1,x2,y2; - gobj_getrect((t_gobj *)t,can,&x1,&y1,&x2,&y2); - if (horiz) x += x2-x1+incr; - else y += y2-y1+incr; - } - if (horiz) outlet_float(bself->outlets[0],x-x_start); - else outlet_float(bself->outlets[0],y-y_start); -#else - post("doesn't work with DesireData"); -#endif -} - -extern t_widgetbehavior text_widgetbehavior; -t_widgetbehavior text_widgetbehavi0r; - -/* i was gonna use gobj_shouldvis but it's only for >= 0.42 */ - -static int text_chou_de_vis(t_text *x, t_glist *glist) { - return (glist->gl_havewindow || - (x->te_pd != canvas_class && x->te_pd->c_wb != &text_widgetbehavior) || - (x->te_pd == canvas_class && (((t_glist *)x)->gl_isgraph)) || - (glist->gl_goprect && (x->te_type == T_TEXT))); -} - -static void text_visfn_hax0r (t_gobj *o, t_canvas *can, int vis) { - text_widgetbehavior.w_visfn(o,can,vis); - //if (vis) return; // if you want to see #X text inlets uncomment this line - t_rtext *y = glist_findrtext(can,(t_text *)o); - if (text_chou_de_vis((t_text *)o,can)) glist_eraseiofor(can,(t_object *)o,rtext_gettag(y)); -} -\end class { - install("gf/lol",1,1); -#ifndef DESIREDATA - class_setpropertiesfn(text_class,(t_propertiesfn)0xDECAFFED); - unsigned long *lol = (unsigned long *)text_class; - int i=0; - while (lol[i]!=0xDECAFFED) i++; - *((char *)(lol+i+1) + 6) = 1; - class_setpropertiesfn(text_class,0); - t_object *bogus = (t_object *)pd_new(text_class); - inlet_class = pd_class((t_pd *) inlet_new(bogus,0,0,0)); - floatinlet_class = pd_class((t_pd *) floatinlet_new(bogus,0)); - symbolinlet_class = pd_class((t_pd *) symbolinlet_new(bogus,0)); - pointerinlet_class = pd_class((t_pd *)pointerinlet_new(bogus,0)); - memcpy(&text_widgetbehavi0r,&text_widgetbehavior,sizeof(t_widgetbehavior)); - text_widgetbehavi0r.w_visfn = text_visfn_hax0r; - class_setwidget(text_class,&text_widgetbehavi0r); -#endif -} - -\class GFStringReplace : FObject { - t_symbol *from; - t_symbol *to; - \constructor (t_symbol *from, t_symbol *to=&s_) {this->from=from; this->to=to;} - \decl 0 symbol (t_symbol *victim); -}; -\def 0 symbol (t_symbol *victim) { - string a = string(victim->s_name); - string b = string(from->s_name); - string c = string(to->s_name); - for (size_t i=0;;) { - i = a.find(b,i); - if (i==string::npos) break; - a = a.replace(i,b.length(),c); - i += c.length(); - } - outlet_symbol(bself->outlets[0],gensym(a.c_str())); -} -\end class {install("gf/string_replace",1,1);} - -\class GFStringLessThan : FObject { - t_symbol *than; - \constructor (t_symbol *than=&s_) {this->than=than;} - \decl 0 symbol (t_symbol *it); - \decl 1 symbol (t_symbol *than); -}; -\def 0 symbol (t_symbol *it) {outlet_float(bself->outlets[0],strcmp(it->s_name,than->s_name)<0);} -\def 1 symbol (t_symbol *than) {this->than=than;} -\end class {install("gf/string_<",2,1);} - -void startup_flow_objects2 () { - \startall -} diff --git a/externals/gridflow/src/dc1394.cxx b/externals/gridflow/src/dc1394.cxx deleted file mode 100644 index e2361a8e..00000000 --- a/externals/gridflow/src/dc1394.cxx +++ /dev/null @@ -1,287 +0,0 @@ -/* - $Id: dc1394.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define DC1394_INCLUDE_HERE -#include -#include "gridflow.hxx.fcs" - -/* speeds are numbered 0 to 5, worth 100< feature_names; - -static void setup_modes () { - int i=64; // format 0 - MODE(160,120,YUV444); - MODE(320,240,YUV422); - MODE(640,480,YUV411); - MODE(640,480,YUV422); - MODE(640,480,RGB); - MODE(640,480,MONO); - MODE(640,480,MONO16); - i=96; // format 1 - MODE(800,600,YUV422); - MODE(800,600,RGB); - MODE(800,600,MONO); - MODE(1024,768,YUV422); - MODE(1024,768,RGB); - MODE(1024,768,MONO); - MODE(800,600,MONO16); - MODE(1024,768,MONO16); - i=128; // format 2 - MODE(1280,960,YUV422); - MODE(1280,960,RGB); - MODE(1280,960,MONO); - MODE(1600,1200,YUV422); - MODE(1600,1200,RGB); - MODE(1600,1200,MONO); - MODE(1280,960,MONO16); - MODE(1600,1200,MONO16); - i=256; // format 6 - // MODE_EXIF= 256 - i=288; // format 7 - //MODE_FORMAT7_0, - //MODE_FORMAT7_1, - //MODE_FORMAT7_2, - //MODE_FORMAT7_3, - //MODE_FORMAT7_4, - //MODE_FORMAT7_5, - //MODE_FORMAT7_6, - //MODE_FORMAT7_7 - -// format7 color modes start at #320 and are MONO8 YUV411 YUV422 YUV444 RGB8 MONO16 RGB16 MONO16S RGB16S RAW8 RAW16 -// trigger modes start at #352 and are 0 1 2 3 -// image formats start at #384 and are VGA_NONCOMPRESSED SVGA_NONCOMPRESSED_1 SVGA_NONCOMPRESSED_2 -// and continue at #390 and are STILL_IMAGE FORMAT_SCALABLE_IMAGE_SIZE - -#define FEATURE(foo) feature_names[i++] = #foo; - - i=416; - FEATURE(BRIGHTNESS); - FEATURE(EXPOSURE); - FEATURE(SHARPNESS); - FEATURE(WHITE_BALANCE); - FEATURE(HUE); - FEATURE(SATURATION); - FEATURE(GAMMA); - FEATURE(SHUTTER); - FEATURE(GAIN); - FEATURE(IRIS); - FEATURE(FOCUS); - FEATURE(TEMPERATURE); - FEATURE(TRIGGER); - FEATURE(TRIGGER_DELAY); - FEATURE(WHITE_SHADING); - FEATURE(FRAME_RATE); - i+=16;/* 16 reserved features */ - FEATURE(ZOOM); - FEATURE(PAN); - FEATURE(TILT); - FEATURE(OPTICAL_FILTER); - i+=12;/* 12 reserved features */ - FEATURE(CAPTURE_SIZE); - FEATURE(CAPTURE_QUALITY); - i+=14;/* 14 reserved features */ - - i=480; // operation modes - //OPERATION_MODE_LEGACY - //OPERATION_MODE_1394B - - i=512; // sensor layouts - //RGGB - //GBRG, - //GRBG, - //BGGR - - i=544; // IIDC_VERSION -#if 0 - IIDC_VERSION(1_04); - IIDC_VERSION(1_20); - IIDC_VERSION(PTGREY); - IIDC_VERSION(1_30); - IIDC_VERSION(1_31); - IIDC_VERSION(1_32); - IIDC_VERSION(1_33); - IIDC_VERSION(1_34); - IIDC_VERSION(1_35); - IIDC_VERSION(1_36); - IIDC_VERSION(1_37); - IIDC_VERSION(1_38); - IIDC_VERSION(1_39); -#endif - -// Return values are SUCCESS FAILURE NO_FRAME NO_CAMERA - -// Parameter flags for dc1394_setup_format7_capture() -//#define QUERY_FROM_CAMERA -1 -//#define USE_MAX_AVAIL -2 -//#define USE_RECOMMENDED -3 - -// The video1394 policy: blocking (wait for a frame forever) or polling (returns if no frames in buffer -// WAIT=0 POLL=1 -}; - -typedef raw1394handle_t RH; -typedef nodeid_t NID; - -#define IO(func,args...) if (func(rh,usenode,args)!=DC1394_SUCCESS) RAISE(#func " failed"); - -\class FormatDC1394 : Format { - RH rh; - int useport; - int usenode; - int framerate_e; - int height; - int width; - dc1394_cameracapture camera; - dc1394_feature_set features; - std::map feature_index; - \constructor (t_symbol *mode) { - bool gotone=false; - post("DC1394: hello world"); - rh = raw1394_new_handle(); - if (!rh) RAISE("could not get a handle for /dev/raw1394 and /dev/video1394"); - int numPorts = raw1394_get_port_info(rh,0,0); - raw1394_destroy_handle(rh); - post("there are %d Feuerweuer ports",numPorts); - if (mode!=gensym("in")) RAISE("sorry, read-only"); - for(int port=0; portrh = dc1394_create_handle(useport); - IO(dc1394_get_camera_feature_set,&features); - dc1394_print_feature_set(&features); - post("NUM_FEATURES=%d",NUM_FEATURES); - for (int i=0; ioutlets[0],gensym("size"),2,a); // abnormal (does not use nested list) - unsigned int width,height; - IO(dc1394_query_format7_max_image_size,MODE_FORMAT7_0,&width,&height); - SETFLOAT(a+0,height); - SETFLOAT(a+1,width); - outlet_anything(bself->outlets[0],gensym("maxsize"),2,a); // abnormal (does not use nested list) - } -} -\def 0 size (int height, int width) { - IO(dc1394_set_format7_image_size,MODE_FORMAT7_0,width,height); - this->height = height; - this->width = width; - setup(); -} - -\def unsigned brightness () {unsigned value; dc1394_get_brightness(rh,usenode,&value); return value;} -\def 0 brightness (unsigned value) {dc1394_set_brightness(rh,usenode, value);} -\def unsigned hue () {unsigned value; dc1394_get_hue( rh,usenode,&value); return value;} -\def 0 hue (unsigned value) {dc1394_set_hue( rh,usenode, value);} -\def unsigned colour () {unsigned value; dc1394_get_saturation(rh,usenode,&value); return value;} -\def 0 colour (unsigned value) {dc1394_set_saturation(rh,usenode, value);} - -void FormatDC1394::setup () { - //dc1394_set_format7_image_size(rh,usenode,0,width,height); - IO(dc1394_setup_capture,0,FORMAT_VGA_NONCOMPRESSED,MODE_640x480_MONO,SPEED_400,framerate_e,&camera); - //IO(dc1394_setup_format7_capture,0,MODE_FORMAT7_0,SPEED_400,QUERY_FROM_CAMERA,0,0,width,height,&camera); - if (dc1394_set_trigger_mode(rh,usenode,TRIGGER_MODE_0) != DC1394_SUCCESS) RAISE("dc1394_set_trigger_mode error"); - if (dc1394_start_iso_transmission(rh,usenode)!=DC1394_SUCCESS) RAISE("dc1394_start_iso_transmission error"); -} - -\def float framerate() { - return 1.875 * (1<<(framerate_e-FRAMERATE_1_875)); -} - -\def 0 framerate(float framerate) { - framerate_e = FRAMERATE_1_875; - while (framerate>=1.875 && framerate_e <= FRAMERATE_240) {framerate/=2; framerate_e++;} - setup(); -} - -static volatile int timeout=0; -static void rien (int) {timeout=1; post("timeout2");} - -\def 0 bang () { - //struct itimerval tval; - //tval.it_interval.tv_sec = 1; - //tval.it_interval.tv_usec = 0; - //tval.it_value = tval.it_interval; - //setitimer(ITIMER_REAL,&tval,0); - //signal(SIGALRM,rien); - if (dc1394_single_capture(rh,&camera)!=DC1394_SUCCESS) RAISE("dc1394_single_capture error"); - //setitimer(ITIMER_REAL,0,0); - out=new GridOutlet(this,0,new Dim(height,width,1)); - //out->send(out->dim->prod(),(uint8 *)camera.capture_buffer); - for (int i=0; isend(out->dim->prod(1),(uint8 *)camera.capture_buffer+640*i); - //if (dc1394_stop_iso_transmission(rh,usenode)!=DC1394_SUCCESS) RAISE("dc1394_stop_iso_transmission error"); - //post("frame_height=%d",camera.frame_height); - //post("frame_width=%d" ,camera.frame_width); - //post("quadlets_per_frame=%d" ,camera.quadlets_per_frame); - //post("quadlets_per_packet=%d" ,camera.quadlets_per_packet); -} - -\end class FormatDC1394 { - install_format("#io.dc1394",4,""); - setup_modes(); -} -void startup_dc1394 () { - \startall -} diff --git a/externals/gridflow/src/fftw.cxx b/externals/gridflow/src/fftw.cxx deleted file mode 100644 index 7aa3f44c..00000000 --- a/externals/gridflow/src/fftw.cxx +++ /dev/null @@ -1,114 +0,0 @@ -/* - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include - -#define C(x) ((fftwf_complex *)x) - -\class GridFFT : FObject { - fftwf_plan plan; - P lastdim; /* of last input (for plan cache) */ - long lastchans; /* of last input (for plan cache) */ - \attr int sign; /* -1 or +1 */ - \attr int skip; /* 0 (y and x) or 1 (x only) */ - \attr bool real; - bool lastreal; - \constructor () {sign=-1; plan=0; lastdim=0; lastchans=0; skip=0; real=false;} - \grin 0 float32 -}; -\def 0 sign (int sign) { - if (sign!=-1 && sign!=1) RAISE("sign should be -1 or +1"); - this->sign=sign; - fftwf_destroy_plan(plan); -} -\def 0 skip (int skip) { - if (skip<0 || skip>1) RAISE("skip should be 0 or 1"); - this->skip=skip; - if (plan) {fftwf_destroy_plan(plan); plan=0;} -} -GRID_INLET(0) { - if (in->nt != float32_e) RAISE("expecting float32"); - if (real && sign==-1) { - if (in->dim->n != 2 && in->dim->n != 3) RAISE("expecting 2 or 3 dimensions: rows,columns,channels?"); - } else { - if (in->dim->n != 3 && in->dim->n != 4) RAISE("expecting 3 or 4 dimensions: rows,columns,channels?,complex"); - if (in->dim->get(in->dim->n-1)!=2) RAISE("expecting Dim(...,2): real,imaginary (got %d)",in->dim->get(2)); - } - in->set_chunk(0); -} GRID_FLOW { - if (skip==1 && !real) RAISE("can't do 1-D FFT in real mode, sorry"); - Dim *dim; - if (!real) dim = in->dim; - else if (sign==-1) { - int v[Dim::MAX_DIM]; - for (int i=0; idim->n; i++) v[i]=in->dim->v[i]; - v[in->dim->n] = 2; - dim = new Dim(in->dim->n+1,v); - } else dim = new Dim(in->dim->n-1,in->dim->v); - GridOutlet out(this,0,dim,in->nt); - float32 *tada = (float32 *)memalign(16,dim->prod()*sizeof(float32)); - long chans = in->dim->n>=3 ? in->dim->get(2) : 1; - CHECK_ALIGN16(data,in->nt) - CHECK_ALIGN16(tada,in->nt) - if (plan && lastdim && lastdim!=in->dim && chans!=lastchans && real==lastreal) {fftwf_destroy_plan(plan); plan=0;} - int v[] = {in->dim->v[0],in->dim->v[1],in->dim->n>2?in->dim->v[2]:1}; -// if (chans==1) { -// if (skip==0) plan = fftwf_plan_dft_2d(v[0],v[1],data,tada,sign,0); -// if (skip==1) plan = fftwf_plan_many_dft(1,&v[1],v[0],data,0,1,v[1],tada,0,1,v[1],sign,0); -// } - if (skip==0) { - //plan = fftwf_plan_dft_2d(v[0],v[1],data,tada,sign,0); - if (!plan) { - int embed[] = {dim->v[0],dim->v[1]}; - if (!real) {plan=fftwf_plan_many_dft( 2,&v[0],chans,C(data),0 ,chans,1,C(tada),0 ,chans,1,sign,0);} - else if (sign==-1) {plan=fftwf_plan_many_dft_r2c(2,&v[0],chans, data ,embed,chans,1,C(tada),embed,chans,1,0);} - else {plan=fftwf_plan_many_dft_c2r(2,&v[0],chans,C(data),embed,chans,1, tada ,embed,chans,1,0);} - } - if (!real) fftwf_execute_dft( plan,C(data),C(tada)); - else if (sign==-1) fftwf_execute_dft_r2c(plan, data ,C(tada)); - else fftwf_execute_dft_c2r(plan,C(data), tada ); - } - if (skip==1) { - if (!plan) plan=fftwf_plan_many_dft(1,&v[1],chans,C(data),0,chans,1,C(tada),0,chans,1,sign,0); - //plan = fftwf_plan_many_dft(1,&v[1],v[0],C(data),0,1,v[1],C(tada),0,1,v[1],sign,0); - long incr = v[1]*chans; - for (int i=0; iprod(),tada); - free(tada); - lastdim=in->dim; lastchans=chans; lastreal=real; -} GRID_END -\end class {install("#fft",1,1);} -void startup_fftw () { - \startall -} diff --git a/externals/gridflow/src/formats.cxx b/externals/gridflow/src/formats.cxx deleted file mode 100644 index 50574285..00000000 --- a/externals/gridflow/src/formats.cxx +++ /dev/null @@ -1,266 +0,0 @@ -/* - $Id$ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include -#include -#include -#define L _L_ - -/* API (version 0.9.3) - mode is :in or :out - def initialize(mode,*args) : - open a file handler (do it via .new of class) - attr_reader :description : - a _literal_ (constant) string describing the format handler - def self.info() optional : - return a string describing the format handler differently - than self.description(). in particular, it can list - compile-time options and similar things. for example, - quicktime returns a list of codecs. - def 0 bang() : - read one frame, send through outlet 0 - return values : - Integer >= 0 : frame number of frame read. - false : no frame was read : end of sequence. - nil : a frame was read, but can't say its number. - note that trying to read a nonexistent frame should no longer - rewind automatically (@in handles that part), nor re-read the - last frame (mpeg/quicktime used to do this) - def 0 seek(Integer i) : select one frame to be read next (by number) - def 0 grid() : frame to write - def 0 get (optional Symbol s) : get one attribute value or all of them - def 0 ...() : options - outlet 0 grid() frame just read - outlet 0 ...() everything else - destructor : close a handler -*/ - -std::map suffix_table; -void suffixes_are (const char *name, const char *suffixes) { - std::string name2 = name; - char *suff2 = strdup(suffixes); - char *suff3 = suff2+strlen(suff2); - for (char *s=suff2; ss_name); - char *t = strrchr(s,'.'); - if (!t) outlet_symbol(bself->outlets[2],gensym(s)); - else { - *t = 0; - outlet_symbol(bself->outlets[1],gensym(t+1)); - std::map::iterator u = suffix_table.find(std::string(t+1)); - if (u==suffix_table.end()) outlet_bang(bself->outlets[0]); - else outlet_symbol(bself->outlets[0],gensym((char *)u->second.data())); - } - free(s); -} -\end class SuffixLookup {install("gf.suffix_lookup",1,3);} - -\class Format : FObject -Format::Format (BFObject *bself, MESSAGE) : FObject(bself,MESSAGE2) { - mode=0; fd=-1; f=0; cast=int32_e; frame=0; - if (argv[0]==gensym("out")) this->mode=2; else - if (argv[0]==gensym("in")) this->mode=4; else RAISE("unknown mode"); -// case mode -// when :in; flags[2]==1 -// when :out; flags[1]==1 -// else raise "Format opening mode is incorrect" - //end or raise "Format '#{self.class.instance_eval{@symbol_name}}' does not support mode '#{mode}'" -} - -\def 0 open(t_symbol *mode, string filename) { - const char *fmode; - if (mode==gensym("in")) fmode="r"; else - if (mode==gensym("out")) fmode="w"; else - RAISE("bad mode"); - if (f) _0_close(0,0); - if (mode==gensym("in")) {filename = gf_find_file(filename);} - f = fopen(filename.data(),fmode); - if (!f) RAISE("can't open file '%s': %s",filename.data(),strerror(errno)); - fd = fileno(f); -// case gzfile: -// if (mode==SYM(in)) {filename = GridFlow.find_file(filename);} -// if (mode==:in) {raw_open_gzip_in filename; else raw_open_gzip_out filename;} -// def self.rewind() raw_open(*@raw_open_args); @frame = 0 end unless @rewind_redefined -// @rewind_redefined = true -} -\def 0 close() {if (f) {fclose(f); f=0; fd=-1;}} -\def 0 cast(NumberTypeE nt) {cast = nt;} - -\def 0 seek(int frame) { - if (!frame) {_0_rewind(0,0); return;} - RAISE("don't know how to seek for frame other than # 0"); -} - -// this is what you should use to rewind -// different file-sources may redefine this as something else -// (eg: gzip) -\def 0 rewind () { - if (!f) RAISE("Nothing to rewind about..."); - fseek(f,0,SEEK_SET); - frame = 0; -} - -Format::~Format () {if (f) fclose(f); /*if (fd>=0) close(fd);*/} -\end class Format {} - -/* This is the Grid format I defined: */ -struct GridHeader { - char magic[5]; // = "\x7fgrid" on little endian, "\x7fGRID" on big endian - uint8 type; // supported: 8=int8 9=uint8 16=int16 32=int32 - // unsupported: 34=float32 64=int64 66=float64 - // (number of bits is multiple of 8; add 1 for unsigned; add 2 for float) - uint8 reserved; // set this to 0 all of the time. - uint8 dimn; // number of dimensions supported: at least 0..4) - // int32 dimv[dimn]; // number of elements in each dimension. (in the file's endianness!) - // raw data goes after that -}; - -\class FormatGrid : Format { - GridHeader head; - int endian; - NumberTypeE nt; - P headerless_dim; // if null: headerful; if Dim: it is the assumed dimensions of received grids - \grin 0 - \constructor (t_symbol *mode, string filename) { - nt = int32_e; - endian = is_le(); - _0_open(0,0,mode,filename); - } - \decl 0 bang (); - \decl 0 headerless (...); - \decl 0 headerful (); - \decl 0 type (NumberTypeE nt); - ~FormatGrid() { - //@stream.close if @stream - //GridFlow.hunt_zombies - } -// \decl void raw_open_gzip_in(string filename); -// \decl void raw_open_gzip_out(string filename); -}; -\def 0 bang () { - P dim; - if (feof(f)) {outlet_bang(bself->te_outlet); return;} - if (headerless_dim) { - dim = headerless_dim; - } else { - if (fread(&head,1,8,f)<8) RAISE("can't read header"); - uint8 *m = (uint8 *)head.magic; - if (strncmp((char *)m,"\x7fgrid",5)==0) endian=1; else - if (strncmp((char *)m,"\x7fGRID",5)==0) endian=0; else - RAISE("unknown header, can't read grid from file: " - "%02x %02x %02x %02x %02x %02x %02x %02x", - m[0],m[1],m[2],m[3],m[4],m[5],m[6],m[7]); - switch (head.type) { - case 8: nt=uint8_e; break; // sorry, was supposed to be signed. - case 9: nt=uint8_e; break; - case 16: nt=int16_e; break; - case 32: nt=int32_e; break; - default: RAISE("unsupported grid type %d in file",head.type); - } - // apparently, head.type 8 and 16 worked too. - if (head.reserved!=0) RAISE("unsupported grid reserved field %d in file",head.reserved); - if (head.dimn>16) RAISE("unsupported grid number of dimensions %d in file",head.dimn); - int32 dimv[head.dimn]; - ; - if (fread(dimv,1,head.dimn*4,f)prod(); -#define FOO(T) {T data[nn]; if (fread(data,1,nn*sizeof(T),f)nt) { - case uint8_e: head.type = 9; break; - case int16_e: head.type = 16; break; - case int32_e: head.type = 32; break; - default: RAISE("can't write that type of number to a file"); - } - head.reserved = 0; - head.dimn = in->dim->n; - fwrite(&head,1,8,f); - fwrite(in->dim->v,in->dim->n,4,f); - } -} GRID_FLOW { -#define FOO(T) {T data2[n]; for(int i=0; int,FOO,) -#undef FOO -} GRID_FINISH { - fflush(f); -} GRID_END - -\def 0 headerless (...) { - if (argc>=0 && argv[0].a_type==A_LIST) { - t_binbuf *b = (t_binbuf *)argv[0]; argc = binbuf_getnatom(b); argv = (t_atom2 *)binbuf_getvec(b);} - int v[argc]; - for (int i=0; int = nt; -} - -//\def void raw_open_gzip_in(string filename) { - //r,w = IO.pipe - //if (pid=fork) {GridFlow.subprocesses[pid]=true; w.close; @stream = r;} - //else {r.close; STDOUT.reopen w; STDIN.reopen filename, "r"; exec "gzip", "-dc";} -//\def void raw_open_gzip_out(string filename) { - //r,w = IO.pipe - //if (pid=fork) {GridFlow.subprocesses[pid]=true; r.close; @stream = w;} - //else {w.close; STDIN.reopen r; STDOUT.reopen filename, "w"; exec "gzip", "-c";} - -\end class FormatGrid {install_format("#io.grid",6,"grid");} - -void startup_format () { - \startall -} diff --git a/externals/gridflow/src/gem.cxx b/externals/gridflow/src/gem.cxx deleted file mode 100644 index 4d1d00c3..00000000 --- a/externals/gridflow/src/gem.cxx +++ /dev/null @@ -1,202 +0,0 @@ -/* - $Id: gem.c 4621 2009-11-01 21:18:17Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include -/* summarising GEM's headers: GemState.h and GemPixUtil.h */ -struct imageStruct { - imageStruct(); ~imageStruct(); - unsigned char* allocate(size_t size); unsigned char* allocate(); - unsigned char* reallocate(size_t size); unsigned char* reallocate(); - void clear(); - GLint xsize, ysize, csize; - GLenum type, format; - int notowned; - void copy2Image(imageStruct *to) const; - void copy2ImageStruct(imageStruct *to) const; // copy the imageStruct (but not the actual data) - void refreshImage(imageStruct *to); - void swapRedBlue (); - void convertTo (imageStruct*to, GLenum dest_format=0); - void convertFrom(imageStruct*from, GLenum dest_format=0); - unsigned char *data; - private: - unsigned char *pdata; - size_t datasize; - public: - GLboolean upsidedown; -}; -struct pixBlock { - pixBlock(); - imageStruct image; - int newimage, newfilm; -}; -class TexCoord { - public: - TexCoord() : s(0.f), t(0.f) {} - TexCoord(float s_, float t_) : s(s_), t(t_) {} - float s,t; -}; -class GemState { - public: - int dirty, inDisplayList, lighting, smooth, texture; - pixBlock *image; - TexCoord *texCoords; - int numTexCoords, multiTexUnits; - float tickTime; - GLenum drawType; - int stackDepth[4]; - int VertexDirty; - GLfloat *VertexArray; int VertexArraySize; int VertexArrayStride; - GLfloat *ColorArray; int HaveColorArray; - GLfloat *NormalArray; int HaveNormalArray; - GLfloat *TexCoordArray; int HaveTexCoordArray; - GemState(); - ~GemState(); - float texCoordX(int num) const {if (texture && numTexCoords > num) return texCoords[num].s; else return 0.;} - float texCoordY(int num) const {if (texture && numTexCoords > num) return texCoords[num].t; else return 0.;} - void reset(); -}; -/* end of summary */ - -// in 0: gem -// in 1: grid -// out 0: gem -\class GridToPix : FObject { - P bit_packing3; - P bit_packing4; - pixBlock m_pixBlock; - \attr bool yflip; - \decl 0 gem_state (...); - void render(GemState *state) {state->image = &m_pixBlock;} - void startRendering () {m_pixBlock.newimage = 1;} - GridToPix (BFObject *bself, MESSAGE) : FObject(bself,MESSAGE2) { - yflip = false; - imageStruct &im = m_pixBlock.image = imageStruct(); - im.ysize = 1; - im.xsize = 1; - im.csize = 4; - im.format = GL_RGBA; - im.type = GL_UNSIGNED_BYTE; - im.allocate(); - *(int*)im.data = 0x0000ff; - uint32 mask[4] = {0x0000ff,0x00ff00,0xff0000,0x000000}; - bit_packing3 = new BitPacking(is_le(),4,3,mask); - bit_packing4 = new BitPacking(is_le(),4,4,mask); - } - ~GridToPix () {} - \grin 1 int -}; -\def 0 gem_state (...) { - if (argc==2) render((GemState *)(void *)argv[1]); else startRendering(); - outlet_anything(bself->te_outlet,gensym("gem_state"),argc,argv); -} -GRID_INLET(1) { - if (in->dim->n != 3) RAISE("expecting 3 dimensions: rows,columns,channels"); - int c = in->dim->get(2); - if (c!=3 && c!=4) RAISE("expecting 3 or 4 channels (got %d)",in->dim->get(2)); - in->set_chunk(1); - imageStruct &im = m_pixBlock.image; - im.clear(); - im.ysize = in->dim->get(0); - im.xsize = in->dim->get(1); - im.type = GL_UNSIGNED_BYTE; - switch (in->dim->get(2)) { - case 1: im.csize = 1; im.format = GL_LUMINANCE; break; - case 3: im.csize = 4; im.format = GL_RGBA; break; - case 4: im.csize = 4; im.format = GL_RGBA; break; - default: RAISE("you shouldn't see this error message."); - } - im.allocate(); -} GRID_FLOW { - uint8 *buf = (uint8 *)m_pixBlock.image.data; - /*!@#$ it would be nice to skip the bitpacking when we can */ - long sxc = in->dim->prod(1); - long sx = in->dim->v[1]; - long sy = in->dim->v[0]; - BitPacking *bp = in->dim->get(2)==3 ? bit_packing3 : bit_packing4; - imageStruct &im = m_pixBlock.image; - if (yflip) {for (long y= dex/sxc; n; data+=sxc, n-=sxc, y++) bp->pack(sx,data,buf+y*sx*im.csize);} - else {for (long y=sy-1-dex/sxc; n; data+=sxc, n-=sxc, y--) bp->pack(sx,data,buf+y*sx*im.csize);} -} GRID_END -\end class {install("#to_pix",2,1); add_creator("#export_pix");} - -//------------------------------------------------------------------------ - -\class GridFromPix : FObject { - P bit_packing; - \attr bool yflip; - \attr NumberTypeE cast; - int channels; - GridFromPix () : FObject(0,0,0,0) {RAISE("don't call this. this exists only to make GEM happy.");} - GridFromPix (BFObject *bself, MESSAGE) : FObject(bself,MESSAGE2) { - uint32 mask[4] = {0x0000ff,0x00ff00,0xff0000,0x000000}; - bit_packing = new BitPacking(is_le(),4,3,mask); - yflip = false; - cast = int32_e; - channels = 3; - } - virtual ~GridFromPix () {} - \decl 0 gem_state (...); - \decl 0 colorspace (t_symbol *s); - void render(GemState *state) { - if (!state->image) {::post("gemstate has no pix"); return;} - imageStruct &im = state->image->image; - if (im.format != GL_RGBA ) {::post("can't produce grid from pix format %d",im.format); return;} - if (im.type != GL_UNSIGNED_BYTE) {::post("can't produce grid from pix type %d", im.type ); return;} - int32 v[] = { im.ysize, im.xsize, channels }; - GridOutlet out(this,0,new Dim(3,v),cast); - long sxc = im.xsize*channels; - long sy = v[0]; - if (channels==3) { - #define FOO(T) {T buf[sxc]; \ - for (int y=0; yunpack(im.xsize,data,buf); out.send(sxc,buf);}} - TYPESWITCH(cast,FOO,) - #undef FOO - } else { - for (int y=0; ys_name); -} -\def 0 gem_state (...) {if (argc==2) render((GemState *)(void *)argv[1]);} -\end class {install("#from_pix",2,1); add_creator("#import_pix");} - -//------------------------------------------------------------------------ - -void startup_gem () { - \startall -} - -/* -virtual void processRGBAImage(imageStruct &image) {} -virtual void processRGBImage (imageStruct &image) {} -virtual void processGrayImage(imageStruct &image) {} -virtual void processYUVImage (imageStruct &image) {} -*/ - diff --git a/externals/gridflow/src/grid.cxx b/externals/gridflow/src/grid.cxx deleted file mode 100644 index 3d721329..00000000 --- a/externals/gridflow/src/grid.cxx +++ /dev/null @@ -1,295 +0,0 @@ -/* - $Id: grid.c 4391 2009-10-25 16:56:27Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include "gridflow.hxx.fcs" -#include - -//#define TRACEBUFS - -#define CHECK_TYPE(d,NT) if (NumberTypeE_type_of(&d)!=NT) RAISE("(%s): " \ - "type mismatch during transmission (got %s expecting %s)", __PRETTY_FUNCTION__, \ - number_type_table[NumberTypeE_type_of(&d)].name, number_type_table[NT].name); -#define CHECK_BUSY1(s) if (!dim) RAISE(#s " not busy"); -#define CHECK_BUSY(s) if (!dim) RAISE(#s " not busy (wanting to write %ld values)",(long)n); -#define CHECK_ALIGN(d,nt) {int bytes = number_type_table[nt].size/8; int align = ((long)(void*)d)%bytes; \ - if (align) {post("(%s): Alignment Warning: %p is not %d-aligned: %d", __PRETTY_FUNCTION__, (void*)d,bytes,align);}} - -// **************** Grid ****************************************** - -void Grid::init_from_list(int n, t_atom *aa, NumberTypeE nt) { - t_atom2 *a = (t_atom2 *)aa; - t_symbol *delim = gensym("#"); - for (int i=0; idata,nt); - if (a[i] != delim) i++; - i++; a+=i; n-=i; - goto fill; - } - } - if (n!=0 && a[0].a_type==A_SYMBOL) {nt = NumberTypeE_find(a[0]); a++; n--;} - init(new Dim(n),nt); - CHECK_ALIGN(this->data,nt); - fill: - int nn = dim->prod(); - n = min(n,nn); -#define FOO(T) { \ - T *p = (T *)*this; \ - if (n==0) CLEAR(p,nn); else { \ - for (int i=0; idata,nt); - ((int32 *)*this)[0] = (int32)a.a_float; - } else { - std::ostringstream s; s << x; - RAISE("can't convert to grid: %s",s.str().data()); - } -} - -// **************** GridInlet ************************************* - -// must be set before the end of GRID_BEGIN phase, and so cannot be changed -// afterwards. This is to allow some optimisations. Anyway there is no good reason -// why this would be changed afterwards. -void GridInlet::set_chunk(long whichdim) { - chunk = whichdim; - long n = dim->prod(whichdim); - if (!n) n=1; - if(!dim) RAISE("huh?"); - if (n>1) { - buf=new Grid(new Dim(n), sender->nt); - bufi=0; - } else buf=0; -} - -bool GridInlet::supports_type(NumberTypeE nt) { -#define FOO(T) return !! gh->flow_##T; - TYPESWITCH(nt,FOO,return false) -#undef FOO -} - -void GridInlet::begin(GridOutlet *sender) { - if (dim) RAISE("grid inlet aborting from %s at %ld/%ld because of %s", - ARGS(this->sender->parent),long(dex),long(dim->prod()),ARGS(sender->parent)); - this->sender = sender; - if (!supports_type(sender->nt)) RAISE("number type %s not supported here", number_type_table[sender->nt].name); - this->nt = sender->nt; - this->dim = sender->dim; - dex=0; - buf=0; - try { -#define FOO(T) gh->flow(this,dex,-1,(T *)0); break; - TYPESWITCH(sender->nt,FOO,) -#undef FOO - } catch (Barf &barf) {this->dim=0; throw;} - this->dim = dim; - sender->callback(this); -#ifdef TRACEBUFS - post("GridInlet: %20s buf for recving from %p",dim->to_s(),sender); -#endif -} - -#define CATCH_IT catch (Barf &slimy) {slimy.error(parent->bself);} - -template void GridInlet::flow(long n, T *data) { - CHECK_BUSY(inlet); CHECK_TYPE(*data,sender->nt); CHECK_ALIGN(data,sender->nt); - if (!n) return; // no data - long d = dex + bufi; - if (d+n > dim->prod()) { - post("grid input overflow: %ld of %ld from [%s] to [%s]", d+n, long(dim->prod()), ARGS(sender->parent), ARGS(parent)); - n = dim->prod() - d; - if (n<=0) return; - } - int bufn = factor(); - if (buf && bufi) { - T *bufd = *buf; - long k = min((long)n,bufn-bufi); - COPY(bufd+bufi,data,k); - bufi+=k; data+=k; n-=k; - if (bufi==bufn) { - long newdex = dex+bufn; - CHECK_ALIGN(bufd,sender->nt); - try {gh->flow(this,dex,bufn,bufd);} CATCH_IT; - dex = newdex; - bufi = 0; - } - } - int m = (n/bufn)*bufn; - if (m) { - int newdex = dex + m; - try {gh->flow(this,dex,m,data);} CATCH_IT; - dex = newdex; - } - data += m; - n -= m; - if (buf && n>0) COPY((T *)*buf+bufi,data,n), bufi+=n; -} - -void GridInlet::finish() { - if (!dim) RAISE("inlet not busy"); - if (dim->prod() != dex) post("%s: incomplete grid: %ld of %ld from [%s] to [%s]", - ARGS(parent),dex,long(dim->prod()),ARGS(sender->parent),ARGS(parent)); -#define FOO(T) try {gh->flow(this,dex,-2,(T *)0);} CATCH_IT; - TYPESWITCH(sender->nt,FOO,) -#undef FOO - dim=0; buf=0; dex=0; -} - -template void GridInlet::from_grid2(Grid *g, T foo) { - GridOutlet out(0,-1,g->dim,g->nt); - begin(&out); - size_t n = g->dim->prod(); - if (n) out.send(n,(T *)*g); else finish(); -} - -void GridInlet::from_grid(Grid *g) { - if (!supports_type(g->nt)) RAISE("number type %s not supported here",number_type_table[g->nt].name); -#define FOO(T) from_grid2(g,(T)0); - TYPESWITCH(g->nt,FOO,) -#undef FOO -} - -/* **************** GridOutlet ************************************ */ - -GridOutlet::GridOutlet(FObject *parent_, int woutlet, P dim_, NumberTypeE nt_) { - parent=parent_; dim=dim_; nt=nt_; dex=0; bufi=0; buf=0; - t_atom a[1]; - SETGRIDOUT(a,this); - if (parent) { - outlet_anything(parent->bself->outlets[woutlet],bsym._grid,1,a); - if (!dim->prod()) finish(); - } -} - -void GridOutlet::create_buf () { - int32 lcm_factor = 1; - for (uint32 i=0; ifactor()); - //size_t ntsz = number_type_table[nt].size; - // biggest packet size divisible by lcm_factor - int32 v = (MAX_PACKET_SIZE/lcm_factor)*lcm_factor; - if (v==0) v=MAX_PACKET_SIZE; // factor too big. don't have a choice. - buf=new Grid(new Dim(v),nt); -#ifdef TRACEBUFS - std::ostringstream text; - oprintf(text,"GridOutlet: %20s buf for sending to ",buf->dim->to_s()); - for (uint i=0; iparent; - post("%s",text.str().data()); -#endif -} - -// send modifies dex; send_direct doesn't -template -void GridOutlet::send_direct(long n, T *data) { - CHECK_BUSY(outlet); CHECK_TYPE(*data,nt); CHECK_ALIGN(data,nt); - while (n>0) { - long pn = n;//min((long)n,MAX_PACKET_SIZE); - for (uint32 i=0; iflow(pn,data);} CATCH_IT; - data+=pn, n-=pn; - } -} - -void GridOutlet::flush() { - if (!buf) return; - if (!bufi) return; -#define FOO(T) send_direct(bufi,(T *)*buf); - TYPESWITCH(buf->nt,FOO,) -#undef FOO - bufi = 0; -} - -template -static void convert_number_type(int n, T *out, S *in) {for (int i=0; i -void GridOutlet::send_2(long n, T *data) { - //if (inlets.size()==1 && inlets[0]->buf) post("GridOutlet::send(%ld), bufsize %ld",long(n),long(inlets[0]->buf->dim->prod())); - if (!n) return; - CHECK_BUSY(outlet); CHECK_ALIGN(data,nt); - if (NumberTypeE_type_of(data)!=nt) { - int bs = MAX_PACKET_SIZE; -#define FOO(T) {T data2[bs]; \ - for (;n>=bs;n-=bs,data+=bs) {convert_number_type(bs,data2,data); send(bs,data2);} \ - convert_number_type(n,data2,data); send(n,data2);} - TYPESWITCH(nt,FOO,) -#undef FOO - } else { - dex += n; - if (n > MIN_PACKET_SIZE || bufi + n > MAX_PACKET_SIZE) flush(); - if (n > MIN_PACKET_SIZE) { - //post("send_direct %d",n); - send_direct(n,data); - } else { - //post("send_indirect %d",n); - if (!buf) create_buf(); - COPY((T *)*buf+bufi,data,n); - bufi += n; - } - if (dex==dim->prod()) finish(); - } -} - -void GridOutlet::callback(GridInlet *in) { - CHECK_BUSY1(outlet); - inlets.push_back(in); -} - -void GridOutlet::finish () { - flush(); - for (uint32 i=0; ifinish(); - dim=0; -} - -// never call this. this is a hack to make some things work. -// i'm trying to circumvent either a bug in the compiler or i don't have a clue. :-( -void make_gimmick () { - GridOutlet foo(0,0,0); -#define FOO(S) foo.send(0,(S *)0); -EACH_NUMBER_TYPE(FOO) -#undef FOO - //foo.send(0,(float64 *)0); // this doesn't work, when trying to fix the new link problem in --lite mode. -} diff --git a/externals/gridflow/src/gridflow.cxx b/externals/gridflow/src/gridflow.cxx deleted file mode 100644 index d30c8f4a..00000000 --- a/externals/gridflow/src/gridflow.cxx +++ /dev/null @@ -1,961 +0,0 @@ -/* - $Id: rubyext.c 3621 2008-04-19 01:47:38Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include - -#ifndef HAVE_DESIREDATA -#include "bundled/g_canvas.h" -#endif - -/* for exception-handling in 0.9.0... Linux-only */ -#ifndef MACOSX -#include -#include -#endif -#undef check - -std::map fclasses; -std::map fclasses_pd; - -//using namespace std; - -BuiltinSymbols bsym; - -Barf::Barf(const char *s, ...) { - std::ostringstream os; - va_list ap; - va_start(ap,s); - voprintf(os,s,ap); - va_end(ap); - text = os.str(); -} -Barf::Barf(const char *file, int line, const char *func, const char *fmt, ...) { - std::ostringstream os; - va_list ap; - va_start(ap,fmt); - voprintf(os,fmt,ap); - //oprintf(os,"\n%s:%d:in `%s'",file,line,func); - va_end(ap); - text = os.str(); -} - -void Barf::error(BFObject *bself) { - if (bself) pd_error(bself,"%s: %s",bself->binbuf_string().data(),text.data()); - else ::error( "%s: %s",bself->binbuf_string().data(),text.data()); -} - -void pd_oprint (std::ostream &o, int argc, t_atom *argv) { - for (int i=0; is_name; - else if (t==A_POINTER) o << "(pointer)"; - else if (t==A_COMMA) o << ","; - else if (t==A_SEMI) o << ";"; - else if (t==A_LIST) { - t_binbuf *b = (t_binbuf *)argv[i].a_gpointer; - o << "["; - pd_oprint(o,binbuf_getnatom(b),binbuf_getvec(b)); - o << "]"; - } else o << "(atom of type " << t << ")"; - if (i!=argc-1) o << " "; - } -} - -void pd_post (const char *s, int argc, t_atom *argv) { - std::ostringstream os; - if (s) os << s << ": "; - pd_oprint(os,argc,argv); - post("%s",os.str().data()); -} - -void pd_oprintf (std::ostream &o, const char *s, int argc, t_atom *argv) { - int i=0; - for (; *s; s++) { - if (*s!='%') {o << (char)*s; continue;} - s++; // skip the % - switch (*s) { - case 'f': - if (!argc) RAISE("not enough args"); - if (argv[i].a_type != A_FLOAT) RAISE("expected float"); - o << argv[i++].a_float; - break; - case 's': - if (!argc) RAISE("not enough args"); - if (argv[i].a_type != A_SYMBOL) RAISE("expected symbol"); - o << argv[i++].a_symbol->s_name; - break; - case '_': - if (!argc) RAISE("not enough args"); - char buf[MAXPDSTRING]; - atom_string(&argv[i++],buf,MAXPDSTRING); - o << buf; - break; - case '%': - o << "%"; - break; - default: - RAISE("sorry, the format character '%c' is not supported yet",*s); - } - } -} - -//---------------------------------------------------------------- -// Dim - -void Dim::check() { - if (n>MAX_DIM) RAISE("too many dimensions"); - for (int i=0; iindex; -} - -NumberTypeE NumberTypeE_find (const t_atom &x) { - if (x.a_type!=A_SYMBOL) RAISE("expected number-type (as symbol)"); - return NumberTypeE_find(string(x.a_symbol->s_name)); -} - -// don't touch. -static void gfmemcopy32(int32 *as, int32 *bs, long n) { - ptrdiff_t ba = bs-as; -#define FOO(I) as[I] = (as+ba)[I]; - UNROLL_8(FOO,n,as) -#undef FOO -} - -void gfmemcopy(uint8 *out, const uint8 *in, long n) { - for (; n>16; in+=16, out+=16, n-=16) { - ((int32*)out)[0] = ((int32*)in)[0]; - ((int32*)out)[1] = ((int32*)in)[1]; - ((int32*)out)[2] = ((int32*)in)[2]; - ((int32*)out)[3] = ((int32*)in)[3]; - } - for (; n>4; in+=4, out+=4, n-=4) *(int32*)out = *(int32*)in; - for (; n; in++, out++, n--) *out=*in; -} - -//---------------------------------------------------------------- - -uint64 gf_timeofday () { - timeval t; - gettimeofday(&t,0); - return t.tv_sec*1000000+t.tv_usec; -} - -#define CONVERT0(z) ((in[z] >> chop[z]) << slide[z]) -#define CONVERT1 t = CONVERT0(0) | CONVERT0(1) | CONVERT0(2) -#define CONVERT2 for (t=0,i=0; isize; i++) t |= CONVERT0(i); - -#define WRITE_LE \ - for (int bytes = self->bytes; bytes; bytes--, t>>=8) *out++ = t; - -#define WRITE_BE {int bytes; \ - bytes = self->bytes; \ - while (bytes--) {out[bytes] = t; t>>=8;}\ - out += self->bytes;} - -/* this macro would be faster if the _increment_ - was done only once every loop. or maybe gcc does it, i dunno */ -#define NTIMES(_x_) \ - for (; n>=4; n-=4) {_x_ _x_ _x_ _x_} \ - for (; n; n--) {_x_} - -/* this could be faster (use asm) */ -void swap64 (long n, uint64 *data) { - NTIMES({ - uint64 x = *data; - x = (x<<32) | (x>>32); - x = ((x&0x0000ffff0000ffffLL)<<16) | ((x>>16)&0x0000ffff0000ffffLL); - x = ((x&0x00ff00ff00ff00ffLL)<< 8) | ((x>> 8)&0x00ff00ff00ff00ffLL); - *data++ = x; - }) -} - -/* this could be faster (use asm) */ -void swap32 (long n, uint32 *data) { - NTIMES({ - uint32 x = *data; - x = (x<<16) | (x>>16); - x = ((x&0xff00ff)<<8) | ((x>>8)&0xff00ff); - *data++ = x; - }) -} - -/* this could be faster (use asm or do it in int32 chunks) */ -void swap16 (long n, uint16 *data) {NTIMES({ uint16 x = *data; *data++ = (x<<8) | (x>>8); })} - -/* **************************************************************** */ - -//#define DEBUG 1 -#ifdef DEBUG -#define TRACE static int use=0; use++; if ((use%10000)==0) post("%s",__PRETTY_FUNCTION__); -#else -#define TRACE -#endif - -template -static void default_pack(BitPacking *self, long n, T *in, uint8 *out) {TRACE - uint32 t; - int i; - int sameorder = self->endian==2 || self->endian==::is_le(); - int size = self->size; - uint32 mask[4]; memcpy(mask,self->mask,size*sizeof(uint32)); - uint32 hb[4]; for (i=0; ibytes) { - case 2: NTIMES(CONVERT1; *((int16 *)out)=t; out+=2; in+=3;) return; - case 4: NTIMES(CONVERT1; *((int32 *)out)=t; out+=4; in+=3;) return; - } - } - if (self->is_le()) { - switch (size) { - case 3: for (; n--; in+=3) {CONVERT1; WRITE_LE;} break; - case 4: for (; n--; in+=4) {CONVERT1; WRITE_LE;} break; - default:for (; n--; in+=size) {CONVERT2; WRITE_LE;}} - } else { - switch (size) { - case 3: for (; n--; in+=3) {CONVERT1; WRITE_BE;} break; - case 4: for (; n--; in+=4) {CONVERT1; WRITE_BE;} break; - default:for (; n--; in+=size) {CONVERT2; WRITE_BE;}} - } -} - -#define LOOP_UNPACK(_reader_) \ - for (; n; n--) { \ - int bytes=0; uint32 temp=0; _reader_; \ - for (int i=0; isize; i++, out++) { \ - uint32 t=temp&self->mask[i]; \ - *out = (t<<(7-hb[i]))|(t>>(hb[i]-7));}} - -template -static void default_unpack(BitPacking *self, long n, uint8 *in, T *out) {TRACE - int hb[4]; - for (int i=0; isize; i++) hb[i] = highest_bit(self->mask[i]); - if (is_le()) { // smallest byte first - LOOP_UNPACK( - for(; self->bytes>bytes; bytes++, in++) temp |= *in<<(8*bytes); - ) - } else { // biggest byte first - LOOP_UNPACK( - bytes=self->bytes; for (; bytes; bytes--, in++) temp=(temp<<8)|*in; - ) - } -} - -/* **************************************************************** */ - -template -static void pack2_565(BitPacking *self, long n, T *in, uint8 *out) {TRACE - uint32 chop[3] = {3,2,3}; - uint32 slide[3] = {11,5,0}; - uint32 t; - NTIMES(CONVERT1; *((short *)out)=t; out+=2; in+=3;) -} - -template -static void pack3_888(BitPacking *self, long n, T *in, uint8 *out) {TRACE - int32 *o32 = (int32 *)out; - while (n>=4) { - o32[0] = (in[5]<<24) | (in[ 0]<<16) | (in[ 1]<<8) | in[2]; - o32[1] = (in[7]<<24) | (in[ 8]<<16) | (in[ 3]<<8) | in[4]; - o32[2] = (in[9]<<24) | (in[10]<<16) | (in[11]<<8) | in[6]; - o32+=3; in+=12; - n-=4; - } - out = (uint8 *)o32; - NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=3; in+=3; ) -} -/* -template <> -static void pack3_888(BitPacking *self, long n, uint8 *in, uint8 *out) {TRACE - uint32 *o32 = uint32 *((uint32 *)out.p,n*3/4); - uint32 *i32 = uint32 *((uint32 *)in.p,n*3/4); - while (n>=4) { -#define Z(w,i) ((word##w>>(i*8))&255) - uint32 word0 = i32[0]; - uint32 word1 = i32[1]; - uint32 word2 = i32[2]; - o32[0] = (Z(1,1)<<24) | (Z(0,0)<<16) | (Z(0,1)<<8) | Z(0,2); - o32[1] = (Z(1,3)<<24) | (Z(2,0)<<16) | (Z(0,3)<<8) | Z(1,0); - o32[2] = (Z(2,1)<<24) | (Z(2,2)<<16) | (Z(2,3)<<8) | Z(1,2); - o32+=3; i32+=3; - n-=4; - } -#undef Z - out = (uint8 *)o32; - in = (uint8 *)i32; - NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=3; in+=3; ) -} -*/ - -template static void unpack3_888 (BitPacking *self, long n, uint8 *in, T *out) {TRACE - NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=3; in+=3; ) -} -template static void pack3_888c(BitPacking *self, long n, T *in, uint8 *out) {TRACE - NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out[3]=0; out+=4; in+=3; ) -} -template static void pack3_888d(BitPacking *self, long n, T *in, uint8 *out) {TRACE - NTIMES( out[0]=in[0]; out[1]=in[1]; out[2]=in[2]; out[3]=0; out+=4; in+=3; ) -} -template static void unpack3_888d(BitPacking *self, long n, uint8 *in, T *out) {TRACE - NTIMES( out[0]=in[0]; out[1]=in[1]; out[2]=in[2]; out+=3; in+=4; ) -} -template static void pack3_bgrn8888b(BitPacking *self, long n, T *in, uint8 *out) {TRACE - NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out[3]=0; out+=4; in+=4; ) -} - -template -static void pack3_888b(BitPacking *self, long n, T *in, uint8 *out) {TRACE - int32 *o32 = (int32 *)out; - while (n>=4) { - o32[0] = (in[0]<<16) | (in [1]<<8) | in [2]; - o32[1] = (in[3]<<16) | (in [4]<<8) | in [5]; - o32[2] = (in[6]<<16) | (in [7]<<8) | in [8]; - o32[3] = (in[9]<<16) | (in[10]<<8) | in[11]; - o32+=4; in+=12; - n-=4; - } - NTIMES( o32[0] = (in[0]<<16) | (in[1]<<8) | in[2]; o32++; in+=3; ) -} - -// (R,G,B,?) -> B:8,G:8,R:8,0:8 -static void pack3_bgrn8888(BitPacking *self, long n, uint8 *in, uint8 *out) {TRACE -/* NTIMES( out[2]=in[0]; out[1]=in[1]; out[0]=in[2]; out+=4; in+=4; ) */ - int32 *i32 = (int32 *)in; - int32 *o32 = (int32 *)out; - while (n>=4) { - o32[0] = ((i32[0]&0xff)<<16) | (i32[0]&0xff00) | ((i32[0]>>16)&0xff); - o32[1] = ((i32[1]&0xff)<<16) | (i32[1]&0xff00) | ((i32[1]>>16)&0xff); - o32[2] = ((i32[2]&0xff)<<16) | (i32[2]&0xff00) | ((i32[2]>>16)&0xff); - o32[3] = ((i32[3]&0xff)<<16) | (i32[3]&0xff00) | ((i32[3]>>16)&0xff); - o32+=4; i32+=4; n-=4; - } - NTIMES( o32[0] = ((i32[0]&0xff)<<16) | (i32[0]&0xff00) | ((i32[0]>>16)&0xff); o32++; i32++; ) -} - -static uint32 bp_masks[][4] = { - {0x0000f800,0x000007e0,0x0000001f,0}, - {0x00ff0000,0x0000ff00,0x000000ff,0}, - {0x000000ff,0x0000ff00,0x00ff0000,0}, -}; - -#define ANYCASE(a) {a,a,a} -static Packer bp_packers[] = { - ANYCASE(default_pack), - ANYCASE(pack2_565), - ANYCASE(pack3_888), - {pack3_888b, default_pack, default_pack}, /* {pack3_888c, pack3_888c, pack3_888c}, not tested */ - {pack3_bgrn8888, pack3_bgrn8888b, pack3_bgrn8888b}, - ANYCASE(pack3_888d), -}; - -static Unpacker bp_unpackers[] = { - ANYCASE(default_unpack), - ANYCASE(unpack3_888), - {pack3_bgrn8888, default_unpack, default_unpack}, - ANYCASE(unpack3_888d), -}; - -static BitPacking builtin_bitpackers[] = { - BitPacking(2, 2, 3, bp_masks[0], &bp_packers[1], &bp_unpackers[0]), - BitPacking(1, 3, 3, bp_masks[1], &bp_packers[2], &bp_unpackers[1]), - BitPacking(1, 4, 3, bp_masks[1], &bp_packers[3], &bp_unpackers[0]), - BitPacking(1, 4, 4, bp_masks[1], &bp_packers[4], &bp_unpackers[2]), - BitPacking(1, 4, 3, bp_masks[2], &bp_packers[5], &bp_unpackers[3]), -}; - -/* **************************************************************** */ - -bool BitPacking::eq(BitPacking *o) { - if (!(bytes == o->bytes)) return false; - if (!(size == o->size)) return false; - for (int i=0; imask[i])) return false; - } - if (endian==o->endian) return true; - /* same==little on a little-endian; same==big on a big-endian */ - return (endian ^ o->endian ^ ::is_le()) == 2; -} - -void post_BitPacking(BitPacking *b) { - ::post("Bitpacking: endian=%d bytes=%d size=%d packer=%d unpacker=%d", - b->endian,b->bytes,b->size,b->packer-bp_packers,b->unpacker-bp_unpackers); - ::post(" mask=[0x%08x,0x%08x,0x%08x,0x%08x]",b->mask[0],b->mask[1],b->mask[2],b->mask[3]); -} - -BitPacking::BitPacking(int endian, int bytes, int size, uint32 *mask, Packer *packer, Unpacker *unpacker) { - this->endian = endian; - this->bytes = bytes; - this->size = size; - for (int i=0; imask[i] = mask[i]; - if (packer) { - this->packer = packer; - this->unpacker = unpacker; - return; - } - int packeri=-1; - this->packer = &bp_packers[0]; - this->unpacker = &bp_unpackers[0]; - for (int i=0; i<(int)(sizeof(builtin_bitpackers)/sizeof(BitPacking)); i++) { - BitPacking *bp = &builtin_bitpackers[i]; - if (this->eq(bp)) { - this-> packer = bp-> packer; - this->unpacker = bp->unpacker; - packeri=i; - goto end; - } - } -end:; -} - -bool BitPacking::is_le() {return endian==1 || (endian ^ ::is_le())==3;} - -#undef TRACE -#ifdef DEBUG -#define TRACE static int use=0; use++; if ((use%10000)==0) post_BitPacking(this); -#else -#define TRACE -#endif -template void BitPacking:: pack(long n, T *in, uint8 *out) {TRACE - switch (NumberTypeE_type_of(in)) { - case uint8_e: packer->as_uint8(this,n,(uint8 *)in,out); break; - case int16_e: packer->as_int16(this,n,(int16 *)in,out); break; - case int32_e: packer->as_int32(this,n,(int32 *)in,out); break; - default: RAISE("argh");}} -template void BitPacking::unpack(long n, uint8 *in, T *out) {TRACE - switch (NumberTypeE_type_of(out)) { - case uint8_e: unpacker->as_uint8(this,n,in,(uint8 *)out); break; - case int16_e: unpacker->as_int16(this,n,in,(int16 *)out); break; - case int32_e: unpacker->as_int32(this,n,in,(int32 *)out); break; - default: RAISE("argh");}} - -// i'm sorry... see the end of grid.c for an explanation... -//static -void make_hocus_pocus () { -// exit(1); -#define FOO(S) \ - ((BitPacking*)0)-> pack(0,(S *)0,(uint8 *)0); \ - ((BitPacking*)0)->unpack(0,(uint8 *)0,(S *)0); -EACH_NUMBER_TYPE(FOO) -#undef FOO -} - -std::vector gf_data_path; -string gf_find_file (string x) { - if (strchr(x.data(),'/')) return x; - int n = gf_data_path.size(); - struct stat dummy; - for (int i=0; iname.data()) - -static FMethod funcall_lookup (FClass *fclass, const char *sel) { - int n = fclass->methodsn; - for (int i=0; imethods[i].selector,sel)==0) return fclass->methods[i].method; - if (fclass->super) return funcall_lookup(fclass->super,sel); - return 0; -} -static FMethod funcall_lookup (BFObject *bself, const char *sel) { - return funcall_lookup(fclasses_pd[pd_class(bself)],sel); -} - -void call_super(int argc, t_atom *argv) {/* unimplemented */} - -//**************************************************************** -// BFObject - -struct BFProxy : t_object { - BFObject *parent; - t_inlet *inlet; - int id; -}; - -static t_class *BFProxy_class; - -static void BFObject_loadbang (BFObject *bself) { - FMethod m = funcall_lookup(bself,"_0_loadbang"); - m(bself->self,0,0); -} - -static void BFObject_anything (BFObject *bself, int winlet, t_symbol *selector, int ac, t_atom2 *at) { - try { - t_atom2 argv[ac+1]; - for (int i=0; is_name); - FMethod m; - m = funcall_lookup(bself,buf); - if (m) {m(bself->self,argc+1,argv); return;} - sprintf(buf,"_%d_%s",winlet,selector->s_name); - m = funcall_lookup(bself,buf); - if (m) {m(bself->self,argc,argv+1); return;} - m = funcall_lookup(bself,"anything"); - if (m) {SETSYMBOL(argv+0,gensym(buf)); m(bself->self,argc+1,argv); return;} - pd_error((t_pd *)bself, "method '%s' not found for inlet %d in class '%s'",selector->s_name,winlet,pd_classname(bself)); - } catch (Barf &oozy) {oozy.error(bself);} -} -static void BFObject_anything0 (BFObject *self, t_symbol *s, int argc, t_atom2 *argv) { - BFObject_anything(self,0,s,argc,argv); -} -static void BFProxy_anything (BFProxy *self, t_symbol *s, int argc, t_atom2 *argv) { - BFObject_anything(self->parent,self->id,s,argc,argv); -} - -static void *BFObject_new (t_symbol *classsym, int ac, t_atom *at) { - string name = string(classsym->s_name); - if (fclasses.find(name)==fclasses.end()) {post("GF: class not found: '%s'",classsym->s_name); return 0;} - t_class *qlass = fclasses[name]->bfclass; - BFObject *bself = (BFObject *)pd_new(qlass); - try { - int argc = ac; - t_atom argv[argc]; - for (int i=0; is_name,argc,argv); - int j; - for (j=0; jself = 0; - bself->mom = (t_canvas *)canvas_getcurrent(); - bself->ninlets = 1; - bself->noutlets = 0; - bself->inlets = new BFProxy*[1]; - bself->outlets = new t_outlet*[1]; - bself->inlets[0] = 0; // inlet 0 of this table is not in use - bself->ninlets_set( fclasses[classsym->s_name]->ninlets ,false); - bself->noutlets_set(fclasses[classsym->s_name]->noutlets,false); - t_allocator alloc = fclasses[string(classsym->s_name)]->allocator; - bself->self = alloc(bself,0,j,(t_atom2 *)argv); - while (jself;} catch (Barf &oozy) {oozy.error(bself);} - bself->ninlets_set(1,false); - delete[] bself->inlets; - delete[] bself->outlets; -} - -//**************************************************************** - -static void BFObject_undrawio (BFObject *bself) { -#ifndef HAVE_DESIREDATA - if (!bself->mom || !glist_isvisible(bself->mom)) return; - t_rtext *rt = glist_findrtext(bself->mom,bself); - if (!rt) return; - glist_eraseiofor(bself->mom,bself,rtext_gettag(rt)); -#endif -} - -static void BFObject_redraw (BFObject *bself) { -#ifndef HAVE_DESIREDATA - if (!bself->mom || !glist_isvisible(bself->mom)) return; - t_rtext *rt = glist_findrtext(bself->mom,bself); - if (!rt) return; - gobj_vis((t_gobj *)bself,bself->mom,0); - gobj_vis((t_gobj *)bself,bself->mom,1); - canvas_fixlinesfor(bself->mom,(t_text *)bself); -#endif -} - -/* warning: deleting inlets that are connected will cause pd to crash */ -void BFObject::ninlets_set (int n, bool draw) { - if (!te_binbuf) draw=false; - if (n<1) RAISE("ninlets_set: n=%d must be at least 1",n); - if (draw) BFObject_undrawio(this); - if (ninletsparent = this; - p->id = ninlets; - p->inlet = inlet_new(this, &p->ob_pd, 0,0); - ninlets++; - } - } else { - while (ninlets>n) { - ninlets--; - inlet_free(inlets[ninlets]->inlet); - pd_free((t_pd *)inlets[ninlets]); - } - } - if (draw) BFObject_redraw(this); -} -/* warning: deleting outlets that are connected will cause pd to crash */ -void BFObject::noutlets_set (int n, bool draw) { - if (!te_binbuf) draw=false; - if (n<0) RAISE("noutlets_set: n=%d must be at least 0",n); - if (draw) BFObject_undrawio(this); - if (noutlets0?n:1]; - memcpy(noo,outlets,noutlets*sizeof(t_outlet*)); - delete[] outlets; - outlets = noo; - while (noutletsn) outlet_free(outlets[--noutlets]); - } - if (draw) BFObject_redraw(this); -} - -string BFObject::binbuf_string () { - if (!te_binbuf) return "[???]"; - std::ostringstream s; - int n = binbuf_getnatom(te_binbuf); - t_atom *at = binbuf_getvec(te_binbuf); - for (int i=0; ic_nmethod-1; i>=0; i--) { - t_methodentry *m = c->c_methods+i; - if (m->me_name==want) {m->me_fun = t_gotfn(BFObject_new); m->me_arg[0]=A_GIMME; m->me_arg[1]=A_NULL; break;} - } -} - -//**************************************************************** - -struct t_namelist; -extern t_namelist *sys_searchpath, *sys_helppath; -extern "C" t_namelist *namelist_append_files(t_namelist *, char *); -static void add_to_path(char *dir) { - static bool debug = false; - char bof[1024]; - if (debug) post("gridflow was found in %s",dir); - gf_data_path.push_back(string(dir)+"/images"); - if (debug) post("adding gf_data_path %s/images",dir); - sprintf(bof,"%s/abstractions",dir); sys_searchpath = namelist_append_files(sys_searchpath,bof); - if (debug) post("adding -path %s",bof); - sprintf(bof,"%s/deprecated",dir); sys_searchpath = namelist_append_files(sys_searchpath,bof); - if (debug) post("adding -path %s",bof); - sprintf(bof,"%s/doc/flow_classes",dir); sys_helppath = namelist_append_files(sys_helppath, bof); - if (debug) post("adding -helppath %s",bof); -} - -//---------------------------------------------------------------- - -t_list *list_new (int argc, t_atom *argv) { - t_list *b = binbuf_new(); - binbuf_add(b,argc,argv); - return b; -} -void list_free (t_list *self) {binbuf_free(self);} - -//---------------------------------------------------------------- - -void fclass_install(FClass *fclass, FClass *super, size_t bytes) { - fclass->super = super; - if (fclass->startup) fclass->startup(fclass); - fclass->bytes = bytes; -} - -void install2(FClass *fclass, const char *name, int inlets, int outlets) { - fclass->ninlets = inlets; - fclass->noutlets = outlets; - fclass->name = string(name); - fclass->bfclass = class_new(gensym((char *)name), (t_newmethod)BFObject_new, (t_method)BFObject_delete, - sizeof(BFObject), CLASS_DEFAULT, A_GIMME,0); - fclasses[string(name)] = fclass; - fclasses_pd[fclass->bfclass] = fclass; - t_class *b = fclass->bfclass; - class_addanything(b,t_method(BFObject_anything0)); - FMethod m = funcall_lookup(fclass,"_0_loadbang"); - //post("class %s loadbang %08x",name,long(m)); - if (m) class_addmethod(fclass->bfclass,t_method(BFObject_loadbang),gensym("loadbang"),A_NULL); -} - -/* This code handles nested lists because PureData (all versions including 0.40) doesn't do it */ -int handle_braces(int ac, t_atom *av) { - int stack[16]; - int stackn=0; - int j=0; - t_binbuf *buf = binbuf_new(); - for (int i=0; is_name; - while (*s=='(') { - if (stackn==16) {binbuf_free(buf); RAISE("too many nested lists (>16)");} - stack[stackn++]=j; - s++; - } - const char *se = s+strlen(s); - while (se>s && se[-1]==')') {se--; close++;} - if (s!=se) { - binbuf_text(buf,(char *)s,se-s); - if ((binbuf_getnatom(buf)==1 && binbuf_getvec(buf)[0].a_type==A_FLOAT) || binbuf_getvec(buf)[0].a_type==A_COMMA) { - av[j++] = binbuf_getvec(buf)[0]; - } else { - char ss[MAXPDSTRING]; - int n = min(long(se-s),long(MAXPDSTRING-1)); - sprintf(ss,"%.*s",n,s); - SETSYMBOL(av+j,gensym(ss)); j++; // av[j++] = gensym(s); - } - } - } else av[j++]=av[i]; - i++; - while (close--) { - if (!stackn) {binbuf_free(buf); RAISE("close-paren without open-paren",av[i]);} - t_binbuf *a2 = binbuf_new(); /* leak because there is no deallocation mechanism whatsoever */ - int j2 = stack[--stackn]; - binbuf_add(a2,j-j2,av+j2); - j=j2; - SETLIST(av+j,a2); - j++; - } - } - binbuf_free(buf); - if (stackn) RAISE("too many open-paren (%d)",stackn); - return j; -} - -// foreach macro from desiredata: -#define foreach(ITER,COLL) for(typeof(COLL.begin()) ITER = COLL.begin(); ITER != (COLL).end(); ITER++) - -\class FObject -\def 0 get (t_symbol *s=0) { - FClass *fc = fclasses_pd[pd_class(bself)]; - if (!s) { - t_atom a[1]; - foreach(attr,fc->attrs) { - SETSYMBOL(a,gensym((char *)attr->second->name.data())); - pd_typedmess((t_pd *)bself,gensym("get"),1,a); - } - } else { - //t_atom a[1]; - //outlet_anything(bself->outlets[bself->noutlets-1],s,1,a); - FMethod m = funcall_lookup(bself,"___get"); - t_atom2 a[1]; - SETSYMBOL(a,s); - if (m) m(this,1,a); - } -} -\def 0 help () { - FClass *fc = fclasses_pd[pd_class(bself)]; - post("attributes ("); - foreach(attr,fc->attrs) post(" %s %s;",attr->second->type.data(),attr->second->name.data()); - post(")"); - post("methods ("); - for (int i=0; imethodsn; i++) post(" %s",fc->methods[i].selector); - post(")"); -} -\classinfo {} -\end class - -void startup_number(); -void startup_flow_objects(); -void startup_flow_objects2(); -void startup_format(); -STARTUP_LIST(void) - -void blargh () { -#ifdef MACOSX - fprintf(stderr,"unhandled exception\n"); -#else - void *array[25]; - int nSize = backtrace(array, 25); - char **symbols = backtrace_symbols(array, nSize); - for (int i=0; igl_list; - while (g->g_next) g=g->g_next; -#endif - return g; -} - -#ifdef DESIRE -extern "C" void canvas_delete(t_canvas *, t_gobj *); -#define glist_delete canvas_delete -#endif - -static void canvas_else (t_canvas *self, t_symbol *s, int argc, t_atom *argv) { - t_gobj *g = canvas_last(self); - if (pd_newest()) return; - glist_delete(self,g); - if (argc<1 || argv[0].a_type!=A_SYMBOL) {error("$1 must be a symbol"); return;} - pd_typedmess((t_pd *)self,argv[0].a_w.w_symbol,argc-1,argv+1); -} - -// those are not really leaks but deleting them make them disappear from valgrind -// however, there's still a problem doing it, so, we won't do it. -static void gridflow_unsetup () { -/* - foreach(iter,fclasses_pd) { - FClass *fc = iter->second; - foreach(iter2,fc->attrs) delete iter2->second; - fc->FClass::~FClass(); - } -*/ -} - -void allow_big_stack () { - struct rlimit happy; - if (0>getrlimit(RLIMIT_STACK,&happy)) - error("GF: getrlimit: %s",strerror(errno)); - happy.rlim_cur = happy.rlim_max; - if (0>setrlimit(RLIMIT_STACK,&happy)) - error("GF: setting stack size to %ld: %s",happy.rlim_cur,strerror(errno)); - else - post( "GF: setting stack size to %ld",happy.rlim_cur); -} - -// note: contrary to what m_pd.h says, pd_getfilename() and pd_getdirname() -// don't exist; also, canvas_getcurrentdir() isn't available during setup -// (segfaults), in addition to libraries not being canvases ;-) -// AND ALSO, CONTRARY TO WHAT m_pd.h SAYS, open_via_path()'s args are reversed!!! -extern "C" void gridflow_setup () { - post("GridFlow " GF_VERSION ", Copyright (c) 2001-2009 Mathieu Bouchard"); - post("GridFlow was compiled on "__DATE__", "__TIME__); - //std::set_terminate(__gnu_cxx::__verbose_terminate_handler); - std::set_terminate(blargh); - allow_big_stack(); - try { - char *dirname = new char[MAXPDSTRING]; - char *dirresult = new char[MAXPDSTRING]; - char *nameresult; - char *zz=getcwd(dirname,MAXPDSTRING); /* zz only exists because gcc 4.3.3 gives me a bogus warning otherwise. */ - if (zz<0) {post("AAAARRRRGGGGHHHH!"); exit(69);} - int fd=open_via_path(dirname,"gridflow/gridflow",PDSUF,dirresult,&nameresult,MAXPDSTRING,1); - if (fd<0) fd=open_via_path(dirname, "gridflow",PDSUF,dirresult,&nameresult,MAXPDSTRING,1); - if (fd>=0) close(fd); else post("%s was not found via the -path!","gridflow"PDSUF); - /* nameresult is only a pointer in dirresult space so don't delete[] it. */ - add_to_path(dirresult); - BFProxy_class = class_new(gensym("gf.proxy"),0,0,sizeof(BFProxy),CLASS_PD|CLASS_NOINLET, A_NULL); - class_addanything(BFProxy_class,BFProxy_anything); - srandom(rdtsc()); -#define FOO(_sym_,_name_) bsym._sym_ = gensym(_name_); -BUILTIN_SYMBOLS(FOO) -#undef FOO - startup_number(); - \startall - startup_flow_objects(); - startup_flow_objects2(); - startup_format(); - STARTUP_LIST() - //sys_gui("bind . {puts %W}\n"); - sys_vgui("proc gridflow_add_to_help {menu} {\n" - "$menu add separator\n" - "$menu add command -label {GridFlow About} -command {pd pd open about.pd %s/doc \\;}\n" - "$menu add command -label {GridFlow Index} -command {pd pd open index.pd %s/doc \\;}\n" - "}\n" - "gridflow_add_to_help .mbar.help\n" - "rename menu_addstd menu_addstd_old\n" - "proc menu_addstd {mbar} {menu_addstd_old $mbar; gridflow_add_to_help $mbar.help}\n",dirresult,dirresult); - delete[] dirresult; - delete[] dirname; - } catch (Barf &oozy) {oozy.error(0);} - signal(SIGSEGV,SIG_DFL); - signal(SIGABRT,SIG_DFL); - signal(SIGBUS, SIG_DFL); - atexit(gridflow_unsetup); - extern t_class *canvas_class; - class_addmethod(canvas_class,(t_method)canvas_else,gensym("else"),A_GIMME,0); -} diff --git a/externals/gridflow/src/gridflow.hxx b/externals/gridflow/src/gridflow.hxx deleted file mode 100644 index bf278ffe..00000000 --- a/externals/gridflow/src/gridflow.hxx +++ /dev/null @@ -1,911 +0,0 @@ -/* - $Id: gridflow.h 4535 2009-10-31 14:50:38Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#ifndef __GRIDFLOW_H -#define __GRIDFLOW_H - -#define GF_VERSION "0.9.6" - -#include "m_pd.h" -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __APPLE__ -static inline void *memalign (size_t a, size_t n) {return malloc(n);} -#else -#include -#endif - -typedef std::string string; - -#ifndef a_float -#define a_float a_w.w_float -#define a_symbol a_w.w_symbol -#define a_gpointer a_w.w_gpointer -#endif - -#define gensym(s) gensym(const_cast(s)) -#define sys_vgui(FMT,ARGS...) sys_vgui(const_cast(FMT),ARGS) -#define sys_gui(s) sys_gui(const_cast(s)) - -#ifndef DESIREDATA -#define A_LIST t_atomtype(13) /* (t_binbuf *) */ -#endif -#define A_GRID t_atomtype(14) /* (Grid *) */ -#define A_GRIDOUT t_atomtype(15) /* (GridOut *) */ -// the use of w_gpointer here is fake, just because there's no suitable member in the union -struct Grid; -struct GridOutlet; -static inline void SETLIST( t_atom *a, t_binbuf *b) {a->a_type = A_LIST; a->a_gpointer = (t_gpointer *)b;} -static inline void SETGRID( t_atom *a, Grid *g) {a->a_type = A_GRID; a->a_gpointer = (t_gpointer *)g;} -static inline void SETGRIDOUT(t_atom *a, GridOutlet *g) {a->a_type = A_GRIDOUT; a->a_gpointer = (t_gpointer *)g;} -static inline void SETNULL( t_atom *a) {a->a_type = A_NULL; a->a_gpointer = 0;} - -typedef t_binbuf t_list; - -t_list *list_new (int argc, t_atom *argv); -void list_free (t_list *self); - -typedef char int8; typedef unsigned char uint8; -typedef short int16; typedef unsigned short uint16; -typedef int int32; typedef unsigned int uint32; -typedef long long int64; typedef unsigned long long uint64; -typedef float float32; -typedef double float64; - -// three-way comparison (T is assumed Comparable) -template static inline T cmp(T a, T b) {return ab;} - -// a remainder function such that div2(a,b)*b+mod(a,b) = a and for which mod(a,b) is in [0;b) or (b;0]. -// in contrast to C-language builtin a%b, this one has uniform behaviour around zero, -// that is, the same as around any other whole number. -static inline int mod(int a, int b) {int c=a%b; c+=b&-(c&&(a<0)^(b<0)); return c;} - -// counterpart of mod(a,b), just like a/b and a%b are counterparts -static inline int div2(int a, int b) {return (a/b)-((a<0)&&!!(a%b));} - -static inline int32 gf_abs( int32 a) {return a>0?a:-a;} -static inline int64 gf_abs( int64 a) {return a>0?a:-a;} -static inline float32 gf_abs(float32 a) {return fabs(a);} -static inline float64 gf_abs(float64 a) {return fabs(a);} - -// integer powers in log(b) time. T is assumed Integer -template static inline T ipow(T a, T b) {T r=1; for(;;) {if (b&1) r*=a; b>>=1; if (!b) return r; a*=a;}} -static inline float32 ipow(float32 a, float32 b) {return pow(a,b);} -static inline float64 ipow(float64 a, float64 b) {return pow(a,b);} - -#undef min -#undef max -// minimum/maximum functions; T is assumed to be Comparable -template static inline T min(T a, T b) {return a static inline T max(T a, T b) {return a>b?a:b;} -template static inline T clip(T a, T lower, T upper) {return aupper?upper:a;} -//template inline T min(T a, T b) { T c = (a-b)>>31; return (a&c)|(b&~c); } - -// greatest common divisor, by euclid's algorithm -// this runs in log(a+b) number operations -template static T gcd (T a, T b) { - while (b) {T c=mod(a,b); a=b; b=c;} - return a; -} - -// greatest common divisor, the binary algorithm. haven't tried yet. -template static T gcd2 (T a, T b) { - int s=0; - while (((a|b)&1)==0) { a>>=1; b>>=1; s++; } - while (a) { - if ((a&1)==0) a>>=1; - else if ((b&1)==0) b>>=1; - else {T t=abs(a-b); if (a static inline T lcm (T a, T b) {return a*b/gcd(a,b);} - -// returns the position (0..63) of highest bit set in a word, or 0 if none. -#define Z(N) if ((x>>N)&(((typeof(x))1<>=N; i+=N; } -static int highest_bit(uint8 x) {int i=0; Z(4)Z(2)Z(1)return i;} -static int highest_bit(uint16 x) {int i=0; Z(8)Z(4)Z(2)Z(1)return i;} -static int highest_bit(uint32 x) {int i=0; Z(16)Z(8)Z(4)Z(2)Z(1)return i;} -static int highest_bit(uint64 x) {int i=0;Z(32)Z(16)Z(8)Z(4)Z(2)Z(1)return i;} -#undef Z -// returns the position (0..63) of lowest bit set in a word, or 0 if none. -template static int lowest_bit(T n) { return highest_bit((~n+1)&n); } - -static double drand() { return 1.0*rand()/(RAND_MAX+1.0); } - -// is little-endian -static inline bool is_le() {int x=1; return ((char *)&x)[0];} - -static inline uint64 rdtsc() -#if defined(HAVE_PENTIUM) -{uint64 x; __asm__ volatile (".byte 0x0f, 0x31":"=A"(x)); return x;} -#else -{return 0;} -#endif - -#ifdef HAVE_LITE -#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32) -#define EACH_FLOAT_TYPE(MACRO) MACRO(float32) -#else -#define EACH_INT_TYPE(MACRO) MACRO(uint8) MACRO(int16) MACRO(int32) MACRO(int64) -#define EACH_FLOAT_TYPE(MACRO) MACRO(float32) MACRO(float64) -#endif -#define EACH_NUMBER_TYPE(MACRO) EACH_INT_TYPE(MACRO) EACH_FLOAT_TYPE(MACRO) - -// note: loop unrolling macros assume N!=0 -// btw this may cause alignment problems when 8 does not divide N -#define UNROLL_8(MACRO,N,PTR,ARGS...) \ - int n__=(-N)&7; PTR-=n__; N+=n__; \ - switch (n__) { start: \ - case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \ - case 4:MACRO(4); case 5:MACRO(5); case 6:MACRO(6); case 7:MACRO(7); \ - PTR+=8; N-=8; ARGS; if (N) goto start; } -#define UNROLL_4(MACRO,N,PTR,ARGS...) \ - int n__=(-N)&3; PTR-=n__; N+=n__; \ - switch (n__) { start: \ - case 0:MACRO(0); case 1:MACRO(1); case 2:MACRO(2); case 3:MACRO(3); \ - PTR+=4; N-=4; ARGS; if (N) goto start; } - -struct BFObject; -struct Barf { - string text; - Barf(const char *s, ...); - Barf(const char *file, int line, const char *func, const char *s, ...); - void error(BFObject *bself); - ~Barf() {} -}; - -#define NEWBUF(T,N) (new T[N]) -#define DELBUF(A) (delete[] A) - -#ifdef __WIN32__ -#define INT winINT -#define random rand -#undef send -#undef close -#define sigjmp_buf jmp_buf -#define siglongjmp longjmp -#endif - -//#define _L_ post("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__); -#define _L_ fprintf(stderr,"%s:%d in %s\n",__FILE__,__LINE__,__PRETTY_FUNCTION__); -#define RAISE(args...) throw Barf(__FILE__,__LINE__,__PRETTY_FUNCTION__,args) -#define VA int argc, t_atom2 *argv -// returns the size of a statically defined array -#define COUNT(_array_) ((int)(sizeof(_array_) / sizeof((_array_)[0]))) -#define WATCH(n,ar) { \ - char foo[16*1024], *p=foo; p += sprintf(p,"%s: ",#ar); \ - for (int q=0; qa_type==A_SYMBOL && this->a_symbol==b;} - bool operator != (t_symbol *b) {return !(*this==b);} - operator float32 () const {if (a_type!=A_FLOAT) RAISE("expected float"); return a_float;} -#define TYPECASTER(T,A,B) operator T () const { \ - float f = round(float32(*this)); if (f=B) RAISE("value %f is out of range",f); return (T)f;} - TYPECASTER( bool, 0 , 2 ) - TYPECASTER( uint8, 0 , 0x100 ) - TYPECASTER( int16, -0x8000 , 0x8000 ) - TYPECASTER( uint16, 0 , 0x10000 ) - TYPECASTER( int32, -0x80000000LL, 0x80000000LL) - TYPECASTER( uint32, 0 ,0x100000000LL) -#undef TYPECASTER - operator uint64 () const {if (a_type!=A_FLOAT) RAISE("expected float"); return (uint64)round(a_float);} - operator int64 () const {if (a_type!=A_FLOAT) RAISE("expected float"); return (int64)round(a_float);} - operator float64 () const {if (a_type!=A_FLOAT) RAISE("expected float"); return a_float ;} - -#define TYPECASTER2(T,A,B,C) operator T () const {if (a_type!=A) RAISE("expected "B); return C;} - TYPECASTER2(std::string ,A_SYMBOL ,"symbol" ,std::string(a_symbol->s_name)) - TYPECASTER2(t_symbol *,A_SYMBOL ,"symbol" , a_symbol ) - TYPECASTER2(void *,A_POINTER,"pointer" , a_gpointer) - TYPECASTER2(t_binbuf *,A_LIST ,"nested list", (t_binbuf *)a_gpointer) - TYPECASTER2(Grid *,A_GRID ,"grid" , (Grid *)a_gpointer) - TYPECASTER2(GridOutlet *,A_GRIDOUT,"grid outlet", (GridOutlet *)a_gpointer) -#undef TYPECASTER2 -}; - -template T convert(const t_atom &x, T *foo) {const t_atom2 *xx = (const t_atom2 *)&x; return (T)*xx;} - -//**************************************************************** - -//template class P : T * {}; -//a reference counting pointer class -template class P { -public: -#define INCR if (p) p->refcount++; -#define DECR if (p) {p->refcount--; if (!p->refcount) delete p;} - T *p; - P() {p=0;} - P(T *_p) {p=_p ; INCR;} - P(const P &_p) {p=_p.p; INCR;} - P &operator = (T * _p) {DECR; p=_p; INCR; return *this;} - P &operator = (P _p) {DECR; p=_p.p; INCR; return *this;} - bool operator == (P _p) {return p==_p.p;} - bool operator != (P _p) {return p!=_p.p;} - ~P() {DECR;} - bool operator !() {return !p;} - operator bool() {return !!p;} - T &operator *() {return *p;} - T *operator ->() {return p;} - operator T *() {return p;} -//#undef INCR -//#undef DECR -}; - -void gfmemcopy(uint8 *out, const uint8 *in, long n); -template inline void COPY(T *dest, T *src, long n) { - gfmemcopy((uint8*)dest,(const uint8*)src,n*sizeof(T)); -} -template inline void CLEAR(T *dest, long n) { - memset(dest,0,n*sizeof(T)); -} -template static void memswap (T *a, T *b, long n) { - T c[n]; COPY(c,a,n); COPY(a,b,n); COPY(b,c,n); -} - -//**************************************************************** - -struct CObject { - int32 refcount; - CObject() : refcount(0) {} - virtual ~CObject() {} - virtual void changed (t_symbol *s=0) {} -}; - -// you shouldn't use MethodDecl directly (used by source_filter.rb) -struct MethodDecl {const char *selector; FMethod method;}; - -#undef check - -//**************************************************************** -// a Dim is a list of dimensions that describe the shape of a grid -typedef int32 Card; /* should be switched to long int soon */ -struct Dim : CObject { - static const Card MAX_DIM=16; // maximum number of dimensions in a grid - Card n; - Card v[MAX_DIM]; // real stuff - void check(); // test invariants - Dim(Card n, Card *v){this->n=n; COPY(this->v,v,n); check();} - Dim() {n=0; check();} - Dim(Card a) {n=1;v[0]=a; check();} - Dim(Card a,Card b) {n=2;v[0]=a;v[1]=b; check();} - Dim(Card a,Card b,Card c){n=3;v[0]=a;v[1]=b;v[2]=c;check();} - Dim(Dim *a, Dim *b, Dim *c=0) { - n=a->n+b->n; if(c) n+=c->n; - if (n>Dim::MAX_DIM) RAISE("too many dims"); - COPY(v ,a->v,a->n); - COPY(v+a->n,b->v,b->n); - if(c) COPY(v+a->n+b->n,c->v,c->n); - } - Card count() {return n;} - Card get(Card i) {return v[i];} -/* Dim *range(Card i, Card j) {return new Dim(...);} */ - Card prod(Card start=0, Card end=-1) { - if (start<0) start+=n; - if (end <0) end +=n; - Card tot=1; - for (Card i=start; i<=end; i++) tot *= v[i]; - return tot; - } - char *to_s(); - bool equal(P o) { - if (n!=o->n) return false; - for (Card i=0; iv[i]) return false; - return true; - } -}; - -//**************************************************************** -//NumberTypeE is a very small int identifying the type of the (smallest) elements of a grid - -#define NT_UNSIGNED (1<<0) -#define NT_FLOAT (1<<1) -#define NT_UNIMPL (1<<2) -#define NUMBER_TYPE_LIMITS(T,a,b,c) \ - inline T nt_smallest(T *bogus) {return a;} \ - inline T nt_greatest(T *bogus) {return b;} \ - inline T nt_all_ones(T *bogus) {return c;} - -NUMBER_TYPE_LIMITS( uint8,0,255,255) -NUMBER_TYPE_LIMITS( int16,-0x8000,0x7fff,-1) -NUMBER_TYPE_LIMITS( int32,-0x80000000,0x7fffffff,-1) -NUMBER_TYPE_LIMITS( int64,-0x8000000000000000LL,0x7fffffffffffffffLL,-1) -NUMBER_TYPE_LIMITS(float32,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0)) -NUMBER_TYPE_LIMITS(float64,-HUGE_VAL,+HUGE_VAL,(RAISE("all_ones"),0)) - -#ifdef HAVE_LITE -#define NT_NOTLITE NT_UNIMPL -#define NONLITE(x...) -#else -#define NT_NOTLITE 0 -#define NONLITE(x...) x -#endif -#define NUMBER_TYPES(MACRO) \ - MACRO(uint8, 8,NT_UNSIGNED, "u8,b") \ - MACRO(int16,16,0, "i16,s") \ - MACRO(int32,32,0, "i32,i") \ - MACRO(int64,64,NT_NOTLITE, "i64,l") \ - MACRO(float32,32,NT_FLOAT, "f32,f") \ - MACRO(float64,64,NT_NOTLITE|NT_FLOAT, "f64,d") - -enum NumberTypeE { -#define FOO(_sym_,args...) _sym_##_e, -NUMBER_TYPES(FOO) -#undef FOO -number_type_table_end -}; - -#define FOO(_type_) \ -inline NumberTypeE NumberTypeE_type_of(_type_ *x) {return _type_##_e;} -EACH_NUMBER_TYPE(FOO) -#undef FOO - -struct NumberType : CObject { - const char *name; - int size; - int flags; - const char *aliases; - NumberTypeE index; - NumberType(const char *name_, int size_, int flags_, const char *aliases_) : - name(name_), size(size_), flags(flags_), aliases(aliases_) {} -}; - -NumberTypeE NumberTypeE_find (string sym); -NumberTypeE NumberTypeE_find (const t_atom &sym); - -#define TYPESWITCH(T,C,E) switch (T) { \ - case uint8_e: C(uint8) break; case int16_e: C(int16) break; \ - case int32_e: C(int32) break; NONLITE(case int64_e: C(int64) break;) \ - case float32_e: C(float32) break; NONLITE(case float64_e: C(float64) break;) \ - default: E; RAISE("type '%s' not available here",number_type_table[T].name);} -#define TYPESWITCH_JUSTINT(T,C,E) switch (T) { \ - case uint8_e: C(uint8) break; case int16_e: C(int16) break; \ - case int32_e: C(int32) break; NONLITE(case int64_e: C(int64) break;) \ - default: E; RAISE("type '%s' not available here",number_type_table[T].name);} - -//**************************************************************** -//BitPacking objects encapsulate optimised loops of bitfield conversion (mostly for I/O) -struct BitPacking; -// those are the types of the optimised loops of conversion; inputs are const -struct Packer { -#define FOO(S) void (*as_##S)(BitPacking *self, long n, S *in, uint8 *out); -EACH_INT_TYPE(FOO) -#undef FOO -}; -struct Unpacker { -#define FOO(S) void (*as_##S)(BitPacking *self, long n, uint8 *in, S *out); -EACH_INT_TYPE(FOO) -#undef FOO -}; - -struct BitPacking : CObject { - Packer * packer; - Unpacker *unpacker; - unsigned int endian; // 0=big, 1=little, 2=same, 3=different - int bytes; - int size; - uint32 mask[4]; - BitPacking(){::abort();} // don't call, but don't remove. sorry. - BitPacking(int endian, int bytes, int size, uint32 *mask, - Packer *packer=0, Unpacker *unpacker=0); - bool is_le(); - bool eq(BitPacking *o); -// main entrances to Packers/Unpackers - template void pack(long n, T *in, uint8 *out); - template void unpack(long n, uint8 *in, T *out); -}; - -int high_bit(uint32 n); -int low_bit(uint32 n); -void swap16(long n, uint16 *data); -void swap32(long n, uint32 *data); -void swap64(long n, uint64 *data); -inline void swap_endian(long n, uint8 *data) {} -inline void swap_endian(long n, int16 *data) {swap16(n,(uint16 *)data);} -inline void swap_endian(long n, int32 *data) {swap32(n,(uint32 *)data);} -inline void swap_endian(long n, int64 *data) {swap64(n,(uint64 *)data);} -inline void swap_endian(long n, float32 *data) {swap32(n,(uint32 *)data);} -inline void swap_endian(long n, float64 *data) {swap64(n,(uint64 *)data);} - -//**************************************************************** -// Numop objects encapsulate optimised loops of simple operations - -enum LeftRight { at_left, at_right }; - -template -struct NumopOn { - // Function Vectorisations - typedef void (*Map )( long n, T *as, T b ); Map map; - typedef void (*Zip )( long n, T *as, T *bs); Zip zip; - typedef void (*Fold)(long an, long n, T *as, T *bs); Fold fold; - typedef void (*Scan)(long an, long n, T *as, T *bs); Scan scan; - // Algebraic Properties (those involving simply numeric types) - typedef bool (*AlgebraicCheck)(T x, LeftRight side); - // neutral: right: forall y {f(x,y)=x}; left: forall x {f(x,y)=y}; - // absorbent: right: exists a forall y {f(x,y)=a}; ... - void (*neutral)(T *,LeftRight); // default neutral: e.g. 0 for addition, 1 for multiplication - AlgebraicCheck is_neutral, is_absorbent; - NumopOn(Map m, Zip z, Fold f, Scan s, - void (*neu)(T *,LeftRight), AlgebraicCheck n, AlgebraicCheck a) : - map(m), zip(z), fold(f), scan(s), neutral(neu), is_neutral(n), is_absorbent(a) {} - NumopOn() : map(0),zip(0),fold(0),scan(0),neutral(0),is_neutral(0),is_absorbent(0) {} - NumopOn(const NumopOn &z) { - map=z.map; zip=z.zip; fold=z.fold; scan=z.scan; - is_neutral = z.is_neutral; neutral = z.neutral; - is_absorbent = z.is_absorbent; } -}; - -// semigroup property: associativity: f(a,f(b,c))=f(f(a,b),c) -#define OP_ASSOC (1<<0) -// abelian property: commutativity: f(a,b)=f(b,a) -#define OP_COMM (1<<1) - -struct Numop { - const char *name; - t_symbol *sym; - int flags; - int size; // numop=1; vecop>1 -#define FOO(T) NumopOn on_##T; \ - NumopOn *on(T &foo) { \ - if (!on_##T.map) RAISE("operator %s does not support type "#T,name); \ - return &on_##T;} -EACH_NUMBER_TYPE(FOO) -#undef FOO - template inline void map(long n, T *as, T b) { - on(*as)->map(n,(T *)as,b);} - template inline void zip(long n, T *as, T *bs) { - on(*as)->zip(n,(T *)as,(T *)bs);} - template inline void fold(long an, long n, T *as, T *bs) { - typename NumopOn::Fold f = on(*as)->fold; - if (!f) RAISE("operator %s does not support fold",name); - f(an,n,(T *)as,(T *)bs);} - template inline void scan(long an, long n, T *as, T *bs) { - typename NumopOn::Scan f = on(*as)->scan; - if (!f) RAISE("operator %s does not support scan",name); - f(an,n,(T *)as,(T *)bs);} - - Numop(const char *name_, -#define FOO(T) NumopOn op_##T, -EACH_NUMBER_TYPE(FOO) -#undef FOO - int flags_, int size_) : name(name_), flags(flags_), size(size_) { -#define FOO(T) on_##T = op_##T; -EACH_NUMBER_TYPE(FOO) -#undef FOO - sym=gensym((char *)name); - } -}; - -extern NumberType number_type_table[]; -extern std::map number_type_dict; -extern std::map op_dict; -extern std::map vop_dict; - -static inline NumberTypeE convert(const t_atom &x, NumberTypeE *bogus) { - if (x.a_type!=A_SYMBOL) RAISE("expected number-type"); return NumberTypeE_find(string(x.a_symbol->s_name));} - - -static Numop *convert(const t_atom &x, Numop **bogus) { - if (x.a_type!=A_SYMBOL) RAISE("expected numop (as symbol)"); - string k = string(x.a_symbol->s_name); - if (op_dict.find(k)==op_dict.end()) { - if (vop_dict.find(k)==vop_dict.end()) RAISE("expected two-input-operator, not '%s'", k.data()); - return vop_dict[k]; - } else return op_dict[k]; -} - -// **************************************************************** -struct Grid : CObject { - P dim; - NumberTypeE nt; - void *data; - int state; /* 0:borrowing 1:owning -1:expired(TODO) */ - Grid(P dim, NumberTypeE nt, bool clear=false) { - state=1; - if (!dim) RAISE("hell"); - init(dim,nt); - if (clear) {long size = bytes(); CLEAR((char *)data,size);} - } - Grid(const t_atom &x) {state=1; init_from_atom(x);} - Grid(int n, t_atom *a, NumberTypeE nt_=int32_e) {state=1; init_from_list(n,a,nt_);} - template Grid(P dim, T *data) { - state=0; this->dim=dim; - this->nt=NumberTypeE_type_of((T *)0); - this->data = data; - } - // parens are necessary to prevent overflow at 1/16th of the word size (256 megs) - long bytes() { return dim->prod()*(number_type_table[nt].size/8); } - P to_dim () { return new Dim(dim->prod(),(int32 *)*this); } -#define FOO(T) operator T *() { return (T *)data; } -EACH_NUMBER_TYPE(FOO) -#undef FOO - Grid *dup () { /* always produce an owning grid even if from a borrowing grid */ - Grid *foo=new Grid(dim,nt); - memcpy(foo->data,data,bytes()); - return foo; - } - ~Grid() {if (state==1 && data) free(data);} -private: - void init(P dim, NumberTypeE nt) { - this->dim = dim; - this->nt = nt; - data = 0; - if (dim) { - data = memalign(16,bytes()+16); - if (!data) RAISE("out of memory (?) trying to get %ld bytes",bytes()); - } - //fprintf(stderr,"rdata=%p data=%p align=%d\n",rdata,data,align); - } - void init_from_atom(const t_atom &x); - void init_from_list(int n, t_atom *a, NumberTypeE nt=int32_e); -}; -static inline Grid *convert (const t_atom &r, Grid **bogus) {return new Grid(r);} - -// DimConstraint interface: -// return if d is acceptable -// else RAISE with proper descriptive message -typedef void (*DimConstraint)(P d); - -struct PtrGrid : public P { - DimConstraint dc; - void constrain(DimConstraint dc_) { dc=dc_; } - P next; - PtrGrid() : P(), dc(0), next(0) {} - PtrGrid(const PtrGrid &_p) : P(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;} -// PtrGrid( P _p) : P(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;} - PtrGrid( Grid *_p) : P(), dc(0), next(0) { - p=_p; -INCR;} - PtrGrid &operator =( Grid *_p) {if(dc&&_p)dc(_p->dim); -DECR; p=_p; INCR; -return *this;} - PtrGrid &operator =(P _p) {if(dc&&_p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;} - PtrGrid &operator =(PtrGrid _p) {if(dc&&_p)dc(_p->dim); DECR; p=_p.p; INCR; return *this;} -}; -#undef INCR -#undef DECR - -static inline P convert(const t_atom &x, P *foo) { - Grid *d = convert(x,(Grid **)0); - if (!d) RAISE("urgh"); - if (d->dim->n!=1) RAISE("dimension list must have only one dimension itself"); - return new Dim(d->dim->v[0],(int32 *)(d->data)); -} -static inline PtrGrid convert(const t_atom &x, PtrGrid *foo) {return PtrGrid(convert(x,(Grid **)0));} - -//**************************************************************** -// GridInlet represents a grid-aware inlet - -#define GRIDHANDLER_ARGS(T) GridInlet *in, long dex, long n, T *data - -// four-part macro for defining the behaviour of a gridinlet in a class -// C:Class I:Inlet -#define GRID_INLET(I) \ - template void THISCLASS::grinw_##I (GRIDHANDLER_ARGS(T)) {\ - ((THISCLASS*)in->parent)->grin_##I(in,dex,n,data);}\ - template void THISCLASS::grin_##I (GRIDHANDLER_ARGS(T)) {if (n==-1) -#define GRID_FLOW else if (n>=0) -#define GRID_FINISH else if (n==-2) -#define GRID_END } - -/* macro for defining a gridinlet's behaviour as just storage (no backstore) */ -// V is a PtrGrid instance-var -#define GRID_INPUT(I,V) \ - GRID_INLET(I) {V=new Grid(in->dim,NumberTypeE_type_of(data));} GRID_FLOW {COPY((T *)*(V)+dex,data,n);} GRID_FINISH - -// macro for defining a gridinlet's behaviour as just storage (with backstore) -// V is a PtrGrid instance-var -#define GRID_INPUT2(I,V) GRID_INLET(I) {V.next = new Grid(in->dim,NumberTypeE_type_of(data));} \ - GRID_FLOW {COPY(((T *)*(V.next?V.next.p:&*V.p))+dex,data,n);} GRID_FINISH - -typedef struct GridInlet GridInlet; -typedef struct GridHandler { -#define FOO(T) void (*flow_##T)(GRIDHANDLER_ARGS(T)); \ - void flow (GRIDHANDLER_ARGS(T)) const {flow_##T(in,dex,n,data);} -EACH_NUMBER_TYPE(FOO) -#undef FOO -} GridHandler; - -struct FObject; -struct GridInlet : CObject { - FObject *parent; - const GridHandler *gh; - GridOutlet *sender; - P dim; - NumberTypeE nt; // kill this - long dex; - int chunk; - PtrGrid buf;// factor-chunk buffer - long bufi; // buffer index: how much of buf is filled - GridInlet(FObject *parent_, const GridHandler *gh_) : - parent(parent_), gh(gh_), sender(0), dim(0), nt(int32_e), dex(0), chunk(-1), bufi(0) {} - ~GridInlet() {} - void set_chunk(long whichdim); - int32 factor() {return buf?buf->dim->prod():1;} // which is usually not the same as this->dim->prod(chunk) - void begin(GridOutlet *sender); - void finish(); - template void flow(long n, T *data); // n=-1 is begin, and n=-2 is finish. - void from_list(VA, NumberTypeE nt=int32_e) {Grid t(argc,argv,nt); from_grid(&t);} - void from_atom(VA) {Grid t(argv[0]); from_grid(&t);} - void from_grid(Grid *g); - bool supports_type(NumberTypeE nt); -private: - template void from_grid2(Grid *g, T foo); -}; - -//**************************************************************** -// for use by source_filter.rb ONLY (for \grin) -#ifndef HAVE_LITE -#define GRIN(TB,TS,TI,TL,TF,TD) {TB,TS,TI,TL,TF,TD} -#else -#define GRIN(TB,TS,TI,TL,TF,TD) {TB,TS,TI,TF} -#endif // HAVE_LITE -#define MESSAGE t_symbol *sel, int argc, t_atom2 *argv -#define MESSAGE2 sel,argc,argv -#define MESSAGE3 t_symbol *, int, t_atom2 * -struct AttrDecl { - string name; - string type; - AttrDecl(string name_, string type_) {name=name_; type=type_;} -}; -typedef FObject *(*t_allocator)(BFObject *,MESSAGE3); -struct FClass { - t_allocator allocator; // returns a new C++ object - void (*startup)(FClass *); - const char *cname; // C++ name (not PD name) - int methodsn; MethodDecl *methods; - FClass *super; - int ninlets; - int noutlets; - t_class *bfclass; - string name; - size_t bytes; - std::map attrs; -}; - -void fclass_install(FClass *fc, FClass *super, size_t bytes); - -//**************************************************************** -// GridOutlet represents a grid-aware outlet -struct GridOutlet : CObject { -// number of (minimum,maximum) BYTES to send at once -// starting with version 0.8, this is amount of BYTES, not amount of NUMBERS. - static const long MIN_PACKET_SIZE = 1<<8; - static const long MAX_PACKET_SIZE = 1<<12; -// those are set only once - FObject *parent; // not a P<> because of circular refs - P dim; // dimensions of the grid being sent - NumberTypeE nt; - std::vector inlets; // which inlets are we connected to -// those are updated during transmission - long dex; // how many numbers were already sent in this connection - - GridOutlet(FObject *parent_, int woutlet, P dim_, NumberTypeE nt_=int32_e); - ~GridOutlet() {} - void callback(GridInlet *in); - - // send/send_direct: data belongs to caller, may be stack-allocated, - // receiver doesn't modify the data; in send(), there is buffering; - // in send_direct(), there is not. When switching from buffered to - // unbuffered mode, flush() must be called - #define FOO(T) void send(long n, T *data) {send_2(n,data);} - EACH_NUMBER_TYPE(FOO) - #undef FOO - template void send_2(long n, T *data); - void flush(); // goes with send(); - PtrGrid buf; // temporary buffer - long bufi; // number of bytes used in the buffer - template void send_direct(long n, T *data); - void finish(); - void create_buf(); -}; - -//**************************************************************** - -#define CHECK_GRIN(class,i) \ - if (in.size()<=i) in.resize(i+1); \ - if (!in[i]) in[i]=new GridInlet((FObject *)this,&class##_grid_##i##_hand); - -#define CHECK_ALIGN16(d,nt) \ - {int bytes = 16; \ - int align = ((unsigned long)(void*)d)%bytes; \ - if (align) {_L_;post("%s(%s): Alignment Warning: %s=%p is not %d-aligned: %d", \ - ARGS(this), __PRETTY_FUNCTION__,#d,(void*)d,bytes,align);}} - -struct BFProxy; -struct BFObject : t_object { - FObject *self; - int ninlets,noutlets; // per object settings (not class) - BFProxy **inlets; // direct access to inlets (not linked lists) - t_outlet **outlets; // direct access to outlets (not linked lists) - t_canvas *mom; - void ninlets_set(int n, bool draw=true); - void noutlets_set(int n, bool draw=true); - string binbuf_string (); -}; - -// represents objects that have inlets/outlets -\class FObject : CObject { - BFObject *bself; // point to PD peer - std::vector > in; - P out; - FObject(BFObject *bself, MESSAGE) : bself(bself) {bself->self = this;} - template void send_out(int outlet, int argc, T *argv) { - t_atom foo[argc]; - for (int i=0; ioutlets[outlet],&s_list,argc,foo); - } - \decl 0 get (t_symbol *s=0); - \decl 0 help (); -}; -\end class - -uint64 gf_timeofday(); -extern "C" void Init_gridflow (); -extern Numop *op_add,*op_sub,*op_mul,*op_div,*op_mod,*op_shl,*op_and,*op_put; - -#undef ARGS -#define ARGS(OBJ) ((OBJ) ? (OBJ)->bself->binbuf_string().data() : "[null]") -#define NOTEMPTY(_a_) if (!(_a_)) RAISE("'%s' is empty",#_a_); -#define SAME_TYPE(_a_,_b_) if ((_a_)->nt != (_b_)->nt) RAISE("same type please (%s has %s; %s has %s)", \ - #_a_, number_type_table[(_a_)->nt].name, \ - #_b_, number_type_table[(_b_)->nt].name); -static void SAME_DIM(int n, P a, int ai, P b, int bi) { - if (ai+n > a->n) RAISE("left hand: not enough dimensions"); - if (bi+n > b->n) RAISE("right hand: not enough dimensions"); - for (int i=0; iv[ai+i] != b->v[bi+i]) { - RAISE("mismatch: left dim #%d is %d, right dim #%d is %d", - ai+i, a->v[ai+i], - bi+i, b->v[bi+i]);}}} - -void suffixes_are (const char *name, const char *suffixes); -#define install(name,inlets,outlets) install2(fclass,name,inlets,outlets) -void install2(FClass *fclass, const char *name, int inlets, int outlets); -#define add_creator(name) add_creator2(fclass,name) -void add_creator2(FClass *fclass, const char *name); -void add_creator3(FClass *fclass, const char *name); -#define install_format(name,mode,suffixes) do {install(name,1,1); suffixes_are(name,suffixes);} while(0) -void call_super(int argc, t_atom *argv); -#define SUPER call_super(argc,argv); - -\class Format : FObject { - int mode; - int fd; - FILE *f; - NumberTypeE cast; - long frame; - Format(BFObject *, MESSAGE); - \decl 0 open (t_symbol *mode, string filename); - \decl 0 close (); - \decl 0 cast (NumberTypeE nt); - \decl 0 seek(int frame); - \decl 0 rewind (); - ~Format (); -}; -\end class - -extern std::vector gf_data_path; -string gf_find_file (string x); -void pd_oprintf (std::ostream &o, const char *s, int argc, t_atom *argv); -void pd_oprint (std::ostream &o, int argc, t_atom *argv); -void pd_post (const char *s, int argc, t_atom *argv); - -inline void set_atom (t_atom *a, uint8 v) {SETFLOAT(a,(float)v);} -inline void set_atom (t_atom *a, int16 v) {SETFLOAT(a,(float)v);} -inline void set_atom (t_atom *a, int32 v) {SETFLOAT(a,(float)v);} -inline void set_atom (t_atom *a, uint32 v) {SETFLOAT(a,(float)v);} -inline void set_atom (t_atom *a, long v) {SETFLOAT(a,(float)v);} -inline void set_atom (t_atom *a, float32 v) {SETFLOAT(a,v);} -inline void set_atom (t_atom *a, float64 v) {SETFLOAT(a,v);} -inline void set_atom (t_atom *a, t_symbol *v) {SETSYMBOL(a,v);} -inline void set_atom (t_atom *a, Numop *v) {SETSYMBOL(a,v->sym);} -inline void set_atom (t_atom *a, t_binbuf *v) {SETLIST(a,v);} - -extern std::map fclasses; -int handle_braces(int ac, t_atom *av); - -extern FClass ciFObject, ciFormat; - -/* both oprintf are copied from desiredata */ - -static inline int voprintf(std::ostream &buf, const char *s, va_list args) { - char *b; - int n = vasprintf(&b,s,args); - buf << b; - free(b); - return n; -} -static inline int oprintf(std::ostream &buf, const char *s, ...) { - va_list args; - va_start(args,s); - int n = voprintf(buf,s,args); - va_end(args); - return n; -} - -/* this function was copied from desiredata */ -#ifndef DESIRE -inline t_symbol *symprintf(const char *s, ...) { - char *buf; - va_list args; - va_start(args,s); - if (vasprintf(&buf,s,args)<0) {/*rien*/} - va_end(args); - t_symbol *r = gensym(buf); - free(buf); - return r; -} -#endif - -std::ostream &operator << (std::ostream &self, const t_atom &a); - -// from pd/src/g_canvas.c -#ifdef DESIRE -#define ce_argc argc -#define ce_argv argv -#else -struct _canvasenvironment { - t_symbol *ce_dir; /* directory patch lives in */ - int ce_argc; /* number of "$" arguments */ - t_atom *ce_argv; /* array of "$" arguments */ - int ce_dollarzero; /* value of "$0" */ -}; -#endif - -#endif // __GF_GRID_H diff --git a/externals/gridflow/src/jpeg.cxx b/externals/gridflow/src/jpeg.cxx deleted file mode 100644 index 97482223..00000000 --- a/externals/gridflow/src/jpeg.cxx +++ /dev/null @@ -1,118 +0,0 @@ -/* - $Id: jpeg.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -//!@#$ not handling abort on compress -//!@#$ not handling abort on decompress - -#include "gridflow.hxx.fcs" -/* removing macros (removing warnings) */ -#undef HAVE_PROTOTYPES -#undef HAVE_STDLIB_H -#undef EXTERN -extern "C" { -#include -}; - -\class FormatJPEG : Format { - P bit_packing; - struct jpeg_compress_struct cjpeg; - struct jpeg_decompress_struct djpeg; - struct jpeg_error_mgr jerr; - short quality; - \constructor (t_symbol *mode, string filename) { - Format::_0_open(0,0,mode,filename); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); - quality = 75; - } - \decl 0 bang (); - \decl 0 quality (short quality); - \grin 0 int -}; - -GRID_INLET(0) { - if (in->dim->n!=3) RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2)!=3) RAISE("expecting 3 channels (got %d)",in->dim->get(2)); - in->set_chunk(1); - cjpeg.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cjpeg); - jpeg_stdio_dest(&cjpeg,f); - cjpeg.image_width = in->dim->get(1); - cjpeg.image_height = in->dim->get(0); - cjpeg.input_components = 3; - cjpeg.in_color_space = JCS_RGB; - jpeg_set_defaults(&cjpeg); - jpeg_set_quality(&cjpeg,quality,false); - jpeg_start_compress(&cjpeg,TRUE); -} GRID_FLOW { - int rowsize = in->dim->get(1)*in->dim->get(2); - int rowsize2 = in->dim->get(1)*3; - uint8 row[rowsize2]; - uint8 *rows[1] = {row}; - while (n) { - bit_packing->pack(in->dim->get(1),data,row); - jpeg_write_scanlines(&cjpeg,rows,1); - n-=rowsize; data+=rowsize; - } -} GRID_FINISH { - jpeg_finish_compress(&cjpeg); - jpeg_destroy_compress(&cjpeg); -} GRID_END - -static bool gfeof(FILE *f) { - off_t cur,end; - cur = ftell(f); - fseek(f,0,SEEK_END); - end = ftell(f); - fseek(f,cur,SEEK_SET); - return cur==end; -} - -\def 0 bang () { - //off_t off = ftell(f); - //fseek(f,off,SEEK_SET); - if (gfeof(f)) {outlet_bang(bself->te_outlet); return;} - djpeg.err = jpeg_std_error(&jerr); - jpeg_create_decompress(&djpeg); - jpeg_stdio_src(&djpeg,f); - jpeg_read_header(&djpeg,TRUE); - int sx=djpeg.image_width, sy=djpeg.image_height, chans=djpeg.num_components; - GridOutlet out(this,0,new Dim(sy,sx,chans),cast); - jpeg_start_decompress(&djpeg); - uint8 row[sx*chans]; - uint8 *rows[1] = { row }; - for (int n=0; nquality = min(max((int)quality,0),100);} - -\classinfo {install_format("#io.jpeg",6,"jpeg jpg");} -\end class FormatJPEG -void startup_jpeg () { - \startall -} diff --git a/externals/gridflow/src/mmx.rb b/externals/gridflow/src/mmx.rb deleted file mode 100644 index 7427771d..00000000 --- a/externals/gridflow/src/mmx.rb +++ /dev/null @@ -1,219 +0,0 @@ -=begin - $Id: mmx.rb 3638 2008-04-21 04:31:20Z matju $ - - GridFlow - Copyright (c) 2001-2008 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -=end - -STDOUT.reopen ARGV[0], "w" -$loader = File.open ARGV[1], "w" -$count = 0 -$lines = 0 -puts "; generated by/for GridFlow 0.9.2" -$loader.puts "#include \"gridflow.hxx.fcs\"\nextern \"C\" {" - -# this class is not really used yet (only self.make) -class AsmFunction - def initialize(name) - @name = name - @label_count = 1 - end - def self.make(name) - puts "", "GLOBAL #{name}", "#{name}:" - puts "push ebp", "mov ebp,esp", "push esi", "push edi" - yield AsmFunction.new(name) - puts "pop edi", "pop esi", "leave", "ret", "" - end - def make_until(*ops) - a = @label_count - b = @label_count+1 - @label_count+=2 - ops[-1] << " #{@name}_#{b}" - puts "#{@name}_#{a}: ", *ops - yield - puts "jmp #{@name}_#{a}" - puts "#{@name}_#{b}:" - end -end - -$sizeof = { - :uint8 => 1, - :int16 => 2, - :int32 => 4, - :int64 => 8, - :float32 => 4, - :float64 => 8, -} -$accum = { - :uint8 => "al", - :int16 => "ax", - :int32 => "eax", -} -$asm_type = { - :uint8 => "byte", - :int16 => "word", - :int32 => "dword", - :int64 => "qword", -} - -# in the following, the opcode "_" means no such thing seems available. -# also >> for x86 ought to be shr in the uint8 case. -# btw, i got all of the MMX information from the NASM manual, Appendix B. -$opcodes = { -# [--GF--|--x86--|--mmx-et-al----------------------------------------] -# [ | |-uint8-|-int16-|-int32-|-int64-|-float32-|-float64-] - :add => %w[ + add paddb paddw paddd paddq ], - :sub => %w[ - sub psubb psubw psubd psubq ], - :and => %w[ & and pand pand pand pand ], - :xor => %w[ ^ xor pxor pxor pxor pxor ], - :or => %w[ | or por por por por ], -# :max => %w[ max _ pmaxub pmaxsw _ _ ], # not plain MMX !!! (req.Katmai) -# :min => %w[ min _ pminub pminsw _ _ ], # not plain MMX !!! (req.Katmai) -# :eq => %w[ == _ pcmpeqb pcmpeqw pcmpeqd _ ], -# :gt => %w[ > _ pcmpgtb pcmpgtw pcmpgtd _ ], -# :shl => %w[ << shl _ psllw pslld psllq ], # noncommutative -# :shr => %w[ >> sar _ psraw psrad _ ], # noncommutative -# :clipadd => %w[ clip+ _ paddusb paddsw _ _ ], # future use -# :clipsub => %w[ clip- _ psubusb psubsw _ _ ], # future use -# :andnot => %w[ ¬ _ pandn pandn pandn pandn ], # not planned -} - -$opcodes.each {|k,op| - op.map! {|x| if x=="_" then nil else x end } - STDERR.puts op.inspect -} -$decls = "" -$install = "" - -def make_fun_map(op,type) - s="mmx_#{type}_map_#{op}" - size = $sizeof[type] - accum = $accum[type] - sym = $opcodes[op][0] - opcode = $opcodes[op][1] - mopcode = $opcodes[op][size+(size<4 ? 1 : 0)] - return if not mopcode - AsmFunction.make(s) {|a| - puts "mov ecx,[ebp+8]", "mov esi,[ebp+12]", "mov eax,[ebp+16]" - puts "mov dx,ax", "shl eax,8", "mov al,dl" if size==1 - puts "mov edx,eax", "shl eax,16", "mov ax,dx" if size<=2 - puts "push eax", "push eax", "movq mm7,[esp]", "add esp,8" - foo = proc {|n| - a.make_until("cmp ecx,#{8/size*n}","jb near") { - 0.step(n,4) {|k| - nn=[n-k,4].min - o=(0..3).map{|x| 8*(x+k) } - for i in 0...nn do puts "movq mm#{i},[esi+#{o[i]}]" end - for i in 0...nn do puts "#{mopcode} mm#{i},mm7" end - for i in 0...nn do puts "movq [esi+#{o[i]}],mm#{i}" end - } - puts "lea esi,[esi+#{8*n}]", "lea ecx,[ecx-#{8 / size*n}]" - } - } - foo.call 4 - foo.call 1 - a.make_until("test ecx,ecx", "jz") { - puts "#{opcode} #{$asm_type[type]} [esi],#{accum}", "lea esi,[esi+#{size}]" - puts "dec ecx" - } - puts "emms" - } - $decls << "void #{s}(long,#{type}*,#{type});\n" - $install << "op_dict[string(\"#{sym}\")]->on_#{type}.map = #{s};\n" - $count += 1 -end - -def make_fun_zip(op,type) - s="mmx_#{type}_zip_#{op}" - size = $sizeof[type] - accum = $accum[type] - sym = $opcodes[op][0] - opcode = $opcodes[op][1] - mopcode = $opcodes[op][size+(size<4 ? 1 : 0)] - return if not mopcode - AsmFunction.make(s) {|a| - puts "mov ecx,[ebp+8]", "mov edi,[ebp+12]", - "mov esi,[ebp+16]"#, "mov ebx,[ebp+20]" - foo = proc {|n| - a.make_until("cmp ecx,#{8/size*n}","jb near") { - 0.step(n,4) {|k| - nn=[n-k,4].min - o=(0..3).map{|x| 8*(x+k) } - for i in 0...nn do puts "movq mm#{i},[edi+#{o[i]}]" end - for i in 0...nn do puts "movq mm#{i+4},[esi+#{o[i]}]" end - for i in 0...nn do puts "#{mopcode} mm#{i},mm#{i+4}" end - for i in 0...nn do puts "movq [edi+#{o[i]}],mm#{i}" end - } - #for i in 0...n do puts "movq [ebx+#{8*i}],mm#{i}" end - puts "lea edi,[edi+#{8*n}]" - puts "lea esi,[esi+#{8*n}]" - #puts "lea ebx,[ebx+#{8*n}]" - puts "lea ecx,[ecx-#{8/size*n}]" - } - } - foo.call 4 - foo.call 1 - a.make_until("test ecx,ecx", "jz") { - # requires commutativity ??? fails with shl, shr - puts "mov #{accum},[esi]" - puts "#{opcode} #{$asm_type[type]} [edi],#{accum}" - #puts "mov #{accum},[edi]" - #puts "#{opcode} #{accum},[esi]" - #puts "mov [ebx],#{accum}" - puts "lea edi,[edi+#{size}]" - puts "lea esi,[esi+#{size}]" - #puts "lea ebx,[ebx+#{size}]" - puts "dec ecx" - } - puts "emms" - } - #$decls << "void #{s}(long,#{type}*,#{type}*,#{type}*);\n" - $decls << "void #{s}(long,#{type}*,#{type}*);\n" - $install << "op_dict[string(\"#{sym}\")]->on_#{type}.zip = #{s};\n" - $count += 1 -end - -for op in $opcodes.keys do - for type in [:uint8, :int16#, :int32 - ] do - make_fun_map(op,type) - make_fun_zip(op,type) - end -end - -$loader.puts $decls -$loader.puts %` -}; /* extern */ -#include -void startup_mmx_loader () {/*bogus*/} -void startup_mmx () { - if (getenv("NO_MMX")) return; - post(\"startup_cpu: using MMX optimisations\"); - #{$install} -}` - -STDERR.puts "automatically generated #{$count} MMX asm functions" - -=begin notes: -CPUID has a bit for detecting MMX -PACKSSDW PACKSSWB PACKUSWB = saturation-casting -PCMPxx: Compare Packed Integers -PMULHW, PMULLW: Multiply Packed _unsigned_ 16-bit Integers, and Store -PUNPCKxxx: Unpack and Interleave Data -=end diff --git a/externals/gridflow/src/mpeg3.cxx b/externals/gridflow/src/mpeg3.cxx deleted file mode 100644 index 4ee5bf1f..00000000 --- a/externals/gridflow/src/mpeg3.cxx +++ /dev/null @@ -1,83 +0,0 @@ -/* - $Id: mpeg3.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define LIBMPEG_INCLUDE_HERE -#include "gridflow.hxx.fcs" -#include -#include -#include - -\class FormatMPEG3 : Format { - mpeg3_t *mpeg; - int track; - ~FormatMPEG3 () {if (mpeg) {mpeg3_close(mpeg); mpeg=0;}} - \constructor (t_symbol *mode, string filename) { - track=0; - // libmpeg3 may be nice, but it won't take a filehandle, only filename - if (mode!=gensym("in")) RAISE("read-only, sorry"); - filename = gf_find_file(filename); - #ifdef MPEG3_UNDEFINED_ERROR - int err; - mpeg = mpeg3_open((char *)filename.data(),&err); - post("mpeg error code = %d",err); - #else - mpeg = mpeg3_open((char *)filename.data()); - #endif - if (!mpeg) RAISE("IO Error: can't open file `%s': %s", filename.data(), strerror(errno)); - } - \decl 0 seek (int32 frame); - \decl 0 rewind (); - \decl 0 bang (); -}; - -\def 0 seek (int32 frame) { - mpeg3_set_frame(mpeg,clip(frame,int32(0),int32(mpeg3_video_frames(mpeg,track)-1)),track); -} -\def 0 rewind () {_0_seek(0,0,0);} - -\def 0 bang () { - int nframe = mpeg3_get_frame(mpeg,track); - int nframes = mpeg3_video_frames(mpeg,track); - //post("track=%d; nframe=%d; nframes=%d",track,nframe,nframes); - if (nframe >= nframes) {outlet_bang(bself->te_outlet); return;} - int sx = mpeg3_video_width(mpeg,track); - int sy = mpeg3_video_height(mpeg,track); - int channels = 3; - /* !@#$ the doc says "You must allocate 4 extra bytes in the - last output_row. This is scratch area for the MMX routines." */ - uint8 *buf = NEWBUF(uint8,sy*sx*channels+16); - uint8 *rows[sy]; - for (int i=0; iprod(1); - for(int y=0; ydim->n!=3) RAISE("need 3 dimensions"); - if (in->dim->v[2]!=3) RAISE("need 3 channels"); - outpam.size = sizeof(struct pam); - outpam.len = sizeof(struct pam); - outpam.file = f; - outpam.format = PPM_FORMAT; - outpam.height = in->dim->v[0]; - outpam.width = in->dim->v[1]; - outpam.depth = in->dim->v[2]; - outpam.plainformat = false; - outpam.maxval = 255; - //outpam.allocation_depth = 3; - strcpy(outpam.tuple_type,PAM_PPM_TUPLETYPE); - pnm_writepaminit(&outpam); - in->set_chunk(1); -} GRID_FLOW { - tuple *tuplerow = pnm_allocpamrow(&outpam); - int m = in->dim->v[1]; - for (int i=0; idim->prod(1)) { - for (int j=0; j -#include -#include -#include -#include -#include -//using namespace std; - -static inline uint64 weight(uint64 x) {uint64 k; - k=0x5555555555555555ULL; x = (x&k) + ((x>> 1)&k); //(2**64-1)/(2**2**0-1) - k=0x3333333333333333ULL; x = (x&k) + ((x>> 2)&k); //(2**64-1)/(2**2**1-1) - k=0x0f0f0f0f0f0f0f0fULL; x = (x&k) + ((x>> 4)&k); //(2**64-1)/(2**2**2-1) - k=0x00ff00ff00ff00ffULL; x = (x&k) + ((x>> 8)&k); //(2**64-1)/(2**2**3-1) - k=0x0000ffff0000ffffULL; x = (x&k) + ((x>>16)&k); //(2**64-1)/(2**2**4-1) - k=0x00000000ffffffffULL; x = (x&k) + ((x>>32)&k); //(2**64-1)/(2**2**5-1) - return x; -} - -#ifdef PASS1 -NumberType number_type_table[] = { -#define FOO(_sym_,_size_,_flags_,args...) NumberType( #_sym_, _size_, _flags_, args ), -NUMBER_TYPES(FOO) -#undef FOO -}; -const long number_type_table_n = COUNT(number_type_table); -#endif - -// those are bogus class-templates in the sense that you don't create -// objects from those, you just call static functions. The same kind -// of pattern is present in STL to overcome some limitations of C++. - -template class Op { -public: - // I call abort() on those because I can't say they're purevirtual. - static T f(T a, T b) {abort();} - static bool is_neutral (T x, LeftRight side) {assert(!"Op::is_neutral called?"); return false;} - static bool is_absorbent(T x, LeftRight side) {assert(!"Op::is_absorbent called?"); return false;} -}; - -template class OpLoops: public NumopOn { -public: - static inline T f(T a, T b) {return O::f(a,b);} - #define FOO(I) as[I]=f(as[I],b); - static void _map (long n, T *as, T b) {if (!n) return; UNROLL_8(FOO,n,as)} - #undef FOO - #define FOO(I) as[I]=f(as[I],as[ba+I]); - static void _zip (long n, T *as, T *bs) {if (!n) return; ptrdiff_t ba=bs-as; UNROLL_8(FOO,n,as)} - #undef FOO - #define W(i) as[i]=f(as[i],bs[i]); - #define Z(i,j) as[i]=f(f(f(f(as[i],bs[i]),bs[i+j]),bs[i+j+j]),bs[i+j+j+j]); - static void _fold (long an, long n, T *as, T *bs) { - switch (an) { - case 1:for(;(n&3)!=0;bs+=1,n--){W(0) } for (;n;bs+= 4,n-=4){Z(0,1) } break; - case 2:for(;(n&3)!=0;bs+=2,n--){W(0)W(1) } for (;n;bs+= 8,n-=4){Z(0,2)Z(1,2) } break; - case 3:for(;(n&3)!=0;bs+=3,n--){W(0)W(1)W(2) } for (;n;bs+=12,n-=4){Z(0,3)Z(1,3)Z(2,3) } break; - case 4:for(;(n&3)!=0;bs+=4,n--){W(0)W(1)W(2)W(3)} for (;n;bs+=16,n-=4){Z(0,4)Z(1,4)Z(2,4)Z(3,4)} break; - default:while (n--) {int i=0; - for (; i<(an&-4); i+=4, bs+=4) { - as[i+0]=f(as[i+0],bs[0]); - as[i+1]=f(as[i+1],bs[1]); - as[i+2]=f(as[i+2],bs[2]); - as[i+3]=f(as[i+3],bs[3]);} - for (; i -static void quick_mod_map (long n, T *as, T b) { - if (!b) return; -#define FOO(I) as[I]=mod(as[I],b); - UNROLL_8(FOO,n,as) -#undef FOO -} - -template static void quick_ign_map (long n, T *as, T b) {} -template static void quick_ign_zip (long n, T *as, T *bs) {} -template static void quick_put_map (long n, T *as, T b) { -#define FOO(I) as[I]=b; - UNROLL_8(FOO,n,as) -#undef FOO -} - -#ifdef PASS1 -void quick_put_map (long n, int16 *as, int16 b) { - if ((n&1)!=0 && ((long)as&4)!=0) {*as++=b; n--;} - quick_put_map(n>>1, (int32 *)as, (int32)(b<<16)+b); - if ((n&1)!=0) *as++=b; -} -void quick_put_map (long n, uint8 *as, uint8 b) { - while ((n&3)!=0 && ((long)as&4)!=0) {*as++=b; n--;} - int32 c=(b<<8)+b; c+=c<<16; - quick_put_map(n>>2, (int32 *)as, c); - while ((n&3)!=0) *as++=b; -} -#endif -template static void quick_put_zip (long n, T *as, T *bs) { - gfmemcopy((uint8 *)as, (uint8 *)bs, n*sizeof(T)); -} - -#define Plex std::complex - -// classic two-input operator - -#define DEF_OP_COMMON(op,expr,neu,isneu,isorb,T) \ - inline static T f(T a, T b) { return (T)(expr); } \ - inline static void neutral (T *a, LeftRight side) {*a = neu;} \ - inline static bool is_neutral (T x, LeftRight side) {return isneu;} \ - inline static bool is_absorbent(T x, LeftRight side) {return isorb;} -#define DEF_OP(op,expr,neu,isneu,isorb) template class Y##op : Op { public: \ - DEF_OP_COMMON(op,expr,neu,isneu,isorb,T);}; -#define DEF_OPFT(op,expr,neu,isneu,isorb,T) template <> class Y##op : Op { public: \ - DEF_OP_COMMON(op,expr,neu,isneu,isorb,T);}; -// this macro is for operators that have different code for the float version -#define DEF_OPF( op,expr,expr2,neu,isneu,isorb) \ - DEF_OP( op,expr, neu,isneu,isorb) \ - DEF_OPFT(op, expr2,neu,isneu,isorb,float32) \ - DEF_OPFT(op, expr2,neu,isneu,isorb,float64) - -#define OL(O,T) OpLoops,T> -#define VOL(O,T) OpLoops >,Plex > -#define DECL_OPON(L,O,T) NumopOn( \ - (NumopOn::Map) L(O,T)::_map, (NumopOn::Zip) L(O,T)::_zip, \ - (NumopOn::Fold)L(O,T)::_fold, (NumopOn::Scan)L(O,T)::_scan, \ - &Y##O::neutral, &Y##O::is_neutral, &Y##O::is_absorbent) -#define DECL_OPON_NOFOLD(L,O,T) NumopOn( \ - (NumopOn::Map)L(O,T)::_map, (NumopOn::Zip)L(O,T)::_zip, 0,0, \ - &Y##O::neutral, &Y##O::is_neutral, &Y##O::is_absorbent) -#define DECLOP( L,M,O,sym,flags,dim) Numop(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \ - NONLITE(,M(L,O,int64)), M(L,O,float32) NONLITE(,M(L,O,float64)),flags,dim) -#define DECLOP_NOFLOAT(L,M,O,sym,flags,dim) Numop(sym,M(L,O,uint8),M(L,O,int16),M(L,O,int32) \ - NONLITE(,M(L,O,int64)),NumopOn() NONLITE(,NumopOn()), flags,dim) -// NONLITE(,M(L,O,int64),NumopOn(),NumopOn()), flags,dim) -#define DECLOP_FLOAT( L,M,O,sym,flags,dim) Numop(sym,NumopOn(),NumopOn(),NumopOn() \ - NONLITE(,NumopOn()),M(L,O,float32) NONLITE(,M(L,O,float64)),flags,dim) - -#define DECL_OP( O,sym,flags) DECLOP( OL,DECL_OPON ,O,sym,flags,1) -#define DECL_OP_NOFLOAT( O,sym,flags) DECLOP_NOFLOAT( OL,DECL_OPON ,O,sym,flags,1) -#define DECL_OP_NOFOLD( O,sym,flags) DECLOP( OL,DECL_OPON_NOFOLD,O,sym,flags,1) -#define DECL_OP_NOFOLD_NOFLOAT( O,sym,flags) DECLOP_NOFLOAT( OL,DECL_OPON_NOFOLD,O,sym,flags,1) -#define DECL_OP_NOFOLD_FLOAT( O,sym,flags) DECLOP_FLOAT( OL,DECL_OPON_NOFOLD,O,sym,flags,1) - -#define DECL_VOP( O,sym,flags,dim) DECLOP( VOL,DECL_OPON ,O,sym,flags,dim) -#define DECL_VOP_NOFLOAT( O,sym,flags,dim) DECLOP_NOFLOAT(VOL,DECL_OPON ,O,sym,flags,dim) -#define DECL_VOP_NOFOLD( O,sym,flags,dim) DECLOP( VOL,DECL_OPON_NOFOLD,O,sym,flags,dim) -#define DECL_VOP_NOFOLD_NOFLOAT(O,sym,flags,dim) DECLOP_NOFLOAT(VOL,DECL_OPON_NOFOLD,O,sym,flags,dim) -#define DECL_VOP_NOFOLD_FLOAT( O,sym,flags,dim) DECLOP_FLOAT( VOL,DECL_OPON_NOFOLD,O,sym,flags,dim) - -template static inline T gf_floor (T a) { - return (T) floor((double)a); } -template static inline T gf_trunc (T a) { - return (T) floor(abs((double)a)) * (a<0?-1:1); } - -#ifdef PASS1 -DEF_OP(ignore, a, 0, side==at_right, side==at_left) -DEF_OP(put, b, 0, side==at_left, side==at_right) -DEF_OP(add, a+b, 0, x==0, false) -DEF_OP(sub, a-b, 0, side==at_right && x==0, false) -DEF_OP(bus, b-a, 0, side==at_left && x==0, false) -DEF_OP(mul, a*b, 1, x==1, x==0) -DEF_OP(mulshr8, (a*b)>>8, 256, x==256, x==0) -DEF_OP(div, b==0 ? (T)0 : a/b , 1, side==at_right && x==1, false) -DEF_OP(div2, b==0 ? 0 : div2(a,b), 1, side==at_right && x==1, false) -DEF_OP(vid, a==0 ? (T)0 : b/a , 1, side==at_left && x==1, false) -DEF_OP(vid2, a==0 ? 0 : div2(b,a), 1, side==at_left && x==1, false) -DEF_OPF(mod, b==0 ? 0 : mod(a,b), b==0 ? 0 : a-b*gf_floor(a/b), 0, false, (side==at_left && x==0) || (side==at_right && x==1)) -DEF_OPF(dom, a==0 ? 0 : mod(b,a), a==0 ? 0 : b-a*gf_floor(b/a), 0, false, (side==at_left && x==0) || (side==at_right && x==1)) -//DEF_OPF(rem, b==0 ? 0 : a%b, b==0 ? 0 : a-b*gf_trunc(a/b)) -//DEF_OPF(mer, a==0 ? 0 : b%a, a==0 ? 0 : b-a*gf_trunc(b/a)) -DEF_OP(rem, b==0?(T)0:a%b, 0, false, (side==at_left&&x==0) || (side==at_right&&x==1)) -DEF_OP(mer, a==0?(T)0:b%a, 0, false, (side==at_left&&x==0) || (side==at_right&&x==1)) -#endif -#ifdef PASS2 -DEF_OP(gcd, gcd(a,b), 0, x==0, x==1) -DEF_OP(gcd2, gcd2(a,b), 0, x==0, x==1) // should test those and pick one of the two -DEF_OP(lcm, a==0 || b==0 ? (T)0 : lcm(a,b), 1, x==1, x==0) -DEF_OPF(or , a|b, (float32)((int32)a | (int32)b), 0, x==0, x==nt_all_ones(&x)) -DEF_OPF(xor, a^b, (float32)((int32)a ^ (int32)b), 0, x==0, false) -DEF_OPF(and, a&b, (float32)((int32)a & (int32)b), -1 /*nt_all_ones((T*)0)*/, x==nt_all_ones(&x), x==0) -DEF_OPF(shl, a<>b, a*pow(2.0,-b), 0, side==at_right && x==0, false) -DEF_OP(sc_and, a ? b : a, 1, side==at_left && x!=0, side==at_left && x==0) -DEF_OP(sc_or, a ? a : b, 0, side==at_left && x==0, side==at_left && x!=0) -DEF_OP(min, min(a,b), nt_greatest((T*)0), x==nt_greatest(&x), x==nt_smallest(&x)) -DEF_OP(max, max(a,b), nt_smallest((T*)0), x==nt_smallest(&x), x==nt_greatest(&x)) -DEF_OP(cmp, cmp(a,b), 0, false, false) -DEF_OP(eq, a == b, 0, false, false) -DEF_OP(ne, a != b, 0, false, false) -DEF_OP(gt, a > b, 0, false, (side==at_left && x==nt_smallest(&x)) || (side==at_right && x==nt_greatest(&x))) -DEF_OP(le, a <= b, 0, false, (side==at_left && x==nt_smallest(&x)) || (side==at_right && x==nt_greatest(&x))) -DEF_OP(lt, a < b, 0, false, (side==at_left && x==nt_greatest(&x)) || (side==at_right && x==nt_smallest(&x))) -DEF_OP(ge, a >= b, 0, false, (side==at_left && x==nt_greatest(&x)) || (side==at_right && x==nt_smallest(&x))) -#endif -#ifdef PASS3 -DEF_OP(sinmul, (float64)b * sin((float64)a * (M_PI / 18000)), 0, false, false) // "LN=9000+36000n RA=0 LA=..." -DEF_OP(cosmul, (float64)b * cos((float64)a * (M_PI / 18000)), 0, false, false) // "LN=36000n RA=0 LA=..." -DEF_OP(atan, atan2(a,b) * (18000 / M_PI), 0, false, false) // "LA=0" -DEF_OP(tanhmul, (float64)b * tanh((float64)a * (M_PI / 18000)), 0, false, x==0) -DEF_OP(gamma, b<=0 ? (T)0 : (T)(0+floor(pow((float64)a/256.0,256.0/(float64)b)*256.0)), 0, false, false) // "RN=256" -DEF_OPF(pow, ipow(a,b), pow(a,b), 0, false, false) // "RN=1" -DEF_OP(logmul, a==0 ? (T)0 : (T)((float64)b * log((float64)gf_abs(a))), 0, false, false) // "RA=0" -// 0.8 -DEF_OPF(clipadd, clipadd(a,b), a+b, 0, x==0, false) -DEF_OPF(clipsub, clipsub(a,b), a-b, 0, side==at_right && x==0, false) -DEF_OP(abssub, gf_abs(a-b), 0, false, false) -DEF_OP(sqsub, (a-b)*(a-b), 0, false, false) -DEF_OP(avg, (a+b)/2, 0, false, false) -DEF_OPF(hypot, floor(sqrt(a*a+b*b)), sqrt(a*a+b*b), 0, false, false) -DEF_OPF(sqrt, floor(sqrt(a)), sqrt(a), 0, false, false) -DEF_OP(rand, a==0 ? (T)0 : (T)(random()%(int32)a), 0, false, false) -//DEF_OP(erf,"erf*", 0) -DEF_OP(weight,weight((uint64)(a^b) & (0xFFFFFFFFFFFFFFFFULL>>(64-sizeof(T)*8))),0,false,false) -#define BITS(T) (sizeof(T)*8) -DEF_OP(rol,((uint64)a<>(T)((-b)&(BITS(T)-1))),0,false,false) -DEF_OP(ror,((uint64)a>>b)|((uint64)a<<(T)((-b)&(BITS(T)-1))),0,false,false) - -DEF_OP(sin, sin(a-b), 0, false, false) -DEF_OP(cos, cos(a-b), 0, false, false) -DEF_OP(atan2,atan2(a,b), 0, false, false) -DEF_OP(tanh, tanh(a-b), 0, false, false) -DEF_OP(exp, exp(a-b), 0, false, false) -DEF_OP(log, log(a-b), 0, false, false) - -#endif -#ifdef PASS4 - -template inline T gf_sqrt(T a) {return (T)floor(sqrt( a));} -inline float32 gf_sqrt(float32 a) {return sqrtf(a) ;} -inline float64 gf_sqrt(float64 a) {return sqrt( a) ;} - -template inline Plex cx_sqsub(const Plex& a, const Plex& b) { Plex v=a-b; return v*v; } -template inline Plex cx_abssub(const Plex& a, const Plex& b) { Plex v=a-b; return norm(v); } - -template inline Plex gf_c2p(const Plex& a) { - return Plex(hypot(a.real(),a.imag()),atan2(a.real(),a.imag())*(18000 / M_PI)); -} -template inline Plex gf_p2c(const Plex& a) { - return Plex((float64)a.real() * sin((float64)a.imag() * (M_PI / 18000)), - (float64)a.real() * cos((float64)a.imag() * (M_PI / 18000))); -} -/* -template inline Plex cx_atan2 (Plex& a, Plex& b) { - if (b==0) return 0; - Plex v=a/b; - return (log(1+iz)-log(log(1-iz))/2i; - // but this is not taking care of sign stuff... - // and then what's the use of atan2 on complexes? (use C.log ...) -} -*/ - -//!@#$ neutral,is_neutral,is_absorbent are impossible to use here -DEF_OP(cx_mul, a*b, 1, false, false) -DEF_OP(cx_mulconj, a*conj(b), 1, false, false) -DEF_OP(cx_div, a/b, 1, false, false) -DEF_OP(cx_divconj, a/conj(b), 1, false, false) -DEF_OP(cx_sqsub, cx_sqsub(a,b), 0, false, false) -DEF_OP(cx_abssub, cx_abssub(a,b), 0, false, false) -DEF_OP(cx_sin, sin(a-b), 0, false, false) -DEF_OP(cx_cos, cos(a-b), 0, false, false) -//DEF_OP(cx_atan2,atan2(a,b), 0, false, false) -DEF_OP(cx_tanh, tanh(a-b), 0, false, false) -DEF_OP(cx_exp, exp(a-b), 0, false, false) -DEF_OP(cx_log, log(a-b), 0, false, false) -DEF_OP(c2p, gf_c2p(a-b), 0, false, false) -DEF_OP(p2c, gf_p2c(a)+b, 0, false, false) -#endif - -extern Numop op_table1[], op_table2[], op_table3[], op_table4[]; -extern const long op_table1_n, op_table2_n, op_table3_n, op_table4_n; - -#ifdef PASS1 -Numop op_table1[] = { - DECL_OP(ignore, "ignore", OP_ASSOC), - DECL_OP(put, "put", OP_ASSOC), - DECL_OP(add, "+", OP_ASSOC|OP_COMM), // "LINV=sub" - DECL_OP(sub, "-", 0), - DECL_OP(bus, "inv+", 0), - DECL_OP(mul, "*", OP_ASSOC|OP_COMM), - DECL_OP_NOFLOAT(mulshr8, "*>>8", OP_ASSOC|OP_COMM), - DECL_OP(div, "/", 0), - DECL_OP_NOFLOAT(div2, "div", 0), - DECL_OP(vid, "inv*", 0), - DECL_OP_NOFLOAT(vid2,"swapdiv", 0), - DECL_OP_NOFLOAT(mod, "%", 0), - DECL_OP_NOFLOAT(dom, "swap%", 0), - DECL_OP_NOFLOAT(rem, "rem", 0), - DECL_OP_NOFLOAT(mer, "swaprem", 0), -}; -const long op_table1_n = COUNT(op_table1); -#endif -#ifdef PASS2 -Numop op_table2[] = { - DECL_OP_NOFLOAT(gcd, "gcd", OP_ASSOC|OP_COMM), - DECL_OP_NOFLOAT(gcd2, "gcd2", OP_ASSOC|OP_COMM), - DECL_OP_NOFLOAT(lcm, "lcm", OP_ASSOC|OP_COMM), - DECL_OP(or , "|", OP_ASSOC|OP_COMM), - DECL_OP(xor, "^", OP_ASSOC|OP_COMM), - DECL_OP(and, "&", OP_ASSOC|OP_COMM), - DECL_OP_NOFOLD(shl, "<<", 0), - DECL_OP_NOFOLD(shr, ">>", 0), - DECL_OP_NOFOLD(sc_and,"&&", 0), - DECL_OP_NOFOLD(sc_or, "||", 0), - DECL_OP(min, "min", OP_ASSOC|OP_COMM), - DECL_OP(max, "max", OP_ASSOC|OP_COMM), - DECL_OP_NOFOLD(eq, "==", OP_COMM), - DECL_OP_NOFOLD(ne, "!=", OP_COMM), - DECL_OP_NOFOLD(gt, ">", 0), - DECL_OP_NOFOLD(le, "<=", 0), - DECL_OP_NOFOLD(lt, "<", 0), - DECL_OP_NOFOLD(ge, ">=", 0), - DECL_OP_NOFOLD(cmp, "cmp",0), -}; -const long op_table2_n = COUNT(op_table2); -#endif -#ifdef PASS3 -uint8 clipadd(uint8 a, uint8 b) { int32 c=a+b; return c<0?0:c>255?255:c; } -int16 clipadd(int16 a, int16 b) { int32 c=a+b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; } -int32 clipadd(int32 a, int32 b) { int64 c=a+b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; } -int64 clipadd(int64 a, int64 b) { int64 c=(a>>1)+(b>>1)+(a&b&1), p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0); - return c

q/2?q:a+b; } -uint8 clipsub(uint8 a, uint8 b) { int32 c=a-b; return c<0?0:c>255?255:c; } -int16 clipsub(int16 a, int16 b) { int32 c=a-b; return c<-0x8000?-0x8000:c>0x7fff?0x7fff:c; } -int32 clipsub(int32 a, int32 b) { int64 c=a-b; return c<-0x80000000?-0x80000000:c>0x7fffffff?0x7fffffff:c; } -int64 clipsub(int64 a, int64 b) { int64 c=(a>>1)-(b>>1); //??? - int64 p=nt_smallest((int64 *)0), q=nt_greatest((int64 *)0); - return c

q/2?q:a-b; } - -Numop op_table3[] = { - DECL_OP_NOFOLD(sinmul, "sin*", 0), - DECL_OP_NOFOLD(cosmul, "cos*", 0), - DECL_OP_NOFOLD(atan, "atan", 0), - DECL_OP_NOFOLD(tanhmul,"tanh*", 0), - DECL_OP_NOFOLD(gamma, "gamma", 0), - DECL_OP_NOFOLD(pow, "**", 0), - DECL_OP_NOFOLD(logmul, "log*", 0), -// 0.8 - DECL_OP(clipadd,"clip+", OP_ASSOC|OP_COMM), - DECL_OP(clipsub,"clip-", 0), - DECL_OP_NOFOLD(abssub,"abs-", OP_COMM), - DECL_OP_NOFOLD(sqsub, "sq-", OP_COMM), - DECL_OP_NOFOLD(avg, "avg", OP_COMM), - DECL_OP_NOFOLD(hypot, "hypot",OP_COMM), // huh, almost OP_ASSOC - DECL_OP_NOFOLD(sqrt, "sqrt", 0), - DECL_OP_NOFOLD(rand, "rand", 0), - //DECL_OP_NOFOLD(erf,"erf*", 0), - DECL_OP_NOFOLD_NOFLOAT(weight,"weight",OP_COMM), - DECL_OP_NOFOLD_NOFLOAT(rol,"rol",0), - DECL_OP_NOFOLD_NOFLOAT(ror,"ror",0), - - DECL_OP_NOFOLD_FLOAT(sin, "sin", 0), - DECL_OP_NOFOLD_FLOAT(cos, "cos", 0), - DECL_OP_NOFOLD_FLOAT(atan2,"atan2", 0), - DECL_OP_NOFOLD_FLOAT(tanh, "tanh", 0), - DECL_OP_NOFOLD_FLOAT(exp, "exp", 0), - DECL_OP_NOFOLD_FLOAT(log, "log", 0), - -}; -const long op_table3_n = COUNT(op_table3); -#endif -#ifdef PASS4 -Numop op_table4[] = { - DECL_VOP(cx_mul, "C.*", OP_ASSOC|OP_COMM,2), - DECL_VOP(cx_mulconj, "C.*conj", OP_ASSOC|OP_COMM,2), - DECL_VOP(cx_div, "C./", 0,2), - DECL_VOP(cx_divconj, "C./conj", 0,2), - DECL_VOP(cx_sqsub, "C.sq-", OP_COMM,2), - DECL_VOP(cx_abssub, "C.abs-", OP_COMM,2), - DECL_VOP_NOFOLD_FLOAT(cx_sin, "C.sin", 0,2), - DECL_VOP_NOFOLD_FLOAT(cx_cos, "C.cos", 0,2), -// DECL_VOP_NOFOLD_FLOAT(cx_atan2,"C.atan2",0,2), - DECL_VOP_NOFOLD_FLOAT(cx_tanh, "C.tanh", 0,2), - DECL_VOP_NOFOLD_FLOAT(cx_exp, "C.exp", 0,2), - DECL_VOP_NOFOLD_FLOAT(cx_log, "C.log", 0,2), - DECL_VOP_NOFOLD( c2p, "c2p", 0,2), - DECL_VOP_NOFOLD( p2c, "p2c", 0,2), -}; -const long op_table4_n = COUNT(op_table4); -#endif - -// D=dictionary, A=table, A##_n=table count. -#define INIT_TABLE(D,A) for(int i=0; i number_type_dict; -std::map op_dict; -std::map vop_dict; -void startup_number () { - INIT_TABLE( op_dict,op_table1) - INIT_TABLE( op_dict,op_table2) - INIT_TABLE( op_dict,op_table3) - INIT_TABLE(vop_dict,op_table4) - INIT_TABLE(number_type_dict,number_type_table) - - for (int i=0; ion_uint8.M=F; \ - foo->on_int16.M=F; \ - foo->on_int32.M=F; } - OVERRIDE_INT(ignore,map,quick_ign_map); - OVERRIDE_INT(ignore,zip,quick_ign_zip); - //OVERRIDE_INT(put,map,quick_put_map); - //OVERRIDE_INT(put,zip,quick_put_zip); - //OVERRIDE_INT(%,map,quick_mod_map); // !@#$ does that make an improvement at all? -} -#endif diff --git a/externals/gridflow/src/opencv.cxx b/externals/gridflow/src/opencv.cxx deleted file mode 100644 index 424d9bd0..00000000 --- a/externals/gridflow/src/opencv.cxx +++ /dev/null @@ -1,537 +0,0 @@ -/* - $Id: opencv.c 4556 2009-11-01 00:40:16Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include -#include - -#define cvRelease(euh) cvRelease((void **)(euh)) -#define binbuf_addv(SELF,FMT,ARGS...) binbuf_addv(SELF,const_cast(FMT),ARGS) -#define USELIST \ - if (a.a_type != A_LIST) RAISE("expected listatom"); \ - t_list *b = (t_list *)a.a_gpointer; \ - int argc = binbuf_getnatom(b); \ - t_atom2 *argv = (t_atom2 *)binbuf_getvec(b); -#define GETF(I) atom_getfloatarg(I,argc,argv) -#define GETI(I) int(atom_getfloatarg(I,argc,argv)) - -int ipl_eltype(NumberTypeE e) { - switch (e) { - case uint8_e: return IPL_DEPTH_8U; - // IPL_DEPTH_8S not supported - // IPL_DEPTH_16U not supported - case int16_e: return IPL_DEPTH_16S; - case int32_e: return IPL_DEPTH_32S; - case float32_e: return IPL_DEPTH_32F; - case float64_e: return IPL_DEPTH_64F; - default: RAISE("unsupported type %s",number_type_table[e].name); - } -} - -NumberTypeE gf_ipltype(int e) { - switch (e) { - case IPL_DEPTH_8U: return uint8_e; - // IPL_DEPTH_8S not supported - // IPL_DEPTH_16U not supported - case IPL_DEPTH_16S: return int16_e; - case IPL_DEPTH_32S: return int32_e; - case IPL_DEPTH_32F: return float32_e; - case IPL_DEPTH_64F: return float64_e; - default: RAISE("unsupported IPL type %d",e); - } -} - -int cv_eltype(NumberTypeE e) { - switch (e) { - case uint8_e: return CV_8U; - // CV_8S not supported - // CV_16U not supported - case int16_e: return CV_16S; - case int32_e: return CV_32S; - case float32_e: return CV_32F; - case float64_e: return CV_64F; - default: RAISE("unsupported type %s",number_type_table[e].name); - } -} - -NumberTypeE gf_cveltype(int e) { - switch (e) { - case CV_8U: return uint8_e; - // CV_8S not supported - // CV_16U not supported - case CV_16S: return int16_e; - case CV_32S: return int32_e; - case CV_32F: return float32_e; - case CV_64F: return float64_e; - default: RAISE("unsupported CV type %d",e); - } -} - -enum CvMode { - cv_mode_auto, - cv_mode_channels, - cv_mode_nochannels, -}; - -CvMode convert (const t_atom2 &x, CvMode *foo) { - if (x==gensym("auto")) return cv_mode_auto; - if (x==gensym("channels")) return cv_mode_channels; - if (x==gensym("nochannels")) return cv_mode_nochannels; - RAISE("invalid CvMode"); -} - -CvTermCriteria convert (const t_atom2 &a, CvTermCriteria *foo) { - USELIST; - CvTermCriteria tc; - tc.type = 0; - if (argc>0 && argv[0]!=gensym("nil")) {tc.type |= CV_TERMCRIT_ITER; tc.max_iter = GETI(0);} - if (argc>1 && argv[1]!=gensym("nil")) {tc.type |= CV_TERMCRIT_EPS ; tc.epsilon = GETF(1);} - if (argc>2) RAISE("invalid CvTermCriteria (too many args)"); - //post("type=0x%08x max_iter=%d epsilon=%f",tc.type,tc.max_iter,tc.epsilon); - return tc; -} - -void set_atom (t_atom *a, CvTermCriteria &tc) { - t_binbuf *b = binbuf_new(); - if (tc.type & CV_TERMCRIT_ITER) binbuf_addv(b,"f",tc.max_iter); else binbuf_addv(b,"s",gensym("nil")); - if (tc.type & CV_TERMCRIT_EPS ) binbuf_addv(b,"f",tc.epsilon ); else binbuf_addv(b,"s",gensym("nil")); - SETLIST(a,b); -} - -CvArr *cvGrid(PtrGrid g, CvMode mode, int reqdims=-1) { - P d = g->dim; - int channels=1; - int dims=g->dim->n; - //post("mode=%d",(int)mode); - if (mode==cv_mode_channels && g->dim->n==0) RAISE("CV: channels dimension required for 'mode channels'"); - if ((mode==cv_mode_auto && g->dim->n>=3) || mode==cv_mode_channels) channels=g->dim->v[--dims]; - if (channels>64) RAISE("CV: too many channels. max 64, got %d",channels); - //post("channels=%d dims=%d nt=%d",channels,dims,g->nt); - //post("bits=%d",number_type_table[g->nt].size); - //if (dims==2) return cvMat(g->dim->v[0],g->dim->v[1],cv_eltype(g->nt),g->data); - if (reqdims>=0 && reqdims!=dims) RAISE("CV: wrong number of dimensions. expected %d, got %d", reqdims, dims); - if (dims==2) { - CvMat *a = cvCreateMatHeader(g->dim->v[0],g->dim->v[1],CV_MAKETYPE(cv_eltype(g->nt),channels)); - cvSetData(a,g->data,g->dim->prod(1)*(number_type_table[g->nt].size/8)); - return a; - } - if (dims==1) { - CvMat *a = cvCreateMatHeader(g->dim->v[0], 1,CV_MAKETYPE(cv_eltype(g->nt),channels)); - cvSetData(a,g->data,g->dim->prod(1)*(number_type_table[g->nt].size/8)); - return a; - } - RAISE("unsupported number of dimensions (got %d)",g->dim->n); - //return 0; -} - -IplImage *cvImageGrid(PtrGrid g /*, CvMode mode */) { - P d = g->dim; - if (d->n!=3) RAISE("expected 3 dimensions, got %s",d->to_s()); - int channels=g->dim->v[2]; - if (channels>64) RAISE("too many channels. max 64, got %d",channels); - CvSize size = {d->v[1],d->v[0]}; - IplImage *a = cvCreateImageHeader(size,ipl_eltype(g->nt),channels); - cvSetData(a,g->data,g->dim->prod(1)*(number_type_table[g->nt].size/8)); - return a; -} - -void cvMatSend(const CvMat *self, FObject *obj, int outno, Dim *dim=0) { - int m = self->rows; - int n = self->cols; - int e = CV_MAT_TYPE(cvGetElemType(self)); - int c = CV_MAT_CN( cvGetElemType(self)); - GridOutlet *out = new GridOutlet(obj,0,dim?dim:new Dim(m,n)); - for (int i=0; isend(c*n, (uint8 *)meuh); break; - case CV_16S: out->send(c*n, (int16 *)meuh); break; - case CV_32S: out->send(c*n, (int32 *)meuh); break; - case CV_32F: out->send(c*n,(float32 *)meuh); break; - case CV_64F: out->send(c*n,(float64 *)meuh); break; - } - } -} - -void set_atom (t_atom *a, CvPoint &v) { - t_binbuf *b = binbuf_new(); - binbuf_addv(b,"ii",v.y,v.x); - SETLIST(a,b); -} -void set_atom (t_atom *a, CvSize &v) { - t_binbuf *b = binbuf_new(); - binbuf_addv(b,"ii",v.height,v.width); - SETLIST(a,b); -} -void set_atom (t_atom *a, CvScalar &scal) { - t_binbuf *b = binbuf_new(); - binbuf_addv(b,"ffff",scal.val[0],scal.val[1],scal.val[2],scal.val[3]); - SETLIST(a,b); -} -CvPoint convert (const t_atom &a, CvPoint *) {USELIST; return cvPoint( GETI(0),GETI(1));} -CvSize convert (const t_atom &a, CvSize *) {USELIST; return cvSize( GETI(0),GETI(1));} -CvScalar convert (const t_atom &a, CvScalar *) {USELIST; return cvScalar(GETF(0),GETF(1),GETF(2),GETF(3));} - -/* ******************************** CLASSES ******************************** */ - -\class CvOp1 : FObject { - \attr CvMode mode; - \constructor (...) {mode = cv_mode_auto;} - /* has no default \grin 0 handler so far. */ -}; -\end class {} - -// from flow_objects.c -static void snap_backstore (PtrGrid &r) {if (r.next) {r=r.next.p; r.next=0;}} - -\class CvOp2 : CvOp1 { - PtrGrid r; - \constructor (Grid *r=0) {this->r = r?r:new Grid(new Dim(),int32_e,true);} - virtual void func(CvArr *l, CvArr *r, CvArr *o) {/* rien */} - \grin 0 - \grin 1 -}; -GRID_INLET(0) { - snap_backstore(r); - SAME_TYPE(in,r); - if (!in->dim->equal(r->dim)) RAISE("dimension mismatch: left:%s right:%s",in->dim->to_s(),r->dim->to_s()); - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,(T *)data); - PtrGrid o = new Grid(in->dim,in->nt); - CvArr *a = cvGrid(l,mode); - CvArr *b = cvGrid(r,mode); - CvArr *c = cvGrid(o,mode); - func(a,b,c); - cvRelease(&a); - cvRelease(&b); - cvRelease(&c); - out = new GridOutlet(this,0,in->dim,in->nt); - out->send(o->dim->prod(),(T *)o->data); -} GRID_END -GRID_INPUT2(1,r) {} GRID_END -\end class {} - -#define FUNC(CLASS) CLASS(BFObject *bself, MESSAGE):CvOp2(bself,MESSAGE2) {} virtual void func(CvArr *l, CvArr *r, CvArr *o) -#define HELP class_sethelpsymbol(fclass->bfclass,gensym("cv/#numop")); - -\class CvAdd : CvOp2 {FUNC(CvAdd) {cvAdd(l,r,o,0);}}; -\end class {install("cv/#Add",2,1); HELP} -\class CvSub : CvOp2 {FUNC(CvSub) {cvSub(l,r,o,0);}}; -\end class {install("cv/#Sub",2,1); HELP} -\class CvMul : CvOp2 {FUNC(CvMul) {cvMul(l,r,o,1);}}; -\end class {install("cv/#Mul",2,1); HELP} -\class CvDiv : CvOp2 {FUNC(CvDiv) {cvDiv(l,r,o,1);}}; -\end class {install("cv/#Div",2,1); HELP} -\class CvAnd : CvOp2 {FUNC(CvAnd) {cvAnd(l,r,o,0);}}; -\end class {install("cv/#And",2,1); HELP} -\class CvOr : CvOp2 {FUNC(CvOr ) {cvOr( l,r,o,0);}}; -\end class {install("cv/#Or" ,2,1); HELP} -\class CvXor : CvOp2 {FUNC(CvXor) {cvXor(l,r,o,0);}}; -\end class {install("cv/#Xor",2,1); HELP} - -\class CvInvert : CvOp1 { - \constructor () {} - \grin 0 -}; -GRID_INLET(0) { - if (in->dim->n!=2) RAISE("should have 2 dimensions"); - if (in->dim->v[0] != in->dim->v[1]) RAISE("matrix should be square"); - in->set_chunk(0); -} GRID_FLOW { - //post("l=%p, r=%p", &*l, &*r); - PtrGrid l = new Grid(in->dim,(T *)data); - PtrGrid o = new Grid(in->dim,in->nt); - CvArr *a = cvGrid(l,mode); - CvArr *c = cvGrid(o,mode); - //post("a=%p, b=%p", a, b); - cvInvert(a,c); - cvRelease(&a); - cvRelease(&c); - out = new GridOutlet(this,0,in->dim,in->nt); - out->send(o->dim->prod(),(T *)o->data); -} GRID_END -\end class {install("cv/#Invert",1,1);} - -\class CvSVD : CvOp1 { - \grin 0 - \constructor () {} -}; -GRID_INLET(0) { - if (in->dim->n!=2) RAISE("should have 2 dimensions"); - if (in->dim->v[0] != in->dim->v[1]) RAISE("matrix should be square"); - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,(T *)data); - PtrGrid o0 = new Grid(in->dim,in->nt); - PtrGrid o1 = new Grid(in->dim,in->nt); - PtrGrid o2 = new Grid(in->dim,in->nt); - CvArr *a = cvGrid(l,mode); - CvArr *c0 = cvGrid(o0,mode); - CvArr *c1 = cvGrid(o1,mode); - CvArr *c2 = cvGrid(o2,mode); - cvSVD(a,c0,c1,c2); - cvRelease(&a); - cvRelease(&c0); - cvRelease(&c1); - cvRelease(&c2); - out = new GridOutlet(this,2,in->dim,in->nt); out->send(o2->dim->prod(),(T *)o2->data); - out = new GridOutlet(this,1,in->dim,in->nt); out->send(o1->dim->prod(),(T *)o1->data); - out = new GridOutlet(this,0,in->dim,in->nt); out->send(o0->dim->prod(),(T *)o0->data); -} GRID_END -\end class {install("cv/#SVD",1,3);} - -\class CvEllipse : FObject { - \grin 0 - \attr CvPoint center; - \attr CvSize axes; - \attr double angle; - \attr double start_angle; - \attr double end_angle; - \attr CvScalar color; - \attr int thickness; - \attr int line_type; - \attr int shift; - \constructor () { - center=cvPoint(0,0); axes=cvSize(0,0); angle=0; start_angle=0; end_angle=360; color=cvScalar(0); - thickness=1; line_type=8; shift=0; - } -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,in->nt); COPY((T *)*l,data,in->dim->prod()); - IplImage *img = cvImageGrid(l); - cvEllipse(img,center,axes,angle,start_angle,end_angle,color,thickness,line_type,shift); - cvReleaseImageHeader(&img); - out = new GridOutlet(this,0,in->dim,in->nt); out->send(in->dim->prod(),(T *)*l); -} GRID_END -\end class {install("cv/#Ellipse",1,2);} - -\class CvApproxPoly : CvOp1 { - \grin 0 - \attr int accuracy; - \attr bool closed; - CvMemStorage* storage; - \constructor () {closed=true; storage = cvCreateMemStorage(0);} - ~CvApproxPoly () {cvReleaseMemStorage(&storage);} -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,(T *)data); CvArr *a = cvGrid(l,mode); - CvSeq *seq = cvApproxPoly(a,sizeof(CvMat),storage,CV_POLY_APPROX_DP,accuracy,closed); - seq=seq; //blah -} GRID_END -\end class {install("cv/#ApproxPoly",1,1);} - -\class CvCalcOpticalFlowHS : CvOp1 { - \grin 0 - \attr double lambda; - //\attr CvTermCriteria criteria; - \constructor () {} -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { -// cvCalcOpticalFlowHS(prev,curr,use_previous, CvArr* velx, CvArr* vely, lambda, CvTermCriteria criteria ); -} GRID_END -\end class {install("cv/#CalcOpticalFlowHS",1,1);} -\class CvCalcOpticalFlowLK : CvOp1 { - \grin 0 - \constructor () {} -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { -} GRID_END -\end class {install("cv/#CalcOpticalFlowLK",1,1);} -\class CvCalcOpticalFlowBM : CvOp1 { - \grin 0 - \constructor () {} -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { -} GRID_END -\end class {install("cv/#CalcOpticalFlowBM",1,1);} -\class CvCalcOpticalFlowPyrLK : CvOp1 { - \grin 0 - \constructor () {} -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { -} GRID_END -\end class {install("cv/#CalcOpticalFlowPyrLK",1,1);} - -/* -void cvCalcOpticalFlowLK(const CvArr* prev, const CvArr* curr, CvSize win_size, CvArr* velx, CvArr* vely); -void cvCalcOpticalFlowBM(const CvArr* prev, const CvArr* curr, CvSize block_size, CvSize shift_size, CvSize max_range, int use_previous, - CvArr* velx, CvArr* vely); -void cvCalcOpticalFlowPyrLK(const CvArr* prev, const CvArr* curr, CvArr* prev_pyr, CvArr* curr_pyr, - const CvPoint2D32f* prev_features, CvPoint2D32f* curr_features, - int count, CvSize win_size, int level, char* status, - float* track_error, CvTermCriteria criteria, int flags ); -void cvCalcBackProject( IplImage** image, CvArr* back_project, const CvHistogram* hist ); -void cvCalcHist( IplImage** image, CvHistogram* hist, int accumulate=0, const CvArr* mask=NULL ); -CvHistogram* cvCreateHist( int dims, int* sizes, int type, float** ranges=NULL, int uniform=1 ); -void cvSnakeImage( const IplImage* image, CvPoint* points, int length, float* alpha, float* beta, float* gamma, int coeff_usage, - CvSize win, CvTermCriteria criteria, int calc_gradient=1 ); -int cvMeanShift( const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp ); -int cvCamShift( const CvArr* prob_image, CvRect window, CvTermCriteria criteria, CvConnectedComp* comp, CvBox2D* box=NULL ); -*/ - -/* ******************************** UNFINISHED ******************************** */ - -\class CvSplit : CvOp1 { - int channels; - \constructor (int channels) { - if (channels<0 || channels>64) RAISE("channels=%d is not in 1..64",channels); - this->channels = channels; - bself->noutlets_set(channels); - } -}; -\end class {} - -\class CvHaarDetectObjects : FObject { - \attr double scale_factor; /*=1.1*/ - \attr int min_neighbors; /*=3*/ - \attr int flags; /*=0*/ - \constructor () { - scale_factor=1.1; - min_neighbors=3; - flags=0; - //cascade = cvLoadHaarClassifierCascade("",cvSize(24,24)); - const char *filename = OPENCV_SHARE_PATH "/haarcascades/haarcascade_frontalface_alt2.xml"; - FILE *f = fopen(filename,"r"); - if (!f) RAISE("error opening %s: %s",filename,strerror(errno)); - fclose(f); - cascade = (CvHaarClassifierCascade *)cvLoad(filename,0,0,0); - int s = cvGetErrStatus(); - post("cascade=%p, cvGetErrStatus=%d cvErrorStr=%s",cascade,s,cvErrorStr(s)); - //cascade = cvLoadHaarClassifierCascade(OPENCV_SHARE_PATH "/data/haarcascades/haarcascade_frontalface_alt2.xml",cvSize(24,24)); - storage = cvCreateMemStorage(0); - } - CvHaarClassifierCascade *cascade; - CvMemStorage *storage; - \grin 0 -}; -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,(T *)data); - IplImage *img = cvImageGrid(l); - CvSeq *ret = cvHaarDetectObjects(img,cascade,storage,scale_factor,min_neighbors,flags); - int n = ret ? ret->total : 0; - out = new GridOutlet(this,0,new Dim(n,2,2)); - for (int i=0; iy,r->x,r->y+r->height,r->x+r->width}; - out->send(4,duh); - } -} GRID_END -\end class {install("cv/#HaarDetectObjects",2,1);} - -/* **************************************************************** */ - -\class CvKMeans : CvOp1 { - \attr int numClusters; - \attr CvTermCriteria termcrit; - \grin 0 float32 - \decl 1 float (int v); - \constructor (int v) { - _1_float(0,0,v); - termcrit = CvTermCriteria(); - } -}; - -\def 1 float (int v) {numClusters = v;} - -//post("typeof(a)=%p typeof(c)=%p typeof(CvMat)=%p",cvTypeOf(a),cvTypeOf(c),cvFindType("opencv-matrix")); -//for (CvTypeInfo *t = cvFirstType(); t; t=t->next) post("type %s",t->type_name); - -GRID_INLET(0) { - if (in->dim->n<1) RAISE("should have at least 1 dimension"); - in->set_chunk(0); -} GRID_FLOW { - int32 v[] = {in->dim->prod(0)/in->dim->prod(-1),in->dim->prod(-1)}; - PtrGrid l = new Grid(new Dim(2,v),(T *)data); - CvArr *a = (CvMat *)cvGrid(l,mode,2); - PtrGrid o = new Grid(new Dim(1,v),int32_e); - CvArr *c = (CvMat *)cvGrid(o,mode); - cvKMeans2(a,numClusters,c,termcrit); - int w[in->dim->n]; - COPY(w,in->dim->v,in->dim->n); - w[in->dim->n-1] = 1; - P d = new Dim(in->dim->n,w); - out = new GridOutlet(this,0,d); - out->send(v[0],(int32 *)*o); - cvRelease(&a); - cvRelease(&c); -} GRID_END - -\end class {install("cv/#KMeans",2,1);} - -\class CvCornerHarris : CvOp1 { - \attr int block_size; - \attr int aperture_size; - \attr double k; - \constructor () { - block_size = 3; - aperture_size = 3; - k = 0.04; - } - \grin 0 -}; - -GRID_INLET(0) { - in->set_chunk(0); -} GRID_FLOW { - PtrGrid l = new Grid(in->dim,(T *)data); - CvArr *a = (CvMat *)cvGrid(l,mode,2); - PtrGrid o = new Grid(in->dim,float32_e); - CvArr *c = (CvMat *)cvGrid(o,mode); - cvCornerHarris(a,c,block_size,aperture_size,k); - cvRelease(&a); - cvRelease(&c); - out = new GridOutlet(this,0,in->dim,in->nt); out->send(o->dim->prod(),(T *)o->data); -} GRID_END - -\end class {install("cv/#CornerHarris",1,1);} - -/* **************************************************************** */ - -static int erreur_handleur (int status, const char* func_name, const char* err_msg, const char* file_name, int line, void *userdata) { - cvSetErrStatus(CV_StsOk); - // we might be looking for trouble because we don't know whether OpenCV is throw-proof. - RAISE("OpenCV error: status='%s' func_name=%s err_msg=\"%s\" file_name=%s line=%d",cvErrorStr(status),func_name,err_msg,file_name,line); - // if this breaks OpenCV, then we will have to use post() or a custom hybrid of post() and RAISE() that does not cause a - // longjmp when any OpenCV functions are on the stack. - return 0; -} - -void startup_opencv() { - /* CvErrorCallback z = */ cvRedirectError(erreur_handleur); - \startall -} diff --git a/externals/gridflow/src/png.cxx b/externals/gridflow/src/png.cxx deleted file mode 100644 index d61361c5..00000000 --- a/externals/gridflow/src/png.cxx +++ /dev/null @@ -1,143 +0,0 @@ -/* - $Id: png.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* !@#$ not handling abort on compress */ -/* !@#$ not handling abort on decompress */ - -#include "gridflow.hxx.fcs" -extern "C" { -#include -}; - -\class FormatPNG : Format { - P bit_packing; - png_structp png; - png_infop info; - \constructor (t_symbol *mode, string filename) { - Format::_0_open(0,0,mode,filename); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); - } - \decl 0 bang (); - \grin 0 int -}; - -GRID_INLET(0) { - if (in->dim->n!=3) RAISE("expecting 3 dimensions: rows,columns,channels"); - int c = in->dim->get(2); - if (c!=3) RAISE("expecting 3 channels (got %d)",in->dim->get(2)); - in->set_chunk(0); -} GRID_FLOW { - png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png) RAISE("!png"); - info = png_create_info_struct(png); - if (!info) {if (png) png_destroy_write_struct(&png, NULL); RAISE("!info");} - if (setjmp(png_jmpbuf(png))) {png_destroy_write_struct(&png, &info); RAISE("png write error");} - if (setjmp(png->jmpbuf)) {png_write_destroy(png); free(png); free(info); RAISE("png write error");} - png_init_io(png, f); - info->width = in->dim->get(1); - info->height = in->dim->get(0); - info->bit_depth = 8; -// info->color_type = channels==3 ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_GRAY; - info->color_type = PNG_COLOR_TYPE_RGB; -// info->color_type |= PNG_COLOR_MASK_ALPHA; - info->interlace_type = 1; - png_write_info(png,info); - png_set_packing(png); -// this would have been the GRID_FLOW section - int rowsize = in->dim->get(1)*in->dim->get(2); - int rowsize2 = in->dim->get(1)*3; - uint8 row[rowsize2]; - while (n) { - post("n=%ld",long(n)); - bit_packing->pack(in->dim->get(1),data,row); - png_write_row(png,row); - n-=rowsize; data+=rowsize; - } -// this would have been the GRID_FINISH section - post("GRID FINISH 1"); - png_write_end(png,info); - post("GRID FINISH 2"); - png_write_destroy(png); - post("GRID FINISH 3"); - fflush(f); - free(png); - free(info); - fclose(f); -} GRID_FINISH { -} GRID_END - -\def 0 bang () { - uint8 sig[8]; - if (!fread(sig, 1, 8, f)) {outlet_bang(bself->te_outlet); return;} - if (!png_check_sig(sig, 8)) RAISE("bad signature"); - png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png) RAISE("!png"); - info = png_create_info_struct(png); - if (!info) {png_destroy_read_struct(&png, NULL, NULL); RAISE("!info");} - if (setjmp(png_jmpbuf(png))) {png_destroy_read_struct(&png, &info, NULL); RAISE("png read error");} - png_init_io(png, f); - png_set_sig_bytes(png, 8); // we already read the 8 signature bytes - png_read_info(png, info); // read all PNG info up to image data - png_uint_32 width, height; - int bit_depth, color_type; - png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, 0,0,0); - - png_bytepp row_pointers = 0; - if (color_type == PNG_COLOR_TYPE_PALETTE - || (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - || png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_expand(png); - // 16bpp y, 32bpp ya, 48bpp rgb, 64bpp rgba... - if (bit_depth == 16) png_set_strip_16(png); - - double display_gamma = 2.2; - double gamma; - if (png_get_gAMA(png, info, &gamma)) - png_set_gamma(png, display_gamma, gamma); - png_read_update_info(png, info); - - int rowbytes = png_get_rowbytes(png, info); - int channels = (int)png_get_channels(png, info); - uint8 *image_data = new uint8[rowbytes*height]; - row_pointers = new png_bytep[height]; - //gfpost("png: color_type=%d channels=%d, width=%d, rowbytes=%ld, height=%ld, gamma=%f", - // color_type, channels, width, rowbytes, height, gamma); - for (int i=0; i<(int)height; i++) row_pointers[i] = image_data + i*rowbytes; - if ((uint32)rowbytes != width*channels) - RAISE("rowbytes mismatch: %d is not %d*%d=%d", rowbytes, width, channels, width*channels); - png_read_image(png, row_pointers); - delete[] row_pointers; - row_pointers = 0; - png_read_end(png, 0); - GridOutlet out(this,0,new Dim(height, width, channels), cast); - out.send(rowbytes*height,image_data); - delete[] image_data; - png_destroy_read_struct(&png, &info, NULL); -} - -\classinfo {install_format("#io.png",4,"png");} -\end class FormatPNG -void startup_png () { - \startall -} diff --git a/externals/gridflow/src/pwc-ioctl.h b/externals/gridflow/src/pwc-ioctl.h deleted file mode 100644 index 65805eaa..00000000 --- a/externals/gridflow/src/pwc-ioctl.h +++ /dev/null @@ -1,292 +0,0 @@ -#ifndef PWC_IOCTL_H -#define PWC_IOCTL_H - -/* (C) 2001-2004 Nemosoft Unv. - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* This is pwc-ioctl.h belonging to PWC 8.12.1 - It contains structures and defines to communicate from user space - directly to the driver. - */ - -/* - Changes - 2001/08/03 Alvarado Added ioctl constants to access methods for - changing white balance and red/blue gains - 2002/12/15 G. H. Fernandez-Toribio VIDIOCGREALSIZE - 2003/12/13 Nemosft Unv. Some modifications to make interfacing to - PWCX easier - */ - -/* These are private ioctl() commands, specific for the Philips webcams. - They contain functions not found in other webcams, and settings not - specified in the Video4Linux API. - - The #define names are built up like follows: - VIDIOC VIDeo IOCtl prefix - PWC Philps WebCam - G optional: Get - S optional: Set - ... the function - */ - - - /* Enumeration of image sizes */ -#define PSZ_SQCIF 0x00 -#define PSZ_QSIF 0x01 -#define PSZ_QCIF 0x02 -#define PSZ_SIF 0x03 -#define PSZ_CIF 0x04 -#define PSZ_VGA 0x05 -#define PSZ_MAX 6 - - -/* The frame rate is encoded in the video_window.flags parameter using - the upper 16 bits, since some flags are defined nowadays. The following - defines provide a mask and shift to filter out this value. - - In 'Snapshot' mode the camera freezes its automatic exposure and colour - balance controls. - */ -#define PWC_FPS_SHIFT 16 -#define PWC_FPS_MASK 0x00FF0000 -#define PWC_FPS_FRMASK 0x003F0000 -#define PWC_FPS_SNAPSHOT 0x00400000 - - -/* structure for transfering x & y coordinates */ -struct pwc_coord -{ - int x, y; /* guess what */ - int size; /* size, or offset */ -}; - - -/* Used with VIDIOCPWCPROBE */ -struct pwc_probe -{ - char name[32]; - int type; -}; - -struct pwc_serial -{ - char serial[30]; /* String with serial number. Contains terminating 0 */ -}; - -/* pwc_whitebalance.mode values */ -#define PWC_WB_INDOOR 0 -#define PWC_WB_OUTDOOR 1 -#define PWC_WB_FL 2 -#define PWC_WB_MANUAL 3 -#define PWC_WB_AUTO 4 - -/* Used with VIDIOCPWC[SG]AWB (Auto White Balance). - Set mode to one of the PWC_WB_* values above. - *red and *blue are the respective gains of these colour components inside - the camera; range 0..65535 - When 'mode' == PWC_WB_MANUAL, 'manual_red' and 'manual_blue' are set or read; - otherwise undefined. - 'read_red' and 'read_blue' are read-only. -*/ -struct pwc_whitebalance -{ - int mode; - int manual_red, manual_blue; /* R/W */ - int read_red, read_blue; /* R/O */ -}; - -/* - 'control_speed' and 'control_delay' are used in automatic whitebalance mode, - and tell the camera how fast it should react to changes in lighting, and - with how much delay. Valid values are 0..65535. -*/ -struct pwc_wb_speed -{ - int control_speed; - int control_delay; - -}; - -/* Used with VIDIOCPWC[SG]LED */ -struct pwc_leds -{ - int led_on; /* Led on-time; range = 0..25000 */ - int led_off; /* Led off-time; range = 0..25000 */ -}; - -/* Image size (used with GREALSIZE) */ -struct pwc_imagesize -{ - int width; - int height; -}; - -/* Defines and structures for Motorized Pan & Tilt */ -#define PWC_MPT_PAN 0x01 -#define PWC_MPT_TILT 0x02 -#define PWC_MPT_TIMEOUT 0x04 /* for status */ - -/* Set angles; when absolute != 0, the angle is absolute and the - driver calculates the relative offset for you. This can only - be used with VIDIOCPWCSANGLE; VIDIOCPWCGANGLE always returns - absolute angles. - */ -struct pwc_mpt_angles -{ - int absolute; /* write-only */ - int pan; /* degrees * 100 */ - int tilt; /* degress * 100 */ -}; - -/* Range of angles of the camera, both horizontally and vertically. - */ -struct pwc_mpt_range -{ - int pan_min, pan_max; /* degrees * 100 */ - int tilt_min, tilt_max; -}; - -struct pwc_mpt_status -{ - int status; - int time_pan; - int time_tilt; -}; - - -/* This is used for out-of-kernel decompression. With it, you can get - all the necessary information to initialize and use the decompressor - routines in standalone applications. - */ -struct pwc_video_command -{ - int type; /* camera type (645, 675, 730, etc.) */ - int release; /* release number */ - - int size; /* one of PSZ_* */ - int alternate; - int command_len; /* length of USB video command */ - unsigned char command_buf[13]; /* Actual USB video command */ - int bandlength; /* >0 = compressed */ - int frame_size; /* Size of one (un)compressed frame */ -}; - -/* Flags for PWCX subroutines. Not all modules honour all flags. */ -#define PWCX_FLAG_PLANAR 0x0001 -#define PWCX_FLAG_BAYER 0x0008 - - -/* IOCTL definitions */ - - /* Restore user settings */ -#define VIDIOCPWCRUSER _IO('v', 192) - /* Save user settings */ -#define VIDIOCPWCSUSER _IO('v', 193) - /* Restore factory settings */ -#define VIDIOCPWCFACTORY _IO('v', 194) - - /* You can manipulate the compression factor. A compression preference of 0 - means use uncompressed modes when available; 1 is low compression, 2 is - medium and 3 is high compression preferred. Of course, the higher the - compression, the lower the bandwidth used but more chance of artefacts - in the image. The driver automatically chooses a higher compression when - the preferred mode is not available. - */ - /* Set preferred compression quality (0 = uncompressed, 3 = highest compression) */ -#define VIDIOCPWCSCQUAL _IOW('v', 195, int) - /* Get preferred compression quality */ -#define VIDIOCPWCGCQUAL _IOR('v', 195, int) - - -/* Retrieve serial number of camera */ -#define VIDIOCPWCGSERIAL _IOR('v', 198, struct pwc_serial) - - /* This is a probe function; since so many devices are supported, it - becomes difficult to include all the names in programs that want to - check for the enhanced Philips stuff. So in stead, try this PROBE; - it returns a structure with the original name, and the corresponding - Philips type. - To use, fill the structure with zeroes, call PROBE and if that succeeds, - compare the name with that returned from VIDIOCGCAP; they should be the - same. If so, you can be assured it is a Philips (OEM) cam and the type - is valid. - */ -#define VIDIOCPWCPROBE _IOR('v', 199, struct pwc_probe) - - /* Set AGC (Automatic Gain Control); int < 0 = auto, 0..65535 = fixed */ -#define VIDIOCPWCSAGC _IOW('v', 200, int) - /* Get AGC; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCGAGC _IOR('v', 200, int) - /* Set shutter speed; int < 0 = auto; >= 0 = fixed, range 0..65535 */ -#define VIDIOCPWCSSHUTTER _IOW('v', 201, int) - - /* Color compensation (Auto White Balance) */ -#define VIDIOCPWCSAWB _IOW('v', 202, struct pwc_whitebalance) -#define VIDIOCPWCGAWB _IOR('v', 202, struct pwc_whitebalance) - - /* Auto WB speed */ -#define VIDIOCPWCSAWBSPEED _IOW('v', 203, struct pwc_wb_speed) -#define VIDIOCPWCGAWBSPEED _IOR('v', 203, struct pwc_wb_speed) - - /* LEDs on/off/blink; int range 0..65535 */ -#define VIDIOCPWCSLED _IOW('v', 205, struct pwc_leds) -#define VIDIOCPWCGLED _IOR('v', 205, struct pwc_leds) - - /* Contour (sharpness); int < 0 = auto, 0..65536 = fixed */ -#define VIDIOCPWCSCONTOUR _IOW('v', 206, int) -#define VIDIOCPWCGCONTOUR _IOR('v', 206, int) - - /* Backlight compensation; 0 = off, otherwise on */ -#define VIDIOCPWCSBACKLIGHT _IOW('v', 207, int) -#define VIDIOCPWCGBACKLIGHT _IOR('v', 207, int) - - /* Flickerless mode; = 0 off, otherwise on */ -#define VIDIOCPWCSFLICKER _IOW('v', 208, int) -#define VIDIOCPWCGFLICKER _IOR('v', 208, int) - - /* Dynamic noise reduction; 0 off, 3 = high noise reduction */ -#define VIDIOCPWCSDYNNOISE _IOW('v', 209, int) -#define VIDIOCPWCGDYNNOISE _IOR('v', 209, int) - - /* Real image size as used by the camera; tells you whether or not there's a gray border around the image */ -#define VIDIOCPWCGREALSIZE _IOR('v', 210, struct pwc_imagesize) - - /* Motorized pan & tilt functions */ -#define VIDIOCPWCMPTRESET _IOW('v', 211, int) -#define VIDIOCPWCMPTGRANGE _IOR('v', 211, struct pwc_mpt_range) -#define VIDIOCPWCMPTSANGLE _IOW('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTGANGLE _IOR('v', 212, struct pwc_mpt_angles) -#define VIDIOCPWCMPTSTATUS _IOR('v', 213, struct pwc_mpt_status) - - /* Get the USB set-video command; needed for initializing libpwcx */ -#define VIDIOCPWCGVIDCMD _IOR('v', 215, struct pwc_video_command) -struct pwc_table_init_buffer { - int len; - char *buffer; - -}; -#define VIDIOCPWCGVIDTABLE _IOR('v', 216, struct pwc_table_init_buffer) - -#endif diff --git a/externals/gridflow/src/quartz.m b/externals/gridflow/src/quartz.m deleted file mode 100644 index 91bcb84d..00000000 --- a/externals/gridflow/src/quartz.m +++ /dev/null @@ -1,224 +0,0 @@ -/* - $Id: quartz.m 4517 2009-10-30 16:01:30Z matju $ - - GridFlow - Copyright (c) 2001-2008 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* - This is written in Objective C++, which is the union of C++ and Objective C; - Their intersection is C or almost. They add quite different sets of features. - I need Objective C here because the Cocoa API is for Objective C and Java only, - and the Objective C one was the easiest to integrate in GridFlow. - - The next best possibility may be using RubyCocoa, a port of the Cocoa API to Ruby; - However I haven't checked whether Quartz is wrapped, and how easy it is to - process images. -*/ - -#include -#include -#include - -#include "gridflow.hxx.fcs" - -@interface GFView: NSView { - uint8 *imdata; - int imwidth; - int imheight; -} -- (id) drawRect: (NSRect)rect; -- (id) imageHeight: (int)w width: (int)h; -- (int) imageHeight; -- (int) imageWidth; -- (uint8 *) imageData; -- (int) imageDataSize; -@end - -@implementation GFView - -- (uint8 *) imageData {return imdata;} -- (int) imageDataSize {return imwidth*imheight*4;} -- (int) imageHeight {return imheight;} -- (int) imageWidth {return imwidth;} - -- (id) imageHeight: (int)h width: (int)w { - if (imheight==h && imwidth==w) return self; - //post("new size: y=%d x=%d",h,w); - imheight=h; - imwidth=w; - if (imdata) delete imdata; - int size = [self imageDataSize]; - imdata = new uint8[size]; - CLEAR(imdata,size); - NSSize s = {w,h}; - [[self window] setContentSize: s]; - return self; -} - -- (id) initWithFrame: (NSRect)r { - [super initWithFrame: r]; - imdata=0; imwidth=-1; imheight=-1; - [self imageHeight: 240 width: 320]; - return self; -} - -- (id) drawRect: (NSRect)rect { - [super drawRect: rect]; - if (![self lockFocusIfCanDraw]) return self; - CGContextRef g = (CGContextRef) - [[NSGraphicsContext graphicsContextWithWindow: [self window]] - graphicsPort]; - CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB(); - CGDataProviderRef dp = CGDataProviderCreateWithData( - NULL, imdata, imheight*imwidth*4, NULL); - CGImageRef image = CGImageCreate(imwidth, imheight, 8, 32, imwidth*4, - cs, kCGImageAlphaFirst, dp, NULL, 0, kCGRenderingIntentDefault); - CGDataProviderRelease(dp); - CGColorSpaceRelease(cs); - CGRect rectangle = CGRectMake(0,0,imwidth,imheight); - CGContextDrawImage(g,rectangle,image); - CGImageRelease(image); - [self unlockFocus]; - return self; -} -@end - -/* workaround: bus error in gcc */ -uint8 *GFView_imageData(GFView *self) {return (uint8 *)[self imageData];} - -void GFView_imageHeight_width(GFView *self, int height, int width) { - [self imageHeight: height width: width]; -} - -void GFView_display(GFView *self) { - NSRect r = {{0,0},{[self imageHeight],[self imageWidth]}}; - [self displayRect: r]; - [self setNeedsDisplay: YES]; - [self display]; -} - -struct FormatQuartz; -void FormatQuartz_call(FormatQuartz *self); - -\class FormatQuartz : Format { - NSWindow *window; - NSWindowController *wc; - GFView *widget; /* GridFlow's Cocoa widget */ - t_clock *clock; - \constructor (t_symbol *mode) { - NSRect r = {{0,0}, {320,240}}; - window = [[NSWindow alloc] - initWithContentRect: r - styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask - backing: NSBackingStoreBuffered - defer: YES]; - widget = [[GFView alloc] initWithFrame: r]; - [window setContentView: widget]; - [window setTitle: @"GridFlow"]; - [window makeKeyAndOrderFront: NSApp]; - [window orderFrontRegardless]; - wc = [[NSWindowController alloc] initWithWindow: window]; - clock = clock_new(this,(t_method)FormatQuartz_call); - [window makeFirstResponder: widget]; - //post("mainWindow = %08lx",(long)[NSApp mainWindow]); - //post(" keyWindow = %08lx",(long)[NSApp keyWindow]); - NSColor *color = [NSColor clearColor]; - [window setBackgroundColor: color]; - } - ~FormatQuartz () { - clock_unset(clock); - clock_free(clock); - clock = 0; - [window autorelease]; - [window setReleasedWhenClosed: YES]; - [window close]; - } - void call (); - \grin 0 -}; - -static NSDate *distantFuture, *distantPast; - -void FormatQuartz::call() { - NSEvent *e = [NSApp nextEventMatchingMask: NSAnyEventMask - // untilDate: distantFuture // blocking - untilDate: distantPast // nonblocking - inMode: NSDefaultRunLoopMode - dequeue: YES]; - if (e) { - NSLog(@"%@", e); - [NSApp sendEvent: e]; - } - [NSApp updateWindows]; - [this->window flushWindowIfNeeded]; - clock_delay(clock,20); -} -void FormatQuartz_call(FormatQuartz *self) {self->call();} - -template -static void convert_number_type(int n, T *out, S *in) { - for (int i=0; idim->n!=3) RAISE("expecting 3 dims, not %d", in->dim->n); - int c=in->dim->get(2); - if (c!=3&&c!=4) RAISE("expecting 3 or 4 channels, not %d", in->dim->get(2)); -// [widget imageHeight: in->dim->get(0) width: in->dim->get(1) ]; - GFView_imageHeight_width(widget,in->dim->get(0),in->dim->get(1)); - in->set_chunk(1); -} GRID_FLOW { - int off = dex/in->dim->prod(2); - int c=in->dim->get(2); - NSView *w = widget; - uint8 *data2 = GFView_imageData(w)+off*4; -// convert_number_type(n,data2,data); - if (c==3) { - while(n) { - data2[0]=255; - data2[1]=(uint8)data[0]; - data2[2]=(uint8)data[1]; - data2[3]=(uint8)data[2]; - data+=3; data2+=4; n-=3; - } - } else { - while(n) { - data2[0]=255; - data2[1]=(uint8)data[0]; - data2[2]=(uint8)data[1]; - data2[3]=(uint8)data[2]; - data+=4; data2+=4; n-=4; - } - } -} GRID_FINISH { - GFView_display(widget); -} GRID_END - -\end class FormatQuartz { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - distantFuture = [NSDate distantFuture]; - distantPast = [NSDate distantPast]; - [NSApplication sharedApplication]; - install_format("#io.quartz",2,""); -} -void startup_quartz () { - \startall -} - diff --git a/externals/gridflow/src/quicktimeapple.cxx b/externals/gridflow/src/quicktimeapple.cxx deleted file mode 100644 index 9b32b85e..00000000 --- a/externals/gridflow/src/quicktimeapple.cxx +++ /dev/null @@ -1,456 +0,0 @@ -/* - $Id: quicktimeapple.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include -#include "gridflow.hxx.fcs" -#include -#include -#include -#include - -typedef ComponentInstance VideoDigitizerComponent, VDC; -typedef ComponentResult VideoDigitizerError, VDE; - -#if 0 -//enum {VDCType='vdig', vdigInterfaceRev=2 }; -//enum {ntscIn=0, currentIn=0, palIn, secamIn, ntscReallyIn }; -//enum {compositeIn, sVideoIn, rgbComponentIn, rgbComponentSyncIn, yuvComponentIn, yuvComponentSyncIn, tvTunerIn, sdiIn}; -//enum {vdPlayThruOff, vdPlayThruOn}; -//enum {vdDigitizerBW, vdDigitizerRGB}; -//enum {vdBroadcastMode, vdVTRMode}; -//enum {vdUseAnyField, vdUseOddField, vdUseEvenField}; -//enum {vdTypeBasic, vdTypeAlpha, vdTypeMask, vdTypeKey}; -/*enum {digiInDoesNTSC, digiInDoesPAL, digiInDoesSECAM, skip 4, - digiInDoesGenLock, digiInDoesComposite, digiInDoesSVideo, digiInDoesComponent, - digiInVTR_Broadcast, digiInDoesColor, digiInDoesBW, skip 17, - digiInSignalLock};*/ -/*bitset {digiOutDoes1, digiOutDoes2, digiOutDoes4, - digiOutDoes8, digiOutDoes16, digiOutDoes32, - digiOutDoesDither, digiOutDoesStretch, digiOutDoesShrink, - digiOutDoesMask, skip 1, - digiOutDoesDouble, digiOutDoesQuad, digiOutDoesQuarter, digiOutDoesSixteenth, - digiOutDoesRotate, digiOutDoesHorizFlip, digiOutDoesVertFlip, digiOutDoesSkew, - digiOutDoesBlend, digiOutDoesWarp, digiOutDoesHW_DMA, - digiOutDoesHWPlayThru, digiOutDoesILUT, digiOutDoesKeyColor, - digiOutDoesAsyncGrabs, digiOutDoesUnreadableScreenBits, - digiOutDoesCompress, digiOutDoesCompressOnly, - digiOutDoesPlayThruDuringCompress, digiOutDoesCompressPartiallyVisible, - digiOutDoesNotNeedCopyOfCompressData};*/ -/*struct DigitizerInfo { - short vdigType; - long inputCapabilityFlags, outputCapabilityFlags; - long inputCurrentFlags, outputCurrentFlags; - short slot; - GDHandle gdh, maskgdh; - short minDestHeight, minDestWidth; - short maxDestHeight, maxDestWidth; - short blendLevels; - long reserved;};*/ -/*struct VdigType { long digType, reserved;};*/ -/*struct VdigTypeList { short count; VdigType list[1];};*/ -/*struct VdigBufferRec { PixMapHandle dest; Point location; long reserved;};*/ -/*struct VdigBufferRecList { - short count; MatrixRecordPtr matrix; RgnHandle mask; VdigBufferRec list[1];};*/ -//typedef VdigBufferRecList *VdigBufferRecListPtr; -//typedef VdigBufferRecListPtr *VdigBufferRecListHandle; -//typedef CALLBACK_API(void,VdigIntProcPtr)(long flags, long refcon); -//typedef STACK_UPP_TYPE(VdigIntProcPtr); -/*struct VDCompressionList { - CodecComponent codec; CodecType cType; Str63 typeName, name; - long formatFlags, compressFlags, reserved;};*/ -//typedef VDCompressionList * VDCompressionListPtr; -//typedef VDCompressionListPtr *VDCompressionListHandle; -/*bitset { - dmaDepth1, dmaDepth2, dmaDepth4, dmaDepth8, dmaDepth16, dmaDepth32, - dmaDepth2Gray, dmaDepth4Gray, dmaDepth8Gray};*/ -//enum {kVDIGControlledFrameRate=-1}; -//bitset {vdDeviceFlagShowInputsAsDevices, vdDeviceFlagHideDevice}; -/*bitset { - vdFlagCaptureStarting, vdFlagCaptureStopping, - vdFlagCaptureIsForPreview, vdFlagCaptureIsForRecord, - vdFlagCaptureLowLatency, vdFlagCaptureAlwaysUseTimeBase, - vdFlagCaptureSetSettingsBegin, vdFlagCaptureSetSettingsEnd};*/ -/*\class VDC -VDE VDGetMaxSrcRect (short inputStd, Rect *maxSrcRect) -VDE VDGetActiveSrcRect(short inputStd, Rect *activeSrcRect) -VDE VD[GS]etDigitizerRect(Rect *digitizerRect) -VDE VDGetVBlankRect(short inputStd, Rect *vBlankRect) -VDE VDGetMaskPixMap(PixMapHandlemaskPixMap) -VDE VDGetPlayThruDestination(PixMapHandle * dest, Rect *destRect, MatrixRecord * m, RgnHandle *mask) -VDE VDUseThisCLUT(CTabHandle colorTableHandle) -VDE VD[SG*]etInputGammaValue(Fixed channel1, Fixed channel2, Fixed channel3) -VDE VD[GS]etBrightness(uint16 *) -VDE VD[GS]etContrast(uint16 *) -VDE VD[GS]etHue(uint16 *) -VDE VD[GS]etSharpness(uint16 *) -VDE VD[GS]etSaturation(uint16 *) -VDE VDGrabOneFrame(VDC ci) -VDE VDGetMaxAuxBuffer(PixMapHandle *pm, Rect *r) -VDE VDGetDigitizerInfo(DigitizerInfo *info) -VDE VDGetCurrentFlags(long *inputCurrentFlag, long *outputCurrentFlag) -VDE VD[SG*]etKeyColor(long index) -VDE VDAddKeyColor(long *index) -VDE VDGetNextKeyColor(long index) -VDE VD[GS]etKeyColorRange(RGBColor minRGB, RGBColor maxRGB) -VDE VDSetDigitizerUserInterrupt(long flags, VdigIntUPP userInterruptProc, long refcon) -VDE VD[SG*]etInputColorSpaceMode(short colorSpaceMode) -VDE VD[SG*]etClipState(short clipEnable) -VDE VDSetClipRgn(RgnHandle clipRegion) -VDE VDClearClipRgn(RgnHandle clipRegion) -VDE VDGetCLUTInUse(CTabHandle *colorTableHandle) -VDE VD[SG*]etPLLFilterType(short pllType) -VDE VDGetMaskandValue(uint16 blendLevel, long *mask, long *value) -VDE VDSetMasterBlendLevel(uint16 *blendLevel) -VDE VDSetPlayThruDestination(PixMapHandledest, RectPtr destRect, MatrixRecordPtr m, RgnHandle mask) -VDE VDSetPlayThruOnOff(short state) -VDE VD[SG*]etFieldPreference(short fieldFlag) -VDE VDPreflightDestination(Rect *digitizerRect, PixMap **dest, RectPtr destRect, MatrixRecordPtr m) -VDE VDPreflightGlobalRect(GrafPtr theWindow, Rect *globalRect) -VDE VDSetPlayThruGlobalRect(GrafPtr theWindow, Rect *globalRect) -VDE VDSetInputGammaRecord(VDGamRecPtrinputGammaPtr) -VDE VDGetInputGammaRecord(VDGamRecPtr *inputGammaPtr) -VDE VD[SG]etBlackLevelValue(uint16 *) -VDE VD[SG]etWhiteLevelValue(uint16 *) -VDE VDGetVideoDefaults(uint16 *blackLevel, uint16 *whiteLevel, uint16 *brightness, uint16 *hue, uint16 *saturation, uint16 *contrast, uint16 *sharpness) -VDE VDGetNumberOfInputs(short *inputs) -VDE VDGetInputFormat(short input, short *format) -VDE VD[SG*]etInput(short input) -VDE VDSetInputStandard(short inputStandard) -VDE VDSetupBuffers(VdigBufferRecListHandle bufferList) -VDE VDGrabOneFrameAsync(short buffer) -VDE VDDone(short buffer) -VDE VDSetCompression(OSTypecompressType, short depth, Rect *bounds, CodecQspatialQuality, CodecQtemporalQuality, long keyFrameRate) -VDE VDCompressOneFrameAsync(VDC ci) -VDE VDCompressDone(UInt8 *queuedFrameCount, Ptr *theData, long *dataSize, UInt8 *similarity, TimeRecord *t) -VDE VDReleaseCompressBuffer(Ptr bufferAddr) -VDE VDGetImageDescription(ImageDescriptionHandle desc) -VDE VDResetCompressSequence(VDC ci) -VDE VDSetCompressionOnOff(Boolean) -VDE VDGetCompressionTypes(VDCompressionListHandle h) -VDE VDSetTimeBase(TimeBase t) -VDE VDSetFrameRate(Fixed framesPerSecond) -VDE VDGetDataRate(long *milliSecPerFrame, Fixed *framesPerSecond, long *bytesPerSecond) -VDE VDGetSoundInputDriver(Str255 soundDriverName) -VDE VDGetDMADepths(long *depthArray, long *preferredDepth) -VDE VDGetPreferredTimeScale(TimeScale *preferred) -VDE VDReleaseAsyncBuffers(VDC ci) -VDE VDSetDataRate(long bytesPerSecond) -VDE VDGetTimeCode(TimeRecord *atTime, void *timeCodeFormat, void *timeCodeTime) -VDE VDUseSafeBuffers(Boolean useSafeBuffers) -VDE VDGetSoundInputSource(long videoInput, long *soundInput) -VDE VDGetCompressionTime(OSTypecompressionType, short depth, Rect *srcRect, CodecQ *spatialQuality, CodecQ *temporalQuality, ulong *compressTime) -VDE VDSetPreferredPacketSize(long preferredPacketSizeInBytes) -VDE VD[SG*]etPreferredImageDimensions(long width, long height) -VDE VDGetInputName(long videoInput, Str255 name) -VDE VDSetDestinationPort(CGrafPtr destPort) -VDE VDGetDeviceNameAndFlags(Str255 outName, UInt32 *outNameFlags) -VDE VDCaptureStateChanging(UInt32inStateFlags) -VDE VDGetUniqueIDs(UInt64 *outDeviceID, UInt64 *outInputID) -VDE VDSelectUniqueIDs(const UInt64 *inDeviceID, const UInt64 *inInputID) -*/ -#endif - -static OSErr callback(ComponentInstanceRecord*, char*, long int, long int*, long int, TimeValue, short int, long int) { - post("FormatQuickTimeCamera callback"); - return noErr; -} - -\class FormatQuickTimeCamera : Format { - P dim; - uint8 *buf; - uint8 *buf2; - VDC vdc; - int m_newFrame; - SeqGrabComponent m_sg; - SGChannel m_vc; - short m_pixelDepth; - Rect rect; - GWorldPtr m_srcGWorld; - PixMapHandle m_pixMap; - Ptr m_baseAddr; - long m_rowBytes; - int m_quality; -//int m_colorspace; - \constructor (t_symbol *mode) { - //vdc = SGGetVideoDigitizerComponent(c); - dim = new Dim(240,320,4); - OSErr e; - rect.top=rect.left=0; - rect.bottom=dim->v[0]; rect.right=dim->v[1]; - int n=0; - Component c = 0; - ComponentDescription cd; - cd.componentType = SeqGrabComponentType; - cd.componentSubType = 0; - cd.componentManufacturer = 0; - cd.componentFlags = 0; - cd.componentFlagsMask = 0; - for(;;) { - c = FindNextComponent(c, &cd); - if (!c) break; - ComponentDescription cd2; - Ptr name=0,info=0,icon=0; - GetComponentInfo(c,&cd2,&name,&info,&icon); - post("Component #%d",n); - char *t = (char *)&cd.componentType; - post(" type='%c%c%c%c'",t[3],t[2],t[1],t[0]); - t = (char *)&cd.componentSubType; - post(" subtype='%c%c%c%c'",t[3],t[2],t[1],t[0]); - post(" name=%08x, *name='%*s'",name, *name, name+1); - post(" info=%08x, *info='%*s'",info, *name, info+1); - n++; - } - post("number of components: %d",n); - m_sg = OpenDefaultComponent(SeqGrabComponentType, 0); - if(!m_sg) RAISE("could not open default component"); - e=SGInitialize(m_sg); - if(e!=noErr) RAISE("could not initialize SG"); - e=SGSetDataRef(m_sg, 0, 0, seqGrabDontMakeMovie); - if (e!=noErr) RAISE("dataref failed"); - e=SGNewChannel(m_sg, VideoMediaType, &m_vc); - if(e!=noErr) post("could not make new SG channel"); - e=SGSetChannelBounds(m_vc, &rect); - if(e!=noErr) post("could not set SG ChannelBounds"); - e=SGSetChannelUsage(m_vc, seqGrabPreview); - if(e!=noErr) post("could not set SG ChannelUsage"); - e=SGSetDataProc(m_sg,NewSGDataUPP(callback),0); - if (e!=noErr) post("could not set SG DataProc"); - // m_rowBytes = m_vidXSize*4; - switch (3) { - case 0: e=SGSetChannelPlayFlags(m_vc, channelPlayNormal); break; - case 1: e=SGSetChannelPlayFlags(m_vc, channelPlayHighQuality); break; - case 2: e=SGSetChannelPlayFlags(m_vc, channelPlayFast); break; - case 3: e=SGSetChannelPlayFlags(m_vc, channelPlayAllData); break; - } - int dataSize = dim->prod(); - buf = new uint8[dataSize]; - buf2 = new uint8[dataSize]; - m_rowBytes = dim->prod(1); - e=QTNewGWorldFromPtr (&m_srcGWorld,k32ARGBPixelFormat,&rect,NULL,NULL,0,buf,m_rowBytes); - if (0/*yuv*/) { - int dataSize = dim->prod()*2/4; - buf = new uint8[dataSize]; - m_rowBytes = dim->prod(1)*2/4; - e=QTNewGWorldFromPtr (&m_srcGWorld,k422YpCbCr8CodecType,&rect,NULL,NULL,0,buf,m_rowBytes); - } - if (e!=noErr) RAISE("error #%d at QTNewGWorldFromPtr",e); - if (!m_srcGWorld) RAISE("Could not allocate off screen"); - SGSetGWorld(m_sg,(CGrafPtr)m_srcGWorld, NULL); - //SGStartPreview(m_sg); - e=SGStartRecord(m_sg); - if (e!=noErr) RAISE("error #%d at SGStartRecord",e); - } - ~FormatQuickTimeCamera() { - if (m_vc) if (::SGDisposeChannel(m_sg, m_vc)) RAISE("SGDisposeChannel"); - if (m_sg) { - if (::CloseComponent(m_sg)) RAISE("CloseComponent"); - if (m_srcGWorld) ::DisposeGWorld(m_srcGWorld); - } - } - \decl 0 bang (); - \grin 0 int -}; - -// /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Components.h - -static int nn(int c) {return c?c:' ';} - -/* -pascal Boolean pix_videoDarwin :: SeqGrabberModalFilterProc (DialogPtr theDialog, const EventRecord *theEvent, short *itemHit, long refCon){ - Boolean handled = false; - if ((theEvent->what == updateEvt) && - ((WindowPtr) theEvent->message == (WindowPtr) refCon)) { - BeginUpdate ((WindowPtr) refCon); - EndUpdate ((WindowPtr) refCon); - handled = true; - } - WindowRef awin = GetDialogWindow(theDialog); - ShowWindow (awin); - SetWindowClass(awin,kUtilityWindowClass); - //ChangeWindowAttributes(awin,kWindowStandardHandlerAttribute,0); - //SGPanelEvent(m_sg,m_vc,theDialog,0,theEvent,itemHit,&handled); - //AEProcessAppleEvent (theEvent); - return handled; -} -void pix_videoDarwin :: DoVideoSettings() { - Rect newActiveVideoRect; - Rect curBounds, curVideoRect, newVideoRect; - ComponentResult err; - SGModalFilterUPP seqGragModalFilterUPP; - err = SGGetChannelBounds (m_vc, &curBounds); - err = SGGetVideoRect (m_vc, &curVideoRect); - err = SGPause (m_sg, true); - seqGragModalFilterUPP = (SGModalFilterUPP)NewSGModalFilterUPP(SeqGrabberModalFilterProc); - err = SGSettingsDialog(m_sg, m_vc, 0, NULL, seqGrabSettingsPreviewOnly, seqGragModalFilterUPP, (long)m_srcGWorld); - DisposeSGModalFilterUPP(seqGragModalFilterUPP); - err = SGGetVideoRect (m_vc, &newVideoRect); - err = SGGetSrcVideoBounds (m_vc, &newActiveVideoRect); - err = SGPause (m_sg, false); -} -*/ - -\def 0 bang () { - GridOutlet out(this,0,dim); - int n = dim->prod()/4; - for (int i=0; i> 8; - out.send(dim->prod(),buf2); - SGIdle(m_sg); -} - -GRID_INLET(0) { - RAISE("Unimplemented. Sorry."); -//!@#$ - if (in->dim->n != 3) RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2) != 3) RAISE("expecting 3 channels (got %d)",in->dim->get(2)); - in->set_chunk(0); -} GRID_FLOW { -} GRID_FINISH { -} GRID_END -\end class FormatQuickTimeCamera {install_format("#io.quicktimecamera",4,"");} - -\class FormatQuickTimeApple : Format { - Movie movie; - TimeValue time; - short movie_file; - GWorldPtr gw; /* just like an X11 Image or Pixmap, maybe. */ - uint8 *buffer; - P dim; - int nframe, nframes; - \constructor (t_symbol *mode, string filename) { - /*vdc=0;*/ movie=0; time=0; movie_file=0; gw=0; buffer=0; dim=0; nframe=0; nframes=0; - int err; - filename = gf_find_file(filename); - FSSpec fss; - FSRef fsr; - err = FSPathMakeRef((const UInt8 *)filename.data(), &fsr, NULL); if (err) goto err; - err = FSGetCatalogInfo(&fsr, kFSCatInfoNone, NULL, NULL, &fss, NULL); if (err) goto err; - err = OpenMovieFile(&fss,&movie_file,fsRdPerm); if (err) goto err; - NewMovieFromFile(&movie, movie_file, NULL, NULL, newMovieActive, NULL); - Rect r; - GetMovieBox(movie, &r); - post("handle=%d movie=%d tracks=%d", movie_file, movie, GetMovieTrackCount(movie)); - post("duration=%d; timescale=%d cHz", (long)GetMovieDuration(movie), (long)GetMovieTimeScale(movie)); - nframes = GetMovieDuration(movie); /* i don't think so */ - post("rect=((%d..%d),(%d..%d))", r.top, r.bottom, r.left, r.right); - OffsetRect(&r, -r.left, -r.top); - SetMovieBox(movie, &r); - dim = new Dim(r.bottom-r.top, r.right-r.left, 4); - SetMoviePlayHints(movie, hintsHighQuality, hintsHighQuality); - buffer = new uint8[dim->prod()]; - err = QTNewGWorldFromPtr(&gw, k32ARGBPixelFormat, &r, NULL, NULL, 0, buffer, dim->prod(1)); - if (err) goto err; - return; - err: - // RAISE("can't open file `%s': error #%d (%s)", filename.data(), err, rb_str_ptr(rb_funcall(mGridFlow,SI(macerr),1,INT2NUM(err)))); - RAISE("can't open file `%s': error #%d (0x%08x)", filename.data(), err, err); - } - ~FormatQuickTimeApple() { - if (movie) { - DisposeMovie(movie); - DisposeGWorld(gw); - CloseMovieFile(movie_file); - } - } - \decl 0 codec (string c); - \decl 0 colorspace (string c); - \decl 0 bang (); - \decl 0 seek (int frame); - \decl 0 rewind (); - \grin 0 -}; - -\def 0 seek (int frame) {nframe=frame;} -\def 0 rewind () {_0_seek(0,0,0);} - -\def 0 bang () { - CGrafPtr savedPort; - GDHandle savedDevice; - SetMovieGWorld(movie,gw,GetGWorldDevice(gw)); - Rect r; - GetMovieBox(movie,&r); - PixMapHandle pixmap = GetGWorldPixMap(gw); - short flags = nextTimeStep; - if (nframe>=nframes) {outlet_bang(bself->te_outlet); return;} - if (nframe==0) flags |= nextTimeEdgeOK; - TimeValue duration; - OSType mediaType = VisualMediaCharacteristic; - GetMovieNextInterestingTime(movie, - flags,1,&mediaType,time,0,&time,&duration); - if (time<0) { - time=0; - outlet_bang(bself->te_outlet); - return; - } -// post("quicktime frame #%d; time=%d duration=%d", nframe, (long)time, (long)duration); - SetMovieTimeValue(movie,nframe*duration); - MoviesTask(movie,0); - GridOutlet out(this,0,dim); - uint32 *bufu32 = (uint32 *)buffer; - int n = dim->prod()/4; - int i; - if (is_le()) { - for (; i>8; - } - } else { - for (i=0; i>24); - bufu32[i+1]=(bufu32[i+1]<<8)+(bufu32[i+1]>>24); - bufu32[i+2]=(bufu32[i+2]<<8)+(bufu32[i+2]>>24); - bufu32[i+3]=(bufu32[i+3]<<8)+(bufu32[i+3]>>24); - } - for (; i>24); - } - } - out.send(dim->prod(),buffer); - int nf=nframe; - nframe++; - //return INT2NUM(nf); -} - -GRID_INLET(0) { - RAISE("Unimplemented. Sorry."); -//!@#$ - if (in->dim->n != 3) - RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2) != 3) - RAISE("expecting 3 channels (got %d)",in->dim->get(2)); - in->set_chunk(0); -} GRID_FLOW { -} GRID_FINISH { -} GRID_END - -\def 0 codec (string c) { RAISE("Unimplemented. Sorry."); } -\def 0 colorspace (string c) { RAISE("Unimplemented. Sorry."); } - -\classinfo { - EnterMovies(); - install_format("#io.quicktime",4,"mov"); -} -\end class FormatQuickTimeApple -void startup_quicktimeapple () { - \startall -} diff --git a/externals/gridflow/src/quicktimehw.cxx b/externals/gridflow/src/quicktimehw.cxx deleted file mode 100644 index 38dfcbbb..00000000 --- a/externals/gridflow/src/quicktimehw.cxx +++ /dev/null @@ -1,246 +0,0 @@ -/* - $Id: quicktimehw.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#define QUICKTIMEHW_INCLUDE_HERE -#include "gridflow.hxx.fcs" -#include -#include -#include -#include -#include - -static std::map *> codecs; -static std::map fourccs; - -\class FormatQuickTimeHW : Format { - quicktime_t *anim; - int track; - P dim; - char *codec; - int colorspace; - int channels; - bool started; - P force; - float64 framerate; - P bit_packing; - int jpeg_quality; // in theory we shouldn't need this, but... - ~FormatQuickTimeHW() {if (anim) quicktime_close(anim);} - \constructor (t_symbol *mode, string filename) { - track=0; dim=0; codec=const_cast(QUICKTIME_RAW); - started=false; force=0; framerate=29.97; bit_packing=0; jpeg_quality=75; -// libquicktime may be nice, but it won't take a filehandle, only filename - filename = gf_find_file(filename); - anim = quicktime_open((char *)filename.data(),mode==gensym("in"),mode==gensym("out")); - if (!anim) RAISE("can't open file `%s': %s (or some other reason that libquicktime won't tell us)", - filename.data(), strerror(errno)); - if (mode==gensym("in")) { - /* This doesn't really work: (is it just for encoding?) - if (!quicktime_supported_video(anim,track)) - RAISE("quicktime: unsupported codec: %s", - quicktime_video_compressor(anim,track)); - */ - } - _0_colorspace(0,0,string("rgb")); - quicktime_set_cpus(anim,1); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); - } - \decl 0 bang (); - \decl 0 seek (int32 frame); - \decl 0 rewind (); - \decl 0 force_size (int32 height, int32 width); - \decl 0 codec (string c); - \decl 0 colorspace (string c); - \decl 0 parameter (string name, int32 value); - \decl 0 framerate (float64 f); - \decl 0 size (int32 height, int32 width); - \decl 0 get (); - \grin 0 int -}; - -\def 0 force_size (int32 height, int32 width) { force = new Dim(height, width); } -\def 0 seek (int32 frame) { - quicktime_set_video_position(anim,clip(frame,int32(0),int32(quicktime_video_length(anim,track)-1)),track); -} -\def 0 rewind () {_0_seek(0,0,0);} - -\def 0 bang () { - long length = quicktime_video_length(anim,track); - long nframe = quicktime_video_position(anim,track); - if (nframe >= length) {outlet_bang(bself->te_outlet); return;} - /* if it works, only do it once, to avoid silly stderr messages forgotten in LQT */ - if (!quicktime_reads_cmodel(anim,colorspace,0) && !started) { - RAISE("LQT says this video cannot be decoded into the chosen colorspace"); - } - int sx = quicktime_video_width(anim,track); - int sy = quicktime_video_height(anim,track); - int sz = quicktime_video_depth(anim,track); - channels = sz/8; // hack. how do i get the video's native colormodel ? - switch (sz) { - case 24: colorspace=BC_RGB888; break; - case 32: colorspace=BC_RGBA8888; break; - default: post("strange quicktime. ask matju."); break; - } - if (force) { - sy = force->get(0); - sx = force->get(1); - } - uint8 buf[sy*sx*channels]; - uint8 *rows[sy]; for (int i=0; i(name.data()), &val); - if (name=="jpeg_quality") jpeg_quality=value; -} - -\def 0 framerate (float64 f) { - framerate=f; - quicktime_set_framerate(anim, f); -} - -\def 0 size (int32 height, int32 width) { - if (dim) RAISE("video size already set!"); - // first frame: have to do setup - dim = new Dim(height, width, 3); - quicktime_set_video(anim,1,dim->get(1),dim->get(0),framerate,codec); - quicktime_set_cmodel(anim,colorspace); -} - -GRID_INLET(0) { - if (in->dim->n != 3) RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2)!=channels) RAISE("expecting %d channels (got %d)",channels,in->dim->get(2)); - in->set_chunk(0); - if (dim) { - if (!dim->equal(in->dim)) RAISE("all frames should be same size"); - } else { - // first frame: have to do setup - dim = in->dim; - quicktime_set_video(anim,1,dim->get(1),dim->get(0),framerate,codec); - quicktime_set_cmodel(anim,colorspace); - quicktime_set_depth(anim,8*channels,track); - } - //post("quicktime jpeg_quality %d", jpeg_quality); - quicktime_set_parameter(anim, (char*)"jpeg_quality", &jpeg_quality); -} GRID_FLOW { - int sx = quicktime_video_width(anim,track); - int sy = quicktime_video_height(anim,track); - uint8 *rows[sy]; - if (sizeof(T)>1) { - uint8 data2[n]; - bit_packing->pack(sx*sy,data,(uint8 *)data2); - for (int i=0; ite_outlet,gensym("frames"),1,a); -*/ - t_atom a[1]; - SETFLOAT(a,quicktime_video_length(anim,track)); - outlet_anything(bself->outlets[0],gensym("frames"),1,a); - SETFLOAT(a,quicktime_frame_rate(anim,track)); - outlet_anything(bself->outlets[0],gensym("framerate"),1,a); - SETFLOAT(a,quicktime_video_height(anim,track)); - outlet_anything(bself->outlets[0],gensym("height"),1,a); - SETFLOAT(a,quicktime_video_width(anim,track)); - outlet_anything(bself->outlets[0],gensym("width"),1,a); - SETFLOAT(a,quicktime_video_depth(anim,track)); - outlet_anything(bself->outlets[0],gensym("depth"),1,a); - SETSYMBOL(a,gensym(quicktime_video_compressor(anim,track))); - outlet_anything(bself->outlets[0],gensym("codec"),1,a); - //SUPER; -} - -\classinfo {install_format("#io.quicktime",6,"mov avi"); -// def self.info; %[codecs: #{@codecs.keys.join' '}] end -//#define L fprintf(stderr,"%s:%d in %s\n",__FILE__,__LINE__,__PRETTY_FUNCTION__); -#ifdef LQT_VERSION - lqt_registry_init(); - int n = lqt_get_num_video_codecs(); - for (int i=0; iname) { - fprintf(stderr,"[#in quicktime]: skipping codec with null name!\n"); - continue; - } - string name = string(s->name); - std::vector *f = new std::vector(s->num_fourccs); - if (!s->fourccs) { - post("WARNING: no fourccs (quicktime library is broken?)"); - goto hell; - } - //fprintf(stderr,"num_fourccs=%d fourccs=%p\n",s->num_fourccs,s->fourccs); - for (int j=0; jnum_fourccs; j++) { - string fn = string(s->fourccs[j]); - f->push_back(fn); - fourccs[fn]=name; - } - codecs[name]=f; - hell:; - } -#endif -} -\end class FormatQuickTimeHW -void startup_quicktimehw () { - \startall -} diff --git a/externals/gridflow/src/sdl.cxx b/externals/gridflow/src/sdl.cxx deleted file mode 100644 index 7406611c..00000000 --- a/externals/gridflow/src/sdl.cxx +++ /dev/null @@ -1,209 +0,0 @@ -/* - $Id: sdl.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "gridflow.hxx.fcs" -#include -#include -#include -#include -#include -#include -#include - -struct FormatSDL; -void FormatSDL_call(FormatSDL *self); -static bool in_use = false; -static bool full_screen = false; -static int mousex,mousey,mousem; -SDL_Surface *screen; -FObject *instance; - -static t_symbol *keyboard[SDLK_LAST]; - -static void KEYS_ARE (int i, const char *s__) { - char *s_ = strdup(s__); - char *s = s_; - while (*s) { - char *t = strchr(s,' '); - if (t) *t=0; - keyboard[i] = gensym(s); - if (!t) break; - s=t+1; i++; - } - free(s_); -} - -static void build_keyboard () { - KEYS_ARE(8,"BackSpace Tab"); - KEYS_ARE(13,"Return"); - KEYS_ARE(27,"Escape"); - KEYS_ARE(32,"space exclam quotedbl numbersign dollar percent ampersand apostrophe"); - KEYS_ARE(40,"parenleft parenright asterisk plus comma minus period slash"); - KEYS_ARE(48,"D0 D1 D2 D3 D4 D5 D6 D7 D8 D9"); - KEYS_ARE(58,"colon semicolon less equal greater question at"); - //KEYS_ARE(65,"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"); - KEYS_ARE(91,"bracketleft backslash bracketright asciicircum underscore grave quoteleft"); - KEYS_ARE(97,"a b c d e f g h i j k l m n o p q r s t u v w x y z"); - //SDLK_DELETE = 127 - KEYS_ARE(256,"KP_0 KP_1 KP_2 KP_3 KP_4 KP_5 KP_6 KP_7 KP_8 KP_9"); - KEYS_ARE(266,"KP_Decimal KP_Divide KP_Multiply KP_Subtract KP_Add KP_Enter KP_Equal"); - KEYS_ARE(273,"KP_Up KP_Down KP_Right KP_Left KP_Insert KP_Home KP_End KP_Prior KP_Next"); - KEYS_ARE(282,"F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15"); - KEYS_ARE(300,"Num_Lock Caps_Lock Scroll_Lock"); - KEYS_ARE(303,"Shift_R Shift_L Control_R Control_L Alt_R Alt_L Meta_L Meta_R"); - KEYS_ARE(311,"Super_L Super_R Mode_switch Multi_key"); -} - -static void report_pointer () { - t_atom a[3]; - SETFLOAT(a+0,mousey); - SETFLOAT(a+1,mousex); - SETFLOAT(a+2,mousem); - outlet_anything(instance->bself->outlets[0],gensym("position"),COUNT(a),a); -} - -static void HandleEvent () { - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_KEYDOWN: case SDL_KEYUP: { - int key = event.key.keysym.sym; - int mod = event.key.keysym.mod; - if (event.type==SDL_KEYDOWN && (key==SDLK_F11 || key==SDLK_ESCAPE || key=='f')) { - full_screen = !full_screen; - SDL_WM_ToggleFullScreen(screen); - break; - } - t_symbol *sel = gensym(const_cast(event.type==SDL_KEYDOWN ? "keypress" : "keyrelease")); - t_atom at[4]; - mousem &= ~0xFF; - mousem |= mod; - SETFLOAT(at+0,mousey); - SETFLOAT(at+1,mousex); - SETFLOAT(at+2,mousem); - SETSYMBOL(at+3,keyboard[event.key.keysym.sym]); - outlet_anything(instance->bself->outlets[0],sel,4,at); - } break; - case SDL_MOUSEBUTTONDOWN: SDL_MOUSEBUTTONUP: { - if (SDL_MOUSEBUTTONDOWN) mousem |= (128< bit_packing; - P dim; - t_clock *clock; - void resize_window (int sx, int sy); - void call (); - \decl 0 setcursor (int shape); - \decl 0 hidecursor (); - \decl 0 title (string title); - \constructor (t_symbol *mode) { - dim=0;screen=0; - if (in_use) RAISE("only one FormatSDL object at a time; sorry"); - in_use=true; - if (SDL_Init(SDL_INIT_VIDEO)<0) RAISE("SDL_Init() error: %s",SDL_GetError()); - atexit(SDL_Quit); - resize_window(320,240); - SDL_PixelFormat *f = screen->format; - uint32 mask[3] = {f->Rmask,f->Gmask,f->Bmask}; - switch (f->BytesPerPixel) { - case 1: RAISE("8 bpp not supported"); break; - case 2: case 3: case 4: - bit_packing = new BitPacking(is_le(),f->BytesPerPixel,3,mask); - break; - default: RAISE("%d bytes/pixel: how do I deal with that?",f->BytesPerPixel); break; - } - instance=this; - clock = clock_new(this,(t_method)FormatSDL_call); - clock_delay(clock,0); - _0_title(0,0,string("GridFlow SDL")); - } - \grin 0 int - ~FormatSDL () { - clock_unset(clock); - clock_free(clock); - SDL_Quit(); - instance=0; - in_use=false; - } -}; - -\def 0 title (string title) { - SDL_WM_SetCaption(title.data(),title.data()); -} - -void FormatSDL::call() {HandleEvent(); clock_delay(clock,20);} -void FormatSDL_call(FormatSDL *self) {self->call();} - -void FormatSDL::resize_window (int sx, int sy) { - dim = new Dim(sy,sx,3); - screen = SDL_SetVideoMode(sx,sy,0,SDL_SWSURFACE); - if (!screen) - RAISE("Can't switch to (%d,%d,%dbpp): %s", sy,sx,24, SDL_GetError()); -} - -GRID_INLET(0) { - if (in->dim->n != 3) - RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2) != 3) - RAISE("expecting 3 channels: red,green,blue (got %d)",in->dim->get(2)); - int sx = in->dim->get(1), osx = dim->get(1); - int sy = in->dim->get(0), osy = dim->get(0); - in->set_chunk(1); - if (sx!=osx || sy!=osy) resize_window(sx,sy); -} GRID_FLOW { - int bypl = screen->pitch; - int sxc = in->dim->prod(1); - int sx = in->dim->get(1); - int y = dex/sxc; - if (SDL_MUSTLOCK(screen)) if (SDL_LockSurface(screen) < 0) return; //??? - for (; n>0; y++, data+=sxc, n-=sxc) { - /* convert line */ - bit_packing->pack(sx, data, (uint8 *)screen->pixels+y*bypl); - } - if (SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); -} GRID_FINISH { - SDL_UpdateRect(screen,0,0,in->dim->get(1),in->dim->get(0)); -} GRID_END - -\def 0 setcursor (int shape) {SDL_ShowCursor(SDL_ENABLE);} -\def 0 hidecursor () {SDL_ShowCursor(SDL_DISABLE);} - -\end class FormatSDL {install_format("#io.sdl",2,"");} -void startup_sdl () { - \startall - build_keyboard(); -} diff --git a/externals/gridflow/src/source_filter.rb b/externals/gridflow/src/source_filter.rb deleted file mode 100644 index 9dfef776..00000000 --- a/externals/gridflow/src/source_filter.rb +++ /dev/null @@ -1,311 +0,0 @@ -#!/usr/bin/env ruby -=begin - $Id: source_filter.rb 4452 2009-10-27 15:59:57Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -=end - -$stack = [] -$classes = [] -$exit = 0 - -ClassDecl = Struct.new(:name,:supername,:methods,:grins,:attrs,:info) -MethodDecl = Struct.new(:rettype,:selector,:arglist,:minargs,:maxargs,:where) -Arg = Struct.new(:type,:name,:default) -Attr = Struct.new(:type,:name,:default,:virtual) - -class MethodDecl - def ==(o) - return false unless rettype==o.rettype && maxargs==o.maxargs - arglist.each_index{|i| arglist[i] == o.arglist[i] or return false } - return true - end - def ===(o) - return false unless rettype==o.rettype && maxargs==o.maxargs - arglist.each_index{|i| arglist[i].type == o.arglist[i].type and arglist[i].default == o.arglist[i].default or return false } - return true - end - attr_accessor :done -end - -class Arg - def canon(type) - type="Grid *" if type=="PtrGrid" - type - end - def ==(o) canon(type)==canon(o.type) && name==o.name end -end - -In = File.open ARGV[0], "r" -Out = File.open ARGV[1], "w" - -def handle_class(line) - raise "already in class #{where}" if $stack[-1] and ClassDecl===$stack[-1] - /^(\w+)(?:\s*[:<]\s*(\w+))?\s*(\{.*)?/.match line or raise "syntax error #{where}" - classname = $1 - superclassname = $2 - rest = $3 - q=ClassDecl.new(classname,superclassname,{},{},{},false) - $stack << q - $classes << q - Out.print "#define THISCLASS #{classname}\n\# #{$linenumber}\n" - if rest and /^\{/ =~ rest then - Out.print "struct #{classname} " - Out.print ": #{superclassname}" if superclassname - Out.print rest - end -end - -def parse_methoddecl(line,term) - /^(\w+(?:\s*\*)?)\s+(\w+)\s*\(([^\)]*)\)\s*#{term}/.match line or - raise "syntax error #{where} #{line}" - rettype,selector,arglist = $1,$2,$3,$4 - if /^\d+$/ =~ rettype then - selector = "_"+rettype+"_"+selector - rettype = "void" - end - arglist,minargs,maxargs = parse_arglist arglist - MethodDecl.new(rettype,selector,arglist,minargs,maxargs,where) -end - -def parse_arglist(arglist) - arglist = arglist.split(/,/) - maxargs = arglist.length - args = arglist.map {|arg| - if /^\s*\.\.\.\s*$/.match arg then maxargs=-1; next end - /^\s*([\w\s\*<>]+)\s*\b(\w+)\s*(?:\=(.*))?/.match arg or - raise "syntax error in \"#{arg}\" #{where}" - type,name,default=$1,$2,$3 - Arg.new(type.sub(/\s+$/,""),name,default) - }.compact - minargs = args.length - minargs-=1 while minargs>0 and args[minargs-1].default - [args,minargs,maxargs] -end - -def unparse_arglist(arglist,with_default=true) - arglist.map {|arg| - x="#{arg.type} #{arg.name}" - x << '=' << arg.default if with_default and arg.default - x - }.join(", ") -end - -def where; "[#{ARGV[0]}:#{$linenumber}]" end - -def handle_attr(line) - line.gsub!(/\/\/.*$/,"") # remove comment - frame = $stack[-1] - type = line.gsub(%r"//.*$","").gsub(%r"/\*.*\*/","").gsub(%r";?\s*$","") - virtual = !!type.slice!(/\(\)$/) - name = type.slice!(/\w+$/) - raise "missing \\class #{where}" if not $stack[-1] or not ClassDecl===frame - handle_decl "void ___get(t_symbol *s);" if frame.attrs.size==0 - frame.attrs[name]=Attr.new(type,name,nil,virtual) - if virtual then - handle_decl "#{type} #{name}();" - else - Out.print line - end - type.gsub!(/\s+$/,"") - type.gsub!(/^\s+/,"") - if type=="bool" then - handle_decl "0 #{name} (#{type} #{name}=true);" - else - handle_decl "0 #{name} (#{type} #{name});" - end -end - -def handle_decl(line) - frame = $stack[-1] - raise "missing \\class #{where}" if not frame or not ClassDecl===frame - classname = frame.name - m = parse_methoddecl(line,";\s*$") - frame.methods[m.selector] = m - Out.print "#{m.rettype} #{m.selector}(VA" - Out.print ", #{unparse_arglist m.arglist}" if m.arglist.length>0 - Out.print "); static void #{m.selector}_wrap(#{classname} *self, VA); " -end - -def handle_def(line) - m = parse_methoddecl(line,"\\{?.*$") - term = line[/\{.*/] - qlass = $stack[-1] - raise "missing \\class #{where}" if not qlass or not ClassDecl===qlass - classname = qlass.name - n = m - if qlass.methods[m.selector] - m = qlass.methods[m.selector] - if !m===n then - STDERR.puts "ERROR: def does not match decl:" - STDERR.puts "#{m.where}: \\decl #{m.inspect}" - STDERR.puts "#{n.where}: \\def #{n.inspect}" - $exit = 1 - end - else - qlass.methods[m.selector] = m - end - Out.print "void #{classname}::#{m.selector}_wrap(#{classname} *self, VA) {" - Out.print "static const char *methodspec = \"#{qlass.name}::#{m.selector}(#{unparse_arglist m.arglist,false})\";" - Out.print "#{m.rettype} foo;" if m.rettype!="void" - Out.print "if (argc<#{m.minargs}" - Out.print "||argc>#{m.maxargs}" if m.maxargs!=-1 - Out.print ") RAISE(\"got %d args instead of %d..%d in %s\",argc,#{m.minargs},#{m.maxargs},methodspec);" - Out.print "foo = " if m.rettype!="void" - Out.print " self->#{m.selector}(argc,argv" - m.arglist.each_with_index{|arg,i| - if arg.default then - Out.print ",argc<#{i+1}?#{arg.default}:convert(argv[#{i}],(#{arg.type}*)0)" - else - Out.print ",convert(argv[#{i}],(#{arg.type}*)0)" - end - } - Out.print ");} #{m.rettype} #{classname}::#{m.selector}(VA" - #puts "m=#{m} n=#{n}" - Out.print ","+unparse_arglist(n.arglist,false) if m.arglist.length>0 - Out.print ")#{term} " - qlass.methods[m.selector].done=true -end - -def handle_constructor(line) - frame = $stack[-1] - raise "missing \\class #{where}" if not frame or not ClassDecl===frame - m = parse_methoddecl("void constructor"+line,"(.*)$") - Out.print "#{frame.name}(BFObject *bself, MESSAGE) : #{frame.supername}(bself,MESSAGE2) {" - Out.print "static const char *methodspec = \"#{frame.name}::#{m.selector}(#{unparse_arglist m.arglist,false})\";" - - Out.print "if (argc<#{m.minargs}" - Out.print "||argc>#{m.maxargs}" if m.maxargs!=-1 - Out.print ") RAISE(\"got %d args instead of %d..%d in %s\",argc,#{m.minargs},#{m.maxargs},methodspec);" - Out.print "#{m.selector}(sel,argc,argv" - m.arglist.each_with_index{|arg,i| - if arg.default then - Out.print ",argc<#{i+1}?#{arg.default}:convert(argv[#{i}],(#{arg.type}*)0)" - else - Out.print ",convert(argv[#{i}],(#{arg.type}*)0)" - end - } - Out.print ");}" - Out.print "#{m.rettype} #{m.selector}(MESSAGE" - Out.print ", #{unparse_arglist m.arglist}" if m.arglist.length>0 - Out.print ") "+line[/\{.*/] -end - -def handle_classinfo(line) - frame = $stack[-1] - cl = frame.name - line="{}" if /^\s*$/ =~ line - Out.print "static void #{cl}_startup (FClass *fclass);" - Out.print "static FObject *#{cl}_allocator (BFObject *bself, MESSAGE) {return new #{cl}(bself,sel,argc,argv);}" - Out.print "static MethodDecl #{cl}_methods[] = {" - Out.print frame.methods.map {|foo,method| "{ \"#{method.selector}\",(FMethod)#{frame.name}::#{method.selector}_wrap }" }.join(",") - Out.print "}; FClass ci#{cl} = {#{cl}_allocator,#{cl}_startup,#{cl.inspect},COUNT(#{cl}_methods),#{cl}_methods};" - get="void ___get(t_symbol *s=0) {t_atom a[1];" - frame.attrs.each {|name,attr| - virtual = if attr.virtual then "(0,0)" else "" end - get << "if (s==gensym(\"#{name}\")) set_atom(a,#{name}#{virtual}); else " - if frame.methods["_0_"+name].done then - #STDERR.puts "skipping already defined \\attr #{name}" - next - end - type,name,default = attr.to_a - handle_def "0 #{name} (#{type} #{name}) {this->#{name}=#{name}; changed(gensym(\"#{name}\"));}" - } - line.gsub!(/^\s*(\w+\s*)?\{/,"") - get << "RAISE(\"unknown attr %s\",s->s_name); outlet_anything(bself->outlets[bself->noutlets-1],s,1,a);}" - handle_def get if frame.attrs.size>0 - Out.print "void #{frame.name}_startup (FClass *fclass) {" - frame.attrs.each {|name,attr| Out.print "fclass->attrs[\"#{name}\"] = new AttrDecl(\"#{name}\",\"#{attr.type}\");" } - Out.print line.chomp -end - -def handle_grin(line) - fields = line.split(/\s+/) - i = fields[0].to_i - c = $stack[-1].name - frame = $stack[-1] - Out.print "template void grin_#{i}(GRIDHANDLER_ARGS(T));" - Out.print "template static void grinw_#{i} (GRIDHANDLER_ARGS(T));" - Out.print "static GridHandler grid_#{i}_hand;" - handle_decl "#{i} grid(GridOutlet *foo);" - handle_decl "#{i} list(...);" - handle_decl "#{i} float(float f);" - $stack[-1].grins[i] = fields.dup -end - -def handle_end(line) - frame = $stack.pop - fields = line.split(/\s+/) - n = fields.length - if not ClassDecl===frame then raise "\\end: frame is not a \\class" end - cl = frame.name - if fields[0]!="class" or (n>1 and not /^\{/ =~ fields[1] and fields[1]!=cl) then raise "end not matching #{where}" end - $stack.push frame - frame.grins.each {|i,v| - cli = "#{cl}::grinw_#{i}" - k = case v[1] - when nil ; [1,1,1,1,1,1] - when 'int32'; [0,0,1,0,0,0] - when 'int' ; [1,1,1,1,0,0] - when 'float' ; [0,0,0,0,1,1] - when 'float32'; [0,0,0,0,1,0] - when 'float64'; [0,0,0,0,0,1] - else raise 'BORK BORK BORK' end - ks = k.map{|ke| if ke==0 then 0 else cli end}.join(",") - Out.print "static GridHandler #{cl}_grid_#{i}_hand = GRIN(#{ks});" - handle_def "#{i} grid(GridOutlet *foo) {CHECK_GRIN(#{cl},#{i});"+ - "in[#{i}]->begin(foo);}" - handle_def "#{i} list(...) {CHECK_GRIN(#{cl},#{i});"+ - "in[#{i}]->from_list(argc,argv,int32_e);}" if not frame.methods["_#{i}_list"].done - handle_def "#{i} float(float f) {CHECK_GRIN(#{cl},#{i});"+ - "t_atom2 a[1]; SETFLOAT(a,f);"+ - "in[#{i}]->from_atom(1,a);}" if not frame.methods["_#{i}_float"].done - } - if /^class\s*(\w+\s+)?\{(.*)/ =~ line then handle_classinfo("{"+$2) end - $stack.pop - Out.print "\n#undef THISCLASS\n\# #{$linenumber}\n" -end - -def handle_startall(line) - $classes.each {|q| - Out.print "fclass_install(&ci#{q.name}," - if q.supername then Out.print "&ci#{q.supername}" else Out.print "0" end - Out.print ",sizeof(#{q.name}));" - } -end - -$linenumber=1 -loop{ - x = In.gets - break if not x - if /^\s*\\(\w+)\s*(.*)$/.match x then - begin - send("handle_#{$1}",$2) - Out.puts "//FCS" - rescue StandardError => e - STDERR.puts e.inspect, "at line #{$linenumber}", e.backtrace - File.unlink ARGV[1] - exit 1 - end - else Out.puts x end - $linenumber+=1 -} - -exit $exit diff --git a/externals/gridflow/src/videodev.cxx b/externals/gridflow/src/videodev.cxx deleted file mode 100644 index d908cecf..00000000 --- a/externals/gridflow/src/videodev.cxx +++ /dev/null @@ -1,793 +0,0 @@ -/* - $Id: videodev.c 4620 2009-11-01 21:16:58Z matju $ - - GridFlow - Copyright (c) 2001-2009 by Mathieu Bouchard - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - See file ../COPYING for further informations on licensing terms. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -/* bt878 on matju's comp supports only palette 4 */ -/* bt878 on heri's comp supports palettes 3, 6, 7, 8, 9, 13 */ -/* pwc supports palettes 12 and 15 */ - -#include "gridflow.hxx.fcs" -#include -#include -#include -#include -#include -#include -#include -#include -#include "pwc-ioctl.h" - -//#define error post -static bool debug=0; - -/* **************************************************************** */ - -typedef video_capability VideoCapability; -typedef video_channel VideoChannel ; -typedef video_tuner VideoTuner ; -typedef video_window VideoWindow ; -typedef video_picture VideoPicture ; -typedef video_mbuf VideoMbuf ; -typedef video_mmap VideoMmap ; - -#define FLAG(_num_,_name_,_desc_) #_name_, -#define OPT(_num_,_name_,_desc_) #_name_, - -/* -static const char *video_type_flags[] = { - FLAG( 0,CAPTURE, "Can capture") - FLAG( 1,TUNER, "Can tune") - FLAG( 2,TELETEXT, "Does teletext") - FLAG( 3,OVERLAY, "Overlay onto frame buffer") - FLAG( 4,CHROMAKEY, "Overlay by chromakey") - FLAG( 5,CLIPPING, "Can clip") - FLAG( 6,FRAMERAM, "Uses the frame buffer memory") - FLAG( 7,SCALES, "Scalable") - FLAG( 8,MONOCHROME, "Monochrome only") - FLAG( 9,SUBCAPTURE, "Can capture subareas of the image") - FLAG(10,MPEG_DECODER, "Can decode MPEG streams") - FLAG(11,MPEG_ENCODER, "Can encode MPEG streams") - FLAG(12,MJPEG_DECODER, "Can decode MJPEG streams") - FLAG(13,MJPEG_ENCODER, "Can encode MJPEG streams") -}; -*/ - -static const char *tuner_flags[] = { - FLAG(0,PAL, "") - FLAG(1,NTSC, "") - FLAG(2,SECAM, "") - FLAG(3,LOW, "Uses KHz not MHz") - FLAG(4,NORM, "Tuner can set norm") - FLAG(5,DUMMY5, "") - FLAG(6,DUMMY6, "") - FLAG(7,STEREO_ON,"Tuner is seeing stereo") - FLAG(8,RDS_ON, "Tuner is seeing an RDS datastream") - FLAG(9,MBS_ON, "Tuner is seeing an MBS datastream") -}; - -static const char *channel_flags[] = { - FLAG(0,TUNER,"") - FLAG(1,AUDIO,"") - FLAG(2,NORM ,"") -}; - -static const char *video_palette_choice[] = { - OPT( 0,NIL, "(nil)") - OPT( 1,GREY, "Linear greyscale") - OPT( 2,HI240, "High 240 cube (BT848)") - OPT( 3,RGB565, "565 16 bit RGB") - OPT( 4,RGB24, "24bit RGB") - OPT( 5,RGB32, "32bit RGB") - OPT( 6,RGB555, "555 15bit RGB") - OPT( 7,YUV422, "YUV422 capture") - OPT( 8,YUYV, "") - OPT( 9,UYVY, "The great thing about standards is ...") - OPT(10,YUV420, "") - OPT(11,YUV411, "YUV411 capture") - OPT(12,RAW, "RAW capture (BT848)") - OPT(13,YUV422P, "YUV 4:2:2 Planar") - OPT(14,YUV411P, "YUV 4:1:1 Planar") - OPT(15,YUV420P, "YUV 4:2:0 Planar") - OPT(16,YUV410P, "YUV 4:1:0 Planar") -}; - -static const char *video_mode_choice[] = { - OPT( 0,PAL, "pal") - OPT( 1,NTSC, "ntsc") - OPT( 2,SECAM,"secam") - OPT( 3,AUTO, "auto") -}; - -#define WH(_field_,_spec_) \ - sprintf(buf+strlen(buf), "%s=" _spec_ " ", #_field_, self->_field_); -#define WHYX(_name_,_fieldy_,_fieldx_) \ - sprintf(buf+strlen(buf), "%s=(%d %d) ", #_name_, self->_fieldy_, self->_fieldx_); -#define WHFLAGS(_field_,_table_) { \ - char *foo; \ - sprintf(buf+strlen(buf), "%s:%s ", #_field_, \ - foo=flags_to_s(self->_field_,COUNT(_table_),_table_)); \ - free(foo);} -#define WHCHOICE(_field_,_table_) { \ - char *foo; \ - sprintf(buf+strlen(buf), "%s=%s; ", #_field_, \ - foo=choice_to_s(self->_field_,COUNT(_table_),_table_));\ - free(foo);} - -static char *flags_to_s(int value, int n, const char **table) { - char foo[256]; - *foo = 0; - for(int i=0; i= n) { - char foo[64]; - sprintf(foo,"(Unknown #%d)",value); - return strdup(foo); - } else { - return strdup(table[value]); - } -} -static void gfpost(VideoChannel *self) { - char buf[256] = "[VideoChannel] "; - WH(channel,"%d"); - WH(name,"\"%.32s\""); - WH(tuners,"%d"); - WHFLAGS(flags,channel_flags); - WH(type,"0x%04x"); - WH(norm,"%d"); - post("%s",buf); -} -static void gfpost(VideoTuner *self) { - char buf[256] = "[VideoTuner] "; - WH(tuner,"%d"); - WH(name,"\"%.32s\""); - WH(rangelow,"%lu"); - WH(rangehigh,"%lu"); - WHFLAGS(flags,tuner_flags); - WHCHOICE(mode,video_mode_choice); - WH(signal,"%d"); - post("%s",buf); -} -static void gfpost(VideoWindow *self) { - char buf[256] = "[VideoWindow] "; - WHYX(pos,y,x); - WHYX(size,height,width); - WH(chromakey,"0x%08x"); - WH(flags,"0x%08x"); - WH(clipcount,"%d"); - post("%s",buf); -} -static void gfpost(VideoMbuf *self) { - char buf[256] = "[VideoMBuf] "; - WH(size,"%d"); - WH(frames,"%d"); - sprintf(buf+strlen(buf), "offsets=["); - for (int i=0; iframes; i++) { - /* WH(offsets[i],"%d"); */ - sprintf(buf+strlen(buf), "%d%s", self->offsets[i], - i+1==self->frames?"]":", "); - } - post("%s",buf); -} -static void gfpost(VideoMmap *self) { - char buf[256] = "[VideoMMap] "; - WH(frame,"%u"); - WHYX(size,height,width); - WHCHOICE(format,video_palette_choice); - post("%s",buf); -}; - -/* **************************************************************** */ - -\class FormatVideoDev : Format { - VideoCapability vcaps; - VideoPicture vp; - VideoMbuf vmbuf; - VideoMmap vmmap; - uint8 *image; - int queue[8], queuesize, queuemax, next_frame; - int current_channel, current_tuner; - bool use_mmap, use_pwc; - P bit_packing; - P dim; - bool has_frequency, has_tuner, has_norm; - int fd; - int palettes; /* bitfield */ - - \constructor (string mode, string filename) { - queuesize=0; queuemax=2; next_frame=0; use_mmap=true; use_pwc=false; bit_packing=0; dim=0; - has_frequency=false; - has_tuner=false; - has_norm=false; - image=0; - f = fopen(filename.data(),"r+"); - if (!f) RAISE("can't open device '%s': %s",filename.data(),strerror(errno)); - fd = fileno(f); - initialize2(); - } - void frame_finished (uint8 *buf); - - void alloc_image (); - void dealloc_image (); - void frame_ask (); - void initialize2 (); - ~FormatVideoDev () {if (image) dealloc_image();} - - \decl 0 bang (); - \grin 0 int - - \attr int channel(); - \attr int tuner(); - \attr int norm(); - \decl 0 size (int sy, int sx); - \decl 0 transfer (string sym, int queuemax=2); - - \attr t_symbol *colorspace; - \attr int32 frequency(); - \attr uint16 brightness(); - \attr uint16 hue(); - \attr uint16 colour(); - \attr uint16 contrast(); - \attr uint16 whiteness(); - - \attr bool pwc(); /* 0..1 */ - \attr uint16 framerate(); - \attr uint16 white_mode(); /* 0..1 */ - \attr uint16 white_red(); - \attr uint16 white_blue(); - \attr uint16 white_speed(); - \attr uint16 white_delay(); - \attr int auto_gain(); - \attr int noise_reduction(); /* 0..3 */ - \attr int compression(); /* 0..3 */ - \attr t_symbol *name; - - \decl 0 get (t_symbol *s=0); -}; - -#define DEBUG(args...) 42 -//#define DEBUG(args...) post(args) - -#define IOCTL( F,NAME,ARG) \ - (DEBUG("fd%d.ioctl(0x%08x,0x%08x)",F,NAME,ARG), ioctl(F,NAME,ARG)) -#define WIOCTL( F,NAME,ARG) \ - (IOCTL(F,NAME,ARG)<0 && (error("ioctl %s: %s",#NAME,strerror(errno)),1)) -#define WIOCTL2(F,NAME,ARG) \ - (IOCTL(F,NAME,ARG)<0 && (error("ioctl %s: %s",#NAME,strerror(errno)), RAISE("ioctl error"), 0)) - -\def 0 get (t_symbol *s=0) { - // this is abnormal for a get-function - if (s==gensym("frequency") && !has_frequency ) return; - if (s==gensym("tuner") && !has_tuner ) return; - if (s==gensym("norm") && !has_norm ) return; - if (s==gensym("channel") && vcaps.channels<2) return; - if (!use_pwc && (s==gensym("white_mode") || s==gensym("white_red") || s==gensym("white_blue") || - s==gensym("white_speed") || s==gensym("white_delay") || s==gensym("auto_gain") || - s==gensym("noise_reduction") || s==gensym("compression") || s==gensym("framerate"))) return; - FObject::_0_get(argc,argv,s); - if (!s) { - t_atom a[2]; - SETFLOAT(a+0,vcaps.minheight); - SETFLOAT(a+1,vcaps.minwidth); - outlet_anything(bself->outlets[0],gensym("minsize"),2,a); - SETFLOAT(a+0,vcaps.maxheight); - SETFLOAT(a+1,vcaps.maxwidth); - outlet_anything(bself->outlets[0],gensym("maxsize"),2,a); - char *foo = choice_to_s(vp.palette,COUNT(video_palette_choice),video_palette_choice); - SETSYMBOL(a,gensym(foo)); - free(foo); - outlet_anything(bself->outlets[0],gensym("palette"),1,a); - SETSYMBOL(a,use_mmap ? gensym("mmap") : gensym("read")); - outlet_anything(bself->outlets[0],gensym("transfer"),1,a); - SETFLOAT(a+0,dim->v[0]); - SETFLOAT(a+1,dim->v[1]); - outlet_anything(bself->outlets[0],gensym("size"),2,a); // abnormal (does not use nested list) - } -} - -\def 0 size (int sy, int sx) { - VideoWindow grab_win; - // !@#$ bug here: won't flush the frame queue - dim = new Dim(sy,sx,3); - WIOCTL(fd, VIDIOCGWIN, &grab_win); - if (debug) gfpost(&grab_win); - grab_win.clipcount = 0; - grab_win.flags = 0; - if (sy && sx) { - grab_win.height = sy; - grab_win.width = sx; - } - if (debug) gfpost(&grab_win); - WIOCTL(fd, VIDIOCSWIN, &grab_win); - WIOCTL(fd, VIDIOCGWIN, &grab_win); - if (debug) gfpost(&grab_win); -} - -void FormatVideoDev::dealloc_image () { - if (!image) return; - if (use_mmap) { - munmap(image, vmbuf.size); - image=0; - } else { - delete[] (uint8 *)image; - } -} - -void FormatVideoDev::alloc_image () { - if (use_mmap) { - WIOCTL2(fd, VIDIOCGMBUF, &vmbuf); - //gfpost(&vmbuf); - //size_t size = vmbuf.frames > 4 ? vmbuf.offsets[4] : vmbuf.size; - image = (uint8 *)mmap(0,vmbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); - if (((long)image)==-1) {image=0; RAISE("mmap: %s", strerror(errno));} - } else { - image = new uint8[dim->prod(0,1)*bit_packing->bytes]; - } -} - -void FormatVideoDev::frame_ask () { - if (queuesize>=queuemax) RAISE("queue is full (queuemax=%d)",queuemax); - if (queuesize>=vmbuf.frames) RAISE("queue is full (vmbuf.frames=%d)",vmbuf.frames); - vmmap.frame = queue[queuesize++] = next_frame; - vmmap.format = vp.palette; - vmmap.width = dim->get(1); - vmmap.height = dim->get(0); - WIOCTL2(fd, VIDIOCMCAPTURE, &vmmap); - //gfpost(&vmmap); - next_frame = (next_frame+1) % vmbuf.frames; -} - -static uint8 clip(int x) {return x<0?0 : x>255?255 : x;} - -void FormatVideoDev::frame_finished (uint8 *buf) { - string cs = colorspace->s_name; - int downscale = cs=="magic"; - /* picture is converted here. */ - int sy = dim->get(0)>>downscale; - int sx = dim->get(1)>>downscale; - int bs = dim->prod(1)>>downscale; - uint8 b2[bs]; - //post("sy=%d sx=%d bs=%d",sy,sx,bs); - //post("frame_finished, vp.palette = %d; colorspace = %s",vp.palette,cs.data()); - if (vp.palette==VIDEO_PALETTE_YUV420P) { - GridOutlet out(this,0,cs=="magic"?new Dim(sy,sx,3):(Dim *)dim,cast); - if (cs=="y") { - out.send(sy*sx,buf); - } else if (cs=="rgb") { - for(int y=0; y>8); - b2[xx+1]=clip((298*Y1 - 100*U - 208*V)>>8); - b2[xx+2]=clip((298*Y1 + 516*U )>>8); - b2[xx+3]=clip((298*Y2 + 409*V)>>8); - b2[xx+4]=clip((298*Y2 - 100*U - 208*V)>>8); - b2[xx+5]=clip((298*Y2 + 516*U )>>8); - } - out.send(bs,b2); - } - } else if (cs=="yuv") { - for(int y=0; y>8); - b2[xx+1]=clip(128+(((U-128)*293)>>8)); - b2[xx+2]=clip(128+(((V-128)*293)>>8)); - b2[xx+3]=clip(((bufy[x+1]-16)*298)>>8); - b2[xx+4]=clip(128+(((U-128)*293)>>8)); - b2[xx+5]=clip(128+(((V-128)*293)>>8)); - } - out.send(bs,b2); - } - } else if (cs=="magic") { - for(int y=0; yunpack(sx,buf+y*sx*bit_packing->bytes,rgb); - for (int x=0,xx=0; x>8; - b2[x+1] = (76*rgb[xx+3]+150*rgb[xx+4]+29*rgb[xx+5])>>8; - } - out.send(bs,b2); - } - } else if (cs=="rgb") { - for(int y=0; yunpack(sx,buf+y*sx*bit_packing->bytes,rgb); - out.send(bs,rgb); - } - } else if (cs=="yuv") { - for(int y=0; yunpack(sx,buf+y*sx*bit_packing->bytes,rgb); - for (int x=0,xx=0; x>8)); - b2[xx+1] = clip(128+((- 44*rgb[xx+0] - 85*rgb[xx+1] + 108*rgb[xx+2])>>8)); - b2[xx+2] = clip(128+(( 128*rgb[xx+0] - 108*rgb[xx+1] - 21*rgb[xx+2])>>8)); - b2[xx+3] = clip( (( 76*rgb[xx+3] + 150*rgb[xx+4] + 29*rgb[xx+5])>>8)); - b2[xx+4] = clip(128+((- 44*rgb[xx+3] - 85*rgb[xx+4] + 108*rgb[xx+5])>>8)); - b2[xx+5] = clip(128+(( 128*rgb[xx+3] - 108*rgb[xx+4] - 21*rgb[xx+5])>>8)); - } - out.send(bs,b2); - } - } else if (cs=="magic") { - RAISE("magic colorspace not supported with a RGB palette"); - } - } else { - RAISE("unsupported palette %d",vp.palette); - } -} - -/* these are factors for RGB to analog YUV */ -// Y = 66*R + 129*G + 25*B -// U = - 38*R - 74*G + 112*B -// V = 112*R - 94*G - 18*B - -// strange that read2 is not used and read3 is used instead -static int read2(int fd, uint8 *image, int n) { - int r=0; - while (n>0) { - int rr=read(fd,image,n); - if (rr<0) return rr; else {r+=rr; image+=rr; n-=rr;} - } - return r; -} - -static int read3(int fd, uint8 *image, int n) { - int r=read(fd,image,n); - if (r<0) return r; - return n; -} - -\def 0 bang () { - if (!image) alloc_image(); - if (!use_mmap) { - /* picture is read at once by frame() to facilitate debugging. */ - int tot = dim->prod(0,1) * bit_packing->bytes; - int n = (int) read3(fd,image,tot); - if (n==tot) frame_finished(image); - if (0> n) RAISE("error reading: %s", strerror(errno)); - if (n < tot) RAISE("unexpectedly short picture: %d of %d",n,tot); - return; - } - while(queuesize 100) gfpost("VIDIOCSYNC delay: %d us",t1-t0); - frame_finished(image+vmbuf.offsets[queue[0]]); - queuesize--; - for (int i=0; i3) RAISE("norm must be in range 0..3"); - if (0> IOCTL(fd, VIDIOCGTUNER, &vtuner)) { - post("no tuner #%d", value); - } else { - vtuner.mode = value; - gfpost(&vtuner); - WIOCTL(fd, VIDIOCSTUNER, &vtuner); - } -} - -\def int norm () { - VideoTuner vtuner; - vtuner.tuner = current_tuner; - if (0> IOCTL(fd, VIDIOCGTUNER, &vtuner)) {post("no tuner #%d", current_tuner); return -1;} - return vtuner.mode; -} - -\def 0 tuner (int value) { - VideoTuner vtuner; - vtuner.tuner = current_tuner = value; - if (0> IOCTL(fd, VIDIOCGTUNER, &vtuner)) RAISE("no tuner #%d", value); - vtuner.mode = VIDEO_MODE_NTSC; //??? - gfpost(&vtuner); - WIOCTL(fd, VIDIOCSTUNER, &vtuner); - has_norm = (vtuner.mode<=3); - int meuh; - has_frequency = (ioctl(fd, VIDIOCGFREQ, &meuh)>=0); -} -\def int tuner () {return current_tuner;} - -#define warn(fmt,stuff...) post("warning: " fmt,stuff) - -\def 0 channel (int value) { - VideoChannel vchan; - vchan.channel = value; - current_channel = value; - if (0> IOCTL(fd, VIDIOCGCHAN, &vchan)) warn("no channel #%d", value); - //gfpost(&vchan); - WIOCTL(fd, VIDIOCSCHAN, &vchan); - if (vcaps.type & VID_TYPE_TUNER) _0_tuner(0,0,0); - has_tuner = (vcaps.type & VID_TYPE_TUNER && vchan.tuners > 1); -} -\def int channel () {return current_channel;} - -\def 0 transfer (string sym, int queuemax=2) { - if (sym=="read") { - dealloc_image(); - use_mmap = false; - post("transfer read"); - } else if (sym=="mmap") { - dealloc_image(); - use_mmap = true; - alloc_image(); - queuemax=min(8,min(queuemax,vmbuf.frames)); - post("transfer mmap with queuemax=%d (max max is vmbuf.frames=%d)", queuemax,vmbuf.frames); - this->queuemax=queuemax; - } else RAISE("don't know that transfer mode"); -} - -#define PICTURE_ATTR(_name_) {\ - WIOCTL(fd, VIDIOCGPICT, &vp); \ - vp._name_ = _name_; \ - WIOCTL(fd, VIDIOCSPICT, &vp);} - -#define PICTURE_ATTRGET(_name_) { \ - WIOCTL(fd, VIDIOCGPICT, &vp); \ - /*gfpost("getting %s=%d",#_name_,vp._name_);*/ \ - return vp._name_;} - -\def uint16 brightness () {PICTURE_ATTRGET(brightness)} -\def 0 brightness (uint16 brightness){PICTURE_ATTR( brightness)} -\def uint16 hue () {PICTURE_ATTRGET(hue)} -\def 0 hue (uint16 hue) {PICTURE_ATTR( hue)} -\def uint16 colour () {PICTURE_ATTRGET(colour)} -\def 0 colour (uint16 colour) {PICTURE_ATTR( colour)} -\def uint16 contrast () {PICTURE_ATTRGET(contrast)} -\def 0 contrast (uint16 contrast) {PICTURE_ATTR( contrast)} -\def uint16 whiteness () {PICTURE_ATTRGET(whiteness)} -\def 0 whiteness (uint16 whiteness) {PICTURE_ATTR( whiteness)} -\def int32 frequency () { - int32 value; - //if (ioctl(fd, VIDIOCGFREQ, &value)<0) {has_frequency=false; return 0;} - WIOCTL(fd, VIDIOCGFREQ, &value); - return value; -} -\def 0 frequency (int32 frequency) { - long frequency_ = frequency; - WIOCTL(fd, VIDIOCSFREQ, &frequency_); -} - -\def 0 colorspace (t_symbol *colorspace) { /* y yuv rgb magic */ - string c = colorspace->s_name; - if (c=="y") {} - else if (c=="yuv") {} - else if (c=="rgb") {} - else if (c=="magic") {} - else RAISE("got '%s' but supported colorspaces are: y yuv rgb magic",c.data()); - WIOCTL(fd, VIDIOCGPICT, &vp); - int palette = (palettes&(1<colorspace=gensym(c.data()); - dim = new Dim(dim->v[0],dim->v[1],c=="y"?1:3); -} - -\def bool pwc () {return use_pwc;} -\def 0 pwc (bool pwc) {use_pwc=pwc;} - -void set_pan_and_tilt(int fd, char what, int pan, int tilt) { /*unused*/ - // if (!use_pwc) return; - struct pwc_mpt_angles pma; - pma.absolute=1; - WIOCTL(fd, VIDIOCPWCMPTGANGLE, &pma); - pma.pan = pan; - pma.tilt = tilt; - WIOCTL(fd, VIDIOCPWCMPTSANGLE, &pma); -} - -\def uint16 framerate() { - if (!use_pwc) return 0; - struct video_window vwin; - WIOCTL(fd, VIDIOCGWIN, &vwin); - return (vwin.flags & PWC_FPS_MASK) >> PWC_FPS_SHIFT; -} - -\def 0 framerate(uint16 framerate) { - if (!use_pwc) return; - struct video_window vwin; - WIOCTL(fd, VIDIOCGWIN, &vwin); - vwin.flags &= ~PWC_FPS_FRMASK; - vwin.flags |= (framerate << PWC_FPS_SHIFT) & PWC_FPS_FRMASK; - WIOCTL(fd, VIDIOCSWIN, &vwin); -} - -/* those functions are still mostly unused */ -//void set_compression_preference(int fd, int pref) {if (use_pwc) WIOCTL(fd, VIDIOCPWCSCQUAL, &pref);} - -\def int auto_gain() {int auto_gain=0; if (use_pwc) WIOCTL(fd, VIDIOCPWCGAGC, &auto_gain); return auto_gain;} -\def 0 auto_gain (int auto_gain) {if (use_pwc) WIOCTL(fd, VIDIOCPWCSAGC, &auto_gain);} - -//void set_shutter_speed(int fd, int pref) {if (use_pwc) WIOCTL(fd, VIDIOCPWCSSHUTTER, &pref);} - -\def uint16 white_mode () { - if (!use_pwc) return 0; - struct pwc_whitebalance pwcwb; - WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); - if (pwcwb.mode==PWC_WB_AUTO) return 0; - if (pwcwb.mode==PWC_WB_MANUAL) return 1; - return 2; -} - -\def 0 white_mode (uint16 white_mode) { - if (!use_pwc) return; - struct pwc_whitebalance pwcwb; - WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); - if (white_mode==0) pwcwb.mode = PWC_WB_AUTO; - else if (white_mode==1) pwcwb.mode = PWC_WB_MANUAL; - /*else if (strcasecmp(mode, "indoor") == 0) pwcwb.mode = PWC_WB_INDOOR;*/ - /*else if (strcasecmp(mode, "outdoor") == 0) pwcwb.mode = PWC_WB_OUTDOOR;*/ - /*else if (strcasecmp(mode, "fl") == 0) pwcwb.mode = PWC_WB_FL;*/ - else {error("unknown mode number %d", white_mode); return;} - WIOCTL(fd, VIDIOCPWCSAWB, &pwcwb);} - -\def uint16 white_red() {if (!use_pwc) return 0; - struct pwc_whitebalance pwcwb; WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); return pwcwb.manual_red;} -\def uint16 white_blue() {if (!use_pwc) return 0; - struct pwc_whitebalance pwcwb; WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); return pwcwb.manual_blue;} -\def 0 white_red(uint16 white_red) {if (!use_pwc) return; - struct pwc_whitebalance pwcwb; WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); - pwcwb.manual_red = white_red; WIOCTL(fd, VIDIOCPWCSAWB, &pwcwb);} -\def 0 white_blue(uint16 white_blue) {if (!use_pwc) return; - struct pwc_whitebalance pwcwb; WIOCTL(fd, VIDIOCPWCGAWB, &pwcwb); - pwcwb.manual_blue = white_blue;WIOCTL(fd, VIDIOCPWCSAWB, &pwcwb);} - -\def uint16 white_speed() {if (!use_pwc) return 0; - struct pwc_wb_speed pwcwbs; WIOCTL(fd, VIDIOCPWCGAWBSPEED, &pwcwbs); return pwcwbs.control_speed;} -\def uint16 white_delay() {if (!use_pwc) return 0; - struct pwc_wb_speed pwcwbs; WIOCTL(fd, VIDIOCPWCGAWBSPEED, &pwcwbs); return pwcwbs.control_delay;} -\def 0 white_speed(uint16 white_speed) {if (!use_pwc) return; - struct pwc_wb_speed pwcwbs; WIOCTL(fd, VIDIOCPWCGAWBSPEED, &pwcwbs); - pwcwbs.control_speed = white_speed; WIOCTL(fd, VIDIOCPWCSAWBSPEED, &pwcwbs);} -\def 0 white_delay(uint16 white_delay) {if (!use_pwc) return; - struct pwc_wb_speed pwcwbs; WIOCTL(fd, VIDIOCPWCGAWBSPEED, &pwcwbs); - pwcwbs.control_delay = white_delay; WIOCTL(fd, VIDIOCPWCSAWBSPEED, &pwcwbs);} - -void set_led_on_time(int fd, int val) { - struct pwc_leds pwcl; WIOCTL(fd, VIDIOCPWCGLED, &pwcl); - pwcl.led_on = val; WIOCTL(fd, VIDIOCPWCSLED, &pwcl);} -void set_led_off_time(int fd, int val) { - struct pwc_leds pwcl; WIOCTL(fd, VIDIOCPWCGLED, &pwcl); - pwcl.led_off = val; WIOCTL(fd, VIDIOCPWCSLED, &pwcl);} -void set_sharpness(int fd, int val) {WIOCTL(fd, VIDIOCPWCSCONTOUR, &val);} -void set_backlight_compensation(int fd, int val) {WIOCTL(fd, VIDIOCPWCSBACKLIGHT, &val);} -void set_antiflicker_mode(int fd, int val) {WIOCTL(fd, VIDIOCPWCSFLICKER, &val);} - -\def int noise_reduction() { - if (!use_pwc) return 0; - int noise_reduction; - WIOCTL(fd, VIDIOCPWCGDYNNOISE, &noise_reduction); - return noise_reduction; -} -\def 0 noise_reduction(int noise_reduction) { - if (!use_pwc) return; - WIOCTL(fd, VIDIOCPWCSDYNNOISE, &noise_reduction); -} -\def int compression() { - if (!use_pwc) return 0; - int compression; - WIOCTL(fd, VIDIOCPWCSCQUAL, &compression); - return compression; -} -\def 0 compression(int compression) { - if (!use_pwc) return; - WIOCTL(fd, VIDIOCPWCGCQUAL, &compression); -} - -void FormatVideoDev::initialize2 () { - WIOCTL(fd, VIDIOCGCAP, &vcaps); - _0_size(0,0,vcaps.maxheight,vcaps.maxwidth); - char namebuf[33]; - memcpy(namebuf,vcaps.name,sizeof(vcaps.name)); - int i; - for (i=32; i>=1; i--) if (!namebuf[i] || !isspace(namebuf[i])) break; - namebuf[i]=0; - while (--i>=0) if (isspace(namebuf[i])) namebuf[i]='_'; - name = gensym(namebuf); - WIOCTL(fd, VIDIOCGPICT,&vp); - palettes=0; - int checklist[] = {VIDEO_PALETTE_RGB565,VIDEO_PALETTE_RGB24,VIDEO_PALETTE_RGB32,VIDEO_PALETTE_YUV420P}; -#if 1 - for (size_t i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#ifdef HAVE_X11_SHARED_MEMORY -#include -#include -#include -#endif -#ifdef HAVE_X11_XVIDEO -#include -#include -#endif - -/* X11 Error Handler type */ -typedef int (*XEH)(Display *, XErrorEvent *); - -struct FormatX11; -void FormatX11_call(FormatX11 *p); - -\class FormatX11 : Format { -/* at the Display/Screen level */ - Display *display; /* connection to xserver */ - Visual *visual; /* screen properties */ - Window root_window; - Colormap colormap;/* for 256-color mode */ - short depth; - bool use_stripes; /* use alternate conversion in 256-color mode */ - bool shared_memory; - bool xvideo; -/* at the Window level */ - Window window; /* X11 window number */ - Window parent; /* X11 window number of the parent */ - GC imagegc; /* X11 graphics context (like java.awt.Graphics) */ - XImage *ximage; /* X11 image descriptor */ - uint8 *image; /* the real data (that XImage binds to) */ - bool is_owner; - int32 pos[2]; - P bit_packing; - P dim; - bool lock_size; - bool override_redirect; - t_clock *clock; - std::string title; -#ifdef HAVE_X11_SHARED_MEMORY - XShmSegmentInfo *shm_info; /* to share memory with X11/Unix */ -#endif -#ifdef HAVE_X11_XVIDEO - int xv_format; - int xv_port; - XvImage *xvi; /* ils sont fous ces romains */ - unsigned char *data; - int last_encoding; -#endif - ~FormatX11 () { - clock_unset(clock); - if (is_owner) XDestroyWindow(display,window); - XSync(display,0); - dealloc_image(); - if (imagegc) XFreeGC(display,imagegc); - XCloseDisplay(display); - } - template void frame_by_type (T bogus); - void show_section(int x, int y, int sx, int sy); - void set_wm_hints (); - void dealloc_image (); - bool alloc_image (int sx, int sy); - void resize_window (int sx, int sy); - void open_display(const char *disp_string); - void report_pointer(int y, int x, int state); - void prepare_colormap(); - Window search_window_tree (Window xid, Atom key, const char *value, int level=0); - \constructor (...) { - shared_memory=false; xvideo=false; use_stripes=false; window=0; ximage=0; image=0; is_owner=true; - dim=0; lock_size=false; override_redirect=false; clock=0; imagegc=0; -#ifdef HAVE_X11_SHARED_MEMORY - shm_info=0; -#endif - int sy=240, sx=320; // defaults - argv++, argc--; - t_symbol *domain = argc<1 ? gensym("here") : argv[0]; - int i; - char host[256]; - if (domain==gensym("here")) { - open_display(0); - i=1; - } else if (domain==gensym("local")) { - if (argc<2) RAISE("open x11 local: not enough args"); - sprintf(host,":%d",int32(argv[1])); - open_display(host); - i=2; - } else if (domain==gensym("remote")) { - if (argc<3) RAISE("open x11 remote: not enough args"); - sprintf(host,"%s:%d",string(argv[1]).data(),int32(argv[2])); - open_display(host); - i=3; - } else if (domain==gensym("display")) { - if (argc<2) RAISE("open x11 display: not enough args"); - strcpy(host,string(argv[1]).data()); - for (int k=0; host[k]; k++) if (host[k]=='%') host[k]==':'; - post("mode `display', DISPLAY=`%s'",host); - open_display(host); - i=2; - } else RAISE("x11 destination syntax error"); - for(;i=argc) { - } else { - const t_atom2 &winspec = argv[i]; - if (winspec==gensym("root")) { - window = root_window; - is_owner = false; - } else if (winspec==gensym("embed")) { - string title = argv[i+1]; - sy = sx = pos[0] = pos[1] = 0; - parent = search_window_tree(root_window,XInternAtom(display,"WM_NAME",0),title.data()); - if (parent == 0xDeadBeef) RAISE("Window not found."); - } else if (winspec==gensym("embed_by_id")) { - const char *winspec2 = string(argv[i+1]).data(); - if (strncmp(winspec2,"0x",2)==0) { - parent = strtol(winspec2+2,0,16); - } else { - parent = atoi(winspec2); - } - } else { - if (winspec.a_type==A_SYMBOL) { - const char *winspec2 = string(winspec).data(); - if (strncmp(winspec2,"0x",2)==0) { - window = strtol(winspec2+2,0,16); - } else { - window = atoi(winspec2); // huh? - } - } else { - window = INT(winspec); - } - is_owner = false; - sy = sx = pos[0] = pos[1] = 0; - } - } - resize_window(sx,sy); // "resize" also takes care of creation - if (is_owner) { - Atom wmDeleteAtom = XInternAtom(display, "WM_DELETE_WINDOW", False); - XSetWMProtocols(display,window,&wmDeleteAtom,1); - } - Visual *v = visual; - int disp_is_le = !ImageByteOrder(display); - int bpp = ximage->bits_per_pixel; - switch(visual->c_class) { - case TrueColor: case DirectColor: { - uint32 masks[3] = { v->red_mask, v->green_mask, v->blue_mask }; - bit_packing = new BitPacking(disp_is_le, bpp/8, 3, masks); - } break; - case PseudoColor: { - uint32 masks[3] = { 0x07, 0x38, 0xC0 }; // BBGGGRRR - bit_packing = new BitPacking(disp_is_le, bpp/8, 3, masks); - } break; - default: RAISE("huh?"); - } - clock = clock_new(this,(t_method)FormatX11_call); - clock_delay(clock,0); - show_section(0,0,sx,sy); - if ((mode&4)!=0) { - Window root; int x,y; unsigned sx,sy,sb,depth; - XGetGeometry(display,window,&root,&x,&y,&sx,&sy,&sb,&depth); - post("sx=%d sy=%d",sx,sy); - _0_out_size(argc,argv,sy,sx); - } - } - - \decl 0 bang (); - void call (); - \decl 0 out_size (int sy, int sx); - \decl 0 setcursor (int shape); - \decl 0 hidecursor (); - \decl 0 set_geometry (int y, int x, int sy, int sx); - \decl 0 move (int y, int x); - \decl 0 shared_memory (bool toggle); - \decl 0 xvideo (bool toggle); - \decl 0 title (string title=""); - \decl 0 warp (int y, int x); - \grin 0 int -}; - -/* ---------------------------------------------------------------- */ - -void FormatX11::show_section(int x, int y, int sx, int sy) { - if ((mode&2)==0) return; - int zy=dim->get(0), zx=dim->get(1); - if (y>zy||x>zx) return; - if (y+sy>zy) sy=zy-y; - if (x+sx>zx) sx=zx-x; -#ifndef HAVE_X11_XVIDEO - if (xvideo) RAISE("xvideo not available (recompile)"); -#endif -#ifndef HAVE_X11_SHARED_MEMORY - if (shared_memory) RAISE("xshm not available (recompile)"); -#endif - if (xvideo) { -#ifdef HAVE_X11_XVIDEO - if (shared_memory) { -#ifdef HAVE_X11_SHARED_MEMORY - -#endif // shm - } else { - XvPutImage(display,port,window,imagegc,ximage, - xvi, 0, 0, image_width, image_height, - drwX - (vo_panscan_x >> 1), drwY - (vo_panscan_y >> 1), - vo_dwidth + vo_panscan_x, - vo_dheight + vo_panscan_y); - - } -#endif // xvideo - } else { - if (shared_memory) { -#ifdef HAVE_X11_SHARED_MEMORY - XSync(display,False); - XShmPutImage(display,window,imagegc,ximage,x,y,x,y,sx,sy,False); - XFlush(display); - //XPutImage( display,window,imagegc,ximage,x,y,x,y,sx,sy); - // should completion events be waited for? looks like a bug -#endif // xshm - } else { - XPutImage(display,window,imagegc,ximage,x,y,x,y,sx,sy); - XFlush(display); - } - } -} - -/* window manager hints, defines the window as non-resizable */ -void FormatX11::set_wm_hints () { - if (!is_owner) return; - XWMHints wmh; - char buf[256],*bufp=buf; - if (title=="") { - sprintf(buf,"GridFlow (%d,%d,%d)",dim->get(0),dim->get(1),dim->get(2)); - } else { - sprintf(buf,"%.255s",title.data()); - } - XTextProperty wtitle; XStringListToTextProperty((char **)&bufp, 1, &wtitle); - XSizeHints sh; - sh.flags=PSize|PMaxSize|PMinSize; - sh.min_width = sh.max_width = sh.width = dim->get(1); - sh.min_height = sh.max_height = sh.height = dim->get(0); - wmh.input = True; - wmh.flags = InputHint; - XSetWMProperties(display,window,&wtitle,&wtitle,0,0,&sh,&wmh,0); - XFree(wtitle.value); // do i really have to do that? -} - -void FormatX11::report_pointer(int y, int x, int state) { - t_atom a[3]; - SETFLOAT(a+0,y); - SETFLOAT(a+1,x); - SETFLOAT(a+2,state); - outlet_anything(bself->outlets[0],gensym("position"),COUNT(a),a); -} - -void FormatX11::call() { - XEvent e; - for (;;) { - int xpending = XEventsQueued(display, QueuedAfterFlush); - if (!xpending) break; - XNextEvent(display,&e); - switch (e.type) { - case Expose:{ - XExposeEvent *ex = (XExposeEvent *)&e; - if (mode==2) show_section(ex->x,ex->y,ex->width,ex->height); - }break; - case ButtonPress:{ - XButtonEvent *eb = (XButtonEvent *)&e; - eb->state |= 128<button; - report_pointer(eb->y,eb->x,eb->state); - }break; - case ButtonRelease:{ - XButtonEvent *eb = (XButtonEvent *)&e; - eb->state &= ~(128<button); - report_pointer(eb->y,eb->x,eb->state); - }break; - case KeyPress: - case KeyRelease:{ - XKeyEvent *ek = (XKeyEvent *)&e; - //XLookupString(ek, buf, 63, 0, 0); - char *kss = XKeysymToString(XLookupKeysym(ek, 0)); - char buf[64]; - if (!kss) return; /* unknown keys ignored */ - if (isdigit(*kss)) sprintf(buf,"D%s",kss); else strcpy(buf,kss); - t_atom at[4]; - t_symbol *sel = gensym(const_cast(e.type==KeyPress ? "keypress" : "keyrelease")); - SETFLOAT(at+0,ek->y); - SETFLOAT(at+1,ek->x); - SETFLOAT(at+2,ek->state); - SETSYMBOL(at+3,gensym(buf)); - outlet_anything(bself->outlets[0],sel,4,at); - //XFree(kss); - }break; - case MotionNotify:{ - XMotionEvent *em = (XMotionEvent *)&e; - report_pointer(em->y,em->x,em->state); - }break; - case DestroyNotify:{ - post("This window is being closed, so this handler will close too!"); - delete this; /* really! what else could i do here anyway? */ - return; - }break; - case ConfigureNotify:break; // as if we cared - } - } - clock_delay(clock,20); -} -void FormatX11_call(FormatX11 *p) {p->call();} - -\def 0 bang () { - XGetSubImage(display, window, 0, 0, dim->get(1), dim->get(0), (unsigned)-1, ZPixmap, ximage, 0, 0); - GridOutlet out(this,0,dim,cast); - int sy=dim->get(0), sx=dim->get(1), bs=dim->prod(1); - uint8 b2[bs]; - for(int y=0; ybytes_per_line * y; - bit_packing->unpack(sx,b1,b2); - out.send(bs,b2); - } -} - -/* loathe Xlib's error handlers */ -static FormatX11 *current_x11; -static int FormatX11_error_handler (Display *d, XErrorEvent *xee) { - post("XErrorEvent: type=0x%08x display=0x%08x xid=0x%08x", - xee->type, xee->display, xee->resourceid); - post("... serial=0x%08x error=0x%08x request=0x%08lx minor=0x%08x", - xee->serial, xee->error_code, xee->request_code, xee->minor_code); - if (current_x11->shared_memory==1) { - post("(note: turning shm off)"); - current_x11->shared_memory = 0; - } - return 42; /* it seems that the return value is ignored. */ -} - -bool FormatX11::alloc_image (int sx, int sy) { - dim = new Dim(sy,sx,3); - dealloc_image(); - if (sx==0 || sy==0) return false; - current_x11 = this; - if (!shared_memory) { - ximage = XCreateImage(display,visual,depth,ZPixmap,0,0,sx,sy,8,0); - int size = ximage->bytes_per_line*ximage->height; - if (!ximage) RAISE("can't create image"); - image = new uint8[size]; - ximage->data = (int8 *)image; - } else { -#ifdef HAVE_X11_SHARED_MEMORY - shm_info = new XShmSegmentInfo; - ximage = XShmCreateImage(display,visual,depth,ZPixmap,0,shm_info,sx,sy); - if (!ximage) {post("x11: will retry without shared memory"); shared_memory=false;} - XSync(display,0); - if (!shared_memory) return alloc_image(sx,sy); - int size = ximage->bytes_per_line*ximage->height; - shm_info->shmid = shmget(IPC_PRIVATE,size,IPC_CREAT|0777); - if(shm_info->shmid < 0) RAISE("shmget() failed: %s",strerror(errno)); - ximage->data = shm_info->shmaddr = (char *)shmat(shm_info->shmid,0,0); - if ((long)(shm_info->shmaddr) == -1) RAISE("shmat() failed: %s",strerror(errno)); - image = (uint8 *)ximage->data; - shm_info->readOnly = False; - if (!XShmAttach(display, shm_info)) RAISE("ERROR: XShmAttach: big problem"); - XSync(display,0); // make sure the server picks it up - // yes, this can be done now. should cause auto-cleanup. - shmctl(shm_info->shmid,IPC_RMID,0); - if (!shared_memory) return alloc_image(sx,sy); -#endif - } -#ifdef HAVE_X11_XVIDEO - if (xvideo) { - unsigned int ver, rel, req, ev, err, i, j, adaptors, formats; - XvAdaptorInfo *ai; - if (Success != XvQueryExtension(display,&ver,&rel,&req,&ev,&err)) RAISE("XvQueryExtension problem"); - /* find + lock port */ - if (Success != XvQueryAdaptors(display,DefaultRootWindow(display),&adaptors,&ai)) RAISE("XvQueryAdaptors problem"); - for (i = 0; i < adaptors; i++) { - if (ai[i].type&XvInputMask && ai[i].type&XvImageMask) { - for (j=0; jdata); - XShmDetach(display,shm_info); - if (shm_info) {delete shm_info; shm_info=0;} - XFree(ximage); - ximage = 0; - image = 0; -#endif - } - if (xvideo) { -#ifdef HAVE_X11_XVIDEO - //if (data) delete[] data; - if (xvi) XFree(xvi); - xvi=0; - //data=0; -#endif - } -} - -void FormatX11::resize_window (int sx, int sy) { - if (sy<16) sy=16; if (sy>4096) RAISE("height too big"); - if (sx<16) sx=16; if (sx>4096) RAISE("width too big"); - alloc_image(sx,sy); - if (window) { - if (is_owner && !lock_size) { - set_wm_hints(); - XResizeWindow(display,window,sx,sy); - } - } else { - XSetWindowAttributes xswa; - xswa.do_not_propagate_mask = 0; //? - xswa.override_redirect = override_redirect; //#!@#$ - window = XCreateWindow(display, - parent, pos[1], pos[0], sx, sy, 0, - CopyFromParent, InputOutput, CopyFromParent, - CWOverrideRedirect|CWDontPropagate, &xswa); - if(!window) RAISE("can't create window"); - set_wm_hints(); - - XSelectInput(display, window, - ExposureMask|StructureNotifyMask|PointerMotionMask| - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| - KeyPressMask|KeyReleaseMask); - - if (is_owner) XMapRaised(display, window); - imagegc = XCreateGC(display, window, 0, NULL); - if (visual->c_class == PseudoColor) prepare_colormap(); - } - XSync(display,0); -} - -GRID_INLET(0) { - if (in->dim->n != 3) - RAISE("expecting 3 dimensions: rows,columns,channels"); - if (in->dim->get(2)!=3 && in->dim->get(2)!=4) - RAISE("expecting 3 or 4 channels: red,green,blue,ignored (got %d)",in->dim->get(2)); - int sx = in->dim->get(1), osx = dim->get(1); - int sy = in->dim->get(0), osy = dim->get(0); - in->set_chunk(1); - if (sx!=osx || sy!=osy) resize_window(sx,sy); - if (in->dim->get(2)!=bit_packing->size) { - bit_packing->mask[3]=0; - bit_packing = new BitPacking(bit_packing->endian, - bit_packing->bytes, in->dim->get(2), bit_packing->mask); - } -} GRID_FLOW { - int bypl = ximage->bytes_per_line; - int sxc = in->dim->prod(1); - int sx = in->dim->get(1); - int y = dex/sxc; - for (; n>0; y++, data+=sxc, n-=sxc) { - // convert line - if (use_stripes) { - int o=y*bypl; - for (int x=0, i=0, k=y%3; x>2; - } - } else { - bit_packing->pack(sx, data, image+y*bypl); - } - } -} GRID_FINISH { - show_section(0,0,in->dim->get(1),in->dim->get(0)); -} GRID_END - -\def 0 out_size (int sy, int sx) { resize_window(sx,sy); } - -\def 0 setcursor (int shape) { - shape = 2*(shape&63); - Cursor c = XCreateFontCursor(display,shape); - XDefineCursor(display,window,c); - XFlush(display); -} - -\def 0 hidecursor () { - Font font = XLoadFont(display,"fixed"); - XColor color; /* bogus */ - Cursor c = XCreateGlyphCursor(display,font,font,' ',' ',&color,&color); - XDefineCursor(display,window,c); - XFlush(display); -} - -void FormatX11::prepare_colormap() { - Colormap colormap = XCreateColormap(display,window,visual,AllocAll); - XColor colors[256]; - if (use_stripes) { - for (int i=0; i<192; i++) { - int k=(i&63)*0xffff/63; - colors[i].pixel = i; - colors[i].red = (i>>6)==0 ? k : 0; - colors[i].green = (i>>6)==1 ? k : 0; - colors[i].blue = (i>>6)==2 ? k : 0; - colors[i].flags = DoRed | DoGreen | DoBlue; - } - XStoreColors(display,colormap,colors,192); - } else { - for (int i=0; i<256; i++) { - colors[i].pixel = i; - colors[i].red = ((i>>0)&7)*0xffff/7; - colors[i].green = ((i>>3)&7)*0xffff/7; - colors[i].blue = ((i>>6)&3)*0xffff/3; - colors[i].flags = DoRed | DoGreen | DoBlue; - } - XStoreColors(display,colormap,colors,256); - } - XSetWindowColormap(display,window,colormap); -} - -void FormatX11::open_display(const char *disp_string) { - display = XOpenDisplay(disp_string); - if(!display) RAISE("ERROR: opening X11 display: %s",strerror(errno)); - // btw don't expect too much from Xlib error handling. - // Xlib, you are so free of the ravages of intelligence... - XSetErrorHandler(FormatX11_error_handler); - Screen *screen = DefaultScreenOfDisplay(display); - int screen_num = DefaultScreen(display); - visual = DefaultVisual(display, screen_num); - root_window = DefaultRootWindow(display); - depth = DefaultDepthOfScreen(screen); - colormap = 0; - - switch(visual->c_class) { - // without colormap - case TrueColor: case DirectColor: break; - // with colormap - case PseudoColor: if (depth!=8) RAISE("ERROR: with colormap, only supported depth is 8 (got %d)", depth); break; - default: RAISE("ERROR: visual type not supported (got %d)", visual->c_class); - } - -#if defined(HAVE_X11_XVIDEO) - xvideo = true; -#elif defined(HAVE_X11_SHARED_MEMORY) - shared_memory = !! XShmQueryExtension(display); -#else - shared_memory = false; -#endif -} - -Window FormatX11::search_window_tree (Window xid, Atom key, const char *value, int level) { - if (level>2) return 0xDeadBeef; - Window root_r, parent_r; - Window *children_r; - unsigned int nchildren_r; - XQueryTree(display,xid,&root_r,&parent_r,&children_r,&nchildren_r); - Window target = 0xDeadBeef; - for (int i=0; i<(int)nchildren_r; i++) { - Atom actual_type_r; - int actual_format_r; - unsigned long nitems_r, bytes_after_r; - unsigned char *prop_r; - XGetWindowProperty(display,children_r[i],key,0,666,0,AnyPropertyType, - &actual_type_r,&actual_format_r,&nitems_r,&bytes_after_r,&prop_r); - uint32 value_l = strlen(value); - bool match = prop_r && nitems_r>=value_l && - strncmp((char *)prop_r+nitems_r-value_l,value,value_l)==0; - XFree(prop_r); - if (match) {target=children_r[i]; break;} - target = search_window_tree(children_r[i],key,value,level+1); - if (target != 0xDeadBeef) break; - } - if (children_r) XFree(children_r); - return target; -} - -\def 0 move (int y, int x) { - pos[0]=y; pos[1]=x; - XMoveWindow(display,window,x,y); - XFlush(display); -} - -\def 0 set_geometry (int y, int x, int sy, int sx) { - pos[0]=y; pos[1]=x; - XMoveWindow(display,window,x,y); - resize_window(sx,sy); - XFlush(display); -} - -\def 0 shared_memory (bool toggle) {shared_memory = toggle;} -\def 0 xvideo (bool toggle) {xvideo = toggle;} - -\def 0 warp (int y, int x) { - XWarpPointer(display,None,None,0,0,0,0,x,y); - XFlush(display); -} - -\def 0 title (string title="") {this->title = title; set_wm_hints();} - -\end class FormatX11 {install_format("#io.x11",6,"");} -void startup_x11 () { - \startall -} - -- cgit v1.2.1