module ChunkyPNG::Canvas::PNGDecoding

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:

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 ChunkyPNG::Canvas::PNGEncoding @see www.w3.org/TR/PNG/ The W3C PNG format specification

Public Instance Methods

decode_png_pixelstream(stream, width, height, color_mode, depth, interlace, decoding_palette, transparent_color) click to toggle source

Decodes a canvas from a PNG encoded pixelstream, using a given width, height, color mode and interlacing mode. @param [String] stream The pixelstream to read from. @param [Integer] width The width of the image. @param [Integer] height The height of the image. @param [Integer] color_mode The color mode of the encoded pixelstream. @param [Integer] depth The bit depth of the pixel samples. @param [Integer] interlace The interlace method of the encoded pixelstream. @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors. @param [Integer] transparent_color The color that should be considered fully transparent. @return [ChunkyPNG::Canvas] The decoded Canvas instance.

    # File lib/chunky_png/canvas/png_decoding.rb
 93 def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
 94   raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
 95 
 96   image = case interlace
 97     when ChunkyPNG::INTERLACING_NONE  then decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
 98     when ChunkyPNG::INTERLACING_ADAM7 then decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
 99     else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
100   end
101 
102   image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
103   image
104 end
from_blob(str) click to toggle source

Decodes a Canvas from a PNG encoded string. @param [String] str The string to read from. @return [ChunkyPNG::Canvas] The canvas decoded from the PNG encoded string.

   # File lib/chunky_png/canvas/png_decoding.rb
33 def from_blob(str)
34   from_datastream(ChunkyPNG::Datastream.from_blob(str))
35 end
Also aliased as: from_string
from_datastream(ds) click to toggle source

Decodes the Canvas from a PNG datastream instance. @param [ChunkyPNG::Datastream] ds The datastream to decode. @return [ChunkyPNG::Canvas] The canvas decoded from the PNG datastream.

   # File lib/chunky_png/canvas/png_decoding.rb
58 def from_datastream(ds)
59   width      = ds.header_chunk.width
60   height     = ds.header_chunk.height
61   color_mode = ds.header_chunk.color
62   interlace  = ds.header_chunk.interlace
63   depth      = ds.header_chunk.depth
64 
65   if width == 0 || height == 0
66     raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
67   end
68 
69   decoding_palette, transparent_color = nil, nil
70   case color_mode
71     when ChunkyPNG::COLOR_INDEXED
72       decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
73     when ChunkyPNG::COLOR_TRUECOLOR
74       transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
75     when ChunkyPNG::COLOR_GRAYSCALE
76       transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
77   end
78 
79   decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
80 end
from_file(filename) click to toggle source

Decodes a Canvas from a PNG encoded file. @param [String] filename The file to read from. @return [ChunkyPNG::Canvas] The canvas decoded from the PNG file.

   # File lib/chunky_png/canvas/png_decoding.rb
42 def from_file(filename)
43   from_datastream(ChunkyPNG::Datastream.from_file(filename))
44 end
from_io(io) click to toggle source

Decodes a Canvas from a PNG encoded stream. @param [IO, read] io The stream to read from. @return [ChunkyPNG::Canvas] The canvas decoded from the PNG stream.

   # File lib/chunky_png/canvas/png_decoding.rb
49 def from_io(io)
50   from_datastream(ChunkyPNG::Datastream.from_io(io))
51 end
Also aliased as: from_stream
from_stream(io)
Alias for: from_io
from_string(str)
Alias for: from_blob

Protected Instance Methods

decode_png_extract_1bit_value(byte, index) click to toggle source

Extract a bit from a byte on a given index. @param [Integer] byte The byte (0..255) value to extract a bit from. @param [Integer] index The index within the byte. This should be 0..7;

the value will be modded by 8 to enforce this.

@return [Integer] Either 1 or 0.

    # File lib/chunky_png/canvas/png_decoding.rb
166 def decode_png_extract_1bit_value(byte, index)
167   bitshift = 7 - (index & 0x07)
168   (byte & (0x01 << bitshift)) >> bitshift
169 end
decode_png_extract_2bit_value(byte, index) click to toggle source

Extract 2 consecutive bits from a byte. @param [Integer] byte The byte (0..255) value to extract a 2 bit value from. @param [Integer] index The index within the byte. This should be either 0, 1, 2, or 3;

the value will be modded by 4 to enforce this.

@return [Integer] The extracted 2 bit value (0..3)

    # File lib/chunky_png/canvas/png_decoding.rb
156 def decode_png_extract_2bit_value(byte, index)
157   bitshift = 6 - ((index & 0x03) << 1)
158   (byte & (0x03 << bitshift)) >> bitshift
159 end
decode_png_extract_4bit_value(byte, index) click to toggle source

