wiretap 0.1 → 0.1.2

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 (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
+