Module: ChunkyPNG::Chunk

Defined in:
lib/chunky_png/chunk.rb

Overview

A PNG datastream consists of multiple chunks. This module, and the classes contained within, help with handling these chunks. It supports both reading and writing chunks.

All chunk types are instances of the Base class. For some chunk types a specialized class is available, e.g. the IHDR chunk is represented by the Header class. These specialized classes help accessing the content of the chunk. All other chunks are represented by the Generic class.

See Also:

Defined Under Namespace

Classes: Base, CompressedText, End, Generic, Header, ImageData, InternationalText, Palette, Physical, Text, Transparency

Constant Summary collapse

CHUNK_TYPES =

Maps chunk types to classes, based on the four byte chunk type indicator at the beginning of a chunk.

If a chunk type is not specified in this hash, the Generic chunk type will be used.

See Also:

{
  "IHDR" => Header,
  "IEND" => End,
  "IDAT" => ImageData,
  "PLTE" => Palette,
  "tRNS" => Transparency,
  "tEXt" => Text,
  "zTXt" => CompressedText,
  "iTXt" => InternationalText,
  "pHYs" => Physical,
}

Class Method Summary collapse

Class Method Details

.read(io) ⇒ ChunkyPNG::Chung::Base

Reads a chunk from an IO stream.

Parameters:

  • io (IO, #read)

    The IO stream to read from.

Returns:

  • (ChunkyPNG::Chung::Base)

    The loaded chunk instance.



20
21
22
23
24
25
26
27
28
# File 'lib/chunky_png/chunk.rb', line 20

def self.read(io)
  length, type = read_bytes(io, 8).unpack("Na4")

  content = read_bytes(io, length)
  crc     = read_bytes(io, 4).unpack("N").first
  verify_crc!(type, content, crc)

  CHUNK_TYPES.fetch(type, Generic).read(type, content)
end

.read_bytes(io, length) ⇒ String

Reads an exact number of bytes from an IO stream.

Parameters:

  • io (IO, #read)

    The IO stream to read from.

  • length (Integer)

    The IO exact number of bytes to read.

Returns:

  • (String)

    A binary string of exactly length bytes.

Raises:



36
37
38
39
40
# File 'lib/chunky_png/chunk.rb', line 36

def self.read_bytes(io, length)
  data = io.read(length)
  raise ExpectationFailed, "Couldn't read #{length} bytes from IO stream." if data.nil? || data.bytesize != length
  data
end

.verify_crc!(type, content, found_crc) ⇒ Object

Verifies the CRC of a chunk.

Parameters:

  • type (String)

    The chunk’s type.

  • content (String)

    The chunk’s content.

  • found_crc (Integer)

    The chunk’s found CRC value.

Raises:

  • (ChunkyPNG::CRCMismatch)

    An exception is raised if the found CRC value is not equal to the expected CRC value.



48
49
50
51
# File 'lib/chunky_png/chunk.rb', line 48

def self.verify_crc!(type, content, found_crc)
  expected_crc = Zlib.crc32(content, Zlib.crc32(type))
  raise ChunkyPNG::CRCMismatch, "Chuck CRC mismatch!" if found_crc != expected_crc
end