depix 1.0.2 → 1.0.3
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/History.txt +4 -0
- data/README.txt +1 -1
- data/bin/depix-describe +5 -1
- data/lib/depix.rb +31 -5
- data/lib/depix/dict.rb +16 -2
- data/test/test_depix.rb +18 -4
- data/test/test_dict.rb +43 -7
- metadata +2 -2
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -8,7 +8,7 @@ Read DPX file metadata
|
|
8
8
|
|
9
9
|
== SYNOPSIS:
|
10
10
|
|
11
|
-
meta = Depix
|
11
|
+
meta = Depix.from_file(dpx_file_path)
|
12
12
|
puts meta.time_code #=> 10:00:00:02
|
13
13
|
|
14
14
|
The data returned is described in the DPX_HEADER_STRUCTURE[link:files/DPX_HEADER_STRUCTURE_txt.html]. It's
|
data/bin/depix-describe
CHANGED
@@ -15,5 +15,9 @@ end.parse!
|
|
15
15
|
ARGV.each do | file |
|
16
16
|
puts "Describing DPX #{file}. Empty elements are omitted.\n\n"
|
17
17
|
puts "===================================================\n\n"
|
18
|
-
|
18
|
+
begin
|
19
|
+
puts Depix.describe_file(file, options[:compact])
|
20
|
+
rescue Depix::InvalidHeader
|
21
|
+
puts " - Invalid header data"
|
22
|
+
end
|
19
23
|
end
|
data/lib/depix.rb
CHANGED
@@ -8,7 +8,9 @@ require File.dirname(__FILE__) + '/depix/compact_structs'
|
|
8
8
|
require File.dirname(__FILE__) + '/depix/enums'
|
9
9
|
|
10
10
|
module Depix
|
11
|
-
VERSION = '1.0.
|
11
|
+
VERSION = '1.0.3'
|
12
|
+
|
13
|
+
class InvalidHeader < RuntimeError; end
|
12
14
|
|
13
15
|
# Offers convenience access to a few common attributes bypassing the piecemeal structs
|
14
16
|
module Synthetics
|
@@ -16,8 +18,10 @@ module Depix
|
|
16
18
|
[film.id, film.type, film.offset, film.prefix, film.count].compact.join(' ')
|
17
19
|
end
|
18
20
|
|
21
|
+
# Return the flame reel name. The data after the first null byte is not meant to be seen and is used by Flame internally
|
22
|
+
# as it seems
|
19
23
|
def flame_reel
|
20
|
-
orientation.device.
|
24
|
+
orientation.device.split("\000").shift
|
21
25
|
end
|
22
26
|
|
23
27
|
def time_code
|
@@ -71,16 +75,38 @@ module Depix
|
|
71
75
|
|
72
76
|
def from_file(path, compact)
|
73
77
|
header = File.open(path, 'r') { |f| f.read(DPX.length) }
|
74
|
-
|
78
|
+
begin
|
79
|
+
parse(header, compact)
|
80
|
+
rescue InvalidHeader => e
|
81
|
+
raise InvalidHeader, "Invalid header in file #{path}"
|
82
|
+
end
|
75
83
|
end
|
76
84
|
|
77
85
|
# The hear of Depix
|
78
86
|
def parse(data, compact)
|
79
87
|
magic = data[0..3]
|
88
|
+
|
89
|
+
raise InvalidHeader unless %w( SDPX XPDS).include?(magic)
|
90
|
+
|
80
91
|
struct = compact ? CompactDPX : DPX
|
81
92
|
|
82
|
-
|
83
|
-
|
93
|
+
is_be = (magic == "SDPX")
|
94
|
+
version_check = FileInfo.only(:magic, :version)
|
95
|
+
|
96
|
+
result = begin
|
97
|
+
if is_be
|
98
|
+
version_check.consume!(data.unpack(version_check.pattern))
|
99
|
+
else
|
100
|
+
version_check.consume!(data.unpack(make_le(version_check.pattern)))
|
101
|
+
end
|
102
|
+
rescue ArgumentError
|
103
|
+
raise InvalidHeader
|
104
|
+
end
|
105
|
+
|
106
|
+
raise InvalidHeader unless result.version == "V1.0"
|
107
|
+
|
108
|
+
template = is_be ? DPX.pattern : make_le(DPX.pattern)
|
109
|
+
struct.consume!(data.unpack(struct.pattern))
|
84
110
|
end
|
85
111
|
|
86
112
|
# Describe a filled DPX structure
|
data/lib/depix/dict.rb
CHANGED
@@ -54,6 +54,7 @@ module Depix
|
|
54
54
|
|
55
55
|
class U32Field < Field
|
56
56
|
BLANK = 0xFFFFFFFF
|
57
|
+
undef :length=, :pattern=
|
57
58
|
|
58
59
|
def pattern
|
59
60
|
"N"
|
@@ -69,6 +70,7 @@ module Depix
|
|
69
70
|
end
|
70
71
|
|
71
72
|
class U8Field < Field
|
73
|
+
undef :length=, :pattern=
|
72
74
|
|
73
75
|
BLANK = 0xFF
|
74
76
|
|
@@ -90,6 +92,7 @@ module Depix
|
|
90
92
|
end
|
91
93
|
|
92
94
|
class Filler < Field
|
95
|
+
undef :pattern=
|
93
96
|
def pattern
|
94
97
|
"x#{length ? length.to_i : 1}"
|
95
98
|
end
|
@@ -102,6 +105,7 @@ module Depix
|
|
102
105
|
|
103
106
|
class U16Field < Field
|
104
107
|
BLANK = 0xFFFF
|
108
|
+
undef :length=, :pattern=
|
105
109
|
|
106
110
|
def pattern
|
107
111
|
"n"
|
@@ -121,6 +125,8 @@ module Depix
|
|
121
125
|
end
|
122
126
|
|
123
127
|
class R32Field < Field
|
128
|
+
undef :length=, :pattern=
|
129
|
+
|
124
130
|
def pattern
|
125
131
|
"g"
|
126
132
|
end
|
@@ -140,6 +146,12 @@ module Depix
|
|
140
146
|
|
141
147
|
class CharField < Field
|
142
148
|
BLANK = "\0"
|
149
|
+
undef :pattern=
|
150
|
+
|
151
|
+
BLANKING_VALUES = [0x00.chr, 0xFF.chr]
|
152
|
+
BLANKING_PATTERNS = BLANKING_VALUES.inject([]) do | p, char |
|
153
|
+
p << /^(#{char}+)/ << /(#{char}+)$/
|
154
|
+
end
|
143
155
|
|
144
156
|
def pattern
|
145
157
|
"A#{(length || 1).to_i}"
|
@@ -149,8 +161,8 @@ module Depix
|
|
149
161
|
if v == BLANK
|
150
162
|
nil
|
151
163
|
else
|
152
|
-
|
153
|
-
|
164
|
+
2.times { BLANKING_PATTERNS.each{|p| v.gsub!(p, '')} }
|
165
|
+
v.empty? ? nil : v
|
154
166
|
end
|
155
167
|
end
|
156
168
|
|
@@ -320,6 +332,8 @@ module Depix
|
|
320
332
|
|
321
333
|
anon = Class.new(self)
|
322
334
|
anon.fields.replace(distillate)
|
335
|
+
only_items = distillate.map{|n| n.name }
|
336
|
+
|
323
337
|
anon
|
324
338
|
end
|
325
339
|
|
data/test/test_depix.rb
CHANGED
@@ -4,7 +4,7 @@ require 'test/unit'
|
|
4
4
|
class ReaderTest < Test::Unit::TestCase
|
5
5
|
|
6
6
|
SAMPLE_DPX = File.dirname(__FILE__) + '/samples/E012_P001_L000002_lin.0001.dpx'
|
7
|
-
|
7
|
+
|
8
8
|
def test_parsed_properly
|
9
9
|
file = SAMPLE_DPX
|
10
10
|
parsed = Depix.from_file(file)
|
@@ -38,8 +38,10 @@ class ReaderTest < Test::Unit::TestCase
|
|
38
38
|
assert_equal 8192, parsed.image.image_elements[0].data_offset
|
39
39
|
assert_equal 0, parsed.image.image_elements[0].end_of_line_padding
|
40
40
|
assert_equal 0, parsed.image.image_elements[0].end_of_image_padding
|
41
|
-
assert_equal "IMAGE DESCRIPTION DATA
|
42
|
-
assert_equal "
|
41
|
+
assert_equal "IMAGE DESCRIPTION DATA \000P", parsed.image.image_elements[0].description
|
42
|
+
assert_equal "E012\000\000\000\000x\340\264\020\000\000\000\000\005",
|
43
|
+
parsed.orientation.device #- this is where Flame writes the reel
|
44
|
+
|
43
45
|
assert_equal 853, parsed.orientation.aspect_ratio[0]
|
44
46
|
assert_equal 640, parsed.orientation.aspect_ratio[1]
|
45
47
|
|
@@ -66,7 +68,7 @@ class ReaderTest < Test::Unit::TestCase
|
|
66
68
|
assert_equal "01:15:11:18", parsed.time_code.to_s
|
67
69
|
assert_equal :RGB, parsed.component_type
|
68
70
|
assert_equal :Linear, parsed.colorimetric
|
69
|
-
assert_equal "
|
71
|
+
assert_equal "E012", parsed.flame_reel
|
70
72
|
end
|
71
73
|
|
72
74
|
def test_parsed_properly_using_compact_structs
|
@@ -81,4 +83,16 @@ class ReaderTest < Test::Unit::TestCase
|
|
81
83
|
assert_match(/Offset to data for this image element/, desc)
|
82
84
|
end
|
83
85
|
end
|
86
|
+
|
87
|
+
def test_parsing_something_else_should_raise
|
88
|
+
s = "Mary had a little lamb"
|
89
|
+
assert_raise(Depix::InvalidHeader) { Depix.from_string(s) }
|
90
|
+
|
91
|
+
s = "Mary had a little lamb" * 1000
|
92
|
+
assert_raise(Depix::InvalidHeader) { Depix.from_string(s) }
|
93
|
+
|
94
|
+
s = "SDPX Mary had a little lamb" * 1000
|
95
|
+
assert_raise(Depix::InvalidHeader) { Depix.from_string(s) }
|
96
|
+
|
97
|
+
end
|
84
98
|
end
|
data/test/test_dict.rb
CHANGED
@@ -13,6 +13,10 @@ module FieldConformity
|
|
13
13
|
assert_respond_to f, :rtype
|
14
14
|
assert_respond_to f, :explain
|
15
15
|
end
|
16
|
+
|
17
|
+
def assert_method_removed(f, method)
|
18
|
+
fail("#{f.inspect} should not respond to #{method}") if f.respond_to?(method)
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
class FieldExplainsItself < Test::Unit::TestCase
|
@@ -124,9 +128,15 @@ class TestArrayField < Test::Unit::TestCase
|
|
124
128
|
conform_field!(f)
|
125
129
|
|
126
130
|
assert_respond_to f, :name=
|
127
|
-
|
128
|
-
|
129
|
-
|
131
|
+
|
132
|
+
assert_method_removed f, :length=
|
133
|
+
assert_method_removed f, :pattern=
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_array_does_not_allow_setting_length
|
137
|
+
f = ArrayField.new
|
138
|
+
assert_method_removed(f, :length=)
|
139
|
+
assert_method_removed(f, :pattern=)
|
130
140
|
end
|
131
141
|
|
132
142
|
def test_array_field_has_members
|
@@ -162,8 +172,8 @@ class TestInnerField < Test::Unit::TestCase
|
|
162
172
|
assert_respond_to f, :cast
|
163
173
|
assert_respond_to f, :cast=
|
164
174
|
|
165
|
-
|
166
|
-
|
175
|
+
assert_method_removed(f, :length=)
|
176
|
+
assert_method_removed(f, :pattern=)
|
167
177
|
end
|
168
178
|
|
169
179
|
def test_inner_field_asks_cast_for_pattern_and_length
|
@@ -173,6 +183,10 @@ class TestInnerField < Test::Unit::TestCase
|
|
173
183
|
casted = InnerField.new(:cast => sample)
|
174
184
|
assert_equal 123, casted.length
|
175
185
|
assert_equal 'C123', casted.pattern
|
186
|
+
|
187
|
+
assert_method_removed(casted, :length=)
|
188
|
+
assert_method_removed(casted, :pattern=)
|
189
|
+
|
176
190
|
end
|
177
191
|
|
178
192
|
def test_rtype_for_inner_field_is_cast
|
@@ -203,6 +217,7 @@ class TestCharField < Test::Unit::TestCase
|
|
203
217
|
def test_char_field_conforms_to_basics
|
204
218
|
f = CharField.new :name => :foo
|
205
219
|
conform_field!(f)
|
220
|
+
assert_method_removed(f, :pattern=)
|
206
221
|
end
|
207
222
|
|
208
223
|
def test_char_field_pads
|
@@ -213,14 +228,19 @@ class TestCharField < Test::Unit::TestCase
|
|
213
228
|
assert_equal String, f.rtype
|
214
229
|
end
|
215
230
|
|
216
|
-
def
|
231
|
+
def test_char_field_does_not_clean_inner_nulls
|
217
232
|
f = CharField.new :name => :foo, :length => 15
|
218
|
-
assert_equal "foo", f.clean("\0\0foo")
|
233
|
+
assert_equal "foo\0foo", f.clean("\0\0foo\0foo\0")
|
234
|
+
assert_equal "swoop\377\0bla", f.clean("\0\0\0\377\377swoop\377\0bla\0\0\0\377\377\377\377\0\0\0")
|
219
235
|
end
|
220
236
|
|
221
237
|
def test_char_field_clean_blank
|
222
238
|
f = CharField.new :name => :foo, :length => 15
|
223
239
|
assert_equal nil, f.clean("\0")
|
240
|
+
assert_equal nil, f.clean("\0\0\0\0\0\0")
|
241
|
+
assert_equal nil, f.clean("\0\0\0\377\377\0\0\0")
|
242
|
+
assert_equal "foo\0foo", f.clean("\0\0foo\0foo\0")
|
243
|
+
|
224
244
|
end
|
225
245
|
end
|
226
246
|
|
@@ -249,6 +269,10 @@ class TestSmallintField < Test::Unit::TestCase
|
|
249
269
|
def test_smallint_conformity
|
250
270
|
f = U8Field.new :name => :foo
|
251
271
|
conform_field!(f)
|
272
|
+
|
273
|
+
assert_method_removed(f, :pattern=)
|
274
|
+
assert_method_removed(f, :length=)
|
275
|
+
|
252
276
|
end
|
253
277
|
|
254
278
|
def test_smallint_operation
|
@@ -274,6 +298,9 @@ class TestDoubleField < Test::Unit::TestCase
|
|
274
298
|
def test_double_conformity
|
275
299
|
f = U16Field.new :name => :foo
|
276
300
|
conform_field!(f)
|
301
|
+
|
302
|
+
assert_method_removed(f, :pattern=)
|
303
|
+
assert_method_removed(f, :length=)
|
277
304
|
end
|
278
305
|
|
279
306
|
def test_double_operation
|
@@ -301,6 +328,10 @@ class TestFillerField < Test::Unit::TestCase
|
|
301
328
|
assert_equal "x1", f.pattern
|
302
329
|
end
|
303
330
|
|
331
|
+
def test_filler_does_not_allow_setting_pattern
|
332
|
+
assert_method_removed(Filler.new, :pattern=)
|
333
|
+
end
|
334
|
+
|
304
335
|
def test_pattern_discards_value
|
305
336
|
data = [1,2,3].pack("ccc")
|
306
337
|
filler = Filler.new(:length => 3)
|
@@ -596,11 +627,16 @@ class TestDictCompact < Test::Unit::TestCase
|
|
596
627
|
assert_equal distill.length, c.length, "The distilled struct should occupy the same space"
|
597
628
|
assert_equal 3, distill.fields.length
|
598
629
|
|
630
|
+
result = distill.apply!("abcdefhjhjkujkdkklsalierioeiore")
|
631
|
+
|
599
632
|
assert_kind_of Filler, distill.fields[0]
|
600
633
|
assert_equal 5, distill.fields[0].length
|
601
634
|
|
602
635
|
assert_kind_of Filler, distill.fields[2]
|
603
636
|
assert_equal 14, distill.fields[2].length
|
637
|
+
|
638
|
+
assert_nil result.some
|
639
|
+
assert_nil result.fourth
|
604
640
|
end
|
605
641
|
|
606
642
|
def test_get_filler
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: depix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julik Tarkhanov
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-12-
|
12
|
+
date: 2008-12-23 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|