From d86bc80f430b5adeaae36f2242b10cad98900a05 Mon Sep 17 00:00:00 2001 From: Josh Holmer Date: Fri, 1 Feb 2019 17:27:03 -0500 Subject: [PATCH] Prepare for next release --- CHANGELOG.md | 7 ++ Cargo.lock | 115 +++++++++++----------- Cargo.toml | 7 +- benches/deflate.rs | 184 ++++++++++++++++++++++++++++++++---- src/colors.rs | 6 +- src/deflate/cfzlib.rs | 15 +-- src/deflate/miniz_stream.rs | 6 +- src/deflate/mod.rs | 17 +++- src/error.rs | 2 +- src/evaluate.rs | 89 +++++++++++------ src/filters.rs | 141 ++++++++++++++------------- src/headers.rs | 6 +- src/interlace.rs | 4 +- src/lib.rs | 85 +++++++++-------- src/main.rs | 4 - src/png/mod.rs | 50 +++++----- src/png/scan_lines.rs | 2 +- src/rayon.rs | 26 +++-- src/reduction/alpha.rs | 30 +++--- src/reduction/bit_depth.rs | 31 +++--- src/reduction/color.rs | 15 +-- src/reduction/mod.rs | 80 +++++++++------- tests/filters.rs | 2 +- tests/lib.rs | 2 +- tests/reduction.rs | 2 +- tests/regression.rs | 17 +++- 26 files changed, 593 insertions(+), 352 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 185914fb..e6e74be9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +### Version 2.2.0 + - Various internal improvements ([#154](https://github.com/shssoichiro/oxipng/pull/154)) ([#158](https://github.com/shssoichiro/oxipng/pull/158)) ([#160](https://github.com/shssoichiro/oxipng/pull/160)) ([#161](https://github.com/shssoichiro/oxipng/pull/161)) ([#162](https://github.com/shssoichiro/oxipng/pull/162)) ([#163](https://github.com/shssoichiro/oxipng/pull/163)) + - Update `image` crate to 0.21.0 + - Update `itertools` crate to 0.8.0 + - Update `zopfli` crate to 0.4.0 + - Use Rust edition 2018 + ### Version 2.1.8 - Fix non-standard sBIT headers in other code locations ([#153](https://github.com/shssoichiro/oxipng/issues/153)) diff --git a/Cargo.lock b/Cargo.lock index 00e84300..fdcfe114 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,8 +1,3 @@ -[[package]] -name = "adler32" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "adler32" version = "1.0.3" @@ -18,7 +13,7 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.4.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", @@ -29,7 +24,7 @@ name = "atty" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -51,17 +46,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "byteorder" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "byteorder" -version = "1.2.7" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cc" -version = "1.0.25" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -96,7 +86,7 @@ name = "cloudflare-zlib-sys" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -121,7 +111,7 @@ name = "crossbeam-epoch" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -144,7 +134,7 @@ version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -159,20 +149,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "image" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "inflate" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -180,7 +171,7 @@ dependencies = [ [[package]] name = "itertools" -version = "0.7.11" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -193,7 +184,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.2.44" +version = "0.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -208,7 +199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "miniz_oxide" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -252,10 +243,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -263,28 +254,28 @@ name = "oxipng" version = "2.1.8" dependencies = [ "bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "cloudflare-zlib 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "image 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rgb 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)", + "rgb 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)", "wild 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "zopfli 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "png" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", - "inflate 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -305,13 +296,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.43" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -319,12 +310,17 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rgb" -version = "0.8.11" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "safe-transmute" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -342,8 +338,8 @@ name = "termion" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -399,27 +395,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "zopfli" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "adler32 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "typed-arena 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [metadata] -"checksum adler32 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e928aa58f6dbd754bda26eca562a242549cb606e27a2240fc305fc75a7f12af9" "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum arrayvec 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f405cc4c21cd8b784f6c8fc2adf9bc00f59558f0049b5ec21517f875963040cc" +"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum bit-vec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4440d5cb623bb7390ae27fec0bb6c61111969860f8e3ae198bfa0663645e67cf" "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" "checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855" -"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d" -"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" +"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4a8b715cb4597106ea87c7c84b2f1d452c7492033765df7f32651e66fcf749" "checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum cloudflare-zlib 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cd97a72b7777ef134de513cef589e48c393dc2ea7180ff6dca87dcd3ee078dac" @@ -431,26 +425,27 @@ dependencies = [ "checksum deflate 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)" = "8a6abb26e16e8d419b5c78662aa9f82857c2386a073da266840e474d5055ec86" "checksum either 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" -"checksum image 0.20.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44665b4395d1844c96e7dc8ed5754782a1cdfd9ef458a80bbe45702681450504" -"checksum inflate 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6f53b811ee8e2057ccf9643ca6b4277de90efaf5e61e55fd5254576926bb4245" -"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" +"checksum image 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "52fb0666a1273dac46f9725aa4859bcd5595fc3554cf3495051b4de8db745e7d" +"checksum inflate 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84c683bde2d8413b8f1be3e459c30e4817672b6e7a31d9212b0323154e76eba7" +"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1" -"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311" +"checksum libc 0.2.48 (registry+https://github.com/rust-lang/crates.io-index)" = "e962c7641008ac010fa60a7dfdc1712449f29c44ef2d4702394aea943ee75047" "checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum miniz_oxide 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ad30a47319c16cde58d0314f5d98202a80c9083b5f61178457403dfb14e509c" +"checksum miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c468f2369f07d651a5d0bb2c9079f8488a66d5466efe42d0c5c6466edcb7f71e" "checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" "checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" -"checksum png 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f54b9600d584d3b8a739e1662a595fab051329eff43f20e7d8cc22872962145b" +"checksum num_cpus 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5a69d464bdc213aaaff628444e99578ede64e9c854025aa43b9796530afa9238" +"checksum png 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9adebf7fb91ccf5eac9da1a8e00e83cb8ae882c3e8d8e4ad59da73cb8c82a2c9" "checksum rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "373814f27745b2686b350dd261bfd24576a6fb0e2c5919b3a2b6005f820b0473" "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356" -"checksum redox_syscall 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "679da7508e9a6390aeaf7fbd02a800fdc64b73fe2204dd2c8ae66d22d9d5ad5d" +"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum rgb 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)" = "002bebda58b24482d6911a59512e8a17fa1defecf5a2162521113b7cc5422dd1" +"checksum rgb 0.8.12 (registry+https://github.com/rust-lang/crates.io-index)" = "6909f703ab5260012430324d5e8a5c74b26080597cd465d0bd1d2338d6b24ab7" +"checksum safe-transmute 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9604873ffe1980bc1f179103704a65c8aca141c248d9e52b7af95ff10578166e" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" @@ -462,4 +457,4 @@ dependencies = [ "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum zopfli 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9fd2fb70c78a87410032abe2a9eb2bec4984a2d9bc26adb1f8f768e02673e84e" +"checksum zopfli 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4079b79464426ade2a1b0177fb0ce8396ba6b4084267407e333573c666073964" diff --git a/Cargo.toml b/Cargo.toml index 870ab6fc..1e70eb06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ categories = [ ] description = "A lossless PNG compression optimizer" documentation = "https://docs.rs/oxipng" +edition = "2018" exclude = [ "tests/*", "bench/*", @@ -30,9 +31,9 @@ required-features = ["binary"] bit-vec = "^0.5.0" byteorder = "^1.0.0" crc = "^1.2.0" -itertools = "^0.7.7" +itertools = "^0.8.0" num_cpus = "^1.0.0" -zopfli = "^0.3.4" +zopfli = "^0.4.0" miniz_oxide = "0.2.0" rgb = "0.8.11" @@ -54,7 +55,7 @@ cloudflare-zlib = "^0.2.2" [dependencies.image] default-features = false features = ["png_codec"] -version = "^0.20.0" +version = "^0.21.0" [features] binary = [ diff --git a/benches/deflate.rs b/benches/deflate.rs index 378007e5..c1133bdc 100644 --- a/benches/deflate.rs +++ b/benches/deflate.rs @@ -3,10 +3,12 @@ extern crate oxipng; extern crate test; -use oxipng::internal_tests::*; use std::path::PathBuf; use test::Bencher; +use oxipng::internal_tests::*; +use oxipng::Deadline; + #[bench] fn deflate_16_bits_strategy_0(b: &mut Bencher) { let input = test::black_box(PathBuf::from("tests/files/rgb_16_should_be_rgb_16.png")); @@ -14,7 +16,14 @@ fn deflate_16_bits_strategy_0(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 0, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 0, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -25,7 +34,14 @@ fn deflate_8_bits_strategy_0(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 0, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 0, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -38,7 +54,14 @@ fn deflate_4_bits_strategy_0(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 0, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 0, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -51,7 +74,14 @@ fn deflate_2_bits_strategy_0(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 0, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 0, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -64,7 +94,14 @@ fn deflate_1_bits_strategy_0(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 0, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 0, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -75,7 +112,14 @@ fn deflate_16_bits_strategy_1(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 1, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 1, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -86,7 +130,14 @@ fn deflate_8_bits_strategy_1(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 1, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 1, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -99,7 +150,14 @@ fn deflate_4_bits_strategy_1(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 1, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 1, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -112,7 +170,14 @@ fn deflate_2_bits_strategy_1(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 1, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 1, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -125,7 +190,14 @@ fn deflate_1_bits_strategy_1(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 1, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 1, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -136,7 +208,14 @@ fn deflate_16_bits_strategy_2(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 2, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 2, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -147,7 +226,14 @@ fn deflate_8_bits_strategy_2(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 2, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 2, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -160,7 +246,14 @@ fn deflate_4_bits_strategy_2(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 2, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 2, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -173,7 +266,14 @@ fn deflate_2_bits_strategy_2(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 2, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 2, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -186,7 +286,14 @@ fn deflate_1_bits_strategy_2(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 2, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 2, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -197,7 +304,14 @@ fn deflate_16_bits_strategy_3(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 3, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 3, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -208,7 +322,14 @@ fn deflate_8_bits_strategy_3(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 3, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 3, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -221,7 +342,14 @@ fn deflate_4_bits_strategy_3(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 3, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 3, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -234,7 +362,14 @@ fn deflate_2_bits_strategy_3(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 3, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 3, + 15, + &min, + &Deadline::new(None, false), + ) }); } @@ -247,7 +382,14 @@ fn deflate_1_bits_strategy_3(b: &mut Bencher) { b.iter(|| { let min = AtomicMin::new(None); - deflate(png.raw.data.as_ref(), 9, 3, 15, &min) + deflate( + png.raw.data.as_ref(), + 9, + 3, + 15, + &min, + &Deadline::new(None, false), + ) }); } diff --git a/src/colors.rs b/src/colors.rs index 7e0644ae..615ee33f 100644 --- a/src/colors.rs +++ b/src/colors.rs @@ -17,7 +17,7 @@ pub enum ColorType { impl fmt::Display for ColorType { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}", @@ -73,7 +73,7 @@ pub enum BitDepth { impl fmt::Display for BitDepth { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}", @@ -127,7 +127,7 @@ pub enum AlphaOptim { } impl fmt::Display for AlphaOptim { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "{}", diff --git a/src/deflate/cfzlib.rs b/src/deflate/cfzlib.rs index bfa5979e..e2316f55 100644 --- a/src/deflate/cfzlib.rs +++ b/src/deflate/cfzlib.rs @@ -1,9 +1,9 @@ -use Deadline; -use atomicmin::AtomicMin; +use crate::atomicmin::AtomicMin; +use crate::Deadline; +use crate::PngError; +use crate::PngResult; pub use cloudflare_zlib::is_supported; use cloudflare_zlib::*; -use PngError; -use PngResult; impl From for PngError { fn from(err: ZError) -> Self { @@ -28,7 +28,7 @@ pub(crate) fn cfzlib_deflate( // max size is generally checked after each split, // so splitting the buffer into pieces gives more checks // = better chance of hitting it sooner. - let chunk_size = (data.len()/4).max(1<<15).min(1<<18); // 32-256KB + let chunk_size = (data.len() / 4).max(1 << 15).min(1 << 18); // 32-256KB for chunk in data.chunks(chunk_size) { stream.compress_with_limit(chunk, max_size)?; if deadline.passed() { @@ -47,7 +47,8 @@ fn compress_test() { 15, &AtomicMin::new(None), &Deadline::new(None, false), - ).unwrap(); - let res = ::deflate::inflate(&vec).unwrap(); + ) + .unwrap(); + let res = crate::deflate::inflate(&vec).unwrap(); assert_eq!(&res, b"azxcvbnm"); } diff --git a/src/deflate/miniz_stream.rs b/src/deflate/miniz_stream.rs index 34d6adde..82e7f21c 100644 --- a/src/deflate/miniz_stream.rs +++ b/src/deflate/miniz_stream.rs @@ -1,7 +1,7 @@ -use atomicmin::AtomicMin; -use error::PngError; +use crate::atomicmin::AtomicMin; +use crate::error::PngError; +use crate::PngResult; use miniz_oxide::deflate::core::*; -use PngResult; pub fn compress_to_vec_oxipng( input: &[u8], diff --git a/src/deflate/mod.rs b/src/deflate/mod.rs index 340eea2c..c04a8e4a 100644 --- a/src/deflate/mod.rs +++ b/src/deflate/mod.rs @@ -1,10 +1,10 @@ -use Deadline; -use atomicmin::AtomicMin; -use error::PngError; +use crate::atomicmin::AtomicMin; +use crate::error::PngError; +use crate::Deadline; +use crate::PngResult; use miniz_oxide; use std::cmp::max; use zopfli; -use PngResult; #[doc(hidden)] pub mod miniz_stream; @@ -26,7 +26,14 @@ pub fn inflate(data: &[u8]) -> PngResult> { } /// Compress a data stream using the DEFLATE algorithm -pub(crate) fn deflate(data: &[u8], zc: u8, zs: u8, zw: u8, max_size: &AtomicMin, deadline: &Deadline) -> PngResult> { +pub(crate) fn deflate( + data: &[u8], + zc: u8, + zs: u8, + zw: u8, + max_size: &AtomicMin, + deadline: &Deadline, +) -> PngResult> { #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] { if cfzlib::is_supported() { diff --git a/src/error.rs b/src/error.rs index 9f093b75..dc81cfa7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -26,7 +26,7 @@ impl Error for PngError { impl fmt::Display for PngError { #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { PngError::DeflatedDataTooLong(_) => f.write_str("deflated data too long"), PngError::TimedOut => f.write_str("timed out"), diff --git a/src/evaluate.rs b/src/evaluate.rs index 56352b05..3fb7890d 100644 --- a/src/evaluate.rs +++ b/src/evaluate.rs @@ -1,22 +1,28 @@ //! Check if a reduction makes file smaller, and keep best reductions. //! Works asynchronously when possible -use atomicmin::AtomicMin; +use crate::atomicmin::AtomicMin; +use crate::deflate; +use crate::png::PngData; +use crate::png::PngImage; +use crate::png::STD_COMPRESSION; +use crate::png::STD_FILTERS; +use crate::png::STD_STRATEGY; +use crate::png::STD_WINDOW; +#[cfg(not(feature = "parallel"))] +use crate::rayon; +#[cfg(not(feature = "parallel"))] +use crate::rayon::prelude::*; +use crate::Deadline; +#[cfg(feature = "parallel")] +use rayon; +#[cfg(feature = "parallel")] +use rayon::prelude::*; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering::SeqCst; -use deflate; -use Deadline; -use png::PngData; -use png::PngImage; -use png::STD_COMPRESSION; -use png::STD_FILTERS; -use png::STD_STRATEGY; -use png::STD_WINDOW; -use rayon::prelude::*; use std::sync::mpsc::*; use std::sync::Arc; use std::thread; -use rayon; struct Candidate { image: PngData, @@ -100,16 +106,20 @@ impl Evaluator { ) { best_candidate_size.set_min(idat_data.len()); // the rest is shipped to the evavluation/collection thread - eval_send.as_ref().expect("not finished yet").send(Candidate { - image: PngData { - idat_data, - raw: Arc::clone(&image), - }, - bias, - filter, - is_reduction, - nth, - }).expect("send"); + eval_send + .as_ref() + .expect("not finished yet") + .send(Candidate { + image: PngData { + idat_data, + raw: Arc::clone(&image), + }, + bias, + filter, + is_reduction, + nth, + }) + .expect("send"); } }); }); @@ -124,11 +134,33 @@ impl Evaluator { let is_best = if let Some(ref old) = best_result { // ordering is important - later file gets to use bias over earlier, but not the other way // (this way bias=0 replaces, but doesn't forbid later optimizations) - let new_len = (new.image.idat_data.len() as f64 * if new.nth > old.nth {new.bias as f64} else {1.0}) as usize; - let old_len = (old.image.idat_data.len() as f64 * if new.nth < old.nth {old.bias as f64} else {1.0}) as usize; + let new_len = (new.image.idat_data.len() as f64 + * if new.nth > old.nth { + f64::from(new.bias) + } else { + 1.0 + }) as usize; + let old_len = (old.image.idat_data.len() as f64 + * if new.nth < old.nth { + f64::from(old.bias) + } else { + 1.0 + }) as usize; // choose smallest compressed, or if compresses the same, smallest uncompressed, or cheaper filter - let new = (new_len, new.image.raw.data.len(), new.image.raw.ihdr.bit_depth, new.filter, new.nth); - let old = (old_len, old.image.raw.data.len(), old.image.raw.ihdr.bit_depth, old.filter, old.nth); + let new = ( + new_len, + new.image.raw.data.len(), + new.image.raw.ihdr.bit_depth, + new.filter, + new.nth, + ); + let old = ( + old_len, + old.image.raw.data.len(), + old.image.raw.ihdr.bit_depth, + old.filter, + old.nth, + ); // <= instead of < is important, because best_candidate_size has been set already, // so the current result may be comparing its size with itself new <= old @@ -136,14 +168,9 @@ impl Evaluator { true }; if is_best { - best_result = if new.is_reduction { - Some(new) - } else { - None - }; + best_result = if new.is_reduction { Some(new) } else { None }; } } best_result.map(|res| res.image) } } - diff --git a/src/filters.rs b/src/filters.rs index c0c321f4..875c3420 100644 --- a/src/filters.rs +++ b/src/filters.rs @@ -24,35 +24,40 @@ pub fn filter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> Vec ); }; } - 3 => for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp) { - Some(x) => byte.wrapping_sub(data[x] >> 1), - None => *byte, - }); - } else { - filtered.push(match i.checked_sub(bpp) { - Some(x) => byte - .wrapping_sub(((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8), - None => byte.wrapping_sub(last_line[i] >> 1), - }); - }; - }, - 4 => for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - filtered.push(match i.checked_sub(bpp) { - Some(x) => byte.wrapping_sub(data[x]), - None => *byte, - }); - } else { - filtered.push(match i.checked_sub(bpp) { - Some(x) => { - byte.wrapping_sub(paeth_predictor(data[x], last_line[i], last_line[x])) - } - None => byte.wrapping_sub(last_line[i]), - }); - }; - }, + 3 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + filtered.push(match i.checked_sub(bpp) { + Some(x) => byte.wrapping_sub(data[x] >> 1), + None => *byte, + }); + } else { + filtered.push(match i.checked_sub(bpp) { + Some(x) => byte.wrapping_sub( + ((u16::from(data[x]) + u16::from(last_line[i])) >> 1) as u8, + ), + None => byte.wrapping_sub(last_line[i] >> 1), + }); + }; + } + } + 4 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + filtered.push(match i.checked_sub(bpp) { + Some(x) => byte.wrapping_sub(data[x]), + None => *byte, + }); + } else { + filtered.push(match i.checked_sub(bpp) { + Some(x) => { + byte.wrapping_sub(paeth_predictor(data[x], last_line[i], last_line[x])) + } + None => byte.wrapping_sub(last_line[i]), + }); + }; + } + } _ => unreachable!(), } filtered @@ -64,17 +69,19 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> V 0 => { unfiltered.extend_from_slice(data); } - 1 => for (i, byte) in data.iter().enumerate() { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(b)); - } - None => { - unfiltered.push(*byte); - } - }; - }, + 1 => { + for (i, byte) in data.iter().enumerate() { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(b)); + } + None => { + unfiltered.push(*byte); + } + }; + } + } 2 => { if last_line.is_empty() { unfiltered.extend_from_slice(data); @@ -113,33 +120,35 @@ pub fn unfilter_line(filter: u8, bpp: usize, data: &[u8], last_line: &[u8]) -> V }; } } - 4 => for (i, byte) in data.iter().enumerate() { - if last_line.is_empty() { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(b)); - } - None => { - unfiltered.push(*byte); - } + 4 => { + for (i, byte) in data.iter().enumerate() { + if last_line.is_empty() { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(b)); + } + None => { + unfiltered.push(*byte); + } + }; + } else { + match i.checked_sub(bpp) { + Some(x) => { + let b = unfiltered[x]; + unfiltered.push(byte.wrapping_add(paeth_predictor( + b, + last_line[i], + last_line[x], + ))); + } + None => { + unfiltered.push(byte.wrapping_add(last_line[i])); + } + }; }; - } else { - match i.checked_sub(bpp) { - Some(x) => { - let b = unfiltered[x]; - unfiltered.push(byte.wrapping_add(paeth_predictor( - b, - last_line[i], - last_line[x], - ))); - } - None => { - unfiltered.push(byte.wrapping_add(last_line[i])); - } - }; - }; - }, + } + } _ => unreachable!(), } unfiltered diff --git a/src/headers.rs b/src/headers.rs index 4c0c340b..1667bdbf 100644 --- a/src/headers.rs +++ b/src/headers.rs @@ -1,10 +1,10 @@ +use crate::colors::{BitDepth, ColorType}; +use crate::error::PngError; +use crate::PngResult; use byteorder::{BigEndian, ReadBytesExt}; -use colors::{BitDepth, ColorType}; use crc::crc32; -use error::PngError; use std::collections::HashSet; use std::io::Cursor; -use PngResult; #[derive(Debug, Clone, Copy)] /// Headers from the IHDR chunk of the image diff --git a/src/interlace.rs b/src/interlace.rs index d7916e1a..5f2daccf 100644 --- a/src/interlace.rs +++ b/src/interlace.rs @@ -1,6 +1,6 @@ -use headers::IhdrData; +use crate::headers::IhdrData; +use crate::png::PngImage; use bit_vec::BitVec; -use png::PngImage; #[must_use] pub fn interlace_image(png: &PngImage) -> PngImage { diff --git a/src/lib.rs b/src/lib.rs index c5477d1f..49a0b06f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,28 +1,18 @@ -extern crate bit_vec; -extern crate byteorder; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] -extern crate cloudflare_zlib; -extern crate crc; -extern crate image; -extern crate itertools; -extern crate miniz_oxide; -extern crate num_cpus; +use num_cpus; #[cfg(feature = "parallel")] extern crate rayon; #[cfg(not(feature = "parallel"))] mod rayon; -extern crate rgb; -extern crate zopfli; -use reduction::*; -use atomicmin::AtomicMin; +use crate::atomicmin::AtomicMin; +use crate::colors::BitDepth; +use crate::deflate::inflate; +use crate::evaluate::Evaluator; +use crate::png::PngData; +use crate::png::PngImage; +use crate::reduction::*; use crc::crc32; -use deflate::inflate; -use evaluate::Evaluator; use image::{DynamicImage, GenericImageView, ImageFormat, Pixel}; -use png::PngImage; -use png::PngData; -use colors::BitDepth; use rayon::prelude::*; use std::collections::{HashMap, HashSet}; use std::fmt; @@ -30,13 +20,13 @@ use std::fs::{copy, File}; use std::io::{stdin, stdout, BufWriter, Read, Write}; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; -use std::time::{Duration, Instant}; use std::sync::Arc; +use std::time::{Duration, Instant}; -pub use colors::AlphaOptim; -pub use deflate::Deflaters; -pub use error::PngError; -pub use headers::Headers; +pub use crate::colors::AlphaOptim; +pub use crate::deflate::Deflaters; +pub use crate::error::PngError; +pub use crate::headers::Headers; mod atomicmin; mod colors; @@ -52,11 +42,11 @@ mod reduction; /// Private to oxipng; don't use outside tests and benches #[doc(hidden)] pub mod internal_tests { - pub use atomicmin::*; - pub use colors::*; - pub use deflate::*; - pub use headers::*; - pub use png::*; + pub use crate::atomicmin::*; + pub use crate::colors::*; + pub use crate::deflate::*; + pub use crate::headers::*; + pub use crate::png::*; } #[derive(Clone, Debug)] @@ -92,7 +82,7 @@ impl InFile { } impl fmt::Display for InFile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { InFile::Path(ref p) => write!(f, "{}", p.display()), InFile::StdIn => f.write_str("stdin"), @@ -465,7 +455,12 @@ struct TrialOptions { } /// Perform optimization on the input PNG object using the options provided -fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options, deadline: Arc) -> PngResult> { +fn optimize_png( + png: &mut PngData, + original_data: &[u8], + opts: &Options, + deadline: Arc, +) -> PngResult> { type TrialWithData = (TrialOptions, Vec); let original_png = png.clone(); @@ -582,7 +577,8 @@ fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options, deadlin .map(|f| { let png = png.clone(); (*f, png.raw.filter_image(*f)) - }).collect(); + }) + .collect(); let original_len = original_png.idat_data.len(); let added_interlacing = opts.interlace == Some(1) && original_png.raw.ihdr.interlaced == 0; @@ -639,9 +635,8 @@ fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options, deadlin None } }); - let best: Option = best.reduce_with(|i, j| { - if i.1.len() <= j.1.len() { i } else { j } - }); + let best: Option = + best.reduce_with(|i, j| if i.1.len() <= j.1.len() { i } else { j }); if let Some(better) = best { png.idat_data = better.1; @@ -698,7 +693,7 @@ fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options, deadlin let (old_png, new_png) = rayon::join( || image::load_from_memory_with_format(original_data, ImageFormat::PNG), - || image::load_from_memory_with_format(&output, ImageFormat::PNG) + || image::load_from_memory_with_format(&output, ImageFormat::PNG), ); if let Ok(new_png) = new_png { @@ -720,8 +715,12 @@ fn optimize_png(png: &mut PngData, original_data: &[u8], opts: &Options, deadlin Err(PngError::new("The resulting image is corrupted")) } -fn perform_reductions(mut png: Arc, opts: &Options, deadline: &Deadline, eval: &Evaluator) { - +fn perform_reductions( + mut png: Arc, + opts: &Options, + deadline: &Deadline, + eval: &Evaluator, +) { // must be done first to evaluate rest with the correct interlacing if let Some(interlacing) = opts.interlace { if let Some(reduced) = png.change_interlacing(interlacing) { @@ -752,7 +751,9 @@ fn perform_reductions(mut png: Arc, opts: &Options, deadline: &Deadlin let bits = reduced.ihdr.bit_depth; png = Arc::new(reduced); eval.try_image(png.clone(), 1.0); - if (bits == BitDepth::One || bits == BitDepth::Two) && previous.ihdr.bit_depth != BitDepth::Four { + if (bits == BitDepth::One || bits == BitDepth::Two) + && previous.ihdr.bit_depth != BitDepth::Four + { // Also try 16-color mode for all lower bits images, since that may compress better if let Some(reduced) = reduce_bit_depth(&previous, 4) { eval.try_image(Arc::new(reduced), 0.98); @@ -848,9 +849,11 @@ fn perform_strip(png: &mut PngData, opts: &Options) { .map_or(false, |name| hdrs.contains(name)) }); } - Headers::Strip(ref hdrs) => for hdr in hdrs { - raw.aux_headers.remove(hdr.as_bytes()); - }, + Headers::Strip(ref hdrs) => { + for hdr in hdrs { + raw.aux_headers.remove(hdr.as_bytes()); + } + } Headers::Safe => { const PRESERVED_HEADERS: [[u8; 4]; 9] = [ *b"cHRM", *b"gAMA", *b"iCCP", *b"sBIT", *b"sRGB", *b"bKGD", *b"hIST", *b"pHYs", diff --git a/src/main.rs b/src/main.rs index f83812ae..a83ea18c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,6 @@ #![warn(trivial_casts, trivial_numeric_casts, unused_import_braces)] #![deny(missing_debug_implementations, missing_copy_implementations)] -extern crate clap; -extern crate oxipng; -extern crate wild; - use clap::{App, AppSettings, Arg, ArgMatches}; use oxipng::AlphaOptim; use oxipng::Deflaters; diff --git a/src/png/mod.rs b/src/png/mod.rs index d9ebd764..6d46670e 100644 --- a/src/png/mod.rs +++ b/src/png/mod.rs @@ -1,11 +1,11 @@ +use crate::colors::ColorType; +use crate::deflate; +use crate::error::PngError; +use crate::filters::*; +use crate::headers::*; +use crate::interlace::{deinterlace_image, interlace_image}; use byteorder::{BigEndian, WriteBytesExt}; -use colors::ColorType; use crc::crc32; -use deflate; -use error::PngError; -use filters::*; -use headers::*; -use interlace::{deinterlace_image, interlace_image}; use rgb::ComponentSlice; use rgb::RGBA8; use std::collections::HashMap; @@ -180,7 +180,8 @@ impl PngData { let _ = ihdr_data.write_u8(self.raw.ihdr.interlaced); write_png_block(b"IHDR", &ihdr_data, &mut output); // Ancillary headers - for (key, header) in self.raw + for (key, header) in self + .raw .aux_headers .iter() .filter(|&(key, _)| !(key == b"bKGD" || key == b"hIST" || key == b"tRNS")) @@ -196,16 +197,20 @@ impl PngData { } write_png_block(b"PLTE", &palette_data, &mut output); let num_transparent = - palette.iter().take(max_palette_size).enumerate().fold( - 0, - |prev, (index, px)| { - if px.a != 255 { - index + 1 - } else { - prev - } - }, - ); + palette + .iter() + .take(max_palette_size) + .enumerate() + .fold( + 0, + |prev, (index, px)| { + if px.a != 255 { + index + 1 + } else { + prev + } + }, + ); if num_transparent > 0 { let trns_data: Vec<_> = palette[0..num_transparent].iter().map(|px| px.a).collect(); write_png_block(b"tRNS", &trns_data, &mut output); @@ -215,7 +220,8 @@ impl PngData { write_png_block(b"tRNS", transparency_pixel, &mut output); } // Special ancillary headers that need to come after PLTE but before IDAT - for (key, header) in self.raw + for (key, header) in self + .raw .aux_headers .iter() .filter(|&(key, _)| key == b"bKGD" || key == b"hIST" || key == b"tRNS") @@ -232,7 +238,6 @@ impl PngData { } impl PngImage { - /// Convert the image to the specified interlacing type /// Returns true if the interlacing was changed, false otherwise /// The `interlace` parameter specifies the *new* interlacing mode @@ -261,13 +266,13 @@ impl PngImage { /// Return an iterator over the scanlines of the image #[inline] - pub fn scan_lines(&self) -> ScanLines { + pub fn scan_lines(&self) -> ScanLines<'_> { ScanLines::new(self) } /// Return an iterator over the scanlines of the image #[inline] - pub fn scan_lines_mut(&mut self) -> ScanLinesMut { + pub fn scan_lines_mut(&mut self) -> ScanLinesMut<'_> { ScanLinesMut::new(self) } @@ -331,7 +336,8 @@ impl PngImage { let signed = x as i8; acc + i16::from(signed).abs() as u64 }) - }).unwrap(); + }) + .unwrap(); filtered.push(*best_filter); filtered.extend_from_slice(best_line); } diff --git a/src/png/scan_lines.rs b/src/png/scan_lines.rs index 0b1a6f30..38f98e0f 100644 --- a/src/png/scan_lines.rs +++ b/src/png/scan_lines.rs @@ -1,4 +1,4 @@ -use png::PngImage; +use crate::png::PngImage; #[derive(Debug, Clone)] /// An iterator over the scan lines of a PNG image diff --git a/src/rayon.rs b/src/rayon.rs index 0a5f1cab..c0ffd8c5 100644 --- a/src/rayon.rs +++ b/src/rayon.rs @@ -3,8 +3,13 @@ pub mod prelude { } pub trait ParallelIterator: Iterator + Sized { - fn with_max_len(self, _l: usize) -> Self {self} - fn reduce_with(mut self, op: OP) -> Option where OP: Fn(Self::Item, Self::Item) -> Self::Item + Sync { + fn with_max_len(self, _l: usize) -> Self { + self + } + fn reduce_with(mut self, op: OP) -> Option + where + OP: Fn(Self::Item, Self::Item) -> Self::Item + Sync, + { if let Some(a) = self.next() { Some(self.fold(a, op)) } else { @@ -14,18 +19,21 @@ pub trait ParallelIterator: Iterator + Sized { } pub trait IntoParallelIterator { - type Iter: Iterator; + type Iter: Iterator; type Item: Send; fn into_par_iter(self) -> Self::Iter; } pub trait IntoParallelRefIterator<'data> { - type Iter: Iterator; + type Iter: Iterator; type Item: Send + 'data; fn par_iter(&'data self) -> Self::Iter; } -impl IntoParallelIterator for I where I::Item: Send { +impl IntoParallelIterator for I +where + I::Item: Send, +{ type Iter = I::IntoIter; type Item = I::Item; @@ -35,7 +43,8 @@ impl IntoParallelIterator for I where I::Item: Send { } impl<'data, I: 'data + ?Sized> IntoParallelRefIterator<'data> for I - where &'data I: IntoParallelIterator +where + &'data I: IntoParallelIterator, { type Iter = <&'data I as IntoParallelIterator>::Iter; type Item = <&'data I as IntoParallelIterator>::Item; @@ -45,13 +54,12 @@ impl<'data, I: 'data + ?Sized> IntoParallelRefIterator<'data> for I } } -impl ParallelIterator for I { -} +impl ParallelIterator for I {} pub fn join(a: impl FnOnce() -> A, b: impl FnOnce() -> B) -> (A, B) { (a(), b()) } -pub fn spawn(a: impl FnOnce() -> A) -> A { +pub fn spawn(a: impl FnOnce() -> A) -> A { a() } diff --git a/src/reduction/alpha.rs b/src/reduction/alpha.rs index b620a5a5..089f7cc3 100644 --- a/src/reduction/alpha.rs +++ b/src/reduction/alpha.rs @@ -1,15 +1,21 @@ -use evaluate::Evaluator; -use itertools::flatten; -use png::scan_lines::ScanLine; +use crate::colors::AlphaOptim; +use crate::colors::ColorType; +use crate::evaluate::Evaluator; +use crate::headers::IhdrData; +use crate::png::scan_lines::ScanLine; +use crate::png::PngImage; +#[cfg(not(feature = "parallel"))] +use crate::rayon::prelude::*; +#[cfg(feature = "parallel")] +use rayon::prelude::*; use std::collections::HashSet; use std::sync::Arc; -use colors::AlphaOptim; -use headers::IhdrData; -use png::PngImage; -use colors::ColorType; -use rayon::prelude::*; -pub(crate) fn try_alpha_reductions(png: Arc, alphas: &HashSet, eval: &Evaluator) { +pub(crate) fn try_alpha_reductions( + png: Arc, + alphas: &HashSet, + eval: &Evaluator, +) { assert!(!alphas.is_empty()); let alphas = alphas.iter().collect::>(); let alphas_iter = alphas.par_iter().with_max_len(1); @@ -88,7 +94,7 @@ fn reduced_alpha_to_white(png: &PngImage, bpc: usize, bpp: usize) -> Vec { fn reduced_alpha_to_up(png: &PngImage, bpc: usize, bpp: usize) -> Vec { let mut lines = Vec::new(); - let mut scan_lines = png.scan_lines().collect::>(); + let mut scan_lines = png.scan_lines().collect::>>(); scan_lines.reverse(); let mut last_line = Vec::new(); let mut current_line = Vec::with_capacity(last_line.len()); @@ -111,7 +117,7 @@ fn reduced_alpha_to_up(png: &PngImage, bpc: usize, bpp: usize) -> Vec { lines.push(current_line.clone()); current_line.clear(); } - flatten(lines.into_iter().rev()).collect() + lines.into_iter().rev().flatten().collect() } fn reduced_alpha_to_down(png: &PngImage, bpc: usize, bpp: usize) -> Vec { @@ -154,7 +160,7 @@ fn reduced_alpha_to_left(png: &PngImage, bpc: usize, bpp: usize) -> Vec { last_pixel = pixel.to_owned(); } reduced.push(line.filter); - reduced.extend(flatten(line_bytes.chunks(bpp).rev())); + reduced.extend(line_bytes.chunks(bpp).rev().flatten()); } reduced } diff --git a/src/reduction/bit_depth.rs b/src/reduction/bit_depth.rs index 491a2183..262357b0 100644 --- a/src/reduction/bit_depth.rs +++ b/src/reduction/bit_depth.rs @@ -1,7 +1,7 @@ -use headers::IhdrData; +use crate::colors::{BitDepth, ColorType}; +use crate::headers::IhdrData; +use crate::png::PngImage; use bit_vec::BitVec; -use colors::{BitDepth, ColorType}; -use png::PngImage; const ONE_BIT_PERMUTATIONS: [u8; 2] = [0b0000_0000, 0b1111_1111]; const TWO_BIT_PERMUTATIONS: [u8; 5] = [ @@ -30,8 +30,7 @@ const FOUR_BIT_PERMUTATIONS: [u8; 11] = [ #[must_use] pub fn reduce_bit_depth(png: &PngImage, minimum_bits: usize) -> Option { if png.ihdr.bit_depth != BitDepth::Sixteen { - if png.ihdr.color_type == ColorType::Indexed - || png.ihdr.color_type == ColorType::Grayscale + if png.ihdr.color_type == ColorType::Indexed || png.ihdr.color_type == ColorType::Grayscale { return reduce_bit_depth_8_or_less(png, minimum_bits); } @@ -40,8 +39,8 @@ pub fn reduce_bit_depth(png: &PngImage, minimum_bits: usize) -> Option // Reduce from 16 to 8 bits per channel per pixel let mut reduced = Vec::with_capacity( - (png.ihdr.width * png.ihdr.height * u32::from(png.channels_per_pixel()) - + png.ihdr.height) as usize, + (png.ihdr.width * png.ihdr.height * u32::from(png.channels_per_pixel()) + png.ihdr.height) + as usize, ); let mut high_byte = 0; @@ -84,17 +83,25 @@ pub fn reduce_bit_depth_8_or_less(png: &PngImage, mut minimum_bits: usize) -> Op } for line in png.scan_lines() { if png.ihdr.color_type == ColorType::Indexed { - let line_max = line.data.iter().map(|&byte| match png.ihdr.bit_depth { - BitDepth::Two => (byte & 0x3).max((byte >> 2) & 0x3).max((byte >> 4) & 0x3).max(byte >> 6), + let line_max = line + .data + .iter() + .map(|&byte| match png.ihdr.bit_depth { + BitDepth::Two => (byte & 0x3) + .max((byte >> 2) & 0x3) + .max((byte >> 4) & 0x3) + .max(byte >> 6), BitDepth::Four => (byte & 0xF).max(byte >> 4), - _ => byte, - }).max().unwrap_or(0); + _ => byte, + }) + .max() + .unwrap_or(0); let required_bits = match line_max { x if x > 0x0F => 8, x if x > 0x03 => 4, x if x > 0x01 => 2, _ => 1, - }; + }; if required_bits > minimum_bits { minimum_bits = required_bits; if minimum_bits >= bit_depth { diff --git a/src/reduction/color.rs b/src/reduction/color.rs index abebf38a..bd692dc8 100644 --- a/src/reduction/color.rs +++ b/src/reduction/color.rs @@ -1,7 +1,7 @@ -use headers::IhdrData; -use colors::{BitDepth, ColorType}; +use crate::colors::{BitDepth, ColorType}; +use crate::headers::IhdrData; +use crate::png::PngImage; use itertools::Itertools; -use png::PngImage; use rgb::{FromSlice, RGB8, RGBA8}; use std::collections::HashMap; use std::hash::Hash; @@ -145,7 +145,8 @@ pub fn reduced_color_to_palette(png: &PngImage) -> Option { } else { None } - }).max(); + }) + .max(); let trns_size = num_transparent.map(|n| n + 8).unwrap_or(0); let headers_size = palette.len() * 3 + 8 + trns_size; @@ -212,9 +213,9 @@ pub fn reduce_rgb_to_grayscale(png: &PngImage) -> Option { } else { let pixel_bytes = cur_pixel .iter() - .step(2) + .step_by(2) .cloned() - .zip(cur_pixel.iter().skip(1).step(2).cloned()) + .zip(cur_pixel.iter().skip(1).step_by(2).cloned()) .unique() .collect::>(); if pixel_bytes.len() > 1 { @@ -254,7 +255,7 @@ pub fn reduce_rgb_to_grayscale(png: &PngImage) -> Option { data: reduced, ihdr: IhdrData { color_type: ColorType::Grayscale, - .. png.ihdr + ..png.ihdr }, aux_headers, palette: None, diff --git a/src/reduction/mod.rs b/src/reduction/mod.rs index 9ad245d7..8401b539 100644 --- a/src/reduction/mod.rs +++ b/src/reduction/mod.rs @@ -1,20 +1,20 @@ -use headers::IhdrData; -use std::collections::HashMap; -use colors::{BitDepth, ColorType}; -use std::collections::hash_map::Entry::*; -use png::PngImage; +use crate::colors::{BitDepth, ColorType}; +use crate::headers::IhdrData; +use crate::png::PngImage; use rgb::RGBA8; use std::borrow::Cow; +use std::collections::hash_map::Entry::*; +use std::collections::HashMap; pub mod alpha; -use alpha::*; +use crate::alpha::*; pub mod bit_depth; -use bit_depth::*; +use crate::bit_depth::*; pub mod color; -use color::*; +use crate::color::*; -pub(crate) use bit_depth::reduce_bit_depth; -pub(crate) use alpha::try_alpha_reductions; +pub(crate) use crate::alpha::try_alpha_reductions; +pub(crate) use crate::bit_depth::reduce_bit_depth; /// Attempt to reduce the number of colors in the palette /// Returns `None` if palette hasn't changed @@ -38,33 +38,41 @@ pub fn reduced_palette(png: &PngImage) -> Option { // Find palette entries that are never used for line in png.scan_lines() { match png.ihdr.bit_depth { - BitDepth::Eight => for &byte in line.data { - used[byte as usize] = true; - }, - BitDepth::Four => for &byte in line.data { - used[(byte & 0x0F) as usize] = true; - used[(byte >> 4) as usize] = true; - }, - BitDepth::Two => for &byte in line.data { - used[(byte & 0x03) as usize] = true; - used[((byte >> 2) & 0x03) as usize] = true; - used[((byte >> 4) & 0x03) as usize] = true; - used[(byte >> 6) as usize] = true; - }, + BitDepth::Eight => { + for &byte in line.data { + used[byte as usize] = true; + } + } + BitDepth::Four => { + for &byte in line.data { + used[(byte & 0x0F) as usize] = true; + used[(byte >> 4) as usize] = true; + } + } + BitDepth::Two => { + for &byte in line.data { + used[(byte & 0x03) as usize] = true; + used[((byte >> 2) & 0x03) as usize] = true; + used[((byte >> 4) & 0x03) as usize] = true; + used[(byte >> 6) as usize] = true; + } + } _ => unreachable!(), } } let mut next_index = 0u16; let mut seen = HashMap::with_capacity(palette.len()); - for (i, (used, palette_map)) in - used.iter().cloned().zip(palette_map.iter_mut()).enumerate() + for (i, (used, palette_map)) in used.iter().cloned().zip(palette_map.iter_mut()).enumerate() { if !used { continue; } // There are invalid files that use pixel indices beyond palette size - let color = palette.get(i).cloned().unwrap_or(RGBA8::new(0, 0, 0, 255)); + let color = palette + .get(i) + .cloned() + .unwrap_or_else(|| RGBA8::new(0, 0, 0, 255)); match seen.entry(color) { Vacant(new) => { *palette_map = Some(next_index as u8); @@ -96,7 +104,10 @@ fn do_palette_reduction(png: &PngImage, palette_map: &[Option; 256]) -> Opti let mut aux_headers = png.aux_headers.clone(); if let Some(bkgd_header) = png.aux_headers.get(b"bKGD") { - if let Some(Some(map_to)) = bkgd_header.get(0).and_then(|&idx| palette_map.get(idx as usize)) { + if let Some(Some(map_to)) = bkgd_header + .get(0) + .and_then(|&idx| palette_map.get(idx as usize)) + { aux_headers.insert(*b"bKGD", vec![*map_to]); } } @@ -146,11 +157,13 @@ fn palette_map_to_byte_map(png: &PngImage, palette_map: &[Option; 256]) -> O _ => {} } - return Some(byte_map) + Some(byte_map) } fn reordered_palette(palette: &[RGBA8], palette_map: &[Option; 256]) -> Vec { - let max_index = palette_map.iter().cloned() + let max_index = palette_map + .iter() + .cloned() .filter_map(|x| x) .max() .unwrap_or(0) as usize; @@ -163,7 +176,6 @@ fn reordered_palette(palette: &[RGBA8], palette_map: &[Option; 256]) -> Vec< new_palette } - /// Attempt to reduce the color type of the image /// Returns true if the color type was reduced, false otherwise pub fn reduce_color_type(png: &PngImage) -> Option { @@ -173,7 +185,9 @@ pub fn reduce_color_type(png: &PngImage) -> Option { // Go down one step at a time // Maybe not the most efficient, but it's safe if reduced.ihdr.color_type == ColorType::RGBA { - if let Some(r) = reduce_rgba_to_grayscale_alpha(&reduced).or_else(|| reduced_alpha_channel(&reduced)) { + if let Some(r) = + reduce_rgba_to_grayscale_alpha(&reduced).or_else(|| reduced_alpha_channel(&reduced)) + { reduced = Cow::Owned(r); } else if let Some(r) = reduced_color_to_palette(&reduced) { reduced = Cow::Owned(r); @@ -189,7 +203,9 @@ pub fn reduce_color_type(png: &PngImage) -> Option { } if reduced.ihdr.color_type == ColorType::RGB { - if let Some(r) = reduce_rgb_to_grayscale(&reduced).or_else(|| reduced_color_to_palette(&reduced)) { + if let Some(r) = + reduce_rgb_to_grayscale(&reduced).or_else(|| reduced_color_to_palette(&reduced)) + { reduced = Cow::Owned(r); should_reduce_bit_depth = true; } diff --git a/tests/filters.rs b/tests/filters.rs index 82d2b6d7..3bc4e56e 100644 --- a/tests/filters.rs +++ b/tests/filters.rs @@ -1,4 +1,4 @@ -extern crate oxipng; +use oxipng; use oxipng::internal_tests::*; use oxipng::{InFile, OutFile}; diff --git a/tests/lib.rs b/tests/lib.rs index 06df94ad..a97cd27e 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,4 +1,4 @@ -extern crate oxipng; +use oxipng; use oxipng::Headers; use oxipng::OutFile; diff --git a/tests/reduction.rs b/tests/reduction.rs index a9e5f947..d3b5cc5a 100644 --- a/tests/reduction.rs +++ b/tests/reduction.rs @@ -1,4 +1,4 @@ -extern crate oxipng; +use oxipng; use oxipng::internal_tests::*; use oxipng::{InFile, OutFile}; diff --git a/tests/regression.rs b/tests/regression.rs index e53ba734..70b13cdc 100644 --- a/tests/regression.rs +++ b/tests/regression.rs @@ -1,4 +1,4 @@ -extern crate oxipng; +use oxipng; use oxipng::internal_tests::*; use oxipng::{InFile, OutFile}; @@ -33,7 +33,10 @@ fn test_it_converts( let (output, opts) = custom.unwrap_or_else(|| get_opts(&input)); let png = PngData::new(&input, opts.fix_errors).unwrap(); - assert_eq!(png.raw.ihdr.color_type, color_type_in, "test file is broken"); + assert_eq!( + png.raw.ihdr.color_type, color_type_in, + "test file is broken" + ); assert_eq!(png.raw.ihdr.bit_depth, bit_depth_in, "test file is broken"); match oxipng::optimize(&InFile::Path(input), &output, &opts) { @@ -51,8 +54,14 @@ fn test_it_converts( } }; - assert_eq!(png.raw.ihdr.color_type, color_type_out, "optimized to wrong color type"); - assert_eq!(png.raw.ihdr.bit_depth, bit_depth_out, "optimized to wrong bit depth"); + assert_eq!( + png.raw.ihdr.color_type, color_type_out, + "optimized to wrong color type" + ); + assert_eq!( + png.raw.ihdr.bit_depth, bit_depth_out, + "optimized to wrong bit depth" + ); if let Some(palette) = png.raw.palette.as_ref() { assert!(palette.len() <= 1 << (png.raw.ihdr.bit_depth.as_u8() as usize)); } else {