Extract 4 consecutive bits from a byte. @param [Integer] byte The byte (0..255) value to extract a 4 bit value from. @param [Integer] index The index within the byte. This should be either 0 or 2;

the value will be modded by 2 to enforce this.

@return [Integer] The extracted 4bit value (0..15)

    # File lib/chunky_png/canvas/png_decoding.rb
147 def decode_png_extract_4bit_value(byte, index)
148   index & 0x01 == 0 ? ((byte & 0xf0) >> 4) : (byte & 0x0f)
149 end
decode_png_image_pass(stream, width, height, color_mode, depth, start_pos, decoding_palette) click to toggle source

Decodes a single PNG image pass width a given width, height and color mode, to a Canvas, starting at the given position in the stream.

A non-interlaced image only consists of one pass, while an Adam7 image consists of 7 passes that must be combined after decoding.

@param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param [Integer] start_pos The position in the pixel stream to start reading. @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors. @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)

    # File lib/chunky_png/canvas/png_decoding.rb
381 def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos, decoding_palette)
382   pixels = []
383   if width > 0 && height > 0
384 
385     stream << ChunkyPNG::EXTRA_BYTE if color_mode == ChunkyPNG::COLOR_TRUECOLOR
386     pixel_decoder = decode_png_pixels_from_scanline_method(color_mode, depth)
387     line_length   = ChunkyPNG::Color.scanline_bytesize(color_mode, depth, width)
388     pixel_size    = ChunkyPNG::Color.pixel_bytesize(color_mode, depth)
389 
390     raise ChunkyPNG::ExpectationFailed, "Invalid stream length!" unless stream.bytesize - start_pos >= ChunkyPNG::Color.pass_bytesize(color_mode, depth, width, height)
391 
392     pos, prev_pos = start_pos, nil
393     for _ in 0...height do
394       decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
395       pixels.concat(send(pixel_decoder, stream, pos, width, decoding_palette))
396 
397       prev_pos = pos
398       pos += line_length + 1
399     end
400   end
401 
402   new(width, height, pixels)
403 end
decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 16-bit, grayscale image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
345 def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width, _decoding_palette)
346   values = stream.unpack("@#{pos + 1}n#{width}")
347   values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
348 end
decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 1-bit, grayscale image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
308 def decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width, _decoding_palette)
309   (0...width).map do |index|
310     value = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
311     value == 1 ? ChunkyPNG::Color::WHITE : ChunkyPNG::Color::BLACK
312   end
313 end
decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 2-bit, grayscale image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
318 def decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width, _decoding_palette)
319   (0...width).map do |index|
320     value = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
321     ChunkyPNG::Color.grayscale(decode_png_resample_2bit_value(value))
322   end
323 end
decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 4-bit, grayscale image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
328 def decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width, _decoding_palette)
329   (0...width).map do |index|
330     value = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
331     ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
332   end
333 end
decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of an 8-bit, grayscale image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
338 def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width, _decoding_palette)
339   (1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
340 end
decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 16-bit, grayscale image with transparency into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
297 def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width, _decoding_palette)
298   pixels = []
299   stream.unpack("@#{pos + 1}n#{width * 2}").each_slice(2) do |g, a|
300     pixels << ChunkyPNG::Color.grayscale_alpha(decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(a))
301   end
302   pixels
303 end
decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of an 8-bit, grayscale image with transparency into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
290 def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width, _decoding_palette)
291   (0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
292 end
decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width, decoding_palette) click to toggle source

Decodes a scanline of a 1-bit, indexed image into a row of pixels. @param [String] stream The stream to decode from. @param [Integer] pos The position in the stream on which the scanline starts (including the filter byte). @param [Integer] width The width in pixels of the scanline. @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors. @return [Array<Integer>] An array of decoded pixels.

    # File lib/chunky_png/canvas/png_decoding.rb
212 def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width, decoding_palette)
213   (0...width).map do |index|
214     palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
215     decoding_palette[palette_pos]
216   end
217 end
decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width, decoding_palette) click to toggle source

Decodes a scanline of a 2-bit, indexed image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
222 def decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width, decoding_palette)
223   (0...width).map do |index|
224     palette_pos = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
225     decoding_palette[palette_pos]
226   end
227 end
decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width, decoding_palette) click to toggle source

Decodes a scanline of a 4-bit, indexed image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
232 def decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width, decoding_palette)
233   (0...width).map do |index|
234     palette_pos = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
235     decoding_palette[palette_pos]
236   end
237 end
decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width, decoding_palette) click to toggle source

Decodes a scanline of a 8-bit, indexed image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
242 def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width, decoding_palette)
243   (1..width).map { |i| decoding_palette[stream.getbyte(pos + i)] }
244 end
decode_png_pixels_from_scanline_method(color_mode, depth) click to toggle source

