wiretap 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +32 -0
- data/README +93 -0
- data/ext/Makefile +146 -0
- data/ext/audio_format.cpp +224 -0
- data/ext/bmp.cpp +65 -0
- data/ext/extconf.rb +85 -0
- data/ext/format.cpp +347 -0
- data/ext/image.h +27 -0
- data/ext/image_format.cpp +194 -0
- data/ext/node.cpp +401 -0
- data/ext/nodechildren.cpp +67 -0
- data/ext/nodeframes.cpp +233 -0
- data/ext/nodemetadata.cpp +90 -0
- data/ext/ppm.cpp +132 -0
- data/ext/server.cpp +202 -0
- data/ext/serverlist.cpp +183 -0
- data/ext/sgi.cpp +69 -0
- data/ext/testserver/Makefile +5 -0
- data/ext/testserver/cfg/wiretap_path_translation_db.xml +44 -0
- data/ext/testserver/cfg/wiretapd.cfg +74 -0
- data/ext/testserver/cfg/wiretapd.res +60 -0
- data/ext/testserver/db.sql +50 -0
- data/ext/testserver/server.cpp +206 -0
- data/ext/testserver/testserver.rb +146 -0
- data/ext/thread_worker.cpp +85 -0
- data/ext/wiretap.cpp +68 -0
- data/ext/wiretap.h +115 -0
- data/lib/wiretap.rb +280 -0
- data/test/audio.rb +27 -0
- data/test/convert.rb +35 -0
- data/test/image.rb +101 -0
- data/test/read_frames.rb +142 -0
- data/test/wiretap-images/01.ppm +0 -0
- data/test/wiretap-images/32bit.stoneimage +621 -0
- data/test/wiretap-images/36bit.stoneimage +1036 -0
- data/test/wiretap-images/48bit.stoneimage +800 -1
- 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/b1.stonesound +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/wiretap-images/output.wav +0 -0
- data/test/write_frames.rb +82 -0
- metadata +138 -0
data/ext/wiretap.cpp
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#include "wiretap.h"
|
2
|
+
|
3
|
+
|
4
|
+
VALUE mWiretap, mPPM, cServer, cNodeChildren, cServerList, cServerInfo;
|
5
|
+
VALUE cClipFormat, cAudioFormat, cNodeMetaData, cNodeFrames, cAudioFrames;
|
6
|
+
VALUE cNode, cHost, cVolume, cClip, cAudio, cReel, cLibrary, cProject;
|
7
|
+
VALUE eError;
|
8
|
+
ID to_i;
|
9
|
+
|
10
|
+
VALUE wiretap_to_str(WireTapStr& str) {
|
11
|
+
return rb_str_new(str.c_str(), str.length());
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
VALUE wiretap_false(int argc, VALUE* argv, VALUE self) {
|
16
|
+
return Qfalse;
|
17
|
+
}
|
18
|
+
VALUE wiretap_true(int argc, VALUE* argv, VALUE self) {
|
19
|
+
return Qtrue;
|
20
|
+
}
|
21
|
+
|
22
|
+
void wiretap_throw(const char *file, long unsigned int line, const char *fmt, ...) {
|
23
|
+
char* message;
|
24
|
+
va_list ap;
|
25
|
+
va_start(ap, fmt);
|
26
|
+
vasprintf(&message, fmt, ap);
|
27
|
+
va_end(ap);
|
28
|
+
|
29
|
+
char error_message[strlen(message) + 80];
|
30
|
+
snprintf(error_message, sizeof(error_message), "%s. File: %s, line: %lu", message, file, line);
|
31
|
+
free(message);
|
32
|
+
rb_raise(eError, error_message);
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
extern "C"
|
37
|
+
|
38
|
+
|
39
|
+
void Init_wiretap_bin() {
|
40
|
+
if ( !WireTapClientInit() ) {
|
41
|
+
rb_raise(rb_eStandardError, "Unable to init WireTap Client infrastructure");
|
42
|
+
}
|
43
|
+
to_i = rb_intern("to_i");
|
44
|
+
|
45
|
+
mWiretap = rb_define_module("Wiretap");
|
46
|
+
eError = rb_define_class_under(mWiretap, "Error", rb_eStandardError);
|
47
|
+
|
48
|
+
#ifdef HAVE_SNDFILE_H
|
49
|
+
rb_define_singleton_method(mWiretap, "supports_audio?", VALUEFUNC(wiretap_true), -1);
|
50
|
+
#else
|
51
|
+
rb_define_singleton_method(mWiretap, "supports_audio?", VALUEFUNC(wiretap_false), -1);
|
52
|
+
#endif
|
53
|
+
|
54
|
+
Init_ppm();
|
55
|
+
|
56
|
+
Init_server();
|
57
|
+
Init_node();
|
58
|
+
Init_children();
|
59
|
+
Init_metadata();
|
60
|
+
Init_nodeframes();
|
61
|
+
Init_format();
|
62
|
+
Init_image_format();
|
63
|
+
Init_audio_format();
|
64
|
+
Init_serverlist();
|
65
|
+
|
66
|
+
Init_thread_worker();
|
67
|
+
}
|
68
|
+
|
data/ext/wiretap.h
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#ifndef _WIRETAP_H_
|
2
|
+
#define _WIRETAP_H_
|
3
|
+
|
4
|
+
#include <WireTapClientAPI.h>
|
5
|
+
#include <ifffsWTTypes.h>
|
6
|
+
#include <stdlib.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <ctype.h>
|
9
|
+
#include "ruby.h"
|
10
|
+
#include "rubyio.h"
|
11
|
+
#include <sys/stat.h>
|
12
|
+
#include <sys/types.h>
|
13
|
+
#include <stdarg.h>
|
14
|
+
#include "image.h"
|
15
|
+
#include <memory>
|
16
|
+
|
17
|
+
|
18
|
+
#ifdef __cplusplus
|
19
|
+
# ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
|
20
|
+
# define PROTECTFUNC(f) ((VALUE (*)()) f)
|
21
|
+
# define VALUEFUNC(f) ((VALUE (*)()) f)
|
22
|
+
# define VOIDFUNC(f) ((void (*)()) f)
|
23
|
+
# else
|
24
|
+
# ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
|
25
|
+
# define PROTECTFUNC(f) ((VALUE (*)()) f)
|
26
|
+
# define VALUEFUNC(f) ((VALUE (*)()) f)
|
27
|
+
# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
|
28
|
+
# else /* These definitions should work for Ruby 1.7+ */
|
29
|
+
# define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
|
30
|
+
# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
|
31
|
+
# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
|
32
|
+
# endif
|
33
|
+
# endif
|
34
|
+
#else
|
35
|
+
# define VALUEFUNC(f) (f)
|
36
|
+
# define VOIDFUNC(f) (f)
|
37
|
+
#endif
|
38
|
+
|
39
|
+
#define STR(x) (RSTRING(x)->ptr)
|
40
|
+
#define SAFESTR(x) (x == Qnil ? NULL : RSTRING(x)->ptr)
|
41
|
+
#define CSTR(x) (const char *)(STR(x))
|
42
|
+
#define CSAFESTR(x) (const char *)(SAFESTR(x))
|
43
|
+
#define LEN(x) (RSTRING(x)->len)
|
44
|
+
#define RUN(x) if(!x) { return Qnil; }
|
45
|
+
#define NODERUN(node, x) {if(!x) { \
|
46
|
+
rb_warn("Problem in wiretap: %s. File: %s: %d", node->lastError(), __FILE__, __LINE__); \
|
47
|
+
return Qnil; \
|
48
|
+
}}
|
49
|
+
|
50
|
+
// Run a block with expression wrapping
|
51
|
+
#define RUN_E(expr, container) {if(!(expr)) { \
|
52
|
+
rb_raise(eError, "Problem in wiretap: %s. File: %s: %d", container->lastError(), __FILE__, __LINE__); \
|
53
|
+
}}
|
54
|
+
|
55
|
+
#define NODERUN_E(node, x) RUN_E(x, node)
|
56
|
+
#define SERVERRUN_E(server, x) RUN_E(x, server)
|
57
|
+
|
58
|
+
#define Check_Node_Alive(node) \
|
59
|
+
if(rb_iv_get(self, "@destroyed") == Qtrue) { \
|
60
|
+
rb_warn("Node is already destroyed"); \
|
61
|
+
return Qnil; \
|
62
|
+
} \
|
63
|
+
|
64
|
+
|
65
|
+
VALUE wiretap_false(int argc, VALUE* argv, VALUE self);
|
66
|
+
VALUE wiretap_true(int argc, VALUE* argv, VALUE self);
|
67
|
+
VALUE wiretap_to_str(WireTapStr &str);
|
68
|
+
|
69
|
+
#define THROW(message, ...) wiretap_throw(__FILE__, __LINE__, message, ##__VA_ARGS__)
|
70
|
+
void wiretap_throw(const char* file, long unsigned int line, const char *fmt, ...);
|
71
|
+
|
72
|
+
void Init_serverlist();
|
73
|
+
void Init_server();
|
74
|
+
void Init_node();
|
75
|
+
VALUE wiretap_node_create_with(WireTapNodeHandle& node, VALUE server, VALUE parent);
|
76
|
+
|
77
|
+
|
78
|
+
void Init_format();
|
79
|
+
void wiretap_format_free(WireTapClipFormat* format);
|
80
|
+
|
81
|
+
void Init_children();
|
82
|
+
void Init_metadata();
|
83
|
+
void Init_nodeframes();
|
84
|
+
|
85
|
+
void Init_ppm();
|
86
|
+
bool ppm_read_format(FILE* f, WireTapClipFormat* format);
|
87
|
+
bool ppm_read_image(FILE* f, unsigned char* frame, int width, int height, int bpp);
|
88
|
+
|
89
|
+
|
90
|
+
void Init_image_format();
|
91
|
+
bool wiretap_write_image_frame(int width, int height, int bpp, unsigned char* frame, const char* filename);
|
92
|
+
|
93
|
+
void Init_audio_format();
|
94
|
+
int wiretap_write_audio_frame(int samples, int rate, int bps, ID type, unsigned char* frame, const char* filename);
|
95
|
+
|
96
|
+
|
97
|
+
void Init_thread_worker();
|
98
|
+
|
99
|
+
extern "C" {
|
100
|
+
void Init_wiretap_bin(void);
|
101
|
+
extern VALUE mWiretap, mPPM, cServer, cServerList, cServerInfo;
|
102
|
+
extern VALUE cNode, cHost, cVolume, cClip, cAudio, cReel, cLibrary, cProject;
|
103
|
+
extern VALUE cNodeChildren, cNodeFrames, cAudioFrames, cNodeMetaData, cClipFormat, cAudioFormat;
|
104
|
+
extern VALUE eError;
|
105
|
+
extern ID to_i;
|
106
|
+
|
107
|
+
} /* extern "C" { */
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
|
113
|
+
#endif
|
114
|
+
|
115
|
+
|
data/lib/wiretap.rb
ADDED
@@ -0,0 +1,280 @@
|
|
1
|
+
begin
|
2
|
+
require File.dirname(__FILE__)+'/wiretap_bin'
|
3
|
+
rescue LoadError
|
4
|
+
require File.dirname(__FILE__)+'/../ext/wiretap_bin'
|
5
|
+
end
|
6
|
+
require 'timeout'
|
7
|
+
require 'socket'
|
8
|
+
|
9
|
+
module Wiretap
|
10
|
+
|
11
|
+
FRAMES_PATTERN = /[A-Z]_-(\d){10}_[A-Z]_(\d){10}_[A-Z]_(\d){6}/
|
12
|
+
class Server
|
13
|
+
def find(path)
|
14
|
+
root.find(path.split("/"))
|
15
|
+
end
|
16
|
+
alias :[] :find
|
17
|
+
|
18
|
+
def uri
|
19
|
+
hostname
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :real_alive? :alive?
|
23
|
+
def alive?
|
24
|
+
begin
|
25
|
+
Timeout.timeout(1) {TCPSocket.new(hostname,'7549')}
|
26
|
+
real_alive?
|
27
|
+
rescue
|
28
|
+
false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class ServerInfo
|
34
|
+
def uri
|
35
|
+
server.uri
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class ServerList
|
40
|
+
include Enumerable
|
41
|
+
end
|
42
|
+
|
43
|
+
class Reel
|
44
|
+
def uri
|
45
|
+
[parent.uri, name].join('/')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Node
|
50
|
+
attr_reader :server
|
51
|
+
attr_reader :parent
|
52
|
+
|
53
|
+
def [](path)
|
54
|
+
return find(path) if path.is_a?(String)
|
55
|
+
return children[path] if path.is_a?(Numeric)
|
56
|
+
end
|
57
|
+
|
58
|
+
def find(path)
|
59
|
+
return self if path.empty?
|
60
|
+
return (find_child(path.shift).find(path) rescue nil) if path.respond_to?(:shift)
|
61
|
+
find_child(path)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns a URL for the node that you can later pass to Wiretap::open
|
65
|
+
# Be alert though that it doesn't use the frame IDs - that is, if you have 7 reels of the same name and you ask
|
66
|
+
# for the uri of the second one, the first one is going to be reopened when you pass the uri to Wiretap::open
|
67
|
+
# This is done so that you can maintain "soft links" to specific objects on libraries instead of the frame IDs.
|
68
|
+
# When the clip gets edited you can still access it by name, although the frame IDs have changed.
|
69
|
+
def uri
|
70
|
+
self.server.hostname + '/' + self.id
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_s
|
74
|
+
"#<#{self.class.to_s} '#{self.name}', children: #{self.children.count}>"
|
75
|
+
end
|
76
|
+
alias :inspect :to_s
|
77
|
+
|
78
|
+
# Returns a list of names of all child nodes
|
79
|
+
def ls
|
80
|
+
children.map {|c| c.name}
|
81
|
+
end
|
82
|
+
|
83
|
+
# Creates a project as a child of the Volume node
|
84
|
+
def create_project(name)
|
85
|
+
node = create_node(name, "PROJECT")
|
86
|
+
yield node if block_given?
|
87
|
+
node
|
88
|
+
end
|
89
|
+
|
90
|
+
# Creates a library as a child of the Project node
|
91
|
+
def create_library(name)
|
92
|
+
node = create_node(name, "LIBRARY")
|
93
|
+
yield node if block_given?
|
94
|
+
node
|
95
|
+
end
|
96
|
+
|
97
|
+
# Creates a reel as a child of a Desktop or Library node
|
98
|
+
def create_reel(name)
|
99
|
+
node = create_node(name, "REEL")
|
100
|
+
yield node if block_given?
|
101
|
+
node
|
102
|
+
end
|
103
|
+
|
104
|
+
def import_video(name, file)
|
105
|
+
=begin
|
106
|
+
1. create directory
|
107
|
+
2. change to it
|
108
|
+
3. run mplayer -vo pnm -ao pcm:file=output.wav on our movie
|
109
|
+
4. format = Wiretap::PPM::format(Dir["."].entries.first)
|
110
|
+
5. create clip with this format
|
111
|
+
6. @clip.import_directory(".")
|
112
|
+
7. Find out format of output.wav
|
113
|
+
8. create audioclip with this format. NOTE: by default, output format from mplayer is dlaudio_int16_le
|
114
|
+
9. @audio.import_music("output.wav")
|
115
|
+
=end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Imports the first frame of an image in PPM format
|
119
|
+
def import_image(name, filename)
|
120
|
+
format = Wiretap::PPM::format(filename)
|
121
|
+
node = create_clip(name, "CLIP", format)
|
122
|
+
node.frames.count = 1
|
123
|
+
node.frames.write_from_file(0, filename)
|
124
|
+
node
|
125
|
+
end
|
126
|
+
|
127
|
+
# Destroys all the children of the node and node itself
|
128
|
+
def destroy
|
129
|
+
children.each {|child| child.destroy} rescue nil
|
130
|
+
destroy!
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Library
|
135
|
+
end
|
136
|
+
|
137
|
+
class Clip
|
138
|
+
def to_s
|
139
|
+
"#<#{self.class.to_s} '#{self.name}', frames: #{self.frames.count}>"
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns a name-based path to the clip (as opposed to the frame ID ranges provided by Wiretap ID)
|
143
|
+
def uri
|
144
|
+
ident = (self.server.hostname + '/' + self.id).split(/\//)
|
145
|
+
ident[-1] = name
|
146
|
+
ident[-2] = parent.name if parent.reel?
|
147
|
+
|
148
|
+
return ident.join('/')
|
149
|
+
end
|
150
|
+
|
151
|
+
def dump(path)
|
152
|
+
return unless frame_names = dump!(path)
|
153
|
+
fmt = format
|
154
|
+
mencoder_cmd = "mencoder mf://#{frame_names.join(",")} -mf w=#{fmt.width}:h=#{fmt.height}:fps=25:type=sgi " +
|
155
|
+
" -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:turbo -oac copy -o output.avi"
|
156
|
+
`(cd #{path} && #{mencoder_cmd} && ffmpeg -i output.avi output.mov) 2>&1 >/dev/null`
|
157
|
+
end
|
158
|
+
|
159
|
+
def to_video(path, options = {})
|
160
|
+
return unless frame_names = dump!(path)
|
161
|
+
fmt = format
|
162
|
+
|
163
|
+
if options[:resize]
|
164
|
+
target_width = options[:resize].split(/x/)[0]
|
165
|
+
target_height = options[:resize].split(/x/)[1]
|
166
|
+
|
167
|
+
frame_names.map! do | n |
|
168
|
+
`convert -resize #{options[:resize]}! #{File.join(path,n)} #{File.join(path,n +'.resized.sgi')}`
|
169
|
+
n + '.resized.sgi'
|
170
|
+
end
|
171
|
+
else
|
172
|
+
target_width = fmt.width
|
173
|
+
target_height = fmt.height
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
mencoder_cmd = "mencoder mf://#{frame_names.join(",")} -mf w=#{target_width}:h=#{target_height}:fps=25:type=sgi " +
|
178
|
+
" -ovc lavc -lavcopts vcodec=mpeg4:mbd=2:turbo -o output.avi"
|
179
|
+
|
180
|
+
begin
|
181
|
+
# Try to assimilate audio in the clip
|
182
|
+
find("#{self.name} (audio)").find("#{self.name} (stream)").dump "#{path}/audio.aiff"
|
183
|
+
`(cd #{path} && #{mencoder_cmd} && ffmpeg -i output.avi -acodec aac -i audio.aiff output.mov) 2>&1 >/dev/null`
|
184
|
+
rescue NoMethodError, Wiretap::Error
|
185
|
+
# No audio given, proceed with images only
|
186
|
+
`(cd #{path} && #{mencoder_cmd} && ffmpeg -i output.avi -acodec aac output.mov) 2>&1 >/dev/null`
|
187
|
+
end
|
188
|
+
|
189
|
+
outfile = path + "/output.mov"
|
190
|
+
File.unlink(path + "/0.sgi")
|
191
|
+
File.unlink(path + "/output.avi")
|
192
|
+
|
193
|
+
outfile
|
194
|
+
end
|
195
|
+
|
196
|
+
protected
|
197
|
+
def dump!(path)
|
198
|
+
return nil unless clip?
|
199
|
+
return nil if path.empty?
|
200
|
+
`rm -rf #{path}/*`
|
201
|
+
`mkdir -p #{path}`
|
202
|
+
self.frames.dump_all("#{path}/%d.sgi")
|
203
|
+
frame_names = (0...self.frames.count).to_a.map {|i| "#{i}.sgi" }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
class Audio
|
208
|
+
def to_s
|
209
|
+
"#<#{self.class.to_s} '#{self.name}'>"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
|
214
|
+
class NodeChildren
|
215
|
+
attr_reader :node
|
216
|
+
include Enumerable
|
217
|
+
alias_method :size, :count
|
218
|
+
alias_method :length, :count
|
219
|
+
end
|
220
|
+
|
221
|
+
class NodeFrames
|
222
|
+
attr_reader :node
|
223
|
+
include Enumerable
|
224
|
+
alias_method :size, :count
|
225
|
+
alias_method :length, :count
|
226
|
+
end
|
227
|
+
|
228
|
+
class AudioFrames
|
229
|
+
alias :real_dump :dump
|
230
|
+
def dump(index, filename)
|
231
|
+
FileUtils.rm_r(filename) rescue nil
|
232
|
+
real_dump(index, filename)
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
class NodeMetaData
|
237
|
+
attr_reader :node
|
238
|
+
include Enumerable
|
239
|
+
end
|
240
|
+
|
241
|
+
class ClipFormat
|
242
|
+
def initialize(options = {})
|
243
|
+
options.each do |key, value|
|
244
|
+
self.send("#{key}=".to_sym, value) if self.respond_to?("#{key}=".to_sym)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
|
249
|
+
attr_reader :node
|
250
|
+
@@audio_formats = [:dlaudio_mixed, :dlaudio_float, :dlaudio_float_le, :dlaudio_int16, :dlaudio_int16_le,
|
251
|
+
:dlaudio_int24, :dlaudio_int24_le, :wav, :aiff, :aifc, :dlaudio ]
|
252
|
+
def audio?
|
253
|
+
@@audio_formats.include? self.tag
|
254
|
+
end
|
255
|
+
|
256
|
+
def to_s
|
257
|
+
"#<Wiretap::ClipFormat size: #{self.width}x#{self.height}, bpp: #{self.bpp}, channels: #{self.channels}, rate: #{self.rate}, tag: #{self.tag}>"
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
class AudioFormat
|
262
|
+
def to_s
|
263
|
+
"#<Wiretap::AudioFormat samples: #{self.samples}, bps: #{self.bps}, sample rate: #{self.sample_rate}>"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
def self.open(uri)
|
269
|
+
return unless match_data = uri.match(/([^\/]+)(\/?)(.*)/)
|
270
|
+
server = Server.new(match_data.captures.first)
|
271
|
+
raise Wiretap::ServerDead, "Could not connect to Wiretap host #{match_data.captures.first}" unless server.alive?
|
272
|
+
|
273
|
+
return server if match_data.captures.last.empty?
|
274
|
+
server.find(match_data.captures.last)
|
275
|
+
end
|
276
|
+
|
277
|
+
class ServerDead < RuntimeError
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
data/test/audio.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/wiretap'
|
3
|
+
|
4
|
+
class AudioTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@samples = 48000
|
8
|
+
@rate = 48000.0
|
9
|
+
@bps = 32
|
10
|
+
@temp_outdir = "/tmp/wiretap_tests"
|
11
|
+
FileUtils.mkdir(@temp_outdir) rescue nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_read_audio
|
15
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/b1.stonesound") do |f|
|
16
|
+
Wiretap.dump_audio_data(@samples, @rate, @bps, :dlaudio_float, f.read(@samples*@bps/8), "#{@temp_outdir}/b1.aiff")
|
17
|
+
assert_equal "#{@temp_outdir}/b1.aiff: IFF data, AIFF audio\n", `file #{@temp_outdir}/b1.aiff`
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_get_format
|
22
|
+
assert @format = Wiretap.audio_format(File.dirname(__FILE__) + "/wiretap-images/output.wav")
|
23
|
+
assert_equal 16, @format.bps
|
24
|
+
assert_equal 48000.0, @format.rate
|
25
|
+
assert_equal 97280, @format.samples
|
26
|
+
end
|
27
|
+
end
|
data/test/convert.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/wiretap'
|
3
|
+
require 'benchmark'
|
4
|
+
|
5
|
+
|
6
|
+
class ConvertTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@temp_outdir = "/tmp/wiretap_tests/thread_convert"
|
10
|
+
`rm -rf #{@temp_outdir}`
|
11
|
+
`mkdir -p #{@temp_outdir} 2>/dev/null`
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
def test_convert
|
16
|
+
num = 1
|
17
|
+
iteration = 0
|
18
|
+
|
19
|
+
Wiretap::ThreadWorker::run do |i|
|
20
|
+
filename = File.dirname(__FILE__) + "/wiretap-images/importable-seq/#{(num).to_s.rjust(8, '0')}.ppm"
|
21
|
+
unless File.exists?(filename)
|
22
|
+
iteration += 1
|
23
|
+
if iteration == 100
|
24
|
+
break
|
25
|
+
end
|
26
|
+
num = 1
|
27
|
+
filename = File.dirname(__FILE__) + "/wiretap-images/importable-seq/#{(num).to_s.rjust(8, '0')}.ppm"
|
28
|
+
end
|
29
|
+
num += 1
|
30
|
+
"convert #{filename} #{@temp_outdir}/#{i.to_s.rjust(8,'0')}.jpg"
|
31
|
+
#{}"echo #{i} >> /tmp/log"
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/test/image.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/wiretap'
|
3
|
+
|
4
|
+
class ImageTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@width = 720
|
8
|
+
@height = 576
|
9
|
+
@temp_outdir = "/tmp/wiretap_tests"
|
10
|
+
`mkdir #{@temp_outdir} 2>/dev/null`
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_dump_bmp_24
|
14
|
+
Wiretap.dump_image_format = :bmp
|
15
|
+
0.upto(3) do |i|
|
16
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/a#{i}.stoneimage") do |f|
|
17
|
+
`rm -f #{@temp_outdir}/a#{i}.bmp`
|
18
|
+
Wiretap.dump_image_data(@width, @height, 24, f.read(@width*@height*3), "#{@temp_outdir}/a#{i}.bmp")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_dump_sgi_24
|
24
|
+
Wiretap.dump_image_format = :sgi
|
25
|
+
0.upto(3) do |i|
|
26
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/a#{i}.stoneimage") do |f|
|
27
|
+
`rm -f #{@temp_outdir}/a#{i}.sgi`
|
28
|
+
Wiretap.dump_image_data(@width, @height, 24, f.read(@width*@height*3), "#{@temp_outdir}/a#{i}.sgi")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_dump_bmp36
|
34
|
+
Wiretap.dump_image_format = :bmp
|
35
|
+
`rm -f #{@temp_outdir}/a4.bmp`
|
36
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/a4.stoneimage") do |f|
|
37
|
+
Wiretap.dump_image_data(@width, @height, 36, f.read(@width*@height*9/2), "#{@temp_outdir}/a4.bmp")
|
38
|
+
end
|
39
|
+
`rm -f #{@temp_outdir}/36bit.bmp`
|
40
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/36bit.stoneimage") do |f|
|
41
|
+
Wiretap.dump_image_data(@width, @height, 36, f.read(@width*@height*9/2), "#{@temp_outdir}/36bit.bmp")
|
42
|
+
# `open /tmp/36bit.sgi`
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_dump_sgi36
|
47
|
+
Wiretap.dump_image_format = :sgi
|
48
|
+
`rm -f #{@temp_outdir}/a4.sgi`
|
49
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/a4.stoneimage") do |f|
|
50
|
+
Wiretap.dump_image_data(@width, @height, 36, f.read(@width*@height*9/2), "#{@temp_outdir}/a4.sgi")
|
51
|
+
end
|
52
|
+
`rm -f #{@temp_outdir}/36bit.sgi`
|
53
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/36bit.stoneimage") do |f|
|
54
|
+
Wiretap.dump_image_data(@width, @height, 36, f.read(@width*@height*9/2), "#{@temp_outdir}/36bit.sgi")
|
55
|
+
# `open /tmp/36bit.sgi`
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_dump_bmp32
|
60
|
+
Wiretap.dump_image_format = :bmp
|
61
|
+
`rm -f #{@temp_outdir}/32bit.bmp`
|
62
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/32bit.stoneimage") do |f|
|
63
|
+
Wiretap.dump_image_data(@width, @height, 32, f.read(@width*@height*9/2), "#{@temp_outdir}/32bit.bmp")
|
64
|
+
# `open /tmp/32bit.sgi`
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def test_dump_sgi32
|
68
|
+
Wiretap.dump_image_format = :sgi
|
69
|
+
`rm -f #{@temp_outdir}/32bit.sgi`
|
70
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/32bit.stoneimage") do |f|
|
71
|
+
Wiretap.dump_image_data(@width, @height, 32, f.read(@width*@height*9/2), "#{@temp_outdir}/32bit.sgi")
|
72
|
+
# `open /tmp/32bit.sgi`
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_dump_sgi48
|
77
|
+
Wiretap.dump_image_format = :sgi
|
78
|
+
`rm -f #{@temp_outdir}/48bit.sgi`
|
79
|
+
File.open(File.dirname(__FILE__) + "/wiretap-images/48bit.stoneimage") do |f|
|
80
|
+
Wiretap.dump_image_data(@width, @height, 48, f.read(@width*@height*6), "#{@temp_outdir}/48bit.sgi")
|
81
|
+
# `open #{@temp_outdir}/48bit.sgi`
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_ppm_format
|
87
|
+
assert @format = Wiretap::PPM::format(File.dirname(__FILE__) + "/wiretap-images/01.ppm"), "Should retrieve format from ppm file"
|
88
|
+
assert_equal 720, @format.width
|
89
|
+
assert_equal 576, @format.height
|
90
|
+
assert_equal 24, @format.bpp
|
91
|
+
assert_equal 3, @format.channels
|
92
|
+
assert_equal 720*576*3, @format.buffer_size
|
93
|
+
assert_equal 25, @format.rate
|
94
|
+
assert_equal :progressive, @format.scan
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_ppm_to_sgi
|
98
|
+
assert Wiretap::PPM.to_sgi(File.dirname(__FILE__) + "/wiretap-images/01.ppm","#{@temp_outdir}/ppm1.sgi")
|
99
|
+
assert_equal "#{@temp_outdir}/ppm1.sgi: SGI image data, 3-D, 720 x 576, 3 channels\n", `file #{@temp_outdir}/ppm1.sgi`
|
100
|
+
end
|
101
|
+
end
|