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/README CHANGED
@@ -24,7 +24,8 @@ For sound files:
24
24
  === Running the unit tests
25
25
 
26
26
  Define a RUBY_WIRETAP_TEST_HOST environment variable that will contain the hostname or IP address
27
- of your IFFS system. Make a PAL 720x576 8-bit project on the system and name it "RubyWiretapTest".
27
+ of your IFFS system. If you are running versions EARLIER than 2007 you will also have to
28
+ make a PAL 720x576 8-bit project on the system and name it "RubyWiretapTest".
28
29
 
29
30
  Run rake.
30
31
 
data/ext/Makefile CHANGED
@@ -4,55 +4,58 @@ SHELL = /bin/sh
4
4
  #### Start of system configuration section. ####
5
5
 
6
6
  srcdir = .
7
- topdir = /opt/local/lib/ruby/1.8/i686-darwin8.8.3
7
+ topdir = /usr/local/lib/ruby/1.8/powerpc-darwin8.8.0
8
8
  hdrdir = $(topdir)
9
9
  VPATH = $(srcdir):$(topdir):$(hdrdir)
10
- prefix = $(DESTDIR)/opt/local
11
- exec_prefix = $(DESTDIR)/opt/local
10
+ prefix = $(DESTDIR)/usr/local
11
+ exec_prefix = $(DESTDIR)/usr/local
12
12
  sitedir = $(prefix)/lib/ruby/site_ruby
13
13
  rubylibdir = $(libdir)/ruby/$(ruby_version)
14
+ docdir = $(datarootdir)/doc/$(PACKAGE)
15
+ dvidir = $(docdir)
16
+ datarootdir = $(prefix)/share
14
17
  archdir = $(rubylibdir)/$(arch)
15
18
  sbindir = $(exec_prefix)/sbin
16
- vendordir = $(prefix)/lib/ruby/vendor_ruby
17
- datadir = $(prefix)/share
19
+ psdir = $(docdir)
20
+ localedir = $(datarootdir)/locale
21
+ htmldir = $(docdir)
22
+ datadir = $(datarootdir)
18
23
  includedir = $(prefix)/include
19
- infodir = $(prefix)/info
24
+ infodir = $(datarootdir)/info
20
25
  sysconfdir = $(prefix)/etc
21
- mandir = $(DESTDIR)/opt/local/share/man
22
- libdir = $(DESTDIR)/opt/local/lib
26
+ mandir = $(datarootdir)/man
27
+ libdir = $(DESTDIR)/usr/local/lib
23
28
  sharedstatedir = $(prefix)/com
24
29
  oldincludedir = $(DESTDIR)/usr/include
30
+ pdfdir = $(docdir)
25
31
  sitearchdir = $(sitelibdir)/$(sitearch)
26
- vendorarchdir = $(vendorlibdir)/$(vendorarch)
27
32
  bindir = $(exec_prefix)/bin
28
33
  localstatedir = $(prefix)/var
29
- vendorlibdir = $(vendordir)/$(ruby_version)
30
34
  sitelibdir = $(sitedir)/$(ruby_version)
31
35
  libexecdir = $(exec_prefix)/libexec
32
36
 
33
37
  CC = g++
34
- LIBRUBY = $(LIBRUBY_SO)
38
+ LIBRUBY = $(LIBRUBY_A)
35
39
  LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
36
- LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
40
+ LIBRUBYARG_SHARED =
37
41
  LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
38
42
 
39
43
  RUBY_EXTCONF_H =
40
- CFLAGS = -fno-common -O -pipe -I/opt/local/include -fno-common -pipe -fno-common -I../../wiretap_api//api -Wall
41
- INCFLAGS = -I. -I. -I/opt/local/lib/ruby/1.8/i686-darwin8.8.3 -I.
42
- CPPFLAGS = -DHAVE_WIRETAPCLIENTAPI_H -DHAVE_SNDFILE_H -O -pipe -I/opt/local/include
44
+ CFLAGS = -fno-common -g -O2 -pipe -fno-common -I/Code/wiretap-api-stable/api -I/opt/local/include -I/opt/local/lib -Wall
45
+ INCFLAGS = -I. -I. -I/usr/local/lib/ruby/1.8/powerpc-darwin8.8.0 -I.
46
+ CPPFLAGS = -DHAVE_WIRETAPCLIENTAPI_H -DHAVE_SNDFILE_H
43
47
  CXXFLAGS = $(CFLAGS)