Returns the method name to use to decode scanlines into pixels. @param [Integer] color_mode The color mode of the image. @param [Integer] depth The bit depth of the image. @return [Symbol] The method name to use for decoding, to be called on the canvas class. @raise [ChunkyPNG::NotSupported] when the color_mode and/or bit depth is not supported.

    # File lib/chunky_png/canvas/png_decoding.rb
355 def decode_png_pixels_from_scanline_method(color_mode, depth)
356   decoder_method = case color_mode
357     when ChunkyPNG::COLOR_TRUECOLOR       then :"decode_png_pixels_from_scanline_truecolor_#{depth}bit"
358     when ChunkyPNG::COLOR_TRUECOLOR_ALPHA then :"decode_png_pixels_from_scanline_truecolor_alpha_#{depth}bit"
359     when ChunkyPNG::COLOR_INDEXED         then :"decode_png_pixels_from_scanline_indexed_#{depth}bit"
360     when ChunkyPNG::COLOR_GRAYSCALE       then :"decode_png_pixels_from_scanline_grayscale_#{depth}bit"
361     when ChunkyPNG::COLOR_GRAYSCALE_ALPHA then :"decode_png_pixels_from_scanline_grayscale_alpha_#{depth}bit"
362   end
363 
364   raise ChunkyPNG::NotSupported, "No decoder found for color mode #{color_mode} and #{depth}-bit depth!" unless respond_to?(decoder_method, true)
365   decoder_method
366 end
decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 16-bit, true color image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
279 def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width, _decoding_palette)
280   pixels = []
281   stream.unpack("@#{pos + 1}n#{width * 3}").each_slice(3) do |r, g, b|
282     pixels << ChunkyPNG::Color.rgb(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(b))
283   end
284   pixels
285 end
decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of an 8-bit, true color image into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
272 def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width, _decoding_palette)
273   stream.unpack("@#{pos + 1}" << ("NX" * width)).map { |c| c | 0x000000ff }
274 end
decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of a 16-bit, true color image with transparency into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
256 def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width, _decoding_palette)
257   pixels = []
258   stream.unpack("@#{pos + 1}n#{width * 4}").each_slice(4) do |r, g, b, a|
259     pixels << ChunkyPNG::Color.rgba(
260       decode_png_resample_16bit_value(r),
261       decode_png_resample_16bit_value(g),
262       decode_png_resample_16bit_value(b),
263       decode_png_resample_16bit_value(a),
264     )
265   end
266   pixels
267 end
decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width, _decoding_palette) click to toggle source

Decodes a scanline of an 8-bit, true color image with transparency into a row of pixels. @params (see decode_png_pixels_from_scanline_indexed_1bit) @return (see decode_png_pixels_from_scanline_indexed_1bit)

    # File lib/chunky_png/canvas/png_decoding.rb
249 def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width, _decoding_palette)
250   stream.unpack("@#{pos + 1}N#{width}")
251 end
decode_png_resample_16bit_value(value) click to toggle source

Resamples a 16 bit value to an 8 bit value. This will discard some color information. @param [Integer] value The 16 bit value to resample. @return [Integer] The 8 bit resampled value

    # File lib/chunky_png/canvas/png_decoding.rb
174 def decode_png_resample_16bit_value(value)
175   value >> 8
176 end
decode_png_resample_1bit_value(value) click to toggle source

Resamples a 1 bit value to an 8 bit value. @param [Integer] value The 1 bit value to resample. @return [Integer] The 8 bit resampled value

    # File lib/chunky_png/canvas/png_decoding.rb
202 def decode_png_resample_1bit_value(value)
203   value == 0x01 ? 0xff : 0x00
204 end
decode_png_resample_2bit_value(value) click to toggle source

Resamples a 2 bit value to an 8 bit value. @param [Integer] value The 2 bit value to resample. @return [Integer] The 8 bit resampled value.

    # File lib/chunky_png/canvas/png_decoding.rb
195 def decode_png_resample_2bit_value(value)
196   value << 6 | value << 4 | value << 2 | value
197 end
decode_png_resample_4bit_value(value) click to toggle source

Resamples a 4 bit value to an 8 bit value. @param [Integer] value The 4 bit value to resample. @return [Integer] The 8 bit resampled value.

    # File lib/chunky_png/canvas/png_decoding.rb
188 def decode_png_resample_4bit_value(value)
189   value << 4 | value
190 end
decode_png_resample_8bit_value(value) click to toggle source

No-op - available for completeness sake only @param [Integer] value The 8 bit value to resample. @return [Integer] The 8 bit resampled value

    # File lib/chunky_png/canvas/png_decoding.rb
181 def decode_png_resample_8bit_value(value)
182   value
183 end
decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline if it was encoded using filtering.

