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/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
+ }