Class: ZPNG::Chunk

Inherits:
Object
  • Object
show all
Includes:
DeepCopyable
Defined in:
lib/zpng/chunk.rb,
lib/zpng/text_chunk.rb

Direct Known Subclasses

BMP::BmpPseudoChunk, CHRM, GAMA, IDAT, IEND, IHDR, PHYS, PLTE, SRGB, TIME, TRNS, TextChunk

Defined Under Namespace

Classes: CHRM, GAMA, IDAT, IEND, IHDR, ITXT, PHYS, PLTE, SRGB, TEXT, TIME, TRNS, ZTXT

Constant Summary collapse

KNOWN_TYPES =
%w'IHDR PLTE IDAT IEND cHRM gAMA iCCP sBIT sRGB bKGD hIST tRNS pHYs sPLT tIME iTXt tEXt zTXt'
VALID_SIZE_RANGE =
0..((2**31)-1)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DeepCopyable

#deep_copy

Constructor Details

#initialize(x = {}) ⇒ Chunk

Returns a new instance of Chunk.



26
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
52
# File 'lib/zpng/chunk.rb', line 26

def initialize x = {}
  if x.respond_to?(:read)
    # IO
    @offset = x.tell
    @size, @type = x.read(8).unpack('Na4')
    begin
      @data = x.read(size)
    rescue Errno::EINVAL
      # TODO: show warning?
      @data = x.read if size > VALID_SIZE_RANGE.end
    end
    @crc         = x.read(4).to_s.unpack('N').first
  elsif x.respond_to?(:[])
    # Hash
    %w'size type data crc'.each do |k|
      instance_variable_set "@#{k}", x[k.to_sym]
    end
    if !@type && self.class.superclass == ZPNG::Chunk
      # guess @type from self class name, e.g. ZPNG::Chunk::IHDR => "IHDR"
      @type = self.class.to_s.split("::").last
    end
    if !@size && @data
      # guess @size from @data
      @size = @data.size
    end
  end
end

Instance Attribute Details

#crcObject

Returns the value of attribute crc.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def crc
  @crc
end

#dataObject

Returns the value of attribute data.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def data
  @data
end

#idxObject

Returns the value of attribute idx.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def idx
  @idx
end

#offsetObject

Returns the value of attribute offset.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def offset
  @offset
end

#sizeObject

Returns the value of attribute size.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def size
  @size
end

#typeObject

Returns the value of attribute type.



3
4
5
# File 'lib/zpng/chunk.rb', line 3

def type
  @type
end

Class Method Details

.from_stream(io) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/zpng/chunk.rb', line 10

def self.from_stream io
  size, type = io.read(8).unpack('Na4')
  io.seek(-8,IO::SEEK_CUR)
  begin
    if const_defined?(type.upcase)
      klass = const_get(type.upcase)
      return klass.new(io)
    end
  rescue NameError
    # invalid chunk type?
  end
  # putting this out of rescue makes better non-confusing exception messages
  # if exception occurs somewhere in Chunk.new
  Chunk.new(io)
end

Instance Method Details

#check(checks = {type: true, crc: true, size: true}) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/zpng/chunk.rb', line 78

def check checks = {type: true, crc: true, size: true}
  checks.each do |check_type, check_mode|
    case check_type
    when :type
      return false if check_mode != KNOWN_TYPES.include?(self.type)
    when :crc
      return false if check_mode != crc_ok?
    when :size
      return false if check_mode != VALID_SIZE_RANGE.include?(self.size)
    end
  end
  true
end

#crc_ok?Boolean

Returns:

  • (Boolean)


73
74
75
76
# File 'lib/zpng/chunk.rb', line 73

def crc_ok?
  expected_crc = Zlib.crc32(data, Zlib.crc32(type))
  expected_crc == crc
end

#export(fix_crc: true) ⇒ Object



54
55
56
57
58
59
# File 'lib/zpng/chunk.rb', line 54

def export( fix_crc: true )
  @data = self.export_data # virtual
  @size = @data.size # XXX hmm.. is it always is?
  fix_crc! if fix_crc
  [@size,@type].pack('Na4') + @data + [@crc].pack('N')
end

#export_dataObject



61
62
63
64
# File 'lib/zpng/chunk.rb', line 61

def export_data
  #STDERR.puts "[!] Chunk::#{type} must realize 'export_data' virtual method".yellow if @size != 0
  @data || ''
end

#fix_crc!Object



94
95
96
# File 'lib/zpng/chunk.rb', line 94

def fix_crc!
  @crc = Zlib.crc32(data, Zlib.crc32(type))
end

#inspect(verbosity = 10) ⇒ Object



66
67
68
69
70
71
# File 'lib/zpng/chunk.rb', line 66

def inspect verbosity = 10
  size = @size ? sprintf("%6d",@size) : sprintf("%6s","???")
  crc  = @crc  ? sprintf("%08x",@crc) : sprintf("%8s","???")
  type = @type.to_s.gsub(/[^0-9a-z]/i){ |x| sprintf("\\x%02X",x.ord) }
  sprintf "<Chunk #%02d %4s size=%s, crc=%s >", idx.to_i, type, size, crc
end

#valid?Boolean

Returns:

  • (Boolean)


92
# File 'lib/zpng/chunk.rb', line 92

def valid?; check; end