chunky_png 0.10.5 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile.lock +1 -1
- data/benchmarks/filesize_benchmark.rb +1 -1
- data/chunky_png.gemspec +4 -4
- data/lib/chunky_png.rb +4 -11
- data/lib/chunky_png/canvas.rb +7 -8
- data/lib/chunky_png/canvas/adam7_interlacing.rb +36 -18
- data/lib/chunky_png/canvas/png_decoding.rb +258 -36
- data/lib/chunky_png/canvas/png_encoding.rb +1 -1
- data/lib/chunky_png/color.rb +41 -5
- data/lib/chunky_png/compatibility.rb +15 -0
- data/lib/chunky_png/datastream.rb +6 -0
- data/spec/chunky_png/canvas/adam7_interlacing_spec.rb +7 -7
- data/spec/chunky_png/canvas/png_decoding_spec.rb +33 -20
- data/spec/chunky_png/canvas/png_encoding_spec.rb +2 -3
- data/spec/chunky_png/color_spec.rb +29 -0
- data/spec/chunky_png/datastream_spec.rb +0 -5
- data/spec/chunky_png/rmagick_spec.rb +3 -3
- data/spec/png_suite/background_chunks/bgai4a08.png +0 -0
- data/spec/png_suite/background_chunks/bgai4a16.png +0 -0
- data/spec/png_suite/background_chunks/bgan6a08.png +0 -0
- data/spec/png_suite/background_chunks/bgan6a16.png +0 -0
- data/spec/png_suite/background_chunks/bgbn4a08.png +0 -0
- data/spec/png_suite/background_chunks/bggn4a16.png +0 -0
- data/spec/png_suite/background_chunks/bgwn6a08.png +0 -0
- data/spec/png_suite/background_chunks/bgyn6a16.png +0 -0
- data/spec/png_suite/basic/basi0g01.png +0 -0
- data/spec/png_suite/basic/basi0g01.rgba +0 -0
- data/spec/png_suite/basic/basi0g02.png +0 -0
- data/spec/png_suite/basic/basi0g02.rgba +0 -0
- data/spec/png_suite/basic/basi0g04.png +0 -0
- data/spec/png_suite/basic/basi0g04.rgba +0 -0
- data/spec/png_suite/basic/basi0g08.png +0 -0
- data/spec/png_suite/basic/basi0g08.rgba +0 -0
- data/spec/png_suite/basic/basi0g16.png +0 -0
- data/spec/png_suite/basic/basi0g16.rgba +0 -0
- data/spec/png_suite/basic/basi2c08.png +0 -0
- data/spec/png_suite/basic/basi2c08.rgba +0 -0
- data/spec/png_suite/basic/basi2c16.png +0 -0
- data/spec/png_suite/basic/basi2c16.rgba +0 -0
- data/spec/png_suite/basic/basi3p01.png +0 -0
- data/spec/png_suite/basic/basi3p01.rgba +1 -0
- data/spec/png_suite/basic/basi3p02.png +0 -0
- data/spec/png_suite/basic/basi3p02.rgba +0 -0
- data/spec/png_suite/basic/basi3p04.png +0 -0
- data/spec/png_suite/basic/basi3p04.rgba +0 -0
- data/spec/png_suite/basic/basi3p08.png +0 -0
- data/spec/png_suite/basic/basi3p08.rgba +0 -0
- data/spec/png_suite/basic/basi4a08.png +0 -0
- data/spec/png_suite/basic/basi4a08.rgba +0 -0
- data/spec/png_suite/basic/basi4a16.png +0 -0
- data/spec/png_suite/basic/basi4a16.rgba +0 -0
- data/spec/png_suite/basic/basi6a08.png +0 -0
- data/spec/png_suite/basic/basi6a08.rgba +0 -0
- data/spec/png_suite/basic/basi6a16.png +0 -0
- data/spec/png_suite/basic/basi6a16.rgba +0 -0
- data/spec/png_suite/basic/basn0g01.png +0 -0
- data/spec/png_suite/basic/basn0g01.rgba +0 -0
- data/spec/png_suite/basic/basn0g02.png +0 -0
- data/spec/png_suite/basic/basn0g02.rgba +0 -0
- data/spec/png_suite/basic/basn0g04.png +0 -0
- data/spec/png_suite/basic/basn0g04.rgba +0 -0
- data/spec/png_suite/basic/basn0g08.png +0 -0
- data/spec/png_suite/basic/basn0g08.rgba +0 -0
- data/spec/png_suite/basic/basn0g16.png +0 -0
- data/spec/png_suite/basic/basn0g16.rgba +0 -0
- data/spec/png_suite/basic/basn2c08.png +0 -0
- data/spec/png_suite/basic/basn2c08.rgba +0 -0
- data/spec/png_suite/basic/basn2c16.png +0 -0
- data/spec/png_suite/basic/basn2c16.rgba +0 -0
- data/spec/png_suite/basic/basn3p01.png +0 -0
- data/spec/png_suite/basic/basn3p01.rgba +1 -0
- data/spec/png_suite/basic/basn3p02.png +0 -0
- data/spec/png_suite/basic/basn3p02.rgba +0 -0
- data/spec/{resources/indexed_4bit.png → png_suite/basic/basn3p04.png} +0 -0
- data/spec/png_suite/basic/basn3p04.rgba +0 -0
- data/spec/png_suite/basic/basn3p08.png +0 -0
- data/spec/png_suite/basic/basn3p08.rgba +0 -0
- data/spec/png_suite/basic/basn4a08.png +0 -0
- data/spec/png_suite/basic/basn4a08.rgba +0 -0
- data/spec/png_suite/basic/basn4a16.png +0 -0
- data/spec/png_suite/basic/basn4a16.rgba +0 -0
- data/spec/png_suite/basic/basn6a08.png +0 -0
- data/spec/png_suite/basic/basn6a08.rgba +0 -0
- data/spec/png_suite/basic/basn6a16.png +0 -0
- data/spec/png_suite/basic/basn6a16.rgba +0 -0
- data/spec/png_suite/broken/x00n0g01.png +0 -0
- data/spec/png_suite/broken/xcrn0g04.png +0 -0
- data/spec/png_suite/broken/xlfn0g04.png +13 -0
- data/spec/png_suite/chunk_ordering/oi1n0g16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi1n2c16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi2n0g16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi2n2c16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi4n0g16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi4n2c16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi9n0g16.png +0 -0
- data/spec/png_suite/chunk_ordering/oi9n2c16.png +0 -0
- data/spec/png_suite/compression_levels/z00n2c08.png +0 -0
- data/spec/png_suite/compression_levels/z03n2c08.png +0 -0
- data/spec/png_suite/compression_levels/z06n2c08.png +0 -0
- data/spec/png_suite/compression_levels/z09n2c08.png +0 -0
- data/spec/png_suite/filtering/f00n0g08.png +0 -0
- data/spec/png_suite/filtering/f00n0g08.rgba +0 -0
- data/spec/png_suite/filtering/f00n0g08_reference.png +0 -0
- data/spec/png_suite/filtering/f00n0g08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f00n2c08.png +0 -0
- data/spec/png_suite/filtering/f00n2c08.rgba +0 -0
- data/spec/png_suite/filtering/f00n2c08_reference.png +0 -0
- data/spec/png_suite/filtering/f00n2c08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f01n0g08.png +0 -0
- data/spec/png_suite/filtering/f01n0g08.rgba +0 -0
- data/spec/png_suite/filtering/f01n0g08_reference.png +0 -0
- data/spec/png_suite/filtering/f01n0g08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f01n2c08.png +0 -0
- data/spec/png_suite/filtering/f01n2c08.rgba +0 -0
- data/spec/png_suite/filtering/f01n2c08_reference.png +0 -0
- data/spec/png_suite/filtering/f01n2c08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f02n0g08.png +0 -0
- data/spec/png_suite/filtering/f02n0g08.rgba +0 -0
- data/spec/png_suite/filtering/f02n0g08_reference.png +0 -0
- data/spec/png_suite/filtering/f02n0g08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f02n2c08.png +0 -0
- data/spec/png_suite/filtering/f02n2c08.rgba +0 -0
- data/spec/png_suite/filtering/f02n2c08_reference.png +0 -0
- data/spec/png_suite/filtering/f02n2c08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f03n0g08.png +0 -0
- data/spec/png_suite/filtering/f03n0g08.rgba +0 -0
- data/spec/png_suite/filtering/f03n0g08_reference.png +0 -0
- data/spec/png_suite/filtering/f03n0g08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f03n2c08.png +0 -0
- data/spec/png_suite/filtering/f03n2c08.rgba +0 -0
- data/spec/png_suite/filtering/f03n2c08_reference.png +0 -0
- data/spec/png_suite/filtering/f03n2c08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f04n0g08.png +0 -0
- data/spec/png_suite/filtering/f04n0g08.rgba +0 -0
- data/spec/png_suite/filtering/f04n0g08_reference.png +0 -0
- data/spec/png_suite/filtering/f04n0g08_reference.rgba +0 -0
- data/spec/png_suite/filtering/f04n2c08.png +0 -0
- data/spec/png_suite/filtering/f04n2c08.rgba +0 -0
- data/spec/png_suite/filtering/f04n2c08_reference.png +0 -0
- data/spec/png_suite/filtering/f04n2c08_reference.rgba +0 -0
- data/spec/png_suite/gamma/g03n0g16.png +0 -0
- data/spec/png_suite/gamma/g03n2c08.png +0 -0
- data/spec/png_suite/gamma/g03n3p04.png +0 -0
- data/spec/png_suite/gamma/g04n0g16.png +0 -0
- data/spec/png_suite/gamma/g04n2c08.png +0 -0
- data/spec/png_suite/gamma/g04n3p04.png +0 -0
- data/spec/png_suite/gamma/g05n0g16.png +0 -0
- data/spec/png_suite/gamma/g05n2c08.png +0 -0
- data/spec/png_suite/gamma/g05n3p04.png +0 -0
- data/spec/png_suite/gamma/g07n0g16.png +0 -0
- data/spec/png_suite/gamma/g07n2c08.png +0 -0
- data/spec/png_suite/gamma/g07n3p04.png +0 -0
- data/spec/png_suite/gamma/g10n0g16.png +0 -0
- data/spec/png_suite/gamma/g10n2c08.png +0 -0
- data/spec/png_suite/gamma/g10n3p04.png +0 -0
- data/spec/png_suite/gamma/g25n0g16.png +0 -0
- data/spec/png_suite/gamma/g25n2c08.png +0 -0
- data/spec/png_suite/gamma/g25n3p04.png +0 -0
- data/spec/png_suite/metadata/cm0n0g04.png +0 -0
- data/spec/png_suite/metadata/cm7n0g04.png +0 -0
- data/spec/png_suite/metadata/cm9n0g04.png +0 -0
- data/spec/png_suite/other/ccwn2c08.png +0 -0
- data/spec/png_suite/other/ccwn3p08.png +0 -0
- data/spec/png_suite/other/cdfn2c08.png +0 -0
- data/spec/png_suite/other/cdhn2c08.png +0 -0
- data/spec/png_suite/other/cdsn2c08.png +0 -0
- data/spec/png_suite/other/cdun2c08.png +0 -0
- data/spec/png_suite/other/ch1n3p04.png +0 -0
- data/spec/png_suite/other/ch2n3p08.png +0 -0
- data/spec/png_suite/other/cs3n2c16.png +0 -0
- data/spec/png_suite/other/cs3n3p08.png +0 -0
- data/spec/png_suite/other/cs5n2c08.png +0 -0
- data/spec/png_suite/other/cs5n3p08.png +0 -0
- data/spec/png_suite/other/cs8n2c08.png +0 -0
- data/spec/png_suite/other/cs8n3p08.png +0 -0
- data/spec/png_suite/other/ct0n0g04.png +0 -0
- data/spec/png_suite/other/ct1n0g04.png +0 -0
- data/spec/png_suite/other/ctzn0g04.png +0 -0
- data/spec/png_suite/other/pp0n2c16.png +0 -0
- data/spec/png_suite/other/pp0n6a08.png +0 -0
- data/spec/png_suite/other/ps1n0g08.png +0 -0
- data/spec/png_suite/other/ps1n2c16.png +0 -0
- data/spec/png_suite/other/ps2n0g08.png +0 -0
- data/spec/png_suite/other/ps2n2c16.png +0 -0
- data/spec/png_suite/sizes/s01i3p01.png +0 -0
- data/spec/png_suite/sizes/s01n3p01.png +0 -0
- data/spec/png_suite/sizes/s02i3p01.png +0 -0
- data/spec/png_suite/sizes/s02n3p01.png +0 -0
- data/spec/png_suite/sizes/s03i3p01.png +0 -0
- data/spec/png_suite/sizes/s03n3p01.png +0 -0
- data/spec/png_suite/sizes/s04i3p01.png +0 -0
- data/spec/png_suite/sizes/s04n3p01.png +0 -0
- data/spec/png_suite/sizes/s05i3p02.png +0 -0
- data/spec/png_suite/sizes/s05n3p02.png +0 -0
- data/spec/png_suite/sizes/s06i3p02.png +0 -0
- data/spec/png_suite/sizes/s06n3p02.png +0 -0
- data/spec/png_suite/sizes/s07i3p02.png +0 -0
- data/spec/png_suite/sizes/s07n3p02.png +0 -0
- data/spec/png_suite/sizes/s08i3p02.png +0 -0
- data/spec/png_suite/sizes/s08n3p02.png +0 -0
- data/spec/png_suite/sizes/s09i3p02.png +0 -0
- data/spec/png_suite/sizes/s09n3p02.png +0 -0
- data/spec/png_suite/sizes/s32i3p04.png +0 -0
- data/spec/png_suite/sizes/s32n3p04.png +0 -0
- data/spec/png_suite/sizes/s33i3p04.png +0 -0
- data/spec/png_suite/sizes/s33n3p04.png +0 -0
- data/spec/png_suite/sizes/s34i3p04.png +0 -0
- data/spec/png_suite/sizes/s34n3p04.png +0 -0
- data/spec/png_suite/sizes/s35i3p04.png +0 -0
- data/spec/png_suite/sizes/s35n3p04.png +0 -0
- data/spec/png_suite/sizes/s36i3p04.png +0 -0
- data/spec/png_suite/sizes/s36n3p04.png +0 -0
- data/spec/png_suite/sizes/s37i3p04.png +0 -0
- data/spec/png_suite/sizes/s37n3p04.png +0 -0
- data/spec/png_suite/sizes/s38i3p04.png +0 -0
- data/spec/png_suite/sizes/s38n3p04.png +0 -0
- data/spec/png_suite/sizes/s39i3p04.png +0 -0
- data/spec/png_suite/sizes/s39n3p04.png +0 -0
- data/spec/png_suite/sizes/s40i3p04.png +0 -0
- data/spec/png_suite/sizes/s40n3p04.png +0 -0
- data/spec/png_suite/transparency/tbbn1g04.png +0 -0
- data/spec/png_suite/transparency/tbbn2c16.png +0 -0
- data/spec/png_suite/transparency/tbbn3p08.png +0 -0
- data/spec/png_suite/transparency/tbgn2c16.png +0 -0
- data/spec/png_suite/transparency/tbgn3p08.png +0 -0
- data/spec/png_suite/transparency/tbrn2c08.png +0 -0
- data/spec/png_suite/transparency/tbwn1g16.png +0 -0
- data/spec/png_suite/transparency/tbwn3p08.png +0 -0
- data/spec/png_suite/transparency/tbyn3p08.png +0 -0
- data/spec/png_suite/transparency/tp0n1g08.png +0 -0
- data/spec/png_suite/transparency/tp0n2c08.png +0 -0
- data/spec/png_suite/transparency/tp0n3p08.png +0 -0
- data/spec/png_suite/transparency/tp1n3p08.png +0 -0
- data/spec/png_suite_spec.rb +119 -0
- data/spec/spec_helper.rb +26 -16
- metadata +240 -25
- data/spec/resources/16x16_interlaced.png +0 -0
- data/spec/resources/16x16_non_interlaced.png +0 -0
- data/spec/resources/gray_10x10.png +0 -0
- data/spec/resources/gray_10x10_grayscale.png +0 -0
- data/spec/resources/gray_10x10_grayscale_alpha.png +0 -0
- data/spec/resources/gray_10x10_indexed.png +0 -0
- data/spec/resources/gray_10x10_truecolor.png +0 -0
- data/spec/resources/gray_10x10_truecolor_alpha.png +0 -0
- data/spec/resources/transparent_gray_10x10.png +0 -0
data/Gemfile.lock
CHANGED
@@ -6,7 +6,7 @@ Bundler.setup
|
|
6
6
|
require 'benchmark'
|
7
7
|
require 'chunky_png'
|
8
8
|
|
9
|
-
files = ['pixelstream_reference.png', 'operations.png', '
|
9
|
+
files = ['pixelstream_reference.png', 'operations.png', 'clock_stubbed.png']
|
10
10
|
|
11
11
|
def encode_png(image, constraints = {})
|
12
12
|
filesize = nil
|
data/chunky_png.gemspec
CHANGED
@@ -3,8 +3,8 @@ Gem::Specification.new do |s|
|
|
3
3
|
|
4
4
|
# Do not change the version and date fields by hand. This will be done
|
5
5
|
# automatically by the gem release script.
|
6
|
-
s.version = "0.
|
7
|
-
s.date = "2010-
|
6
|
+
s.version = "0.11.0"
|
7
|
+
s.date = "2010-11-01"
|
8
8
|
|
9
9
|
s.summary = "Pure ruby library for read/write, chunk-level access to PNG files"
|
10
10
|
s.description = <<-EOT
|
@@ -38,6 +38,6 @@ Gem::Specification.new do |s|
|
|
38
38
|
|
39
39
|
# Do not change the files and test_files fields by hand. This will be done
|
40
40
|
# automatically by the gem release script.
|
41
|
-
s.files = %w(.gitignore BENCHMARKS.rdoc Gemfile Gemfile.lock LICENSE README.rdoc Rakefile benchmarks/decoding_benchmark.rb benchmarks/encoding_benchmark.rb benchmarks/filesize_benchmark.rb chunky_png.gemspec lib/chunky_png.rb lib/chunky_png/canvas.rb lib/chunky_png/canvas/adam7_interlacing.rb lib/chunky_png/canvas/drawing.rb lib/chunky_png/canvas/operations.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/stream_exporting.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/chunk.rb lib/chunky_png/color.rb lib/chunky_png/datastream.rb lib/chunky_png/image.rb lib/chunky_png/palette.rb lib/chunky_png/rmagick.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb spec/resources/16x16_interlaced.png spec/resources/16x16_non_interlaced.png spec/resources/adam7.png spec/resources/clock.png spec/resources/clock_base.png spec/resources/clock_flip_horizontally.png spec/resources/clock_flip_vertically.png spec/resources/clock_mask.png spec/resources/clock_mask_updated.png spec/resources/clock_rotate_180.png spec/resources/clock_rotate_left.png spec/resources/clock_rotate_right.png spec/resources/clock_stubbed.png spec/resources/clock_updated.png spec/resources/composited.png spec/resources/cropped.png spec/resources/damaged_chunk.png spec/resources/damaged_signature.png spec/resources/gray_10x10.png spec/resources/gray_10x10_grayscale.png spec/resources/gray_10x10_grayscale_alpha.png spec/resources/gray_10x10_indexed.png spec/resources/gray_10x10_truecolor.png spec/resources/gray_10x10_truecolor_alpha.png spec/resources/indexed_4bit.png spec/resources/lines.png spec/resources/operations.png spec/resources/pixelstream.rgb spec/resources/pixelstream.rgba spec/resources/pixelstream_best_compression.png spec/resources/pixelstream_fast_rgba.png spec/resources/pixelstream_reference.png spec/resources/rect.png spec/resources/replaced.png spec/resources/text_chunk.png spec/resources/transparent_gray_10x10.png spec/resources/ztxt_chunk.png spec/spec_helper.rb tasks/benchmarks.rake tasks/github-gem.rake)
|
42
|
-
s.test_files = %w(spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb)
|
41
|
+
s.files = %w(.gitignore BENCHMARKS.rdoc Gemfile Gemfile.lock LICENSE README.rdoc Rakefile benchmarks/decoding_benchmark.rb benchmarks/encoding_benchmark.rb benchmarks/filesize_benchmark.rb chunky_png.gemspec lib/chunky_png.rb lib/chunky_png/canvas.rb lib/chunky_png/canvas/adam7_interlacing.rb lib/chunky_png/canvas/drawing.rb lib/chunky_png/canvas/operations.rb lib/chunky_png/canvas/png_decoding.rb lib/chunky_png/canvas/png_encoding.rb lib/chunky_png/canvas/stream_exporting.rb lib/chunky_png/canvas/stream_importing.rb lib/chunky_png/chunk.rb lib/chunky_png/color.rb lib/chunky_png/compatibility.rb lib/chunky_png/datastream.rb lib/chunky_png/image.rb lib/chunky_png/palette.rb lib/chunky_png/rmagick.rb spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb spec/png_suite/background_chunks/bgai4a08.png spec/png_suite/background_chunks/bgai4a16.png spec/png_suite/background_chunks/bgan6a08.png spec/png_suite/background_chunks/bgan6a16.png spec/png_suite/background_chunks/bgbn4a08.png spec/png_suite/background_chunks/bggn4a16.png spec/png_suite/background_chunks/bgwn6a08.png spec/png_suite/background_chunks/bgyn6a16.png spec/png_suite/basic/basi0g01.png spec/png_suite/basic/basi0g01.rgba spec/png_suite/basic/basi0g02.png spec/png_suite/basic/basi0g02.rgba spec/png_suite/basic/basi0g04.png spec/png_suite/basic/basi0g04.rgba spec/png_suite/basic/basi0g08.png spec/png_suite/basic/basi0g08.rgba spec/png_suite/basic/basi0g16.png spec/png_suite/basic/basi0g16.rgba spec/png_suite/basic/basi2c08.png spec/png_suite/basic/basi2c08.rgba spec/png_suite/basic/basi2c16.png spec/png_suite/basic/basi2c16.rgba spec/png_suite/basic/basi3p01.png spec/png_suite/basic/basi3p01.rgba spec/png_suite/basic/basi3p02.png spec/png_suite/basic/basi3p02.rgba spec/png_suite/basic/basi3p04.png spec/png_suite/basic/basi3p04.rgba spec/png_suite/basic/basi3p08.png spec/png_suite/basic/basi3p08.rgba spec/png_suite/basic/basi4a08.png spec/png_suite/basic/basi4a08.rgba spec/png_suite/basic/basi4a16.png spec/png_suite/basic/basi4a16.rgba spec/png_suite/basic/basi6a08.png spec/png_suite/basic/basi6a08.rgba spec/png_suite/basic/basi6a16.png spec/png_suite/basic/basi6a16.rgba spec/png_suite/basic/basn0g01.png spec/png_suite/basic/basn0g01.rgba spec/png_suite/basic/basn0g02.png spec/png_suite/basic/basn0g02.rgba spec/png_suite/basic/basn0g04.png spec/png_suite/basic/basn0g04.rgba spec/png_suite/basic/basn0g08.png spec/png_suite/basic/basn0g08.rgba spec/png_suite/basic/basn0g16.png spec/png_suite/basic/basn0g16.rgba spec/png_suite/basic/basn2c08.png spec/png_suite/basic/basn2c08.rgba spec/png_suite/basic/basn2c16.png spec/png_suite/basic/basn2c16.rgba spec/png_suite/basic/basn3p01.png spec/png_suite/basic/basn3p01.rgba spec/png_suite/basic/basn3p02.png spec/png_suite/basic/basn3p02.rgba spec/png_suite/basic/basn3p04.png spec/png_suite/basic/basn3p04.rgba spec/png_suite/basic/basn3p08.png spec/png_suite/basic/basn3p08.rgba spec/png_suite/basic/basn4a08.png spec/png_suite/basic/basn4a08.rgba spec/png_suite/basic/basn4a16.png spec/png_suite/basic/basn4a16.rgba spec/png_suite/basic/basn6a08.png spec/png_suite/basic/basn6a08.rgba spec/png_suite/basic/basn6a16.png spec/png_suite/basic/basn6a16.rgba spec/png_suite/broken/x00n0g01.png spec/png_suite/broken/xcrn0g04.png spec/png_suite/broken/xlfn0g04.png spec/png_suite/chunk_ordering/oi1n0g16.png spec/png_suite/chunk_ordering/oi1n2c16.png spec/png_suite/chunk_ordering/oi2n0g16.png spec/png_suite/chunk_ordering/oi2n2c16.png spec/png_suite/chunk_ordering/oi4n0g16.png spec/png_suite/chunk_ordering/oi4n2c16.png spec/png_suite/chunk_ordering/oi9n0g16.png spec/png_suite/chunk_ordering/oi9n2c16.png spec/png_suite/compression_levels/z00n2c08.png spec/png_suite/compression_levels/z03n2c08.png spec/png_suite/compression_levels/z06n2c08.png spec/png_suite/compression_levels/z09n2c08.png spec/png_suite/filtering/f00n0g08.png spec/png_suite/filtering/f00n0g08.rgba spec/png_suite/filtering/f00n0g08_reference.png spec/png_suite/filtering/f00n0g08_reference.rgba spec/png_suite/filtering/f00n2c08.png spec/png_suite/filtering/f00n2c08.rgba spec/png_suite/filtering/f00n2c08_reference.png spec/png_suite/filtering/f00n2c08_reference.rgba spec/png_suite/filtering/f01n0g08.png spec/png_suite/filtering/f01n0g08.rgba spec/png_suite/filtering/f01n0g08_reference.png spec/png_suite/filtering/f01n0g08_reference.rgba spec/png_suite/filtering/f01n2c08.png spec/png_suite/filtering/f01n2c08.rgba spec/png_suite/filtering/f01n2c08_reference.png spec/png_suite/filtering/f01n2c08_reference.rgba spec/png_suite/filtering/f02n0g08.png spec/png_suite/filtering/f02n0g08.rgba spec/png_suite/filtering/f02n0g08_reference.png spec/png_suite/filtering/f02n0g08_reference.rgba spec/png_suite/filtering/f02n2c08.png spec/png_suite/filtering/f02n2c08.rgba spec/png_suite/filtering/f02n2c08_reference.png spec/png_suite/filtering/f02n2c08_reference.rgba spec/png_suite/filtering/f03n0g08.png spec/png_suite/filtering/f03n0g08.rgba spec/png_suite/filtering/f03n0g08_reference.png spec/png_suite/filtering/f03n0g08_reference.rgba spec/png_suite/filtering/f03n2c08.png spec/png_suite/filtering/f03n2c08.rgba spec/png_suite/filtering/f03n2c08_reference.png spec/png_suite/filtering/f03n2c08_reference.rgba spec/png_suite/filtering/f04n0g08.png spec/png_suite/filtering/f04n0g08.rgba spec/png_suite/filtering/f04n0g08_reference.png spec/png_suite/filtering/f04n0g08_reference.rgba spec/png_suite/filtering/f04n2c08.png spec/png_suite/filtering/f04n2c08.rgba spec/png_suite/filtering/f04n2c08_reference.png spec/png_suite/filtering/f04n2c08_reference.rgba spec/png_suite/gamma/g03n0g16.png spec/png_suite/gamma/g03n2c08.png spec/png_suite/gamma/g03n3p04.png spec/png_suite/gamma/g04n0g16.png spec/png_suite/gamma/g04n2c08.png spec/png_suite/gamma/g04n3p04.png spec/png_suite/gamma/g05n0g16.png spec/png_suite/gamma/g05n2c08.png spec/png_suite/gamma/g05n3p04.png spec/png_suite/gamma/g07n0g16.png spec/png_suite/gamma/g07n2c08.png spec/png_suite/gamma/g07n3p04.png spec/png_suite/gamma/g10n0g16.png spec/png_suite/gamma/g10n2c08.png spec/png_suite/gamma/g10n3p04.png spec/png_suite/gamma/g25n0g16.png spec/png_suite/gamma/g25n2c08.png spec/png_suite/gamma/g25n3p04.png spec/png_suite/metadata/cm0n0g04.png spec/png_suite/metadata/cm7n0g04.png spec/png_suite/metadata/cm9n0g04.png spec/png_suite/other/ccwn2c08.png spec/png_suite/other/ccwn3p08.png spec/png_suite/other/cdfn2c08.png spec/png_suite/other/cdhn2c08.png spec/png_suite/other/cdsn2c08.png spec/png_suite/other/cdun2c08.png spec/png_suite/other/ch1n3p04.png spec/png_suite/other/ch2n3p08.png spec/png_suite/other/cs3n2c16.png spec/png_suite/other/cs3n3p08.png spec/png_suite/other/cs5n2c08.png spec/png_suite/other/cs5n3p08.png spec/png_suite/other/cs8n2c08.png spec/png_suite/other/cs8n3p08.png spec/png_suite/other/ct0n0g04.png spec/png_suite/other/ct1n0g04.png spec/png_suite/other/ctzn0g04.png spec/png_suite/other/pp0n2c16.png spec/png_suite/other/pp0n6a08.png spec/png_suite/other/ps1n0g08.png spec/png_suite/other/ps1n2c16.png spec/png_suite/other/ps2n0g08.png spec/png_suite/other/ps2n2c16.png spec/png_suite/sizes/s01i3p01.png spec/png_suite/sizes/s01n3p01.png spec/png_suite/sizes/s02i3p01.png spec/png_suite/sizes/s02n3p01.png spec/png_suite/sizes/s03i3p01.png spec/png_suite/sizes/s03n3p01.png spec/png_suite/sizes/s04i3p01.png spec/png_suite/sizes/s04n3p01.png spec/png_suite/sizes/s05i3p02.png spec/png_suite/sizes/s05n3p02.png spec/png_suite/sizes/s06i3p02.png spec/png_suite/sizes/s06n3p02.png spec/png_suite/sizes/s07i3p02.png spec/png_suite/sizes/s07n3p02.png spec/png_suite/sizes/s08i3p02.png spec/png_suite/sizes/s08n3p02.png spec/png_suite/sizes/s09i3p02.png spec/png_suite/sizes/s09n3p02.png spec/png_suite/sizes/s32i3p04.png spec/png_suite/sizes/s32n3p04.png spec/png_suite/sizes/s33i3p04.png spec/png_suite/sizes/s33n3p04.png spec/png_suite/sizes/s34i3p04.png spec/png_suite/sizes/s34n3p04.png spec/png_suite/sizes/s35i3p04.png spec/png_suite/sizes/s35n3p04.png spec/png_suite/sizes/s36i3p04.png spec/png_suite/sizes/s36n3p04.png spec/png_suite/sizes/s37i3p04.png spec/png_suite/sizes/s37n3p04.png spec/png_suite/sizes/s38i3p04.png spec/png_suite/sizes/s38n3p04.png spec/png_suite/sizes/s39i3p04.png spec/png_suite/sizes/s39n3p04.png spec/png_suite/sizes/s40i3p04.png spec/png_suite/sizes/s40n3p04.png spec/png_suite/transparency/tbbn1g04.png spec/png_suite/transparency/tbbn2c16.png spec/png_suite/transparency/tbbn3p08.png spec/png_suite/transparency/tbgn2c16.png spec/png_suite/transparency/tbgn3p08.png spec/png_suite/transparency/tbrn2c08.png spec/png_suite/transparency/tbwn1g16.png spec/png_suite/transparency/tbwn3p08.png spec/png_suite/transparency/tbyn3p08.png spec/png_suite/transparency/tp0n1g08.png spec/png_suite/transparency/tp0n2c08.png spec/png_suite/transparency/tp0n3p08.png spec/png_suite/transparency/tp1n3p08.png spec/png_suite_spec.rb spec/resources/adam7.png spec/resources/clock.png spec/resources/clock_base.png spec/resources/clock_flip_horizontally.png spec/resources/clock_flip_vertically.png spec/resources/clock_mask.png spec/resources/clock_mask_updated.png spec/resources/clock_rotate_180.png spec/resources/clock_rotate_left.png spec/resources/clock_rotate_right.png spec/resources/clock_stubbed.png spec/resources/clock_updated.png spec/resources/composited.png spec/resources/cropped.png spec/resources/damaged_chunk.png spec/resources/damaged_signature.png spec/resources/lines.png spec/resources/operations.png spec/resources/pixelstream.rgb spec/resources/pixelstream.rgba spec/resources/pixelstream_best_compression.png spec/resources/pixelstream_fast_rgba.png spec/resources/pixelstream_reference.png spec/resources/rect.png spec/resources/replaced.png spec/resources/text_chunk.png spec/resources/ztxt_chunk.png spec/spec_helper.rb tasks/benchmarks.rake tasks/github-gem.rake)
|
42
|
+
s.test_files = %w(spec/chunky_png/canvas/adam7_interlacing_spec.rb spec/chunky_png/canvas/drawing_spec.rb spec/chunky_png/canvas/operations_spec.rb spec/chunky_png/canvas/png_decoding_spec.rb spec/chunky_png/canvas/png_encoding_spec.rb spec/chunky_png/canvas_spec.rb spec/chunky_png/color_spec.rb spec/chunky_png/datastream_spec.rb spec/chunky_png/image_spec.rb spec/chunky_png/rmagick_spec.rb spec/chunky_png_spec.rb spec/png_suite_spec.rb)
|
43
43
|
end
|
data/lib/chunky_png.rb
CHANGED
@@ -3,6 +3,7 @@ require 'zlib'
|
|
3
3
|
require 'stringio'
|
4
4
|
require 'enumerator'
|
5
5
|
|
6
|
+
require 'chunky_png/compatibility'
|
6
7
|
require 'chunky_png/datastream'
|
7
8
|
require 'chunky_png/chunk'
|
8
9
|
require 'chunky_png/palette'
|
@@ -27,7 +28,7 @@ module ChunkyPNG
|
|
27
28
|
|
28
29
|
# The current version of ChunkyPNG. This value will be updated automatically
|
29
30
|
# by them gem:release rake task.
|
30
|
-
VERSION = "0.
|
31
|
+
VERSION = "0.11.0"
|
31
32
|
|
32
33
|
###################################################
|
33
34
|
# PNG international standard defined constants
|
@@ -81,14 +82,6 @@ module ChunkyPNG
|
|
81
82
|
class OutOfBounds < ChunkyPNG::ExpectationFailed
|
82
83
|
end
|
83
84
|
|
84
|
-
EMPTY_BYTEARRAY = (
|
85
|
-
EXTRA_BYTE = (
|
86
|
-
end
|
87
|
-
|
88
|
-
if RUBY_VERSION.to_f < 1.9
|
89
|
-
class String
|
90
|
-
alias_method :getbyte, :[]
|
91
|
-
alias_method :setbyte, :[]=
|
92
|
-
alias_method :bytesize, :size
|
93
|
-
end
|
85
|
+
EMPTY_BYTEARRAY = String.method_defined?(:force_encoding) ? "".force_encoding('ASCII-8BIT').freeze : "".freeze
|
86
|
+
EXTRA_BYTE = String.method_defined?(:force_encoding) ? "\0".force_encoding('ASCII-8BIT') : "\0"
|
94
87
|
end
|
data/lib/chunky_png/canvas.rb
CHANGED
@@ -215,15 +215,14 @@ module ChunkyPNG
|
|
215
215
|
ChunkyPNG::Image.from_canvas(self)
|
216
216
|
end
|
217
217
|
|
218
|
-
|
219
|
-
#
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
yield(self)
|
225
|
-
self
|
218
|
+
# Alternative implementation of the inspect method.
|
219
|
+
# @return [String] A nicely formatted string representation of this canvas.
|
220
|
+
def inspect
|
221
|
+
inspected = "<#{self.class.name} #{width}x#{height} ["
|
222
|
+
for y in 0...height
|
223
|
+
inspected << "\n\t[" << row(y).map { |p| ChunkyPNG::Color.to_hex(p) }.join(' ') << ']'
|
226
224
|
end
|
225
|
+
inspected << "\n]>"
|
227
226
|
end
|
228
227
|
|
229
228
|
protected
|
@@ -1,47 +1,65 @@
|
|
1
1
|
module ChunkyPNG
|
2
2
|
class Canvas
|
3
3
|
|
4
|
-
# Methods for decoding and encoding
|
4
|
+
# Methods for decoding and encoding Adam7 interlacing.
|
5
5
|
#
|
6
|
+
# Adam7 interlacing extractg 7 pass images out of a single image, that can be encoded to a
|
7
|
+
# stream separately so the image can be built up progressively. The module is included into
|
8
|
+
# ChunkyPNG canvas and is used to extract the pass images from the original image, or to
|
9
|
+
# reconstruct an original image from separate pass images.
|
6
10
|
module Adam7Interlacing
|
7
11
|
|
12
|
+
# Returns an array with the x-shift, x-offset, y-shift and y-offset for the requested pass.
|
13
|
+
# @param [Integer] pass The pass number, should be in 0..6.
|
8
14
|
def adam7_multiplier_offset(pass)
|
9
|
-
|
10
|
-
|
11
|
-
:x_offset => (pass & 1 == 0) ? 0 : 8 >> ((pass + 1) >> 1),
|
12
|
-
:y_shift => pass == 0 ? 3 : 3 - ((pass - 1) >> 1),
|
13
|
-
:y_offset => (pass == 0 || pass & 1 == 1) ? 0 : 8 >> (pass >> 1)
|
14
|
-
}
|
15
|
+
[3 - (pass >> 1), (pass & 1 == 0) ? 0 : 8 >> ((pass + 1) >> 1),
|
16
|
+
pass == 0 ? 3 : 3 - ((pass - 1) >> 1), (pass == 0 || pass & 1 == 1) ? 0 : 8 >> (pass >> 1)]
|
15
17
|
end
|
16
18
|
|
19
|
+
# Returns the pixel dimensions of the requested pass.
|
20
|
+
# @param [Integer] pass The pass number, should be in 0..6.
|
21
|
+
# @param [Integer] original_width The width of the original image.
|
22
|
+
# @param [Integer] original_height The height of the original image.
|
17
23
|
def adam7_pass_size(pass, original_width, original_height)
|
18
|
-
|
19
|
-
[ (original_width -
|
20
|
-
(original_height -
|
24
|
+
x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
|
25
|
+
[ (original_width - x_offset + (1 << x_shift) - 1) >> x_shift,
|
26
|
+
(original_height - y_offset + (1 << y_shift) - 1) >> y_shift]
|
21
27
|
end
|
22
|
-
|
28
|
+
|
29
|
+
# Returns an array of the dimension of all the pass images.
|
30
|
+
# @param [Integer] original_width The width of the original image.
|
31
|
+
# @param [Integer] original_height The height of the original image.
|
32
|
+
# @return [Array<Array<Integer>>] Returns an array with 7 pairs of dimensions.
|
33
|
+
# @see #adam7_pass_size
|
23
34
|
def adam7_pass_sizes(original_width, original_height)
|
24
35
|
(0...7).map { |pass| adam7_pass_size(pass, original_width, original_height) }
|
25
36
|
end
|
26
37
|
|
38
|
+
# Merges a pass image into a total image that is being constructed.
|
39
|
+
# @param [Integer] pass The pass number, should be in 0..6.
|
40
|
+
# @param [ChunkyPNG::Canvas] canvas The image that is being constructed.
|
41
|
+
# @param [ChunkyPNG::Canvas] subcanvas The pass image that should be merged
|
27
42
|
def adam7_merge_pass(pass, canvas, subcanvas)
|
28
|
-
|
43
|
+
x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
|
29
44
|
for y in 0...subcanvas.height do
|
30
45
|
for x in 0...subcanvas.width do
|
31
|
-
new_x = (x <<
|
32
|
-
new_y = (y <<
|
46
|
+
new_x = (x << x_shift) | x_offset
|
47
|
+
new_y = (y << y_shift) | y_offset
|
33
48
|
canvas[new_x, new_y] = subcanvas[x, y]
|
34
49
|
end
|
35
50
|
end
|
36
|
-
canvas
|
37
51
|
end
|
38
52
|
|
53
|
+
# Extracts a pass from a complete image
|
54
|
+
# @param [Integer] pass The pass number, should be in 0..6.
|
55
|
+
# @param [ChunkyPNG::Canvas] canvas The image that is being deconstructed.
|
56
|
+
# @return [ChunkyPNG::Canvas] The extracted pass image.
|
39
57
|
def adam7_extract_pass(pass, canvas)
|
40
|
-
|
58
|
+
x_shift, x_offset, y_shift, y_offset = adam7_multiplier_offset(pass)
|
41
59
|
sm_pixels = []
|
42
60
|
|
43
|
-
|
44
|
-
|
61
|
+
y_offset.step(canvas.height - 1, 1 << y_shift) do |y|
|
62
|
+
x_offset.step(canvas.width - 1, 1 << x_shift) do |x|
|
45
63
|
sm_pixels << canvas[x, y]
|
46
64
|
end
|
47
65
|
end
|
@@ -63,17 +63,16 @@ module ChunkyPNG
|
|
63
63
|
# @param [ChunkyPNG::Datastream] ds The datastream to decode.
|
64
64
|
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG datastream.
|
65
65
|
def from_datastream(ds)
|
66
|
-
raise ChunkyPNG::NotSupported, "Only 8-bit color depth is currently supported by ChunkyPNG!" unless ds.header_chunk.depth == 8
|
66
|
+
# raise ChunkyPNG::NotSupported, "Only 8-bit color depth is currently supported by ChunkyPNG!" unless ds.header_chunk.depth == 8
|
67
67
|
|
68
68
|
width = ds.header_chunk.width
|
69
69
|
height = ds.header_chunk.height
|
70
70
|
color_mode = ds.header_chunk.color
|
71
71
|
interlace = ds.header_chunk.interlace
|
72
|
+
depth = ds.header_chunk.depth
|
72
73
|
|
73
74
|
self.decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
|
74
|
-
|
75
|
-
|
76
|
-
decode_png_pixelstream(pixelstream, width, height, color_mode, interlace)
|
75
|
+
decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
|
77
76
|
end
|
78
77
|
|
79
78
|
# Decodes a canvas from a PNG encoded pixelstream, using a given width, height,
|
@@ -82,14 +81,14 @@ module ChunkyPNG
|
|
82
81
|
# @param [Integer] width The width of the image.
|
83
82
|
# @param [Integer] width The height of the image.
|
84
83
|
# @param [Integer] color_mode The color mode of the encoded pixelstream.
|
84
|
+
# @param [Integer] depth The bit depth of the pixel samples.
|
85
85
|
# @param [Integer] interlace The interlace method of the encoded pixelstream.
|
86
86
|
# @return [ChunkyPNG::Canvas] The decoded Canvas instance.
|
87
|
-
def decode_png_pixelstream(stream, width, height, color_mode
|
87
|
+
def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)
|
88
88
|
raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
|
89
|
-
|
90
|
-
|
91
|
-
when ChunkyPNG::
|
92
|
-
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode)
|
89
|
+
case interlace
|
90
|
+
when ChunkyPNG::INTERLACING_NONE; decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
91
|
+
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
93
92
|
else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
|
94
93
|
end
|
95
94
|
end
|
@@ -102,9 +101,10 @@ module ChunkyPNG
|
|
102
101
|
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
103
102
|
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
104
103
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
104
|
+
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
105
105
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
106
|
-
def decode_png_without_interlacing(stream, width, height, color_mode)
|
107
|
-
decode_png_image_pass(stream, width, height, color_mode, 0)
|
106
|
+
def decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
107
|
+
decode_png_image_pass(stream, width, height, color_mode, depth, 0)
|
108
108
|
end
|
109
109
|
|
110
110
|
# Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a
|
@@ -113,19 +113,249 @@ module ChunkyPNG
|
|
113
113
|
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
114
114
|
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
115
115
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
116
|
+
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
116
117
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
117
|
-
def decode_png_with_adam7_interlacing(stream, width, height, color_mode)
|
118
|
-
canvas
|
119
|
-
|
120
|
-
|
121
|
-
for pass in 0...7 do
|
118
|
+
def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
119
|
+
canvas = new(width, height)
|
120
|
+
start_pos = 0
|
121
|
+
for pass in 0...7
|
122
122
|
sm_width, sm_height = adam7_pass_size(pass, width, height)
|
123
|
-
sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, start_pos)
|
123
|
+
sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos)
|
124
124
|
adam7_merge_pass(pass, canvas, sm)
|
125
|
-
start_pos += (sm_width
|
125
|
+
start_pos += ChunkyPNG::Color.pass_bytesize(color_mode, depth, sm_width, sm_height)
|
126
126
|
end
|
127
127
|
canvas
|
128
128
|
end
|
129
|
+
|
130
|
+
# Extract 4 consecutive bits from a byte.
|
131
|
+
# @param [Integer] byte The byte (0..255) value to extract a 4 bit value from.
|
132
|
+
# @param [Integer] index The index within the byte. This should be either 0 or 2;
|
133
|
+
# the value will be modded by 2 to enforce this.
|
134
|
+
# @return [Integer] The extracted 4bit value (0..15)
|
135
|
+
def decode_png_extract_4bit_value(byte, index)
|
136
|
+
(index & 0x01 == 0) ? ((byte & 0xf0) >> 4) : (byte & 0x0f)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Extract 2 consecutive bits from a byte.
|
140
|
+
# @param [Integer] byte The byte (0..255) value to extract a 2 bit value from.
|
141
|
+
# @param [Integer] index The index within the byte. This should be either 0, 1, 2, or 3;
|
142
|
+
# the value will be modded by 4 to enforce this.
|
143
|
+
# @return [Integer] The extracted 2 bit value (0..3)
|
144
|
+
def decode_png_extract_2bit_value(byte, index)
|
145
|
+
bitshift = 6 - ((index & 0x03) << 1)
|
146
|
+
(byte & (0x03 << bitshift)) >> bitshift
|
147
|
+
end
|
148
|
+
|
149
|
+
# Extract a bit from a byte on a given index.
|
150
|
+
# @param [Integer] byte The byte (0..255) value to extract a a bit from.
|
151
|
+
# @param [Integer] index The index within the byte. This should be 0..7;
|
152
|
+
# the value will be modded by 8 to enforce this.
|
153
|
+
# @return [Integer] Either 1 or 0.
|
154
|
+
def decode_png_extract_1bit_value(byte, index)
|
155
|
+
bitshift = 7 - (index & 0x07)
|
156
|
+
(byte & (0x01 << bitshift)) >> bitshift
|
157
|
+
end
|
158
|
+
|
159
|
+
# Resamples a 16 bit value to an 8 bit value. This will discard some color information.
|
160
|
+
# @param [Integer] value The 16 bit value to resample.
|
161
|
+
# @return [Integer] The 8 bit resampled value
|
162
|
+
def decode_png_resample_16bit_value(value)
|
163
|
+
value >> 8
|
164
|
+
end
|
165
|
+
|
166
|
+
# Resamples a 4 bit value to an 8 bit value.
|
167
|
+
# @param [Integer] value The 4 bit value to resample.
|
168
|
+
# @return [Integer] The 8 bit resampled value.
|
169
|
+
def decode_png_resample_4bit_value(value)
|
170
|
+
case value
|
171
|
+
when 0x00; 0
|
172
|
+
when 0x01; 17
|
173
|
+
when 0x02; 34
|
174
|
+
when 0x03; 51
|
175
|
+
when 0x04; 68
|
176
|
+
when 0x05; 85
|
177
|
+
when 0x06; 102
|
178
|
+
when 0x07; 119
|
179
|
+
when 0x08; 137
|
180
|
+
when 0x09; 154
|
181
|
+
when 0x0a; 171
|
182
|
+
when 0x0b; 188
|
183
|
+
when 0x0c; 205
|
184
|
+
when 0x0d; 222
|
185
|
+
when 0x0e; 239
|
186
|
+
when 0x0f; 255
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Resamples a 2 bit value to an 8 bit value.
|
191
|
+
# @param [Integer] value The 2 bit value to resample.
|
192
|
+
# @return [Integer] The 8 bit resampled value.
|
193
|
+
def decode_png_resample_2bit_value(value)
|
194
|
+
case value
|
195
|
+
when 0x00; 0x00
|
196
|
+
when 0x01; 0x55
|
197
|
+
when 0x02; 0xaa
|
198
|
+
when 0x03; 0xff
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# Decodes a scanline of a 1-bit, indexed image into a row of pixels.
|
203
|
+
# @param [String] stream The stream to decode from.
|
204
|
+
# @param [Integer] pos The position in the stream on qhich the scanline starts (including the filter byte).
|
205
|
+
# @param [Integer] width The width in pixels of the scanline.
|
206
|
+
# @return [Array<Integer>] An array of decoded pixels.
|
207
|
+
def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width)
|
208
|
+
(0...width).map do |index|
|
209
|
+
palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
210
|
+
decoding_palette[palette_pos]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# Decodes a scanline of a 2-bit, indexed image into a row of pixels.
|
215
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
216
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
217
|
+
def decode_png_pixels_from_scanline_indexed_2bit(stream, pos, width)
|
218
|
+
(0...width).map do |index|
|
219
|
+
palette_pos = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
220
|
+
decoding_palette[palette_pos]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Decodes a scanline of a 4-bit, indexed image into a row of pixels.
|
225
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
226
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
227
|
+
def decode_png_pixels_from_scanline_indexed_4bit(stream, pos, width)
|
228
|
+
(0...width).map do |index|
|
229
|
+
palette_pos = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
230
|
+
decoding_palette[palette_pos]
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
# Decodes a scanline of a 8-bit, indexed image into a row of pixels.
|
235
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
236
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
237
|
+
def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width)
|
238
|
+
(1..width).map { |i| decoding_palette[stream.getbyte(pos + i)] }
|
239
|
+
end
|
240
|
+
|
241
|
+
# Decodes a scanline of an 8-bit, true color image with transparency into a row of pixels.
|
242
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
243
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
244
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width)
|
245
|
+
stream.unpack("@#{pos + 1}N#{width}")
|
246
|
+
end
|
247
|
+
|
248
|
+
# Decodes a scanline of a 16-bit, true color image with transparency into a row of pixels.
|
249
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
250
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
251
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width)
|
252
|
+
[].tap do |pixels|
|
253
|
+
stream.unpack("@#{pos + 1}n#{width * 4}").each_slice(4) do |r, g, b, a|
|
254
|
+
pixels << ChunkyPNG::Color.rgba(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g),
|
255
|
+
decode_png_resample_16bit_value(b), decode_png_resample_16bit_value(a))
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Decodes a scanline of an 8-bit, true color image into a row of pixels.
|
261
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
262
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
263
|
+
def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width)
|
264
|
+
stream.unpack("@#{pos + 1}" << ('NX' * width)).map { |c| c | 0x000000ff }
|
265
|
+
end
|
266
|
+
|
267
|
+
# Decodes a scanline of a 16-bit, true color image into a row of pixels.
|
268
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
269
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
270
|
+
def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width)
|
271
|
+
[].tap do |pixels|
|
272
|
+
stream.unpack("@#{pos + 1}n#{width * 3}").each_slice(3) do |r, g, b|
|
273
|
+
pixels << ChunkyPNG::Color.rgb(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(b))
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
# Decodes a scanline of an 8-bit, grayscale image with transparency into a row of pixels.
|
279
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
280
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
281
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width)
|
282
|
+
(0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
|
283
|
+
end
|
284
|
+
|
285
|
+
# Decodes a scanline of a 16-bit, grayscale image with transparency into a row of pixels.
|
286
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
287
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
288
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width)
|
289
|
+
[].tap do |pixels|
|
290
|
+
stream.unpack("@#{pos + 1}n#{width * 2}").each_slice(2) do |g, a|
|
291
|
+
pixels << ChunkyPNG::Color.grayscale_alpha(decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(a))
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# Decodes a scanline of a 1-bit, grayscale image into a row of pixels.
|
297
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
298
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
299
|
+
def decode_png_pixels_from_scanline_grayscale_1bit(stream, pos, width)
|
300
|
+
(0...width).map do |index|
|
301
|
+
value = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
302
|
+
value == 1 ? ChunkyPNG::Color::WHITE : ChunkyPNG::Color::BLACK
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
# Decodes a scanline of a 2-bit, grayscale image into a row of pixels.
|
307
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
308
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
309
|
+
def decode_png_pixels_from_scanline_grayscale_2bit(stream, pos, width)
|
310
|
+
(0...width).map do |index|
|
311
|
+
value = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
312
|
+
ChunkyPNG::Color.grayscale(decode_png_resample_2bit_value(value))
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
# Decodes a scanline of a 4-bit, grayscale image into a row of pixels.
|
317
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
318
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
319
|
+
def decode_png_pixels_from_scanline_grayscale_4bit(stream, pos, width)
|
320
|
+
(0...width).map do |index|
|
321
|
+
value = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
322
|
+
ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# Decodes a scanline of an 8-bit, grayscale image into a row of pixels.
|
327
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
328
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
329
|
+
def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width)
|
330
|
+
(1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
|
331
|
+
end
|
332
|
+
|
333
|
+
# Decodes a scanline of a 16-bit, grayscale image into a row of pixels.
|
334
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
335
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
336
|
+
def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width)
|
337
|
+
values = stream.unpack("@#{pos + 1}n#{width}")
|
338
|
+
values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
|
339
|
+
end
|
340
|
+
|
341
|
+
# Returns the method name to use to decode scanlines into pixels.
|
342
|
+
# @param [Integer] color_mode The color mode of the image.
|
343
|
+
# @param [Integer] depth The bit depth of the image.
|
344
|
+
# @return [Symbol] The method name to use for decoding, to be called on the canvas class.
|
345
|
+
# @raise [ChunkyPNG::NotSupported] when the color_mode and/or bit depth is not supported.
|
346
|
+
def decode_png_pixels_from_scanline_method(color_mode, depth)
|
347
|
+
decoder_method = case color_mode
|
348
|
+
when ChunkyPNG::COLOR_TRUECOLOR; :"decode_png_pixels_from_scanline_truecolor_#{depth}bit"
|
349
|
+
when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; :"decode_png_pixels_from_scanline_truecolor_alpha_#{depth}bit"
|
350
|
+
when ChunkyPNG::COLOR_INDEXED; :"decode_png_pixels_from_scanline_indexed_#{depth}bit"
|
351
|
+
when ChunkyPNG::COLOR_GRAYSCALE; :"decode_png_pixels_from_scanline_grayscale_#{depth}bit"
|
352
|
+
when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; :"decode_png_pixels_from_scanline_grayscale_alpha_#{depth}bit"
|
353
|
+
else nil
|
354
|
+
end
|
355
|
+
|
356
|
+
raise ChunkyPNG::NotSupported, "No decoder found for color mode #{color_mode} and #{depth}-bit depth!" unless respond_to?(decoder_method)
|
357
|
+
decoder_method
|
358
|
+
end
|
129
359
|
|
130
360
|
# Decodes a single PNG image pass width a given width, height and color
|
131
361
|
# mode, to a Canvas, starting at the given position in the stream.
|
@@ -139,36 +369,28 @@ module ChunkyPNG
|
|
139
369
|
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
140
370
|
# @param [Integer] start_pos The position in the pixel stream to start reading.
|
141
371
|
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
142
|
-
def decode_png_image_pass(stream, width, height, color_mode, start_pos)
|
143
|
-
stream << ChunkyPNG::EXTRA_BYTE if color_mode == ChunkyPNG::COLOR_TRUECOLOR
|
144
|
-
pixel_size = Color.bytesize(color_mode)
|
145
|
-
pixel_decoder = case color_mode
|
146
|
-
when ChunkyPNG::COLOR_TRUECOLOR; lambda { |s, pos| s.unpack("@#{pos + 1}" << ('NX' * width)).map { |c| c | 0x000000ff } }
|
147
|
-
when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; lambda { |s, pos| s.unpack("@#{pos + 1}N#{width}") }
|
148
|
-
when ChunkyPNG::COLOR_INDEXED; lambda { |s, pos| (1..width).map { |i| decoding_palette[s.getbyte(pos + i)] } }
|
149
|
-
when ChunkyPNG::COLOR_GRAYSCALE; lambda { |s, pos| (1..width).map { |i| ChunkyPNG::Color.grayscale(s.getbyte(pos + i)) } }
|
150
|
-
when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; lambda { |s, pos| (0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(s.getbyte(pos + (i * 2) + 1), s.getbyte(pos + (i * 2) + 2)) } }
|
151
|
-
else raise ChunkyPNG::NotSupported, "No suitable pixel decoder found for color mode #{color_mode}!"
|
152
|
-
end
|
372
|
+
def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos)
|
153
373
|
|
154
374
|
pixels = []
|
155
|
-
if width > 0
|
375
|
+
if width > 0 && height > 0
|
156
376
|
|
157
|
-
|
377
|
+
stream << ChunkyPNG::EXTRA_BYTE if color_mode == ChunkyPNG::COLOR_TRUECOLOR
|
378
|
+
pixel_decoder = decode_png_pixels_from_scanline_method(color_mode, depth)
|
379
|
+
line_length = ChunkyPNG::Color.scanline_bytesize(color_mode, depth, width)
|
380
|
+
pixel_size = ChunkyPNG::Color.pixel_bytesize(color_mode, depth)
|
158
381
|
|
159
|
-
|
160
|
-
line_length = width * pixel_size
|
161
|
-
pos, prev_pos = start_pos, nil
|
382
|
+
raise ChunkyPNG::ExpectationFailed, "Invalid stream length!" unless stream.bytesize - start_pos >= ChunkyPNG::Color.pass_bytesize(color_mode, depth, width, height)
|
162
383
|
|
384
|
+
pos, prev_pos = start_pos, nil
|
163
385
|
for line_no in 0...height do
|
164
386
|
decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
165
|
-
pixels += pixel_decoder
|
387
|
+
pixels += send(pixel_decoder, stream, pos, width)
|
166
388
|
|
167
389
|
prev_pos = pos
|
168
390
|
pos += line_length + 1
|
169
391
|
end
|
170
392
|
end
|
171
|
-
|
393
|
+
|
172
394
|
new(width, height, pixels)
|
173
395
|
end
|
174
396
|
|