wiretap 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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/format.cpp ADDED
@@ -0,0 +1,347 @@
1
+ #include "wiretap.h"
2
+
3
+ void wiretap_format_free(WireTapClipFormat* format) {
4
+ delete format;
5
+ }
6
+
7
+
8
+ static VALUE wiretap_clipformat_allocate(VALUE klass) {
9
+ return Data_Wrap_Struct(klass, 0, wiretap_format_free, new WireTapClipFormat());
10
+ }
11
+
12
+ static VALUE wiretap_audioformat_allocate(VALUE klass) {
13
+ return Data_Wrap_Struct(klass, 0, wiretap_format_free, new WireTapAudioFormat());
14
+ }
15
+
16
+ /*
17
+ * Get width of clip
18
+ */
19
+ static VALUE wiretap_format_get_width(VALUE self) {
20
+ WireTapClipFormat* format;
21
+ Data_Get_Struct(self, WireTapClipFormat, format);
22
+ return INT2FIX(format->width());
23
+ }
24
+
25
+ /*
26
+ * Set width of clip
27
+ */
28
+ static VALUE wiretap_format_set_width(VALUE self, VALUE value_) {
29
+ VALUE value = rb_funcall(value_, to_i, 0);
30
+
31
+ WireTapClipFormat* format;
32
+ Data_Get_Struct(self, WireTapClipFormat, format);
33
+ format->setWidth(NUM2INT(value));
34
+ return self;
35
+ }
36
+
37
+ /*
38
+ * Get height of clip
39
+ */
40
+ static VALUE wiretap_format_get_height(VALUE self) {
41
+ WireTapClipFormat* format;
42
+ Data_Get_Struct(self, WireTapClipFormat, format);
43
+ return INT2FIX(format->height());
44
+ }
45
+
46
+ /*
47
+ * Set height of clip
48
+ */
49
+ static VALUE wiretap_format_set_height(VALUE self, VALUE value_){
50
+ VALUE value = rb_funcall(value_, to_i, 0);
51
+
52
+ WireTapClipFormat* format;
53
+ Data_Get_Struct(self, WireTapClipFormat, format);
54
+ format->setHeight(NUM2INT(value));
55
+ return self;
56
+ }
57
+
58
+ /*
59
+ * Get bits per pixel in clip
60
+ */
61
+ static VALUE wiretap_format_get_bpp(VALUE self) {
62
+ WireTapClipFormat* format;
63
+ Data_Get_Struct(self, WireTapClipFormat, format);
64
+ return INT2FIX(format->bitsPerPixel());
65
+ }
66
+
67
+ /*
68
+ * Sets bits per pixel in clip
69
+ */
70
+ static VALUE wiretap_format_set_bpp(VALUE self, VALUE value_){
71
+ VALUE value = rb_funcall(value_, to_i, 0);
72
+
73
+ WireTapClipFormat* format;
74
+ Data_Get_Struct(self, WireTapClipFormat, format);
75
+ format->setBitsPerPixel(NUM2INT(value));
76
+ return self;
77
+ }
78
+
79
+ /*
80
+ * Get number of channels in clip
81
+ */
82
+ static VALUE wiretap_format_get_channels(VALUE self) {
83
+ WireTapClipFormat* format;
84
+ Data_Get_Struct(self, WireTapClipFormat, format);
85
+ return INT2FIX(format->numChannels());
86
+ }
87
+
88
+ /*
89
+ * Set number channels in clip
90
+ */
91
+ static VALUE wiretap_format_set_channels(VALUE self, VALUE value_){
92
+ VALUE value = rb_funcall(value_, to_i, 0);
93
+
94
+ WireTapClipFormat* format;
95
+ Data_Get_Struct(self, WireTapClipFormat, format);
96
+ format->setNumChannels(NUM2INT(value));
97
+ return self;
98
+ }
99
+
100
+ /*
101
+ * Get buffer size in clip. It is size of one frame (really a bit more).
102
+ * Usually, it is not required from ruby
103
+ */
104
+ static VALUE wiretap_format_get_buffer_size(VALUE self) {
105
+ WireTapClipFormat* format;
106
+ Data_Get_Struct(self, WireTapClipFormat, format);
107
+ return INT2FIX(format->frameBufferSize());
108
+ }
109
+
110
+ /*
111
+ * set buffer size for clip
112
+ */
113
+ static VALUE wiretap_format_set_buffer_size(VALUE self, VALUE value_){
114
+ VALUE value = rb_funcall(value_, to_i, 0);
115
+
116
+ WireTapClipFormat* format;
117
+ Data_Get_Struct(self, WireTapClipFormat, format);
118
+ format->setFrameBufferSize(NUM2INT(value));
119
+ return self;
120
+ }
121
+
122
+ /*
123
+ * Get frame rate per second of this clip
124
+ */
125
+ static VALUE wiretap_format_get_rate(VALUE self) {
126
+ WireTapClipFormat* format;
127
+ Data_Get_Struct(self, WireTapClipFormat, format);
128
+ return rb_float_new(double(format->frameRate()));
129
+ }
130
+
131
+ /*
132
+ * Set frame rate per second of this clip
133
+ */
134
+ static VALUE wiretap_format_set_rate(VALUE self, VALUE value_){
135
+ VALUE value = rb_funcall(value_, rb_intern("to_f"), 0);
136
+ WireTapClipFormat* format;
137
+ Data_Get_Struct(self, WireTapClipFormat, format);
138
+ format->setFrameRate(float(RFLOAT(value)->value));
139
+ return self;
140
+ }
141
+
142
+ /*
143
+ * Get pixel ratio of clip. It is not frame ratio, but pixel ratio
144
+ */
145
+ static VALUE wiretap_format_get_ratio(VALUE self) {
146
+ WireTapClipFormat* format;
147
+ Data_Get_Struct(self, WireTapClipFormat, format);
148
+ return rb_float_new(double(format->pixelRatio()));
149
+ }
150
+
151
+ /*
152
+ * Set pixel ratio of clip. It is not frame ratio, but pixel ratio
153
+ */
154
+ static VALUE wiretap_format_set_ratio(VALUE self, VALUE value_){
155
+ VALUE value = rb_funcall(value_, rb_intern("to_f"), 0);
156
+ WireTapClipFormat* format;
157
+ Data_Get_Struct(self, WireTapClipFormat, format);
158
+ format->setPixelRatio(float(RFLOAT(value)->value));
159
+ return self;
160
+ }
161
+
162
+ /*
163
+ * Get scan format of clip
164
+ */
165
+ static VALUE wiretap_format_get_scan(VALUE self) {
166
+ WireTapClipFormat* format;
167
+ Data_Get_Struct(self, WireTapClipFormat, format);
168
+ return ID2SYM(rb_intern(format->scanFormatStr(format->scanFormat())));
169
+ }
170
+
171
+ /*
172
+ * Set scan format of clip
173
+ */
174
+ static VALUE wiretap_format_set_scan(VALUE self, VALUE value){
175
+ WireTapClipFormat* format;
176
+ Data_Get_Struct(self, WireTapClipFormat, format);
177
+ VALUE scan = rb_funcall(value, rb_intern("to_s"), 0);
178
+ WireTapClipFormat::ScanFormat scan_format = format->strToScanFormat(CSTR(scan));
179
+ format->setScanFormat(scan_format);
180
+ return self;
181
+ }
182
+
183
+ /*
184
+ * Get format tag for clip
185
+ */
186
+ static VALUE wiretap_format_get_tag(VALUE self) {
187
+ WireTapClipFormat* format;
188
+ Data_Get_Struct(self, WireTapClipFormat, format);
189
+ return ID2SYM(rb_intern(format->formatTag()));
190
+ }
191
+
192
+ /*
193
+ * Set format tag for clip
194
+ */
195
+ static VALUE wiretap_format_set_tag(VALUE self, VALUE value){
196
+ WireTapClipFormat* format;
197
+ Data_Get_Struct(self, WireTapClipFormat, format);
198
+ VALUE tag = rb_funcall(value, rb_intern("to_s"), 0);
199
+ format->setFormatTag(CSTR(tag));
200
+ return self;
201
+ }
202
+
203
+ /*
204
+ * Get metadata for format
205
+ */
206
+ static VALUE wiretap_format_get_meta(VALUE self) {
207
+ WireTapClipFormat* format;
208
+ Data_Get_Struct(self, WireTapClipFormat, format);
209
+ return rb_str_new2(format->metaData());
210
+ }
211
+
212
+ /*
213
+ * Set metadata for format
214
+ */
215
+ static VALUE wiretap_format_set_meta(VALUE self, VALUE value){
216
+ WireTapClipFormat* format;
217
+ Data_Get_Struct(self, WireTapClipFormat, format);
218
+ VALUE meta = rb_funcall(value, rb_intern("to_s"), 0);
219
+ format->setMetaData(CSTR(meta));
220
+ return self;
221
+ }
222
+
223
+ /*
224
+ * Get meta tag of format
225
+ */
226
+ static VALUE wiretap_format_get_meta_tag(VALUE self) {
227
+ WireTapClipFormat* format;
228
+ Data_Get_Struct(self, WireTapClipFormat, format);
229
+ return ID2SYM(rb_intern(format->metaDataTag()));
230
+ }
231
+
232
+ /*
233
+ * Set meta tag for format
234
+ */
235
+ static VALUE wiretap_format_set_meta_tag(VALUE self, VALUE value){
236
+ WireTapClipFormat* format;
237
+ Data_Get_Struct(self, WireTapClipFormat, format);
238
+ VALUE meta = rb_funcall(value, rb_intern("to_s"), 0);
239
+ format->setMetaDataTag(CSTR(meta));
240
+ return self;
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+
248
+ /*
249
+ * Get number of audio samples in audio clip
250
+ */
251
+ static VALUE wiretap_format_get_samples(VALUE self) {
252
+ WireTapAudioFormat* format;
253
+ Data_Get_Struct(self, WireTapAudioFormat, format);
254
+ return INT2FIX(format->numSamples());
255
+ }
256
+
257
+ /*
258
+ * Set number of samples in audio clip
259
+ */
260
+ static VALUE wiretap_format_set_samples(VALUE self, VALUE value) {
261
+ WireTapAudioFormat* format;
262
+ Data_Get_Struct(self, WireTapAudioFormat, format);
263
+ format->setNumSamples(NUM2INT(value));
264
+ return self;
265
+ }
266
+
267
+ /*
268
+ * Get bits per sample in audio clip
269
+ */
270
+ static VALUE wiretap_format_get_bps(VALUE self) {
271
+ WireTapAudioFormat* format;
272
+ Data_Get_Struct(self, WireTapAudioFormat, format);
273
+ return INT2FIX(format->bitsPerSample());
274
+ }
275
+
276
+ /*
277
+ * Set bits per sample in audio clip
278
+ */
279
+ static VALUE wiretap_format_set_bps(VALUE self, VALUE value) {
280
+ WireTapAudioFormat* format;
281
+ Data_Get_Struct(self, WireTapAudioFormat, format);
282
+ format->setBitsPerSample(NUM2INT(value));
283
+ return self;
284
+ }
285
+
286
+ /*
287
+ * Get sample rate of the clip
288
+ */
289
+ static VALUE wiretap_format_get_sample_rate(VALUE self) {
290
+ WireTapAudioFormat* format;
291
+ Data_Get_Struct(self, WireTapAudioFormat, format);
292
+ return rb_float_new(double(format->sampleRate()));
293
+ }
294
+
295
+ /*
296
+ * Set sample rate of the clip
297
+ */
298
+ static VALUE wiretap_format_set_sample_rate(VALUE self, VALUE value){
299
+ WireTapAudioFormat* format;
300
+ Data_Get_Struct(self, WireTapAudioFormat, format);
301
+ format->setSampleRate(float(RFLOAT(value)->value));
302
+ return self;
303
+ }
304
+
305
+
306
+
307
+ void Init_format() {
308
+
309
+ cClipFormat = rb_define_class_under(mWiretap, "ClipFormat", rb_cObject);
310
+ rb_define_alloc_func(cClipFormat, wiretap_clipformat_allocate);
311
+ rb_define_method(cClipFormat, "width", VALUEFUNC(wiretap_format_get_width), 0);
312
+ rb_define_method(cClipFormat, "width=", VALUEFUNC(wiretap_format_set_width), 1);
313
+ rb_define_method(cClipFormat, "height", VALUEFUNC(wiretap_format_get_height), 0);
314
+ rb_define_method(cClipFormat, "height=", VALUEFUNC(wiretap_format_set_height), 1);
315
+ rb_define_method(cClipFormat, "bpp", VALUEFUNC(wiretap_format_get_bpp), 0);
316
+ rb_define_method(cClipFormat, "bpp=", VALUEFUNC(wiretap_format_set_bpp), 1);
317
+ rb_define_method(cClipFormat, "channels", VALUEFUNC(wiretap_format_get_channels), 0);
318
+ rb_define_method(cClipFormat, "channels=", VALUEFUNC(wiretap_format_set_channels), 1);
319
+ rb_define_method(cClipFormat, "buffer_size", VALUEFUNC(wiretap_format_get_buffer_size), 0);
320
+ rb_define_method(cClipFormat, "buffer_size=", VALUEFUNC(wiretap_format_set_buffer_size), 1);
321
+ rb_define_method(cClipFormat, "rate", VALUEFUNC(wiretap_format_get_rate), 0);
322
+ rb_define_method(cClipFormat, "rate=", VALUEFUNC(wiretap_format_set_rate), 1);
323
+ rb_define_method(cClipFormat, "ratio", VALUEFUNC(wiretap_format_get_ratio), 0);
324
+ rb_define_method(cClipFormat, "ratio=", VALUEFUNC(wiretap_format_set_ratio), 1);
325
+ rb_define_method(cClipFormat, "scan", VALUEFUNC(wiretap_format_get_scan), 0);
326
+ rb_define_method(cClipFormat, "scan=", VALUEFUNC(wiretap_format_set_scan), 1);
327
+ rb_define_method(cClipFormat, "tag", VALUEFUNC(wiretap_format_get_tag), 0);
328
+ rb_define_method(cClipFormat, "tag=", VALUEFUNC(wiretap_format_set_tag), 1);
329
+ rb_define_method(cClipFormat, "meta", VALUEFUNC(wiretap_format_get_meta), 0);
330
+ rb_define_method(cClipFormat, "meta=", VALUEFUNC(wiretap_format_set_meta), 1);
331
+ rb_define_method(cClipFormat, "meta_tag", VALUEFUNC(wiretap_format_get_meta_tag), 0);
332
+ rb_define_method(cClipFormat, "meta_tag=", VALUEFUNC(wiretap_format_set_meta_tag), 1);
333
+
334
+ cAudioFormat = rb_define_class_under(mWiretap, "AudioFormat", cClipFormat);
335
+ rb_define_alloc_func(cAudioFormat, wiretap_audioformat_allocate);
336
+ rb_define_method(cAudioFormat, "samples", VALUEFUNC(wiretap_format_get_samples), 0);
337
+ rb_define_method(cAudioFormat, "samples=", VALUEFUNC(wiretap_format_set_samples), 1);
338
+ rb_define_method(cAudioFormat, "bps", VALUEFUNC(wiretap_format_get_bps), 0);
339
+ rb_define_method(cAudioFormat, "bps=", VALUEFUNC(wiretap_format_set_bps), 1);
340
+ rb_define_method(cAudioFormat, "sample_rate", VALUEFUNC(wiretap_format_get_sample_rate), 0);
341
+ rb_define_method(cAudioFormat, "sample_rate=", VALUEFUNC(wiretap_format_set_sample_rate), 1);
342
+
343
+ }
344
+
345
+ #undef ATTRIBUTE
346
+
347
+
data/ext/image.h ADDED
@@ -0,0 +1,27 @@
1
+ #ifndef _WIRETAP_IMAGE_H_
2
+ #define _WIRETAP_IMAGE_H_
3
+
4
+ typedef struct _memstream {
5
+ unsigned char* ptr;
6
+ } memstream;
7
+ typedef struct _filestream {
8
+ int count;
9
+ unsigned char buffer[3];
10
+ FILE* f;
11
+ } filestream;
12
+
13
+ void write_to_memory(void *stream, unsigned char channel);
14
+ void write_to_file(void* file, unsigned char channel);
15
+ void write_to_file_bgr(void* file, unsigned char channel);
16
+ typedef void (*bitstream_writer)(void *data, unsigned char channel);
17
+ void write_string_value(char* value, bitstream_writer writer, void *data);
18
+
19
+
20
+ bool wiretap_write_frame_bmp(int width, int height, int bpp, unsigned char* frame, FILE* f);
21
+ bool wiretap_write_frame_sgi(int width, int height, int bpp, unsigned char* frame, FILE* f);
22
+
23
+ int wiretap_write_image_data(int width, int height, int bpp, const unsigned char* frame, bitstream_writer writer, void *data);
24
+
25
+ #endif /* _WIRETAP_IMAGE_H_ */
26
+
27
+
@@ -0,0 +1,194 @@
1
+ #include "wiretap.h"
2
+
3
+ enum {IMAGE_BMP, IMAGE_SGI};
4
+ int img_format = IMAGE_SGI;
5
+
6
+
7
+
8
+ static int wiretap_reduce_frame_bits24(const unsigned char* frame, int byte_length, bitstream_writer writer, void *data) {
9
+ for(int index = 0; index < byte_length; index++) {
10
+ writer(data, frame[index]);
11
+ }
12
+ return 0;
13
+ }
14
+
15
+
16
+ static int wiretap_reduce_frame_bits32(const unsigned char* frame, int byte_length, bitstream_writer writer, void *data) {
17
+ for(int index = 0; index < byte_length; index += 4) {
18
+ writer(data, frame[0]);
19
+
20
+ writer(data, frame[1] << 2 | frame[2] >> 6);
21
+
22
+ writer(data, frame[2] << 4 | frame[3] >> 4);
23
+ frame += 4;
24
+ }
25
+ return 0;
26
+ }
27
+
28
+
29
+
30
+ static int wiretap_reduce_frame_bits36(const unsigned char* frame, int byte_length, bitstream_writer writer, void *data) {
31
+
32
+ int orphan_index = 0;
33
+ int orphan[3*6]; //куски, которые пропускаем
34
+
35
+ int pixelnum = 0;
36
+
37
+ for(int index = 0; index < byte_length*2/9; index++) {
38
+ if (pixelnum == 6) //7й пиксель собираем и пропущеных кусков
39
+ {
40
+ writer(data, ((orphan[4] & 0xF) << 4) + (orphan[2] & 0xF)); // R
41
+ writer(data, ((orphan[5] & 0xF) << 4) + (orphan[3] & 0xF)); // G
42
+ writer(data, ((orphan[10] & 0xF) << 4) + (orphan[8] & 0xF));// B
43
+
44
+ pixelnum++;
45
+ continue;
46
+ }
47
+
48
+ if (pixelnum == 7) //8й пиксель тоже собираем из пропущеных кусков
49
+ {
50
+ writer(data, ((orphan[11] & 0xF) << 4) + (orphan[9] & 0xF)); // R
51
+ writer(data, ((orphan[16] & 0xF) << 4) + (orphan[14] & 0xF));// G
52
+ writer(data, ((orphan[17] & 0xF) << 4) + (orphan[15] & 0xF));// B
53
+
54
+ pixelnum = 0;
55
+ orphan_index = 0;
56
+
57
+ continue;
58
+ }
59
+
60
+ writer(data, *frame++); // R
61
+ orphan[orphan_index++] = *frame++;
62
+
63
+ writer(data, *frame++); // G
64
+ orphan[orphan_index++] = *frame++;
65
+
66
+ writer(data, *frame++); // B
67
+ orphan[orphan_index++] = *frame++;
68
+
69
+ pixelnum++;
70
+ }
71
+ return 0;
72
+ }
73
+
74
+ static int wiretap_reduce_frame_bits48(const unsigned char* frame, int byte_length, bitstream_writer writer, void* data) {
75
+ for(int index = 0; index < byte_length / 6; index++) {
76
+ writer(data, frame[index*6 + 0]);
77
+ writer(data, frame[index*6 + 2]);
78
+ writer(data, frame[index*6 + 4]);
79
+ }
80
+ return 0;
81
+ }
82
+
83
+ bool wiretap_write_image_frame(int width, int height, int bpp, unsigned char* frame, const char* filename) {
84
+ FILE *f = fopen(filename, "w+");
85
+ if(!f) {
86
+ THROW("Couldn't open file for dump: %s", filename);
87
+ }
88
+
89
+ switch(img_format) {
90
+ case IMAGE_SGI: {
91
+ wiretap_write_frame_sgi(width, height, bpp, frame, f);
92
+ break;
93
+ }
94
+ case IMAGE_BMP: {
95
+ wiretap_write_frame_bmp(width, height, bpp, frame, f);
96
+ break;
97
+ }
98
+ default: {
99
+ fclose(f);
100
+ THROW("Error. Wrong internal format provided: %d", img_format);
101
+ }
102
+ }
103
+ fclose(f);
104
+ return true;
105
+ }
106
+
107
+
108
+ void write_to_memory(void *stream, unsigned char channel) {
109
+ memstream* data = (memstream *)stream;
110
+ *data->ptr++ = channel;
111
+ }
112
+
113
+ void write_to_file(void *stream, unsigned char channel) {
114
+ filestream* data = (filestream *)stream;
115
+ fwrite(&channel, sizeof(channel), 1, data->f);
116
+ }
117
+
118
+
119
+
120
+ int reduced_frame_length(int byte_length, int bpp) {
121
+ const int bits_in_byte = 8;
122
+ const int bytes_in_pixel = 3;
123
+ // bpp/bits_in_byte - number of bytes per pixel in income frame. Maybe 3 (in case of 24bpp) or 4.5 (in case of 36bpp)
124
+ // byte_length/bytes_per_pixel - number of pixels in income frame
125
+ // number_pixels * 3 - number of pixels in outgoing frame
126
+ // 3 * byte_length/bpp * bits_in_byte
127
+ return (bytes_in_pixel * byte_length * bits_in_byte) / bpp;
128
+ }
129
+
130
+
131
+
132
+ int wiretap_write_image_data(int width, int height, int bpp, const unsigned char* frame, bitstream_writer writer, void *data) {
133
+ switch(bpp) {
134
+ case 24: {
135
+ wiretap_reduce_frame_bits24(frame, width*height*3, writer, data);
136
+ break;
137
+ }
138
+ case 30:
139
+ case 32: {
140
+ wiretap_reduce_frame_bits32(frame, width*height*4, writer, data);
141
+ break;
142
+ }
143
+ case 36: {
144
+ wiretap_reduce_frame_bits36(frame, width*height*9/2, writer, data);
145
+ break;
146
+ }
147
+ case 48: {
148
+ wiretap_reduce_frame_bits48(frame, width*height*6, writer, data);
149
+ break;
150
+ }
151
+ default: {
152
+ THROW("Unsupported color depth: %d", bpp);
153
+ }
154
+ }
155
+ return 0;
156
+ }
157
+
158
+
159
+ VALUE wiretap_dump_image_data(VALUE self, VALUE width, VALUE height, VALUE bpp, VALUE raw, VALUE filename) {
160
+ wiretap_write_image_frame(NUM2INT(width), NUM2INT(height), NUM2INT(bpp), (unsigned char* )STR(raw), CSTR(filename));
161
+ return Qtrue;
162
+ }
163
+
164
+ VALUE wiretap_set_dump_image_format(VALUE self, VALUE format) {
165
+ ID bmp, sgi, format_id;
166
+ bmp = rb_intern("bmp");
167
+ sgi = rb_intern("sgi");
168
+ Check_Type(format, T_SYMBOL);
169
+ format_id = SYM2ID(format);
170
+
171
+ if(format_id == bmp ) {
172
+ img_format = IMAGE_BMP;
173
+ } else if(format_id == sgi) {
174
+ img_format = IMAGE_SGI;
175
+ } else {
176
+ THROW("Unknown format");
177
+ }
178
+ return self;
179
+ }
180
+
181
+ VALUE wiretap_get_dump_image_format(VALUE self) {
182
+ switch(img_format) {
183
+ case IMAGE_SGI: return ID2SYM(rb_intern("sgi"));
184
+ case IMAGE_BMP: return ID2SYM(rb_intern("bmp"));
185
+ }
186
+ return Qnil;
187
+ }
188
+
189
+
190
+ void Init_image_format() {
191
+ rb_define_singleton_method(mWiretap, "dump_image_data", VALUEFUNC(wiretap_dump_image_data), 5);
192
+ rb_define_singleton_method(mWiretap, "dump_image_format=", VALUEFUNC(wiretap_set_dump_image_format), 1);
193
+ rb_define_singleton_method(mWiretap, "dump_image_format", VALUEFUNC(wiretap_get_dump_image_format), 0);
194
+ }