bench9000 0.1
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +7 -0
- data/benchmarks/chunky_png/chunky-canvas-resampling-bilinear.rb +69 -0
- data/benchmarks/chunky_png/chunky-canvas-resampling-nearest-neighbor.rb +68 -0
- data/benchmarks/chunky_png/chunky-canvas-resampling-steps-residues.rb +37 -0
- data/benchmarks/chunky_png/chunky-canvas-resampling-steps.rb +37 -0
- data/benchmarks/chunky_png/chunky-color-a.rb +39 -0
- data/benchmarks/chunky_png/chunky-color-b.rb +39 -0
- data/benchmarks/chunky_png/chunky-color-compose-quick.rb +39 -0
- data/benchmarks/chunky_png/chunky-color-g.rb +39 -0
- data/benchmarks/chunky_png/chunky-color-r.rb +39 -0
- data/benchmarks/chunky_png/chunky-decode-png-image-pass.rb +74 -0
- data/benchmarks/chunky_png/chunky-encode-png-image-pass-to-stream.rb +84 -0
- data/benchmarks/chunky_png/chunky-operations-compose.rb +70 -0
- data/benchmarks/chunky_png/chunky-operations-replace.rb +69 -0
- data/benchmarks/chunky_png/chunky_png.patch +22 -0
- data/benchmarks/chunky_png/version.txt +2 -0
- data/benchmarks/classic/binary-trees.rb +100 -0
- data/benchmarks/classic/deltablue.rb +732 -0
- data/benchmarks/classic/fannkuch-redux.rb +111 -0
- data/benchmarks/classic/fasta-string.rb +71 -0
- data/benchmarks/classic/mandelbrot.rb +112 -0
- data/benchmarks/classic/matrix-multiply.rb +78 -0
- data/benchmarks/classic/n-body.rb +188 -0
- data/benchmarks/classic/pidigits.rb +88 -0
- data/benchmarks/classic/red-black.rb +363 -0
- data/benchmarks/classic/richards-kwargs.rb +403 -0
- data/benchmarks/classic/richards.rb +403 -0
- data/benchmarks/classic/spectral-norm.rb +95 -0
- data/benchmarks/default.config.rb +206 -0
- data/benchmarks/graph/connected.rb +62 -0
- data/benchmarks/literature/acid.rb +46 -0
- data/benchmarks/micro/pack-big-U-loop.rb +24 -0
- data/benchmarks/micro/pack-big-xLX-repeat.rb +22 -0
- data/benchmarks/micro/pack-small-mixture.rb +17 -0
- data/benchmarks/micro/string-equal.rb +28 -0
- data/benchmarks/octane/deltablue.rb +981 -0
- data/benchmarks/psd.rb/mock-logger.rb +23 -0
- data/benchmarks/psd.rb/psd-color-cmyk-to-rgb.rb +46 -0
- data/benchmarks/psd.rb/psd-compose-color-burn.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-color-dodge.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-darken.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-difference.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-exclusion.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-hard-light.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-hard-mix.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-lighten.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-linear-burn.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-linear-dodge.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-linear-light.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-multiply.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-normal.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-overlay.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-pin-light.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-screen.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-soft-light.rb +43 -0
- data/benchmarks/psd.rb/psd-compose-vivid-light.rb +43 -0
- data/benchmarks/psd.rb/psd-imageformat-layerraw-parse-raw.rb +70 -0
- data/benchmarks/psd.rb/psd-imageformat-rle-decode-rle-channel.rb +87 -0
- data/benchmarks/psd.rb/psd-imagemode-cmyk-combine-cmyk-channel.rb +65 -0
- data/benchmarks/psd.rb/psd-imagemode-greyscale-combine-greyscale-channel.rb +68 -0
- data/benchmarks/psd.rb/psd-imagemode-rgb-combine-rgb-channel.rb +65 -0
- data/benchmarks/psd.rb/psd-renderer-blender-compose.rb +113 -0
- data/benchmarks/psd.rb/psd-renderer-clippingmask-apply.rb +129 -0
- data/benchmarks/psd.rb/psd-renderer-mask-apply.rb +137 -0
- data/benchmarks/psd.rb/psd-util-clamp.rb +42 -0
- data/benchmarks/psd.rb/psd-util-pad2.rb +42 -0
- data/benchmarks/psd.rb/psd-util-pad4.rb +42 -0
- data/benchmarks/psd.rb/psd_native.patch +99 -0
- data/benchmarks/psd.rb/version.txt +2 -0
- data/benchmarks/topaz/neural-net.rb +208 -0
- data/benchmarks/vm/codeload.rb +35 -0
- data/benchmarks/vm/fixtures/codeload/LICENSE.txt +25 -0
- data/benchmarks/vm/fixtures/codeload/lexer.rb +21493 -0
- data/bin/bench9000 +13 -0
- data/example/report.data +945 -0
- data/example/report.html +59178 -0
- data/lib/bench9000.rb +27 -0
- data/lib/bench9000/benchmark.rb +29 -0
- data/lib/bench9000/commands/command.rb +30 -0
- data/lib/bench9000/commands/compare-reference.rb +70 -0
- data/lib/bench9000/commands/compare.rb +43 -0
- data/lib/bench9000/commands/detail.rb +51 -0
- data/lib/bench9000/commands/list-benchmarks.rb +29 -0
- data/lib/bench9000/commands/list-implementations.rb +29 -0
- data/lib/bench9000/commands/reference.rb +46 -0
- data/lib/bench9000/commands/remove.rb +41 -0
- data/lib/bench9000/commands/report.rb +71 -0
- data/lib/bench9000/commands/score.rb +27 -0
- data/lib/bench9000/config.rb +88 -0
- data/lib/bench9000/group.rb +23 -0
- data/lib/bench9000/harness.rb +68 -0
- data/lib/bench9000/implementation.rb +134 -0
- data/lib/bench9000/json-formatter.rb +50 -0
- data/lib/bench9000/main.rb +268 -0
- data/lib/bench9000/measurement.rb +75 -0
- data/lib/bench9000/micro-harness.rb +39 -0
- data/lib/bench9000/options.rb +31 -0
- data/lib/bench9000/report/bootstrap-theme.css +5 -0
- data/lib/bench9000/report/bootstrap.css +5 -0
- data/lib/bench9000/report/bootstrap.js +6 -0
- data/lib/bench9000/report/chart.js +3432 -0
- data/lib/bench9000/report/chartjs.patch +91 -0
- data/lib/bench9000/report/jquery.js +4 -0
- data/lib/bench9000/report/report.html +177 -0
- data/lib/bench9000/report/report.js +547 -0
- data/lib/bench9000/stats.rb +41 -0
- data/readme.md +205 -0
- data/vendor/chunky_png/BENCHMARKS.rdoc +31 -0
- data/vendor/chunky_png/Gemfile +10 -0
- data/vendor/chunky_png/LICENSE +20 -0
- data/vendor/chunky_png/README.rdoc +84 -0
- data/vendor/chunky_png/Rakefile +11 -0
- data/vendor/chunky_png/benchmarks/decoding_benchmark.rb +36 -0
- data/vendor/chunky_png/benchmarks/encoding_benchmark.rb +40 -0
- data/vendor/chunky_png/benchmarks/filesize_benchmark.rb +28 -0
- data/vendor/chunky_png/chunky_png.gemspec +47 -0
- data/vendor/chunky_png/lib/chunky_png.rb +160 -0
- data/vendor/chunky_png/lib/chunky_png/canvas.rb +372 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/adam7_interlacing.rb +72 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/data_url_exporting.rb +15 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/data_url_importing.rb +21 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/drawing.rb +338 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/masking.rb +91 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/operations.rb +395 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/png_decoding.rb +492 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/png_encoding.rb +442 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/resampling.rb +147 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/stream_exporting.rb +58 -0
- data/vendor/chunky_png/lib/chunky_png/canvas/stream_importing.rb +77 -0
- data/vendor/chunky_png/lib/chunky_png/chunk.rb +328 -0
- data/vendor/chunky_png/lib/chunky_png/color.rb +780 -0
- data/vendor/chunky_png/lib/chunky_png/compatibility.rb +15 -0
- data/vendor/chunky_png/lib/chunky_png/datastream.rb +185 -0
- data/vendor/chunky_png/lib/chunky_png/dimension.rb +113 -0
- data/vendor/chunky_png/lib/chunky_png/image.rb +79 -0
- data/vendor/chunky_png/lib/chunky_png/palette.rb +209 -0
- data/vendor/chunky_png/lib/chunky_png/point.rb +115 -0
- data/vendor/chunky_png/lib/chunky_png/rmagick.rb +43 -0
- data/vendor/chunky_png/lib/chunky_png/vector.rb +186 -0
- data/vendor/chunky_png/lib/chunky_png/version.rb +5 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/adam7_interlacing_spec.rb +106 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/data_url_exporting_spec.rb +13 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/data_url_importing_spec.rb +15 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/drawing_spec.rb +170 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/masking_spec.rb +51 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/operations_spec.rb +388 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/png_decoding_spec.rb +97 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/png_encoding_spec.rb +235 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/resampling_spec.rb +121 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/stream_exporting_spec.rb +59 -0
- data/vendor/chunky_png/spec/chunky_png/canvas/stream_importing_spec.rb +31 -0
- data/vendor/chunky_png/spec/chunky_png/canvas_spec.rb +226 -0
- data/vendor/chunky_png/spec/chunky_png/color_spec.rb +251 -0
- data/vendor/chunky_png/spec/chunky_png/datastream_spec.rb +32 -0
- data/vendor/chunky_png/spec/chunky_png/dimension_spec.rb +48 -0
- data/vendor/chunky_png/spec/chunky_png/image_spec.rb +25 -0
- data/vendor/chunky_png/spec/chunky_png/point_spec.rb +76 -0
- data/vendor/chunky_png/spec/chunky_png/rmagick_spec.rb +23 -0
- data/vendor/chunky_png/spec/chunky_png/vector_spec.rb +104 -0
- data/vendor/chunky_png/spec/chunky_png_spec.rb +8 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgai4a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgai4a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgan6a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgan6a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgbn4a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bggn4a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgwn6a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/background_chunks/bgyn6a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g01.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g02.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g04.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi0g16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi2c16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p01.rgba +1 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p02.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p04.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi3p08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi4a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi4a08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi4a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi4a16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi6a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi6a08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi6a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basi6a16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g01.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g02.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g04.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn0g16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn2c16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p01.rgba +1 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p02.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p04.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn3p08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn4a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn4a08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn4a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn4a16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn6a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn6a08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn6a16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/basic/basn6a16.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/broken/x00n0g01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/broken/xcrn0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/broken/xlfn0g04.png +13 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi1n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi1n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi2n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi2n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi4n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi4n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi9n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/chunk_ordering/oi9n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/compression_levels/z00n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/compression_levels/z03n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/compression_levels/z06n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/compression_levels/z09n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n0g08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n0g08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n2c08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f00n2c08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n0g08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n0g08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n2c08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f01n2c08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n0g08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n0g08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n2c08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f02n2c08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n0g08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n0g08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n2c08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f03n2c08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n0g08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n0g08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n0g08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n2c08.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n2c08_reference.png +0 -0
- data/vendor/chunky_png/spec/png_suite/filtering/f04n2c08_reference.rgba +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g03n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g03n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g03n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g04n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g04n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g04n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g05n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g05n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g05n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g07n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g07n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g07n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g10n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g10n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g10n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g25n0g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g25n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/gamma/g25n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/metadata/cm0n0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/metadata/cm7n0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/metadata/cm9n0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ccwn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ccwn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cdfn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cdhn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cdsn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cdun2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ch1n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ch2n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs3n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs3n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs5n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs5n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs8n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/cs8n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ct0n0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ct1n0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ctzn0g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/pp0n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/pp0n6a08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ps1n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ps1n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ps2n0g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/other/ps2n2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s01i3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s01n3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s02i3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s02n3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s03i3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s03n3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s04i3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s04n3p01.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s05i3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s05n3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s06i3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s06n3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s07i3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s07n3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s08i3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s08n3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s09i3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s09n3p02.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s32i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s32n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s33i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s33n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s34i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s34n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s35i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s35n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s36i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s36n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s37i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s37n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s38i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s38n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s39i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s39n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s40i3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/sizes/s40n3p04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbbn1g04.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbbn2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbbn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbgn2c16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbgn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbrn2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbwn1g16.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbwn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tbyn3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tp0n1g08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tp0n2c08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tp0n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite/transparency/tp1n3p08.png +0 -0
- data/vendor/chunky_png/spec/png_suite_spec.rb +121 -0
- data/vendor/chunky_png/spec/resources/adam7.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_five_point.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_four_point.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_four_point_flipped.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_four_point_s.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_six_point.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_three_point.png +0 -0
- data/vendor/chunky_png/spec/resources/bezier_three_point_flipped.png +0 -0
- data/vendor/chunky_png/spec/resources/circles.png +0 -0
- data/vendor/chunky_png/spec/resources/clock.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_base.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_bl_xdown_ydown.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_bl_xdown_yup.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_bl_xup_yup.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_mask.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_mask_updated.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_nn_xdown_ydown.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_nn_xdown_yup.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_nn_xup_yup.png +0 -0
- data/vendor/chunky_png/spec/resources/clock_updated.png +0 -0
- data/vendor/chunky_png/spec/resources/composited.png +0 -0
- data/vendor/chunky_png/spec/resources/cropped.png +0 -0
- data/vendor/chunky_png/spec/resources/damaged_chunk.png +0 -0
- data/vendor/chunky_png/spec/resources/damaged_signature.png +13 -0
- data/vendor/chunky_png/spec/resources/lines.png +0 -0
- data/vendor/chunky_png/spec/resources/operations.png +0 -0
- data/vendor/chunky_png/spec/resources/operations_border.png +0 -0
- data/vendor/chunky_png/spec/resources/operations_grayscale.png +0 -0
- data/vendor/chunky_png/spec/resources/partial_circles.png +0 -0
- data/vendor/chunky_png/spec/resources/pixelstream.bgr +67 -0
- data/vendor/chunky_png/spec/resources/pixelstream.rgb +67 -1
- data/vendor/chunky_png/spec/resources/pixelstream.rgba +67 -0
- data/vendor/chunky_png/spec/resources/pixelstream_best_compression.png +0 -0
- data/vendor/chunky_png/spec/resources/pixelstream_fast_rgba.png +0 -0
- data/vendor/chunky_png/spec/resources/pixelstream_reference.png +0 -0
- data/vendor/chunky_png/spec/resources/polygon_filled_horizontal.png +0 -0
- data/vendor/chunky_png/spec/resources/polygon_filled_vertical.png +0 -0
- data/vendor/chunky_png/spec/resources/polygon_triangle_filled.png +0 -0
- data/vendor/chunky_png/spec/resources/polygon_unfilled.png +0 -0
- data/vendor/chunky_png/spec/resources/rect.png +0 -0
- data/vendor/chunky_png/spec/resources/replaced.png +0 -0
- data/vendor/chunky_png/spec/resources/text_chunk.png +0 -0
- data/vendor/chunky_png/spec/resources/ztxt_chunk.png +0 -0
- data/vendor/chunky_png/spec/spec_helper.rb +52 -0
- data/vendor/chunky_png/tasks/benchmarks.rake +26 -0
- data/vendor/oily_png/Gemfile +4 -0
- data/vendor/oily_png/LICENSE +20 -0
- data/vendor/oily_png/README.rdoc +26 -0
- data/vendor/oily_png/Rakefile +19 -0
- data/vendor/oily_png/ext/oily_png/color.c +58 -0
- data/vendor/oily_png/ext/oily_png/color.h +29 -0
- data/vendor/oily_png/ext/oily_png/extconf.rb +3 -0
- data/vendor/oily_png/ext/oily_png/oily_png_ext.c +59 -0
- data/vendor/oily_png/ext/oily_png/oily_png_ext.h +72 -0
- data/vendor/oily_png/ext/oily_png/operations.c +122 -0
- data/vendor/oily_png/ext/oily_png/operations.h +36 -0
- data/vendor/oily_png/ext/oily_png/png_decoding.c +374 -0
- data/vendor/oily_png/ext/oily_png/png_decoding.h +27 -0
- data/vendor/oily_png/ext/oily_png/png_encoding.c +302 -0
- data/vendor/oily_png/ext/oily_png/png_encoding.h +19 -0
- data/vendor/oily_png/ext/oily_png/resampling.c +213 -0
- data/vendor/oily_png/ext/oily_png/resampling.h +25 -0
- data/vendor/oily_png/lib/oily_png.rb +21 -0
- data/vendor/oily_png/lib/oily_png/canvas.rb +15 -0
- data/vendor/oily_png/lib/oily_png/version.rb +3 -0
- data/vendor/oily_png/oily_png.gemspec +39 -0
- data/vendor/oily_png/spec/color_spec.rb +38 -0
- data/vendor/oily_png/spec/decoding_spec.rb +51 -0
- data/vendor/oily_png/spec/encoding_spec.rb +135 -0
- data/vendor/oily_png/spec/operations_spec.rb +52 -0
- data/vendor/oily_png/spec/resampling_spec.rb +51 -0
- data/vendor/oily_png/spec/resources/basi0g01.png +0 -0
- data/vendor/oily_png/spec/resources/basi0g02.png +0 -0
- data/vendor/oily_png/spec/resources/basi0g04.png +0 -0
- data/vendor/oily_png/spec/resources/basi0g08.png +0 -0
- data/vendor/oily_png/spec/resources/basi0g16.png +0 -0
- data/vendor/oily_png/spec/resources/basi2c08.png +0 -0
- data/vendor/oily_png/spec/resources/basi2c16.png +0 -0
- data/vendor/oily_png/spec/resources/basi3p01.png +0 -0
- data/vendor/oily_png/spec/resources/basi3p02.png +0 -0
- data/vendor/oily_png/spec/resources/basi3p04.png +0 -0
- data/vendor/oily_png/spec/resources/basi3p08.png +0 -0
- data/vendor/oily_png/spec/resources/basi4a08.png +0 -0
- data/vendor/oily_png/spec/resources/basi4a16.png +0 -0
- data/vendor/oily_png/spec/resources/basi6a08.png +0 -0
- data/vendor/oily_png/spec/resources/basi6a16.png +0 -0
- data/vendor/oily_png/spec/resources/basn0g01.png +0 -0
- data/vendor/oily_png/spec/resources/basn0g02.png +0 -0
- data/vendor/oily_png/spec/resources/basn0g04.png +0 -0
- data/vendor/oily_png/spec/resources/basn0g08.png +0 -0
- data/vendor/oily_png/spec/resources/basn0g16.png +0 -0
- data/vendor/oily_png/spec/resources/basn2c08.png +0 -0
- data/vendor/oily_png/spec/resources/basn2c16.png +0 -0
- data/vendor/oily_png/spec/resources/basn3p01.png +0 -0
- data/vendor/oily_png/spec/resources/basn3p02.png +0 -0
- data/vendor/oily_png/spec/resources/basn3p04.png +0 -0
- data/vendor/oily_png/spec/resources/basn3p08.png +0 -0
- data/vendor/oily_png/spec/resources/basn4a08.png +0 -0
- data/vendor/oily_png/spec/resources/basn4a16.png +0 -0
- data/vendor/oily_png/spec/resources/basn6a08.png +0 -0
- data/vendor/oily_png/spec/resources/basn6a16.png +0 -0
- data/vendor/oily_png/spec/resources/composited.png +0 -0
- data/vendor/oily_png/spec/resources/gray.png +0 -0
- data/vendor/oily_png/spec/resources/interlaced.png +0 -0
- data/vendor/oily_png/spec/resources/nonsquare.png +0 -0
- data/vendor/oily_png/spec/resources/operations.png +0 -0
- data/vendor/oily_png/spec/resources/replaced.png +0 -0
- data/vendor/oily_png/spec/resources/s01i3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s01n3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s02i3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s02n3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s03i3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s03n3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s04i3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s04n3p01.png +0 -0
- data/vendor/oily_png/spec/resources/s05i3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s05n3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s06i3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s06n3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s07i3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s07n3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s08i3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s08n3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s09i3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s09n3p02.png +0 -0
- data/vendor/oily_png/spec/resources/s32i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s32n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s33i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s33n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s34i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s34n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s35i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s35n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s36i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s36n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s37i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s37n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s38i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s38n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s39i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s39n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s40i3p04.png +0 -0
- data/vendor/oily_png/spec/resources/s40n3p04.png +0 -0
- data/vendor/oily_png/spec/resources/square.png +0 -0
- data/vendor/oily_png/spec/resources/tbbn1g04.png +0 -0
- data/vendor/oily_png/spec/resources/tbbn2c16.png +0 -0
- data/vendor/oily_png/spec/resources/tbbn3p08.png +0 -0
- data/vendor/oily_png/spec/resources/tbgn2c16.png +0 -0
- data/vendor/oily_png/spec/resources/tbgn3p08.png +0 -0
- data/vendor/oily_png/spec/resources/tbrn2c08.png +0 -0
- data/vendor/oily_png/spec/resources/tbwn1g16.png +0 -0
- data/vendor/oily_png/spec/resources/tbwn3p08.png +0 -0
- data/vendor/oily_png/spec/resources/tbyn3p08.png +0 -0
- data/vendor/oily_png/spec/resources/tp0n1g08.png +0 -0
- data/vendor/oily_png/spec/resources/tp0n2c08.png +0 -0
- data/vendor/oily_png/spec/resources/tp0n3p08.png +0 -0
- data/vendor/oily_png/spec/resources/tp1n3p08.png +0 -0
- data/vendor/oily_png/spec/spec_helper.rb +40 -0
- data/vendor/oily_png/tasks/testing.rake +49 -0
- data/vendor/psd.rb/CONTRIBUTING.md +7 -0
- data/vendor/psd.rb/Gemfile +2 -0
- data/vendor/psd.rb/Guardfile +8 -0
- data/vendor/psd.rb/LICENSE.txt +22 -0
- data/vendor/psd.rb/README.md +235 -0
- data/vendor/psd.rb/Rakefile +6 -0
- data/vendor/psd.rb/circle.yml +6 -0
- data/vendor/psd.rb/examples/build_image.rb +16 -0
- data/vendor/psd.rb/examples/export_image.rb +12 -0
- data/vendor/psd.rb/examples/export_layer_images.rb +19 -0
- data/vendor/psd.rb/examples/export_node.rb +7 -0
- data/vendor/psd.rb/examples/export_text_data.rb +13 -0
- data/vendor/psd.rb/examples/guides.rb +17 -0
- data/vendor/psd.rb/examples/images/comp-example.psd +0 -0
- data/vendor/psd.rb/examples/images/example-cmyk.psd +0 -0
- data/vendor/psd.rb/examples/images/example-greyscale.psd +0 -0
- data/vendor/psd.rb/examples/images/example-nocompat.psd +0 -0
- data/vendor/psd.rb/examples/images/example.psd +0 -0
- data/vendor/psd.rb/examples/images/example16.psd +0 -0
- data/vendor/psd.rb/examples/images/guides.psd +0 -0
- data/vendor/psd.rb/examples/layer_comps.rb +20 -0
- data/vendor/psd.rb/examples/parse.rb +36 -0
- data/vendor/psd.rb/examples/path.rb +7 -0
- data/vendor/psd.rb/examples/profile.rb +15 -0
- data/vendor/psd.rb/examples/slices.rb +17 -0
- data/vendor/psd.rb/examples/tree.rb +8 -0
- data/vendor/psd.rb/examples/unimplemented_info.rb +9 -0
- data/vendor/psd.rb/lib/psd.rb +173 -0
- data/vendor/psd.rb/lib/psd/blend_mode.rb +80 -0
- data/vendor/psd.rb/lib/psd/channel_image.rb +115 -0
- data/vendor/psd.rb/lib/psd/color.rb +125 -0
- data/vendor/psd.rb/lib/psd/descriptor.rb +200 -0
- data/vendor/psd.rb/lib/psd/file.rb +104 -0
- data/vendor/psd.rb/lib/psd/header.rb +69 -0
- data/vendor/psd.rb/lib/psd/helpers.rb +51 -0
- data/vendor/psd.rb/lib/psd/image.rb +123 -0
- data/vendor/psd.rb/lib/psd/image_exports/png.rb +31 -0
- data/vendor/psd.rb/lib/psd/image_formats/layer_raw.rb +21 -0
- data/vendor/psd.rb/lib/psd/image_formats/layer_rle.rb +24 -0
- data/vendor/psd.rb/lib/psd/image_formats/raw.rb +12 -0
- data/vendor/psd.rb/lib/psd/image_formats/rle.rb +63 -0
- data/vendor/psd.rb/lib/psd/image_modes/cmyk.rb +31 -0
- data/vendor/psd.rb/lib/psd/image_modes/greyscale.rb +22 -0
- data/vendor/psd.rb/lib/psd/image_modes/rgb.rb +32 -0
- data/vendor/psd.rb/lib/psd/layer.rb +77 -0
- data/vendor/psd.rb/lib/psd/layer/blend_modes.rb +30 -0
- data/vendor/psd.rb/lib/psd/layer/blending_ranges.rb +62 -0
- data/vendor/psd.rb/lib/psd/layer/channel_image.rb +15 -0
- data/vendor/psd.rb/lib/psd/layer/exporting.rb +28 -0
- data/vendor/psd.rb/lib/psd/layer/helpers.rb +77 -0
- data/vendor/psd.rb/lib/psd/layer/info.rb +74 -0
- data/vendor/psd.rb/lib/psd/layer/mask.rb +19 -0
- data/vendor/psd.rb/lib/psd/layer/name.rb +33 -0
- data/vendor/psd.rb/lib/psd/layer/path_components.rb +22 -0
- data/vendor/psd.rb/lib/psd/layer/position_and_channels.rb +47 -0
- data/vendor/psd.rb/lib/psd/layer_info.rb +27 -0
- data/vendor/psd.rb/lib/psd/layer_info/blend_clipping_elements.rb +13 -0
- data/vendor/psd.rb/lib/psd/layer_info/blend_interior_elements.rb +13 -0
- data/vendor/psd.rb/lib/psd/layer_info/fill_opacity.rb +13 -0
- data/vendor/psd.rb/lib/psd/layer_info/layer_group.rb +30 -0
- data/vendor/psd.rb/lib/psd/layer_info/layer_id.rb +13 -0
- data/vendor/psd.rb/lib/psd/layer_info/layer_name_source.rb +14 -0
- data/vendor/psd.rb/lib/psd/layer_info/layer_section_divider.rb +48 -0
- data/vendor/psd.rb/lib/psd/layer_info/legacy_typetool.rb +88 -0
- data/vendor/psd.rb/lib/psd/layer_info/locked.rb +19 -0
- data/vendor/psd.rb/lib/psd/layer_info/metadata_setting.rb +35 -0
- data/vendor/psd.rb/lib/psd/layer_info/object_effects.rb +16 -0
- data/vendor/psd.rb/lib/psd/layer_info/placed_layer.rb +13 -0
- data/vendor/psd.rb/lib/psd/layer_info/reference_point.rb +16 -0
- data/vendor/psd.rb/lib/psd/layer_info/typetool.rb +165 -0
- data/vendor/psd.rb/lib/psd/layer_info/unicode_name.rb +17 -0
- data/vendor/psd.rb/lib/psd/layer_info/vector_mask.rb +25 -0
- data/vendor/psd.rb/lib/psd/layer_info/vector_mask_2.rb +10 -0
- data/vendor/psd.rb/lib/psd/layer_info/vector_stroke.rb +12 -0
- data/vendor/psd.rb/lib/psd/layer_info/vector_stroke_content.rb +15 -0
- data/vendor/psd.rb/lib/psd/layer_mask.rb +129 -0
- data/vendor/psd.rb/lib/psd/lazy_execute.rb +60 -0
- data/vendor/psd.rb/lib/psd/logger.rb +40 -0
- data/vendor/psd.rb/lib/psd/mask.rb +74 -0
- data/vendor/psd.rb/lib/psd/node.rb +70 -0
- data/vendor/psd.rb/lib/psd/node_exporting.rb +20 -0
- data/vendor/psd.rb/lib/psd/node_group.rb +86 -0
- data/vendor/psd.rb/lib/psd/node_layer.rb +81 -0
- data/vendor/psd.rb/lib/psd/node_root.rb +93 -0
- data/vendor/psd.rb/lib/psd/nodes/ancestry.rb +98 -0
- data/vendor/psd.rb/lib/psd/nodes/build_preview.rb +17 -0
- data/vendor/psd.rb/lib/psd/nodes/has_children.rb +13 -0
- data/vendor/psd.rb/lib/psd/nodes/lock_to_origin.rb +7 -0
- data/vendor/psd.rb/lib/psd/nodes/parse_layers.rb +18 -0
- data/vendor/psd.rb/lib/psd/nodes/search.rb +91 -0
- data/vendor/psd.rb/lib/psd/path_record.rb +180 -0
- data/vendor/psd.rb/lib/psd/renderer.rb +91 -0
- data/vendor/psd.rb/lib/psd/renderer/blender.rb +53 -0
- data/vendor/psd.rb/lib/psd/renderer/canvas.rb +95 -0
- data/vendor/psd.rb/lib/psd/renderer/canvas_management.rb +26 -0
- data/vendor/psd.rb/lib/psd/renderer/clipping_mask.rb +41 -0
- data/vendor/psd.rb/lib/psd/renderer/compose.rb +361 -0
- data/vendor/psd.rb/lib/psd/renderer/layer_styles.rb +56 -0
- data/vendor/psd.rb/lib/psd/renderer/layer_styles/color_overlay.rb +65 -0
- data/vendor/psd.rb/lib/psd/renderer/layer_styles/drop_shadow.rb +75 -0
- data/vendor/psd.rb/lib/psd/renderer/mask.rb +46 -0
- data/vendor/psd.rb/lib/psd/resource.rb +26 -0
- data/vendor/psd.rb/lib/psd/resource_section.rb +22 -0
- data/vendor/psd.rb/lib/psd/resources.rb +69 -0
- data/vendor/psd.rb/lib/psd/resources/guides.rb +35 -0
- data/vendor/psd.rb/lib/psd/resources/layer_comps.rb +42 -0
- data/vendor/psd.rb/lib/psd/resources/slices.rb +132 -0
- data/vendor/psd.rb/lib/psd/section.rb +26 -0
- data/vendor/psd.rb/lib/psd/util.rb +18 -0
- data/vendor/psd.rb/lib/psd/version.rb +3 -0
- data/vendor/psd.rb/psd.gemspec +32 -0
- data/vendor/psd.rb/spec/files/blendmodes.psd +0 -0
- data/vendor/psd.rb/spec/files/empty-layer-subgroups.psd +0 -0
- data/vendor/psd.rb/spec/files/empty-layer.psd +0 -0
- data/vendor/psd.rb/spec/files/example.psd +0 -0
- data/vendor/psd.rb/spec/files/guides.psd +0 -0
- data/vendor/psd.rb/spec/files/locked.psd +0 -0
- data/vendor/psd.rb/spec/files/one_layer.psd +0 -0
- data/vendor/psd.rb/spec/files/path.psd +0 -0
- data/vendor/psd.rb/spec/files/pixel.psd +0 -0
- data/vendor/psd.rb/spec/files/simplest.psd +0 -0
- data/vendor/psd.rb/spec/files/slices.psd +0 -0
- data/vendor/psd.rb/spec/files/text.psd +0 -0
- data/vendor/psd.rb/spec/guides_spec.rb +34 -0
- data/vendor/psd.rb/spec/hierarchy_spec.rb +152 -0
- data/vendor/psd.rb/spec/image_spec.rb +86 -0
- data/vendor/psd.rb/spec/lazy_execute_spec.rb +20 -0
- data/vendor/psd.rb/spec/locked_spec.rb +78 -0
- data/vendor/psd.rb/spec/parsing_spec.rb +163 -0
- data/vendor/psd.rb/spec/psd_spec.rb +37 -0
- data/vendor/psd.rb/spec/slices_spec.rb +57 -0
- data/vendor/psd.rb/spec/spec_helper.rb +13 -0
- data/vendor/psd.rb/spec/text_spec.rb +27 -0
- data/vendor/psd_native/Gemfile +4 -0
- data/vendor/psd_native/Guardfile +6 -0
- data/vendor/psd_native/LICENSE.txt +22 -0
- data/vendor/psd_native/README.md +48 -0
- data/vendor/psd_native/Rakefile +13 -0
- data/vendor/psd_native/ext/psd_native/blender.c +57 -0
- data/vendor/psd_native/ext/psd_native/blender.h +6 -0
- data/vendor/psd_native/ext/psd_native/canvas.c +9 -0
- data/vendor/psd_native/ext/psd_native/canvas.h +6 -0
- data/vendor/psd_native/ext/psd_native/clipping_mask.c +57 -0
- data/vendor/psd_native/ext/psd_native/clipping_mask.h +6 -0
- data/vendor/psd_native/ext/psd_native/color.c +20 -0
- data/vendor/psd_native/ext/psd_native/color.h +18 -0
- data/vendor/psd_native/ext/psd_native/compose.c +394 -0
- data/vendor/psd_native/ext/psd_native/compose.h +43 -0
- data/vendor/psd_native/ext/psd_native/extconf.rb +3 -0
- data/vendor/psd_native/ext/psd_native/file.c +20 -0
- data/vendor/psd_native/ext/psd_native/file.h +9 -0
- data/vendor/psd_native/ext/psd_native/image_mode_cmyk.c +64 -0
- data/vendor/psd_native/ext/psd_native/image_mode_cmyk.h +6 -0
- data/vendor/psd_native/ext/psd_native/image_mode_greyscale.c +27 -0
- data/vendor/psd_native/ext/psd_native/image_mode_greyscale.h +6 -0
- data/vendor/psd_native/ext/psd_native/image_mode_rgb.c +49 -0
- data/vendor/psd_native/ext/psd_native/image_mode_rgb.h +6 -0
- data/vendor/psd_native/ext/psd_native/layer_raw.c +20 -0
- data/vendor/psd_native/ext/psd_native/layer_raw.h +6 -0
- data/vendor/psd_native/ext/psd_native/mask.c +52 -0
- data/vendor/psd_native/ext/psd_native/mask.h +6 -0
- data/vendor/psd_native/ext/psd_native/psd_native_ext.c +87 -0
- data/vendor/psd_native/ext/psd_native/psd_native_ext.h +31 -0
- data/vendor/psd_native/ext/psd_native/rle_decoding.c +53 -0
- data/vendor/psd_native/ext/psd_native/rle_decoding.h +6 -0
- data/vendor/psd_native/ext/psd_native/util.c +17 -0
- data/vendor/psd_native/ext/psd_native/util.h +8 -0
- data/vendor/psd_native/lib/psd_native.rb +35 -0
- data/vendor/psd_native/lib/psd_native/compose.rb +19 -0
- data/vendor/psd_native/lib/psd_native/version.rb +3 -0
- data/vendor/psd_native/psd_native.gemspec +35 -0
- data/vendor/psd_native/spec/files/example.psd +0 -0
- data/vendor/psd_native/spec/files/one_layer.psd +0 -0
- data/vendor/psd_native/spec/files/path.psd +0 -0
- data/vendor/psd_native/spec/files/pixel.psd +0 -0
- data/vendor/psd_native/spec/files/simplest.psd +0 -0
- data/vendor/psd_native/spec/files/text.psd +0 -0
- data/vendor/psd_native/spec/image_spec.rb +86 -0
- data/vendor/psd_native/spec/psd_spec.rb +37 -0
- data/vendor/psd_native/spec/spec_helper.rb +13 -0
- data/vendor/psd_native/spec/util_spec.rb +15 -0
- metadata +767 -0
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
module ChunkyPNG
|
|
2
|
+
class Canvas
|
|
3
|
+
# The ChunkyPNG::Canvas::Operations module defines methods to perform
|
|
4
|
+
# operations on a {ChunkyPNG::Canvas}. The module is included into the
|
|
5
|
+
# Canvas class so all these methods are available on every canvas.
|
|
6
|
+
#
|
|
7
|
+
# Note that some of these operations modify the canvas, while some
|
|
8
|
+
# operations return a new canvas and leave the original intact.
|
|
9
|
+
#
|
|
10
|
+
# @see ChunkyPNG::Canvas
|
|
11
|
+
module Operations
|
|
12
|
+
# Converts the canvas to grayscale.
|
|
13
|
+
#
|
|
14
|
+
# This method will modify the canvas. The obtain a new canvas and leave
|
|
15
|
+
# the current instance intact, use {#grayscale} instead.
|
|
16
|
+
#
|
|
17
|
+
# @return [ChunkyPNG::Canvas] Returns itself, converted to grayscale.
|
|
18
|
+
# @see {#grayscale}
|
|
19
|
+
# @see {ChunkyPNG::Color#to_grayscale}
|
|
20
|
+
def grayscale!
|
|
21
|
+
pixels.map! { |pixel| ChunkyPNG::Color.to_grayscale(pixel) }
|
|
22
|
+
self
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Converts the canvas to grayscale, returning a new canvas.
|
|
26
|
+
#
|
|
27
|
+
# This method will not modify the canvas. To modift the current canvas,
|
|
28
|
+
# use {#grayscale!} instead.
|
|
29
|
+
#
|
|
30
|
+
# @return [ChunkyPNG::Canvas] A copy of the canvas, converted to
|
|
31
|
+
# grayscale.
|
|
32
|
+
# @see {#grayscale!}
|
|
33
|
+
# @see {ChunkyPNG::Color#to_grayscale}
|
|
34
|
+
def grayscale
|
|
35
|
+
dup.grayscale!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Composes another image onto this image using alpha blending. This will
|
|
39
|
+
# modify the current canvas.
|
|
40
|
+
#
|
|
41
|
+
# If you simply want to replace pixels or when the other image does not
|
|
42
|
+
# have transparency, it is faster to use {#replace!}.
|
|
43
|
+
#
|
|
44
|
+
# @param [ChunkyPNG::Canvas] other The foreground canvas to compose on
|
|
45
|
+
# the current canvas, using alpha compositing.
|
|
46
|
+
# @param [Integer] offset_x The x-offset to apply the new foreground on.
|
|
47
|
+
# @param [Integer] offset_y The y-offset to apply the new foreground on.
|
|
48
|
+
# @return [ChunkyPNG::Canvas] Returns itself, but with the other canvas
|
|
49
|
+
# composed onto it.
|
|
50
|
+
# @raise [ChunkyPNG::OutOfBounds] when the other canvas doesn't fit on
|
|
51
|
+
# this one, given the offset and size of the other canvas.
|
|
52
|
+
# @see #replace!
|
|
53
|
+
# @see #compose
|
|
54
|
+
def compose!(other, offset_x = 0, offset_y = 0)
|
|
55
|
+
check_size_constraints!(other, offset_x, offset_y)
|
|
56
|
+
|
|
57
|
+
for y in 0...other.height do
|
|
58
|
+
for x in 0...other.width do
|
|
59
|
+
set_pixel(x + offset_x,
|
|
60
|
+
y + offset_y,
|
|
61
|
+
ChunkyPNG::Color.compose(other.get_pixel(x, y),
|
|
62
|
+
get_pixel(x + offset_x,
|
|
63
|
+
y + offset_y)))
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Composes another image onto this image using alpha blending. This will
|
|
70
|
+
# return a new canvas and leave the original intact.
|
|
71
|
+
#
|
|
72
|
+
# If you simply want to replace pixels or when the other image does not
|
|
73
|
+
# have transparency, it is faster to use {#replace}.
|
|
74
|
+
#
|
|
75
|
+
# @param (see #compose!)
|
|
76
|
+
# @return [ChunkyPNG::Canvas] Returns the new canvas, composed of the
|
|
77
|
+
# other 2.
|
|
78
|
+
# @raise [ChunkyPNG::OutOfBounds] when the other canvas doesn't fit on
|
|
79
|
+
# this one, given the offset and size of the other canvas.
|
|
80
|
+
#
|
|
81
|
+
# @note API changed since 1.0 - This method now no longer is in place,
|
|
82
|
+
# but returns a new canvas and leaves the original intact. Use
|
|
83
|
+
# {#compose!} if you want to compose on the canvas in place.
|
|
84
|
+
# @see #replace
|
|
85
|
+
def compose(other, offset_x = 0, offset_y = 0)
|
|
86
|
+
dup.compose!(other, offset_x, offset_y)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Replaces pixels on this image by pixels from another pixels, on a given
|
|
90
|
+
# offset. This method will modify the current canvas.
|
|
91
|
+
#
|
|
92
|
+
# This will completely replace the pixels of the background image. If you
|
|
93
|
+
# want to blend them with semi-transparent pixels from the foreground
|
|
94
|
+
# image, see {#compose!}.
|
|
95
|
+
#
|
|
96
|
+
# @param [ChunkyPNG::Canvas] other The foreground canvas to get the
|
|
97
|
+
# pixels from.
|
|
98
|
+
# @param [Integer] offset_x The x-offset to apply the new foreground on.
|
|
99
|
+
# @param [Integer] offset_y The y-offset to apply the new foreground on.
|
|
100
|
+
# @return [ChunkyPNG::Canvas] Returns itself, but with the other canvas
|
|
101
|
+
# placed onto it.
|
|
102
|
+
# @raise [ChunkyPNG::OutOfBounds] when the other canvas doesn't fit on
|
|
103
|
+
# this one, given the offset and size of the other canvas.
|
|
104
|
+
# @see #compose!
|
|
105
|
+
# @see #replace
|
|
106
|
+
def replace!(other, offset_x = 0, offset_y = 0)
|
|
107
|
+
check_size_constraints!(other, offset_x, offset_y)
|
|
108
|
+
|
|
109
|
+
for y in 0...other.height do
|
|
110
|
+
for d in 0...other.width
|
|
111
|
+
pixels[(y + offset_y) * width + offset_x + d] = other.pixels[y * other.width + d]
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
self
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Replaces pixels on this image by pixels from another pixels, on a given
|
|
118
|
+
# offset. This method will modify the current canvas.
|
|
119
|
+
#
|
|
120
|
+
# This will completely replace the pixels of the background image. If you
|
|
121
|
+
# want to blend them with semi-transparent pixels from the foreground
|
|
122
|
+
# image, see {#compose!}.
|
|
123
|
+
#
|
|
124
|
+
# @param (see #replace!)
|
|
125
|
+
# @return [ChunkyPNG::Canvas] Returns a new, combined canvas.
|
|
126
|
+
# @raise [ChunkyPNG::OutOfBounds] when the other canvas doesn't fit on
|
|
127
|
+
# this one, given the offset and size of the other canvas.
|
|
128
|
+
#
|
|
129
|
+
# @note API changed since 1.0 - This method now no longer is in place,
|
|
130
|
+
# but returns a new canvas and leaves the original intact. Use
|
|
131
|
+
# {#replace!} if you want to replace pixels on the canvas in place.
|
|
132
|
+
# @see #compose
|
|
133
|
+
def replace(other, offset_x = 0, offset_y = 0)
|
|
134
|
+
dup.replace!(other, offset_x, offset_y)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Crops an image, given the coordinates and size of the image that needs
|
|
138
|
+
# to be cut out. This will leave the original image intact and return a
|
|
139
|
+
# new, cropped image with pixels copied from the original image.
|
|
140
|
+
#
|
|
141
|
+
# @param [Integer] x The x-coordinate of the top left corner of the image
|
|
142
|
+
# to be cropped.
|
|
143
|
+
# @param [Integer] y The y-coordinate of the top left corner of the image
|
|
144
|
+
# to be cropped.
|
|
145
|
+
# @param [Integer] crop_width The width of the image to be cropped.
|
|
146
|
+
# @param [Integer] crop_height The height of the image to be cropped.
|
|
147
|
+
# @return [ChunkyPNG::Canvas] Returns the newly created cropped image.
|
|
148
|
+
# @raise [ChunkyPNG::OutOfBounds] when the crop dimensions plus the given
|
|
149
|
+
# coordinates are bigger then the original image.
|
|
150
|
+
def crop(x, y, crop_width, crop_height)
|
|
151
|
+
dup.crop!(x, y, crop_width, crop_height)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Crops an image, given the coordinates and size of the image that needs
|
|
155
|
+
# to be cut out.
|
|
156
|
+
#
|
|
157
|
+
# This will change the size and content of the current canvas. Use
|
|
158
|
+
# {#crop} if you want to have a new canvas returned instead, leaving the
|
|
159
|
+
# current canvas intact.
|
|
160
|
+
#
|
|
161
|
+
# @param [Integer] x The x-coordinate of the top left corner of the image
|
|
162
|
+
# to be cropped.
|
|
163
|
+
# @param [Integer] y The y-coordinate of the top left corner of the image
|
|
164
|
+
# to be cropped.
|
|
165
|
+
# @param [Integer] crop_width The width of the image to be cropped.
|
|
166
|
+
# @param [Integer] crop_height The height of the image to be cropped.
|
|
167
|
+
# @return [ChunkyPNG::Canvas] Returns itself, but cropped.
|
|
168
|
+
# @raise [ChunkyPNG::OutOfBounds] when the crop dimensions plus the given
|
|
169
|
+
# coordinates are bigger then the original image.
|
|
170
|
+
def crop!(x, y, crop_width, crop_height)
|
|
171
|
+
if crop_width + x > width
|
|
172
|
+
raise ChunkyPNG::OutOfBounds, 'Original image width is too small!'
|
|
173
|
+
end
|
|
174
|
+
if crop_height + y > height
|
|
175
|
+
raise ChunkyPNG::OutOfBounds, 'Original image height is too small!'
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
new_pixels = []
|
|
179
|
+
for cy in 0...crop_height do
|
|
180
|
+
new_pixels += pixels.slice((cy + y) * width + x, crop_width)
|
|
181
|
+
end
|
|
182
|
+
replace_canvas!(crop_width, crop_height, new_pixels)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Flips the image horizontally, leaving the original intact.
|
|
186
|
+
#
|
|
187
|
+
# This will flip the image on its horizontal axis, e.g. pixels on the top
|
|
188
|
+
# will now be pixels on the bottom. Chaining this method twice will
|
|
189
|
+
# return the original canvas. This method will leave the original object
|
|
190
|
+
# intact and return a new canvas.
|
|
191
|
+
#
|
|
192
|
+
# @return [ChunkyPNG::Canvas] The flipped image
|
|
193
|
+
# @see #flip_horizontally!
|
|
194
|
+
def flip_horizontally
|
|
195
|
+
dup.flip_horizontally!
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Flips the image horizontally in place.
|
|
199
|
+
#
|
|
200
|
+
# This will flip the image on its horizontal axis, e.g. pixels on the top
|
|
201
|
+
# will now be pixels on the bottom. Chaining this method twice will
|
|
202
|
+
# return the original canvas. This method will leave the original object
|
|
203
|
+
# intact and return a new canvas.
|
|
204
|
+
#
|
|
205
|
+
# @return [ChunkyPNG::Canvas] Itself, but flipped
|
|
206
|
+
# @see #flip_horizontally
|
|
207
|
+
def flip_horizontally!
|
|
208
|
+
for y in 0..((height - 1) >> 1) do
|
|
209
|
+
other_y = height - (y + 1)
|
|
210
|
+
other_row = row(other_y)
|
|
211
|
+
replace_row!(other_y, row(y))
|
|
212
|
+
replace_row!(y, other_row)
|
|
213
|
+
end
|
|
214
|
+
self
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
alias_method :flip!, :flip_horizontally!
|
|
218
|
+
alias_method :flip, :flip_horizontally
|
|
219
|
+
|
|
220
|
+
# Flips the image vertically, leaving the original intact.
|
|
221
|
+
#
|
|
222
|
+
# This will flip the image on its vertical axis, e.g. pixels on the left
|
|
223
|
+
# will now be pixels on the right. Chaining this method twice will return
|
|
224
|
+
# the original canvas. This method will leave the original object intact
|
|
225
|
+
# and return a new canvas.
|
|
226
|
+
#
|
|
227
|
+
# @return [ChunkyPNG::Canvas] The flipped image
|
|
228
|
+
# @see #flip_vertically!
|
|
229
|
+
def flip_vertically
|
|
230
|
+
dup.flip_vertically!
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Flips the image vertically in place.
|
|
234
|
+
#
|
|
235
|
+
# This will flip the image on its vertical axis, e.g. pixels on the left
|
|
236
|
+
# will now be pixels on the right. Chaining this method twice will return
|
|
237
|
+
# the original canvas. This method will leave the original object intact
|
|
238
|
+
# and return a new canvas.
|
|
239
|
+
#
|
|
240
|
+
# @return [ChunkyPNG::Canvas] Itself, but flipped
|
|
241
|
+
# @see #flip_vertically
|
|
242
|
+
def flip_vertically!
|
|
243
|
+
for y in 0...height do
|
|
244
|
+
replace_row!(y, row(y).reverse)
|
|
245
|
+
end
|
|
246
|
+
self
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
alias_method :mirror!, :flip_vertically!
|
|
250
|
+
alias_method :mirror, :flip_vertically
|
|
251
|
+
|
|
252
|
+
# Returns a new canvas instance that is rotated 90 degrees clockwise.
|
|
253
|
+
#
|
|
254
|
+
# This method will return a new canvas and leaves the original intact.
|
|
255
|
+
#
|
|
256
|
+
# @return [ChunkyPNG::Canvas] A clockwise-rotated copy.
|
|
257
|
+
# @see #rotate_right! for the in place version.
|
|
258
|
+
def rotate_right
|
|
259
|
+
dup.rotate_right!
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Rotates the image 90 degrees clockwise in place.
|
|
263
|
+
#
|
|
264
|
+
# This method will change the current canvas.
|
|
265
|
+
#
|
|
266
|
+
# @return [ChunkyPNG::Canvas] Itself, but rotated clockwise.
|
|
267
|
+
# @see #rotate_right for a version that leaves the current canvas intact
|
|
268
|
+
def rotate_right!
|
|
269
|
+
rotated = self.class.new(height, width)
|
|
270
|
+
new_pixels = []
|
|
271
|
+
0.upto(width - 1) { |i| new_pixels += column(i).reverse }
|
|
272
|
+
replace_canvas!(height, width, new_pixels)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
alias_method :rotate_clockwise, :rotate_right
|
|
276
|
+
alias_method :rotate_clockwise!, :rotate_right!
|
|
277
|
+
|
|
278
|
+
# Returns an image that is rotated 90 degrees counter-clockwise.
|
|
279
|
+
#
|
|
280
|
+
# This method will leave the original object intact and return a new
|
|
281
|
+
# canvas.
|
|
282
|
+
#
|
|
283
|
+
# @return [ChunkyPNG::Canvas] A rotated copy of itself.
|
|
284
|
+
# @see #rotate_left! for the in-place version.
|
|
285
|
+
def rotate_left
|
|
286
|
+
dup.rotate_left!
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Rotates the image 90 degrees counter-clockwise in place.
|
|
290
|
+
#
|
|
291
|
+
# This method will change the original canvas. See {#rotate_left} for a
|
|
292
|
+
# version that leaves the canvas intact and returns a new rotated canvas
|
|
293
|
+
# instead.
|
|
294
|
+
#
|
|
295
|
+
# @return [ChunkyPNG::Canvas] Itself, but rotated.
|
|
296
|
+
def rotate_left!
|
|
297
|
+
new_pixels = []
|
|
298
|
+
(width - 1).downto(0) { |i| new_pixels += column(i) }
|
|
299
|
+
replace_canvas!(height, width, new_pixels)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
alias_method :rotate_counter_clockwise, :rotate_left
|
|
303
|
+
alias_method :rotate_counter_clockwise!, :rotate_left!
|
|
304
|
+
|
|
305
|
+
# Rotates the image 180 degrees.
|
|
306
|
+
#
|
|
307
|
+
# This method will leave the original object intact and return a new
|
|
308
|
+
# canvas.
|
|
309
|
+
#
|
|
310
|
+
# @return [ChunkyPNG::Canvas] The rotated image.
|
|
311
|
+
# @see #rotate_180!
|
|
312
|
+
def rotate_180
|
|
313
|
+
dup.rotate_180!
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Rotates the image 180 degrees in place.
|
|
317
|
+
#
|
|
318
|
+
# @return [ChunkyPNG::Canvas] Itself, but rotated 180 degrees.
|
|
319
|
+
# @see #rotate_180
|
|
320
|
+
def rotate_180!
|
|
321
|
+
pixels.reverse!
|
|
322
|
+
self
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
# Trims the border around the image, presumed to be the color of the
|
|
326
|
+
# first pixel.
|
|
327
|
+
#
|
|
328
|
+
# @param [Integer] border The color to attempt to trim.
|
|
329
|
+
# @return [ChunkyPNG::Canvas] The trimmed image.
|
|
330
|
+
# @see #trim!
|
|
331
|
+
def trim(border = pixels.first)
|
|
332
|
+
dup.trim!
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Trims the border around the image in place.
|
|
336
|
+
#
|
|
337
|
+
# @param [Integer] border The color to attempt to trim.
|
|
338
|
+
# @return [ChunkyPNG::Canvas] Returns itself, but with the border
|
|
339
|
+
# trimmed.
|
|
340
|
+
# @see #trim
|
|
341
|
+
def trim!(border = pixels.first)
|
|
342
|
+
x1 = [*0...width].index { |c| column(c).uniq != [border] }
|
|
343
|
+
x2 = [*0...width].rindex { |c| column(c).uniq != [border] }
|
|
344
|
+
y1 = [*0...height].index { |r| row(r).uniq != [border] }
|
|
345
|
+
y2 = [*0...height].rindex { |r| row(r).uniq != [border] }
|
|
346
|
+
|
|
347
|
+
crop! x1, y1, x2 - x1 + 1, y2 - y1 + 1
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
# Draws a border around the image.
|
|
351
|
+
#
|
|
352
|
+
# @param [Integer] size The size of the border.
|
|
353
|
+
# @param [Integer] color The color of the border.
|
|
354
|
+
# @return [ChunkyPNG::Canvas] Returns a bordered version of the image.
|
|
355
|
+
# @see #border!
|
|
356
|
+
def border(size, color = ChunkyPNG::Color::BLACK)
|
|
357
|
+
dup.border!(size, color)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# Draws a border around the image in place.
|
|
361
|
+
#
|
|
362
|
+
# @param [Integer] size The size of the border.
|
|
363
|
+
# @param [Integer] color The color of the border.
|
|
364
|
+
# @return [ChunkyPNG::Canvas] Returns itself with the border added.
|
|
365
|
+
# @see #border
|
|
366
|
+
def border!(size, color = ChunkyPNG::Color::BLACK)
|
|
367
|
+
new_width = width + size * 2
|
|
368
|
+
new_height = height + size * 2
|
|
369
|
+
|
|
370
|
+
bg = Canvas.new(new_width, new_height, color).replace(self, size, size)
|
|
371
|
+
replace_canvas!(new_width, new_height, bg.pixels)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
protected
|
|
375
|
+
|
|
376
|
+
# Checks whether another image has the correct dimension to be used for
|
|
377
|
+
# an operation on the current image, given an offset coordinate to work
|
|
378
|
+
# with.
|
|
379
|
+
# @param [ChunkyPNG::Canvas] other The other canvas
|
|
380
|
+
# @param [Integer] offset_x The x offset on which the other image will be
|
|
381
|
+
# applied.
|
|
382
|
+
# @param [Integer] offset_y The y offset on which the other image will be
|
|
383
|
+
# applied.
|
|
384
|
+
# @raise [ChunkyPNG::OutOfBounds] when the other image doesn't fit.
|
|
385
|
+
def check_size_constraints!(other, offset_x, offset_y)
|
|
386
|
+
if width < other.width + offset_x
|
|
387
|
+
raise ChunkyPNG::OutOfBounds, 'Background image width is too small!'
|
|
388
|
+
end
|
|
389
|
+
if height < other.height + offset_y
|
|
390
|
+
raise ChunkyPNG::OutOfBounds, 'Background image height is too small!'
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
end
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
module ChunkyPNG
|
|
2
|
+
class Canvas
|
|
3
|
+
|
|
4
|
+
# The PNGDecoding contains methods for decoding PNG datastreams to create a
|
|
5
|
+
# Canvas object. The datastream can be provided as filename, string or IO
|
|
6
|
+
# stream.
|
|
7
|
+
#
|
|
8
|
+
# Overview of the decoding process:
|
|
9
|
+
#
|
|
10
|
+
# * The optional PLTE and tRNS chunk are decoded for the color palette of
|
|
11
|
+
# the original image.
|
|
12
|
+
# * The contents of the IDAT chunks is combined, and uncompressed using
|
|
13
|
+
# Inflate decompression to the image pixelstream.
|
|
14
|
+
# * Based on the color mode, width and height of the original image, which
|
|
15
|
+
# is read from the PNG header (IHDR chunk), the amount of bytes
|
|
16
|
+
# per line is determined.
|
|
17
|
+
# * For every line of pixels in the encoded image, the original byte values
|
|
18
|
+
# are restored by unapplying the milter method for that line.
|
|
19
|
+
# * The read bytes are unfiltered given by the filter function specified by
|
|
20
|
+
# the first byte of the line.
|
|
21
|
+
# * The unfiltered pixelstream are is into colored pixels, using the color mode.
|
|
22
|
+
# * All lines combined to form the original image.
|
|
23
|
+
#
|
|
24
|
+
# For interlaced images, the original image was split into 7 subimages.
|
|
25
|
+
# These images get decoded just like the process above (from step 3), and get
|
|
26
|
+
# combined to form the original images.
|
|
27
|
+
#
|
|
28
|
+
# @see ChunkyPNG::Canvas::PNGEncoding
|
|
29
|
+
# @see http://www.w3.org/TR/PNG/ The W3C PNG format specification
|
|
30
|
+
module PNGDecoding
|
|
31
|
+
|
|
32
|
+
# The palette that is used to decode the image, loading from the PLTE and
|
|
33
|
+
# tRNS chunk from the PNG stream. For RGB(A) images, no palette is required.
|
|
34
|
+
# @return [ChunkyPNG::Palette]
|
|
35
|
+
attr_accessor :decoding_palette
|
|
36
|
+
|
|
37
|
+
# The color to be replaced with fully transparent pixels.
|
|
38
|
+
attr_accessor :transparent_color
|
|
39
|
+
|
|
40
|
+
# Decodes a Canvas from a PNG encoded string.
|
|
41
|
+
# @param [String] str The string to read from.
|
|
42
|
+
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG encoded string.
|
|
43
|
+
def from_blob(str)
|
|
44
|
+
from_datastream(ChunkyPNG::Datastream.from_blob(str))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
alias_method :from_string, :from_blob
|
|
48
|
+
|
|
49
|
+
# Decodes a Canvas from a PNG encoded file.
|
|
50
|
+
# @param [String] filename The file to read from.
|
|
51
|
+
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG file.
|
|
52
|
+
def from_file(filename)
|
|
53
|
+
from_datastream(ChunkyPNG::Datastream.from_file(filename))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Decodes a Canvas from a PNG encoded stream.
|
|
57
|
+
# @param [IO, #read] io The stream to read from.
|
|
58
|
+
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG stream.
|
|
59
|
+
def from_io(io)
|
|
60
|
+
from_datastream(ChunkyPNG::Datastream.from_io(io))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
alias_method :from_stream, :from_io
|
|
64
|
+
|
|
65
|
+
# Decodes the Canvas from a PNG datastream instance.
|
|
66
|
+
# @param [ChunkyPNG::Datastream] ds The datastream to decode.
|
|
67
|
+
# @return [ChunkyPNG::Canvas] The canvas decoded from the PNG datastream.
|
|
68
|
+
def from_datastream(ds)
|
|
69
|
+
width = ds.header_chunk.width
|
|
70
|
+
height = ds.header_chunk.height
|
|
71
|
+
color_mode = ds.header_chunk.color
|
|
72
|
+
interlace = ds.header_chunk.interlace
|
|
73
|
+
depth = ds.header_chunk.depth
|
|
74
|
+
|
|
75
|
+
if width == 0 || height == 0
|
|
76
|
+
raise ExpectationFailed, "Invalid image size, width: #{width}, height: #{height}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
case color_mode
|
|
80
|
+
when ChunkyPNG::COLOR_INDEXED
|
|
81
|
+
self.decoding_palette = ChunkyPNG::Palette.from_chunks(ds.palette_chunk, ds.transparency_chunk)
|
|
82
|
+
when ChunkyPNG::COLOR_TRUECOLOR
|
|
83
|
+
self.transparent_color = ds.transparency_chunk.truecolor_entry(depth) if ds.transparency_chunk
|
|
84
|
+
when ChunkyPNG::COLOR_GRAYSCALE
|
|
85
|
+
self.transparent_color = ds.transparency_chunk.grayscale_entry(depth) if ds.transparency_chunk
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
decode_png_pixelstream(ds.imagedata, width, height, color_mode, depth, interlace)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Decodes a canvas from a PNG encoded pixelstream, using a given width, height,
|
|
92
|
+
# color mode and interlacing mode.
|
|
93
|
+
# @param [String] stream The pixelstream to read from.
|
|
94
|
+
# @param [Integer] width The width of the image.
|
|
95
|
+
# @param [Integer] width The height of the image.
|
|
96
|
+
# @param [Integer] color_mode The color mode of the encoded pixelstream.
|
|
97
|
+
# @param [Integer] depth The bit depth of the pixel samples.
|
|
98
|
+
# @param [Integer] interlace The interlace method of the encoded pixelstream.
|
|
99
|
+
# @return [ChunkyPNG::Canvas] The decoded Canvas instance.
|
|
100
|
+
def decode_png_pixelstream(stream, width, height, color_mode, depth, interlace)
|
|
101
|
+
raise ChunkyPNG::ExpectationFailed, "This palette is not suitable for decoding!" if decoding_palette && !decoding_palette.can_decode?
|
|
102
|
+
|
|
103
|
+
image = case interlace
|
|
104
|
+
when ChunkyPNG::INTERLACING_NONE; decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
|
105
|
+
when ChunkyPNG::INTERLACING_ADAM7; decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
|
106
|
+
else raise ChunkyPNG::NotSupported, "Don't know how the handle interlacing method #{interlace}!"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
image.pixels.map! { |c| c == transparent_color ? ChunkyPNG::Color::TRANSPARENT : c } if transparent_color
|
|
110
|
+
return image
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
protected
|
|
114
|
+
|
|
115
|
+
# Decodes a canvas from a non-interlaced PNG encoded pixelstream, using a
|
|
116
|
+
# given width, height and color mode.
|
|
117
|
+
# @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
118
|
+
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
119
|
+
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
120
|
+
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
121
|
+
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
122
|
+
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
123
|
+
def decode_png_without_interlacing(stream, width, height, color_mode, depth)
|
|
124
|
+
decode_png_image_pass(stream, width, height, color_mode, depth, 0)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Decodes a canvas from a Adam 7 interlaced PNG encoded pixelstream, using a
|
|
128
|
+
# given width, height and color mode.
|
|
129
|
+
# @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
130
|
+
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
131
|
+
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
132
|
+
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
133
|
+
# @param depth (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
134
|
+
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
135
|
+
def decode_png_with_adam7_interlacing(stream, width, height, color_mode, depth)
|
|
136
|
+
canvas = new(width, height)
|
|
137
|
+
start_pos = 0
|
|
138
|
+
for pass in 0...7
|
|
139
|
+
sm_width, sm_height = adam7_pass_size(pass, width, height)
|
|
140
|
+
sm = decode_png_image_pass(stream, sm_width, sm_height, color_mode, depth, start_pos)
|
|
141
|
+
adam7_merge_pass(pass, canvas, sm)
|
|
142
|
+
start_pos += ChunkyPNG::Color.pass_bytesize(color_mode, depth, sm_width, sm_height)
|
|
143
|
+
end
|
|
144
|
+
canvas
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Extract 4 consecutive bits from a byte.
|
|
148
|
+
# @param [Integer] byte The byte (0..255) value to extract a 4 bit value from.
|
|
149
|
+
# @param [Integer] index The index within the byte. This should be either 0 or 2;
|
|
150
|
+
# the value will be modded by 2 to enforce this.
|
|
151
|
+
# @return [Integer] The extracted 4bit value (0..15)
|
|
152
|
+
def decode_png_extract_4bit_value(byte, index)
|
|
153
|
+
(index & 0x01 == 0) ? ((byte & 0xf0) >> 4) : (byte & 0x0f)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Extract 2 consecutive bits from a byte.
|
|
157
|
+
# @param [Integer] byte The byte (0..255) value to extract a 2 bit value from.
|
|
158
|
+
# @param [Integer] index The index within the byte. This should be either 0, 1, 2, or 3;
|
|
159
|
+
# the value will be modded by 4 to enforce this.
|
|
160
|
+
# @return [Integer] The extracted 2 bit value (0..3)
|
|
161
|
+
def decode_png_extract_2bit_value(byte, index)
|
|
162
|
+
bitshift = 6 - ((index & 0x03) << 1)
|
|
163
|
+
(byte & (0x03 << bitshift)) >> bitshift
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Extract a bit from a byte on a given index.
|
|
167
|
+
# @param [Integer] byte The byte (0..255) value to extract a bit from.
|
|
168
|
+
# @param [Integer] index The index within the byte. This should be 0..7;
|
|
169
|
+
# the value will be modded by 8 to enforce this.
|
|
170
|
+
# @return [Integer] Either 1 or 0.
|
|
171
|
+
def decode_png_extract_1bit_value(byte, index)
|
|
172
|
+
bitshift = 7 - (index & 0x07)
|
|
173
|
+
(byte & (0x01 << bitshift)) >> bitshift
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Resamples a 16 bit value to an 8 bit value. This will discard some color information.
|
|
177
|
+
# @param [Integer] value The 16 bit value to resample.
|
|
178
|
+
# @return [Integer] The 8 bit resampled value
|
|
179
|
+
def decode_png_resample_16bit_value(value)
|
|
180
|
+
value >> 8
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# No-op - available for completeness sake only
|
|
184
|
+
# @param [Integer] value The 8 bit value to resample.
|
|
185
|
+
# @return [Integer] The 8 bit resampled value
|
|
186
|
+
def decode_png_resample_8bit_value(value)
|
|
187
|
+
value
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Resamples a 4 bit value to an 8 bit value.
|
|
191
|
+
# @param [Integer] value The 4 bit value to resample.
|
|
192
|
+
# @return [Integer] The 8 bit resampled value.
|
|
193
|
+
def decode_png_resample_4bit_value(value)
|
|
194
|
+
value << 4 | value
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Resamples a 2 bit value to an 8 bit value.
|
|
198
|
+
# @param [Integer] value The 2 bit value to resample.
|
|
199
|
+
# @return [Integer] The 8 bit resampled value.
|
|
200
|
+
def decode_png_resample_2bit_value(value)
|
|
201
|
+
value << 6 | value << 4 | value << 2 | value
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Resamples a 1 bit value to an 8 bit value.
|
|
205
|
+
# @param [Integer] value The 1 bit value to resample.
|
|
206
|
+
# @return [Integer] The 8 bit resampled value
|
|
207
|
+
def decode_png_resample_1bit_value(value)
|
|
208
|
+
value == 0x01 ? 0xff : 0x00
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# Decodes a scanline of a 1-bit, indexed image into a row of pixels.
|
|
213
|
+
# @param [String] stream The stream to decode from.
|
|
214
|
+
# @param [Integer] pos The position in the stream on which the scanline starts (including the filter byte).
|
|
215
|
+
# @param [Integer] width The width in pixels of the scanline.
|
|
216
|
+
# @return [Array<Integer>] An array of decoded pixels.
|
|
217
|
+
def decode_png_pixels_from_scanline_indexed_1bit(stream, pos, width)
|
|
218
|
+
(0...width).map do |index|
|
|
219
|
+
palette_pos = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
|
220
|
+
decoding_palette[palette_pos]
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# Decodes a scanline of a 2-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_2bit(stream, pos, width)
|
|
228
|
+
(0...width).map do |index|
|
|
229
|
+
palette_pos = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
|
230
|
+
decoding_palette[palette_pos]
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# Decodes a scanline of a 4-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_4bit(stream, pos, width)
|
|
238
|
+
(0...width).map do |index|
|
|
239
|
+
palette_pos = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
|
240
|
+
decoding_palette[palette_pos]
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# Decodes a scanline of a 8-bit, indexed image into a row of pixels.
|
|
245
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
246
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
247
|
+
def decode_png_pixels_from_scanline_indexed_8bit(stream, pos, width)
|
|
248
|
+
(1..width).map { |i| decoding_palette[stream.getbyte(pos + i)] }
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Decodes a scanline of an 8-bit, true color image with transparency into a row of pixels.
|
|
252
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
253
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
254
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_8bit(stream, pos, width)
|
|
255
|
+
stream.unpack("@#{pos + 1}N#{width}")
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Decodes a scanline of a 16-bit, true color image with transparency into a row of pixels.
|
|
259
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
260
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
261
|
+
def decode_png_pixels_from_scanline_truecolor_alpha_16bit(stream, pos, width)
|
|
262
|
+
pixels = []
|
|
263
|
+
stream.unpack("@#{pos + 1}n#{width * 4}").each_slice(4) do |r, g, b, a|
|
|
264
|
+
pixels << ChunkyPNG::Color.rgba(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g),
|
|
265
|
+
decode_png_resample_16bit_value(b), decode_png_resample_16bit_value(a))
|
|
266
|
+
end
|
|
267
|
+
return pixels
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Decodes a scanline of an 8-bit, true color image into a row of pixels.
|
|
271
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
272
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
273
|
+
def decode_png_pixels_from_scanline_truecolor_8bit(stream, pos, width)
|
|
274
|
+
stream.unpack("@#{pos + 1}" << ('NX' * width)).map { |c| c | 0x000000ff }
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Decodes a scanline of a 16-bit, true color image into a row of pixels.
|
|
278
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
279
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
280
|
+
def decode_png_pixels_from_scanline_truecolor_16bit(stream, pos, width)
|
|
281
|
+
pixels = []
|
|
282
|
+
stream.unpack("@#{pos + 1}n#{width * 3}").each_slice(3) do |r, g, b|
|
|
283
|
+
pixels << ChunkyPNG::Color.rgb(decode_png_resample_16bit_value(r), decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(b))
|
|
284
|
+
end
|
|
285
|
+
return pixels
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Decodes a scanline of an 8-bit, grayscale image with transparency into a row of pixels.
|
|
289
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
290
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
291
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_8bit(stream, pos, width)
|
|
292
|
+
(0...width).map { |i| ChunkyPNG::Color.grayscale_alpha(stream.getbyte(pos + (i * 2) + 1), stream.getbyte(pos + (i * 2) + 2)) }
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Decodes a scanline of a 16-bit, grayscale image with transparency into a row of pixels.
|
|
296
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
297
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
298
|
+
def decode_png_pixels_from_scanline_grayscale_alpha_16bit(stream, pos, width)
|
|
299
|
+
pixels = []
|
|
300
|
+
stream.unpack("@#{pos + 1}n#{width * 2}").each_slice(2) do |g, a|
|
|
301
|
+
pixels << ChunkyPNG::Color.grayscale_alpha(decode_png_resample_16bit_value(g), decode_png_resample_16bit_value(a))
|
|
302
|
+
end
|
|
303
|
+
return pixels
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Decodes a scanline of a 1-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_1bit(stream, pos, width)
|
|
310
|
+
(0...width).map do |index|
|
|
311
|
+
value = decode_png_extract_1bit_value(stream.getbyte(pos + 1 + (index >> 3)), index)
|
|
312
|
+
value == 1 ? ChunkyPNG::Color::WHITE : ChunkyPNG::Color::BLACK
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Decodes a scanline of a 2-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_2bit(stream, pos, width)
|
|
320
|
+
(0...width).map do |index|
|
|
321
|
+
value = decode_png_extract_2bit_value(stream.getbyte(pos + 1 + (index >> 2)), index)
|
|
322
|
+
ChunkyPNG::Color.grayscale(decode_png_resample_2bit_value(value))
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
# Decodes a scanline of a 4-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_4bit(stream, pos, width)
|
|
330
|
+
(0...width).map do |index|
|
|
331
|
+
value = decode_png_extract_4bit_value(stream.getbyte(pos + 1 + (index >> 1)), index)
|
|
332
|
+
ChunkyPNG::Color.grayscale(decode_png_resample_4bit_value(value))
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Decodes a scanline of an 8-bit, grayscale image into a row of pixels.
|
|
337
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
338
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
339
|
+
def decode_png_pixels_from_scanline_grayscale_8bit(stream, pos, width)
|
|
340
|
+
(1..width).map { |i| ChunkyPNG::Color.grayscale(stream.getbyte(pos + i)) }
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
# Decodes a scanline of a 16-bit, grayscale image into a row of pixels.
|
|
344
|
+
# @params (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
345
|
+
# @return (see #decode_png_pixels_from_scanline_indexed_1bit)
|
|
346
|
+
def decode_png_pixels_from_scanline_grayscale_16bit(stream, pos, width)
|
|
347
|
+
values = stream.unpack("@#{pos + 1}n#{width}")
|
|
348
|
+
values.map { |value| ChunkyPNG::Color.grayscale(decode_png_resample_16bit_value(value)) }
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# Returns the method name to use to decode scanlines into pixels.
|
|
352
|
+
# @param [Integer] color_mode The color mode of the image.
|
|
353
|
+
# @param [Integer] depth The bit depth of the image.
|
|
354
|
+
# @return [Symbol] The method name to use for decoding, to be called on the canvas class.
|
|
355
|
+
# @raise [ChunkyPNG::NotSupported] when the color_mode and/or bit depth is not supported.
|
|
356
|
+
def decode_png_pixels_from_scanline_method(color_mode, depth)
|
|
357
|
+
decoder_method = case color_mode
|
|
358
|
+
when ChunkyPNG::COLOR_TRUECOLOR; :"decode_png_pixels_from_scanline_truecolor_#{depth}bit"
|
|
359
|
+
when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; :"decode_png_pixels_from_scanline_truecolor_alpha_#{depth}bit"
|
|
360
|
+
when ChunkyPNG::COLOR_INDEXED; :"decode_png_pixels_from_scanline_indexed_#{depth}bit"
|
|
361
|
+
when ChunkyPNG::COLOR_GRAYSCALE; :"decode_png_pixels_from_scanline_grayscale_#{depth}bit"
|
|
362
|
+
when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; :"decode_png_pixels_from_scanline_grayscale_alpha_#{depth}bit"
|
|
363
|
+
else nil
|
|
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
|
|
369
|
+
|
|
370
|
+
# Decodes a single PNG image pass width a given width, height and color
|
|
371
|
+
# mode, to a Canvas, starting at the given position in the stream.
|
|
372
|
+
#
|
|
373
|
+
# A non-interlaced image only consists of one pass, while an Adam7
|
|
374
|
+
# image consists of 7 passes that must be combined after decoding.
|
|
375
|
+
#
|
|
376
|
+
# @param stream (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
377
|
+
# @param width (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
378
|
+
# @param height (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
379
|
+
# @param color_mode (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
380
|
+
# @param [Integer] start_pos The position in the pixel stream to start reading.
|
|
381
|
+
# @return (see ChunkyPNG::Canvas::PNGDecoding#decode_png_pixelstream)
|
|
382
|
+
def decode_png_image_pass(stream, width, height, color_mode, depth, start_pos)
|
|
383
|
+
|
|
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 line_no in 0...height do
|
|
396
|
+
decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
|
397
|
+
pixels += send(pixel_decoder, stream, pos, width)
|
|
398
|
+
|
|
399
|
+
prev_pos = pos
|
|
400
|
+
pos += line_length + 1
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
new(width, height, pixels)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# Decodes a scanline if it was encoded using filtering.
|
|
408
|
+
#
|
|
409
|
+
# It will extract the filtering method from the first byte of the scanline, and uses the
|
|
410
|
+
# method to change the subsequent bytes to unfiltered values. This will modify the pixelstream.
|
|
411
|
+
#
|
|
412
|
+
# The bytes of the scanline can then be used to construct pixels, based on the color mode..
|
|
413
|
+
#
|
|
414
|
+
# @param [String] stream The pixelstream to undo the filtering in.
|
|
415
|
+
# @param [Integer] pos The starting position of the scanline to decode.
|
|
416
|
+
# @param [Integer, nil] prev_pos The starting position of the previously decoded scanline, or <tt>nil</tt>
|
|
417
|
+
# if this is the first scanline of the image.
|
|
418
|
+
# @param [Integer] line_length The number of bytes in the scanline, discounting the filter method byte.
|
|
419
|
+
# @param [Integer] pixel_size The number of bytes used per pixel, based on the color mode.
|
|
420
|
+
# @return [void]
|
|
421
|
+
def decode_png_str_scanline(stream, pos, prev_pos, line_length, pixel_size)
|
|
422
|
+
case stream.getbyte(pos)
|
|
423
|
+
when ChunkyPNG::FILTER_NONE; # noop
|
|
424
|
+
when ChunkyPNG::FILTER_SUB; decode_png_str_scanline_sub( stream, pos, prev_pos, line_length, pixel_size)
|
|
425
|
+
when ChunkyPNG::FILTER_UP; decode_png_str_scanline_up( stream, pos, prev_pos, line_length, pixel_size)
|
|
426
|
+
when ChunkyPNG::FILTER_AVERAGE; decode_png_str_scanline_average( stream, pos, prev_pos, line_length, pixel_size)
|
|
427
|
+
when ChunkyPNG::FILTER_PAETH; 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
|
|
431
|
+
|
|
432
|
+
# Decodes a scanline that wasn't encoded using filtering. This is a no-op.
|
|
433
|
+
# @params (see #decode_png_str_scanline)
|
|
434
|
+
# @return [void]
|
|
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
|
|
438
|
+
|
|
439
|
+
# Decodes a scanline in a pixelstream that was encoded using SUB filtering.
|
|
440
|
+
# This will change the pixelstream to have unfiltered values.
|
|
441
|
+
# @params (see #decode_png_str_scanline)
|
|
442
|
+
# @return [void]
|
|
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
|
|
448
|
+
|
|
449
|
+
# Decodes a scanline in a pixelstream that was encoded using UP filtering.
|
|
450
|
+
# This will change the pixelstream to have unfiltered values.
|
|
451
|
+
# @params (see #decode_png_str_scanline)
|
|
452
|
+
# @return [void]
|
|
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
|
|
459
|
+
|
|
460
|
+
# Decodes a scanline in a pixelstream that was encoded using AVERAGE filtering.
|
|
461
|
+
# This will change the pixelstream to have unfiltered values.
|
|
462
|
+
# @params (see #decode_png_str_scanline)
|
|
463
|
+
# @return [void]
|
|
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
|
|
471
|
+
|
|
472
|
+
# Decodes a scanline in a pixelstream that was encoded using PAETH filtering.
|
|
473
|
+
# This will change the pixelstream to have unfiltered values.
|
|
474
|
+
# @params (see #decode_png_str_scanline)
|
|
475
|
+
# @return [void]
|
|
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 = (pa <= pb) ? (pa <= pc ? a : c) : (pb <= pc ? b : c)
|
|
487
|
+
stream.setbyte(cur_pos, (stream.getbyte(cur_pos) + pr) & 0xff)
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
end
|