diff options
author | N.N. <matju@users.sourceforge.net> | 2008-04-28 18:10:15 +0000 |
---|---|---|
committer | N.N. <matju@users.sourceforge.net> | 2008-04-28 18:10:15 +0000 |
commit | 91c0003b158e5f0ed9d0677fb136ae8bb6f86ec5 (patch) | |
tree | d413a48086819f6a2620cd27d030861d122d4f3f /externals/gridflow/format | |
parent | 98dfdfa2fc1c92ba69e33fd77ed3392034297c1f (diff) |
this is an old gridflow, and there's already a svn repository at http://gridflow.ca/svn/trunk
svn path=/trunk/; revision=9739
Diffstat (limited to 'externals/gridflow/format')
-rw-r--r-- | externals/gridflow/format/aalib.c | 168 | ||||
-rw-r--r-- | externals/gridflow/format/dc1394.c | 346 | ||||
-rw-r--r-- | externals/gridflow/format/jpeg.c | 138 | ||||
-rw-r--r-- | externals/gridflow/format/main.rb | 807 | ||||
-rw-r--r-- | externals/gridflow/format/mpeg3.c | 98 | ||||
-rw-r--r-- | externals/gridflow/format/opengl.c | 181 | ||||
-rw-r--r-- | externals/gridflow/format/png.c | 138 | ||||
-rw-r--r-- | externals/gridflow/format/quartz.m | 241 | ||||
-rw-r--r-- | externals/gridflow/format/quicktimeapple.c | 500 | ||||
-rw-r--r-- | externals/gridflow/format/quicktimehw.c | 243 | ||||
-rw-r--r-- | externals/gridflow/format/sdl.c | 123 | ||||
-rw-r--r-- | externals/gridflow/format/videodev.c | 544 | ||||
-rw-r--r-- | externals/gridflow/format/x11.c | 669 |
13 files changed, 0 insertions, 4196 deletions
diff --git a/externals/gridflow/format/aalib.c b/externals/gridflow/format/aalib.c deleted file mode 100644 index cf029dfe..00000000 --- a/externals/gridflow/format/aalib.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - $Id: aalib.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003 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 "../base/grid.h.fcs" -#define aa_hardwareparams aa_hardware_params -#include <aalib.h> - -/* MINNOR is a typo in aalib.h, sorry */ -typedef -#if AA_LIB_MINNOR == 2 - int -#else - enum aa_attribute -#endif -AAAttr; - -\class FormatAALib < Format -struct FormatAALib : Format { - aa_context *context; - aa_renderparams *rparams; - int autodraw; /* as for X11 */ - bool raw_mode; - - FormatAALib () : context(0), autodraw(1) {} - - \decl void initialize (Symbol mode, Symbol target); - \decl void close (); - \decl void _0_hidecursor (); - \decl void _0_print (int y, int x, int a, Symbol text); - \decl void _0_draw (); - \decl void _0_autodraw (int autodraw); - \decl void _0_dump (); - \grin 0 int -}; - -GRID_INLET(FormatAALib,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_factor(in->dim->get(1)*in->dim->get(2)); -} GRID_FLOW { - int f = in->factor(); - if (raw_mode) { - int sx = min(f,aa_scrwidth(context)); - int y = in->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 = in->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 void close () { - if (context) { - aa_close(context); - context=0; - } -} - -\def void _0_hidecursor () { aa_hidemouse(context); } -\def void _0_draw () { aa_flush(context); } -\def void _0_print (int y, int x, int a, Symbol text) { - aa_puts(context,x,y,(AAAttr)a,(char *)rb_sym_name(text)); - if (autodraw==1) aa_flush(context); -} -\def void _0_autodraw (int autodraw) { - if (autodraw<0 || autodraw>1) - RAISE("autodraw=%d is out of range",autodraw); - this->autodraw = autodraw; -} -\def void _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++) { - STACK_ARRAY(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); - } - } -} - -/* !@#$ varargs missing here */ -\def void initialize (Symbol mode, Symbol target) { - rb_call_super(argc,argv); - argc-=2; argv+=2; - char *argv2[argc]; - for (int i=0; i<argc; i++) - argv2[i] = strdup(rb_str_ptr(rb_funcall(argv[i],SI(to_s),0))); - if (mode!=SYM(out)) RAISE("write-only, sorry"); - aa_parseoptions(0,0,&argc,argv2); - for (int i=0; i<argc; i++) free(argv2[i]); - Ruby drivers = rb_ivar_get(rb_obj_class(rself),SI(@drivers)); - Ruby driver_address = rb_hash_aref(drivers,target); - if (driver_address==Qnil) - RAISE("unknown aalib driver '%s'",rb_sym_name(target)); - aa_driver *driver = FIX2PTR(aa_driver,driver_address); - 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}; - gfpost("aalib image size: %s",(new Dim(3,v))->to_s()); -} - -\classinfo { - Ruby drivers = rb_ivar_set(rself,SI(@drivers),rb_hash_new()); - const aa_driver *const *p = aa_drivers; - for (; *p; p++) { - rb_hash_aset(drivers,ID2SYM(rb_intern((*p)->shortname)), PTR2FIX(*p)); - } -// IEVAL(rself,"GridFlow.post('aalib supports: %s', @drivers.keys.join(', '))"); - IEVAL(rself,"install '#in:aalib',1,1;@flags=2;@comment='Ascii Art Library'"); -} -\end class FormatAALib -void startup_aalib () { - \startall -} diff --git a/externals/gridflow/format/dc1394.c b/externals/gridflow/format/dc1394.c deleted file mode 100644 index 5349c231..00000000 --- a/externals/gridflow/format/dc1394.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - $Id: dc1394.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 <libraw1394/raw1394.h> -#include <libdc1394/dc1394_control.h> -#include "../base/grid.h.fcs" - -typedef raw1394handle_t RH; -typedef nodeid_t NID; - -static const int ruby_lineno = __LINE__; -static const char *ruby_code = -\ruby - -def choice(*)end -class CStruct - def initialize(*) end -end - -choice :name,:Speed,:start,0,:values,%w(SPEED_100 SPEED_200 SPEED_400) -choice :name,:Framerate,:start,32,:values, -%w(FRAMERATE_1_875 FRAMERATE_3_75 FRAMERATE_7_5 FRAMERATE_15 - FRAMERATE_30 FRAMERATE_60) - -choice :name,:Format0Mode,:start,64,:values,%w( - MODE_160x120_YUV444 MODE_320x240_YUV422 - MODE_640x480_YUV411 MODE_640x480_YUV422 - MODE_640x480_RGB MODE_640x480_MONO - MODE_640x480_MONO16) - -choice :name,:Format1Mode,:start,96,:values,%w( - MODE_800x600_YUV422 MODE_800x600_RGB - MODE_800x600_MONO MODE_1024x768_YUV422 - MODE_1024x768_RGB MODE_1024x768_MONO - MODE_800x600_MONO16 MODE_1024x768_MONO16) - -choice :name,:Format2Mode,:start,128,:values,%w( - MODE_1280x960_YUV422 MODE_1280x960_RGB - MODE_1280x960_MONO MODE_1600x1200_YUV422 - MODE_1600x1200_RGB MODE_1600x1200_MONO - MODE_1280x960_MONO16 MODE_1600x1200_MONO16) - -choice :name,:Format6Mode,:start,256,:values,%w(MODE_EXIF) - -choice :name,:Format7Mode,:start,288,:values,%w( - MODE_FORMAT7_0 MODE_FORMAT7_1 MODE_FORMAT7_2 MODE_FORMAT7_3 - MODE_FORMAT7_4 MODE_FORMAT7_5 MODE_FORMAT7_6 MODE_FORMAT7_7) - -choice :name,:Format7ColorMode,:start,320,:values,%w( - COLOR_FORMAT7_MONO8 COLOR_FORMAT7_YUV411 - COLOR_FORMAT7_YUV422 COLOR_FORMAT7_YUV444 - COLOR_FORMAT7_RGB8 COLOR_FORMAT7_MONO16 - COLOR_FORMAT7_RGB16) - -choice :name,:TriggerMode,:start,352,:values,%w( - TRIGGER_MODE_0 TRIGGER_MODE_1 TRIGGER_MODE_2 TRIGGER_MODE_3) - -choice :name,:CameraImageFormat,:start,384,:values,%w( - FORMAT_VGA_NONCOMPRESSED FORMAT_SVGA_NONCOMPRESSED_1 - FORMAT_SVGA_NONCOMPRESSED_2 skip 3 - FORMAT_STILL_IMAGE FORMAT_SCALABLE_IMAGE_SIZE) - -choice :name,:CameraFeatures,:start,416,:values,%w( - 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 skip 19 - FEATURE_ZOOM FEATURE_PAN - FEATURE_TILT FEATURE_OPTICAL_FILTER - skip 12 FEATURE_CAPTURE_SIZE - FEATURE_CAPTURE_QUALITY skip 14) - -choice :name,:DCBool,:start,0,:values,%w(False True) - -#define MAX_CHARS 32 -#define SUCCESS 1 -#define FAILURE -1 -#define NO_CAMERA 0xffff - -# Parameter flags for setup_format7_capture() -#define QUERY_FROM_CAMERA -1 -#define USE_MAX_AVAIL -2 -#define USE_RECOMMENDED -3 - -# all dc1394_ prefixes removed -# raw1394handle_t = RH -# nodeid_t = NID -# RH+NID = RN - -CameraInfo = CStruct.new %{ - RH rh; - NID id; - octlet_t ccr_offset; - u_int64_t euid_64; - char vendor[MAX_CHARS + 1]; - char model[MAX_CHARS + 1]; -} - -CameraCapture = CStruct.new %{ - NID node; - int channel, frame_rate, frame_width, frame_height; - int * capture_buffer; - int quadlets_per_frame, quadlets_per_packet; - const unsigned char * dma_ring_buffer; - int dma_buffer_size, dma_frame_size, num_dma_buffers, dma_last_buffer; - const char * dma_device_file; - int dma_fd, port; - struct timeval filltime; - int dma_extra_count; - unsigned char * dma_extra_buffer; - int drop_frames; -} - -MiscInfo = CStruct.new %{ - int format, mode, framerate; - bool is_iso_on; - int iso_channel, iso_speed, mem_channel_number; - int save_channel, load_channel; -} - -FeatureInfo = CStruct.new %{ - uint feature_id; - bool available, one_push, readout_capable, on_off_capable; - bool auto_capable, manual_capable, polarity_capable, one_push_active; - bool is_on, auto_active; - char trigger_mode_capable_mask; - int trigger_mode; - bool trigger_polarity; - int min, max, value, BU_value, RV_value, target_value; -} - -FeatureSet = CStruct.new %{ - FeatureInfo feature[NUM_FEATURES]; -} -#void print_feature_set(FeatureSet *features); -#extern const char *feature_desc[NUM_FEATURES]; -#void print_feature(FeatureInfo *feature); -#RawFire create_handle(int port); -#destroy_handle(RH rh); -#void print_camera_info(camerainfo *info); - -class RH; %{ - # those two: - # Return -1 in numCameras and NULL from the call if there is a problem - # otherwise the number of cameras and the NID array from the call - NID* get_camera_nodes(int *numCameras, int showCameras); - NID* get_sorted_camera_nodes(int numids, int *ids, int *numCameras, int showCameras); - release_camera(CameraCapture *camera); - single_capture(CameraCapture *camera); -# this one returns FAILURE or SUCCESS - multi_capture(CameraCapture *cams, int num); -}end - -class RN; %{ - init_camera(); - is_camera(bool *value); - get_camera_feature_set(FeatureSetFeatureInfo *features); - get_camera_feature(FeatureInfo *feature); - get_camera_misc_info(miscinfo *info); - get_sw_version(quadlet_t *value); - get_camera_info(camerainfo *info); - query_supported_formats(quadlet_t *value); - query_supported_modes(uint format, quadlet_t *value); - query_supported_framerates(uint format, uint mode, quadlet_t *value); - query_revision(int mode, quadlet_t *value); - query_basic_functionality(quadlet_t *value); - query_advanced_feature_offset(quadlet_t *value); - attr set_video_framerate(uint framerate); - attr video_mode(uint mode); - attr video_format(uint format); - double_attr iso_channel_and_speed(uint channel, uint speed); - camera_on(); - camera_off(); - start_iso_transmission(); - stop_iso_transmission(); - get_iso_status(bool *is_on); - set_one_shot(); - unset_one_shot(); - set_multi_shot(uint numFrames); - unset_multi_shot(); -# attributes : -# those are get_/set_ methods where the get has an input parameter -# and the set has an output parameter - attr uint brightness - attr uint exposure - attr uint sharpness - double_attr set_white_balance(uint u_b_value, uint v_r_value); - attr uint hue - attr uint saturation(uint saturation); - attr uint gamma(uint gamma); - attr shutter(uint shutter); - attr uint gain - attr uint iris - attr uint focus - attr uint trigger_mode - attr uint zoom - attr uint pan - attr uint tilt - attr uint optical_filter - attr uint capture_size - attr uint capture_quality - int get_temperature(uint *target_temperature, uint *temperature); - int set_temperature(uint target_temperature); - - get_memory_load_ch(uint *channel); - get_memory_save_ch(uint *channel); - is_memory_save_in_operation(bool *value); - set_memory_save_ch(uint channel); - memory_save(); - memory_load(uint channel); - attr bool trigger_polarity - trigger_has_polarity(bool *polarity); - attr bool set_trigger_on_off - -# this one returns SUCCESS on success, FAILURE otherwise - setup_capture( - int channel, int format, int mode, int speed, int frame_rate, - CameraCapture *camera); - dma_setup_capture( - int channel, int format, int mode, int speed, int frame_rate, - int num_dma_buffers, int drop_frames, const char *dma_device_file, - CameraCapture *camera); - setup_format7_capture( - int channel, int mode, int speed, int bytes_per_packet, - uint left, uint top, uint width, uint height, CameraCapture *camera); - dma_setup_format7_capture( - int channel, int mode, int speed, int bytes_per_packet, - uint left, uint top, uint width, uint height, - int num_dma_buffers, CameraCapture *camera); -}end - -#RNF = RN+uint feature -class RNF; %{ - query_feature_control(uint *availability); - query_feature_characteristics(quadlet_t *value); - attr uint feature_value - is_feature_present(bool *value); - has_one_push_auto(bool *value); - is_one_push_in_operation(bool *value); - start_one_push_operation(); - can_read_out(bool *value); - can_turn_on_off(bool *value); - is_feature_on(bool *value); - feature_on_off(uint value); - has_auto_mode(bool *value); - has_manual_mode(bool *value); - is_feature_auto(bool *value); - auto_on_off(uint value); - get_min_value(uint *value); - get_max_value(uint *value); -}end - -# DMA Capture Functions -#dma_release_camera(RH rh, CameraCapture *camera); -#dma_unlisten(RH rh, CameraCapture *camera); -#dma_single_capture(CameraCapture *camera); -#dma_multi_capture(CameraCapture *cams,int num); -#dma_done_with_buffer(CameraCapture * camera); - -# default return type is int, prolly means SUCCESS/FAILURE - -#RNM = RN+uint mode -class RNM; %{ - query_format7_max_image_size(uint *horizontal_size, uint *vertical_size); - query_format7_unit_size(uint *horizontal_unit, uint *vertical_unit); - query_format7_color_coding(quadlet_t *value); - query_format7_pixel_number(uint *pixnum); - query_format7_total_bytes(uint *total_bytes); - query_format7_packet_para(uint *min_bytes, uint *max_bytes); - query_format7_recommended_byte_per_packet(uint *bpp); - query_format7_packet_per_frame(uint *ppf); - query_format7_unit_position(uint *horizontal_pos, uint *vertical_pos); - # those were query/set pairs. - double_qattr format7_image_position(uint left, uint top); - double_qattr format7_image_size(uint width, uint height); - qattr uint format7_color_coding_id - qattr uint format7_byte_per_packet - query_format7_value_setting(uint *present, uint *setting1, uint *err_flag1, uint *err_flag2); - set_format7_value_setting(); //huh? -}end - -\end ruby -; - -\class FormatDC1394 < Format -struct FormatDC1394 : Format { - \decl void initialize (Symbol mode); - \decl void frame (); -}; - -\def void initialize(Symbol mode) { - gfpost("DC1394: hello world"); - RH rh = raw1394_new_handle(); - int numPorts = raw1394_get_port_info(rh,0,0); - raw1394_destroy_handle(rh); - gfpost("there are %d Feuerweuer ports",numPorts); - if (mode!=SYM(in)) RAISE("sorry, read-only"); - for(int port=0; port<numPorts; port++) { - gfpost("trying port #%d...",port); - RH rh = dc1394_create_handle(port); - int numCameras=0xDEADBEEF; - NID *nodes = dc1394_get_camera_nodes(rh,&numCameras,0); - gfpost("port #%d has %d cameras",port,numCameras); - for (int i=0; i<numCameras; i++) gfpost("camera at node #%d",nodes[i]); - // I'm stuck here, can't find that iSight camera. -- matju - } - dc1394_destroy_handle(rh); -} - -\def void frame () { - gfpost("i'd like to get a frame from the cam, but how?"); -} - -\classinfo { - IEVAL(rself,"install '#io:dc1394',1,1;@flags=4;@comment='Video4linux 1.x'"); - //IEVAL(rself,ruby_code); - rb_funcall(rself,SI(instance_eval),3,rb_str_new2(ruby_code), - rb_str_new2(__FILE__),INT2NUM(ruby_lineno+3)); -} -\end class FormatDC1394 -void startup_dc1394 () { - \startall -} diff --git a/externals/gridflow/format/jpeg.c b/externals/gridflow/format/jpeg.c deleted file mode 100644 index 4363be52..00000000 --- a/externals/gridflow/format/jpeg.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - $Id: jpeg.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 "../base/grid.h.fcs" -/* removing macros (removing warnings) */ -#undef HAVE_PROTOTYPES -#undef HAVE_STDLIB_H -#undef EXTERN -extern "C" { -#include <jpeglib.h> -}; - -\class FormatJPEG < Format -struct FormatJPEG : Format { - P<BitPacking> bit_packing; - struct jpeg_compress_struct cjpeg; - struct jpeg_decompress_struct djpeg; - struct jpeg_error_mgr jerr; - int fd; - FILE *f; - \decl Ruby frame (); - \decl void quality (short quality); - \decl void initialize (Symbol mode, Symbol source, String filename); - \grin 0 int -}; - -GRID_INLET(FormatJPEG,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_factor(in->dim->get(1)*in->dim->get(2)); - 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_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,Pt<uint8>(row,rowsize)); - 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 Ruby frame () { - off_t off = NUM2LONG(rb_funcall(rb_ivar_get(rself,SI(@stream)),SI(tell),0)); - fseek(f,off,SEEK_SET); - if (gfeof(f)) return Qfalse; - 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), - NumberTypeE_find(rb_ivar_get(rself,SI(@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,Pt<uint8>(row,sx*chans)); - } - jpeg_finish_decompress(&djpeg); - jpeg_destroy_decompress(&djpeg); - return Qnil; -} - -\def void quality (short quality) { - quality = min(max((int)quality,0),100); - // should the last arg ("baseline") be set to true ? - // and what is it for? is it for accuracy of the DC component? - jpeg_set_quality(&cjpeg,quality,false); -} - -\def void initialize (Symbol mode, Symbol source, String filename) { - rb_call_super(argc,argv); - if (source!=SYM(file)) RAISE("usage: jpeg file <filename>"); - rb_funcall(rself,SI(raw_open),3,mode,source,filename); - Ruby stream = rb_ivar_get(rself,SI(@stream)); - fd = NUM2INT(rb_funcall(stream,SI(fileno),0)); - f = fdopen(fd,mode==SYM(in)?"r":"w"); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); -} - -\classinfo { - IEVAL(rself, - "install '#io:jpeg',1,1;@mode=6;" - "include GridFlow::EventIO; suffixes_are'jpeg','jpg'"); -} -\end class FormatJPEG -void startup_jpeg () { - \startall -} diff --git a/externals/gridflow/format/main.rb b/externals/gridflow/format/main.rb deleted file mode 100644 index 1cac124f..00000000 --- a/externals/gridflow/format/main.rb +++ /dev/null @@ -1,807 +0,0 @@ -=begin - $Id: main.rb,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 - -require "socket" -require "fcntl" - -module GridFlow - -class<<self - def max_rank; 16; end - def max_size; 64*1024**2; end - def max_packet; 1024*2; end -end - -ENDIAN_BIG,ENDIAN_LITTLE,ENDIAN_SAME,ENDIAN_DIFF = 0,1,2,3 - -OurByteOrder = case [1].pack("L") - when "\0\0\0\1"; ENDIAN_BIG # Mac, Sun, SiliconGraphics - when "\1\0\0\0"; ENDIAN_LITTLE # Intel - else raise "Cannot determine byte order" end - -class Format < GridObject - FF_R,FF_W = 4,2 # flags indicating support of :in and :out respectively. - attr_accessor :parent -=begin API (version 0.8) - 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 frame() : - 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 seek(Integer i) : select one frame to be read next (by number) - def length() : ^Integer returns number of frames (never implemented ?) - def close() : close a handler - inlet 0 : - grid : frame to write - other : special options - outlet 0 : grid : frame just read - outlet 1 : everything else -=end - - def initialize(mode,*) - super - @cast = :int32 - @colorspace = :rgb - @mode = mode - @frame = 0 - @parent = nil - @stream = nil - flags = self.class.instance_eval{if defined?@flags then @flags else 6 end} - # FF_W, FF_R, FF_RW - 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}'" - end - - def close - @stream.close if defined? @stream and @stream - end - - def self.suffixes_are(*suffixes) - suffixes.map{|s|s.split(/[, ]/)}.flatten.each {|suffix| - Format.suffixes[suffix] = self - } - end - - class<<self - attr_reader :symbol_name - attr_reader :description - attr_reader :flags - attr_reader :suffixes - end - @suffixes = {} - def seek frame - (rewind; return) if frame == 0 - raise "don't know how to seek for frame other than # 0" - end - - # this is what you should use to rewind - # different file-sources may redefine this as something else - # (eg: gzip) - def rewind - raise "Nothing to rewind about..." if not @stream - @stream.seek 0,IO::SEEK_SET - @frame = 0 - end - - # This is different from IO#eof, which waits until a read has failed - # doesn't work in nonblocking mode? (I don't recall why) - def eof? - thispos = (@stream.seek 0,IO::SEEK_CUR; @stream.tell) - lastpos = (@stream.seek 0,IO::SEEK_END; @stream.tell) - @stream.seek thispos,IO::SEEK_SET - return thispos == lastpos - rescue Errno::ESPIPE # just ignore if seek is not possible - return false - end - - # "ideal" buffer size or something - # the buffer may be bigger than this but usually not by much. - def self.buffersize; 16384 end - - def _0_headerless(*args) #!@#$ goes in FormatGrid ? - args=args[0] if Array===args[0] - #raise "expecting dimension list..." - args.map! {|a| - Numeric===a or raise "expecting dimension list..." - a.to_i - } - @headerless = args - end - def _0_headerful #!@#$ goes in FormatGrid ? - @headerless = nil - end - def _0_type arg - #!@#$ goes in FormatGrid ? - #!@#$ bug: should not be able to modify this _during_ a transfer - case arg - when :uint8; @bpv=8; @bp=BitPacking.new(ENDIAN_LITTLE,1,[0xff]) - when :int16; @bpv=16; @bp=BitPacking.new(ENDIAN_LITTLE,1,[0xffff]) - when :int32; @bpv=32; @bp=nil - else raise "unsupported number type: #{arg}" - end - end - def _0_cast arg - case arg - when :uint8, :int16, :int32, :int64, :float32, :float64 - @cast = arg - else raise "unsupported number type: #{arg}" - end - end - def frame; @frame+=1; @frame-1 end -end - -# common parts between GridIn and GridOut -module GridIO - def check_file_open; if not @format then raise "can't do that: file not open" end end - def _0_close; check_file_open; @format.close; @format = nil end - def delete; @format.close if @format; @format = nil; super end - attr_reader :format - - def _0_open(sym,*a) - sym = sym.intern if String===sym - if a.length==0 and /\./ =~ sym.to_s then a=[sym]; sym=:file end - qlass = GridFlow.fclasses["\#io:#{sym}"] - if not qlass then raise "unknown file format identifier: #{sym}" end - _0_close if @format - @format = qlass.new @mode, *a - @format.connect 0,self,1 - @format.connect 1,self,2 - @format.parent = self - @loop = true - end - - def _0_timelog flag; @timelog = Integer(flag)!=0 end - def _0_loop flag; @loop = Integer(flag)!=0 end - def method_missing(*message) - sel = message[0].to_s - if sel =~ /^_0_/ - message[0] = sel.sub(/^_0_/,"").intern - @format.send_in 0, *message - elsif sel =~ /^_2_/ - sel = sel.sub(/^_2_/,"").intern - message.shift - send_out 1, sel, *message - else - return super - end - end -end - -GridObject.subclass("#in",1,2) { - install_rgrid 0 - include GridIO - def initialize(*a) - super - @format = nil - @timelog = false - @framecount = 0 - @time = Time.new - @mode = :in - return if a.length==0 - _0_open(*a) - end - def _0_bang - check_file_open - framenum = @format.frame - if framenum == false - send_out 1 - return if not @loop - @format.seek 0 - framenum = @format.frame - if framenum == false - raise "can't read frame: the end is at the beginning???" - end - end - send_out 1, framenum if framenum - end - def _0_float frame; _0_set frame; _0_bang end - def _0_set frame; check_file_open; @format.seek frame end - def _0_reset; check_file_open; @format.seek 0; end - def _1_grid(*a) send_out 0,:grid,*a end - def _0_load(*a); _0_open(*a); _0_bang; _0_close end -} - -GridObject.subclass("#out",1,1) { - include GridIO - def initialize(*a) - super - @format = nil - @timelog = false - @framecount = 0 - @time = Time.new - @mode = :out - return if a.length==0 - if Integer===a[0] or Float===a[0] - _0_open :x11,:here - _0_out_size a[0],a[1] - else - _0_open(*a) - end - end - - def _0_list(*a) @format._0_list(*a) end - - # hacks - def _1_grid(*a) send_out 0,:grid,*a end # for aalib - def _1_position(*a) send_out 0,:position,*a end - def _1_keypress(*a) send_out 0,:keypress,*a end - def _1_keyrelease(*a) send_out 0,:keyrelease,*a end - - def _0_grid(*a) - check_file_open - @format._0_grid(*a) - send_out 0,:bang - log if @timelog - @framecount+=1 - end - - def log - time = Time.new - post("\#out: frame#%04d time: %10.3f s; diff: %5d ms", - @framecount, time, ((time-@time)*1000).to_i) - @time = time - end - install_rgrid 0 -} - -class BitPacking - alias pack pack2 - alias unpack unpack2 -end - -# adding event-driven IO to a Format class -module EventIO - def read_wait?; !!@action; end - - def initialize(*) - @acceptor = nil - @buffer = nil - @action = nil - @chunksize = nil - @rewind_redefined = false - @clock = Clock.new self - @delay = 100 # ms - super - end - - def call() try_read end - - def on_read(n,&action) - @action = action - @chunksize = n - end - - def try_accept - #!@#$ use setsockopt(SO_REUSEADDR) here??? - TCPSocket.do_not_reverse_lookup = true # hack - @acceptor.nonblock = true - @stream = @acceptor.accept - @stream.nonblock = true - @stream.sync = true - @clock.unset -# send_out 0, :accept # does not work - rescue Errno::EAGAIN - end - - def try_read(dummy=nil) - n = @chunksize-(if @buffer then @buffer.length else 0 end) - t = @stream.read(n) # or raise EOFError - if not t - raise "heck" if not @stream.eof? - rewind - t = @stream.read(n) or raise "can't read any of #{n} bytes?" - end - if @buffer then @buffer << t else @buffer = t end - if @buffer.length == @chunksize - action,buffer = @action,@buffer - @action,@buffer = nil,"" - @clock.unset - action.call buffer - end - rescue Errno::EAGAIN - post "read would block" - end - - def raw_open_gzip_in(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" - end - end - def raw_open_gzip_out(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 - end - def raw_open(mode,source,*args) - @raw_open_args = mode,source,*args - fmode = case mode - when :in; "r" - when :out; "w" - else raise "bad mode" end - @stream.close if @stream - case source - when :file - filename = args[0].to_s - filename = GridFlow.find_file filename if mode==:in - @stream = File.open filename, fmode - when :gzfile - filename = args[0].to_s - filename = GridFlow.find_file filename if mode==:in - if mode==:in then - raw_open_gzip_in filename - else - raw_open_gzip_out filename - end - def self.rewind - raw_open(*@raw_open_args) - @frame = 0 - end unless @rewind_redefined - @rewind_redefined = true - when :tcp - if RUBY_VERSION < "1.6.6" - raise "use at least 1.6.6 (reason: bug in socket code)" - end - post "-----------" - time = Time.new - TCPSocket.do_not_reverse_lookup = true # hack - @stream = TCPSocket.open(args[0].to_s,args[1].to_i) - post "----------- #{Time.new-time}" - @stream.nonblock = true - @stream.sync = true - @clock.delay @delay - when :tcpserver - TCPSocket.do_not_reverse_lookup = true # hack - TCPServer.do_not_reverse_lookup = true # hack - post "-----------" - time = Time.new - @acceptor = TCPServer.open(args[0].to_s) - post "----------- #{Time.new-time}" - @acceptor.nonblock = true - #$tasks[self] = proc {self.try_accept} #!!!!! - else - raise "unknown access method '#{source}'" - end - end - def close - @acceptor.close if @acceptor - @stream.close if @stream - GridFlow.hunt_zombies - end -end - -Format.subclass("#io:file",1,1) { - def self.new(mode,file) - file=file.to_s - a = [mode,:file,file] - if not /\./=~file then raise "no filename suffix?" end - suf=file.split(/\./)[-1] - h=Format.suffixes[suf] - if not h then raise "unknown suffix '.#{suf}'" end - h.new(*a) - end - @comment="format autodetection proxy" -} - -Format.subclass("#io:grid",1,1) { - include EventIO - install_rgrid 0 - @comment = "GridFlow file format" - suffixes_are "grid" -=begin - This is the Grid format I defined: - 1 uint8: 0x7f - 4 uint8: "GRID" big endian | "grid" little endian - 1 uint8: type { - number of bits in 8,16,32,64, plus one of: 1:unsigned 2:float - but float8,float16 are not allowed (!) - } - 1 uint8: reserved (supported: 0) - 1 uint8: number of dimensions N (supported: at least 0..4) - N uint32: number of elements per dimension D[0]..D[N-1] - raw data goes there. -=end - # bits per value: 32 only - attr_accessor :bpv # Fixnum: bits-per-value - # endianness - # attr_accessor :endian # ENDIAN_LITTLE or ENDIAN_BIG - # IO or File or TCPSocket - attr_reader :stream - # nil=headerful; array=assumed dimensions of received grids - #attr_accessor :headerless - - def initialize(mode,source,*args) - super - @bpv = 32 - @headerless = nil - @endian = OurByteOrder - raw_open mode,source,*args - end - - def post(*s) - # because i'm using miller_0_38 and it can't disable the console - # i am using fprintf stderr instead of post. - ### STDERR.puts(sprintf(*s)) - # disabled because i don't need it now - end - - # rewinding and starting - def frame - raise "can't get frame when there is no connection" if not @stream - raise "already waiting for input" if read_wait? - return false if eof? - post "----- 1" - if @headerless then - @n_dim=@headerless.length - @dim = @headerless - @dex = 0 - set_bufsize - send_out_grid_begin 0, @dim - on_read(bufsize) {|data| frame3 data } - else - on_read(8) {|data| frame1 data } - end - post "----- 2" - (try_read nil while read_wait?) if not TCPSocket===@stream - post "----- 3" - super - post "----- 4" - end - - def set_bufsize - @prod = 1 - @dim.each {|x| @prod *= x } - n = @prod/@dim[0] - k = GridFlow.max_packet / n - k=1 if k<1 - @bufsize = k*n*@bpv/8 - @bufsize = @prod if @bufsize > @prod - end - - # the header - def frame1 data - post "----- frame1" - head,@bpv,reserved,@n_dim = data.unpack "a5ccc" - @endian = case head - when "\x7fGRID"; ENDIAN_BIG - when "\x7fgrid"; ENDIAN_LITTLE - else raise "grid header: invalid (#{data.inspect})" end - case bpv - when 8, 16, 32; # ok - else raise "unsupported bpv (#{@bpv})" - end - if reserved!=0 - raise "reserved field is not zero" - end - if @n_dim > GridFlow.max_rank - raise "too many dimensions (#{@n_dim})" - end - on_read(4*@n_dim) {|data| frame2 data } - end - - # the dimension list - def frame2 data - post "----- frame2" - @dim = data.unpack(if @endian==ENDIAN_LITTLE then "V*" else "N*" end) - set_bufsize - if @prod > GridFlow.max_size - raise "dimension list: invalid prod (#{@prod})" - end - send_out_grid_begin 0, @dim, @cast - - on_read(bufsize) {|data| frame3 data } - @dex = 0 - end - - attr_reader :bufsize - - # for each slice of the body - def frame3 data - post "----- frame3 with dex=#{@dex.inspect}, prod=#{@prod.inspect}" - n = data.length - nn = n*8/@bpv - # is/was there a problem with the size of the data being read? - case @bpv - when 8 - @bp = BitPacking.new(@endian,1,[0xff]) - send_out_grid_flow(0, @bp.unpack(data)) - @dex += data.length - when 16 - @bp = BitPacking.new(@endian,2,[0xffff]) - send_out_grid_flow(0, @bp.unpack(data)) - @dex += data.length/2 - when 32 - data.swap32! if @endian!=OurByteOrder - send_out_grid_flow 0, data - @dex += data.length/4 - end - if @dex >= @prod - @clock.unset - else - on_read(bufsize) {|data| frame3 data } - end - end - - def _0_rgrid_begin - if not @stream - raise "can't send frame when there is no connection" - end - @dim = inlet_dim 0 - post "@dim=#{@dim.inspect}" - return if @headerless - # header - @stream.write( - [if @endian==ENDIAN_LITTLE then "\x7fgrid" else "\x7fGRID" end, - @bpv,0,@dim.length].pack("a5ccc")) - # dimension list - @stream.write( - @dim.to_a.pack(if @endian==ENDIAN_LITTLE then "V*" else "N*" end)) - end - - def _0_rgrid_flow data - case @bpv - when 8, 16 - @stream.write @bp.pack(data) - when 32 - data.swap32! if GridFlow::OurByteOrder != @endian - @stream.write data - end - end - - def _0_rgrid_end; @stream.flush end - - def endian(a) - @endian = case a - when :little; ENDIAN_LITTLE - when :big; ENDIAN_BIG - when :same; ENDIAN_SAME - else raise "argh" - end - end - - def headerless(*args) - args=args[0] if Array===args[0] - args.map! {|a| - Numeric===a or raise "expecting dimension list..." - a.to_i - } - @headerless = args - end - - def headerful; @headerless = nil end - - #!@#$ method name conflict ? - def type(nt) - #!@#$ bug: should not be able to modify this _during_ a transfer - case nt - when :uint8; @bpv= 8; @bp=BitPacking.new(ENDIAN_LITTLE,1,[0xff]) - when :int16; @bpv=16; @bp=BitPacking.new(ENDIAN_LITTLE,1,[0xffff]) - when :int32; @bpv=32; @bp=nil - else raise "unsupported number type" - end - end -} - -module PPMandTarga - # "and false" disables features that may cause crashes and don't - # accelerate gridflow that much. - def frame_read_body height, width, channels - bs = width*channels - n = bs*height - bs = (self.class.buffersize/bs)*bs+bs # smallest multiple of bs over BufferSize - buf = "" - if RUBY_VERSION >= "1.8.0" and false - data = "x"*bs # must preallocate (bug in 1.8.0.pre1-3) - while n>0 do - bs=n if bs>n - @stream.read(bs,data) or raise EOFError - if @bp then - send_out_grid_flow 0, @bp.unpack(data,buf) - else - send_out_grid_flow 0, data, :uint8 - end - n-=bs - end - else - nothing = "" - while n>0 do - bs=n if bs>n - data = @stream.read(bs) or raise EOFError - if @bp then - send_out_grid_flow 0, @bp.unpack(data,buf) - else - send_out_grid_flow 0, data, :uint8 - end - data.replace nothing and false # prevent clogging memory - n-=bs - end - end - end -end - -Format.subclass("#io:ppm",1,1) { - install_rgrid 0 - @comment = "Portable PixMap (PPM) File Format" - suffixes_are "ppm" - include EventIO, PPMandTarga - - def initialize(mode,source,*args) - @bp = if mode==:out - BitPacking.new(ENDIAN_LITTLE,3,[0x0000ff,0x00ff00,0xff0000]) - else nil end - super - raw_open mode,source,*args - end - def frame - #@stream.sync = false - metrics=[] - return false if eof? - line = @stream.gets - (rewind; line = @stream.gets) if not line # hack - line.chomp! - if line != "P6" then raise "Wrong format (needing PPM P6)" end - while metrics.length<3 - line = @stream.gets - next if line =~ /^#/ - metrics.push(*(line.split(/\s+/).map{|x| Integer x })) - end - metrics[2]==255 or - raise "Wrong color depth (max_value=#{metrics[2]} instead of 255)" - - send_out_grid_begin 0, [metrics[1], metrics[0], 3], @cast - frame_read_body metrics[1], metrics[0], 3 - super - end - - def _0_rgrid_begin - dim = inlet_dim 0 - raise "expecting (rows,columns,channels)" if dim.length!=3 - raise "expecting channels=3" if dim[2]!=3 - @stream.write "P6\n" - @stream.write "# generated using GridFlow #{GF_VERSION}\n" - @stream.write "#{dim[1]} #{dim[0]}\n255\n" - @stream.flush - inlet_set_factor 0, 3 - end - def _0_rgrid_flow(data) @stream.write @bp.pack(data) end - def _0_rgrid_end; @stream.flush end - self -}.subclass("#io:tk",1,1) { - install_rgrid 0 - def initialize(mode) - if mode!=:out then raise "only #out" end - super(mode,:file,"/tmp/tk-#{$$}-#{object_id}.ppm") - GridFlow.gui "toplevel .#{object_id}\n" - GridFlow.gui "wm title . GridFlow/Tk\n" - GridFlow.gui "image create photo #{object_id} -width 320 -height 240\n" - GridFlow.gui "pack [label .#{object_id}.im -image #{object_id}]\n" - end - def _0_rgrid_end - super - @stream.seek 0,IO::SEEK_SET - GridFlow.gui "image create photo #{object_id} -file /tmp/tk-#{$$}-#{object_id}.ppm\n" - end - def delete - GridFlow.gui "destroy .#{object_id}\n" - GridFlow.gui "image delete #{object_id}\n" - end - alias close delete -} - -Format.subclass("#io:targa",1,1) { - install_rgrid 0 - @comment = "TrueVision Targa" - suffixes_are "tga" - include EventIO, PPMandTarga -=begin -targa header is like: - [:comment, Uint8, :length], - [:colortype, Uint8], - [:colors, Uint8], 5, - [:origin_x, Int16], - [:origin_y, Int16], - [:w, Uint16], - [:h, Uint16], - [:depth, Uint8], 1, - [:comment, String8Unpadded, :data], -=end - def initialize(mode,source,*args) - super - raw_open mode,source,*args - end - - def set_bitpacking depth - @bp = case depth - #!@#$ endian here doesn't seem to be changing much ? - when 24; BitPacking.new(ENDIAN_LITTLE,3,[0xff0000,0x00ff00,0x0000ff]) - when 32; BitPacking.new(ENDIAN_LITTLE,4, - [0x00ff0000,0x0000ff00,0x000000ff,0xff000000]) - else - raise "tga: unsupported colour depth: #{depth}\n" - end - end - - def frame - return false if eof? - head = @stream.read(18) - comment_length,colortype,colors,w,h,depth = head.unpack("cccx9vvcx") - comment = @stream.read(comment_length) - raise "unsupported color format: #{colors}" if colors != 2 -# post "tga: size y=#{h} x=#{w} depth=#{depth} colortype=#{colortype}" -# post "tga: comment: \"#{comment}\"" - set_bitpacking depth - send_out_grid_begin 0, [ h, w, depth/8 ], @cast - frame_read_body h, w, depth/8 - super - end - - def _0_rgrid_begin - dim = inlet_dim 0 - raise "expecting (rows,columns,channels)" if dim.length!=3 - raise "expecting channels=3 or 4" if dim[2]!=3 and dim[2]!=4 - # comment = "created using GridFlow" - #!@#$ why did i use that comment again? - comment = "generated using GridFlow #{GF_VERSION}" - @stream.write [comment.length,colortype=0,colors=2,"\0"*9, - dim[1],dim[0],8*dim[2],(8*(dim[2]-3))|32,comment].pack("ccca9vvcca*") - set_bitpacking 8*dim[2] - inlet_set_factor 0, dim[2] - end - def _0_rgrid_flow data; @stream.write @bp.pack(data) end - def _0_rgrid_end; @stream.flush end -} -end # module GridFlow diff --git a/externals/gridflow/format/mpeg3.c b/externals/gridflow/format/mpeg3.c deleted file mode 100644 index c2b85192..00000000 --- a/externals/gridflow/format/mpeg3.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - $Id: mpeg3.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003 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 "../base/grid.h.fcs" -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -\class FormatMPEG3 < Format -struct FormatMPEG3 : Format { - mpeg3_t *mpeg; - P<BitPacking> bit_packing; - int track; - FormatMPEG3 () : track(0) {} - \decl void initialize (Symbol mode, Symbol source, String filename); - \decl void seek (int frame); - \decl Ruby frame (); - \decl void close (); -}; - -\def void seek (int frame) { mpeg3_set_frame(mpeg,frame,track); } - -\def Ruby frame () { - int nframe = mpeg3_get_frame(mpeg,track); - if (nframe >= mpeg3_video_frames(mpeg,track)) return Qfalse; - - int sx = mpeg3_video_width(mpeg,track); - int sy = mpeg3_video_height(mpeg,track); - int npixels = sx*sy; - int channels = 3; - Pt<uint8> buf = ARRAY_NEW(uint8,sy*sx*channels+16); - uint8 *rows[sy]; - for (int i=0; i<sy; i++) rows[i]=buf+i*sx*channels; - int result = mpeg3_read_frame(mpeg,rows,0,0,sx,sy,sx,sy,MPEG3_RGB888,track); - - GridOutlet out(this,0,new Dim(sy, sx, channels), - NumberTypeE_find(rb_ivar_get(rself,SI(@cast)))); - int bs = out.dim->prod(1); - STACK_ARRAY(int32,b2,bs); - for(int y=0; y<sy; y++) { - Pt<uint8> row = buf+channels*sx*y; - /* bit_packing->unpack(sx,row,b2); out.send(bs,b2); */ - out.send(bs,row); - } - delete[] (uint8 *)buf; - return INT2NUM(nframe); -} - -\def void close () { -// fprintf(stderr, "begin mpeg3_close...\n"); - if (mpeg) { mpeg3_close(mpeg); mpeg=0; } - rb_call_super(argc,argv); -// fprintf(stderr, "end mpeg3_close...\n"); -} - -// libmpeg3 may be nice, but it won't take a filehandle, only filename -\def void initialize (Symbol mode, Symbol source, String filename) { - rb_call_super(argc,argv); - if (mode!=SYM(in)) RAISE("read-only, sorry"); - if (source!=SYM(file)) RAISE("usage: mpeg file <filename>"); - if (TYPE(filename)!=T_STRING) RAISE("PATATE POILUE"); - filename = rb_funcall(mGridFlow,SI(find_file),1,filename); - mpeg = mpeg3_open(rb_str_ptr(filename)); - if (!mpeg) RAISE("IO Error: can't open file `%s': %s", filename, strerror(errno)); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); -} - -\classinfo { - IEVAL(rself,"install '#io:mpeg',1,1;@flags=4;" - "@comment='Motion Picture Expert Group Format" - " (using HeroineWarrior\\'s)';suffixes_are'mpg,mpeg'"); -} -\end class FormatMPEG3 -void startup_mpeg3 () { - \startall -} diff --git a/externals/gridflow/format/opengl.c b/externals/gridflow/format/opengl.c deleted file mode 100644 index 39979f68..00000000 --- a/externals/gridflow/format/opengl.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - $Id: opengl.c,v 1.1 2006-03-15 04:54:54 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004,2005 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 "../base/grid.h.fcs" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> -#include <signal.h> -#ifdef MACOSX -#include <OpenGL/gl.h> -#include <OpenGL/glu.h> -#else -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glut.h> -#endif -#include <setjmp.h> - -static bool in_use = false; - -\class FormatOpenGL < Format -struct FormatOpenGL : Format { - int window; - GLuint gltex; - P<BitPacking> bit_packing; - P<Dim> dim; - Pt<uint8> buf; - \decl void call (); - \decl void initialize (Symbol mode); - \decl void close (); - \decl void resize_window (int sx, int sy); - \grin 0 -}; - -static jmp_buf hack; -static void my_idle () { longjmp(hack,1); } - -\def void call () { - int32 sy = dim->get(0); - int32 sx = dim->get(1); - glEnable(GL_TEXTURE_2D); - if (!gltex) { - } - glTexSubImage2D(GL_TEXTURE_2D,0,0,0,sx,sy,GL_RGBA,GL_UNSIGNED_BYTE,buf); - glBindTexture(GL_TEXTURE_2D, gltex); - glBegin(GL_QUADS); - glColor3f(1.f,1.f,1.f); - glTexCoord2f(0.f,0.f); glVertex2f(0.f,0.f); - glTexCoord2f(1.f,0.f); glVertex2f( sx,0.f); - glTexCoord2f(1.f,1.f); glVertex2f( sx, sy); - glTexCoord2f(0.f,1.f); glVertex2f(0.f, sy); - glEnd(); - - //Here comes some (un)fair amount of arm-twisting - //This is for processing queued events and then "returning". - glutIdleFunc(my_idle); - if(!setjmp(hack)) glutMainLoop(); - //done - - IEVAL(rself,"@clock.delay 100"); -} - -\def void resize_window (int sx, int sy) {L - dim = new Dim(sy,sx,3); - char foo[666]; - sprintf(foo,"GridFlow/GL (%d,%d,3)",sy,sx); - if ((unsigned)window==0xDeadBeef) { - glutInitWindowSize(sx,sy); - window = glutCreateWindow(foo); - } else { - glutReshapeWindow(sx,sy); - } - if (buf) delete buf.p; - buf = ARRAY_NEW(uint8,sy*sx*4); - glViewport(0,0,sx,sy); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(0,sx,sy,0,-99999,99999); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (gltex) glDeleteTextures(1, (GLuint*)&gltex); - glGenTextures(1, (GLuint*)&gltex); - glBindTexture(GL_TEXTURE_2D,gltex); - glPixelStorei(GL_UNPACK_ALIGNMENT,1); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); - glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,sx,sy,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL); - -} - -GRID_INLET(FormatOpenGL,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 sxc = in->dim->prod(1); - int sx = in->dim->get(1), osx = dim->get(1); - int sy = in->dim->get(0), osy = dim->get(0); - in->set_factor(sxc); - if (sx!=osx || sy!=osy) resize_window(0,0,sx,sy); -} GRID_FLOW { - int sxc = in->dim->prod(1); - int sx = in->dim->get(1); - int bypl = 4*sx; - int y = in->dex / sxc; - assert((in->dex % sxc) == 0); - assert((n % sxc) == 0); - for (; n>0; y++, data+=sxc, n-=sxc) bit_packing->pack(sx, data, buf+y*bypl); - } GRID_FINISH { -} GRID_END - -\def void close () { - IEVAL(rself,"@clock.unset"); - if (gltex) glDeleteTextures(1, (GLuint*)&gltex); - if (buf) delete buf.p; - in_use=false; - if ((unsigned)window!=0xDeadBeef) { - glutDestroyWindow(window); - window=0xDeadBeef; - } -} - -\def void initialize (Symbol mode) { - rb_call_super(argc,argv); - if (in_use) RAISE("only one #io:opengl object at a time; sorry"); - in_use=true; - if (mode!=SYM(out)) RAISE("write-only, sorry"); - gltex = 0; - glEnable(GL_TEXTURE_2D); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glDisable(GL_ALPHA_TEST); - glDisable(GL_CULL_FACE); - glDisable(GL_DITHER); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - window = 0xDeadBeef; - int dummy = 0; - glutInit(&dummy,0); - glutInitDisplayMode(GLUT_RGBA); - resize_window(0,0,320,240); - uint32 mask[3] = {0xff000000,0x00ff0000,0x0000ff00}; - bit_packing = new BitPacking(4,4,3,mask); - IEVAL(rself,"@clock = Clock.new self; @clock.delay 0"); - gfpost("@clock = Clock.new self"); -} - -\classinfo { - IEVAL(rself,"install '#io:opengl',1,1;@comment='Silicon Graphics OpenGL'"); -} -\end class FormatOpenGL -void startup_opengl () { - \startall -}
\ No newline at end of file diff --git a/externals/gridflow/format/png.c b/externals/gridflow/format/png.c deleted file mode 100644 index 5db0c254..00000000 --- a/externals/gridflow/format/png.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - $Id: png.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 "../base/grid.h.fcs" -extern "C" { -#include <libpng12/png.h> -}; - -\class FormatPNG < Format -struct FormatPNG : Format { - P<BitPacking> bit_packing; - png_structp png; - png_infop info; - int fd; - FILE *f; - FormatPNG () : bit_packing(0), png(0), f(0) {} - \decl Ruby frame (); - \decl void initialize (Symbol mode, Symbol source, String filename); - \grin 0 int -}; - -GRID_INLET(FormatPNG,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_factor(in->dim->get(1)*in->dim->get(2)); - RAISE("bother, said pooh, as the PNG encoding was found unimplemented"); -} GRID_FLOW { - int rowsize = in->dim->get(1)*in->dim->get(2); - int rowsize2 = in->dim->get(1)*3; - uint8 row[rowsize2]; - while (n) { - bit_packing->pack(in->dim->get(1),data,Pt<uint8>(row,rowsize)); - n-=rowsize; data+=rowsize; - } -} GRID_FINISH { -} GRID_END - -\def Ruby frame () { - uint8 sig[8]; - if (!fread(sig, 1, 8, f)) return Qfalse; - 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); - Pt<uint8> image_data = ARRAY_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), - NumberTypeE_find(rb_ivar_get(rself,SI(@cast)))); - out.send(rowbytes*height,image_data); - free(image_data); - png_destroy_read_struct(&png, &info, NULL); - return Qnil; -} - -\def void initialize (Symbol mode, Symbol source, String filename) { - rb_call_super(argc,argv); - if (source!=SYM(file)) RAISE("usage: png file <filename>"); - rb_funcall(rself,SI(raw_open),3,mode,source,filename); - Ruby stream = rb_ivar_get(rself,SI(@stream)); - fd = NUM2INT(rb_funcall(stream,SI(fileno),0)); - f = fdopen(fd,mode==SYM(in)?"r":"w"); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); -} - -\classinfo { - IEVAL(rself, - "install '#io:png',1,1;@mode=4;include GridFlow::EventIO; suffixes_are'png'"); -} -\end class FormatPNG -void startup_png () { - \startall -} diff --git a/externals/gridflow/format/quartz.m b/externals/gridflow/format/quartz.m deleted file mode 100644 index 9cb00078..00000000 --- a/externals/gridflow/format/quartz.m +++ /dev/null @@ -1,241 +0,0 @@ -/* - $Id: quartz.m,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003 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> - -/* wrapping name conflict */ -#define T_DATA T_COCOA_DATA -#include <Cocoa/Cocoa.h> -#undef T_DATA - -#include "../base/grid.h.fcs" - -@interface GFView: NSView { - Pt<uint8> imdata; - int imwidth; - int imheight; -} -- (id) drawRect: (NSRect)rect; -- (id) imageHeight: (int)w width: (int)h; -- (uint8 *) imageData; -- (int) imageDataSize; -@end - -@implementation GFView - -- (uint8 *) imageData { return imdata; } -- (int) imageDataSize { return imwidth*imheight*4; } - -- (id) imageHeight: (int)h width: (int)w { - if (imheight==h && imwidth==w) return self; - gfpost("new size: y=%d x=%d",h,w); - imheight=h; - imwidth=w; - if (imdata) delete imdata.p; - int size = [self imageDataSize]; - imdata = ARRAY_NEW(uint8,size); - uint8 *p = imdata; - CLEAR(imdata,size); - NSSize s = {w,h}; - [[self window] setContentSize: s]; - return self; -} - -- (id) initWithFrame: (NSRect)r { - [super initWithFrame: r]; - imdata=Pt<uint8>(); 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 */ -Pt<uint8> GFView_imageData(GFView *self) { - return Pt<uint8>([self imageData], [self imageDataSize]); -} -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->imheight,self->imwidth}}; - [self displayRect: r]; - [self setNeedsDisplay: YES]; - [self display]; -} - -\class FormatQuartz < Format -struct FormatQuartz : Format { - NSWindow *window; - NSWindowController *wc; - GFView *widget; /* GridFlow's Cocoa widget */ - NSDate *distantFuture; - \decl void initialize (Symbol mode); - \decl void delete_m (); - \decl void close (); - \decl void call (); - \grin 0 -}; - -static NSDate *distantFuture, *distantPast; - -\def void 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]; - IEVAL(rself,"@clock.delay 20"); -} - -template <class T, class S> -static void convert_number_type(int n, Pt<T> out, Pt<S> in) { - for (int i=0; i<n; i++) out[i]=(T)in[i]; -} - -GRID_INLET(FormatQuartz,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_factor(in->dim->prod(1)); -} GRID_FLOW { - int off = in->dex/in->dim->prod(2); - int c=in->dim->get(2); - NSView *w = widget; - Pt<uint8> data2 = GFView_imageData(w)+off*4; -// convert_number_type(n,data2,data); - if (c==3) { - while(n) { - data2[0]=255; - data2[1]=data[0]; - data2[2]=data[1]; - data2[3]=data[2]; - data+=3; data2+=4; n-=3; - } - } else { - while(n) { - data2[0]=255; - data2[1]=data[0]; - data2[2]=data[1]; - data2[3]=data[2]; - data+=4; data2+=4; n-=4; - } - } -} GRID_FINISH { - GFView_display(widget); -} GRID_END - -\def void initialize (Symbol mode) { - rb_call_super(argc,argv); - 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]; - IEVAL(rself,"@clock = Clock.new self"); - [window makeFirstResponder: widget]; - gfpost("mainWindow = %08lx",(long)[NSApp mainWindow]); - gfpost(" keyWindow = %08lx",(long)[NSApp keyWindow]); - NSColor *color = [NSColor clearColor]; - [window setBackgroundColor: color]; -} - -\def void delete_m () { - [window autorelease]; -} - -\def void close () { - IEVAL(rself,"@clock.unset"); - rb_call_super(argc,argv); - [window autorelease]; - [window setReleasedWhenClosed: YES]; - [window close]; -} - -\classinfo { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - distantFuture = [NSDate distantFuture]; - distantPast = [NSDate distantPast]; - [NSApplication sharedApplication]; - IEVAL(rself, -\ruby - install '#io:quartz',1,1 - @comment = "Apple Quartz/Cocoa" - @flags = 2 -\end ruby -);} - -\end class FormatQuartz -void startup_quartz () { - \startall -} - diff --git a/externals/gridflow/format/quicktimeapple.c b/externals/gridflow/format/quicktimeapple.c deleted file mode 100644 index 2a485424..00000000 --- a/externals/gridflow/format/quicktimeapple.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - $Id: quicktimeapple.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 T_DATA T_COCOA_DATA -#include <Quicktime/Quicktime.h> -#include <Quicktime/Movies.h> -#include <Quicktime/QuickTimeComponents.h> -#undef T_DATA -#include "../base/grid.h.fcs" -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <CoreServices/CoreServices.h> - -typedef ComponentInstance VideoDigitizerComponent, VDC; -typedef ComponentResult VideoDigitizerError, VDE; - -//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) -\end class VDC -*/ - -\class FormatQuickTimeCamera < Format -struct FormatQuickTimeCamera : Format { - P<Dim> dim; - Pt<uint8> buf; - 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; - FormatQuickTimeCamera() : vdc(0) {} - \decl void initialize (Symbol mode, Symbol source, String filename); - \decl void frame (); - \decl void close (); - \grin 0 int -}; - -// /System/Library/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers/Components.h - -static int nn(int c) {return c?c:' ';} - -\def void initialize (Symbol mode, Symbol source, String filename) { - L -//vdc = SGGetVideoDigitizerComponent(c); - rb_call_super(argc,argv); - 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); - gfpost("Component #%d",n); - char *t = (char *)&cd.componentType; - gfpost(" type='%c%c%c%c'",nn(t[3]),nn(t[2]),nn(t[1]),nn(t[0])); - t = (char *)&cd.componentSubType; - gfpost(" subtype='%c%c%c%c'",nn(t[3]),nn(t[2]),nn(t[1]),nn(t[0])); - gfpost(" name=%08x, *name='%*s'",name, *name, name+1); - gfpost(" info=%08x, *info='%*s'",info, *name, info+1); - n++; - } - gfpost("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) gfpost("could not make new SG channel"); - e=SGSetChannelBounds(m_vc, &rect); - if(e!=noErr) gfpost("could not set SG ChannelBounds"); - e=SGSetChannelUsage(m_vc, seqGrabPreview); - if(e!=noErr) gfpost("could not set SG ChannelUsage"); -// 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 = ARRAY_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 = ARRAY_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); -} - -/*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 void frame () { - GridOutlet out(this,0,dim); - out.send(dim->prod(),buf); -L} - -\def void close () { - L - if (m_vc) { - if (::SGDisposeChannel(m_sg, m_vc)) RAISE("SGDisposeChannel"); - m_vc=0; - } - if (m_sg) { - if (::CloseComponent(m_sg)) RAISE("CloseComponent"); - m_sg = NULL; - if (m_srcGWorld) { - ::DisposeGWorld(m_srcGWorld); - m_pixMap = NULL; - m_srcGWorld = NULL; - m_baseAddr = NULL; - } - } -} - -GRID_INLET(FormatQuickTimeCamera,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_factor(in->dim->prod()); -} GRID_FLOW { -} GRID_FINISH { -} GRID_END - -\classinfo { - IEVAL(rself, -\ruby - install '#io:quicktimecamera',1,1 - @comment="Apple Quicktime (CAMERA MODULE)" - @flags=4 -\end ruby -);} -\end class FormatQuickTimeCamera - -\class FormatQuickTimeApple < Format -struct FormatQuickTimeApple : Format { - Movie movie; - TimeValue time; - short movie_file; - GWorldPtr gw; /* just like an X11 Image or Pixmap, maybe. */ - Pt<uint8> buffer; - P<Dim> dim; - int nframe, nframes; - - FormatQuickTimeApple() : movie(0), time(0), movie_file(0), gw(0), - buffer(), dim(0), nframe(0), nframes(0) {} - \decl void initialize (Symbol mode, Symbol source, String filename); - \decl void close (); - \decl void codec_m (String c); - \decl void colorspace_m (Symbol c); - \decl Ruby frame (); - \decl void seek (int frame); - \grin 0 -}; - -\def void seek (int frame) { - nframe=frame; -} - -\def Ruby frame () { - CGrafPtr savedPort; - GDHandle savedDevice; - SetMovieGWorld(movie,gw,GetGWorldDevice(gw)); - Rect r; - GetMovieBox(movie,&r); - PixMapHandle pixmap = GetGWorldPixMap(gw); - short flags = nextTimeStep; - if (nframe>=nframes) return Qfalse; - if (nframe==0) flags |= nextTimeEdgeOK; - TimeValue duration; - OSType mediaType = VisualMediaCharacteristic; - GetMovieNextInterestingTime(movie, - flags,1,&mediaType,time,0,&time,&duration); - if (time<0) { - time=0; - return Qfalse; - } -// gfpost("quicktime frame #%d; time=%d duration=%d", nframe, (long)time, (long)duration); - SetMovieTimeValue(movie,nframe*duration); - MoviesTask(movie,0); - GridOutlet out(this,0,dim); - Pt<uint32> bufu32 = Pt<uint32>((uint32 *)buffer.p,dim->prod()/4); - int n = dim->prod()/4; - int i; - 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(FormatQuickTimeApple,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_factor(in->dim->prod()); -} GRID_FLOW { -} GRID_FINISH { -} GRID_END - -\def void codec_m (String c) { RAISE("Unimplemented. Sorry."); } -\def void colorspace_m (Symbol c) { RAISE("Unimplemented. Sorry."); } - -\def void close () { -//!@#$ - if (movie) { - DisposeMovie(movie); - DisposeGWorld(gw); - CloseMovieFile(movie_file); - movie_file=0; - } - rb_call_super(argc,argv); -} - -\def void initialize (Symbol mode, Symbol source, String filename) { - int err; - rb_call_super(argc,argv); - if (source==SYM(file)) { - filename = rb_funcall(mGridFlow,SI(find_file),1,filename); - FSSpec fss; - FSRef fsr; - err = FSPathMakeRef((const UInt8 *)rb_str_ptr(filename), &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; - } else { - RAISE("usage: quicktime [file <filename> | camera bleh]"); - } - NewMovieFromFile(&movie, movie_file, NULL, NULL, newMovieActive, NULL); - Rect r; - GetMovieBox(movie, &r); - gfpost("handle=%d movie=%d tracks=%d", - movie_file, movie, GetMovieTrackCount(movie)); - gfpost("duration=%d; timescale=%d cHz", - (long)GetMovieDuration(movie), - (long)GetMovieTimeScale(movie)); - nframes = GetMovieDuration(movie); /* i don't think so */ - gfpost("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 = ARRAY_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)", rb_str_ptr(filename), - err, - rb_str_ptr(rb_funcall(mGridFlow,SI(macerr),1,INT2NUM(err)))); -} - -\classinfo { - EnterMovies(); -IEVAL(rself, -\ruby - install '#io:quicktime',1,1 - @comment="Apple Quicktime (using Apple's)" - @flags=4 - suffixes_are'mov' - def self.new(mode,source,filename) - if source==:camera then FormatQuickTimeCamera.new(mode,source,filename) else super end - end -\end ruby -);} -\end class FormatQuickTimeApple -void startup_quicktimeapple () { - \startall -} diff --git a/externals/gridflow/format/quicktimehw.c b/externals/gridflow/format/quicktimehw.c deleted file mode 100644 index 58f415a0..00000000 --- a/externals/gridflow/format/quicktimehw.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - $Id: quicktimehw.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004,2005,2006 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 "../base/grid.h.fcs" -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -\class FormatQuickTimeHW < Format -struct FormatQuickTimeHW : Format { - quicktime_t *anim; - int track; - P<Dim> dim; - char *codec; - int colorspace; - int channels; - bool started; - P<Dim> force; - int length; // in frames - float64 framerate; - P<BitPacking> bit_packing; - FormatQuickTimeHW() : track(0), dim(0), codec(QUICKTIME_RAW), - started(false), force(0), framerate(29.97), bit_packing(0) {} - \decl void initialize (Symbol mode, Symbol source, String filename); - \decl void close (); - \decl Ruby frame (); - \decl void seek (int frame); - - \decl void _0_force_size (int32 height, int32 width); - \decl void _0_codec (String c); - \decl void _0_colorspace (Symbol c); - \decl void _0_parameter (Symbol name, int32 value); - \decl void _0_framerate (float64 f); - \decl void _0_size (int32 height, int32 width); - \grin 0 int -}; - -\def void _0_force_size (int32 height, int32 width) { force = new Dim(height, width); } -\def void seek (int frame) {quicktime_set_video_position(anim,frame,track);} - -\def Ruby frame () { - int nframe = quicktime_video_position(anim,track); - int length2 = quicktime_video_length(anim,track); - if (nframe >= length) { -// gfpost("nframe=%d length=%d length2=%d",nframe,length,length2); - return Qfalse; - } - /* 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: gfpost("strange quicktime. ask matju."); break; - } - if (force) { - sy = force->get(0); - sx = force->get(1); - } - Pt<uint8> buf = ARRAY_NEW(uint8,sy*sx*channels); - uint8 *rows[sy]; for (int i=0; i<sy; i++) rows[i]=buf+i*sx*channels; - int result = quicktime_decode_scaled(anim,0,0,sx,sy,sx,sy,colorspace,rows,track); - GridOutlet out(this,0,new Dim(sy, sx, channels), - NumberTypeE_find(rb_ivar_get(rself,SI(@cast)))); - int bs = out.dim->prod(1); - out.give(sy*sx*channels,buf); - started=true; - return INT2NUM(nframe); -} - -//!@#$ should also support symbol values (how?) -\def void _0_parameter (Symbol name, int32 value) { - quicktime_set_parameter(anim, (char*)rb_sym_name(name), &value); -} - -\def void _0_framerate (float64 f) { - framerate=f; - quicktime_set_framerate(anim, f); -} - -\def void _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(FormatQuickTimeHW,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_factor(in->dim->prod()); - 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); - } -} 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,Pt<uint8>(data2,n)); - 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]=data+i*sx*channels; - quicktime_encode_video(anim,rows,track); - } -} GRID_FINISH { -} GRID_END - -\def void _0_codec (String c) { - //fprintf(stderr,"codec = %s\n",rb_str_ptr(rb_inspect(c))); -#ifdef LQT_VERSION - char buf[5]; - strncpy(buf,rb_str_ptr(c),4); - for (int i=rb_str_len(c); i<4; i++) buf[i]=' '; - buf[4]=0; - Ruby fourccs = rb_ivar_get(rb_obj_class(rself),SI(@fourccs)); - if (Qnil==rb_hash_aref(fourccs,rb_str_new2(buf))) - RAISE("warning: unknown fourcc '%s' (%s)", - buf, rb_str_ptr(rb_inspect(rb_funcall(fourccs,SI(keys),0)))); -#endif - codec = strdup(buf); -} - -\def void _0_colorspace (Symbol c) { - if (0) { - } else if (c==SYM(rgb)) { channels=3; colorspace=BC_RGB888; - } else if (c==SYM(rgba)) { channels=4; colorspace=BC_RGBA8888; - } else if (c==SYM(bgr)) { channels=3; colorspace=BC_BGR888; - } else if (c==SYM(bgrn)) { channels=4; colorspace=BC_BGR8888; - } else if (c==SYM(yuv)) { channels=3; colorspace=BC_YUV888; - } else if (c==SYM(yuva)) { channels=4; colorspace=BC_YUVA8888; - } else if (c==SYM(YUV420P)) { channels=3; colorspace=BC_YUV420P; - } else RAISE("unknown colorspace '%s' (supported: rgb, rgba, bgr, bgrn, yuv, yuva)",rb_sym_name(c)); -} - -\def void close () { - if (anim) { quicktime_close(anim); anim=0; } - rb_call_super(argc,argv); -} - -// libquicktime may be nice, but it won't take a filehandle, only filename -\def void initialize (Symbol mode, Symbol source, String filename) { - rb_call_super(argc,argv); - if (source!=SYM(file)) RAISE("usage: quicktime file <filename>"); - filename = rb_funcall(mGridFlow,SI(find_file),1,filename); - anim = quicktime_open(rb_str_ptr(filename),mode==SYM(in),mode==SYM(out)); - if (!anim) RAISE("can't open file `%s': %s", rb_str_ptr(filename), strerror(errno)); - if (mode==SYM(in)) { - length = quicktime_video_length(anim,track); - gfpost("quicktime: codec=%s height=%d width=%d depth=%d framerate=%f", - quicktime_video_compressor(anim,track), - quicktime_video_height(anim,track), - quicktime_video_width(anim,track), - quicktime_video_depth(anim,track), - quicktime_frame_rate(anim,track)); -/* 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,SYM(rgb)); - quicktime_set_cpus(anim,1); - uint32 mask[3] = {0x0000ff,0x00ff00,0xff0000}; - bit_packing = new BitPacking(is_le(),3,3,mask); -} - -\classinfo { - IEVAL(rself, -\ruby - install '#io:quicktime',1,1 - @comment=%[Burkhard Plaum's (or HeroineWarrior's) libquicktime] - suffixes_are 'mov' - @flags=6 - def self.info; %[codecs: #{@codecs.keys.join' '}] end -\end ruby -); - -//#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(); - Ruby codecs = rb_hash_new(); - Ruby fourccs = rb_hash_new(); - 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; - } - Ruby name = rb_str_new2(s->name); - Ruby f = rb_ary_new2(s->num_fourccs); - for (int j=0; j<s->num_fourccs; j++) { - Ruby fn = rb_str_new2(s->fourccs[j]); - rb_ary_push(f,fn); - rb_hash_aset(fourccs,fn,name); - } - rb_hash_aset(codecs,name,f); - } - rb_ivar_set(rself,SI(@codecs),codecs); - rb_ivar_set(rself,SI(@fourccs),fourccs); -#endif -} -\end class FormatQuickTimeHW -void startup_quicktimehw () { - \startall -} diff --git a/externals/gridflow/format/sdl.c b/externals/gridflow/format/sdl.c deleted file mode 100644 index 32ba64a5..00000000 --- a/externals/gridflow/format/sdl.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - $Id: sdl.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 "../base/grid.h.fcs" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> -#include <signal.h> -#include <SDL/SDL.h> - -static bool in_use = false; - -\class FormatSDL < Format -struct FormatSDL : Format { - SDL_Surface *screen; - P<BitPacking> bit_packing; - P<Dim> dim; - void resize_window (int sx, int sy); - void call (); - Pt<uint8> pixels () { - return Pt<uint8>((uint8 *)screen->pixels, - dim->prod(0,1)*bit_packing->bytes); - } - \decl void initialize (Symbol mode); - \decl void close (); - \grin 0 int -}; - -void FormatSDL::call() { - SDL_Event event; - while(SDL_PollEvent(&event)) {} - IEVAL(rself,"@clock.delay 20"); -} - -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(FormatSDL,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 sxc = in->dim->prod(1); - int sx = in->dim->get(1), osx = dim->get(1); - int sy = in->dim->get(0), osy = dim->get(0); - in->set_factor(sxc); - 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 = in->dex / sxc; - assert((in->dex % sxc) == 0); - assert((n % sxc) == 0); - 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, 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 void close () { - IEVAL(rself,"@clock.unset"); - in_use=false; -} - -\def void initialize (Symbol mode) { - dim=0;screen=0; - rb_call_super(argc,argv); - 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; - } - IEVAL(rself,"@clock = Clock.new self"); -} - -\classinfo { - IEVAL(rself,"install '#io:sdl',1,1;@flags=2;@comment='Simple Directmedia Layer'"); -} -\end class FormatSDL -void startup_sdl () { - \startall -} diff --git a/externals/gridflow/format/videodev.c b/externals/gridflow/format/videodev.c deleted file mode 100644 index 0f458408..00000000 --- a/externals/gridflow/format/videodev.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - $Id: videodev.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004 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 "../base/grid.h.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> - -/* **************************************************************** */ - -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 ; - -static const char *ruby_code = -\ruby -flags :name,:VideoTypeFlags,:start,0,:values,%w( - CAPTURE TUNER TELETEXT OVERLAY CHROMAKEY CLIPPING FRAMERAM - SCALES MONOCHROME SUBCAPTURE - MPEG_DECODER MPEG_ENCODER MJPEG_DECODER MJPEG_ENCODER -) -flags :name,:TunerFlags,:start,0,:values,%w( - PAL NTSC SECAM LOW NORM DUMMY5 DUMMY6 STEREO_ON RDS_ON MBS_ON -) -flags :name,:ChannelFlags,:start,0,:values,%w( - TUNER AUDIO NORM -) -choice :name,:VideoPaletteChoice,:start,0,:values,%w( - NIL GREY HI240 - RGB565 RGB24 RGB32 RGB555 - YUV422 YUYV UYVY YUV420 YUV411 RAW - YUV422P YUV411P YUV420P YUV410P -) -choice :name,:VideoModeChoice,:start,0,:values,%w( - PAL NTSC SECAM AUTO -) -\end ruby -; - -/* **************************************************************** */ - -/* -#define WH(_field_,_spec_) \ - sprintf(buf+strlen(buf), "%s: " _spec_ "; ", #_field_, self->_field_); -#define WHYX(_name_,_fieldy_,_fieldx_) \ - sprintf(buf+strlen(buf), "%s: y=%d, x=%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_)); \ - delete[] foo;} -#define WHCHOICE(_field_,_table_) { \ - char *foo; \ - sprintf(buf+strlen(buf), "%s: %s; ", #_field_, \ - foo=choice_to_s(self->_field_,COUNT(_table_),_table_));\ - delete[] foo;} -static char *flags_to_s(int value, int n, named_int *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].name); - } - if (!*foo) strcat(foo,"0"); - return strdup(foo); -} -static char *choice_to_s(int value, int n, named_int *table) { - if (value < 0 || value >= n) { - char foo[64]; - sprintf(foo,"(Unknown #%d)",value); - return strdup(foo); - } else { - return strdup(table[value].name); - } -} -*/ - -class RStream { -public: - Ruby a; - RStream(Ruby a) : a(a) {} - RStream &operator <<(/*Ruby*/ void *v) { rb_ary_push(a,(Ruby)v); return *this; } - RStream &operator <<(int v) { return *this<<(void *)INT2NUM(v); } -}; - -static void gfpost(VideoChannel *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoChannel) << self->channel - << (void *)rb_str_new(self->name,strnlen(self->name,32)) - << self->tuners << self->flags << self->type << self->norm; - rb_p(rs.a); -} - -static void gfpost(VideoTuner *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoTuner) << self->tuner - << (void *)rb_str_new(self->name,strnlen(self->name,32)) - << self->rangelow << self->rangehigh - << self->flags << self->mode << self->signal; - rb_p(rs.a); -} - -static void gfpost(VideoCapability *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoCapability) - << (void *)rb_str_new(self->name,strnlen(self->name,32)) - << self->type - << self->channels << self->audios - << self->maxheight << self->maxwidth - << self->minheight << self->minwidth; - rb_p(rs.a); -} - -static void gfpost(VideoWindow *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoWindow) - << self->y << self->x - << self->height << self->width - << self->chromakey << self->flags << self->clipcount; - rb_p(rs.a); -} - -static void gfpost(VideoPicture *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoPicture) - << self->brightness << self->contrast << self->colour - << self->hue << self->whiteness << self->depth << self->palette; - rb_p(rs.a); -} - -static void gfpost(VideoMbuf *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoMBuf) << self->size << self->frames; - for (int i=0; i<4; i++) rs << self->offsets[i]; - rb_p(rs.a); -} - -static void gfpost(VideoMmap *self) { - RStream rs(rb_ary_new()); - rs << (void *)SYM(VideoMMap) << self->frame - << self->height << self->width << self->format; - rb_p(rs.a); -}; - -/* **************************************************************** */ - -\class FormatVideoDev < Format -struct FormatVideoDev : Format { - VideoCapability vcaps; - VideoMbuf vmbuf; - VideoMmap vmmap; - Pt<uint8> image; - int palette; - int queue[8], queuesize, queuemax, next_frame; - int current_channel, current_tuner; - bool use_mmap; - P<BitPacking> bit_packing; - P<Dim> dim; - - FormatVideoDev () : queuesize(0), queuemax(2), next_frame(0), use_mmap(true), bit_packing(0), dim(0) {} - void frame_finished (Pt<uint8> buf); - - \decl void initialize (Symbol mode, String filename, Symbol option=Qnil); - \decl void initialize2 (); - \decl void close (); - \decl void alloc_image (); - \decl void dealloc_image (); - \decl void frame (); - \decl void frame_ask (); - \grin 0 int - - \decl void _0_size (int sy, int sx); - \decl void _0_norm (int value); - \decl void _0_tuner (int value); - \decl void _0_channel (int value); - \decl void _0_frequency (int value); - \decl void _0_transfer (Symbol sym, int queuemax=2); - \decl void _0_colorspace (Symbol c); - \decl void _0_get (Symbol attr=0); - \decl void _0_brightness (uint16 value); - \decl void _0_hue (uint16 value); - \decl void _0_colour (uint16 value); - \decl void _0_contrast (uint16 value); - \decl void _0_whiteness (uint16 value); -}; - -#define DEBUG(args...) 42 -//#define DEBUG(args...) gfpost - -#define IOCTL(_f_,_name_,_arg_) \ - (DEBUG("fd%d.ioctl(0x%08x(:%s),0x%08x)\n",_f_,_name_,#_name_,_arg_), \ - ioctl(_f_,_name_,_arg_)) - -#define WIOCTL(_f_,_name_,_arg_) \ - (DEBUG("fd%d.ioctl(0x%08x(:%s),0x%08x)\n",_f_,_name_,#_name_,_arg_), \ - ioctl(_f_,_name_,_arg_) < 0) && \ - (gfpost("ioctl %s: %s",#_name_,strerror(errno)),1) - -#define WIOCTL2(_f_,_name_,_arg_) \ - ((DEBUG("fd%d.ioctl(0x%08x(:%s),0x%08x)\n",_f_,_name_,#_name_,_arg_), \ - ioctl(_f_,_name_,_arg_) < 0) && \ - (gfpost("ioctl %s: %s",#_name_,strerror(errno)), \ - RAISE("ioctl error"), 0)) - -#define GETFD NUM2INT(rb_funcall(rb_ivar_get(rself,SI(@stream)),SI(fileno),0)) - -\def void _0_size (int sy, int sx) { - int fd = GETFD; - VideoWindow grab_win; - // !@#$ bug here: won't flush the frame queue - dim = new Dim(sy,sx,3); - WIOCTL(fd, VIDIOCGWIN, &grab_win); - gfpost(&grab_win); - grab_win.clipcount = 0; - grab_win.flags = 0; - if (sy && sx) { - grab_win.height = sy; - grab_win.width = sx; - } - gfpost(&grab_win); - WIOCTL(fd, VIDIOCSWIN, &grab_win); - WIOCTL(fd, VIDIOCGWIN, &grab_win); - gfpost(&grab_win); -} - -\def void dealloc_image () { - if (!image) return; - if (!use_mmap) { - delete[] (uint8 *)image; - } else { - munmap(image, vmbuf.size); - image = Pt<uint8>(); - } -} - -\def void alloc_image () { - if (!use_mmap) { - image = ARRAY_NEW(uint8,dim->prod(0,1)*bit_packing->bytes); - return; - } - int fd = GETFD; - WIOCTL2(fd, VIDIOCGMBUF, &vmbuf); - image = Pt<uint8>((uint8 *) - mmap(0,vmbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0), - vmbuf.size); - if (((int)image)<=0) { - image=Pt<uint8>(); - RAISE("mmap: %s", strerror(errno)); - } -} - -\def void frame_ask () { - int fd = GETFD; - 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 = palette; - vmmap.width = dim->get(1); - vmmap.height = dim->get(0); - WIOCTL2(fd, VIDIOCMCAPTURE, &vmmap); - next_frame = (next_frame+1) % vmbuf.frames; -} - -void FormatVideoDev::frame_finished (Pt<uint8> buf) { - GridOutlet out(this,0,dim,NumberTypeE_find(rb_ivar_get(rself,SI(@cast)))); - /* picture is converted here. */ - int sy = dim->get(0); - int sx = dim->get(1); - int bs = dim->prod(1); - if (palette==VIDEO_PALETTE_YUV420P) { - STACK_ARRAY(uint8,b2,bs); - for(int y=0; y<sy; y++) { - Pt<uint8> bufy = buf+sx*y; - Pt<uint8> bufu = buf+sx*sy +(sx/2)*(y/2); - Pt<uint8> bufv = buf+sx*sy*5/4+(sx/2)*(y/2); - for (int x=0; x<sx; x++) { - b2[x*3+0]=bufy[x]; - b2[x*3+1]=bufu[x/2]; - b2[x*3+2]=bufv[x/2]; - } - out.send(bs,b2); - } - } else if (bit_packing) { - STACK_ARRAY(uint8,b2,bs); - for(int y=0; y<sy; y++) { - Pt<uint8> buf2 = buf+bit_packing->bytes*sx*y; - bit_packing->unpack(sx,buf2,b2); - out.send(bs,b2); - } - } else { - out.send(sy*bs,buf); - } -} - -static int read2(int fd, uint8 *image, int n) { - int r=0; - for (; n>0; ) { - int rr=read(fd,image,n); - if (rr<0) return rr; - 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 void frame () { - if (!image) rb_funcall(rself,SI(alloc_image),0); - int fd = GETFD; - 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) rb_funcall(rself,SI(frame_ask),0); - 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]; - rb_funcall(rself,SI(frame_ask),0); -} - -GRID_INLET(FormatVideoDev,0) { - RAISE("can't write."); -} GRID_FLOW { -} GRID_FINISH { -} GRID_END - -\def void _0_norm (int value) { - int fd = GETFD; - 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)) { - gfpost("no tuner #%d", value); - } else { - vtuner.mode = value; - gfpost(&vtuner); - WIOCTL(fd, VIDIOCSTUNER, &vtuner); - } -} - -\def void _0_tuner (int value) { - int fd = GETFD; - 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); -} - -\def void _0_channel (int value) { - int fd = GETFD; - VideoChannel vchan; - vchan.channel = value; - current_channel = value; - if (0> IOCTL(fd, VIDIOCGCHAN, &vchan)) RAISE("no channel #%d", value); - gfpost(&vchan); - WIOCTL(fd, VIDIOCSCHAN, &vchan); - if (vcaps.type & VID_TYPE_TUNER) rb_funcall(rself,SI(_0_tuner),1,INT2NUM(0)); -} - -\def void _0_frequency (int value) { - int fd = GETFD; - if (0> IOCTL(fd, VIDIOCSFREQ, &value)) RAISE("can't set frequency to %d",value); -} - -\def void _0_transfer (Symbol sym, int queuemax=2) { - if (sym == SYM(read)) { - rb_funcall(rself,SI(dealloc_image),0); - use_mmap = false; - gfpost("transfer read"); - } else if (sym == SYM(mmap)) { - rb_funcall(rself,SI(dealloc_image),0); - use_mmap = true; - rb_funcall(rself,SI(alloc_image),0); - queuemax=min(queuemax,vmbuf.frames); - gfpost("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_) {\ - int fd = GETFD; \ - VideoPicture vp; \ - WIOCTL(fd, VIDIOCGPICT, &vp); \ - vp._name_ = value; \ - WIOCTL(fd, VIDIOCSPICT, &vp);} - -\def void _0_brightness (uint16 value) {PICTURE_ATTR(brightness)} -\def void _0_hue (uint16 value) {PICTURE_ATTR(hue)} -\def void _0_colour (uint16 value) {PICTURE_ATTR(colour)} -\def void _0_contrast (uint16 value) {PICTURE_ATTR(contrast)} -\def void _0_whiteness (uint16 value) {PICTURE_ATTR(whiteness)} - -#define PICTURE_ATTR_GET(_name_) { \ - int fd = GETFD; \ - VideoPicture vp; \ - WIOCTL(fd, VIDIOCGPICT, &vp); \ - Ruby argv[3] = {INT2NUM(1), SYM(_name_), INT2NUM(vp._name_)}; \ - send_out(COUNT(argv),argv);} - -\def void _0_get (Symbol attr) { - if (!attr) { - _0_get(0,0,SYM(brightness)); - _0_get(0,0,SYM(hue )); - _0_get(0,0,SYM(colour )); - _0_get(0,0,SYM(contrast )); - _0_get(0,0,SYM(whiteness )); - _0_get(0,0,SYM(frequency )); - } else if (attr==SYM(brightness)) { PICTURE_ATTR_GET(brightness); - } else if (attr==SYM(hue )) { PICTURE_ATTR_GET(hue ); - } else if (attr==SYM(colour )) { PICTURE_ATTR_GET(colour ); - } else if (attr==SYM(contrast )) { PICTURE_ATTR_GET(contrast ); - } else if (attr==SYM(whiteness )) { PICTURE_ATTR_GET(whiteness ); - } else if (attr==SYM(frequency )) { - int fd = GETFD; - int value; - WIOCTL(fd, VIDIOCGFREQ, &value); - {Ruby argv[3] ={INT2NUM(1), SYM(frequency), INT2NUM(value)}; send_out(COUNT(argv),argv);} - } else { RAISE("What you say?"); } -} - -\def void close () { - if (image) rb_funcall(rself,SI(dealloc_image),0); - rb_call_super(argc,argv); -} - -\def void _0_colorspace (Symbol c) { - if (c==SYM(RGB24)) palette=VIDEO_PALETTE_RGB24; - else if (c==SYM(YUV420P)) palette=VIDEO_PALETTE_YUV420P; - else RAISE("supported: RGB24, YUV420P"); - - int fd = GETFD; - VideoPicture *gp = new VideoPicture; - WIOCTL(fd, VIDIOCGPICT, gp); - gp->palette = palette; - WIOCTL(fd, VIDIOCSPICT, gp); - WIOCTL(fd, VIDIOCGPICT, gp); - //if (bit_packing) { delete bit_packing; bit_packing=0; } - switch(palette) { - case VIDEO_PALETTE_RGB24:{ - uint32 masks[3] = { 0xff0000,0x00ff00,0x0000ff }; - bit_packing = new BitPacking(is_le(),3,3,masks); - }break; - case VIDEO_PALETTE_YUV420P:{ - // woops, special case already, can't do that with bit_packing - } - default: - RAISE("can't handle palette %d", gp->palette); - } - delete gp; -} - -\def void initialize2 () { - int fd = GETFD; - VideoPicture *gp = new VideoPicture; -/* long flags; - fcntl(fd,F_GETFL,&flags); - flags |= O_NONBLOCK; - fcntl(fd,F_SETFL,&flags); */ - - WIOCTL(fd, VIDIOCGCAP, &vcaps); - gfpost(&vcaps); - rb_funcall(rself,SI(_0_size),2,INT2NUM(vcaps.maxheight),INT2NUM(vcaps.maxwidth)); - WIOCTL(fd, VIDIOCGPICT, gp); - gfpost(gp); - char buf[1024] = ""; - int n = 17 /*COUNT(video_palette_choice)*/; - for (int i=0; i<n; i++) { - gp->palette = i; - ioctl(fd, VIDIOCSPICT, gp); - ioctl(fd, VIDIOCGPICT, gp); - if (gp->palette == i) { - if (*buf) strcpy(buf+strlen(buf),", "); - //strcpy(buf+strlen(buf),video_palette_choice[i].name); - sprintf(buf+strlen(buf),"%d",i); - } - } - gfpost("This card supports palettes: %s", buf); - _0_colorspace(0,0,SYM(RGB24)); - rb_funcall(rself,SI(_0_channel),1,INT2NUM(0)); - delete gp; -} - -\def void initialize (Symbol mode, String filename, Symbol option=Qnil) { - rb_call_super(argc,argv); - image = Pt<uint8>(); - rb_ivar_set(rself,SI(@stream), - rb_funcall(rb_cFile,SI(open),2,filename,rb_str_new2("r+"))); - rb_funcall(rself,SI(initialize2),0); -} - -\classinfo { - IEVAL(rself,"install '#io:videodev',1,1;@flags=4;@comment='Video4linux 1.x'"); -} -\end class FormatVideoDev -void startup_videodev () { - \startall -} diff --git a/externals/gridflow/format/x11.c b/externals/gridflow/format/x11.c deleted file mode 100644 index 9237a6b6..00000000 --- a/externals/gridflow/format/x11.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - $Id: x11.c,v 1.2 2006-03-15 04:37:46 matju Exp $ - - GridFlow - Copyright (c) 2001,2002,2003,2004,2005 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 "../base/grid.h.fcs" -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#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 - -#undef L -#define L gfpost("%s:%d in %s",__FILE__,__LINE__,__PRETTY_FUNCTION__); - -/* X11 Error Handler type */ -typedef int (*XEH)(Display *, XErrorEvent *); - -\class FormatX11 < Format -struct 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; - int transfer; /* 0=plain 1=xshm 2=xvideo */ - bool use_stripes; /* use alternate conversion in 256-color mode */ -/* 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 */ - Pt<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; -#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; - unsigned char *data; - int last_encoding; -#endif - FormatX11 () : transfer(0), use_stripes(false), - window(0), ximage(0), image(Pt<uint8>()), is_owner(true), - dim(0), lock_size(false), override_redirect(false) -#ifdef HAVE_X11_SHARED_MEMORY - , shm_info(0) -#endif - {} - 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 FormatX11::search_window_tree (Window xid, Atom key, const char *value, int level=0); - \decl void initialize (...); - \decl void frame (); - \decl void close (); - \decl void call (); - \decl void _0_out_size (int sy, int sx); - \decl void _0_setcursor (int shape); - \decl void _0_hidecursor (); - \decl void _0_set_geometry (int y, int x, int sy, int sx); - \decl void _0_fall_thru (int flag); - \decl void _0_transfer (Symbol s); - \decl void _0_title (String s=Qnil); - \grin 0 int -}; - -/* ---------------------------------------------------------------- */ - -static const char *xfers[3] = {"plain","xshm","xvideo"}; - -void FormatX11::show_section(int x, int y, int sx, int sy) { - 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; - switch (transfer) { - case 0: XPutImage(display,window,imagegc,ximage,x,y,x,y,sx,sy); - XFlush(display); - break; -#ifdef HAVE_X11_SHARED_MEMORY - case 1: 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 - break; -#endif -#ifdef HAVE_X11_XVIDEO - case 2: - break; -#endif - default: RAISE("transfer mode '%s' not available", xfers[transfer]); - } -} - -/* window manager hints, defines the window as non-resizable */ -void FormatX11::set_wm_hints () { - Ruby title = rb_ivar_get(rself,SI(@title)); - if (!is_owner) return; - XWMHints wmh; - char buf[256],*bufp=buf; - if (title==Qnil) { - sprintf(buf,"GridFlow (%d,%d,%d)",dim->get(0),dim->get(1),dim->get(2)); - } else { - sprintf(buf,"%.255s",rb_str_ptr(title)); - } - 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); -} - -void FormatX11::report_pointer(int y, int x, int state) { - Ruby argv[5] = { - INT2NUM(0), SYM(position), - INT2NUM(y), INT2NUM(x), INT2NUM(state) }; - send_out(COUNT(argv),argv); -} - -\def void 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 (rb_ivar_get(rself,SI(@mode)) == SYM(out)) { - 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); - Ruby argv[6] = { - INT2NUM(0), e.type==KeyPress ? SYM(keypress) : SYM(keyrelease), - INT2NUM(ek->y), INT2NUM(ek->x), INT2NUM(ek->state), - rb_funcall(rb_str_new2(buf),SI(intern),0) }; - send_out(COUNT(argv),argv); - //XFree(kss); - }break; - case MotionNotify:{ - XMotionEvent *em = (XMotionEvent *)&e; - report_pointer(em->y,em->x,em->state); - }break; - case DestroyNotify:{ - gfpost("This window is being closed, so this handler will close too!"); - rb_funcall(rself,SI(close),0); - return; - }break; - case ConfigureNotify:break; // as if we cared - } - } - IEVAL(rself,"@clock.delay 20"); -} - -\def void frame () { - XGetSubImage(display, window, 0, 0, dim->get(1), dim->get(0), - (unsigned)-1, ZPixmap, ximage, 0, 0); - GridOutlet out(this,0,dim,NumberTypeE_find(rb_ivar_get(rself,SI(@cast)))); - int sy=dim->get(0), sx=dim->get(1), bs=dim->prod(1); - STACK_ARRAY(uint8,b2,bs); - for(int y=0; y<sy; y++) { - Pt<uint8> b1 = Pt<uint8>(image,ximage->bytes_per_line*dim->get(0)) - + 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) { - gfpost("XErrorEvent: type=0x%08x display=0x%08x xid=0x%08x", - xee->type, xee->display, xee->resourceid); - gfpost("... 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->transfer==1) { - gfpost("(note: turning shm off)"); - current_x11->transfer = 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; - switch (transfer) { - case 0: { - 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 = ARRAY_NEW(uint8,size); - ximage->data = (int8 *)image; - } break; -#ifdef HAVE_X11_SHARED_MEMORY - case 1: { - shm_info = new XShmSegmentInfo; - ximage = XShmCreateImage(display,visual,depth,ZPixmap,0,shm_info,sx,sy); - if (!ximage) {gfpost("shm got disabled, retrying..."); transfer=0;} - XSync(display,0); - if (transfer==0) return alloc_image(sx,sy); - int size = ximage->bytes_per_line*ximage->height; - gfpost("size = %d",size); - 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)); - gfpost("shmaddr=%p",shm_info->shmaddr); - image = Pt<uint8>((uint8 *)ximage->data,size); - 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 (transfer==0) return alloc_image(sx,sy); - } break; -#endif -#ifdef HAVE_X11_XVIDEO - case 2: { - 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++) gfpost("XvEncodingInfo: name='%s' encoding_id=0x%08x",enc[i].name,enc[i].encoding_id);*/ - gfpost("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"); - } break; -#endif - default: RAISE("transfer mode '%s' not available", xfers[transfer]); - } - int status = XInitImage(ximage); - if (status!=1) gfpost("XInitImage returned: %d", status); - return true; -retry: - gfpost("shm got disabled, retrying..."); - return alloc_image(sx,sy); -} - -void FormatX11::dealloc_image () { - if (!ximage) return; - switch (transfer) { - case 0: XFree(ximage); ximage=0; image=Pt<uint8>(); break; -#ifdef HAVE_X11_SHARED_MEMORY - case 1: - shmdt(ximage->data); - XShmDetach(display,shm_info); - if (shm_info) {delete shm_info; shm_info=0;} - XFree(ximage); - ximage = 0; - image = Pt<uint8>(); - break; -#endif -#ifdef HAVE_X11_XVIDEO - case 2: { - if (data) delete[] data; - if (xvi) XFree(xvi); - xvi=0; - data=0; - } - break; -#endif - default: RAISE("transfer mode '%s' not available",xfers[transfer]); - } -} - -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(); - _0_fall_thru(0,0,is_owner); - if (is_owner) XMapRaised(display, window); - imagegc = XCreateGC(display, window, 0, NULL); - if (visual->c_class == PseudoColor) prepare_colormap(); - } - XSync(display,0); -} - -GRID_INLET(FormatX11,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 sxc = in->dim->prod(1); - int sx = in->dim->get(1), osx = dim->get(1); - int sy = in->dim->get(0), osy = dim->get(0); - in->set_factor(sxc); - 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 = in->dex/sxc; - int oy = y; - 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 void close () { - if (!this) RAISE("stupid error: trying to close display NULL. =)"); - bit_packing=0; - IEVAL(rself,"@clock.unset"); - if (is_owner) XDestroyWindow(display,window); - XSync(display,0); - dealloc_image(); - XCloseDisplay(display); - display=0; - rb_call_super(argc,argv); -} - -\def void _0_out_size (int sy, int sx) { resize_window(sx,sy); } - -\def void _0_setcursor (int shape) { - shape = 2*(shape&63); - Cursor c = XCreateFontCursor(display,shape); - XDefineCursor(display,window,c); - XFlush(display); -} - -\def void _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) - transfer = 2; -#elif defined(HAVE_X11_SHARED_MEMORY) - transfer = !! XShmQueryExtension(display); -#else - transfer = 0; -#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 void _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 void _0_fall_thru (int flag) { - int mask = ExposureMask | StructureNotifyMask; - if (flag) mask |= ExposureMask|StructureNotifyMask|PointerMotionMask| - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask| - KeyPressMask|KeyReleaseMask; - XSelectInput(display, window, mask); - XFlush(display); -} - -\def void _0_transfer (Symbol s) { - if (s==SYM(plain)) transfer=0; - else if (s==SYM(xshm)) transfer=1; - else if (s==SYM(xvideo)) transfer=2; - else RAISE("unknown transfer mode (possible: plain xshm xvideo)"); -} - -\def void _0_title (String s=Qnil) { - rb_ivar_set(rself,SI(@title),s); - set_wm_hints(); -} - -\def void initialize (...) { - int sy=240, sx=320; // defaults - rb_call_super(argc,argv); - rb_ivar_set(rself,SI(@title),Qnil); - argv++, argc--; - VALUE domain = argc<1 ? SYM(here) : argv[0]; - int i; - char host[256]; - if (domain==SYM(here)) { - open_display(0); - i=1; - } else if (domain==SYM(local)) { - if (argc<2) RAISE("open x11 local: not enough args"); - sprintf(host,":%ld",NUM2LONG(argv[1])); - open_display(host); - i=2; - } else if (domain==SYM(remote)) { - if (argc<3) RAISE("open x11 remote: not enough args"); - sprintf(host,"%s:%ld",rb_sym_name(argv[1]),NUM2LONG(argv[2])); - open_display(host); - i=3; - } else if (domain==SYM(display)) { - if (argc<2) RAISE("open x11 display: not enough args"); - strcpy(host,rb_sym_name(argv[1])); - for (int k=0; host[k]; k++) if (host[k]=='%') host[k]==':'; - gfpost("mode `display', DISPLAY=`%s'",host); - open_display(host); - i=2; - } else { - RAISE("x11 destination syntax error"); - } - - for(;i<argc;i++) { - Ruby a=argv[i]; - if (a==SYM(override_redirect)) override_redirect = true; - else if (a==SYM(use_stripes)) use_stripes = true; - else RAISE("argument '%s' not recognized",rb_sym_name(argv[i])); - } - - pos[1]=pos[0]=0; - parent = root_window; - if (i>=argc) { - } else { - VALUE winspec = argv[i]; - if (winspec==SYM(root)) { - window = root_window; - is_owner = false; - } else if (winspec==SYM(embed)) { - Ruby title_s = rb_funcall(argv[i+1],SI(to_s),0); - char *title = strdup(rb_str_ptr(title_s)); - sy = sx = pos[0] = pos[1] = 0; - parent = search_window_tree(root_window,XInternAtom(display,"WM_NAME",0),title); - free(title); - if (parent == 0xDeadBeef) RAISE("Window not found."); - } else if (winspec==SYM(embed_by_id)) { - const char *winspec2 = rb_sym_name(argv[i+1]); - if (strncmp(winspec2,"0x",2)==0) { - parent = strtol(winspec2+2,0,16); - } else { - parent = atoi(winspec2); - } - } else { - if (TYPE(winspec)==T_SYMBOL) { - const char *winspec2 = rb_sym_name(winspec); - 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" also takes care of creation - resize_window(sx,sy); - - 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 }; - bit_packing = new BitPacking(disp_is_le, bpp/8, 3, masks); - } break; - default: { RAISE("huh?"); } - } - IEVAL(rself,"@clock = Clock.new self; @clock.delay 0"); - show_section(0,0,sx,sy); -} - -\classinfo { - IEVAL(rself,"install '#io:x11',1,1;@mode=6;@comment='X Window System Version 11.x'"); -} -\end class FormatX11 -void startup_x11 () { - \startall -} - |