Module: ChunkyPNG::Canvas::Adam7Interlacing

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

Overview

Methods for decoding and encoding Adam7 interlacing.

Adam7 interlacing extracts 7 pass images out of a single image, that can be encoded to a stream separately so the image can be built up progressively. The module is included into ChunkyPNG canvas and is used to extract the pass images from the original image, or to reconstruct an original image from separate pass images.

Instance Method Summary collapse

Instance Method Details

#adam7_extract_pass(pass, canvas) ⇒ ChunkyPNG::Canvas

Extracts a pass from a complete image

Parameters:

  • pass (Integer)

    The pass number, should be in 0..6.

  • canvas (ChunkyPNG::Canvas)

    The image that is being deconstructed.

Returns:



63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/chunky_png/canvas/adam7_interlacing.rb', line 63

def adam7_extract_pass(pass, canvas)
  x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
  sm_pixels = []

  y_offset.step(canvas.height - 1, 1 << y_shift) do |y|
    x_offset.step(canvas.width - 1, 1 << x_shift) do |x|
      sm_pixels << canvas[x, y]
    end
  end

  new_canvas_args = adam7_pass_size(pass, canvas.width, canvas.height) + [sm_pixels]
  ChunkyPNG::Canvas.new(*new_canvas_args)
end

#adam7_merge_pass(pass, canvas, subcanvas) ⇒ Object

Merges a pass image into a total image that is being constructed.

Parameters:

  • pass (Integer)

    The pass number, should be in 0..6.

  • canvas (ChunkyPNG::Canvas)

    The image that is being constructed.

  • subcanvas (ChunkyPNG::Canvas)

    The pass image that should be merged



48
49
50
51
52
53
54
55
56
57
# File 'lib/chunky_png/canvas/adam7_interlacing.rb', line 48

def adam7_merge_pass(pass, canvas, subcanvas)
  x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
  for y in 0...subcanvas.height do
    for x in 0...subcanvas.width do
      new_x = (x << x_shift) | x_offset
      new_y = (y << y_shift) | y_offset
      canvas[new_x, new_y] = subcanvas[x, y]
    end
  end
end

#adam7_multiplier_offset(pass) ⇒ Object

Returns an array with the x-shift, x-offset, y-shift and y-offset for the requested pass.

Parameters:

  • pass (Integer)

    The pass number, should be in 0..6.



14
15
16
17
18
19
20
21
# File 'lib/chunky_png/canvas/adam7_interlacing.rb', line 14

def adam7_multiplier_offset(pass)
  [
    3 - (pass >> 1),
    pass & 1 == 0 ? 0 : 8 >> ((pass + 1) >> 1),
    pass == 0 ? 3 : 3 - ((pass - 1) >> 1),
    pass == 0 || pass & 1 == 1 ? 0 : 8 >> (pass >> 1),
  ]
end

#adam7_pass_size(pass, original_width, original_height) ⇒ Object

Returns the pixel dimensions of the requested pass.

Parameters:

  • pass (Integer)

    The pass number, should be in 0..6.

  • original_width (Integer)

    The width of the original image.

  • original_height (Integer)

    The height of the original image.



27
28
29
30
31
32
33
# File 'lib/chunky_png/canvas/adam7_interlacing.rb', line 27

def adam7_pass_size(pass, original_width, original_height)
  x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
  [
    (original_width  - x_offset + (1 << x_shift) - 1) >> x_shift,
    (original_height - y_offset + (1 << y_shift) - 1) >> y_shift,
  ]
end

#adam7_pass_sizes(original_width, original_height) ⇒ Array<Array<Integer>>

Returns an array of the dimension of all the pass images.

Parameters:

  • original_width (Integer)

    The width of the original image.

  • original_height (Integer)

    The height of the original image.

Returns:

  • (Array<Array<Integer>>)

    Returns an array with 7 pairs of dimensions.

See Also:



40
41
42
# File 'lib/chunky_png/canvas/adam7_interlacing.rb', line 40

def adam7_pass_sizes(original_width, original_height)
  (0...7).map { |pass| adam7_pass_size(pass, original_width, original_height) }
end