44
- DLDFLAGS = -L/opt/local/lib -L../../wiretap_api//lib/dbg/MACOSX/fat/Darwin_8_3_0/GCC_4_0_1/
45
- LDSHARED = cc -dynamic -bundle -undefined suppress -flat_namespace
48
+ DLDFLAGS = -L/Code/wiretap-api-stable/libs/Mac/OSX/gcc_3.3/dbg -L/usr/local/lib -L/opt/local/lib
49
+ LDSHARED = g++ -dynamic -bundle -undefined suppress -flat_namespace
46
50
  AR = ar
47
51
  EXEEXT =
48
52
 
49
53
  RUBY_INSTALL_NAME = ruby
50
54
  RUBY_SO_NAME = ruby
51
- arch = i686-darwin8.8.3
52
- sitearch = i686-darwin8.8.3
53
- vendorarch = i686-darwin8.8.3
55
+ arch = powerpc-darwin8.8.0
56
+ sitearch = powerpc-darwin8.8.0
54
57
  ruby_version = 1.8
55
- ruby = /opt/local/bin/ruby
58
+ ruby = /usr/local/bin/ruby
56
59
  RUBY = $(ruby)
57
60
  RM = rm -f
58
61
  MAKEDIRS = mkdir -p
@@ -76,9 +79,9 @@ extout =
76
79
  extout_prefix =
77
80
  target_prefix =
78
81
  LOCAL_LIBS =
79
- LIBS = $(LIBRUBYARG_SHARED) -lwiretapClientAPI -lsndfile -lpthread -ldl -lobjc
80
- SRCS = audio_format.cpp bmp.cpp format.cpp image_format.cpp node.cpp nodechildren.cpp nodeframes.cpp nodemetadata.cpp ppm.cpp server.cpp serverlist.cpp sgi.cpp thread_worker.cpp wiretap.cpp
81
- OBJS = audio_format.o bmp.o format.o image_format.o node.o nodechildren.o nodeframes.o nodemetadata.o ppm.o server.o serverlist.o sgi.o thread_worker.o wiretap.o
82
+ LIBS = -lwiretapClientAPI -lsndfile -lpthread -ldl -lobjc
83
+ SRCS = audio_format.cpp format.cpp frame_io.cpp image_format.cpp image_io.cpp node.cpp nodechildren.cpp nodeframes.cpp nodemetadata.cpp server.cpp serverlist.cpp thread_worker.cpp wiretap.cpp
84
+ OBJS = audio_format.o format.o frame_io.o image_format.o image_io.o node.o nodechildren.o nodeframes.o nodemetadata.o server.o serverlist.o thread_worker.o wiretap.o
82
85
  TARGET = wiretap_bin
83
86
  DLLIB = $(TARGET).bundle
84
87
  EXTSTATIC =
