wiretap 0.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +2 -1
- data/ext/Makefile +27 -24
- data/ext/audio_format.cpp +10 -8
- data/ext/charstream.h +41 -0
- data/ext/extconf.rb +8 -10
- data/ext/frame_io.cpp +120 -0
- data/ext/frame_io.h +45 -0
- data/ext/image_format.cpp +49 -169
- data/ext/image_io.cpp +466 -0
- data/ext/image_io.h +73 -0
- data/ext/node.cpp +71 -48
- data/ext/nodeframes.cpp +36 -34
- data/ext/nodemetadata.cpp +21 -3
- data/ext/server.cpp +2 -2
- data/ext/serverlist.cpp +20 -8
- data/ext/wiretap.cpp +11 -8
- data/ext/wiretap.h +17 -13
- data/lib/wiretap.rb +65 -5
- data/test_new/common.rb +8 -0
- data/{test/wiretap-images → test_new/fixtures/img/ppm-8bit}/01.ppm +0 -0
- data/test_new/fixtures/raw/cube_2k_12bitP_1f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_2k_8bit_1f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_10bit_5f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_10bit_5f/1.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_10bit_5f/2.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_10bit_5f/3.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_10bit_5f/4.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitP_5f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitP_5f/1.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitP_5f/2.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitP_5f/3.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitP_5f/4.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitU_5f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitU_5f/1.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitU_5f/2.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitU_5f/3.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_12bitU_5f/4.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/0.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/1.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/2.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/3.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/4.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/5.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/6.stoneimage +0 -0
- data/test_new/fixtures/raw/cube_SD_8bit_8f/7.stoneimage +0 -0
- data/{test/wiretap-images/b1.stonesound → test_new/fixtures/raw-snd/simple.stonesound} +0 -0
- data/{test/wiretap-images/output.wav → test_new/fixtures/snd/simple-wave.wav} +0 -0
- data/test_new/test_audio_conversions.rb +28 -0
- data/test_new/test_image_conversions.rb +132 -0
- data/test_new/test_parts/connect_to_test_host.rb +27 -0
- data/test_new/test_parts/constants.rb +7 -0
- data/test_new/test_parts/create_test_project.rb +37 -0
- data/test_new/test_parts/raw_formats_and_uploads.rb +170 -0
- data/test_new/test_parts/server_list.rb +20 -0
- data/test_new/test_parts/simple_node_lookup_and_browsing.rb +76 -0
- data/test_new/test_suite.rb +70 -0
- data/{test/convert.rb → test_new/test_thread_worker.rb} +2 -3
- metadata +71 -61
- data/ext/bmp.cpp +0 -65
- data/ext/image.h +0 -27
- data/ext/ppm.cpp +0 -132
- data/ext/sgi.cpp +0 -69
- data/test/audio.rb +0 -27
- data/test/image.rb +0 -101
- data/test/read_frames.rb +0 -142
- data/test/wiretap-images/32bit.stoneimage +0 -621
- data/test/wiretap-images/36bit.stoneimage +0 -1036
- data/test/wiretap-images/48bit.stoneimage +1 -800
- 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/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/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.
|
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 = /
|
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)/
|
11
|
-
exec_prefix = $(DESTDIR)/
|
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
|
-
|
17
|
-
|
19
|
+
psdir = $(docdir)
|
20
|
+
localedir = $(datarootdir)/locale
|
21
|
+
htmldir = $(docdir)
|
22
|
+
datadir = $(datarootdir)
|
18
23
|
includedir = $(prefix)/include
|
19
|
-
infodir = $(
|
24
|
+
infodir = $(datarootdir)/info
|
20
25
|
sysconfdir = $(prefix)/etc
|
21
|
-
mandir = $(
|
22
|
-
libdir = $(DESTDIR)/
|
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 = $(
|
38
|
+
LIBRUBY = $(LIBRUBY_A)
|
35
39
|
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
36
|
-
LIBRUBYARG_SHARED =
|
40
|
+
LIBRUBYARG_SHARED =
|
37
41
|
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
|
38
42
|
|
39
43
|
RUBY_EXTCONF_H =
|
40
|
-
CFLAGS = -fno-common -
|
41
|
-
INCFLAGS = -I. -I. -I/
|
42
|
-
CPPFLAGS = -DHAVE_WIRETAPCLIENTAPI_H -DHAVE_SNDFILE_H
|
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/
|
45
|
-
LDSHARED =
|
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 =
|
52
|
-
sitearch =
|
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 = /
|
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 =
|
80
|
-
SRCS = audio_format.cpp
|
81
|
-
OBJS = audio_format.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("
|
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
|
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
|
-
|
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
|
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, "
|
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
|
-
@
|
13
|
-
@
|
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
|
74
|
-
puts "but
|
75
|
-
puts "
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
5
|
+
WireTapClipFormat format;
|
6
|
+
format.setWidth(width);
|
7
|
+
format.setHeight(height);
|
8
|
+
format.setBitsPerPixel(bpp);
|
88
9
|
|
89
|
-
|
90
|
-
|
91
|
-
|
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
|
-
|
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
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
-
|
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
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
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, "
|
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
|
}
|