bench9000 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|