data/ext/audio_format.cpp CHANGED
@@ -94,7 +94,7 @@ int wiretap_write_audio_frame(int samples, int rate, int bps, ID type, unsigned
94
94
  SNDFILE *input = sf_open_virtual(&v_io, SFM_READ, &info, &vf);
95
95
 
96
96
  if(!input) {
97
- THROW("Couldn't open frame for reading");
97
+ THROW("Couldn't open audio frame for reading");
98
98
  }
99
99
 
100
100
  std::auto_ptr<float> output_items(new float[item_count]);
@@ -106,20 +106,20 @@ int wiretap_write_audio_frame(int samples, int rate, int bps, ID type, unsigned
106
106
  sf_close(input);
107
107
  if(error) {
108
108
  output_items.release();
109
- THROW("Waited to read %d frames, got %d: %s", item_count, size, error);
109
+ THROW("Did not reach %d frames, got %d: %s", item_count, size, error);
110
110
  }
111
111
 
112
112
  SF_INFO out_info = info;
113
113
  out_info.format = SF_FORMAT_AIFF | SF_FORMAT_PCM_16;
114
114
  if(!sf_format_check(&out_info)) {
115
115
  output_items.release();
116
- THROW("Invalid format provided for output file");
116
+ THROW("Invalid format provided for audio output file");
117
117
  }
118
118
 
119
119
  SNDFILE *output = sf_open(filename, SFM_RDWR, &out_info);
120
120
  if(!output) {
121
121
  output_items.release();
122
- THROW("Couldn't open file %s for write", filename);
122
+ THROW("Couldn't open file %s for writing", filename);
123
123
  }
124
124
  int out_size = sf_write_float(output, output_items.get(), item_count);
125
125
  output_items.release();
@@ -158,7 +158,10 @@ static VALUE wiretap_get_audio_format(VALUE self, VALUE filename) {
158
158
  return Data_Wrap_Struct(cAudioFormat, 0, wiretap_format_free, new WireTapAudioFormat(audio_format));
159
159
  }
160
160
 
161
- static VALUE wiretap_audio_import_music(VALUE self, VALUE filename) {
161
+ /*
162
+ * Importing music is possible on Audio clips
163
+ */
164
+ static VALUE wiretap_audio_import_audio_file(VALUE self, VALUE filename) {
162
165
  Check_Type(filename, T_STRING);
163
166
 
164
167
  SF_INFO sfinfo;
@@ -181,7 +184,7 @@ static VALUE wiretap_audio_import_music(VALUE self, VALUE filename) {
181
184
  return self;
182
185
  }
183
186
 
184
- /* This is called on node. Not on NodeFrames */
187
+ /* This is called on the node itself, but not on NodeFrames */
185
188
 
186
189
  static VALUE wiretap_audio_dump(VALUE self, VALUE file) {
187
190
  WireTapNodeHandle* node;
@@ -212,13 +215,12 @@ static VALUE wiretap_audio_dump(VALUE self, VALUE file) {
212
215
 
213
216
  #endif /* HAVE_SNDFILE_H */
214
217
 
215
-
216
218
  void Init_audio_format() {
217
219
  #ifdef HAVE_SNDFILE_H
218
220
  rb_define_singleton_method(mWiretap, "dump_audio_data", VALUEFUNC(wiretap_dump_audio_data), 6);
219
221
  rb_define_singleton_method(mWiretap, "audio_format", VALUEFUNC(wiretap_get_audio_format), 1);
220
222
 
221
- rb_define_method(cAudio, "import_music", VALUEFUNC(wiretap_audio_import_music), 1);
223
+ rb_define_method(cAudio, "import_audio!", VALUEFUNC(wiretap_audio_import_audio_file), 1);
222
224
  rb_define_method(cAudio, "dump", VALUEFUNC(wiretap_audio_dump), 1);
223
225
  #endif /* HAVE_SNDFILE_H */
224
226
  }
data/ext/charstream.h ADDED
@@ -0,0 +1,41 @@
1
+ #ifndef _CHARSTREAM_H_
2
+ #define _CHARSTREAM_H_
3
+ #include <stdio.h>
4
+
5
+ class charstream {
6
+ public:
7
+ charstream();
8
+ virtual void write_char(unsigned char channel);
9
+ virtual ~charstream();
10
+
11
+ void write_int32_le(int value);
12
+ void write_int32_be(int value);
13
+ void write_int16_le(short value);
14
+ void write_int16_be(short value);
15
+ void write_string(char* value);
16
+ };
17
+
18
+ class memstream : public charstream {
19
+ unsigned char* ptr;
20
+ public:
21
+ memstream(unsigned char* _ptr);
22
+ void write_char(unsigned char channel);
23
+ };
24
+
25
+ class filestream : public charstream {
26
+ FILE* f;
27
+ public:
28
+ filestream(FILE* _f);
29
+ void write_char(unsigned char channel);
30
+ };
31
+
32
+ class filestream_bgr : public charstream {
33
+ int count;
34
+ unsigned char buffer[3];
35
+ FILE* f;
36
+ public:
37
+ filestream_bgr(FILE* _f);
38
+ void write_char(unsigned char channel);
39
+ };
40
+
41
+ #endif /* _CHARSTREAM_H_ */
data/ext/extconf.rb CHANGED
@@ -6,11 +6,10 @@ CONFIG["CPP"] = "g++ -E "
6
6
  CONFIG["CC"] = "g++ "
7
7
  CONFIG["LDSHARED"].gsub!(/^cc /,"g++ ")
8
8
 
9
- #@wiretap_placements = [ "../../wiretap_api", "/Code/wiretap-api"]
10
9
  @wiretap_placements = []
11
-
12
- @includes = []
13
- @libraries = []
10
+ @includes = ["/opt/local/include", "/opt/local/lib", ]
11
+ @libraries = ["/usr/local/lib", "/opt/local/lib"]
12
+ @wiretap_placements << ENV['WIRETAP_INSTALL_DIR'] if ENV['WIRETAP_INSTALL_DIR']
14
13
 
15
14
  OptionParser.new do |opts|
16
15
  opts.on("-S PATH", "--sndfile-dir=PATH", "Prefix, where libsndfile is installed: /usr/local or /opt/local") do |path|
@@ -67,12 +66,12 @@ end
67
66
  $CFLAGS << include_flags
68
67
  $LDFLAGS << library_flags
69
68
 
70
- have_header "WireTapClientAPI.h"
69
+ have_header "WireTapClientAPI.h" or raise "We must have the Wiretap client header. Check the --wiretap-dir parameter"
71
70
  unless have_header("sndfile.h") && have_library("sndfile")
72
71
  puts "*********************"
73
- puts "You don't have libsndfile installed. You can use wiretap ruby binding without it,"
74
- puts "but You will not have support of audio."
75
- puts "If You install libsndfile, reinstall gem after it."
72
+ puts "You don't have libsndfile installed. You can use wiretap ruby bindings without it,"
73
+ puts "but without audio support. If you will be installing libsndfile, recompile the gem afterwards."
74
+ puts "Verify if you have audio by calling Wiretap::supports_audio?"
76
75
  end
77
76
  have_library "wiretapClientAPI", "WireTapClientInit" do <<-SRC
78
77
  #include <WireTapClientAPI.h>
@@ -81,5 +80,4 @@ int main(void) {
81
80
  }
82
81
  SRC
83
82
  end
84
- create_makefile "wiretap_bin"
85
-
83
+ create_makefile "wiretap_bin"
data/ext/frame_io.cpp ADDED
@@ -0,0 +1,120 @@
1
+ #include "frame_io.h"
2
+
3
+ FrameIO::FrameIO(unsigned char* _frame, int _width, int _height) {
4
+ frame = _frame;
5
+ width = _width;
6
+ height = _height;
7
+ length = 0;
8
+ }
9
+
10
+ FrameIO::~FrameIO() {}
11
+
12
+ FrameIO* FrameIO::decoder(unsigned char* frame, int width, int height, int bpp) {
13
+ switch(bpp) {
14
+ case 24: return new FrameIO_24(frame, width, height);
15
+ case 30:
16
+ case 32: return new FrameIO_32(frame, width, height);
17
+ case 36: return new FrameIO_36(frame, width, height);
18
+ case 48: return new FrameIO_48(frame, width, height);
19
+ }
20
+ return NULL;
21
+ }
22
+
23
+ unsigned char* FrameIO::get_frame() { return frame; }
24
+
25
+
26
+ FrameIO_24::FrameIO_24(unsigned char* _frame, int _width, int _height) : FrameIO(_frame, _width, _height) {
27
+ length = width*height*3;
28
+ }
29
+
30
+ void FrameIO_24::decode(charstream& writer, bool bit16) {
31
+ for(size_t index = 0; index < length; index++) {
32
+ writer.write_char(frame[index]);
33
+ // TODO: Here is only bigendian encoding
34
+ if(bit16) writer.write_char(0);
35
+ }
36
+ }
37
+
38
+ FrameIO_32::FrameIO_32(unsigned char* _frame, int _width, int _height) : FrameIO(_frame, _width, _height) {
39
+ length = width*height*4;
40
+ }
41
+
42
+ void FrameIO_32::decode(charstream& writer, bool bit16) {
43
+ unsigned char* frame = get_frame();
44
+ for(size_t index = 0; index < length; index += 4) {
45
+ short r = (short(frame[0]) << 2) + (frame[1] >> 6);
46
+ short g = (short(frame[1]) << 2) + (frame[2] >> 6);
47
+ short b = (short(frame[2]) << 4) + (frame[3] >> 4);
48
+ if(bit16) {
49
+ writer.write_int16_be(r);
50
+ writer.write_int16_be(g);
51
+ writer.write_int16_be(b);
52
+ } else {
53
+ writer.write_char((r >> 2) & 0xFF);
54
+ writer.write_char((g >> 2) & 0xFF);
55
+ writer.write_char((b >> 2) & 0xFF);
56
+ }
57
+ frame += 4;
58
+ }
59
+ }
60
+
61
+ FrameIO_36::FrameIO_36(unsigned char* _frame, int _width, int _height) : FrameIO(_frame, _width, _height) {
62
+ length = width*height*9/2;
63
+ }
64
+ void FrameIO_36::decode(charstream& writer, bool bit16) {
65
+ unsigned char* frame = get_frame();
66
+ int orphan_index = 0;
67
+ int orphan[3*6]; //куски, которые пропускаем
68
+
69
+ int pixelnum = 0;
70
+
71
+ for(size_t index = 0; index < length*2/9; index++) {
72
+ if (pixelnum == 6) //7й пиксель собираем и пропущеных кусков
73
+ {
74
+ writer.write_char(((orphan[4] & 0xF) << 4) + (orphan[2] & 0xF)); // R
75
+ writer.write_char(((orphan[5] & 0xF) << 4) + (orphan[3] & 0xF)); // G
76
+ writer.write_char(((orphan[10] & 0xF) << 4) + (orphan[8] & 0xF));// B
77
+
78
+ pixelnum++;
79
+ continue;
80
+ }
81
+
82
+ if (pixelnum == 7) //8й пиксель тоже собираем из пропущеных кусков
83
+ {
84
+ writer.write_char(((orphan[11] & 0xF) << 4) + (orphan[9] & 0xF)); // R
85
+ writer.write_char(((orphan[16] & 0xF) << 4) + (orphan[14] & 0xF));// G
86
+ writer.write_char(((orphan[17] & 0xF) << 4) + (orphan[15] & 0xF));// B
87
+
88
+ pixelnum = 0;
89
+ orphan_index = 0;
90
+
91
+ continue;
92
+ }
93
+
94
+ writer.write_char(*frame++); // R
95
+ orphan[orphan_index++] = *frame++;
96
+
97
+ writer.write_char(*frame++); // G
98
+ orphan[orphan_index++] = *frame++;
99
+
100
+ writer.write_char(*frame++); // B
101
+ orphan[orphan_index++] = *frame++;
102
+
103
+ pixelnum++;
104
+ }
105
+ }
106
+
107
+ FrameIO_48::FrameIO_48(unsigned char* _frame, int _width, int _height) : FrameIO(_frame, _width, _height) {
108
+ length = width*height*6;
109
+ }
110
+ void FrameIO_48::decode(charstream& writer, bool bit16) {
111
+ for(size_t index = 0; index < length / 6; index++) {
112
+ writer.write_char(frame[index*6 + 0]);
113
+ if(bit16) writer.write_char(frame[index*6 + 1]);
114
+ writer.write_char(frame[index*6 + 2]);
115
+ if(bit16) writer.write_char(frame[index*6 + 3]);
116
+ writer.write_char(frame[index*6 + 4]);
117
+ if(bit16) writer.write_char(frame[index*6 + 5]);
118
+ }
119
+ }
120
+
data/ext/frame_io.h ADDED
@@ -0,0 +1,45 @@
1
+ #ifndef _FRAME_IO_H_
2
+ #define _FRAME_IO_H_
3
+ #include "charstream.h"
4
+ #include "wiretap.h"
5
+
6
+
7
+ class FrameIO {
8
+ public:
9
+ FrameIO(unsigned char* _frame, int width, int height);
10
+ virtual void decode(charstream& writer, bool bit16 = false) = 0;
11
+ virtual ~FrameIO();
12
+ static FrameIO* decoder(unsigned char* frame, int width, int height, int bpp);
13
+ unsigned char* get_frame();
14
+ protected:
15
+ unsigned char* frame;
16
+ size_t length;
17
+ int width;
18
+ int height;
19
+ };
20
+
21
+ class FrameIO_24 : public FrameIO {
22
+ public:
23
+ FrameIO_24(unsigned char* _frame, int width, int height);
24
+ virtual void decode(charstream& writer, bool bit16 = false);
25
+ };
26
+
27
+ class FrameIO_32 : public FrameIO {
28
+ public:
29
+ FrameIO_32(unsigned char* _frame, int width, int height);
30
+ virtual void decode(charstream& writer, bool bit16 = false);
31
+ };
32
+
33
+ class FrameIO_36 : public FrameIO {
34
+ public:
35
+ FrameIO_36(unsigned char* _frame, int width, int height);
36
+ virtual void decode(charstream& writer, bool bit16 = false);
37
+ };
38
+
39
+ class FrameIO_48 : public FrameIO {
40
+ public:
41
+ FrameIO_48(unsigned char* _frame, int width, int height);
42
+ virtual void decode(charstream& writer, bool bit16 = false);
43
+ };
44
+
45
+ #endif /* _FRAME_IO_H_ */
data/ext/image_format.cpp CHANGED
@@ -1,194 +1,74 @@
1
1
  #include "wiretap.h"
2
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
3
 
83
4
  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
- }
5
+ WireTapClipFormat format;
6
+ format.setWidth(width);
7
+ format.setHeight(height);
8
+ format.setBitsPerPixel(bpp);
88
9
 
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
- }
10
+ std::auto_ptr<ImageIO> image(ImageIO::open(filename, format, false));
11
+ if(!image.get()) {
12
+ THROW("Couldn't guess image format for file: %s", filename);
102
13
  }
103
- fclose(f);
14
+ image->write_data(frame);
104
15
  return true;
105
16
  }
106
17
 
107
18
 
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
19
  VALUE wiretap_dump_image_data(VALUE self, VALUE width, VALUE height, VALUE bpp, VALUE raw, VALUE filename) {
160
20
  wiretap_write_image_frame(NUM2INT(width), NUM2INT(height), NUM2INT(bpp), (unsigned char* )STR(raw), CSTR(filename));
161
21
  return Qtrue;
162
22
  }
163
23
 
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");
24
+ /*
25
+ * Extract Wiretap clip format from image file. The format will inherit the bit depths of the image and allocate
26
+ * the framebuffer size into which the imported image will fit
27
+ *
28
+ * @clipformat = Wiretap::image_format("test/wiretap-images/01.ppm")
29
+ */
30
+ static VALUE wiretap_get_format(VALUE self, VALUE input) {
31
+ WireTapClipFormat format;
32
+ std::auto_ptr<ImageIO> image(ImageIO::open(CSTR(input), format));
33
+ if(!image.get()) {
34
+ THROW("Couldn't open file %s for reading", CSTR(input));
177
35
  }
178
- return self;
36
+ image->read_format();
37
+ VALUE clip_format = rb_funcall(cClipFormat, rb_intern("new"), 0);
38
+ DATA_PTR(clip_format) = new WireTapClipFormat(format);
39
+ return clip_format;
179
40
  }
180
41
 
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"));
42
+ /*
43
+ * Convert a PPM file to an SGI file
44
+ *
45
+ * Wiretap::convert_image("test/wiretap-images/01.ppm", "/tmp/a.sgi")
46
+ */
47
+ static VALUE wiretap_convert_image(VALUE self, VALUE input, VALUE output) {
48
+ Check_Type(input, T_STRING);
49
+ Check_Type(output, T_STRING);
50
+
51
+ WireTapClipFormat format;
52
+ std::auto_ptr<ImageIO> image(ImageIO::open(CSTR(input), format));
53
+ if(!image.get()) {
54
+ image.release();
55
+ THROW("Couldn't open file %s for read", CSTR(input));
56
+ }
57
+ image->read_format();
58
+ std::auto_ptr<unsigned char> frame(image->read_data());
59
+
60
+ if(!wiretap_write_image_frame(format.width(), format.height(), format.bitsPerPixel(), frame.get(), CSTR(output))) {
61
+ rb_warn("Couldn't dump image to file %s", CSTR(output));
62
+ return Qfalse;
185
63
  }
186
- return Qnil;
64
+ return Qtrue;
187
65
  }
188
66
 
189
67
 
68
+
190
69
  void Init_image_format() {
70
+ rb_define_singleton_method(mWiretap, "convert_image", VALUEFUNC(wiretap_convert_image), 2);
71
+ rb_define_singleton_method(mWiretap, "image_format", VALUEFUNC(wiretap_get_format), 1);
191
72
  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);
73
+ rb_define_singleton_method(mWiretap, "convert_image", VALUEFUNC(wiretap_convert_image), 2);
194
74
  }