aboutsummaryrefslogtreecommitdiff
path: root/externals/gridflow/src
diff options
context:
space:
mode:
authorN.N. <matju@users.sourceforge.net>2010-01-05 17:50:51 +0000
committerN.N. <matju@users.sourceforge.net>2010-01-05 17:50:51 +0000
commit39ba8a640bd178fd732d945760df7eef3e2c1e1a (patch)
treeb59fa5bc00fcbb6389ea3ebf2c7ee8b9ced1daa8 /externals/gridflow/src
parent8cabe6dabadf2422240ff4e9d5f5f8c95622b682 (diff)
no gridflow snapshots in pure-data svn
svn path=/trunk/; revision=12888
Diffstat (limited to 'externals/gridflow/src')
-rw-r--r--externals/gridflow/src/aalib.cxx144
-rw-r--r--externals/gridflow/src/classes1.cxx2342
-rw-r--r--externals/gridflow/src/classes2.cxx1183
-rw-r--r--externals/gridflow/src/dc1394.cxx287
-rw-r--r--externals/gridflow/src/fftw.cxx114
-rw-r--r--externals/gridflow/src/formats.cxx266
-rw-r--r--externals/gridflow/src/gem.cxx202
-rw-r--r--externals/gridflow/src/grid.cxx295
-rw-r--r--externals/gridflow/src/gridflow.cxx961
-rw-r--r--externals/gridflow/src/gridflow.hxx911
-rw-r--r--externals/gridflow/src/jpeg.cxx118
-rw-r--r--externals/gridflow/src/mmx.rb219
-rw-r--r--externals/gridflow/src/mpeg3.cxx83
-rw-r--r--externals/gridflow/src/netpbm.cxx117
-rw-r--r--externals/gridflow/src/number.cxx446
-rw-r--r--externals/gridflow/src/opencv.cxx537
-rw-r--r--externals/gridflow/src/png.cxx143
-rw-r--r--externals/gridflow/src/pwc-ioctl.h292
-rw-r--r--externals/gridflow/src/quartz.m224
-rw-r--r--externals/gridflow/src/quicktimeapple.cxx456
-rw-r--r--externals/gridflow/src/quicktimehw.cxx246
-rw-r--r--externals/gridflow/src/sdl.cxx209
-rw-r--r--externals/gridflow/src/source_filter.rb311
-rw-r--r--externals/gridflow/src/videodev.cxx793
-rw-r--r--externals/gridflow/src/x11.cxx664
25 files changed, 0 insertions, 11563 deletions
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 <aalib.h>
-#include <map>
-
-/* MINNOR is a typo in aalib.h, sorry */
-typedef
-#if AA_LIB_MINNOR == 2
- int
-#else
- enum aa_attribute
-#endif
-AAAttr;
-
-static std::map<string,const aa_driver *> 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; i<argc; i++) argv2[i] = strdup(string(argv[i]).data());
- if (mode!=gensym("out")) RAISE("write-only, sorry");
- aa_parseoptions(0,0,&argc,argv2);
- for (int i=0; i<argc; i++) free(argv2[i]);
- if (drivers.find(target)==drivers.end()) RAISE("unknown aalib driver '%s'",target.data());
- const aa_driver *driver = drivers[target];
- context = aa_init(driver,&aa_defparams,0);
- rparams = aa_getrenderparams();
- if (!context) RAISE("opening aalib didn't work");
- int32 v[]={context->imgheight,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; x<sx; x++) {
- context->textbuffer[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; x<sx; x++) aa_putpixel(context,x,y,data[x]);
- y++;
- n-=f;
- data+=f;
- }
- }
-} GRID_FINISH {
- if (!raw_mode) {
- aa_palette pal;
- for (int i=0; i<256; i++) aa_setpalette(pal,i,i,i,i);
- aa_renderpalette(context,pal,rparams,0,0,
- aa_scrwidth(context),aa_scrheight(context));
- }
- if (autodraw==1) aa_flush(context);
-} GRID_END
-
-\def 0 hidecursor () { aa_hidemouse(context); }
-\def 0 draw () { aa_flush(context); }
-\def 0 print (int y, int x, int a, string text) {
- aa_puts(context,x,y,(AAAttr)a,(char *)text.data());
- if (autodraw==1) aa_flush(context);
-}
-
-\def 0 dump () {
- int32 v[] = {aa_scrheight(context), aa_scrwidth(context), 2};
- GridOutlet out(this,0,new Dim(3,v));
- for (int y=0; y<aa_scrheight(context); y++) {
- for (int x=0; x<aa_scrwidth(context); x++) {
- int32 data[2];
- data[0] = context->textbuffer[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 <sys/time.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string>
-#include <sstream>
-#include <iomanip>
-#include <errno.h>
-#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<n>::f(a,b)
-#endif
-
-template <long n> class SCopy {
-public: template <class T> static inline void __attribute__((always_inline)) f(T *a, T *b) {
- *a=*b; SCopy<n-1>::f(a+1,b+1);}};
-template <> class SCopy<0> {
-public: template <class T> static inline void __attribute__((always_inline)) f(T *a, T *b) {}};
-
-/*template <> class SCopy<4> {
-public: template <class T>
- 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<Dim> d) {
- if (d->n!=1) RAISE("dimension list should be Dim[n], not %s",d->to_s());}
-//static void expect_min_one_dim (P<Dim> d) {
-// if (d->n<1) RAISE("minimum 1 dimension");}
-static void expect_max_one_dim (P<Dim> d) {
- if (d->n>1) RAISE("expecting Dim[] or Dim[n], got %s",d->to_s());}
-//static void expect_exactly_one_dim (P<Dim> 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> 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 <class T> 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<Dim> 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; i<n; i++) outlet_float(bself->outlets[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; i<n; i++) c[i]=(char)data[i];
- c[n]=0;
- outlet_symbol(bself->outlets[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<n; i++) SETFLOAT(a+i,s[i]);
- //fprintf(stderr,"dest=%p\n",dest);
- //fprintf(stderr,"*dest={%08x,%08x,%08x,%08x,...}\n",dest[0],dest[1],dest[2],dest[3]);
- pd_typedmess(dest,gensym("very_long_name_that_nobody_uses"),n,a);
- }
- }
- void puts (std::string s) {puts(s.data());}
- void puts (std::ostringstream &s) {puts(s.str());}
- template <class T> void make_columns (int n, T *data);
- template <class T> 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<n; i++) {
- if (base!=2) oprintf(s,f.data(),data[i]);
- else {
- T x = gf_abs(data[i]);
- int ndigits = 1+highest_bit(uint64(x));
- for (int j=columns-ndigits-(data[i]!=x); j>=0; j--) s<<' ';
- if (data[i]!=x) s<<'-';
- for (int j=ndigits-1; j>=0; j--) {
- s<<char('0'+(((long)x>>j)&1));
- }
- }
- if (i<n-1) s << sep;
- if (s.tellp()>trunc) return;
- }
- }
- void dump_dims(std::ostream &s, GridInlet *in) {
- if (name && name!=&s_) s << name->s_name << ": ";
- s << "Dim[";
- for (int i=0; i<in->dim->n; i++) {
- s << in->dim->v[i];
- if (i<in->dim->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 <class T> void GridPrint::make_columns (int n, T *data) {
- long maxv=0;
- long minv=0;
- for (int i=0; i<n; i++) {
- if (maxv<data[i]) maxv=long(data[i]);
- if (minv>data[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; row<sy; row++) {
- std::ostringstream body;
- dump(body,sx,&data[sx*row],' ',trunc);
- if (body.tellp()>trunc) 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; row<sy; row++) {
- std::ostringstream str;
- for (int col=0; col<sx; col++) {
- str << "(";
- dump(str,sz2,&data[sz*row+sz2*col],' ',trunc);
- if (str.tellp()>trunc) {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 <class T> 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 <class T> void GridStore::compute_indices(T *v, long nc, long nd) {
- for (int i=0; i<nc; i++) {
- uint32 wrap = r->dim->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; i<nc; i++) for (long j=0; j<n; j+=nc) v[k++] = data[i+j];
- compute_indices(v,nc,nd);
- }
-#define FOO(type) { \
- type *p = (type *)*r; \
- if (size<=16) { \
- type tada[nd*size]; \
- type *foo = tada; \
- long i=0; \
- switch (size) { \
- case 1: for (; i<(nd&-4); i+=4, foo+=4) { \
- foo[0] = p[v[i+0]]; \
- foo[1] = p[v[i+1]]; \
- foo[2] = p[v[i+2]]; \
- foo[3] = p[v[i+3]]; \
- } break; \
- case 2: for (; i<nd; i++, foo+=2) SCOPY(foo,p+2*v[i],2); break; \
- case 3: for (; i<nd; i++, foo+=3) SCOPY(foo,p+3*v[i],3); break; \
- case 4: for (; i<nd; i++, foo+=4) SCOPY(foo,p+4*v[i],4); break; \
- default:; }; \
- for (; i<nd; i++, foo+=size) COPY(foo,p+size*v[i],size); \
- out->send(size*nd,tada); \
- } else { \
- for (int i=0; i<nd; i++) out->send(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; i<nn; i++) { fromb[i]=0; sizeb[i]=1; }
- COPY(wdex ,(int32 *)*put_at ,put_at->dim->prod());
- COPY(fromb+nn-na,(int32 *)*put_at ,na);
- COPY(sizeb+nn-nb,(int32 *)in->dim->v,nb);
- for (int i=0; i<nn; i++) to2[i] = fromb[i]+sizeb[i];
- d=0;
- // find out when we can skip computing indices
- //!@#$ should actually also stop before blowing up packet size
- lsd=nn;
- while (lsd>=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(;d<lsd;d++) x[d]=fromb[d];
- COPY(v,x,lsd);
- compute_indices(v,lsd,1);
- op->zip(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]<to2[d]) break;}
- d++;
- }
-} GRID_END
-\def 0 bang () {
- t_atom a[2];
- SETFLOAT(a+0,0);
- SETSYMBOL(a+1,gensym("#"));
- pd_list((t_pd *)bself,&s_list,2,a);
-}
-\def 1 reassign () {put_at=0;}
-\def 1 put_at (...) {
- if (argv[0].a_type==A_LIST) put_at=convert(argv[0],(Grid **)0);
- else {
- put_at=new Grid(new Dim(argc),int32_e);
- int32 *v = (int32 *)*put_at;
- for (int i=0; i<argc; i++) v[i]=convert(argv[i],(int32 *)0);
- }
-}
-\end class {install("#store",2,1); add_creator("@store");}
-
-//****************************************************************
-//{ Dim[*As]<T> -> Dim[*As]<T> } or
-//{ Dim[*As]<T>,Dim[*Bs]<T> -> Dim[*As]<T> }
-\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; i<nn; i+=loop) COPY(data2+i,rdata,loop);
- if (n>nn) 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]<T>,Dim[*Cs]<T> -> Dim[*As,*Cs]<T> }
- 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; i<n; i++) out->send(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]<T>,Dim[*Cs]<T> -> Dim[*As,B,*Cs]<T> }
- 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; i<n; i+=factor) op->scan(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; i<n; i+=factor) op->scan(zn,yn, seed,buf+i);
- }
- out->send(n,buf);
-} GRID_END
-
-\end class {install("#scan",1,1);}
-
-//****************************************************************
-// L is a Dim[*si,sj, *ss]<T>
-// R is a Dim[ sj,*sk,*ss]<T>
-// Seed is a Dim[ *ss]<T>
-// result is a Dim[*si, *sk,*ss]<T>
-// 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 <class T> void inner_child_a (T *as, T *bs, int sj, int sk, int chunk) {
- for (int j=0; j<chunk; j++, as+=sk, bs+=sj) op_put->map(sk,as,*bs);}
-template <class T, int sk> void inner_child_b (T *as, T *bs, int sj, int chunk) {
- for (int j=0; j<chunk; j++, as+=sk, bs+=sj) op_put->map(sk,as,*bs);}
-
-// Inner product in a Module on the (+,*) Ring
-// | BBBBB
-// j BBBBB
-// | BBBBB
-// --j--*---k---
-// AAAAA CCCCC
-template <class T> void dot_add_mul (long sk, long sj, T *cs, T *as, T *bs) {
- for (long k=0; k<sk; k++) {T c=0; for (long j=0; j<sj; j++) {c+=as[j]*bs[j*sk+k];} *cs++=c;}}
-template <class T, long sj> void dot_add_mul (long sk, T *cs, T *as, T *bs) {
- for (long k=0; k<sk; k++) {T c=0; for (long j=0; j<sj; j++) {c+=as[j]*bs[j*sk+k];} *cs++=c;}}
-template <class T, long sj, long sk> void dot_add_mul (T *cs, T *as, T *bs) {
- for (long k=0; k<sk; k++) {T c=0; for (long j=0; j<sj; j++) {c+=as[j]*bs[j*sk+k];} *cs++=c;}}
-
-GRID_INLET(0) {
- SAME_TYPE(in,r);
- SAME_TYPE(in,seed);
- P<Dim> 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; i<sj; i++)
- for (long j=0; j<chunk; j++)
- COPY(buf3+(j+i*chunk)*sk,rdata+i*sk,sk);
- use_dot = op==op_mul && fold==op_add && seed->dim->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<chunk; i++) dot_add_mul<T,sj,sk>( 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<chunk; i++) dot_add_mul<T,sj>(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; i<chunk; i++) dot_add_mul(sk,sj,buf2+sk*i,data+sj*i,(T *)*r);
- }
- out->send(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<sj; i++) {
- switch (sk) {
- case 1: inner_child_b<T,1>(buf,data+i,sj,chunk); break;
- case 2: inner_child_b<T,2>(buf,data+i,sj,chunk); break;
- case 3: inner_child_b<T,3>(buf,data+i,sj,chunk); break;
- case 4: inner_child_b<T,4>(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]<T>,Dim[*Bs]<T> -> Dim[*As,*Bs]<T> }*/
-\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<Dim> a = in->dim;
- P<Dim> 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; j<b_prod; j++) buf[j] = *data;
- op->zip(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; k<n; i++) {Z;} break;
- case 2: for (long i=0,k=0; k<n; i++) {Z;Z;} break;
- case 3: for (long i=0,k=0; k<n; i++) {Z;Z;Z;} break;
- case 4: for (long i=0,k=0; k<n; i++) {Z;Z;Z;Z;} break;
- default:for (long i=0,k=0; k<n; i++) for (int j=0; j<b_prod; j++, k++) Z;
- }
- #undef Z
- int ch=64*b_prod;
- int nn=(n/ch)*ch;
- for (int j=0; j<nn; j+=ch) op->zip(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[]<T>,Dim[]<T>,Dim[]<T> -> Dim[A]<T> } or
-//{ Dim[B]<T>,Dim[B]<T>,Dim[B]<T> -> Dim[*As,B]<T> }
-\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 <class T> void trigger (T bogus);
-};
-
-template <class T>
-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<n; i++) {
- nn[i] = (tob[i] - fromb[i] + stepb[i] - cmp(stepb[i],(T)0)) / stepb[i];
- if (nn[i]<0) nn[i]=0;
- to2[i] = fromb[i]+stepb[i]*nn[i];
- }
- P<Dim> 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(;d<n;d++) x[k+d]=fromb[d];
- k+=n;
- if (k==64*n) {out->send(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<char *>(number_type_table[in->nt].name)));
- /*in->set_mode(0);*/
-} GRID_END
-\end class {install("#type",1,1); add_creator("@type");}
-
-//****************************************************************
-//{ Dim[*As]<T>,Dim[B] -> Dim[*Cs]<T> }
-\class GridRedim : FObject {
- \attr P<Dim> 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 (a<b) temp=new Grid(new Dim(a),in->nt);
- 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; i<b; i+=a) out->send(min(a,b-i),(T *)*temp);
- } else {
- T foo[1]={0}; for (long i=0; i<b; i++) out->send(1,foo);
- }
- }
- temp=0;
-} GRID_END
-
-GRID_INPUT(1,dim_grid) {
- P<Dim> 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<Dim> 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; i<d->n; 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 <class T> struct GradeFunction {
- static int comparator (T **a, T **b) {return **a-**b;}};
-#define FOO(T) \
-template <> struct GradeFunction<T> { \
- 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<m; i++) foo[i] = &data[i];
- qsort(foo,m,sizeof(T *),(comparator_t)GradeFunction<T>::comparator);
- for (int i=0; i<m; i++) bar[i] = foo[i]-(T *)data;
- out->send(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; a<na; a++)
- for (long b=0; b<nb; b++)
- for (long c=0; c<nc; c++)
- COPY(res +((c*nb+b)*na+a)*nd,
- data+((a*nb+b)*nc+c)*nd,nd);
- out->send(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; i<hf1; i+=f2) memswap(data+i,data2-i,f2);
- out->send(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; x<sx; x++) {
- sumx+=x*data[x];
- sumy+=y*data[x];
- sum += data[x];
- }
- n-=sx;
- data+=sx;
- y++;
- }
-} GRID_FINISH {
- int32 blah[2];
- blah[0] = sum ? sumy/sum : 0;
- blah[1] = sum ? sumx/sum : 0;
- out->send(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> 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; x<sx; x++) {
- sumy+=y*data[x];
- sumx+=x*data[x];
- sum += data[x];
- }
- break;
- case 2:
- for (int x=0; x<sx; x++) {
- int ty=y-oy;
- int tx=x-ox;
- sumy +=ty*ty*data[x];
- sumxy+=tx*ty*data[x];
- sumx +=tx*tx*data[x];
- sum += data[x];
- }
- }
- n-=sx;
- data+=sx;
- y++;
- }
-} GRID_FINISH {
- int32 blah[4];
- switch (order) {
- case 1: /* centroid vector */
- blah[0] = sum ? sumy/sum : 0;
- blah[1] = sum ? sumx/sum : 0;
- out->send(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 <class T> 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<x2 */
- int x2; for (x2=x; x2<sx; x2++) if (AT(y,x2)!=1) break;
- int x1; for (x1=x; x1>=0; x1--) if (AT(y,x1)!=1) break;
- x1++;
- if (form==0) {
- for (x=x1; x<x2; x++) {
- AT(y,x)=label;
- stat->yy += y*y; stat->y += y;
- stat->yx += y*x; stat->area++;
- stat->xx += x*x; stat->x += x;
- }
- for (x=x1; x<x2; x++) {
- if (y>0 && AT(y-1,x)==1) flood_fill(dat,sy,sx,y-1,x,stat,label,form);
- if (y<sy-1 && AT(y+1,x)==1) flood_fill(dat,sy,sx,y+1,x,stat,label,form);
- }
- } else {
- for (x=x1; x<x2; x++) {
- AT(y,x)=label;
- }
- stat->y=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; i<n; i++) dat[i]=data[i];
- int y,x=0,label=2;
- for (y=0; y<sy; y++) for (x=0; x<sx; x++) {
- if (dat[y*sx+x]!=1) continue;
- Stats s;
- flood_fill(dat,sy,sx,y,x,&s,label,form_val);
- if (form_val==0) {
- float32 cooked[6] = {
- (s.yy-s.y*s.y/s.area)/s.area,
- (s.yx-s.y*s.x/s.area)/s.area,
- (s.yx-s.y*s.x/s.area)/s.area,
- (s.xx-s.x*s.x/s.area)/s.area,
- s.y/s.area,
- s.x/s.area};
- float a[] = {s.area};
- send_out(3,1,a);
- GridOutlet o2(this,2,new Dim(2)); o2.send(2,cooked+4);
- GridOutlet o1(this,1,new Dim(2,2)); o1.send(4,cooked);
- } else {
- float32 cooked[4] = {s.y,s.x1,s.y,s.x2};
- GridOutlet o1(this,1,new Dim(2,2)); o1.send(4,cooked);
- }
- label++;
- }
- out = new GridOutlet(this,0,new Dim(sy,sx,1),in->nt);
- 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<Dim> diml;
- \attr P<Dim> 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; i<n; i++) v[i]=in->dim->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; x<zxc; x++) duh[x]=0;
- for (int y=0; y<diml->v[0]; y++) out->send(zxc,duh);
- for (int y=0; y<sy; y++) {
- out->send(diml->v[1]*sc,duh);
- out->send(sxc,data+y*sxc);
- out->send(dimr->v[1]*sc,duh);
- }
- for (int i=0; i<dimr->v[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<Dim> d) {
- if (d->n!=3) RAISE("(height,width,chans) dimensions please");}
-static void expect_rgb_picture (P<Dim> d) {
- expect_picture(d);
- if (d->get(2)!=3) RAISE("(red,green,blue) channels please");}
-static void expect_rgba_picture (P<Dim> d) {
- expect_picture(d);
- if (d->get(2)!=4) RAISE("(red,green,blue,alpha) channels please");}
-
-//****************************************************************
-//{ Dim[A,B,*Cs]<T>,Dim[D,E]<T> -> Dim[A,B,*Cs]<T> }
-
-static void expect_convolution_matrix (P<Dim> 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 <class T> void copy_row (T *buf, long sx, long y, long x);
- template <class T> void make_plan (T bogus);
- ~GridConvolve () {if (plan) delete[] plan;}
-};
-
-template <class T> 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 <class T> void GridConvolve::make_plan (T bogus) {
- P<Dim> 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; y<dby; y++) {
- for (long x=0; x<dbx; x++) {
- long k = anti ? y*dbx+x : (dby-1-y)*dbx+(dbx-1-x);
- T rh = ((T *)*b)[k];
- bool neutral = op->on(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<Dim> 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; ay<day; ay++) {
- op_put->map(n,buf,*(T *)*seed);
- for (long i=0; i<plann; i++) {
- long by = plan[i].y;
- long bx = plan[i].x;
- long k = anti ? by*dbx+bx : (dby-1-by)*dbx+(dbx-1-bx);
- T rh = ((T *)*b)[k];
- if (i==0 || by!=plan[i-1].y || orh!=rh) {
- if (wrap) copy_row(buf2,sx,ay+by-margy,-margx);
- else copy_row(buf2,sx,ay+by,0);
- if (!plan[i].neutral) op->map(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]<T> -> Dim[C,D,3]<T> }*/
-
-static void expect_scale_factor (P<Dim> 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<Dim> 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; i<rowsize; i+=z) \
- for (int k=0; k<scalex; k++, p+=z)
- switch (chans) {
- 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 c=0; c<chans; c++) Z(c);}
- }
- #undef LOOP
- for (int j=0; j<scaley; j++) out->send(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]<T> -> Dim[C,D,3]<T> }
-\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<Dim> 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; p<rowsize2; p+=z) \
- for (int j=0; j<scalex; j++,i+=z)
- switch (chans) {
- 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; k<chans; k++) Z(k);} break;
- }
- #undef LOOP
- y++;
- if (y%scaley==0 && out->dim) {
- 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; p<rowsize2; i+=xinc, p+=z)
- switch(in->dim->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; k<chans; k++) Z(k);}break;
- }
- #undef LOOP
- out->send(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<Dim> 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; i<n; i+=4,j+=3) {
- COMPUTE_ALPHA(0,3);
- COMPUTE_ALPHA(1,3);
- COMPUTE_ALPHA(2,3);
- }
-#undef COMPUTE_ALPHA
- out->send(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<Dim> 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; i<nl; i++) {
- ld[i].y1 = pd[j+0];
- ld[i].x1 = pd[j+1];
- j=(j+2)%(2*tnl);
- ld[i].y2 = pd[j+0];
- ld[i].x2 = pd[j+1];
- if (omit==OMIT_ODD) j=(j+2)%(2*tnl);
- if (draw!=DRAW_POINT) if (ld[i].y1>ld[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; i<lines_stop; i++) {
- if (ld[i].y2<=y-fudge) {memswap(ld+i,ld+lines_start,1); lines_start++;}
- }
- }
- if (lines_start == lines_stop) {
- out->send(f,data);
- } else {
- int32 xl = in->dim->get(1);
- T data2[f];
- COPY(data2,data,f);
- for (int i=lines_start; i<lines_stop; i++) {
- Line &l = ld[i];
- l.ox = l.x;
- l.x = l.x1 + (((y-l.y1)*l.m)>>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<lines_stop-1; i+=2) {
- int xs = max(ld[i].x,(int32)0);
- int xe = min(ld[i+1].x,xl);
- if (xs>=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<lines_stop; i++) {
- if (ld[i].y1==ld[i].y2) ld[i].ox=ld[i].x2;
- int xs = min(ld[i].x,ld[i].ox);
- int xe = max(ld[i].x,ld[i].ox);
- if (xs==xe) xe++;
- if ((xs<0 && xe<0) || (xs>=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<lines_stop; i++) {
- if (y!=ld[i].y1) continue;
- int xs=ld[i].x1;
- int xe=xs+1;
- if (xs<0 || xs>=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<Dim> 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 <class T> 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 <class T> 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; x<sx; x+=rsx) {
- draw_segment(data2,data,mod(y-py,rsy),x);
- }
- } else {
- draw_segment(data2,data,y-py,px);
- }
- out->send(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; i<n; i++) {
- long off = 0;
- for (long k=0; k>m; k++) off = off*in->dim->v[k] + pdata[i*points->dim->v[1]+k];
- off *= cn;
- for (long j=0; j<cn; j++) data[off+j] = cdata[j];
- }
-// out->send(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; i<n; i+=3) {
- if (data[i+0]<=thresh) {
- tada[i+0]=0; tada[i+1]=0; tada[i+2]=0;
- } else {
- tada[i+0]=data[i+0]; tada[i+1]=data[i+1]; tada[i+2]=data[i+2];
- }
- }
- out->send(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; i++) for (int j=0; j<n; j++) rotator[i*n+j] = scale * (i==j);
- float th = angle * M_PI / 18000;
- for (int i=0; i<2; i++) for (int j=0; j<2; j++)
- rotator[(i?to:from)*n+(j?to:from)] = (int32)round(scale*cos(th+(j-i)*M_PI/2));
- GridOutlet out(this,0,new Dim(n,n),int32_e);
- out.send(n*n,rotator);
-}
-\def 0 axis(int from, int to, int n) {
- if (n<0) RAISE("n-axis number incorrect");
- if (from<0 || from>=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<Dim> 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 <class T> 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<n; i++, ldata++, rdata+=chans) {
- if (*ldata<0 || *ldata>=numClusters) RAISE("value out of range in left grid");
- OP(+)->zip(chans,sdata+(*ldata)*chans,rdata);
- cdata[*ldata]++;
- }
- for (int i=0; i<numClusters; i++) OP(/)->map(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<Dim> 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 <algorithm>
-#include <errno.h>
-#include <sys/time.h>
-#include <string>
-
-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; i<argc; i++) {
- if (argv[i].a_type==A_LIST) {
- t_binbuf *b = (t_binbuf *)argv[i].a_gpointer;
- int bac = binbuf_getnatom(b);
- t_atom *bat = binbuf_getvec(b);
- sargv[i].name = atom_getsymbolarg(0,bac,bat);
- sargv[i].type = atom_getsymbolarg(1,bac,bat);
- if (bac<3) SETNULL(&sargv[i].defaultv); else sargv[i].defaultv = bat[2];
- } else if (argv[i].a_type==A_SYMBOL) {
- sargv[i].name = argv[i].a_symbol;
- sargv[i].type = gensym("a");
- SETNULL(&sargv[i].defaultv);
- } else RAISE("expected symbol or nested list");
- }
- bself->noutlets_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; i<ac; i++) av[i] = env->ce_argv[i];
- //ac = handle_braces(ac,av);
- t_symbol *comma = gensym(",");
- int j;
- for (j=0; j<ac; j++) if (av[j].a_type==A_SYMBOL && av[j].a_symbol==comma) break;
- int jj = handle_braces(j,av);
- process_args(jj,av);
- while (j<ac) {
- j++;
- int k=j;
- for (; j<ac; j++) if (av[j].a_type==A_SYMBOL && av[j].a_symbol==comma) break;
- //outlet_anything2(bself->outlets[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 <class T> 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<t_atom2> contents;
- \constructor () {}
- \decl 0 list(...);
- void traverse (int argc, t_atom2 *argv) {
- for (int i=0; i<argc; i++) {
- if (argv[i].a_type==A_LIST) traverse(binbuf_getnatom(argv[i]),(t_atom2 *)binbuf_getvec(argv[i]));
- else contents.push_back(argv[i]);
- }
- }
-};
-\def 0 list (...) {
- traverse(argc,argv);
- outlet_list(bself->te_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; i<argc; i++) at[i] = argv[i];
-}
-\def 0 list (...) {
- if (argc<1) RAISE("empty input");
- int i=0; for (; i<ac; i++) if (atom_eq(at[i],argv[0])) break;
- outlet_float(bself->outlets[0],i==ac?-1:i);
-}
-\def 0 float (float f) {
- int i=0; for (; i<ac; i++) if (atom_eq(at[i],argv[0])) break;
- outlet_float(bself->outlets[0],i==ac?-1:i);
-}
-\def 0 symbol (t_symbol *s) {
- int i=0; for (; i<ac; i++) if (atom_eq(at[i],argv[0])) break;
- outlet_float(bself->outlets[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<argc; i++) at[i] = argv[i];
-}
-\end class {install("listread",2,1);}
-
-\class Range : FObject {
- t_float *mosusses;
- int nmosusses;
- \constructor (...) {
- nmosusses = argc;
- for (int i=0; i<argc; i++) if (argv[i].a_type!=A_FLOAT) RAISE("$%d: expected float",i+1);
- mosusses = new t_float[argc];
- for (int i=0; i<argc; i++) mosusses[i]=argv[i].a_float;
- bself-> 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; i<nmosusses; i++) if (f<mosusses[i]) break;
- outlet_float(bself->outlets[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<char *>(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; i<argc; i++) self << argv[i] << " )"[i==argc-1];
- break;
- }
- default: self << "\\a(" << a.a_type << " " << std::hex << a.a_gpointer << std::dec << ")"; break;
- }
- return self;
-}
-\def 0 grid(...) {pd_typedmess(gp,gensym("grid"),argc,argv);}
-\def void anything(...) {
- std::ostringstream text;
- text << prefix->s_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<argc; i++) {text << " " << argv[i];}
- post("%s",text.str().data());
-}
-\end class {install("gf.print",1,0); add_creator3(fclass,"print");}
-
-#ifdef HAVE_DESIREDATA
-t_glist *glist_getcanvas(t_glist *foo) {return foo;}//dummy
-void canvas_fixlinesfor(t_glist *foo,t_text *) {}//dummy
-#endif
-
-//#ifdef HAVE_DESIREDATA
-static void display_update(void *x);
-\class Display : FObject {
- bool selected;
- t_glist *canvas;
- t_symbol *rsym;
- int y,x,sy,sx;
- bool vis;
- std::ostringstream text;
- t_clock *clock;
- t_pd *gp;
- \constructor () {
- selected=false; canvas=0; y=0; x=0; sy=16; sx=80; vis=false; clock=0;
- std::ostringstream os;
- rsym = gensym(const_cast<char *>(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;i<n;i++) {
- if (s[i]=='\n') quoted << "\\n";
- else if (strchr("\"[]$",s[i])) quoted << "\\" << (char)s[i];
- else quoted << (char)s[i];
- }
- //return if not canvas or not @vis # can't show for now...
- /* we're not using quoting for now because there's a bug in it. */
- /* btw, this quoting is using "", but we're gonna use {} instead for now, because of newlines */
- sys_vgui("display_update %s %d %d #000000 #cccccc %s {Courier -12} .x%x.c {%s}\n",
- rsym->s_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; i<argc; i++) {
- atom_string(&argv[i],buf,MAXPDSTRING);
- text << buf;
- col += strlen(buf);
- if (i!=argc-1) {
- text << " ";
- col++;
- if (col>56) {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; i<argc; i++) text << (char)INT(argv[i]);
-}
-\end class {
-#ifndef DESIRE
- install("display",1,0);
- t_class *qlass = fclass->bfclass;
- 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 <linux/parport.h>
-#define LPCHAR 0x0601
-#define LPCAREFUL 0x0609 /* obsoleted??? wtf? */
-#define LPGETSTATUS 0x060b /* return LP_S(minor) */
-#define LPGETFLAGS 0x060e /* get status flags */
-
-#include <sys/ioctl.h>
-
-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; i<nsels; i++) if (sel==sels[i]) break;
- outlet_anything(bself->outlets[i],sel,argc-1,argv+1);
-}
-\def 1 list(...) {
- for (int i=0; i<argc; i++) if (argv[i].a_type!=A_SYMBOL) {delete[] sels; RAISE("$%d: expected symbol",i+1);}
- if (sels) delete[] sels;
- nsels = argc;
- sels = new t_symbol*[argc];
- for (int i=0; i<argc; i++) sels[i] = argv[i].a_symbol;
-}
-\end class {install("route2",1,1);}
-
-template <class T> int sgn(T a, T b=0) {return a<b?-1:a>b;}
-
-\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 (index<lo || index>hi) {
- 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; i<ac; i++) {
- av[i] = (ReceivesProxy *)pd_new(ReceivesProxy_class);
- av[i]->parent = this;
- av[i]->suffix = argv[i];
- pd_bind( (t_pd *)av[i],local(av[i]->suffix));
- }
- }
- void do_unbind () {
- for (int i=0; i<ac; i++) {
- pd_unbind((t_pd *)av[i],local(av[i]->suffix));
- 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; i<argc; i++) if (!atom_eq(at[i],argv[i])) {outlet_float(bself->outlets[0],0); return;}
- outlet_float(bself->outlets[0],1);
-}
-\end class {install("list.==",2,1);}
-
-//****************************************************************
-//#ifdef UNISTD
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/param.h>
-#include <unistd.h>
-//#endif
-#if defined (__APPLE__) || defined (__FreeBSD__)
-#define HZ CLK_TCK
-#endif
-
-uint64 cpu_hertz;
-int uint64_compare(uint64 &a, uint64 &b) {return a<b?-1:a>b;}
-
-\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; i<argc; i++) {
- atom_string(&argv[i],buf,MAXPDSTRING);
- o << buf;
- if (i!=argc-1) o << ' ';
- }
- format = o.str();
- }
- \decl 0 bang ();
- \decl 0 float (float f);
- \decl 0 symbol (t_symbol *s);
- \decl 0 list (...);
-};
-\def 0 bang () {_0_list(0,0);}
-\def 0 float (float f) {_0_list(argc,argv);}
-\def 0 symbol (t_symbol *s) {_0_list(argc,argv);}
-
-\def 0 list (...) {
- std::ostringstream o;
- pd_oprintf(o,format.data(),argc,argv);
- t_canvas *canvas = canvas_getrootfor(bself->mom);
- 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; i<argc; i++) {
- if (argv[i].a_type==A_FLOAT) outlet_float( o,argv[i]);
- else if (argv[i].a_type==A_SYMBOL) outlet_symbol(o,argv[i]);
- else RAISE("oops. unsupported.");
- }
-}
-\end class {install("foreach",1,1);}
-
-//****************************************************************
-
-#define MOM \
- t_canvas *mom = bself->mom; \
- for (int i=0; i<n; i++) {mom = mom->gl_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; i<n; i++) {mom = mom->gl_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; i<n; i++) {ouch = ouch->next; 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<t_object *> 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 <libraw1394/raw1394.h>
-#include "gridflow.hxx.fcs"
-
-/* speeds are numbered 0 to 5, worth 100<<speednum */
-/* framerates are numbers 32 to 39, worth 1.875<<(frameratenum-32) */
-
-#define MODE(x,y,palette) /* nothing for now */
-
-static std::map<int,string> 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<int,int> 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; port<numPorts; port++) {
- post("trying port #%d...",port);
- RH rh = dc1394_create_handle(port);
- int numCameras=0xDEADBEEF;
- NID *nodes = dc1394_get_camera_nodes(rh,&numCameras,0);
- post("port #%d has %d cameras",port,numCameras);
- for (int i=0; i<numCameras; i++) {
- post("camera at node #%d",nodes[i]);
- if (!gotone) {gotone=true; useport=port; usenode=nodes[i];}
- }
- dc1394_destroy_handle(rh);
- }
- if (!gotone) RAISE("no cameras available");
- this->rh = 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; i<NUM_FEATURES; i++) {
- dc1394_feature_info &f = features.feature[i];
- int id = f.feature_id;
- string name = feature_names.find(id)==feature_names.end() ? "(unknown)" : feature_names[id];
- bool is_there = f.available;
- post(" feature %d '%s' is %s",id,name.data(),is_there?"present":"absent");
- if (!is_there) continue;
- post(" min=%u max=%u abs_min=%u abs_max=%u",f.min,f.max,f.abs_min,f.abs_max);
- }
- framerate_e = FRAMERATE_30;
- height = 480;
- width = 640;
- setup();
- }
- \decl 0 bang ();
- \attr float framerate();
- \attr unsigned brightness();
- \attr unsigned hue();
- \attr unsigned colour();
- //\attr uint16 contrast();
- //\attr uint16 whiteness();
- void setup ();
- \decl 0 get (t_symbol *s=0);
- \decl 0 size (int height, int width);
-};
-
-\def 0 get (t_symbol *s=0) {
- FObject::_0_get(argc,argv,s);
- t_atom a[2];
- if (!s) {
- SETFLOAT(a+0,camera.frame_height);
- SETFLOAT(a+1,camera.frame_width);
- outlet_anything(bself->outlets[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; i<height; i++) out->send(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 <fftw3.h>
-
-#define C(x) ((fftwf_complex *)x)
-
-\class GridFFT : FObject {
- fftwf_plan plan;
- P<Dim> 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; i<in->dim->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; i<v[0]; i++) fftwf_execute_dft(plan,C(data)+i*incr,C(tada)+i*incr);
- }
- if (real && sign==-1) {
- for (int i=0; i<v[0]; i++) {
- int h = mod(-i,v[0]);
- T *tada2 = tada + (h*v[1]+v[1]/2)*v[2]*2;
- T *tada3 = tada + (i*v[1]+v[1]/2)*v[2]*2;
- for (int j=1+v[1]/2; j<v[1]; j++) {
- tada2-=v[2]*2; tada3+=v[2]*2;
- for (int k=0; k<v[2]; k++) {tada3[k+k]=tada2[k+k]; tada3[k+k+1]=-tada2[k+k+1];}
- }
- }
- }
- out.send(out.dim->prod(),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 <string>
-#include <map>
-#include <errno.h>
-#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<std::string,std::string> 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; s<suff3; s++) if (*s==' ' || *s==',') *s=0;
- for (char *s=suff2; s<suff3; s+=strlen(s)+1) {
- std::string ss = s;
- suffix_table[ss]=name2;
- }
-}
-
-\class SuffixLookup : FObject {
- \constructor () {}
- \decl 0 symbol (t_symbol *str);
-};
-\def 0 symbol (t_symbol *str) {
- char *s = strdup(str->s_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<std::string,std::string>::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<Dim> 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> 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)<size_t(head.dimn*4)) RAISE("can't read dimension list");
- if (endian != is_le()) swap32(head.dimn,(uint32 *)dimv);
- dim = new Dim(head.dimn,dimv);
- }
- GridOutlet out(this,0,dim,nt);
- long nn = dim->prod();
-#define FOO(T) {T data[nn]; if (fread(data,1,nn*sizeof(T),f)<nn*sizeof(T)) RAISE("can't read grid data (body)"); out.send(nn,(T *)data);}
-TYPESWITCH(nt,FOO,)
-#undef FOO
- SUPER;
-}
-
-GRID_INLET(0) {
- if (!headerless_dim) {
- strncpy(head.magic,is_le()?"\x7fgrid":"\x7fGRID",5);
- switch (in->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; i<n; i++) data2[i]=(T)data[i]; \
- if (endian!=is_le()) swap_endian(n,data2); \
- fwrite(data2,n,sizeof(T),f);}
-TYPESWITCH(in->nt,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; i<argc; i++) v[i] = argv[i];
- headerless_dim = new Dim(argc,v);
-}
-\def 0 headerful () { headerless_dim = 0; }
-//#!@#$ method name conflict ?
-\def 0 type (NumberTypeE nt) {
- //!@#$ bug: should not be able to modify this _during_ a transfer
- switch (nt) {
- case uint8_e: head.type= 8; break;
- case int16_e: head.type=16; break;
- case int32_e: head.type=32; break;
- default: RAISE("unsupported type");
- }
- this->nt = 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 <GL/gl.h>
-/* 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<BitPacking> bit_packing3;
- P<BitPacking> 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<BitPacking> 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; y<v[0]; y++) { \
- uint8 *data = (uint8 *)im.data+im.xsize*im.csize*(yflip?y:sy-1-y); \
- bit_packing->unpack(im.xsize,data,buf); out.send(sxc,buf);}}
- TYPESWITCH(cast,FOO,)
- #undef FOO
- } else {
- for (int y=0; y<v[0]; y++) out.send(sxc,(uint8 *)im.data+sxc*(yflip?y:sy-1-y));
- }
- }
-};
-\def 0 colorspace (t_symbol *s) {
- if (s==gensym("rgb" )) channels=3; else
- if (s==gensym("rgba")) channels=4; else
- RAISE("unknown colorspace '%s'",s->s_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 <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "gridflow.hxx.fcs"
-#include <ctype.h>
-
-//#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; i<n; i++) {
- if (a[i] == delim) {
- int32 v[i];
- if (i!=0 && a[i-1].a_type==A_SYMBOL) nt=NumberTypeE_find(a[--i]);
- for (int j=0; j<i; j++) v[j] = convert(a[j],(int32*)0);
- init(new Dim(i,v),nt);
- CHECK_ALIGN(this->data,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; i<n; i++) p[i] = a[i]; \
- for (int i=n; i<nn; i+=n) COPY(p+i,p,min(n,nn-i)); }}
- TYPESWITCH(nt,FOO,)
-#undef FOO
-}
-
-void Grid::init_from_atom(const t_atom &x) {
- const t_atom2 &a = *(t_atom2 *)&x;
- if (a.a_type==A_LIST) {
- t_binbuf *b = a;
- init_from_list(binbuf_getnatom(b),binbuf_getvec(b));
- } else if (x.a_type==A_FLOAT) {
- init(new Dim(),int32_e);
- CHECK_ALIGN(this->data,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 <class T> 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 <class T> 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> 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; i<inlets.size(); i++) lcm_factor = lcm(lcm_factor,inlets[i]->factor());
- //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; i<inlets.size(); i++) text << " " << (void *)inlets[i]->parent;
- post("%s",text.str().data());
-#endif
-}
-
-// send modifies dex; send_direct doesn't
-template <class T>
-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; i<inlets.size(); i++) try {inlets[i]->flow(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 <class T, class S>
-static void convert_number_type(int n, T *out, S *in) {for (int i=0; i<n; i++) out[i]=(T)in[i];}
-
-//!@#$ buffering in outlet still is 8x faster...?
-//!@#$ should use BitPacking for conversion...?
-// send modifies dex; send_direct doesn't
-template <class T>
-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; i<inlets.size(); i++) inlets[i]->finish();
- 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 <ctype.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <errno.h>
-#include <signal.h>
-#include <setjmp.h>
-#include <stdlib.h>
-//#include <cstdlib>
-#include <sys/stat.h>
-#include <time.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <limits.h>
-
-#ifndef HAVE_DESIREDATA
-#include "bundled/g_canvas.h"
-#endif
-
-/* for exception-handling in 0.9.0... Linux-only */
-#ifndef MACOSX
-#include <exception>
-#include <execinfo.h>
-#endif
-#undef check
-
-std::map<string,FClass *> fclasses;
-std::map<t_class *,FClass *> 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; i<argc; i++) {
- t_atomtype t = argv[i].a_type;
- if (t==A_FLOAT) o << argv[i].a_float;
- else if (t==A_SYMBOL) o << argv[i].a_symbol->s_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; i<n; i++) if (v[i]<0) RAISE("Dim: negative dimension");
-}
-
-// !@#$ big leak machine?
-// returns a string like "Dim[240,320,3]"
-char *Dim::to_s() {
- // if you blow 256 chars it's your own fault
- char buf[256];
- char *s = buf;
- s += sprintf(s,"Dim[");
- for(int i=0; i<n; i++) s += sprintf(s,"%s%d", ","+!i, v[i]);
- s += sprintf(s,"]");
- return strdup(buf);
-}
-
-NumberTypeE NumberTypeE_find (string s) {
- if (number_type_dict.find(s)==number_type_dict.end()) RAISE("unknown number type \"%s\"", s.data());
- return number_type_dict[s]->index;
-}
-
-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; i<self->size; 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 <class T>
-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; i<size; i++) hb[i] = highest_bit(mask[i]);
- uint32 span[4]; for (i=0; i<size; i++) span[i] = hb[i] - lowest_bit(mask[i]);
- uint32 chop[4]; for (i=0; i<size; i++) chop[i] = 7-span[i];
- uint32 slide[4]; for (i=0; i<size; i++) slide[i] = hb[i]-span[i];
-
- if (sameorder && size==3) {
- switch(self->bytes) {
- 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; i<self->size; i++, out++) { \
- uint32 t=temp&self->mask[i]; \
- *out = (t<<(7-hb[i]))|(t>>(hb[i]-7));}}
-
-template <class T>
-static void default_unpack(BitPacking *self, long n, uint8 *in, T *out) {TRACE
- int hb[4];
- for (int i=0; i<self->size; 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 <class T>
-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 <class T>
-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 <class T> 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 <class T> 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 <class T> 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 <class T> 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 <class T> 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 <class T>
-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; i<size; i++) {
- if (!(mask[i] == o->mask[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; i<size; i++) this->mask[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 <class T> 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 <class T> 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<string> 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; i<n; i++) {
- string s = gf_data_path[i]+"/"+x;
- if (lstat(s.data(),&dummy)==0) return s;
- }
- return x;
-}
-
-/* **************************************************************** */
-
-#undef pd_class
-#define pd_class(x) (*(t_pd *)x)
-#define pd_classname(x) (fclasses_pd[pd_class(x)]->name.data())
-
-static FMethod funcall_lookup (FClass *fclass, const char *sel) {
- int n = fclass->methodsn;
- for (int i=0; i<n; i++) if (strcmp(fclass->methods[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; i<ac; i++) argv[i+1] = at[i];
- int argc = handle_braces(ac,argv+1);
- SETFLOAT(argv+0,winlet);
- char buf[256];
- sprintf(buf,"_n_%s",selector->s_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; i<argc; i++) argv[i] = at[i];
- argc = handle_braces(argc,argv);
- //pd_post(classsym->s_name,argc,argv);
- int j;
- for (j=0; j<argc; j++) if (argv[j].a_type==A_COMMA) break;
-
- bself->self = 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 (j<argc) {
- j++;
- int k=j;
- for (; j<argc; j++) if (argv[j].a_type==A_COMMA) break;
- if (argv[k].a_type==A_SYMBOL) pd_typedmess((t_pd *)bself,argv[k].a_symbol,j-k-1,argv+k+1);
- }
- return bself;
- } catch (Barf &oozy) {oozy.error(bself); return 0;}
-}
-
-static void BFObject_delete (BFObject *bself) {
- try {delete bself->self;} 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 (ninlets<n) {
- BFProxy **noo = new BFProxy*[n];
- memcpy(noo,inlets,ninlets*sizeof(BFProxy*));
- delete[] inlets;
- inlets = noo;
- while (ninlets<n) {
- BFProxy *p = inlets[ninlets] = (BFProxy *)pd_new(BFProxy_class);
- p->parent = 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 (noutlets<n) {
- t_outlet **noo = new t_outlet*[n>0?n:1];
- memcpy(noo,outlets,noutlets*sizeof(t_outlet*));
- delete[] outlets;
- outlets = noo;
- while (noutlets<n) outlets[noutlets++] = outlet_new(this,&s_anything);
- } else {
- while (noutlets>n) 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; i<n; i++) s << (i ? " " : "[") << at[i];
- s << "]";
- return s.str();
-}
-
-void add_creator2(FClass *fclass, const char *name) {
- fclasses[string(name)] = fclass;
- class_addcreator((t_newmethod)BFObject_new,gensym((char *)name),A_GIMME,0);
-}
-typedef struct _methodentry
-{
- t_symbol *me_name;
- t_gotfn me_fun;
- t_atomtype me_arg[MAXPDARG+1];
-} t_methodentry;
-struct _class {
- t_symbol *c_name; /* name (mostly for error reporting) */
- t_symbol *c_helpname; /* name of help file */
- t_symbol *c_externdir; /* directory extern was loaded from */
- size_t c_size; /* size of an instance */
- t_methodentry *c_methods; /* methods other than bang, etc below */
- int c_nmethod; /* number of methods */
- // ...
-};
-void add_creator3(FClass *fclass, const char *name) {
- fclasses[string(name)] = fclass;
- t_class *c = pd_objectmaker;
- t_symbol *want = gensym(name);
- for (int i=c->c_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; i<ac; ) {
- int close=0;
- if (av[i].a_type==A_SYMBOL) {
- const char *s = av[i].a_symbol->s_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; i<fc->methodsn; 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; i<nSize; i++) fprintf(stderr,"%d: %s\n",i,symbols[i]);
- free(symbols);
-#endif
-}
-
-static t_gobj *canvas_last (t_canvas *self) {
-#ifdef DESIRE
- t_gobj *g = canvas_first(self);
- while (gobj_next(g)) g=gobj_next(g);
-#else
- t_gobj *g = self->gl_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 . <Motion> {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 <vector>
-#include <string>
-#include <sstream>
-#include <map>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <math.h>
-#ifdef __APPLE__
-static inline void *memalign (size_t a, size_t n) {return malloc(n);}
-#else
-#include <malloc.h>
-#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<char *>(s))
-#define sys_vgui(FMT,ARGS...) sys_vgui(const_cast<char *>(FMT),ARGS)
-#define sys_gui(s) sys_gui(const_cast<char *>(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 <class T> static inline T cmp(T a, T b) {return a<b ? -1 : a>b;}
-
-// 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 <class T> 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 <class T> static inline T min(T a, T b) {return a<b?a:b;}
-template <class T> static inline T max(T a, T b) {return a>b?a:b;}
-template <class T> static inline T clip(T a, T lower, T upper) {return a<lower?lower:a>upper?upper:a;}
-//template <class T> 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 <class T> 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 <class T> 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<b) b=t; else a=t;}
- }
- return b<<s;
-}
-
-// least common multiple; this runs in log(a+b) like gcd.
-template <class T> 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)-1)) { x>>=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 <class T> 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; q<n; q++) p += sprintf(p,"%lld ",(long long)ar[q]); \
- post("%s",foo);}
-
-//****************************************************************
-
-struct FObject;
-struct t_atom2;
-typedef void (*FMethod)(FObject *, int, t_atom2 *);
-
-#define BUILTIN_SYMBOLS(MACRO) \
- MACRO(_grid,"grid") MACRO(_bang,"bang") MACRO(_float,"float") \
- MACRO(_list,"list") MACRO(_sharp,"#") \
- MACRO(_in,"in") MACRO(_out,"out")
-
-extern struct BuiltinSymbols {
-#define FOO(_sym_,_str_) t_symbol *_sym_;
-BUILTIN_SYMBOLS(FOO)
-#undef FOO
-} bsym;
-
-struct Numop;
-struct Pointer;
-#define INT(x) convert(x,(int32*)0)
-#define TO(T,x) convert(x,(T*)0)
-
-// trick to be able to define methods in t_atom
-struct t_atom2 : t_atom {
- bool operator == (t_symbol *b) {return this->a_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<A || 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 <class T> T convert(const t_atom &x, T *foo) {const t_atom2 *xx = (const t_atom2 *)&x; return (T)*xx;}
-
-//****************************************************************
-
-//template <class T> class P : T * {};
-//a reference counting pointer class
-template <class T> 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<T> &_p) {p=_p.p; INCR;}
- P<T> &operator = (T * _p) {DECR; p=_p; INCR; return *this;}
- P<T> &operator = (P<T> _p) {DECR; p=_p.p; INCR; return *this;}
- bool operator == (P<T> _p) {return p==_p.p;}
- bool operator != (P<T> _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 <class T> inline void COPY(T *dest, T *src, long n) {
- gfmemcopy((uint8*)dest,(const uint8*)src,n*sizeof(T));
-}
-template <class T> inline void CLEAR(T *dest, long n) {
- memset(dest,0,n*sizeof(T));
-}
-template <class T> 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<Dim> o) {
- if (n!=o->n) return false;
- for (Card i=0; i<n; i++) if (v[i]!=o->v[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 <class T> void pack(long n, T *in, uint8 *out);
- template <class T> 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 <class T>
-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<T> on_##T; \
- NumopOn<T> *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 <class T> inline void map(long n, T *as, T b) {
- on(*as)->map(n,(T *)as,b);}
- template <class T> inline void zip(long n, T *as, T *bs) {
- on(*as)->zip(n,(T *)as,(T *)bs);}
- template <class T> inline void fold(long an, long n, T *as, T *bs) {
- typename NumopOn<T>::Fold f = on(*as)->fold;
- if (!f) RAISE("operator %s does not support fold",name);
- f(an,n,(T *)as,(T *)bs);}
- template <class T> inline void scan(long an, long n, T *as, T *bs) {
- typename NumopOn<T>::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<T> 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<string,NumberType *> number_type_dict;
-extern std::map<string,Numop *> op_dict;
-extern std::map<string,Numop *> 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> dim;
- NumberTypeE nt;
- void *data;
- int state; /* 0:borrowing 1:owning -1:expired(TODO) */
- Grid(P<Dim> 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 <class T> Grid(P<Dim> 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<Dim> 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> 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<Dim> d);
-
-struct PtrGrid : public P<Grid> {
- DimConstraint dc;
- void constrain(DimConstraint dc_) { dc=dc_; }
- P<Grid> next;
- PtrGrid() : P<Grid>(), dc(0), next(0) {}
- PtrGrid(const PtrGrid &_p) : P<Grid>(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;}
-// PtrGrid( P<Grid> _p) : P<Grid>(), dc(0), next(0) {dc=_p.dc; p=_p.p; INCR;}
- PtrGrid( Grid *_p) : P<Grid>(), 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<Grid> _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<Dim> convert(const t_atom &x, P<Dim> *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 <class T> void THISCLASS::grinw_##I (GRIDHANDLER_ARGS(T)) {\
- ((THISCLASS*)in->parent)->grin_##I(in,dex,n,data);}\
- template <class T> 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> 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 <class T> 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 <class T> 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<string,AttrDecl *> 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> dim; // dimensions of the grid being sent
- NumberTypeE nt;
- std::vector<GridInlet *> 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> 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 <class T> 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 <class T> 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<P<GridInlet> > in;
- P<GridOutlet> out;
- FObject(BFObject *bself, MESSAGE) : bself(bself) {bself->self = this;}
- template <class T> void send_out(int outlet, int argc, T *argv) {
- t_atom foo[argc];
- for (int i=0; i<argc; i++) SETFLOAT(&foo[i],argv[i]);
- outlet_list(bself->outlets[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<Dim> a, int ai, P<Dim> 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; i<n; i++) {
- if (a->v[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<string> 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<string,FClass *> 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 <jpeglib.h>
-};
-
-\class FormatJPEG : Format {
- P<BitPacking> 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; n<sy; n++) {
- jpeg_read_scanlines(&djpeg,rows,1);
- out.send(sx*chans,row);
- }
- jpeg_finish_decompress(&djpeg);
- jpeg_destroy_decompress(&djpeg);
-}
-
-\def 0 quality (short quality) {this->quality = 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[ &not _ 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 <stdlib.h>
-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 <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-\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; i<sy; i++) rows[i]=buf+i*sx*channels;
- mpeg3_read_frame(mpeg,rows,0,0,sx,sy,sx,sy,MPEG3_RGB888,track);
- GridOutlet out(this,0,new Dim(sy,sx,channels),cast);
- int bs = out.dim->prod(1);
- for(int y=0; y<sy; y++) out.send(bs,buf+channels*sx*y);
- DELBUF(buf);
-// return INT2NUM(nframe);
-}
-
-\classinfo {install_format("#io.mpeg",4,"mpg mpeg");}
-\end class FormatMPEG3
-void startup_mpeg3 () {
- \startall
-}
diff --git a/externals/gridflow/src/netpbm.cxx b/externals/gridflow/src/netpbm.cxx
deleted file mode 100644
index 32ef5645..00000000
--- a/externals/gridflow/src/netpbm.cxx
+++ /dev/null
@@ -1,117 +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.
-*/
-
-#define NETPBM_INCLUDE_HERE
-#include "gridflow.hxx.fcs"
-
-\class FormatNetPBM : Format {
- struct pam inpam, outpam;
- \grin 0
- \constructor (t_symbol *mode, string filename) {
- Format::_0_open(0,0,mode,filename);
- memset(& inpam,0,sizeof(pam));
- memset(&outpam,0,sizeof(pam));
- }
- \decl 0 bang ();
-};
-\def 0 bang () {
- //inpam.allocation_depth = 3;
- pnm_readpaminit(f, &inpam, /*PAM_STRUCT_SIZE(tuple_type)*/ sizeof(struct pam));
- tuple *tuplerow = pnm_allocpamrow(&inpam);
- if (inpam.depth!=3) RAISE("image has %d channels instead of 3 channels",inpam.depth);
- GridOutlet out(this,0,new Dim(inpam.height,inpam.width,inpam.depth),cast);
- uint8 buf[inpam.width*3];
- for (int i=0; i<inpam.height; i++) {
- pnm_readpamrow(&inpam, tuplerow);
- for (int j=0; j<inpam.width; j++) {
- buf[j*3+0] = tuplerow[j][0];
- buf[j*3+1] = tuplerow[j][1];
- buf[j*3+2] = tuplerow[j][2];
- }
- out.send(inpam.width*inpam.depth,buf);
- }
- pnm_freepamrow(tuplerow);
-}
-GRID_INLET(0) {
- if (in->dim->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; i<n; i+=in->dim->prod(1)) {
- for (int j=0; j<m; j++, data+=3) {
- tuplerow[j][0] = int(data[0]);
- tuplerow[j][1] = int(data[1]);
- tuplerow[j][2] = int(data[2]);
- }
- pnm_writepamrow(&outpam, tuplerow);
- }
- pnm_freepamrow(tuplerow);
-} GRID_FINISH {
- fflush(f);
-} GRID_END
-/* was supposed to be "#io.netpbm" but there's backwards compat. */
-\classinfo {install_format("#io.ppm",6,"ppm pgm pnm pam");}
-\end class FormatNetPBM
-
-/*FormatPPM.subclass("#io:tk",1,1) {
- install_rgrid 0
- def initialize(mode)
- @id = sprintf("x%08x",object_id)
- @filename = "/tmp/tk-#{$$}-#{@id}.ppm"
- if mode!=:out then raise "only #out" end
- super(mode,:file,@filename)
- GridFlow.gui "toplevel .#{@id}\n"
- GridFlow.gui "wm title . GridFlow/Tk\n"
- GridFlow.gui "image create photo gf#{@id} -width 320 -height 240\n"
- GridFlow.gui "pack [label .#{@id}.im -image #{@id}]\n"
- end
- def _0_rgrid_end
- super
- @stream.seek 0,IO::SEEK_SET
- GridFlow.gui "image create photo #{@id} -file #{@filename}\n"
- end
- def delete
- GridFlow.gui "destroy .#{@id}\n"
- GridFlow.gui "image delete #{@id}\n"
- end
- alias close delete
-}*/
-
-void startup_netpbm () {
- pm_init(0,0);
- \startall
-}
diff --git a/externals/gridflow/src/number.cxx b/externals/gridflow/src/number.cxx
deleted file mode 100644
index 00acb645..00000000
--- a/externals/gridflow/src/number.cxx
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- $Id: number.c 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.
-*/
-
-#include "gridflow.hxx.fcs"
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <limits.h>
-#include <complex>
-#include <assert.h>
-//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 T> 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 O, class T> class OpLoops: public NumopOn<T> {
-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<an; i++, bs++) as[i] = f(as[i],*bs);}}}
- #undef W
- #undef Z
- static void _scan (long an, long n, T *as, T *bs) {
- for (; n--; as=bs-an) {
- for (int i=0; i<an; i++, as++, bs++) *bs=f(*as,*bs);
- }
- }
-};
-
-template <class T>
-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 <class T> static void quick_ign_map (long n, T *as, T b) {}
-template <class T> static void quick_ign_zip (long n, T *as, T *bs) {}
-template <class T> 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 <class T> 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 T> class Y##op : Op<T> { public: \
- DEF_OP_COMMON(op,expr,neu,isneu,isorb,T);};
-#define DEF_OPFT(op,expr,neu,isneu,isorb,T) template <> class Y##op<T> : Op<T> { 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<Y##O<T>,T>
-#define VOL(O,T) OpLoops<Y##O<Plex<T> >,Plex<T> >
-#define DECL_OPON(L,O,T) NumopOn<T>( \
- (NumopOn<T>::Map) L(O,T)::_map, (NumopOn<T>::Zip) L(O,T)::_zip, \
- (NumopOn<T>::Fold)L(O,T)::_fold, (NumopOn<T>::Scan)L(O,T)::_scan, \
- &Y##O<T>::neutral, &Y##O<T>::is_neutral, &Y##O<T>::is_absorbent)
-#define DECL_OPON_NOFOLD(L,O,T) NumopOn<T>( \
- (NumopOn<T>::Map)L(O,T)::_map, (NumopOn<T>::Zip)L(O,T)::_zip, 0,0, \
- &Y##O<T>::neutral, &Y##O<T>::is_neutral, &Y##O<T>::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<float32>() NONLITE(,NumopOn<float64>()), flags,dim)
-// NONLITE(,M(L,O,int64),NumopOn<float32>(),NumopOn<float64>()), flags,dim)
-#define DECLOP_FLOAT( L,M,O,sym,flags,dim) Numop(sym,NumopOn<uint8>(),NumopOn<int16>(),NumopOn<int32>() \
- NONLITE(,NumopOn<int64>()),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 <class T> static inline T gf_floor (T a) {
- return (T) floor((double)a); }
-template <class T> 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_OPF(shr, 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<<b)|((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 <class T> 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 <class T> inline Plex<T> cx_sqsub(const Plex<T>& a, const Plex<T>& b) { Plex<T> v=a-b; return v*v; }
-template <class T> inline Plex<T> cx_abssub(const Plex<T>& a, const Plex<T>& b) { Plex<T> v=a-b; return norm(v); }
-
-template <class T> inline Plex<T> gf_c2p(const Plex<T>& a) {
- return Plex<T>(hypot(a.real(),a.imag()),atan2(a.real(),a.imag())*(18000 / M_PI));
-}
-template <class T> inline Plex<T> gf_p2c(const Plex<T>& a) {
- return Plex<T>((float64)a.real() * sin((float64)a.imag() * (M_PI / 18000)),
- (float64)a.real() * cos((float64)a.imag() * (M_PI / 18000)));
-}
-/*
-template <class T> inline Plex<T> cx_atan2 (Plex<T>& a, Plex<T>& b) {
- if (b==0) return 0;
- Plex<T> 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<p/2?p: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<p/2?p: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<A##_n; i++) D[string(A[i].name)]=&A[i];
-
-#ifdef PASS1
-std::map<string,NumberType *> number_type_dict;
-std::map<string,Numop *> op_dict;
-std::map<string,Numop *> 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; i<COUNT(number_type_table); i++) {
- number_type_table[i].index = (NumberTypeE) i;
- char a[64];
- strcpy(a,number_type_table[i].aliases);
- char *b = strchr(a,',');
- if (b) {
- *b=0;
- number_type_dict[string(b+1)]=&number_type_table[i];
- }
- number_type_dict[string(a)]=&number_type_table[i];
- }
-// S:name; M:mode; F:replacement function;
-#define OVERRIDE_INT(S,M,F) { \
- Numop *foo = op_dict[string(#S)]; \
- foo->on_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 <opencv/cv.h>
-#include <errno.h>
-
-#define cvRelease(euh) cvRelease((void **)(euh))
-#define binbuf_addv(SELF,FMT,ARGS...) binbuf_addv(SELF,const_cast<char *>(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<Dim> 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<Dim> 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; i<m; i++) {
- uchar *meuh = cvPtr2D(self,i,0,0);
- switch (e) {
- case CV_8U: out->send(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("<default_face_cascade>",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; i<n; i++) {
- CvRect *r = (CvRect *)cvGetSeqElem(ret,i);
- int32 duh[] = {r->y,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<Dim> 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 <libpng12/png.h>
-};
-
-\class FormatPNG : Format {
- P<BitPacking> 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 <luc@saillard.org>.
- 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 <stdio.h>
-#include <objc/Object.h>
-#include <Cocoa/Cocoa.h>
-
-#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 <class T, class S>
-static void convert_number_type(int n, T *out, S *in) {
- for (int i=0; i<n; i++) out[i]=(T)in[i];
-}
-
-GRID_INLET(0) {
- if (in->dim->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 <QuickTime/QuickTime.h>
-#include <QuickTime/Movies.h>
-#include <QuickTime/QuickTimeComponents.h>
-#include "gridflow.hxx.fcs"
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <CoreServices/CoreServices.h>
-
-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> 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<n; i++) ((uint32 *)buf2)[i] = ((uint32 *)buf)[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> 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<n; i++) {
- bufu32[i+0]=bufu32[i+0]>>8;
- }
- } else {
- for (i=0; i<n&-4; i+=4) {
- bufu32[i+0]=(bufu32[i+0]<<8)+(bufu32[i+0]>>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<n; i++) {
- bufu32[i+0]=(bufu32[i+0]<<8)+(bufu32[i+0]>>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 <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <map>
-#include <vector>
-
-static std::map<string,std::vector<string> *> codecs;
-static std::map<string,string> fourccs;
-
-\class FormatQuickTimeHW : Format {
- quicktime_t *anim;
- int track;
- P<Dim> dim;
- char *codec;
- int colorspace;
- int channels;
- bool started;
- P<Dim> force;
- float64 framerate;
- P<BitPacking> 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<char *>(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<sy; i++) rows[i]=buf+i*sx*channels;
- quicktime_decode_scaled(anim,0,0,sx,sy,sx,sy,colorspace,rows,track);
- GridOutlet out(this,0,new Dim(sy,sx,channels),cast);
- out.send(sy*sx*channels,buf);
- started=true;
-// return INT2NUM(nframe);
-}
-
-//!@#$ should also support symbol values (how?)
-\def 0 parameter (string name, int32 value) {
- int val = value;
- //post("quicktime_set_parameter %s %d",name.data(), val);
- quicktime_set_parameter(anim, const_cast<char *>(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; i<sy; i++) rows[i]=data2+i*sx*channels;
- quicktime_encode_video(anim,rows,track);
- } else {
- for (int i=0; i<sy; i++) rows[i]=(uint8 *)data+i*sx*channels;
- quicktime_encode_video(anim,rows,track);
- }
-} GRID_FINISH {
-} GRID_END
-
-\def 0 codec (string c) {
-#ifdef LQT_VERSION
- char buf[5];
- strncpy(buf,c.data(),4);
- for (int i=c.length(); i<4; i++) buf[i]=' ';
- buf[4]=0;
- if (fourccs.find(string(buf))==fourccs.end())
- RAISE("warning: unknown fourcc '%s'" /*" (%s)"*/, buf /*, rb_str_ptr(rb_inspect(rb_funcall(fourccs,SI(keys),0)))*/);
-#endif
- codec = strdup(buf);
-}
-
-\def 0 colorspace (string c) {
- if (0) {
- } else if (c=="rgb") { channels=3; colorspace=BC_RGB888;
- } else if (c=="rgba") { channels=4; colorspace=BC_RGBA8888;
- } else if (c=="bgr") { channels=3; colorspace=BC_BGR888;
- } else if (c=="bgrn") { channels=4; colorspace=BC_BGR8888;
-// } else if (c=="yuv") { channels=3; colorspace=BC_YUV888;
- } else if (c=="yuva") { channels=4; colorspace=BC_YUVA8888;
- } else if (c=="YUV420P") { channels=3; colorspace=BC_YUV420P;
- } else RAISE("unknown colorspace '%s' (supported: rgb, rgba, bgr, bgrn, yuv, yuva)",c.data());
-}
-
-\def 0 get () {
-/* t_atom a[1];
- SETFLOAT(a,(float)length);
- outlet_anything(bself->te_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; i<n; i++) {
- const lqt_codec_info_t *s = lqt_get_video_codec_info(i);
- if (!s->name) {
- fprintf(stderr,"[#in quicktime]: skipping codec with null name!\n");
- continue;
- }
- string name = string(s->name);
- std::vector<string> *f = new std::vector<string>(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; j<s->num_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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <SDL/SDL.h>
-
-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<char *>(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<<event.button.button);
- else mousem &= ~(128<<event.button.button);
- //post("mousem=%d",mousem);
- report_pointer();
- } break;
- case SDL_MOUSEMOTION: {
- mousey = event.motion.y;
- mousex = event.motion.x;
- report_pointer();
- } break;
- case SDL_VIDEORESIZE: {
- } break;
- }
- }
-}
-
-\class FormatSDL : Format {
- P<BitPacking> bit_packing;
- P<Dim> 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 <class T> void grin_#{i}(GRIDHANDLER_ARGS(T));"
- Out.print "template <class T> 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 <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <linux/videodev.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#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; i++) {
- if ((value & (1<<i)) == 0) continue;
- if (*foo) strcat(foo," | ");
- strcat(foo,table[i]);
- }
- if (!*foo) strcat(foo,"0");
- return strdup(foo);
-}
-static char *choice_to_s(int value, int n, const char **table) {
- if (value < 0 || value >= 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; i<self->frames; 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<BitPacking> bit_packing;
- P<Dim> 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<sy; y++) {
- uint8 *bufy = buf+sx* y;
- uint8 *bufu = buf+sx*sy +(sx/2)*(y/2);
- uint8 *bufv = buf+sx*sy*5/4+(sx/2)*(y/2);
- int Y1,Y2,U,V;
- for (int x=0,xx=0; x<sx; x+=2,xx+=6) {
- Y1=bufy[x] - 16;
- Y2=bufy[x+1] - 16;
- U=bufu[x/2] - 128;
- V=bufv[x/2] - 128;
- b2[xx+0]=clip((298*Y1 + 409*V)>>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<sy; y++) {
- uint8 *bufy = buf+sx* y;
- uint8 *bufu = buf+sx*sy +(sx/2)*(y/2);
- uint8 *bufv = buf+sx*sy*5/4+(sx/2)*(y/2);
- int U,V;
- for (int x=0,xx=0; x<sx; x+=2,xx+=6) {
- U=bufu[x/2];
- V=bufv[x/2];
- b2[xx+0]=clip(((bufy[x+0]-16)*298)>>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; y<sy; y++) {
- uint8 *bufy = buf +4*sx*y;
- uint8 *bufu = buf+4*sx*sy+ sx*y;
- uint8 *bufv = buf+5*sx*sy+ sx*y;
- for (int x=0,xx=0; x<sx; x++,xx+=3) {
- b2[xx+0]=bufy[x+x];
- b2[xx+1]=bufu[x];
- b2[xx+2]=bufv[x];
- }
- out.send(bs,b2);
- }
- }
- } else if (vp.palette==VIDEO_PALETTE_RGB32 || vp.palette==VIDEO_PALETTE_RGB24 || vp.palette==VIDEO_PALETTE_RGB565) {
- GridOutlet out(this,0,dim,cast);
- uint8 rgb[sx*3];
- uint8 b2[sx*3];
- if (cs=="y") {
- for(int y=0; y<sy; y++) {
- bit_packing->unpack(sx,buf+y*sx*bit_packing->bytes,rgb);
- for (int x=0,xx=0; x<sx; x+=2,xx+=6) {
- b2[x+0] = (76*rgb[xx+0]+150*rgb[xx+1]+29*rgb[xx+2])>>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; y<sy; y++) {
- bit_packing->unpack(sx,buf+y*sx*bit_packing->bytes,rgb);
- out.send(bs,rgb);
- }
- } else if (cs=="yuv") {
- for(int y=0; y<sy; y++) {
- bit_packing->unpack(sx,buf+y*sx*bit_packing->bytes,rgb);
- for (int x=0,xx=0; x<sx; x+=2,xx+=6) {
- b2[xx+0] = clip( (( 76*rgb[xx+0] + 150*rgb[xx+1] + 29*rgb[xx+2])>>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<queuemax) frame_ask();
- vmmap.frame = queue[0];
- //uint64 t0 = gf_timeofday();
- WIOCTL2(fd, VIDIOCSYNC, &vmmap);
- //uint64 t1 = gf_timeofday();
- //if (t1-t0 > 100) gfpost("VIDIOCSYNC delay: %d us",t1-t0);
- frame_finished(image+vmbuf.offsets[queue[0]]);
- queuesize--;
- for (int i=0; i<queuesize; i++) queue[i]=queue[i+1];
- frame_ask();
-}
-
-GRID_INLET(0) {
- RAISE("can't write.");
-} GRID_FLOW {
-} GRID_FINISH {
-} GRID_END
-
-\def 0 norm (int value) {
- VideoTuner vtuner;
- vtuner.tuner = current_tuner;
- if (value<0 || value>3) 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<<VIDEO_PALETTE_RGB24)) ? VIDEO_PALETTE_RGB24 :
- (palettes&(1<<VIDEO_PALETTE_RGB32)) ? VIDEO_PALETTE_RGB32 :
- (palettes&(1<<VIDEO_PALETTE_RGB565)) ? VIDEO_PALETTE_RGB565 :
- VIDEO_PALETTE_YUV420P;
- vp.palette = palette;
- WIOCTL(fd, VIDIOCSPICT, &vp);
- WIOCTL(fd, VIDIOCGPICT, &vp);
- if (vp.palette != palette) {
- post("this driver is unsupported: it wants palette %d instead of %d",vp.palette,palette);
- return;
- }
- if (palette == VIDEO_PALETTE_RGB565) {
- //uint32 masks[3] = { 0x00fc00,0x003e00,0x00001f };
- uint32 masks[3] = { 0x00f800,0x007e0,0x00001f };
- bit_packing = new BitPacking(is_le(),2,3,masks);
- } else if (palette == VIDEO_PALETTE_RGB32) {
- uint32 masks[3] = { 0xff0000,0x00ff00,0x0000ff };
- bit_packing = new BitPacking(is_le(),4,3,masks);
- } else {
- uint32 masks[3] = { 0xff0000,0x00ff00,0x0000ff };
- bit_packing = new BitPacking(is_le(),3,3,masks);
- }
- this->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<sizeof(checklist)/sizeof(*checklist); i++) {
- int p = checklist[i];
-#else
- for (size_t p=0; p<17; p++) {
-#endif
- vp.palette = p;
- ioctl(fd, VIDIOCSPICT,&vp);
- ioctl(fd, VIDIOCGPICT,&vp);
- if (vp.palette == p) {
- palettes |= 1<<p;
- post("palette %d supported",p);
- }
- }
- _0_colorspace(0,0,gensym("rgb"));
- _0_channel(0,0,0);
-}
-
-\end class FormatVideoDev {install_format("#io.videodev",4,"");}
-void startup_videodev () {
- \startall
-}
diff --git a/externals/gridflow/src/x11.cxx b/externals/gridflow/src/x11.cxx
deleted file mode 100644
index 46778089..00000000
--- a/externals/gridflow/src/x11.cxx
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- $Id: x11.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.
-
- Note: some of the code was adapted from PDP's (the XVideo stuff).
-*/
-#include "gridflow.hxx.fcs"
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <string>
-#include <sys/time.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-//#include <X11/StringDefs.h>
-#ifdef HAVE_X11_SHARED_MEMORY
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <X11/extensions/XShm.h>
-#endif
-#ifdef HAVE_X11_XVIDEO
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvlib.h>
-#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<BitPacking> bit_packing;
- P<Dim> 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 <class T> 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;i++) {
- if (argv[i]==gensym("override_redirect")) override_redirect = true;
- else if (argv[i]==gensym("use_stripes")) use_stripes = true;
- else break; /*RAISE("argument '%s' not recognized",string(argv[i]).data());*/
- }
- pos[1]=pos[0]=0;
- parent = root_window;
- if (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<<eb->button;
- report_pointer(eb->y,eb->x,eb->state);
- }break;
- case ButtonRelease:{
- XButtonEvent *eb = (XButtonEvent *)&e;
- eb->state &= ~(128<<eb->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<char *>(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; y<sy; y++) {
- uint8 *b1 = image + ximage->bytes_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; j<ai[i].num_ports; j++) {
- if (Success != XvGrabPort(display,ai[i].base_id+j,CurrentTime)) RAISE("XvGrabPort problem");
- xv_port = ai[i].base_id + j;
- goto breakout;
- }
- }
- }
- breakout:
- XFree(ai);
- if (!xv_port) RAISE("no xv_port");
-/*
- unsigned int encn;
- XvEncodingInfo *enc;
- XvQueryEncodings(display,xv_port,&encn,&enc);
- for (i=0; i<encn; i++) post("XvEncodingInfo: name='%s' encoding_id=0x%08x",enc[i].name,enc[i].encoding_id);
- post("pdp_xvideo: grabbed port %d on adaptor %d",xv_port,i);
- size_t size = sx*sy*4;
- data = new uint8[size];
- for (i=0; i<size; i++) data[i]=0;
- xvi = XvCreateImage(display,xv_port,0x51525762,(char *)data,sx,sy);
- last_encoding=-1;
- if (!xvi) RAISE("XvCreateImage problem");
-*/
- }
-#endif
- int status = XInitImage(ximage);
- if (status!=1) post("XInitImage returned: %d", status);
- return true;
-retry:
- post("couldn't allocate image buffer for output... retrying...");
- return alloc_image(sx,sy);
-}
-
-void FormatX11::dealloc_image () {
- if (!ximage) return;
- if (!shared_memory) {
- XFree(ximage); ximage=0; image=0;
- } else {
-#ifdef HAVE_X11_SHARED_MEMORY
- shmdt(ximage->data);
- 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<sx; x++, i+=3, k=(k+1)%3) {
- image[o+x] = (k<<6) | data[i+k]>>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
-}
-