wiretap 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/LICENSE +32 -0
  2. data/README +93 -0
  3. data/ext/Makefile +146 -0
  4. data/ext/audio_format.cpp +224 -0
  5. data/ext/bmp.cpp +65 -0
  6. data/ext/extconf.rb +85 -0
  7. data/ext/format.cpp +347 -0
  8. data/ext/image.h +27 -0
  9. data/ext/image_format.cpp +194 -0
  10. data/ext/node.cpp +401 -0
  11. data/ext/nodechildren.cpp +67 -0
  12. data/ext/nodeframes.cpp +233 -0
  13. data/ext/nodemetadata.cpp +90 -0
  14. data/ext/ppm.cpp +132 -0
  15. data/ext/server.cpp +202 -0
  16. data/ext/serverlist.cpp +183 -0
  17. data/ext/sgi.cpp +69 -0
  18. data/ext/testserver/Makefile +5 -0
  19. data/ext/testserver/cfg/wiretap_path_translation_db.xml +44 -0
  20. data/ext/testserver/cfg/wiretapd.cfg +74 -0
  21. data/ext/testserver/cfg/wiretapd.res +60 -0
  22. data/ext/testserver/db.sql +50 -0
  23. data/ext/testserver/server.cpp +206 -0
  24. data/ext/testserver/testserver.rb +146 -0
  25. data/ext/thread_worker.cpp +85 -0
  26. data/ext/wiretap.cpp +68 -0
  27. data/ext/wiretap.h +115 -0
  28. data/lib/wiretap.rb +280 -0
  29. data/test/audio.rb +27 -0
  30. data/test/convert.rb +35 -0
  31. data/test/image.rb +101 -0
  32. data/test/read_frames.rb +142 -0
  33. data/test/wiretap-images/01.ppm +0 -0
  34. data/test/wiretap-images/32bit.stoneimage +621 -0
  35. data/test/wiretap-images/36bit.stoneimage +1036 -0
  36. data/test/wiretap-images/48bit.stoneimage +800 -1
  37. data/test/wiretap-images/a.stoneimage +0 -0
  38. data/test/wiretap-images/a0.stoneimage +0 -0
  39. data/test/wiretap-images/a1.stoneimage +0 -0
  40. data/test/wiretap-images/a2.stoneimage +0 -0
  41. data/test/wiretap-images/a3.stoneimage +0 -0
  42. data/test/wiretap-images/a4.stoneimage +0 -0
  43. data/test/wiretap-images/b1.stonesound +0 -0
  44. data/test/wiretap-images/importable-seq/00000001.ppm +0 -0
  45. data/test/wiretap-images/importable-seq/00000002.ppm +0 -0
  46. data/test/wiretap-images/importable-seq/00000003.ppm +0 -0
  47. data/test/wiretap-images/importable-seq/00000004.ppm +0 -0
  48. data/test/wiretap-images/importable-seq/00000005.ppm +0 -0
  49. data/test/wiretap-images/importable-seq/00000006.ppm +0 -0
  50. data/test/wiretap-images/importable-seq/00000007.ppm +0 -0
  51. data/test/wiretap-images/importable-seq/00000008.ppm +0 -0
  52. data/test/wiretap-images/importable-seq/00000009.ppm +0 -0
  53. data/test/wiretap-images/importable-seq/00000010.ppm +0 -0
  54. data/test/wiretap-images/importable-seq/00000011.ppm +0 -0
  55. data/test/wiretap-images/importable-seq/00000012.ppm +0 -0
  56. data/test/wiretap-images/monsters_001.tif +0 -0
  57. data/test/wiretap-images/monsters_002.tif +0 -0
  58. data/test/wiretap-images/monsters_003.tif +0 -0
  59. data/test/wiretap-images/output.mov +0 -0
  60. data/test/wiretap-images/output.wav +0 -0
  61. data/test/write_frames.rb +82 -0
  62. metadata +138 -0
