wiretap 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +32 -0
- data/README +93 -0
- data/ext/Makefile +146 -0
- data/ext/audio_format.cpp +224 -0
- data/ext/bmp.cpp +65 -0
- data/ext/extconf.rb +85 -0
- data/ext/format.cpp +347 -0
- data/ext/image.h +27 -0
- data/ext/image_format.cpp +194 -0
- data/ext/node.cpp +401 -0
- data/ext/nodechildren.cpp +67 -0
- data/ext/nodeframes.cpp +233 -0
- data/ext/nodemetadata.cpp +90 -0
- data/ext/ppm.cpp +132 -0
- data/ext/server.cpp +202 -0
- data/ext/serverlist.cpp +183 -0
- data/ext/sgi.cpp +69 -0
- data/ext/testserver/Makefile +5 -0
- data/ext/testserver/cfg/wiretap_path_translation_db.xml +44 -0
- data/ext/testserver/cfg/wiretapd.cfg +74 -0
- data/ext/testserver/cfg/wiretapd.res +60 -0
- data/ext/testserver/db.sql +50 -0
- data/ext/testserver/server.cpp +206 -0
- data/ext/testserver/testserver.rb +146 -0
- data/ext/thread_worker.cpp +85 -0
- data/ext/wiretap.cpp +68 -0
- data/ext/wiretap.h +115 -0
- data/lib/wiretap.rb +280 -0
- data/test/audio.rb +27 -0
- data/test/convert.rb +35 -0
- data/test/image.rb +101 -0
- data/test/read_frames.rb +142 -0
- data/test/wiretap-images/01.ppm +0 -0
- data/test/wiretap-images/32bit.stoneimage +621 -0
- data/test/wiretap-images/36bit.stoneimage +1036 -0
- data/test/wiretap-images/48bit.stoneimage +800 -1
- data/test/wiretap-images/a.stoneimage +0 -0
- data/test/wiretap-images/a0.stoneimage +0 -0
- data/test/wiretap-images/a1.stoneimage +0 -0
- data/test/wiretap-images/a2.stoneimage +0 -0
- data/test/wiretap-images/a3.stoneimage +0 -0
- data/test/wiretap-images/a4.stoneimage +0 -0
- data/test/wiretap-images/b1.stonesound +0 -0
- data/test/wiretap-images/importable-seq/00000001.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000002.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000003.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000004.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000005.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000006.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000007.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000008.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000009.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000010.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000011.ppm +0 -0
- data/test/wiretap-images/importable-seq/00000012.ppm +0 -0
- data/test/wiretap-images/monsters_001.tif +0 -0
- data/test/wiretap-images/monsters_002.tif +0 -0
- data/test/wiretap-images/monsters_003.tif +0 -0
- data/test/wiretap-images/output.mov +0 -0
- data/test/wiretap-images/output.wav +0 -0
- data/test/write_frames.rb +82 -0
- 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
|
+
}
|