Class: ChunkyPNG::Datastream

Inherits:
Object
  • Object
show all
Defined in:
lib/chunky_png/datastream.rb

Overview

The Datastream class represents a PNG formatted datastream. It supports both reading from and writing to strings, stremas and files.

A PNG datastream begins with the PNG signature, and than contains multiple chunks, starting with a header (IHDR) chunk and finishing with an end (IEND) chunk.

See Also:

Constant Summary collapse

SIGNATURE =

The signature that each PNG file or stream should begin with.

[137, 80, 78, 71, 13, 10, 26, 10].pack('C8')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDatastream

Initializes a new Datastream instance.



41
42
43
44
# File 'lib/chunky_png/datastream.rb', line 41

def initialize
  @other_chunks = []
  @data_chunks  = []
end

Instance Attribute Details

#data_chunksArray<ChunkyPNG::Chunk::ImageData>

The chunks that together compose the images pixel data.

Returns:



34
35
36
# File 'lib/chunky_png/datastream.rb', line 34

def data_chunks
  @data_chunks
end

#end_chunkChunkyPNG::Chunk::Header

The empty chunk that signals the end of this datastream



38
39
40
# File 'lib/chunky_png/datastream.rb', line 38

def end_chunk
  @end_chunk
end

#header_chunkChunkyPNG::Chunk::Header

The header chunk of this datastream.



18
19
20
# File 'lib/chunky_png/datastream.rb', line 18

def header_chunk
  @header_chunk
end

#other_chunksArray<ChunkyPNG::Chunk::Generic>

All other chunks in this PNG file.

Returns:



22
23
24
# File 'lib/chunky_png/datastream.rb', line 22

def other_chunks
  @other_chunks
end

#palette_chunkChunkyPNG::Chunk::Palette

The chunk containing the image’s palette.



26
27
28
# File 'lib/chunky_png/datastream.rb', line 26

def palette_chunk
  @palette_chunk
end

#transparency_chunkChunkyPNG::Chunk::Transparency

The chunk containing the transparency information of the palette.



30
31
32
# File 'lib/chunky_png/datastream.rb', line 30

def transparency_chunk
  @transparency_chunk
end

Class Method Details

.from_blob(str) ⇒ ChunkyPNG::Datastream Also known as: from_string

Reads a PNG datastream from a string.

Parameters:

  • str (String)

    The PNG encoded string to load from.

Returns:



55
56
57
# File 'lib/chunky_png/datastream.rb', line 55

def from_blob(str)
  from_io(StringIO.new(str))
end

.from_file(filename) ⇒ ChunkyPNG::Datastream

Reads a PNG datastream from a file.

Parameters:

  • filename (String)

    The path of the file to load from.

Returns:



64
65
66
67
68
# File 'lib/chunky_png/datastream.rb', line 64

def from_file(filename)
  ds = nil
  File.open(filename, 'rb') { |f| ds = from_io(f) }
  ds
end

.from_io(io) ⇒ ChunkyPNG::Datastream

Reads a PNG datastream from an input stream

Parameters:

  • io (IO)

    The stream to read from.

Returns:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chunky_png/datastream.rb', line 73

def from_io(io)
  verify_signature!(io)

  ds = self.new
  until io.eof?
    chunk = ChunkyPNG::Chunk.read(io)
    case chunk
      when ChunkyPNG::Chunk::Header       then ds.header_chunk        = chunk
      when ChunkyPNG::Chunk::Palette      then ds.palette_chunk       = chunk
      when ChunkyPNG::Chunk::Transparency then ds.transparency_chunk  = chunk
      when ChunkyPNG::Chunk::ImageData    then ds.data_chunks        << chunk
      when ChunkyPNG::Chunk::End          then ds.end_chunk           = chunk
      else ds.other_chunks << chunk
    end
  end
  return ds
end

.verify_signature!(io) ⇒ Object

Verifies that the current stream is a PNG datastream by checking its signature.

This method reads the PNG signature from the stream, setting the current position of the stream directly after the signature, where the IHDR chunk should begin.

Parameters:

  • io (IO)

    The stream to read the PNG signature from.

Raises:

  • (RuntimeError)

    An exception is raised if the PNG signature is not found at the beginning of the stream.



99
100
101
102
103
104
# File 'lib/chunky_png/datastream.rb', line 99

def verify_signature!(io)
  signature = io.read(ChunkyPNG::Datastream::SIGNATURE.length)
  unless signature == ChunkyPNG::Datastream::SIGNATURE
    raise ChunkyPNG::SignatureMismatch, "PNG signature not found!"
  end
end

Instance Method Details

#chunksEnumerable::Enumerator

Returns an enumerator instance for this datastream’s chunks.

Returns:

  • (Enumerable::Enumerator)

    An enumerator for the :each_chunk method.

See Also:



131
132
133
# File 'lib/chunky_png/datastream.rb', line 131

def chunks
  enum_for(:each_chunk)
end

#each_chunk {|chunk| ... } ⇒ Object

Enumerates the chunks in this datastream.

This will iterate over the chunks using the order in which the chunks should appear in the PNG file.

Yields:

  • (chunk)

    Yields the chunks in this datastrean, one by one in the correct order.

Yield Parameters:

See Also:



119
120
121
122
123
124
125
126
# File 'lib/chunky_png/datastream.rb', line 119

def each_chunk
  yield(header_chunk)
  other_chunks.each { |chunk| yield(chunk) }
  yield(palette_chunk)      if palette_chunk
  yield(transparency_chunk) if transparency_chunk
  data_chunks.each  { |chunk| yield(chunk) }
  yield(end_chunk)
end

#metadataHash

Returns all the textual metadata key/value pairs as hash.

Returns:

  • (Hash)

    A hash containing metadata fields and their values.



137
138
139
140
141
142
143
# File 'lib/chunky_png/datastream.rb', line 137

def 
   = {}
  other_chunks.select do |chunk|
    [chunk.keyword] = chunk.value if chunk.respond_to?(:keyword)
  end
  
end

#save(filename) ⇒ Object

Saves this datastream as a PNG file.

Parameters:

  • filename (String)

    The filename to use.



158
159
160
# File 'lib/chunky_png/datastream.rb', line 158

def save(filename)
  File.open(filename, 'wb') { |f| write(f) }
end

#to_blobString Also known as: to_string, to_s

Encodes this datastream into a string.

Returns:

  • (String)

    The encoded PNG datastream.



164
165
166
167
168
# File 'lib/chunky_png/datastream.rb', line 164

def to_blob
  str = StringIO.new
  write(str)
  return str.string
end

#write(io) ⇒ Object

Writes the datastream to the given output stream.

Parameters:

  • io (IO)

    The output stream to write to.



151
152
153
154
# File 'lib/chunky_png/datastream.rb', line 151

def write(io)
  io << SIGNATURE
  each_chunk { |c| c.write(io) }
end