data/ext/node.cpp ADDED
@@ -0,0 +1,401 @@
1
+ #include "wiretap.h"
2
+
3
+
4
+ static void node_free(WireTapNodeHandle* node) {
5
+ delete node;
6
+ }
7
+
8
+ static void node_leave(WireTapNodeHandle* node) {
9
+ }
10
+
11
+ static VALUE node_detect_klass(WireTapNodeHandle* node) {
12
+ int type;
13
+ NODERUN_E(node, node->getNodeType(type));
14
+ switch(type) {
15
+ case IFFFS_WT_TYPE_NODE: {
16
+ return cNode;
17
+ }
18
+ case IFFFS_WT_TYPE_HOST: {
19
+ return cHost;
20
+ }
21
+ case IFFFS_WT_TYPE_VOLUME: {
22
+ return cVolume;
23
+ }
24
+ case IFFFS_WT_TYPE_PROJECT: {
25
+ return cProject;
26
+ }
27
+ case IFFFS_WT_TYPE_LIBRARY: {
28
+ return cLibrary;
29
+ }
30
+ case IFFFS_WT_TYPE_REEL: {
31
+ return cReel;
32
+ }
33
+ case IFFFS_WT_TYPE_CLIP:
34
+ case IFFFS_WT_TYPE_CLIP_HIRES:
35
+ case IFFFS_WT_TYPE_CLIP_LOWRES:
36
+ case IFFFS_WT_TYPE_CLIP_SLATE: {
37
+ return cClip;
38
+ }
39
+ case IFFFS_WT_TYPE_CLIP_AUDIO:
40
+ case IFFFS_WT_TYPE_CLIP_AUDIO_STREAM: {
41
+ return cAudio;
42
+ }
43
+ case IFFFS_WT_TYPE_USER:
44
+ case IFFFS_WT_TYPE_SETUP:
45
+ case IFFFS_WT_TYPE_USER_PREFERENCE: {
46
+ }
47
+ }
48
+ return cNode;
49
+ }
50
+
51
+ VALUE wiretap_node_create_with(WireTapNodeHandle& node, VALUE server, VALUE parent) {
52
+ WireTapNodeHandle* new_node = new WireTapNodeHandle(node);
53
+
54
+ VALUE created_node = Data_Wrap_Struct(node_detect_klass(new_node), 0, node_free, new_node);
55
+ rb_iv_set(created_node, "@server", server);
56
+ rb_iv_set(created_node, "@parent", parent);
57
+ return created_node;
58
+ }
59
+
60
+
61
+ static VALUE wiretap_node_allocate(VALUE klass) {
62
+ WireTapNodeHandle* new_node = new WireTapNodeHandle();
63
+ return Data_Wrap_Struct(klass, 0, node_free, new_node);
64
+ }
65
+
66
+ static VALUE wiretap_node_get_id(VALUE self) {
67
+ Check_Node_Alive(self);
68
+
69
+ WireTapNodeHandle* node;
70
+ Data_Get_Struct(self, WireTapNodeHandle, node);
71
+ return rb_str_new2(node->getNodeId().id());
72
+ }
73
+
74
+ static VALUE wiretap_node_set_id(VALUE self, VALUE id) {
75
+ Check_Node_Alive(self);
76
+
77
+ WireTapNodeHandle* node;
78
+ Check_Type(id, T_STRING);
79
+ Data_Get_Struct(self, WireTapNodeHandle, node);
80
+ // node->setNodeId(WireTapNodeId(STR(id)));
81
+ return self;
82
+ }
83
+
84
+ static VALUE wiretap_node_reload(VALUE self) {
85
+ Check_Node_Alive(self);
86
+
87
+ WireTapNodeHandle* node;
88
+ Data_Get_Struct(self, WireTapNodeHandle, node);
89
+ WireTapNodeId id = node->getNodeId();
90
+ WireTapServerHandle server = node->getServer();
91
+ delete node;
92
+ *((WireTapNodeHandle **)&(RDATA(self)->data)) = new WireTapNodeHandle(server, id.id());
93
+ return self;
94
+ }
95
+
96
+ static VALUE wiretap_node_find(VALUE self, VALUE path) {
97
+ Check_Node_Alive(self);
98
+
99
+ WireTapNodeHandle* node;
100
+ Check_Type(path, T_STRING);
101
+ Data_Get_Struct(self, WireTapNodeHandle, node);
102
+
103
+ if(LEN(path) == 0) {
104
+ return self;
105
+ }
106
+ WireTapNodeHandle child;
107
+ if(!WireTapFindChild(*node, CSTR(path), child)) {
108
+ if(!node->lastError() || !*node->lastError()) {
109
+ return Qnil;
110
+ }
111
+ rb_raise(eError, "Problem while looking for child '%s': %s", CSTR(path), node->lastError());
112
+ }
113
+
114
+ return wiretap_node_create_with(child, rb_iv_get(self, "@server"), self);
115
+ }
116
+
117
+
118
+ static VALUE wiretap_clip_import_directory(VALUE self, VALUE dir_name) {
119
+ Check_Node_Alive(self);
120
+
121
+ Check_Type(dir_name, T_STRING);
122
+
123
+ WireTapNodeHandle* node;
124
+ Data_Get_Struct(self, WireTapNodeHandle, node);
125
+
126
+ int count = 0;
127
+ struct stat sb;
128
+ /*
129
+ * Mplayer decoding video always start writing frame from 00000001.ppm
130
+ */
131
+ for(int i = 1;; i++) {
132
+ char filename[PATH_MAX];
133
+ snprintf(filename, sizeof(filename), "%s/%08d.ppm", STR(dir_name), i);
134
+ if(stat(filename, &sb) != 0) {
135
+ break;
136
+ }
137
+ count = i;
138
+ }
139
+
140
+ if(count <= 0) {
141
+ return Qnil;
142
+ }
143
+
144
+
145
+ NODERUN_E(node, node->setNumFrames(count));
146
+ WireTapClipFormat format;
147
+ NODERUN_E(node, node->getClipFormat(format));
148
+ unsigned char frame[format.frameBufferSize()];
149
+
150
+ /** TODO - refactor to use write_frame **/
151
+
152
+ for(int i = 0; i < count; i++) {
153
+ char filename[PATH_MAX];
154
+ snprintf(filename, sizeof(filename), "%s/%08d.ppm", STR(dir_name), i+1);
155
+ //rb_warn("Opening file %s", filename);
156
+
157
+
158
+ FILE* infile = fopen(filename, "r");
159
+ if(!infile) {
160
+ THROW("Couldn't open file %s for read", filename);
161
+ }
162
+
163
+ if(!ppm_read_format(infile, NULL)) {
164
+ fclose(infile);
165
+ THROW("Couldn't read PPM format from file %s", filename);
166
+ }
167
+
168
+ if(!ppm_read_image(infile, frame, format.width(), format.height(), format.bitsPerPixel())) {
169
+ fclose(infile);
170
+ rb_warn("Couldn't read PPM image data from file %s", filename);
171
+ return Qnil;
172
+ }
173
+ fclose(infile);
174
+
175
+ NODERUN_E(node, node->writeFrame(i, frame, sizeof(frame)));
176
+ }
177
+ return self;
178
+ }
179
+
180
+ static VALUE wiretap_node_get_type(VALUE self) {
181
+ Check_Node_Alive(self);
182
+
183
+ WireTapNodeHandle* node;
184
+ Data_Get_Struct(self, WireTapNodeHandle, node);
185
+ WireTapStr type;
186
+ NODERUN_E(node, node->getNodeTypeStr(type));
187
+ return wiretap_to_str(type);
188
+ }
189
+
190
+ static VALUE wiretap_node_get_name(VALUE self) {
191
+ Check_Node_Alive(self);
192
+
193
+ WireTapNodeHandle* node;
194
+ Data_Get_Struct(self, WireTapNodeHandle, node);
195
+ WireTapStr name;
196
+ NODERUN_E(node, node->getDisplayName(name));
197
+ return wiretap_to_str(name);
198
+ }
199
+
200
+
201
+ static VALUE wiretap_node_create_node(int argc, VALUE* argv, VALUE self) {
202
+ Check_Node_Alive(self);
203
+
204
+ WireTapNodeHandle* node;
205
+ Data_Get_Struct(self, WireTapNodeHandle, node);
206
+ VALUE display_name, extended_type;
207
+
208
+ rb_scan_args(argc, argv, "11", &display_name, &extended_type);
209
+ Check_Type(display_name, T_STRING);
210
+ WireTapNodeHandle node_return;
211
+
212
+ if(extended_type == Qnil) {
213
+ extended_type = INT2FIX(0);
214
+ }
215
+ switch(TYPE(extended_type)) {
216
+ case T_FIXNUM:
217
+ NODERUN_E(node, node->createNode(CSTR(display_name), NUM2INT(extended_type), node_return));
218
+ break;
219
+ case T_STRING:
220
+ NODERUN_E(node, node->createNode(CSTR(display_name), CSTR(extended_type), node_return));
221
+ break;
222
+ default:
223
+ rb_raise(rb_eArgError, "extended type must be integer or string");
224
+ }
225
+
226
+ return wiretap_node_create_with(node_return, rb_iv_get(self, "@server"), self);
227
+ }
228
+
229
+
230
+ static VALUE wiretap_node_create_clip(int argc, VALUE* argv, VALUE self) {
231
+ WireTapNodeHandle* node;
232
+ Data_Get_Struct(self, WireTapNodeHandle, node);
233
+ VALUE display_name, extended_type, format;
234
+
235
+ Check_Node_Alive(self);
236
+
237
+ rb_scan_args(argc, argv, "12", &display_name, &extended_type, &format);
238
+ Check_Type(display_name, T_STRING);
239
+ WireTapNodeHandle node_return;
240
+
241
+ if(extended_type == Qnil) {
242
+ extended_type = INT2FIX(0);
243
+ }
244
+ if(format == Qnil) {
245
+ format = rb_funcall(self, rb_intern("format"), 0);
246
+ }
247
+
248
+ WireTapClipFormat *f;
249
+ Data_Get_Struct(format, WireTapClipFormat, f);
250
+
251
+ switch(TYPE(extended_type)) {
252
+ case T_FIXNUM:
253
+ NODERUN_E(node, node->createClipNode(CSTR(display_name), *f, NUM2INT(extended_type), node_return));
254
+ break;
255
+ case T_STRING:
256
+ NODERUN_E(node, node->createClipNode(CSTR(display_name), *f, CSTR(extended_type), node_return));
257
+ break;
258
+ default:
259
+ rb_raise(rb_eArgError, "extended type must be integer or string");
260
+ }
261
+
262
+ return wiretap_node_create_with(node_return, rb_iv_get(self, "@server"), self);
263
+ }
264
+
265
+
266
+ static VALUE wiretap_node_destroy(VALUE self) {
267
+ WireTapNodeHandle* node;
268
+ Data_Get_Struct(self, WireTapNodeHandle, node);
269
+ NODERUN_E(node, node->destroyNode());
270
+ rb_iv_set(self, "@destroyed", Qtrue);
271
+ return Qtrue;
272
+ }
273
+
274
+
275
+
276
+ /*
277
+ * Extract metadata from node
278
+ * @node.metadata
279
+ */
280
+ static VALUE wiretap_node_metadata(VALUE self) {
281
+ Check_Node_Alive(self);
282
+
283
+ WireTapNodeHandle* node;
284
+ Data_Get_Struct(self, WireTapNodeHandle, node);
285
+ VALUE metadata = Data_Wrap_Struct(cNodeMetaData, 0, node_leave, node);
286
+ rb_iv_set(metadata, "@node", self);
287
+
288
+ /*
289
+ WireTapStr metaDataBody; <--- !
290
+ node->getMetaData(streamName, filter, depth)
291
+ plainly speaking - somehow this has to happen, all that schtuff
292
+ */
293
+
294
+ return metadata;
295
+ }
296
+
297
+
298
+
299
+ static VALUE wiretap_clip_format(VALUE self) {
300
+ Check_Node_Alive(self);
301
+
302
+ WireTapNodeHandle* node;
303
+ Data_Get_Struct(self, WireTapNodeHandle, node);
304
+ WireTapClipFormat format;
305
+ NODERUN_E(node, node->getClipFormat(format));
306
+ VALUE clipformat = Data_Wrap_Struct(cClipFormat, 0, wiretap_format_free, new WireTapClipFormat(format));
307
+ rb_iv_set(clipformat, "@node", self);
308
+ return clipformat;
309
+ }
310
+
311
+
312
+ static VALUE wiretap_audio_format(VALUE self) {
313
+ Check_Node_Alive(self);
314
+
315
+ WireTapNodeHandle* node;
316
+ Data_Get_Struct(self, WireTapNodeHandle, node);
317
+ WireTapAudioFormat audio_format;
318
+ NODERUN_E(node, node->getClipFormat(audio_format));
319
+ VALUE audioformat = Data_Wrap_Struct(cAudioFormat, 0, wiretap_format_free, new WireTapAudioFormat(audio_format));
320
+ rb_iv_set(audioformat, "@node", self);
321
+ return audioformat;
322
+ }
323
+
324
+
325
+ static VALUE wiretap_clip_frames(VALUE self) {
326
+ Check_Node_Alive(self);
327
+
328
+ WireTapNodeHandle* node;
329
+ Data_Get_Struct(self, WireTapNodeHandle, node);
330
+ VALUE frames = Data_Wrap_Struct(cNodeFrames, 0, node_leave, node);
331
+ rb_iv_set(frames, "@node", self);
332
+ return frames;
333
+ }
334
+
335
+
336
+ static VALUE wiretap_audio_frames(VALUE self) {
337
+ Check_Node_Alive(self);
338
+
339
+ WireTapNodeHandle* node;
340
+ Data_Get_Struct(self, WireTapNodeHandle, node);
341
+ VALUE audioframes = Data_Wrap_Struct(cAudioFrames, 0, node_leave, node);
342
+ rb_iv_set(audioframes, "@node", self);
343
+ return audioframes;
344
+ }
345
+
346
+
347
+
348
+
349
+ void Init_node() {
350
+
351
+ cNode = rb_define_class_under(mWiretap, "Node", rb_cObject);
352
+ cClip = rb_define_class_under(mWiretap, "Clip", cNode);
353
+ cAudio = rb_define_class_under(mWiretap, "Audio", cNode);
354
+ cReel = rb_define_class_under(mWiretap, "Reel", cNode);
355
+ cLibrary = rb_define_class_under(mWiretap, "Library", cNode);
356
+ cProject = rb_define_class_under(mWiretap, "Project", cNode);
357
+ cVolume = rb_define_class_under(mWiretap, "Volume", cNode);
358
+ cHost = rb_define_class_under(mWiretap, "Host", cNode);
359
+
360
+ rb_define_alloc_func(cNode, wiretap_node_allocate);
361
+ rb_define_method(cNode, "id", VALUEFUNC(wiretap_node_get_id), 0);
362
+ rb_define_method(cNode, "id=", VALUEFUNC(wiretap_node_set_id), 1);
363
+ rb_define_method(cNode, "reload", VALUEFUNC(wiretap_node_reload), 0);
364
+
365
+ rb_define_method(cNode, "metadata", VALUEFUNC(wiretap_node_metadata), 0);
366
+
367
+ rb_define_method(cClip, "format", VALUEFUNC(wiretap_clip_format), 0);
368
+ rb_define_method(cAudio, "format", VALUEFUNC(wiretap_audio_format), 0);
369
+ rb_define_method(cClip, "frames", VALUEFUNC(wiretap_clip_frames), 0);
370
+ rb_define_method(cAudio, "frames", VALUEFUNC(wiretap_audio_frames), 0);
371
+
372
+
373
+
374
+ rb_define_method(cNode, "host?", VALUEFUNC(wiretap_false), -1);
375
+ rb_define_method(cNode, "volume?", VALUEFUNC(wiretap_false), -1);
376
+ rb_define_method(cNode, "project?", VALUEFUNC(wiretap_false), -1);
377
+ rb_define_method(cNode, "library?", VALUEFUNC(wiretap_false), -1);
378
+ rb_define_method(cNode, "reel?", VALUEFUNC(wiretap_false), -1);
379
+ rb_define_method(cNode, "clip?", VALUEFUNC(wiretap_false), -1);
380
+ rb_define_method(cNode, "audio?", VALUEFUNC(wiretap_false), -1);
381
+
382
+ rb_define_method(cHost, "host?", VALUEFUNC(wiretap_true), -1);
383
+ rb_define_method(cVolume, "volume?", VALUEFUNC(wiretap_true), -1);
384
+ rb_define_method(cProject, "project?", VALUEFUNC(wiretap_true), -1);
385
+ rb_define_method(cLibrary, "library?", VALUEFUNC(wiretap_true), -1);
386
+ rb_define_method(cReel, "reel?", VALUEFUNC(wiretap_true), -1);
387
+ rb_define_method(cClip, "clip?", VALUEFUNC(wiretap_true), -1);
388
+ rb_define_method(cAudio, "clip?", VALUEFUNC(wiretap_true), -1);
389
+ rb_define_method(cAudio, "audio?", VALUEFUNC(wiretap_true), -1);
390
+
391
+
392
+ rb_define_method(cNode, "find_child", VALUEFUNC(wiretap_node_find), 1);
393
+ rb_define_method(cNode, "type", VALUEFUNC(wiretap_node_get_type), 0);
394
+ rb_define_method(cNode, "name", VALUEFUNC(wiretap_node_get_name), 0);
395
+
396
+ rb_define_method(cClip, "import_directory", VALUEFUNC(wiretap_clip_import_directory), 1);
397
+ rb_define_protected_method(cNode, "create_node", VALUEFUNC(wiretap_node_create_node), -1);
398
+ rb_define_protected_method(cNode, "create_clip", VALUEFUNC(wiretap_node_create_clip), -1);
399
+
400
+ rb_define_method(cNode, "destroy!", VALUEFUNC(wiretap_node_destroy), 0);
401
+ }
@@ -0,0 +1,67 @@
1
+ #include "wiretap.h"
2
+
3
+
4
+ static void wiretap_node_children_free(WireTapNodeHandle* node) {
5
+ }
6
+
7
+
8
+ static VALUE wiretap_node_children_count(VALUE self) {
9
+ WireTapNodeHandle* node;
10
+ int num;
11
+ Data_Get_Struct(self, WireTapNodeHandle, node);
12
+ RUN(node->getNumChildren(num));
13
+ return INT2FIX(num);
14
+ }
15
+
16
+ static VALUE wiretap_node_children_get_at(VALUE self, VALUE index) {
17
+ WireTapNodeHandle* node;
18
+ Check_Type(index, T_FIXNUM);
19
+
20
+ Data_Get_Struct(self, WireTapNodeHandle, node);
21
+
22
+ WireTapNodeHandle child;
23
+ RUN(node->getChild(FIX2INT(index), child));
24
+
25
+ return wiretap_node_create_with(child, rb_iv_get(self, "@server"), rb_iv_get(self, "@node"));
26
+ }
27
+
28
+ static VALUE wiretap_node_children_each(VALUE self) {
29
+ WireTapNodeHandle* node;
30
+ int i, num;
31
+ Data_Get_Struct(self, WireTapNodeHandle, node);
32
+ RUN(node->getNumChildren(num));
33
+ VALUE server = rb_iv_get(self, "@server");
34
+ VALUE parent = rb_iv_get(self, "@node");
35
+
36
+ for(i = 0; i < num; i++) {
37
+ WireTapNodeHandle child;
38
+ RUN(node->getChild(i, child));
39
+ rb_yield(wiretap_node_create_with(child, server, parent));
40
+ }
41
+ return self;
42
+ }
43
+
44
+
45
+ static VALUE wiretap_node_children(VALUE self) {
46
+ Check_Node_Alive(self);
47
+
48
+ WireTapNodeHandle* node;
49
+ Data_Get_Struct(self, WireTapNodeHandle, node);
50
+ VALUE children = Data_Wrap_Struct(cNodeChildren, 0, wiretap_node_children_free, node);
51
+ rb_iv_set(children, "@node", self);
52
+ rb_iv_set(children, "@server", rb_iv_get(self, "@server"));
53
+ return children;
54
+ }
55
+
56
+
57
+ void Init_children() {
58
+
59
+ rb_define_method(cNode, "children", VALUEFUNC(wiretap_node_children), 0);
60
+ cNodeChildren = rb_define_class_under(mWiretap, "NodeChildren", rb_cObject);
61
+ rb_define_method(cNodeChildren, "count", VALUEFUNC(wiretap_node_children_count), 0);
62
+ rb_define_method(cNodeChildren, "[]", VALUEFUNC(wiretap_node_children_get_at), 1);
63
+ rb_define_method(cNodeChildren, "each", VALUEFUNC(wiretap_node_children_each), 0);
64
+
65
+ }
66
+
67
+
@@ -0,0 +1,233 @@
1
+ #include "wiretap.h"
2
+
3
+ #define NODERUN_E_FRAME(node, x) {if(!x) { \
4
+ frame.release(); \
5
+ rb_raise(eError, "Problem in wiretap: %s. File: %s: %d", node->lastError(), __FILE__, __LINE__); \
6
+ }}
7
+
8
+ /*
9
+ * Get frames count of clip
10
+ */
11
+ static VALUE wiretap_node_frames_count(VALUE self) {
12
+ WireTapNodeHandle* node;
13
+ int num;
14
+ Data_Get_Struct(self, WireTapNodeHandle, node);
15
+ NODERUN_E(node, node->getNumFrames(num));
16
+ return INT2FIX(num);
17
+ }
18
+
19
+ /*
20
+ * Set frames count in clip
21
+ */
22
+ static VALUE wiretap_node_frames_set_count(VALUE self, VALUE value) {
23
+ VALUE count = rb_funcall(value, rb_intern("to_i"), 0);
24
+
25
+ WireTapNodeHandle* node;
26
+ Data_Get_Struct(self, WireTapNodeHandle, node);
27
+ NODERUN_E(node, node->setNumFrames(NUM2INT(count)));
28
+ return count;
29
+ }
30
+
31
+ /*
32
+ * Get frame by index.
33
+ */
34
+ static VALUE wiretap_node_frames_get_at(VALUE self, VALUE index) {
35
+ WireTapNodeHandle* node;
36
+ Data_Get_Struct(self, WireTapNodeHandle, node);
37
+
38
+ Check_Type(index, T_FIXNUM);
39
+ WireTapClipFormat format;
40
+ RUN(node->getClipFormat(format));
41
+
42
+ VALUE frame = rb_str_buf_new(format.frameBufferSize());
43
+ RSTRING(frame)->len = format.frameBufferSize();
44
+
45
+ NODERUN_E(node, node->readFrame(FIX2INT(index), STR(frame), LEN(frame)));
46
+
47
+ return frame;
48
+ }
49
+
50
+ /*
51
+ * Set frame at index. Accepts the formatted Stone image buffer as value.
52
+ */
53
+ static VALUE wiretap_node_frames_set_at(VALUE self, VALUE index, VALUE value) {
54
+ WireTapNodeHandle* node;
55
+ Data_Get_Struct(self, WireTapNodeHandle, node);
56
+ Check_Type(index, T_STRING);
57
+ Check_Type(value, T_STRING);
58
+
59
+ NODERUN_E(node, node->writeFrame(FIX2INT(index), CSTR(value), LEN(value)));
60
+ return self;
61
+ }
62
+
63
+ /*
64
+ * Eval block on each frame
65
+ */
66
+ static VALUE wiretap_node_frames_each(VALUE self) {
67
+ WireTapNodeHandle* node;
68
+ int i, num;
69
+ Data_Get_Struct(self, WireTapNodeHandle, node);
70
+ RUN(node->getNumFrames(num));
71
+
72
+ WireTapClipFormat format;
73
+ RUN(node->getClipFormat(format));
74
+
75
+ for(i = 0; i < num; i++) {
76
+ VALUE frame = rb_str_buf_new(format.frameBufferSize());
77
+ RSTRING(frame)->len = format.frameBufferSize();
78
+
79
+ RUN(node->readFrame(i, STR(frame), LEN(frame)));
80
+ //rb_iv_set(frame, "@path", wiretap_node_frames_get_path_at(self, INT2FIX(i)));
81
+ rb_yield(frame);
82
+ }
83
+ return self;
84
+ }
85
+
86
+ /*
87
+ * Get path of frame at index
88
+ */
89
+ static VALUE wiretap_node_frames_get_path_at(VALUE self, VALUE index) {
90
+ WireTapNodeHandle* node;
91
+ Data_Get_Struct(self, WireTapNodeHandle, node);
92
+
93
+ Check_Type(index, T_FIXNUM);
94
+
95
+ WireTapStr path;
96
+ RUN(node->getFrameIdPath(FIX2INT(index), path));
97
+
98
+ return wiretap_to_str(path);
99
+ }
100
+
101
+
102
+ static void frame_prepare(VALUE self, WireTapNodeHandle** node, unsigned long* size, WireTapClipFormat** format) {
103
+ VALUE r_node = rb_iv_get(self, "@node");
104
+ VALUE r_format = rb_funcall(r_node, rb_intern("format"), 0);
105
+
106
+ WireTapNodeHandle* real_node;
107
+ Data_Get_Struct(self, WireTapNodeHandle, real_node);
108
+ *node = real_node;
109
+
110
+ WireTapClipFormat* real_format;
111
+ Data_Get_Struct(r_format, WireTapClipFormat, real_format);
112
+ *format = real_format;
113
+
114
+ *size = real_format->frameBufferSize();
115
+ }
116
+
117
+ /*
118
+ * Dump all frames into files, matched by pattern.
119
+ * @clip.frames.dump_all("/tmp/clip/%d.sgi")
120
+ *
121
+ * It is substituted via snprintf
122
+ */
123
+ static VALUE wiretap_node_frame_dump_all(VALUE self, VALUE file_pattern) {
124
+ WireTapNodeHandle* node;
125
+ unsigned long size;
126
+ WireTapClipFormat* format;
127
+ frame_prepare(self, &node, &size, &format);
128
+
129
+ int frame_count = NUM2INT(rb_funcall(self, rb_intern("count"), 0));
130
+ std::auto_ptr<unsigned char> frame(new unsigned char[size]);
131
+ for(int i = 0; i < frame_count; i++) {
132
+ NODERUN_E_FRAME(node, node->readFrame(i, frame.get(), size));
133
+ size_t buffer_size = PATH_MAX;
134
+ char file_name[buffer_size];
135
+ snprintf(file_name, buffer_size, STR(file_pattern), i);
136
+ wiretap_write_image_frame(format->width(), format->height(), format->bitsPerPixel(), frame.get(), file_name);
137
+ }
138
+
139
+ return self;
140
+ }
141
+
142
+ /*
143
+ * Dump one frame to file
144
+ */
145
+ static VALUE wiretap_node_frame_dump(VALUE self, VALUE index, VALUE file) {
146
+ WireTapNodeHandle* node;
147
+ unsigned long size;
148
+ WireTapClipFormat* format;
149
+ frame_prepare(self, &node, &size, &format);
150
+
151
+ std::auto_ptr<unsigned char> frame(new unsigned char[size]);
152
+ NODERUN_E_FRAME(node, node->readFrame(NUM2INT(index), frame.get(), size));
153
+
154
+ wiretap_write_image_frame(format->width(), format->height(), format->bitsPerPixel(), frame.get(), CSTR(file));
155
+ return self;
156
+ }
157
+
158
+ /*
159
+ * Read one frame from a PPM file. If this is the first frame (index 0) and the clip has no frames yet one frame will be allocated.
160
+ * You cannot change the number of frames afterwards.
161
+ * THIS METHOD SHOULD BE PRIVATE DAMN!
162
+ */
163
+ static VALUE wiretap_node_frame_write_from_file(VALUE self, VALUE index, VALUE filename) {
164
+ WireTapNodeHandle* node;
165
+ WireTapClipFormat format;
166
+
167
+ Data_Get_Struct(self, WireTapNodeHandle, node);
168
+ NODERUN_E(node, node->getClipFormat(format));
169
+
170
+ unsigned int bufSize = format.frameBufferSize();
171
+ std::auto_ptr<unsigned char> frame(new unsigned char[bufSize]);
172
+
173
+ int i = NUM2INT(index);
174
+
175
+ FILE* infile = fopen(CSTR(filename), "r");
176
+ if(!infile) {
177
+ frame.release();
178
+ THROW("Couldn't open file %s for reading", filename);
179
+ }
180
+
181
+ if(!ppm_read_format(infile, &format)) {
182
+ frame.release();
183
+ fclose(infile);
184
+ THROW("Couldn't read PPM format from file %s", filename);
185
+ }
186
+
187
+ if(!ppm_read_image(infile, frame.get(), format.width(), format.height(), format.bitsPerPixel())) {
188
+ frame.release();
189
+ fclose(infile);
190
+ THROW("Couldn't read PPM image data from file %s", filename);
191
+ }
192
+
193
+ fclose(infile);
194
+
195
+ int totalFrms;
196
+ NODERUN_E_FRAME(node, node->getNumFrames(totalFrms));
197
+
198
+ /* Edge case - If we are setting the first frame and the clip has no frames */
199
+ if ((totalFrms == i) && (i == 0)) {
200
+ NODERUN_E_FRAME(node, node->setNumFrames(i+1)); /* wiretapd will crash on setNumFrames(0) */
201
+ } else if (i >= totalFrms) {
202
+ /* Edge case - trying to add a frame to a clip after the fact will crash wiretapd */
203
+ frame.release();
204
+ THROW("You cannot add frames to an existing clip");
205
+ }
206
+
207
+ NODERUN_E_FRAME(node, node->writeFrame(i, frame.get(), bufSize));
208
+ return self;
209
+ }
210
+
211
+
212
+ void Init_nodeframes() {
213
+
214
+ cNodeFrames = rb_define_class_under(mWiretap, "NodeFrames", rb_cObject);
215
+
216
+ rb_define_method(cNodeFrames, "count", VALUEFUNC(wiretap_node_frames_count), 0);
217
+ rb_define_method(cNodeFrames, "count=", VALUEFUNC(wiretap_node_frames_set_count), 1);
218
+ rb_define_method(cNodeFrames, "[]", VALUEFUNC(wiretap_node_frames_get_at), 1);
219
+ rb_define_method(cNodeFrames, "[]=", VALUEFUNC(wiretap_node_frames_set_at), 2);
220
+ rb_define_method(cNodeFrames, "path_at", VALUEFUNC(wiretap_node_frames_get_path_at), 1);
221
+ rb_define_method(cNodeFrames, "each", VALUEFUNC(wiretap_node_frames_each), 0);
222
+
223
+ rb_define_method(cNodeFrames, "dump", VALUEFUNC(wiretap_node_frame_dump), 2);
224
+ rb_define_method(cNodeFrames, "dump_all", VALUEFUNC(wiretap_node_frame_dump_all), 1);
225
+
226
+ rb_define_method(cNodeFrames, "write_from_file", VALUEFUNC(wiretap_node_frame_write_from_file), 2);
227
+
228
+ cAudioFrames = rb_define_class_under(mWiretap, "AudioFrames", cNodeFrames);
229
+ rb_define_method(cAudioFrames, "dump", VALUEFUNC(wiretap_false), -1);
230
+ rb_define_method(cAudioFrames, "read", VALUEFUNC(wiretap_false), -1);
231
+ rb_define_method(cAudioFrames, "dump_all", VALUEFUNC(wiretap_false), -1);
232
+
233
+ }