Module: ChunkyPNG::Canvas::PNGDecoding

Included in:
ChunkyPNG::Canvas
Defined in:
lib/chunky_png/canvas/png_decoding.rb

Overview

The PNGDecoding contains methods for decoding PNG datastreams to create a Canvas object. The datastream can be provided as filename, string or IO stream.

Overview of the decoding process:

  • The optional PLTE and tRNS chunk are decoded for the color palette of the original image.

  • The contents of the IDAT chunks is combined, and uncompressed using Inflate decompression to the image pixelstream.

  • Based on the color mode, width and height of the original image, which is read from the PNG header (IHDR chunk), the amount of bytes per line is determined.

  • For every line of pixels in the encoded image, the original byte values are restored by unapplying the milter method for that line.

  • The read bytes are unfiltered given by the filter function specified by the first byte of the line.

  • The unfiltered pixelstream are is into colored pixels, using the color mode.

  • All lines combined to form the original image.

For interlaced images, the original image was split into 7 subimages. These images get decoded just like the process above (from step 3), and get combined to form the original images.

See Also:

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (ChunkyPNG::Palette) decoding_palette

The palette that is used to decode the image, loading from the PLTE and tRNS chunk from the PNG stream. For RGB(A) images, no palette is required.



35
36
37
# File 'lib/chunky_png/canvas/png_decoding.rb', line 35

def decoding_palette
  @decoding_palette
end

- (Object) transparent_color

The color to be replaced with fully transparent pixels.



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

def transparent_color
  @transparent_color
end

Instance Method Details

- (ChunkyPNG::Canvas) decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)

Decodes a canvas from a PNG encoded pixelstream, using a given width, height, color mode and interlacing mode.



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/chunky_png/canvas/png_decoding.rb', line 100

def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)
  raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?

  image = case interlace
    when ChunkyPNG::INTERLACING_NONE;  decode_png_without_interlacing(stream, width, height, color_mode, depth)
    when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
    else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
  end
  
  image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
  return image
end

- (ChunkyPNG::Canvas) from_blob(str) Also known as: from_string

Decodes a Canvas from a PNG encoded string.



43
44
45
# File 'lib/chunky_png/canvas/png_decoding.rb', line 43

def from_blob(str)
  from_datastream(ChunkyPNG::Datastream.from_blob(str))
end

- (ChunkyPNG::Canvas) from_datastream(ds)

Decodes the Canvas from a PNG datastream instance.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chunky_png/canvas/png_decoding.rb', line 68

def from_datastream(ds)
  width      = ds.header_chunk.width
  height     = ds.header_chunk.height
  color_mode = ds.header_chunk.color
  interlace  = ds.header_chunk.interlace
  depth      = ds.header_chunk.depth

  if width == 0 || height == 0
    raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
  end

  case color_mode
    when ChunkyPNG::COLOR_INDEXED
      self.decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
    when ChunkyPNG::COLOR_TRUECOLOR
      self.transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
    when ChunkyPNG::COLOR_GRAYSCALE
      self.transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
  end
      
  decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
end

- (ChunkyPNG::Canvas) from_file(filename)

Decodes a Canvas from a PNG encoded file.



52
53
54
# File 'lib/chunky_png/canvas/png_decoding.rb', line 52

def from_file(filename)
  from_datastream(ChunkyPNG::Datastream.from_file(filename))
end

- (ChunkyPNG::Canvas) from_io(io) Also known as: from_stream

Decodes a Canvas from a PNG encoded stream.



59
60
61
# File 'lib/chunky_png/canvas/png_decoding.rb', line 59

def from_io(io)
  from_datastream(ChunkyPNG::Datastream.from_io(io))
end