Class: Depix::Reader

Inherits:
Object
  • Object
show all
Defined in:
lib/depix/reader.rb

Instance Method Summary collapse

Instance Method Details

#describe_file(path, compact = false) ⇒ Object

Returns a printable report on all the headers present in the file at the path passed



5
6
7
8
9
# File 'lib/depix/reader.rb', line 5

def describe_file(path, compact = false)
  header = File.open(path, 'r') { |f| f.read(DPX.length) }
  struct = parse(header, false)
  describe_struct(struct) + describe_synthetics_of_struct(struct)
end

#describe_struct(result, pad_offset = 0) ⇒ Object

Describe a filled DPX structure



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/depix/reader.rb', line 54

def describe_struct(result, pad_offset = 0)
  result.class.fields.inject([]) do | info, field |
    value = result.send(field.name)
    parts = []
    if value
      parts << field.desc if field.desc
      parts << if field.is_a?(InnerField)
        describe_struct(value, pad_offset + 1)
      elsif field.is_a?(ArrayField)
        # Exception for image elements
        value = result.image_elements[0...result.number_elements] if field.name == :image_elements
        value.map { | v | v.is_a?(Dict) ? describe_struct(v, pad_offset + 2) : v }
      else
        value
      end
    end
    if parts.any?
      info << parts.join(' ')
    end
    info
  end.map{|e| ('  ' * pad_offset) + e }.join("\n")
end

#describe_synthetics_of_struct(struct) ⇒ Object



11
12
13
14
15
# File 'lib/depix/reader.rb', line 11

def describe_synthetics_of_struct(struct)
  Synthetics.instance_methods.reject{|m| m.include?('=')}.map do | m |
    [m, struct.send(m)].join(' : ')
  end.unshift("============").unshift("\nSynthetic properties").join("\n")
end

#from_file(path, compact) ⇒ Object



17
18
19
20
21
22
23
24
# File 'lib/depix/reader.rb', line 17

def from_file(path, compact)
  header = File.open(path, 'r') { |f| f.read(DPX.length) }
  begin
    parse(header, compact)
  rescue InvalidHeader => e
    raise InvalidHeader, "Invalid header in file #{path} - #{e.message}"
  end
end

#make_le(pattern) ⇒ Object

Convert an unpack pattern to LE



78
79
80
# File 'lib/depix/reader.rb', line 78

def make_le(pattern)
  pattern.gsub(/n/, "v").gsub(/N/, "V").gsub(/g/, "f")
end

#parse(data, compact) ⇒ Object

The hear of Depix

Raises:



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/depix/reader.rb', line 27

def parse(data, compact)
  magic = data[0..3]
  
  raise InvalidHeader, "No magic bytes found at start" unless %w( SDPX XPDS).include?(magic)
  
  struct = compact ? CompactDPX : DPX
  
  is_be = (magic == "SDPX")
  version_check = FileInfo.only(:magic, :version)
  
  result = begin
    if is_be
      version_check.consume!(data.unpack(version_check.pattern))
    else
      version_check.consume!(data.unpack(make_le(version_check.pattern)))
    end
  rescue ArgumentError
    raise InvalidHeader
  end
  
  raise InvalidHeader, "Unknown version tag #{result.version}" unless result.version =~ /V(\d)\.(\d+)/i
  
  template = is_be ? DPX.pattern : make_le(DPX.pattern)
  struct.consume!(data.unpack(struct.pattern))
end