wiretap 0.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/README +2 -1
  2. data/ext/Makefile +27 -24
  3. data/ext/audio_format.cpp +10 -8
  4. data/ext/charstream.h +41 -0
  5. data/ext/extconf.rb +8 -10
  6. data/ext/frame_io.cpp +120 -0
  7. data/ext/frame_io.h +45 -0
  8. data/ext/image_format.cpp +49 -169
  9. data/ext/image_io.cpp +466 -0
  10. data/ext/image_io.h +73 -0
  11. data/ext/node.cpp +71 -48
  12. data/ext/nodeframes.cpp +36 -34
  13. data/ext/nodemetadata.cpp +21 -3
  14. data/ext/server.cpp +2 -2
  15. data/ext/serverlist.cpp +20 -8
  16. data/ext/wiretap.cpp +11 -8
  17. data/ext/wiretap.h +17 -13
  18. data/lib/wiretap.rb +65 -5
  19. data/test_new/common.rb +8 -0
  20. data/{test/wiretap-images → test_new/fixtures/img/ppm-8bit}/01.ppm +0 -0
  21. data/test_new/fixtures/raw/cube_2k_12bitP_1f/0.stoneimage +0 -0
  22. data/test_new/fixtures/raw/cube_2k_8bit_1f/0.stoneimage +0 -0
  23. data/test_new/fixtures/raw/cube_SD_10bit_5f/0.stoneimage +0 -0
  24. data/test_new/fixtures/raw/cube_SD_10bit_5f/1.stoneimage +0 -0
  25. data/test_new/fixtures/raw/cube_SD_10bit_5f/2.stoneimage +0 -0
  26. data/test_new/fixtures/raw/cube_SD_10bit_5f/3.stoneimage +0 -0
  27. data/test_new/fixtures/raw/cube_SD_10bit_5f/4.stoneimage +0 -0
  28. data/test_new/fixtures/raw/cube_SD_12bitP_5f/0.stoneimage +0 -0
  29. data/test_new/fixtures/raw/cube_SD_12bitP_5f/1.stoneimage +0 -0
  30. data/test_new/fixtures/raw/cube_SD_12bitP_5f/2.stoneimage +0 -0
  31. data/test_new/fixtures/raw/cube_SD_12bitP_5f/3.stoneimage +0 -0
  32. data/test_new/fixtures/raw/cube_SD_12bitP_5f/4.stoneimage +0 -0
  33. data/test_new/fixtures/raw/cube_SD_12bitU_5f/0.stoneimage +0 -0
  34. data/test_new/fixtures/raw/cube_SD_12bitU_5f/1.stoneimage +0 -0
  35. data/test_new/fixtures/raw/cube_SD_12bitU_5f/2.stoneimage +0 -0
  36. data/test_new/fixtures/raw/cube_SD_12bitU_5f/3.stoneimage +0 -0
  37. data/test_new/fixtures/raw/cube_SD_12bitU_5f/4.stoneimage +0 -0
  38. data/test_new/fixtures/raw/cube_SD_8bit_8f/0.stoneimage +0 -0
  39. data/test_new/fixtures/raw/cube_SD_8bit_8f/1.stoneimage +0 -0
  40. data/test_new/fixtures/raw/cube_SD_8bit_8f/2.stoneimage +0 -0
  41. data/test_new/fixtures/raw/cube_SD_8bit_8f/3.stoneimage +0 -0
  42. data/test_new/fixtures/raw/cube_SD_8bit_8f/4.stoneimage +0 -0
  43. data/test_new/fixtures/raw/cube_SD_8bit_8f/5.stoneimage +0 -0
  44. data/test_new/fixtures/raw/cube_SD_8bit_8f/6.stoneimage +0 -0
  45. data/test_new/fixtures/raw/cube_SD_8bit_8f/7.stoneimage +0 -0
  46. data/{test/wiretap-images/b1.stonesound → test_new/fixtures/raw-snd/simple.stonesound} +0 -0
  47. data/{test/wiretap-images/output.wav → test_new/fixtures/snd/simple-wave.wav} +0 -0
  48. data/test_new/test_audio_conversions.rb +28 -0
  49. data/test_new/test_image_conversions.rb +132 -0
  50. data/test_new/test_parts/connect_to_test_host.rb +27 -0
  51. data/test_new/test_parts/constants.rb +7 -0
  52. data/test_new/test_parts/create_test_project.rb +37 -0
  53. data/test_new/test_parts/raw_formats_and_uploads.rb +170 -0
  54. data/test_new/test_parts/server_list.rb +20 -0
  55. data/test_new/test_parts/simple_node_lookup_and_browsing.rb +76 -0
  56. data/test_new/test_suite.rb +70 -0
  57. data/{test/convert.rb → test_new/test_thread_worker.rb} +2 -3
  58. metadata +71 -61
  59. data/ext/bmp.cpp +0 -65
  60. data/ext/image.h +0 -27
  61. data/ext/ppm.cpp +0 -132
  62. data/ext/sgi.cpp +0 -69
  63. data/test/audio.rb +0 -27
  64. data/test/image.rb +0 -101
  65. data/test/read_frames.rb +0 -142
  66. data/test/wiretap-images/32bit.stoneimage +0 -621
  67. data/test/wiretap-images/36bit.stoneimage +0 -1036
  68. data/test/wiretap-images/48bit.stoneimage +1 -800
  69. data/test/wiretap-images/a.stoneimage +0 -0
  70. data/test/wiretap-images/a0.stoneimage +0 -0
  71. data/test/wiretap-images/a1.stoneimage +0 -0
  72. data/test/wiretap-images/a2.stoneimage +0 -0
  73. data/test/wiretap-images/a3.stoneimage +0 -0
  74. data/test/wiretap-images/a4.stoneimage +0 -0
  75. data/test/wiretap-images/importable-seq/00000001.ppm +0 -0
  76. data/test/wiretap-images/importable-seq/00000002.ppm +0 -0
  77. data/test/wiretap-images/importable-seq/00000003.ppm +0 -0
  78. data/test/wiretap-images/importable-seq/00000004.ppm +0 -0
  79. data/test/wiretap-images/importable-seq/00000005.ppm +0 -0
  80. data/test/wiretap-images/importable-seq/00000006.ppm +0 -0
  81. data/test/wiretap-images/importable-seq/00000007.ppm +0 -0
  82. data/test/wiretap-images/importable-seq/00000008.ppm +0 -0
  83. data/test/wiretap-images/importable-seq/00000009.ppm +0 -0
  84. data/test/wiretap-images/importable-seq/00000010.ppm +0 -0
  85. data/test/wiretap-images/importable-seq/00000011.ppm +0 -0
  86. data/test/wiretap-images/importable-seq/00000012.ppm +0 -0
  87. data/test/wiretap-images/monsters_001.tif +0 -0
  88. data/test/wiretap-images/monsters_002.tif +0 -0
  89. data/test/wiretap-images/monsters_003.tif +0 -0
  90. data/test/wiretap-images/output.mov +0 -0
  91. data/test/write_frames.rb +0 -82
