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
 95 def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
 96   raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
 97 
 98   image = case interlace
 99     when ChunkyPNG::INTERLACING_NONE  then decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
100     when ChunkyPNG::INTERLACING_ADAM7 then decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
101     else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
102   end
103 
104   image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
105   image
106 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
35 def from_blob(str)
36   from_datastream(ChunkyPNG::Datastream.from_blob(str))
37 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
60 def from_datastream(ds)
61   width      = ds.header_chunk.width
62   height     = ds.header_chunk.height
63   color_mode = ds.header_chunk.color
64   interlace  = ds.header_chunk.interlace
65   depth      = ds.header_chunk.depth
66 
67   if width == 0 || height == 0
68     raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
69   end
70 
71   decoding_palette, transparent_color = nil, nil
72   case color_mode
73     when ChunkyPNG::COLOR_INDEXED
74       decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
75     when ChunkyPNG::COLOR_TRUECOLOR
76       transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
77     when ChunkyPNG::COLOR_GRAYSCALE
78       transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
79   end
80 
81   decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace, decoding_palette, transparent_color)
82 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
44 def from_file(filename)
45   from_datastream(ChunkyPNG::Datastream.from_file(filename))
46 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
51 def from_io(io)
52   from_datastream(ChunkyPNG::Datastream.from_io(io))
53 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
168 def decode_png_extract_1bit_value(byte, index)
169   bitshift = 7 - (index & 0x07)
170   (byte & (0x01 << bitshift)) >> bitshift
171 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
158 def decode_png_extract_2bit_value(byte, index)
159   bitshift = 6 - ((index & 0x03) << 1)
160   (byte & (0x03 << bitshift)) >> bitshift
161 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
149 def decode_png_extract_4bit_value(byte, index)
150   index & 0x01 == 0 ? ((byte & 0xf0) >> 4) : (byte & 0x0f)
151 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
383 def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos, decoding_palette)
384   pixels = []
385   if width > 0 && height > 0
386 
387     stream << ChunkyPNG::EXTRA_BYTE if color_mode == ChunkyPNG::COLOR_TRUECOLOR
388     pixel_decoder = decode_png_pixels_from_scanline_method(color_mode, depth)
389     line_length   = ChunkyPNG::Color.scanline_bytesize(color_mode, depth, width)
390     pixel_size    = ChunkyPNG::Color.pixel_bytesize(color_mode, depth)
391 
392     raise ChunkyPNG::ExpectationFailed, "Invalid stream length!" unless stream.bytesize - start_pos >= ChunkyPNG::Color.pass_bytesize(color_mode, depth, width, height)
393 
394     pos, prev_pos = start_pos, nil
395     for _ in 0...height do
396       decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
397       pixels.concat(send(pixel_decoder, stream, pos, width, decoding_palette))
398 
399       prev_pos = pos
400       pos += line_length + 1
401     end
402   end
403 
404   new(width, height, pixels)
405 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
347 def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width, _decoding_palette)
348   values = stream.unpack("@#{pos + 1}n#{width}")
349   values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
350 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
310 def decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width, _decoding_palette)
311   (0...width).map do |index|
312     value = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
313     value == 1 ? ChunkyPNG::Color::WHITE : ChunkyPNG::Color::BLACK
314   end
315 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
320 def decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width, _decoding_palette)
321   (0...width).map do |index|
322     value = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
323     ChunkyPNG::Color.grayscale(decode_png_resample_2bit_value(value))
324   end
325 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
330 def decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width, _decoding_palette)
331   (0...width).map do |index|
332     value = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
333     ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
334   end
335 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
340 def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width, _decoding_palette)
341   (1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
342 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
299 def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width, _decoding_palette)
300   pixels = []
301   stream.unpack("@#{pos + 1}n#{width * 2}").each_slice(2) do |g, a|
302     pixels << ChunkyPNG::Color.grayscale_alpha(decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(a))
303   end
304   pixels
305 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
292 def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width, _decoding_palette)
293   (0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
294 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
214 def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width, decoding_palette)
215   (0...width).map do |index|
216     palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
217     decoding_palette[palette_pos]
218   end
219 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
224 def decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width, decoding_palette)
225   (0...width).map do |index|
226     palette_pos = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
227     decoding_palette[palette_pos]
228   end
229 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
234 def decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width, decoding_palette)
235   (0...width).map do |index|
236     palette_pos = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
237     decoding_palette[palette_pos]
238   end
239 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
244 def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width, decoding_palette)
245   (1..width).map { |i| decoding_palette[stream.getbyte(pos + i)] }
246 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
357 def decode_png_pixels_from_scanline_method(color_mode, depth)
358   decoder_method = case color_mode
359     when ChunkyPNG::COLOR_TRUECOLOR       then :"decode_png_pixels_from_scanline_truecolor_#{depth}bit"
360     when ChunkyPNG::COLOR_TRUECOLOR_ALPHA then :"decode_png_pixels_from_scanline_truecolor_alpha_#{depth}bit"
361     when ChunkyPNG::COLOR_INDEXED         then :"decode_png_pixels_from_scanline_indexed_#{depth}bit"
362     when ChunkyPNG::COLOR_GRAYSCALE       then :"decode_png_pixels_from_scanline_grayscale_#{depth}bit"
363     when ChunkyPNG::COLOR_GRAYSCALE_ALPHA then :"decode_png_pixels_from_scanline_grayscale_alpha_#{depth}bit"
364   end
365 
366   raise ChunkyPNG::NotSupported, "No decoder found for color mode #{color_mode} and #{depth}-bit depth!" unless respond_to?(decoder_method, true)
367   decoder_method
368 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
281 def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width, _decoding_palette)
282   pixels = []
283   stream.unpack("@#{pos + 1}n#{width * 3}").each_slice(3) do |r, g, b|
284     pixels << ChunkyPNG::Color.rgb(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(b))
285   end
286   pixels
287 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
274 def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width, _decoding_palette)
275   stream.unpack("@#{pos + 1}#{"NX" * width}").map { |c| c | 0x000000ff }
276 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
258 def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width, _decoding_palette)
259   pixels = []
260   stream.unpack("@#{pos + 1}n#{width * 4}").each_slice(4) do |r, g, b, a|
261     pixels << ChunkyPNG::Color.rgba(
262       decode_png_resample_16bit_value(r),
263       decode_png_resample_16bit_value(g),
264       decode_png_resample_16bit_value(b),
265       decode_png_resample_16bit_value(a),
266     )
267   end
268   pixels
269 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
251 def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width, _decoding_palette)
252   stream.unpack("@#{pos + 1}N#{width}")
253 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
176 def decode_png_resample_16bit_value(value)
177   value >> 8
178 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
204 def decode_png_resample_1bit_value(value)
205   value == 0x01 ? 0xff : 0x00
206 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
197 def decode_png_resample_2bit_value(value)
198   value << 6 | value << 4 | value << 2 | value
199 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
190 def decode_png_resample_4bit_value(value)
191   value << 4 | value
192 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
183 def decode_png_resample_8bit_value(value)
184   value
185 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
421 def decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
422   case stream.getbyte(pos)
423     when ChunkyPNG::FILTER_NONE    then # rubocop:disable Lint/EmptyWhen # no-op
424     when ChunkyPNG::FILTER_SUB     then decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size)
425     when ChunkyPNG::FILTER_UP      then decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size)
426     when ChunkyPNG::FILTER_AVERAGE then decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size)
427     when ChunkyPNG::FILTER_PAETH   then decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size)
428     else raise ChunkyPNG::NotSupported, "Unknown filter type: #{stream.getbyte(pos)}!"
429   end
430 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
464 def decode_png_str_scanline_average(stream, pos, prev_pos, line_length, pixel_size)
465   for i in 1..line_length do
466     a = i > pixel_size ? stream.getbyte(pos + i - pixel_size) : 0
467     b = prev_pos ? stream.getbyte(prev_pos + i) : 0
468     stream.setbyte(pos + i, (stream.getbyte(pos + i) + ((a + b) >> 1)) & 0xff)
469   end
470 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
476 def decode_png_str_scanline_paeth(stream, pos, prev_pos, line_length, pixel_size)
477   for i in 1..line_length do
478     cur_pos = pos + i
479     a = i > pixel_size ? stream.getbyte(cur_pos - pixel_size) : 0
480     b = prev_pos ? stream.getbyte(prev_pos + i) : 0
481     c = prev_pos && i > pixel_size ? stream.getbyte(prev_pos + i - pixel_size) : 0
482     p = a + b - c
483     pa = (p - a).abs
484     pb = (p - b).abs
485     pc = (p - c).abs
486     pr = if pa <= pb
487       pa <= pc ? a : c
488     else
489       pb <= pc ? b : c
490     end
491 
492     stream.setbyte(cur_pos, (stream.getbyte(cur_pos) + pr) & 0xff)
493   end
494 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
443 def decode_png_str_scanline_sub(stream, pos, prev_pos, line_length, pixel_size)
444   for i in 1..line_length do
445     stream.setbyte(pos + i, (stream.getbyte(pos + i) + (i > pixel_size ? stream.getbyte(pos + i - pixel_size) : 0)) & 0xff)
446   end
447 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
435 def decode_png_str_scanline_sub_none(stream, pos, prev_pos, line_length, pixel_size)
436   # noop - this method shouldn't get called.
437 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
453 def decode_png_str_scanline_up(stream, pos, prev_pos, line_length, pixel_size)
454   for i in 1..line_length do
455     up = prev_pos ? stream.getbyte(prev_pos + i) : 0
456     stream.setbyte(pos + i, (stream.getbyte(pos + i) + up) & 0xff)
457   end
458 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
132 def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth, decoding_palette)
133   canvas = new(width, height)
134   start_pos = 0
135   for pass in 0...7
136     sm_width, sm_height = adam7_pass_size(pass, width, height)
137     sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos, decoding_palette)
138     adam7_merge_pass(pass, canvas, sm)
139     start_pos += ChunkyPNG::Color.pass_bytesize(color_mode, depth, sm_width, sm_height)
140   end
141   canvas
142 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
119 def decode_png_without_interlacing(stream, width, height, color_mode, depth, decoding_palette)
120   decode_png_image_pass(stream, width, height, color_mode, depth, 0, decoding_palette)
121 end