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.
- 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
|
}
|