Verify images are correct before outputting them, and fix a bug in certain images
Closes #60
This commit is contained in:
parent
c79ba3ab8a
commit
6c8e7d253d
14 changed files with 157 additions and 237 deletions
|
|
@ -1,3 +1,7 @@
|
|||
**Version 0.15.0 (unreleased)**
|
||||
- [SEMVER_MINOR] Check images for correctness before writing result ([#60](https://github.com/shssoichiro/oxipng/issues/60))
|
||||
- Fix invalid output when reducing image to a different color type but file size does not improve ([#60](https://github.com/shssoichiro/oxipng/issues/60))
|
||||
|
||||
**Version 0.14.4**
|
||||
- Fix bug when reducing RGBA to Indexed if image has 256 colors plus a background color
|
||||
|
||||
|
|
|
|||
122
Cargo.lock
generated
122
Cargo.lock
generated
|
|
@ -5,13 +5,13 @@ dependencies = [
|
|||
"bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.118 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crc 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zopfli 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -24,7 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "0.3.0"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -65,8 +65,8 @@ name = "cargo_metadata"
|
|||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -87,22 +87,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clippy"
|
||||
version = "0.0.114"
|
||||
version = "0.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cargo_metadata 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy_lints 0.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy_lints 0.0.118 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clippy_lints"
|
||||
version = "0.0.114"
|
||||
version = "0.0.118"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -112,15 +112,15 @@ name = "crc"
|
|||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deflate"
|
||||
version = "0.7.4"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -203,12 +203,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.2"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.20"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -221,7 +221,7 @@ name = "memchr"
|
|||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -230,14 +230,9 @@ version = "0.1.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.33"
|
||||
|
|
@ -271,10 +266,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.2.1"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -283,7 +278,7 @@ version = "0.6.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"deflate 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"deflate 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"inflate 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
@ -295,7 +290,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -303,7 +298,7 @@ name = "rand"
|
|||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -312,8 +307,8 @@ version = "0.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -342,33 +337,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.2.3"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.9.9"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_codegen_internals"
|
||||
version = "0.14.0"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "0.9.9"
|
||||
version = "0.9.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen_internals 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -379,7 +379,7 @@ dependencies = [
|
|||
"dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -394,17 +394,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.11.6"
|
||||
version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "synom"
|
||||
version = "0.11.0"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -416,7 +416,7 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
|
@ -426,7 +426,7 @@ version = "3.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -511,7 +511,7 @@ dependencies = [
|
|||
|
||||
[metadata]
|
||||
"checksum adler32 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e928aa58f6dbd754bda26eca562a242549cb606e27a2240fc305fc75a7f12af9"
|
||||
"checksum adler32 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57be033eb4100070a93a9400a725839cda9c415244f808b0357e72b9e003d5ba"
|
||||
"checksum adler32 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ff33fe13a08dbce05bcefa2c68eea4844941437e33d6f808240b54d7157b9cd"
|
||||
"checksum aho-corasick 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0638fd549427caa90c499814196d1b9e3725eb4d15d7339d6de073a680ed0ca2"
|
||||
"checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6"
|
||||
"checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d"
|
||||
|
|
@ -520,10 +520,10 @@ dependencies = [
|
|||
"checksum byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c40977b0ee6b9885c9013cd41d9feffdd22deb3bb4dc3a71d901cc7a77de18c8"
|
||||
"checksum cargo_metadata 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "34fdab49a2904acb112c83b62f0118de3de3ce28e52a9188dec2858e43878f25"
|
||||
"checksum clap 2.20.5 (registry+https://github.com/rust-lang/crates.io-index)" = "7db281b0520e97fbd15cd615dcd8f8bcad0c26f5f7d5effe705f090f39e9a758"
|
||||
"checksum clippy 0.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "808f9027f62dda9f764f26542a10465a6db221a5bd57981a63a2f84a6518b098"
|
||||
"checksum clippy_lints 0.0.114 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d58f7fdb30f25e6c4dac79d0156bec6fb69834ba270dc2dc2e12754cebef75"
|
||||
"checksum clippy 0.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "6cb0894ce1af2464033706bf9b33e28c4a8fc72df8449fcd60f7a5162a7a9630"
|
||||
"checksum clippy_lints 0.0.118 (registry+https://github.com/rust-lang/crates.io-index)" = "67d4bf7c7bb21b11b4d62146bcc8abaaf4e230a6346a21c9e88fa0c3540c71a4"
|
||||
"checksum crc 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc1914fae6f18ae347320f0ba5e4fc270e17c037ea621fe41ec7e8adf67d11b0"
|
||||
"checksum deflate 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "24c5f3de3a8e183ab9a169654b652407e5e80bed40986bcca92c2b088b9bfa80"
|
||||
"checksum deflate 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebb02aaf4b775afc96684b8402510a338086974e38570a1f65bea8c202eb77a7"
|
||||
"checksum deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1614659040e711785ed8ea24219140654da1729f3ec8a47a9719d041112fe7bf"
|
||||
"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
|
||||
"checksum either 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "63f94a35a9ca0d4178e85f0250373f2cea55c5d603e6993778d68a99b3d8071c"
|
||||
|
|
@ -535,34 +535,34 @@ dependencies = [
|
|||
"checksum itertools 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d95557e7ba6b71377b0f2c3b3ae96c53f1b75a926a6901a500f557a370af730a"
|
||||
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
|
||||
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
"checksum lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6abe0ee2e758cd6bc8a2cd56726359007748fbf4128da998b65d0b70f881e19b"
|
||||
"checksum libc 0.2.20 (registry+https://github.com/rust-lang/crates.io-index)" = "684f330624d8c3784fb9558ca46c4ce488073a8d22450415c5eb4f4cfb0d11b5"
|
||||
"checksum lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7291b1dd97d331f752620b02dfdbc231df7fc01bf282a00769e1cdb963c460dc"
|
||||
"checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135"
|
||||
"checksum matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efd7622e3022e1a6eaa602c4cea8912254e5582c9c692e9167714182244801b1"
|
||||
"checksum memchr 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1dbccc0e46f1ea47b9f17e6d67c5a96bd27030519c519c9c91327e31275a47b4"
|
||||
"checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726"
|
||||
"checksum nom 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b8c256fd9471521bcb84c3cdba98921497f1a331cbc15b8030fc63b82050ce"
|
||||
"checksum num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "21e4df1098d1d797d27ef0c69c178c3fab64941559b290fcae198e0825c9c8b5"
|
||||
"checksum num-iter 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d1891bd7b936f12349b7d1403761c8a0b85a18b148e9da4429d5d102c1a41e"
|
||||
"checksum num-rational 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "c2dc5ea04020a8f18318ae485c751f8cfa1c0e69dcf465c29ddaaa64a313cc44"
|
||||
"checksum num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "e1cbfa3781f3fe73dc05321bed52a06d2d491eaa764c52335cf4399f046ece99"
|
||||
"checksum num_cpus 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a225d1e2717567599c24f88e49f00856c6e825a12125181ee42c4257e3688d39"
|
||||
"checksum num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18c392466409c50b87369414a2680c93e739aedeb498eb2bff7d7eb569744e2"
|
||||
"checksum png 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3cb773e9a557edb568ce9935cf783e3cdcabe06a9449d41b3e5506d88e582c82"
|
||||
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
|
||||
"checksum quote 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "08de3f12e670f83f61e450443cbae34496a35b665691fd8e99b24ec662f75865"
|
||||
"checksum quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7375cf7ad34a92e8fd18dd9c42f58b9a11def59ab48bec955bf359a788335592"
|
||||
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
||||
"checksum rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50c575b58c2b109e2fbc181820cbe177474f35610ff9e357dc75f6bac854ffbf"
|
||||
"checksum regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4278c17d0f6d62dfef0ab00028feb45bd7d2102843f80763474eeb1be8a10c01"
|
||||
"checksum regex-syntax 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9191b1f57603095f105d317e375d19b1c9c5c3185ea9633a99a6dcbed04457"
|
||||
"checksum rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)" = "237546c689f20bb44980270c73c3b9edd0891c1be49cc1274406134a66d3957b"
|
||||
"checksum semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2d5b7638a1f03815d94e88cb3b3c08e87f0db4d683ef499d1836aaf70a45623f"
|
||||
"checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"
|
||||
"checksum serde_codegen_internals 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5113d5bd16471b183803b374f0fe4877ad9658b95e33b11f4a004d73aacc74a"
|
||||
"checksum serde_derive 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "a85017d774504173e5f908f69790ad7616f535f4ea91d0cdc65676ea3c933709"
|
||||
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "a702319c807c016e51f672e5c77d6f0b46afddd744b5e437d6b8436b888b458f"
|
||||
"checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e"
|
||||
"checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452"
|
||||
"checksum serde_json 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6501ac6f8b74f9b1033f7ddf79a08edfa0f58d6f8e3190cb8dc97736afa257a8"
|
||||
"checksum simd 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63b5847c2d766ca7ce7227672850955802fabd779ba616aeabead4c2c3877023"
|
||||
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
|
||||
"checksum syn 0.11.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0e28da8d02d75d1e58b89258e0741128f0b0d8a8309fb5c627be0fbd37a76c67"
|
||||
"checksum synom 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8fece1853fb872b0acdc3ff88f37c474018e125ef81cd4cb8c0ca515746b62ed"
|
||||
"checksum syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)" = "37c279fb816210c9bb28b2c292664581e7b87b4561e86b94df462664d8620bb8"
|
||||
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
|
||||
"checksum term_size 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "07b6c1ac5b3fffd75073276bca1ceed01f67a28537097a2a9539e116e50fb21a"
|
||||
"checksum thread-id 3.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4437c97558c70d129e40629a5b385b3fb1ffac301e63941335e4d354081ec14a"
|
||||
"checksum thread_local 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c85048c6260d17cf486ceae3282d9fb6b90be220bf5b28c400f5485ffc29f0c7"
|
||||
|
|
|
|||
10
Cargo.toml
10
Cargo.toml
|
|
@ -38,15 +38,15 @@ version = "^2.10.0"
|
|||
optional = true
|
||||
version = ">=0.0.85"
|
||||
|
||||
[dependencies.regex]
|
||||
optional = true
|
||||
version = "^0.2.0"
|
||||
|
||||
[dev-dependencies.image]
|
||||
[dependencies.image]
|
||||
default-features = false
|
||||
features = ["png_codec"]
|
||||
version = "^0.12.0"
|
||||
|
||||
[dependencies.regex]
|
||||
optional = true
|
||||
version = "^0.2.0"
|
||||
|
||||
[features]
|
||||
default = ["binary"]
|
||||
binary = ["clap", "regex"]
|
||||
|
|
|
|||
|
|
@ -7,12 +7,14 @@ pub struct PngError {
|
|||
}
|
||||
|
||||
impl Error for PngError {
|
||||
#[inline]
|
||||
fn description(&self) -> &str {
|
||||
&self.description
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for PngError {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.description)
|
||||
}
|
||||
|
|
|
|||
71
src/lib.rs
71
src/lib.rs
|
|
@ -4,6 +4,7 @@
|
|||
extern crate bit_vec;
|
||||
extern crate byteorder;
|
||||
extern crate crc;
|
||||
extern crate image;
|
||||
extern crate itertools;
|
||||
extern crate libc;
|
||||
extern crate miniz_sys;
|
||||
|
|
@ -13,7 +14,9 @@ extern crate zopfli;
|
|||
|
||||
use deflate::Deflaters;
|
||||
use error::PngError;
|
||||
use image::{GenericImage, Pixel, ImageFormat};
|
||||
use headers::Headers;
|
||||
use png::PngData;
|
||||
use rayon::prelude::*;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::{File, copy};
|
||||
|
|
@ -286,16 +289,13 @@ pub fn optimize(filepath: &Path, opts: &Options) -> Result<(), PngError> {
|
|||
}
|
||||
|
||||
let in_file = Path::new(filepath);
|
||||
let original_size = in_file.metadata().unwrap().len() as usize;
|
||||
let mut png = match png::PngData::new(in_file, opts.fix_errors) {
|
||||
Ok(x) => x,
|
||||
Err(x) => return Err(x),
|
||||
};
|
||||
let in_data = PngData::read_file(in_file)?;
|
||||
let mut png = PngData::from_slice(&in_data, opts.fix_errors)?;
|
||||
|
||||
// Run the optimizer on the decoded PNG.
|
||||
let optimized_output = optimize_png(&mut png, original_size, opts);
|
||||
let optimized_output = optimize_png(&mut png, &in_data, opts)?;
|
||||
|
||||
if is_fully_optimized(original_size, optimized_output.len(), opts) {
|
||||
if is_fully_optimized(in_data.len(), optimized_output.len(), opts) {
|
||||
writeln!(&mut stderr(), "File already optimized").ok();
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -408,13 +408,10 @@ pub fn optimize_from_memory(data: &[u8], opts: &Options) -> Result<Vec<u8>, PngE
|
|||
writeln!(&mut stderr(), "Processing from memory").ok();
|
||||
}
|
||||
let original_size = data.len() as usize;
|
||||
let mut png = match png::PngData::from_slice(data, opts.fix_errors) {
|
||||
Ok(x) => x,
|
||||
Err(x) => return Err(x),
|
||||
};
|
||||
let mut png = PngData::from_slice(data, opts.fix_errors)?;
|
||||
|
||||
// Run the optimizer on the decoded PNG.
|
||||
let optimized_output = optimize_png(&mut png, original_size, opts);
|
||||
let optimized_output = optimize_png(&mut png, data, opts)?;
|
||||
|
||||
if is_fully_optimized(original_size, optimized_output.len(), opts) {
|
||||
writeln!(&mut stderr(), "Image already optimized").ok();
|
||||
|
|
@ -425,10 +422,16 @@ pub fn optimize_from_memory(data: &[u8], opts: &Options) -> Result<Vec<u8>, PngE
|
|||
}
|
||||
|
||||
/// Perform optimization on the input PNG object using the options provided
|
||||
fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Options) -> Vec<u8> {
|
||||
fn optimize_png(png: &mut PngData,
|
||||
original_data: &[u8],
|
||||
opts: &Options)
|
||||
-> Result<Vec<u8>, PngError> {
|
||||
type TrialWithData = (u8, u8, u8, u8, Vec<u8>);
|
||||
|
||||
let original_png = png.clone();
|
||||
|
||||
// Print png info
|
||||
let file_original_size = original_data.len();
|
||||
let idat_original_size = png.idat_data.len();
|
||||
if opts.verbosity.is_some() {
|
||||
writeln!(&mut stderr(),
|
||||
|
|
@ -485,9 +488,9 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op
|
|||
}
|
||||
}
|
||||
|
||||
let something_changed = perform_reductions(&mut png, opts);
|
||||
let reduction_occurred = perform_reductions(png, opts);
|
||||
|
||||
if opts.idat_recoding || something_changed {
|
||||
if opts.idat_recoding || reduction_occurred {
|
||||
// Go through selected permutations and determine the best
|
||||
let combinations = if opts.deflate == Deflaters::Zlib {
|
||||
filter.len() * compression.len() * memory.len() * strategies.len()
|
||||
|
|
@ -569,10 +572,12 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op
|
|||
png.idat_data.len())
|
||||
.ok();
|
||||
}
|
||||
} else if reduction_occurred {
|
||||
png.reset_from_original(original_png);
|
||||
}
|
||||
}
|
||||
|
||||
perform_strip(&mut png, opts);
|
||||
perform_strip(png, opts);
|
||||
|
||||
let output = png.output();
|
||||
|
||||
|
|
@ -609,47 +614,65 @@ fn optimize_png(mut png: &mut png::PngData, file_original_size: usize, opts: &Op
|
|||
}
|
||||
}
|
||||
|
||||
output
|
||||
let old_png = image::load_from_memory_with_format(original_data, ImageFormat::PNG);
|
||||
let new_png = image::load_from_memory_with_format(&output, ImageFormat::PNG);
|
||||
|
||||
if let Ok(new_png) = new_png {
|
||||
if let Ok(old_png) = old_png {
|
||||
if old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() {
|
||||
return Ok(output);
|
||||
}
|
||||
} else {
|
||||
// The original image might be invalid if, for example, there is a CRC error,
|
||||
// and we set fix_errors to true. In that case, all we can do is check that the
|
||||
// new image is decodable.
|
||||
return Ok(output);
|
||||
}
|
||||
}
|
||||
|
||||
writeln!(&mut stderr(), "The resulting image is corrupted and will not be outputted.\nThis is a bug! Please report it at https://github.com/shssoichiro/oxipng/issues").ok();
|
||||
Err(PngError::new("The resulting image is corrupted"))
|
||||
}
|
||||
|
||||
/// Attempt all reduction operations requested by the given `Options` struct
|
||||
/// and apply them directly to the `PngData` passed in
|
||||
fn perform_reductions(png: &mut png::PngData, opts: &Options) -> bool {
|
||||
let mut something_changed = false;
|
||||
let mut reduction_occurred = false;
|
||||
|
||||
if opts.palette_reduction && png.reduce_palette() {
|
||||
something_changed = true;
|
||||
reduction_occurred = true;
|
||||
if opts.verbosity == Some(1) {
|
||||
report_reduction(png);
|
||||
}
|
||||
}
|
||||
|
||||
if opts.bit_depth_reduction && png.reduce_bit_depth() {
|
||||
something_changed = true;
|
||||
reduction_occurred = true;
|
||||
if opts.verbosity == Some(1) {
|
||||
report_reduction(png);
|
||||
}
|
||||
}
|
||||
|
||||
if opts.color_type_reduction && png.reduce_color_type() {
|
||||
something_changed = true;
|
||||
reduction_occurred = true;
|
||||
if opts.verbosity == Some(1) {
|
||||
report_reduction(png);
|
||||
}
|
||||
}
|
||||
|
||||
if something_changed && opts.verbosity.is_some() {
|
||||
if reduction_occurred && opts.verbosity.is_some() {
|
||||
report_reduction(png);
|
||||
}
|
||||
|
||||
if let Some(interlacing) = opts.interlace {
|
||||
if png.change_interlacing(interlacing) {
|
||||
png.ihdr_data.interlaced = interlacing;
|
||||
something_changed = true;
|
||||
reduction_occurred = true;
|
||||
}
|
||||
}
|
||||
|
||||
something_changed
|
||||
reduction_occurred
|
||||
}
|
||||
|
||||
/// Display the status of the image data after a reduction has taken place
|
||||
|
|
|
|||
|
|
@ -231,16 +231,16 @@ fn main() {
|
|||
.unwrap()
|
||||
.map(PathBuf::from)
|
||||
.collect(),
|
||||
opts);
|
||||
&opts);
|
||||
}
|
||||
|
||||
fn handle_optimization(inputs: Vec<PathBuf>, opts: Options) {
|
||||
fn handle_optimization(inputs: Vec<PathBuf>, opts: &Options) {
|
||||
for input in inputs {
|
||||
let mut current_opts = opts.clone();
|
||||
if input.is_dir() {
|
||||
if current_opts.recursive {
|
||||
handle_optimization(input.read_dir().unwrap().map(|x| x.unwrap().path()).collect(),
|
||||
current_opts)
|
||||
¤t_opts)
|
||||
} else {
|
||||
writeln!(&mut stderr(),
|
||||
"{} is a directory, skipping",
|
||||
|
|
|
|||
22
src/png.rs
22
src/png.rs
|
|
@ -183,7 +183,14 @@ pub struct PngData {
|
|||
|
||||
impl PngData {
|
||||
/// Create a new `PngData` struct by opening a file
|
||||
#[inline]
|
||||
pub fn new(filepath: &Path, fix_errors: bool) -> Result<PngData, PngError> {
|
||||
let byte_data = PngData::read_file(filepath)?;
|
||||
|
||||
PngData::from_slice(&byte_data, fix_errors)
|
||||
}
|
||||
|
||||
pub fn read_file(filepath: &Path) -> Result<Vec<u8>, PngError> {
|
||||
let mut file = match File::open(filepath) {
|
||||
Ok(f) => f,
|
||||
Err(_) => return Err(PngError::new("Failed to open file for reading")),
|
||||
|
|
@ -194,8 +201,7 @@ impl PngData {
|
|||
Ok(_) => (),
|
||||
Err(_) => return Err(PngError::new("Failed to read from file")),
|
||||
}
|
||||
|
||||
PngData::from_slice(&byte_data, fix_errors)
|
||||
Ok(byte_data)
|
||||
}
|
||||
|
||||
/// Create a new `PngData` struct by reading a slice
|
||||
|
|
@ -273,6 +279,17 @@ impl PngData {
|
|||
Ok(png_data)
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn reset_from_original(&mut self, original: PngData) {
|
||||
self.idat_data = original.idat_data;
|
||||
self.ihdr_data = original.ihdr_data;
|
||||
self.raw_data = original.raw_data;
|
||||
self.palette = original.palette;
|
||||
self.transparency_pixel = original.transparency_pixel;
|
||||
self.transparency_palette = original.transparency_palette;
|
||||
self.aux_headers = original.aux_headers;
|
||||
}
|
||||
|
||||
/// Return the number of channels in the image, based on color type
|
||||
#[inline]
|
||||
pub fn channels_per_pixel(&self) -> u8 {
|
||||
|
|
@ -330,6 +347,7 @@ impl PngData {
|
|||
}
|
||||
|
||||
/// Return an iterator over the scanlines of the image
|
||||
#[inline]
|
||||
pub fn scan_lines(&self) -> ScanLines {
|
||||
ScanLines {
|
||||
png: self,
|
||||
|
|
|
|||
BIN
tests/files/issue-60.png
Normal file
BIN
tests/files/issue-60.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 133 B |
|
|
@ -1,8 +1,5 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use image::GenericImage;
|
||||
use image::Pixel;
|
||||
use oxipng::colors::{BitDepth, ColorType};
|
||||
use oxipng::png;
|
||||
use std::collections::HashSet;
|
||||
|
|
@ -52,13 +49,6 @@ fn test_it_converts(input: &Path,
|
|||
assert_eq!(png.ihdr_data.color_type, color_type_out);
|
||||
assert_eq!(png.ihdr_data.bit_depth, bit_depth_out);
|
||||
|
||||
let old_png = image::open(input).unwrap();
|
||||
let new_png = image::open(output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use image::GenericImage;
|
||||
use image::Pixel;
|
||||
use oxipng::colors::{BitDepth, ColorType};
|
||||
use oxipng::deflate::Deflaters;
|
||||
use oxipng::headers::Headers;
|
||||
|
|
@ -54,13 +51,6 @@ fn test_it_converts(input: &Path,
|
|||
assert_eq!(png.ihdr_data.color_type, color_type_out);
|
||||
assert_eq!(png.ihdr_data.bit_depth, bit_depth_out);
|
||||
|
||||
let old_png = image::open(input).unwrap();
|
||||
let new_png = image::open(output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -111,13 +101,6 @@ fn strip_headers_list() {
|
|||
assert!(png.aux_headers.contains_key("iTXt"));
|
||||
assert!(!png.aux_headers.contains_key("iCCP"));
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -152,13 +135,6 @@ fn strip_headers_safe() {
|
|||
assert!(!png.aux_headers.contains_key("iTXt"));
|
||||
assert!(png.aux_headers.contains_key("iCCP"));
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -193,13 +169,6 @@ fn strip_headers_all() {
|
|||
assert!(!png.aux_headers.contains_key("iTXt"));
|
||||
assert!(!png.aux_headers.contains_key("iCCP"));
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -234,13 +203,6 @@ fn strip_headers_none() {
|
|||
assert!(png.aux_headers.contains_key("iTXt"));
|
||||
assert!(png.aux_headers.contains_key("iCCP"));
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -271,13 +233,6 @@ fn interlacing_0_to_1() {
|
|||
|
||||
assert_eq!(png.ihdr_data.interlaced, 1);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -308,13 +263,6 @@ fn interlacing_1_to_0() {
|
|||
|
||||
assert_eq!(png.ihdr_data.interlaced, 0);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -349,13 +297,6 @@ fn interlacing_0_to_1_small_files() {
|
|||
assert_eq!(png.ihdr_data.color_type, ColorType::Indexed);
|
||||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::One);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -390,13 +331,6 @@ fn interlacing_1_to_0_small_files() {
|
|||
assert_eq!(png.ihdr_data.color_type, ColorType::Indexed);
|
||||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::One);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -430,13 +364,6 @@ fn interlaced_0_to_1_other_filter_mode() {
|
|||
|
||||
assert_eq!(png.ihdr_data.interlaced, 1);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use image::GenericImage;
|
||||
use image::Pixel;
|
||||
use oxipng::colors::{BitDepth, ColorType};
|
||||
use oxipng::png;
|
||||
use std::collections::HashSet;
|
||||
|
|
@ -53,13 +50,6 @@ fn test_it_converts(input: &Path,
|
|||
assert_eq!(png.ihdr_data.color_type, color_type_out);
|
||||
assert_eq!(png.ihdr_data.bit_depth, bit_depth_out);
|
||||
|
||||
let old_png = image::open(input).unwrap();
|
||||
let new_png = image::open(output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use std::default::Default;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use image::GenericImage;
|
||||
use image::Pixel;
|
||||
use oxipng::colors::{BitDepth, ColorType};
|
||||
use oxipng::png;
|
||||
use std::collections::HashSet;
|
||||
|
|
@ -53,13 +50,6 @@ fn test_it_converts(input: &Path,
|
|||
assert_eq!(png.ihdr_data.color_type, color_type_out);
|
||||
assert_eq!(png.ihdr_data.bit_depth, bit_depth_out);
|
||||
|
||||
let old_png = image::open(input).unwrap();
|
||||
let new_png = image::open(output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -1264,13 +1254,6 @@ fn palette_should_be_reduced_with_dupes() {
|
|||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight);
|
||||
assert_eq!(png.palette.unwrap().len(), 35 * 3);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -1304,13 +1287,6 @@ fn palette_should_be_reduced_with_unused() {
|
|||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight);
|
||||
assert_eq!(png.palette.unwrap().len(), 33 * 3);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -1344,12 +1320,5 @@ fn palette_should_be_reduced_with_both() {
|
|||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight);
|
||||
assert_eq!(png.palette.unwrap().len(), 33 * 3);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
extern crate image;
|
||||
extern crate oxipng;
|
||||
|
||||
use image::GenericImage;
|
||||
use image::Pixel;
|
||||
use oxipng::colors::{BitDepth, ColorType};
|
||||
use oxipng::png;
|
||||
use std::collections::HashSet;
|
||||
|
|
@ -52,13 +49,6 @@ fn test_it_converts(input: &Path,
|
|||
assert_eq!(png.ihdr_data.color_type, color_type_out);
|
||||
assert_eq!(png.ihdr_data.bit_depth, bit_depth_out);
|
||||
|
||||
let old_png = image::open(input).unwrap();
|
||||
let new_png = image::open(output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -108,13 +98,6 @@ fn issue_42() {
|
|||
assert_eq!(png.ihdr_data.color_type, ColorType::GrayscaleAlpha);
|
||||
assert_eq!(png.ihdr_data.bit_depth, BitDepth::Eight);
|
||||
|
||||
let old_png = image::open(&input).unwrap();
|
||||
let new_png = image::open(&output).unwrap();
|
||||
|
||||
// Conversion should be lossless
|
||||
assert!(old_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>() ==
|
||||
new_png.pixels().map(|x| x.2.channels().to_owned()).collect::<Vec<Vec<u8>>>());
|
||||
|
||||
remove_file(output).ok();
|
||||
}
|
||||
|
||||
|
|
@ -252,3 +235,18 @@ fn issue_59() {
|
|||
ColorType::RGBA,
|
||||
BitDepth::Eight);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn issue_60() {
|
||||
let input = PathBuf::from("tests/files/issue-60.png");
|
||||
let opts = get_opts(&input);
|
||||
let output = opts.out_file.clone();
|
||||
|
||||
test_it_converts(&input,
|
||||
&output,
|
||||
&opts,
|
||||
ColorType::RGBA,
|
||||
BitDepth::Eight,
|
||||
ColorType::GrayscaleAlpha,
|
||||
BitDepth::Eight);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue