class ChunkyPNG::Datastream
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 then contains multiple chunks, starting with a header (IHDR) chunk and finishing with an end (IEND) chunk.
@see ChunkyPNG::Chunk
Constants
- SIGNATURE
The signature that each PNG file or stream should begin with.
Attributes
The chunks that together compose the images pixel data. @return [Array<ChunkyPNG::Chunk::ImageData>]
The empty chunk that signals the end of this datastream @return [ChunkyPNG::Chunk::Header]
The header chunk of this datastream. @return [ChunkyPNG::Chunk::Header]
All other chunks in this PNG file. @return [Array<ChunkyPNG::Chunk::Generic>]
The chunk containing the image's palette. @return [ChunkyPNG::Chunk::Palette]
The chunk containing the physical dimensions of the PNG's pixels. @return [ChunkyPNG::Chunk::Physical]
The chunk containing the transparency information of the palette. @return [ChunkyPNG::Chunk::Transparency]
Public Class Methods
Reads a PNG datastream from a string. @param [String] str The PNG encoded string to load from. @return [ChunkyPNG::Datastream] The loaded datastream instance.
# File lib/chunky_png/datastream.rb, line 57 def from_blob(str) from_io(StringIO.new(str, "rb")) end
Reads a PNG datastream from a file. @param [String] filename The path of the file to load from. @return [ChunkyPNG::Datastream] The loaded datastream instance.
# File lib/chunky_png/datastream.rb, line 66 def from_file(filename) ds = nil File.open(filename, "rb") { |f| ds = from_io(f) } ds end
Reads a PNG datastream from an input stream @param [IO] io The stream to read from. @return [ChunkyPNG::Datastream] The loaded datastream instance.
# File lib/chunky_png/datastream.rb, line 75 def from_io(io) io.set_encoding(::Encoding::BINARY) verify_signature!(io) ds = new while ds.end_chunk.nil? 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::Physical then ds.physical_chunk = chunk when ChunkyPNG::Chunk::End then ds.end_chunk = chunk else ds.other_chunks << chunk end end ds end
Initializes a new Datastream instance.
# File lib/chunky_png/datastream.rb, line 44 def initialize @other_chunks = [] @data_chunks = [] end
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.
@param [IO] io The stream to read the PNG signature from. @raise [RuntimeError] An exception is raised if the PNG signature is not found at
the beginning of the stream.
# File lib/chunky_png/datastream.rb, line 103 def verify_signature!(io) signature = io.read(ChunkyPNG::Datastream::SIGNATURE.length) unless signature == ChunkyPNG::Datastream::SIGNATURE raise ChunkyPNG::SignatureMismatch, "PNG signature not found, found #{signature.inspect} instead of #{ChunkyPNG::Datastream::SIGNATURE.inspect}!" end end
Public Instance Methods
Returns an enumerator instance for this datastream's chunks. @return [Enumerable::Enumerator] An enumerator for the :each_chunk method. @see #each_chunk
# File lib/chunky_png/datastream.rb, line 136 def chunks enum_for(:each_chunk) end
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.
@yield [chunk] Yields the chunks in this datastream, one by one in the correct order. @yieldparam [ChunkyPNG::Chunk::Base] chunk A chunk in this datastream. @see #chunks
# File lib/chunky_png/datastream.rb, line 123 def each_chunk yield(header_chunk) other_chunks.each { |chunk| yield(chunk) } yield(palette_chunk) if palette_chunk yield(transparency_chunk) if transparency_chunk yield(physical_chunk) if physical_chunk data_chunks.each { |chunk| yield(chunk) } yield(end_chunk) end
Returns the uncompressed image data, combined from all the IDAT chunks @return [String] The uncompressed image data for this datastream
# File lib/chunky_png/datastream.rb, line 152 def imagedata ChunkyPNG::Chunk::ImageData.combine_chunks(data_chunks) end
Returns all the textual metadata key/value pairs as hash. @return [Hash] A hash containing metadata fields and their values.
# File lib/chunky_png/datastream.rb, line 142 def metadata metadata = {} other_chunks.each do |chunk| metadata[chunk.keyword] = chunk.value if chunk.respond_to?(:keyword) && chunk.respond_to?(:value) end metadata end
Saves this datastream as a PNG file. @param [String] filename The filename to use.
# File lib/chunky_png/datastream.rb, line 169 def save(filename) File.open(filename, "wb") { |f| write(f) } end
Encodes this datastream into a string. @return [String] The encoded PNG datastream.
# File lib/chunky_png/datastream.rb, line 175 def to_blob str = StringIO.new str.set_encoding("ASCII-8BIT") write(str) str.string end
Writes the datastream to the given output stream. @param [IO] io The output stream to write to.
# File lib/chunky_png/datastream.rb, line 162 def write(io) io << SIGNATURE each_chunk { |c| c.write(io) } end