It will extract the filtering method from the first byte of the scanline, and uses the method to change the subsequent bytes to unfiltered values. This will modify the pixelstream.

The bytes of the scanline can then be used to construct pixels, based on the color mode..

@param [String] stream The pixelstream to undo the filtering in. @param [Integer] pos The starting position of the scanline to decode. @param [Integer, nil] prev_pos The starting position of the previously decoded scanline, or nil

if this is the first scanline of the image.

@param [Integer] line_length The number of bytes in the scanline, discounting the filter method byte. @param [Integer] pixel_size The number of bytes used per pixel, based on the color mode. @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
419 def decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
420   case stream.getbyte(pos)
421     when ChunkyPNG::FILTER_NONE    then # rubocop:disable Lint/EmptyWhen # no-op
422     when ChunkyPNG::FILTER_SUB     then decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size)
423     when ChunkyPNG::FILTER_UP      then decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size)
424     when ChunkyPNG::FILTER_AVERAGE then decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size)
425     when ChunkyPNG::FILTER_PAETH   then decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size)
426     else raise ChunkyPNG::NotSupported, "Unknown filter type: #{stream.getbyte(pos)}!"
427   end
428 end
decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline in a pixelstream that was encoded using AVERAGE filtering. This will change the pixelstream to have unfiltered values. @params (see decode_png_str_scanline) @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
462 def decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size)
463   for i in 1..line_length do
464     a = i > pixel_size ? stream.getbyte(pos + i - pixel_size) : 0
465     b = prev_pos ? stream.getbyte(prev_pos + i) : 0
466     stream.setbyte(pos + i, (stream.getbyte(pos + i) + ((a + b) >> 1)) & 0xff)
467   end
468 end
decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline in a pixelstream that was encoded using PAETH filtering. This will change the pixelstream to have unfiltered values. @params (see decode_png_str_scanline) @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
474 def decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size)
475   for i in 1..line_length do
476     cur_pos = pos + i
477     a = i > pixel_size ? stream.getbyte(cur_pos - pixel_size) : 0
478     b = prev_pos ? stream.getbyte(prev_pos + i) : 0
479     c = prev_pos && i > pixel_size ? stream.getbyte(prev_pos + i - pixel_size) : 0
480     p = a + b - c
481     pa = (p - a).abs
482     pb = (p - b).abs
483     pc = (p - c).abs
484     pr = if pa <= pb
485       pa <= pc ? a : c
486     else
487       pb <= pc ? b : c
488     end
489 
490     stream.setbyte(cur_pos, (stream.getbyte(cur_pos) + pr) & 0xff)
491   end
492 end
decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline in a pixelstream that was encoded using SUB filtering. This will change the pixelstream to have unfiltered values. @params (see decode_png_str_scanline) @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
441 def decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size)
442   for i in 1..line_length do
443     stream.setbyte(pos + i, (stream.getbyte(pos + i) + (i > pixel_size ? stream.getbyte(pos + i - pixel_size) : 0)) & 0xff)
444   end
445 end
decode_png_str_scanline_sub_none(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline that wasn't encoded using filtering. This is a no-op. @params (see decode_png_str_scanline) @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
433 def decode_png_str_scanline_sub_none(stream, pos, prev_pos, line_length, pixel_size)
434   # noop - this method shouldn't get called.
435 end
decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size) click to toggle source

Decodes a scanline in a pixelstream that was encoded using UP filtering. This will change the pixelstream to have unfiltered values. @params (see decode_png_str_scanline) @return [void]

    # File lib/chunky_png/canvas/png_decoding.rb
451 def decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size)
452   for i in 1..line_length do
453     up = prev_pos ? stream.getbyte(prev_pos + i) : 0
454     stream.setbyte(pos + i, (stream.getbyte(pos + i) + up) & 0xff)
455   end
456 end
decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette) click to toggle source

Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a given width, height and color mode. @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors. @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)

    # File lib/chunky_png/canvas/png_decoding.rb
130 def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
131   canvas = new(width, height)
132   start_pos = 0
133   for pass in 0...7
134     sm_width, sm_height = adam7_pass_size(pass, width, height)
135     sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos, decoding_palette)
136     adam7_merge_pass(pass, canvas, sm)
137     start_pos += ChunkyPNG::Color.pass_bytesize(color_mode, depth, sm_width, sm_height)
138   end
139   canvas
140 end
decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette) click to toggle source

Decodes a canvas from a non-interlaced PNG encoded pixelstream, using a given width, height and color mode. @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream) @param [ChunkyPNG::Palette] decoding_palette The palette to use to decode colors. @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)

    # File lib/chunky_png/canvas/png_decoding.rb
117 def decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
118   decode_png_image_pass(stream, width, height, color_mode, depth, 0, decoding_palette)
119 end