wiretap 0.1
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/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
|