data/ext/image_io.cpp ADDED
@@ -0,0 +1,466 @@
1
+ #include "wiretap.h"
2
+ #include <sys/types.h>
3
+ #include <sys/stat.h>
4
+
5
+ /************ Memstream writers *****************/
6
+ charstream::charstream() {}
7
+ void charstream::write_char(unsigned char channel) {}
8
+ charstream::~charstream() {}
9
+
10
+
11
+ void charstream::write_int32_le(int value) {
12
+ write_char(value >> 0 & 0xFF);
13
+ write_char(value >> 8 & 0xFF);
14
+ write_char(value >> 16& 0xFF);
15
+ write_char(value >> 24& 0xFF);
16
+ }
17
+
18
+ void charstream::write_int32_be(int value) {
19
+ write_char(value >> 24& 0xFF);
20
+ write_char(value >> 16& 0xFF);
21
+ write_char(value >> 8 & 0xFF);
22
+ write_char(value >> 0 & 0xFF);
23
+ }
24
+
25
+ void charstream::write_int16_le(short value) {
26
+ write_char(value >> 0 & 0xFF);
27
+ write_char(value >> 8 & 0xFF);
28
+ }
29
+
30
+ void charstream::write_int16_be(short value) {
31
+ write_char(value >> 8 & 0xFF);
32
+ write_char(value >> 0 & 0xFF);
33
+ }
34
+
35
+ void charstream::write_string(char* value) {
36
+ while(value && *value) {
37
+ write_char(*value);
38
+ value++;
39
+ }
40
+ }
41
+
42
+
43
+ memstream::memstream(unsigned char* _ptr) { ptr = _ptr; }
44
+ void memstream::write_char(unsigned char channel) {
45
+ *ptr++ = channel;
46
+ }
47
+
48
+ filestream::filestream(FILE* _f) { f = _f; }
49
+ void filestream::write_char(unsigned char channel) {
50
+ fwrite(&channel, sizeof(channel), 1, f);
51
+ }
52
+
53
+ filestream_bgr::filestream_bgr(FILE* _f){ f = _f; count = 0; memset(buffer, 0, sizeof(buffer)); }
54
+ void filestream_bgr::write_char(unsigned char channel) {
55
+ buffer[2 - count] = channel;
56
+ count++;
57
+ if(count == 3) {
58
+ fwrite(buffer, sizeof(buffer), 1, f);
59
+ count = 0;
60
+ }
61
+ }
62
+
63
+
64
+ /************ ImageIO *************/
65
+
66
+ ImageIO* ImageIO::open(const char* filename, WireTapClipFormat& format, bool read_only) {
67
+ FILE* infile = fopen(filename, read_only ? "r" : "w+");
68
+ if(!infile) {
69
+ THROW("Couldn't open file %s for %s", filename, read_only ? "reading" : "writing");
70
+ }
71
+ char *extension = 0;
72
+ for(extension = const_cast<char *>(filename) + strlen(filename); extension > filename; extension--) {
73
+ if(*extension == '.') {
74
+ extension++;
75
+ break;
76
+ }
77
+ }
78
+ if(!strcmp(extension, "ppm")) return new ImageIO_PPM(filename, infile, format);
79
+ if(!strcmp(extension, "sgi")) return new ImageIO_SGI(filename, infile, format);
80
+ if(!strcmp(extension, "bmp")) return new ImageIO_BMP(filename, infile, format);
81
+ if(!strcmp(extension, "stoneimage")) return new ImageIO_RAW(filename, infile, format);
82
+ return NULL;
83
+ }
84
+
85
+
86
+ int ImageIO::extract_int() {
87
+ char buffer[256];
88
+ int pos = 0;
89
+ char c;
90
+ while(!feof(this->f)) {
91
+ c = fgetc(this->f);
92
+ if(!isalnum(c)) {
93
+ break;
94
+ }
95
+ buffer[pos++] = c;
96
+ if(pos == sizeof(buffer)) break;
97
+ }
98
+ buffer[pos] = '\0';
99
+ return atoi(buffer);
100
+ }
101
+
102
+ int ImageIO::read_int32_be() {
103
+ unsigned char bytes[4];
104
+ fread(bytes, sizeof(bytes), 1, f);
105
+ return (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + (bytes[3]);
106
+ }
107
+
108
+ short ImageIO::read_int16_be() {
109
+ unsigned char bytes[2];
110
+ fread(bytes, sizeof(bytes), 1, f);
111
+ return (bytes[0] << 8) + (bytes[1]);
112
+ }
113
+
114
+ unsigned char ImageIO::read_int8() {
115
+ unsigned char byte;
116
+ fread(&byte, 1, 1, f);
117
+ return byte;
118
+ }
119
+
120
+
121
+
122
+ ImageIO::ImageIO(const char* _filename, FILE* _f, WireTapClipFormat& _format) : format(_format) {
123
+ filename = _filename;
124
+ f = _f;
125
+ }
126
+
127
+
128
+ ImageIO::~ImageIO() {
129
+ if(f) {
130
+ fclose(f);
131
+ }
132
+ }
133
+
134
+
135
+ void ImageIO::decode_image_data(unsigned char* frame, charstream& writer) {
136
+ std::auto_ptr<FrameIO> frame_io(FrameIO::decoder(frame, format.width(), format.height(), format.bitsPerPixel()));
137
+ if(!frame_io.get()) {
138
+ THROW("Unsupported color depth for dumping image: %d", format.bitsPerPixel());
139
+ }
140
+ frame_io->decode(writer);
141
+ }
142
+
143
+ /************** PPM format *****************/
144
+
145
+ ImageIO_PPM::ImageIO_PPM(const char* _filename, FILE* _f, WireTapClipFormat& _format) : ImageIO(_filename, _f, _format) {
146
+ }
147
+
148
+ void ImageIO_PPM::read_format() {
149
+ extract_int();
150
+
151
+ format.setWidth(extract_int());
152
+ format.setHeight(extract_int());
153
+
154
+ int maxval = extract_int();
155
+ if(maxval > 255) {
156
+ //FIXME: possible memory leak in using function.
157
+ THROW("Decoding 16bit PPM files is not supported");
158
+ }
159
+
160
+ format.setBitsPerPixel(24);
161
+ format.setNumChannels(3);
162
+ format.setFrameBufferSize((format.bitsPerPixel()/8)*format.width()*format.height());
163
+ format.setFrameRate(25);
164
+ format.setScanFormat(format.strToScanFormat("progressive"));
165
+ format.setFormatTag("rgb");
166
+ format.setMetaDataTag("IFFFS_XML");
167
+ format.setMetaData("<IFFFS_XML Version=\"1.0\"><ClipData></ClipData></IFFFS_XML>");
168
+ }
169
+
170
+
171
+ unsigned char* ImageIO_PPM::read_data() {
172
+ unsigned char* frame = new unsigned char[format.frameBufferSize()];
173
+
174
+ size_t row_size = format.width()*3;
175
+
176
+ for(int i = 0; i < format.height(); i++) {
177
+ size_t read_bytes = fread(frame + (format.height() - 1 - i)*row_size, 1, row_size, f);
178
+ if(read_bytes != row_size) {
179
+ rb_warn("Read %d bytes, expected %d. Step: %d", read_bytes, row_size, i);
180
+ return 0;
181
+ }
182
+ }
183
+
184
+ return frame;
185
+ }
186
+
187
+ void ImageIO_PPM::write_data(unsigned char* frame) {
188
+
189
+ }
190
+
191
+
192
+ /************** SGI format *****************/
193
+
194
+
195
+ ImageIO_SGI::ImageIO_SGI(const char* _filename, FILE* _f, WireTapClipFormat& _format) : ImageIO(_filename, _f, _format) {
196
+ compressed = false;
197
+ bit16 = false;
198
+ }
199
+
200
+ void ImageIO_SGI::read_format() {
201
+ const int header_padding = 404;
202
+ const int magic = 474;
203
+
204
+ short _magic = read_int16_be();
205
+ if(_magic != magic) {
206
+ rb_warn("Warning: %s has a broken file format: %d", filename, _magic);
207
+ }
208
+
209
+ compressed = read_int8() ? true : false;
210
+ switch(read_int8()) { // 1 for 1 byte per channel. 24 bit picture
211
+ case 1: format.setBitsPerPixel(24);
212
+ break;
213
+ case 2: format.setBitsPerPixel(48);
214
+ bit16 = true;
215
+ break;
216
+ }
217
+
218
+ format.setFrameBufferSize((format.bitsPerPixel()/8)*format.width()*format.height());
219
+ format.setFrameRate(25);
220
+ format.setScanFormat(format.strToScanFormat("progressive"));
221
+ format.setFormatTag("rgb");
222
+ format.setMetaDataTag("IFFFS_XML");
223
+ format.setMetaData("<IFFFS_XML Version=\"1.0\"><ClipData></ClipData></IFFFS_XML>");
224
+
225
+ short d;
226
+ if((d = read_int16_be()) != 3) {
227
+ rb_warn("Unknown number of dimensions: %d. Cannot read", d);
228
+ }
229
+ format.setWidth(read_int16_be());
230
+ format.setHeight(read_int16_be());
231
+ format.setNumChannels(read_int16_be());
232
+ /*int pix_min = */read_int32_be();
233
+ /*int pix_max = */read_int32_be();
234
+ read_int32_be(); // dummy
235
+
236
+ char image_name[80];
237
+ fread(image_name, sizeof(image_name), 1, f);
238
+
239
+ int cl;
240
+ if((cl = read_int32_be()) != 0) {
241
+ rb_warn("Unkwnown colormap: %d", cl);
242
+ }
243
+ char padding[header_padding];
244
+ fread(padding, sizeof(padding), 1, f);
245
+ if(compressed) {
246
+ int tablen = format.height()*3; //Only for colour pictures
247
+
248
+ start_table = std::auto_ptr<unsigned long>(new unsigned long[tablen]);
249
+ for(int i = 0; i < tablen; i++) {
250
+ start_table.get()[i] = read_int32_be();
251
+ }
252
+
253
+ length_table = std::auto_ptr<unsigned long>(new unsigned long[tablen]);
254
+ for(int i = 0; i < tablen; i++) {
255
+ length_table.get()[i] = read_int32_be();
256
+ }
257
+ }
258
+ }
259
+
260
+ unsigned char* ImageIO_SGI::read_channel(int channel) {
261
+ return compressed ? read_compressed(channel) : read_uncompressed(channel);
262
+ }
263
+
264
+ /*
265
+ * Decoding as here: http://www.martinreddy.net/gfx/2d/RGB.txt
266
+ */
267
+ unsigned char* ImageIO_SGI::read_compressed(int channel) {
268
+ int row_size = format.width()*format.bitsPerPixel()/24;
269
+ int line_size = row_size*format.height();
270
+ unsigned char* line = new unsigned char[line_size];
271
+ for(int rowno = 0; rowno < format.height(); rowno++) {
272
+ int compressed_row_length = length_table.get()[rowno + channel*format.height()];
273
+ std::auto_ptr<unsigned char> row_in(new unsigned char[compressed_row_length]);
274
+ fseek(f, start_table.get()[rowno + channel*format.height()], SEEK_SET);
275
+ fread(row_in.get(), compressed_row_length, 1, f);
276
+ expand_row(line + row_size*rowno, row_in.get());
277
+ }
278
+ return line;
279
+ }
280
+
281
+ void ImageIO_SGI::expand_row(unsigned char* optr, unsigned char* iptr) {
282
+ unsigned char pixel, count, pixel_high = 0;
283
+ while(1) {
284
+ pixel = *iptr++;
285
+ if(bit16) pixel = *iptr++;
286
+ if ( !(count = (pixel & 0x7f)) ) {
287
+ return;
288
+ }
289
+ if(pixel & 0x80) {
290
+ while(count--) {
291
+ *optr = *iptr++;
292
+ optr++;
293
+ if(bit16) {
294
+ *optr = *iptr++;
295
+ optr++;
296
+ }
297
+ }
298
+ } else {
299
+ pixel = *iptr++;
300
+ if(bit16) {
301
+ pixel_high = pixel;
302
+ pixel = *iptr++;
303
+ }
304
+ while(count--) {
305
+ if(bit16) {
306
+ *optr = pixel_high;
307
+ optr++;
308
+ }
309
+ *optr = pixel;
310
+ optr++;
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+
317
+ unsigned char* ImageIO_SGI::read_uncompressed(int channel) {
318
+ int line_size = format.width()*format.height()*format.bitsPerPixel()/24;
319
+ unsigned char* line = new unsigned char[line_size];
320
+ fread(line, line_size, 1, f);
321
+ return line;
322
+ }
323
+
324
+ unsigned char* ImageIO_SGI::read_data() {
325
+ int pixel_count = format.width()*format.height()*format.bitsPerPixel()/8;
326
+ unsigned char* frame = new unsigned char[pixel_count];
327
+ std::auto_ptr<unsigned char> line_r(read_channel(0));
328
+ std::auto_ptr<unsigned char> line_g(read_channel(1));
329
+ std::auto_ptr<unsigned char> line_b(read_channel(2));
330
+
331
+ int frame_ptr = 0;
332
+ int line_ptr = 0;
333
+ for(int i = 0; i < format.height(); i++) {
334
+ for(int j = 0; j < format.width(); j++) {
335
+ frame[frame_ptr++] = line_r.get()[line_ptr];
336
+ if(bit16) frame[frame_ptr++] = line_r.get()[line_ptr+1];
337
+ frame[frame_ptr++] = line_g.get()[line_ptr];
338
+ if(bit16) frame[frame_ptr++] = line_g.get()[line_ptr+1];
339
+ frame[frame_ptr++] = line_b.get()[line_ptr];
340
+ if(bit16) frame[frame_ptr++] = line_b.get()[line_ptr+1];
341
+ line_ptr++;
342
+ if(bit16) line_ptr++;
343
+ }
344
+ }
345
+ return frame;
346
+ }
347
+
348
+
349
+
350
+ static void write_channel(int width, int height, int number, unsigned char* frame, FILE* f) {
351
+ std::auto_ptr<unsigned char> buffer(new unsigned char[width*height]);
352
+ for(int i = 0; i < width*height; i++) {
353
+ buffer.get()[i] = frame[3*i + number];
354
+ }
355
+ fwrite(buffer.get(), width*height, 1, f);
356
+ }
357
+
358
+
359
+ static int wiretap_write_sgi_header(int width, int height, charstream& writer) {
360
+ //const int header_size = 512;
361
+ const int header_padding = 404;
362
+ const int magic = 474;
363
+
364
+ writer.write_int16_be(magic); // Magic 474
365
+ writer.write_char(0); // 0 for uncompressed
366
+ writer.write_char(1); // 1 for 1 byte per channel. 24 bit picture
367
+ writer.write_int16_be(3); // 3 dimensions - one plain image with multiple channels
368
+ writer.write_int16_be(width);
369
+ writer.write_int16_be(height);
370
+ writer.write_int16_be(3); // 3 for RGB mode: 3 channels
371
+ writer.write_int32_be(0); // minimum pixel value
372
+ writer.write_int32_be(0xFF); // maximum pixel value
373
+ writer.write_int32_be(0); // dummy
374
+
375
+ char image_name[80] = "Ruby wiretap encoded";
376
+ for(size_t i = 0; i < sizeof(image_name); i++) {
377
+ writer.write_char(image_name[i]);
378
+ }
379
+
380
+ writer.write_int32_be(0); // colormap is in normal mode (0)
381
+ for(int i = 0; i < header_padding; i++) {
382
+ writer.write_char(0);
383
+ }
384
+ return 0;
385
+ }
386
+
387
+
388
+
389
+ void ImageIO_SGI::write_data(unsigned char* frame) {
390
+ std::auto_ptr<unsigned char> buffer(new unsigned char[format.width()*format.height()*3]);
391
+ filestream stream(f);
392
+ memstream mem(buffer.get());
393
+
394
+ wiretap_write_sgi_header(format.width(), format.height(), stream);
395
+ decode_image_data(frame, mem);
396
+
397
+ write_channel(format.width(), format.height(), 0, buffer.get(), f);
398
+ write_channel(format.width(), format.height(), 1, buffer.get(), f);
399
+ write_channel(format.width(), format.height(), 2, buffer.get(), f);
400
+ }
401
+
402
+
403
+
404
+ /************** BMP format *****************/
405
+
406
+ ImageIO_BMP::ImageIO_BMP(const char* _filename, FILE* _f, WireTapClipFormat& _format) : ImageIO(_filename, _f, _format) {
407
+ }
408
+
409
+ void ImageIO_BMP::read_format() {
410
+ }
411
+ unsigned char* ImageIO_BMP::read_data() {
412
+ return NULL;
413
+ }
414
+
415
+ void ImageIO_BMP::write_header() {
416
+ filestream writer(f);
417
+ const int header_size = 54;
418
+ int size = header_size + format.width() * format.height() * 3;
419
+ writer.write_string("BM"); // 0,1
420
+ writer.write_int32_le(size); // 2,3,4,5
421
+ writer.write_int32_le(0); // 6,7,8,9: reserved data
422
+ writer.write_int32_le(header_size); // 10,11,12,13: Image header ends.
423
+ writer.write_int32_le(40); // 14,15,16,17: Image information size
424
+ writer.write_int32_le(format.width()); // 18,19,20,21: Width
425
+ writer.write_int32_le(format.height()); // 22,23,24,25: Height
426
+ writer.write_int16_le(1); // 26,27: Number of color planes
427
+ writer.write_int16_le(24); // 28,29: Bits per pixel. We write only 24 bit images
428
+ writer.write_int32_le(0); // 30,31,32,33: Compression schema. None
429
+ writer.write_int32_le(format.width()*format.height()*3); // 34,35,36,37: raw data size. 3 bytes per pixel.
430
+ writer.write_int32_le(2834); // 38,39,40,41: horisontal resolution. Perhaprs 72 dpi. I don't know
431
+ writer.write_int32_le(2834); // 42,43,44,45: vertical resolution
432
+ writer.write_int32_le(0); // 46,47,48,49: number of colors
433
+ writer.write_int32_le(0); // 50,51,52,53: number of important colors
434
+ }
435
+
436
+
437
+ void ImageIO_BMP::write_data(unsigned char* frame) {
438
+ filestream_bgr stream_bgr(f);
439
+
440
+ write_header();
441
+ decode_image_data(frame, stream_bgr);
442
+ }
443
+
444
+
445
+ /************** RAW format *****************/
446
+ ImageIO_RAW::ImageIO_RAW(const char* _filename, FILE* _f, WireTapClipFormat& _format) : ImageIO(_filename, _f, _format) {
447
+ }
448
+
449
+ void ImageIO_RAW::read_format() {}
450
+ unsigned char* ImageIO_RAW::read_data() {
451
+ struct stat sb;
452
+ if(!stat(filename, &sb)) {
453
+ return NULL;
454
+ }
455
+ unsigned char* frame = new unsigned char[sb.st_size];
456
+ if(!fread(frame, sb.st_size, 1, f)) {
457
+ delete frame;
458
+ return NULL;
459
+ }
460
+ return frame;
461
+ }
462
+
463
+ void ImageIO_RAW::write_data(unsigned char* frame) {
464
+ fwrite(frame, format.frameBufferSize(), 1, f);
465
+ }
466
+
data/ext/image_io.h ADDED
@@ -0,0 +1,73 @@
1
+ #ifndef _IMAGE_IO_H_
2
+ #define _IMAGE_IO_H_
3
+ #include <string.h>
4
+ #include "charstream.h"
5
+
6
+
7
+
8
+
9
+ class ImageIO {
10
+ public:
11
+ virtual void read_format() = 0;
12
+ virtual unsigned char* read_data() = 0;
13
+ virtual void write_data(unsigned char* frame) = 0;
14
+
15
+ static ImageIO* open(const char* filename, WireTapClipFormat& format, bool read_only = true);
16
+ ImageIO(const char* _filename, FILE* _f, WireTapClipFormat& _format);
17
+ virtual ~ImageIO();
18
+ protected:
19
+ FILE* f;
20
+ const char* filename;
21
+ WireTapClipFormat& format;
22
+ int extract_int();
23
+ int read_int32_be();
24
+ short read_int16_be();
25
+ unsigned char read_int8();
26
+ void decode_image_data(unsigned char* frame, charstream& writer);
27
+ };
28
+
29
+ class ImageIO_SGI : public ImageIO {
30
+ public:
31
+ ImageIO_SGI(const char* filename, FILE* f, WireTapClipFormat& _format);
32
+ virtual void read_format();
33
+ virtual unsigned char* read_data();
34
+ virtual void write_data(unsigned char* frame);
35
+ protected:
36
+ bool compressed;
37
+ bool bit16;
38
+ std::auto_ptr<unsigned long> length_table;
39
+ std::auto_ptr<unsigned long> start_table;
40
+ unsigned char* read_channel(int channel);
41
+ unsigned char* read_uncompressed(int channel);
42
+ unsigned char* read_compressed(int channel);
43
+ void expand_row(unsigned char* optr, unsigned char* iptr);
44
+ };
45
+
46
+ class ImageIO_PPM : public ImageIO {
47
+ public:
48
+ ImageIO_PPM(const char* filename, FILE* f, WireTapClipFormat& _format);
49
+ virtual void read_format();
50
+ virtual unsigned char* read_data();
51
+ virtual void write_data(unsigned char* frame);
52
+ };
53
+
54
+ class ImageIO_BMP : public ImageIO {
55
+ public:
56
+ ImageIO_BMP(const char* filename, FILE* f, WireTapClipFormat& _format);
57
+ virtual void read_format();
58
+ virtual unsigned char* read_data();
59
+ virtual void write_data(unsigned char* frame);
60
+ protected:
61
+ void write_header();
62
+ };
63
+
64
+ class ImageIO_RAW : public ImageIO {
65
+ public:
66
+ ImageIO_RAW(const char* filename, FILE* f, WireTapClipFormat& _format);
67
+ virtual void read_format();
68
+ virtual unsigned char* read_data();
69
+ virtual void write_data(unsigned char* frame);
70
+ };
71
+
72
+ #endif /* _IMAGE_IO_H_ */
73
+