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, streams 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

.empty_bytearrayString

Returns an empty stream using binary encoding that can be used as stream to encode to.

Returns:

  • (String)

    An empty, binary string.



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

def self.empty_bytearray
  ChunkyPNG::EMPTY_BYTEARRAY.dup
end

.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;       ds.header_chunk = chunk
      when ChunkyPNG::Chunk::Palette;      ds.palette_chunk = chunk
      when ChunkyPNG::Chunk::Transparency; ds.transparency_chunk = chunk
      when ChunkyPNG::Chunk::ImageData;    ds.data_chunks << chunk
      when ChunkyPNG::Chunk::End;          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 datastream, 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

#imagedataString

Returns the uncompressed image data, combined from all the IDAT chunks

Returns:

  • (String)

    The uncompressed image data for this datastream



147
148
149
# File 'lib/chunky_png/datastream.rb', line 147

def imagedata
  ChunkyPNG::Chunk::ImageData.combine_chunks(data_chunks)
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.



170
171
172
# File 'lib/chunky_png/datastream.rb', line 170

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.



176
177
178
179
180
# File 'lib/chunky_png/datastream.rb', line 176

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.



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

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