Commit graph

296 commits

Author SHA1 Message Date
andrews05
bd5a0b526b
More Reductions (#468)
* Add test for issue 195

* Reduce grayscale alpha to palette

* Black alpha before color type reductions
2022-12-07 13:22:13 -05:00
andrews05
1934587253
Rebalance presets (#467)
* Add --fast option

* Rebalance presets

* Retain filtered idat
2022-12-07 08:09:19 -05:00
andrews05
3365aca12f
Palette reduction fixes (#466)
* Verify bKGD in tests

* Don't truncate bKGD on output

* Make sure correct bKGD is retained

* Update safe chunk list

* Perform strip first

* Check entire palette map
2022-12-07 07:49:52 -05:00
andrews05
6022fc2aa1
Refactor use_heuristics for fast filter evaluation (#463) 2022-12-02 05:34:38 -05:00
Andrew
15a9b4a3e7 Fast deinterlace for 8-bit+ 2022-11-25 04:23:38 -05:00
andrews05
a41d7de348
New filter strategies (#461)
* Refactor filters as enum

* Include filter byte in filter output

* Add entropy filter

* Add bigrams filter

* Add bigram entropy filter

* Add brute filter

* Replace bit-vec

* Add tests and benches

* Show filters in help

* Use FxHasher in color to palette

* Use windows function for minor improvement
2022-11-19 08:49:25 -05:00
andrews05
420d904ba9
Strengthen alpha reductions (#460)
* Improve up and left alpha reductions

* Disable alpha down and right by default

* Improve performance of up
2022-11-01 19:13:24 -04:00
andrews05
446c788eb3
Full switch to Libdeflater (#457)
* Switch main compressor to libdeflate

* Use libdeflater in evaluate

* Use libdeflater to inflate

* Use libdeflater crc

* Tidy up

* Fix benches

* Allow libdeflater/freestanding feature

* Fix building without zopfli
2022-11-01 09:02:08 -04:00
andrews05
f688d20fe6
Allow setting libdeflate compression level (#455)
* Allow --zc with libdeflater

* Update libdeflater

* Allocate sufficient space for libdefate
2022-10-28 21:54:04 -04:00
andrews05
a02d4ff0dd
Fix directional alpha reductions (#458)
* Fix alpha up and down

* Fix alpha left and right
2022-10-28 19:41:44 -04:00
Andrew
8396a262c3 Fix level 0 2022-10-28 15:40:58 -04:00
Tristan
86a72ea127 Avoid printing output bytes on decompress error
Instead, print the number of bytes decompressed so far

Fixes #452
2022-10-07 14:47:34 -04:00
Alejandro González
84bbec0666
Add initial support for changing Zopfli iterations (#446)
* Update and optimize dependencies

These changes update the dependencies to their latest versions, fixing
some known issues that prevented doing so in the first place.

In addition, the direct dependency on byteorder was dropped in favor
of stdlib functions that have been stabilized for some time in Rust, and
the transitive dependency on chrono, pulled by stderrlog, was also
dropped, which had been affected by security issues and improperly
maintained in the past:

- https://github.com/cardoe/stderrlog-rs/issues/31
- https://www.reddit.com/r/rust/comments/ts84n4/chrono_or_time_03/

* Run rustfmt

* Bump MSRV to 1.56.1

Updating to this patch version should not be cumbersome for end-users,
and it is required by a transitive dependency.

* Bump MSRV to 1.57.0

os_str_bytes requires it.

* Add initial support for changing Zopfli iterations

PR https://github.com/shssoichiro/oxipng/pull/445 did some dependency
updates, which included using the latest zopfli version. The latest
version of this crate exposes new options in its API that allow users to
choose the desired number of Zopfli compression iterations, which
may greatly affect execution time. In fact, other optimizers such as
zopflipng dynamically select this number depending on the input file
size (see: https://github.com/shssoichiro/oxipng/issues/414).

As a first step towards making OxiPNG deal with Zopfli better, let's add
the necessary options for libraries to be able to choose the number of
iterations. This number is still fixed to 15 as before when using the
CLI.

* Fix Clippy lint

Co-authored-by: Josh Holmer <jholmer.in@gmail.com>
2022-09-05 12:50:13 -04:00
Alejandro González
94ba8b70b3
Update and optimize dependencies (#445)
* Update and optimize dependencies

These changes update the dependencies to their latest versions, fixing
some known issues that prevented doing so in the first place.

In addition, the direct dependency on byteorder was dropped in favor
of stdlib functions that have been stabilized for some time in Rust, and
the transitive dependency on chrono, pulled by stderrlog, was also
dropped, which had been affected by security issues and improperly
maintained in the past:

- https://github.com/cardoe/stderrlog-rs/issues/31
- https://www.reddit.com/r/rust/comments/ts84n4/chrono_or_time_03/

* Run rustfmt

* Bump MSRV to 1.56.1

Updating to this patch version should not be cumbersome for end-users,
and it is required by a transitive dependency.

* Bump MSRV to 1.57.0

os_str_bytes requires it.
2022-09-05 12:37:47 -04:00
Josh Holmer
17f5cc36ca Fix clippy lints 2022-07-05 10:05:06 -04:00
carbotaniuman
9054b2d947 Add check option 2022-05-07 23:48:06 -04:00
Rémi Lauzier
7ffbe1fb78 Update dependency and replace deprecated function 2022-03-14 09:21:22 -04:00
Josh Holmer
ece9787822 Bump all dependencies 2022-01-12 02:47:59 -05:00
Josh Holmer
bc0d673af0 Fix a hard error in clippy 2021-11-15 11:41:40 -05:00
Nino Burini
2d16819cbf
apply_preset_5 and apply_preset_6 to set correct compression levels. (#425)
The for loop in apply_preset_5 was not including 9.
apply_preset_6 now builds now calls apply_preset_4 instead of
apply_preset_5, and adds all compression levels from 1 to 9.

Co-authored-by: Nino Burini <nburini@jabra.com>
2021-11-15 11:17:52 -05:00
Josh Holmer
44d89ecff4 Fix clippy lints 2021-07-11 23:42:37 -04:00
Josh Holmer
d089176030 Bump dependencies 2021-07-11 23:42:12 -04:00
Moe
40a88f57f7
initial implementation of timestamp preservation #166 (#360)
Closes #166
2021-07-11 23:34:10 -04:00
Alejandro González
491d753edc
Add option to skip grayscale reduction of RGB(A) images (#409)
For RGB(A) images that contain gray colors, this reduction can achieve
significant space savings. However, in the absence of gamma correction
data, some PNG decoders assume more exotic color spaces for grayscale
images instead of the ubiquitous sRGB. This results in gamma
miscorrection, and for the end user this means that colors will look
wrong, like "washed-out". Java's ImageIO class, which is popular in the
JVM world to read PNG files, uses rather unconventional defaults, as
explained in this StackOverflow question: https://stackoverflow.com/questions/31312645/java-imageio-grayscale-png-issue

Gamma miscorrection problems aside, OxiPNG currently tries hard to
reduce RGB(A) images to grayscale, because it expects that reduction to
be quite effective. However, in some cases, OxiPNG generates smaller
PNG files when reducing grasycale RGB(A) images to paletted color than
actual grayscale color. For example, let's say that "~/gray.png" is a
256x256 RGBA image entirely filled with (119, 119, 119, 255) pixels.
OxiPNG, by default, reduces this image to grayscale and achieves a
68.23% decrease:

$ cargo build --release && target/release/oxipng -omax --out ~/out.png ~/gray.png
Processing: /home/user/gray.png
    256x256 pixels, PNG format
    4x8 bits/pixel, RGBA
    IDAT size = 604 bytes
    File size = 661 bytes
Reducing image to 1x4 bits/pixel, Grayscale
Trying: 144 combinations
Found better combination:
    zc = 6  zs = 0  f = 0        153 bytes
    IDAT size = 153 bytes (451 bytes decrease)
    file size = 210 bytes (451 bytes = 68.23% decrease)
Output: /home/user/out.png

However, if the --ng option that this commit adds is used to skip the
grayscale reduction step, OxiPNG reduces to a single color palette
instead, which is much more efficient, achieving a 84.42% decrease:

$ cargo build --release && target/release/oxipng -omax --ng --out ~/out.png ~/gray.png
Processing: /home/alejandro/gray.png
    256x256 pixels, PNG format
    4x8 bits/pixel, RGBA
    IDAT size = 604 bytes
    File size = 661 bytes
Reducing image to 1 bits/pixel, 1 colors in palette
Trying: 144 combinations
Found better combination:
    zc = 3  zs = 3  f = 0        31 bytes
    IDAT size = 31 bytes (573 bytes decrease)
    file size = 103 bytes (558 bytes = 84.42% decrease)
Output: /home/alejandro/out.png

While OxiPNG should arguably be made smarter to better handle these
cases, in the meantime, adding an option to manually skip that grayscale
reduction can't hurt. In fact, it may even help users achieving the most
out of current versions of OxiPNG, and developers reasoning about what
makes a grayscale-like RGB(A) image compress better with a color
palette.

Due to the reasons stated above, this adds a simple "grayscale_reduction"
option to the Options struct, and a "no-grayscale-reduction" command
line switch, that makes OxiPNG not try this problematic grayscale
reduction on RGB(A) images.
2021-07-11 23:21:38 -04:00
Kornel
ea75f6ccc1
Handle files with invalid filters (#410)
The bad filter case is reachable, and can happen when the PNG file is corrupted.
2021-07-11 23:07:18 -04:00
Rémi Lauzier
286aaffa31 small fix 2021-06-24 19:47:21 -04:00
Rémi Lauzier
91a18ebe97 Fix some clippy warnings 2021-06-24 15:57:41 -04:00
Kornel
c4910709d9 Assertions 2021-06-16 19:39:05 -04:00
Kornel
3e996a0f82 Make sure passes clear last line 2021-06-16 19:39:05 -04:00
Kornel
d2cebc3c2d Don't allocate reduced buffer until needed 2021-06-16 17:37:33 -04:00
Kornel
b6cc8e2414
Optimize unfiltering (#400)
* Clippy lints

* Fewer pushes

* Remove special case for empty last line

* Zip with last line

* Combine bound checks
2021-05-19 15:16:14 -04:00
Kornel
14867c7abc
Clippy lints (#401) 2021-05-19 10:04:31 -04:00
Kornel
f2e89140ed
Prevent panics in parse_ihdr_header (#392) 2021-02-24 15:48:30 -05:00
Josh Holmer
76da6b5468 Fix Rust 1.50 clippy error 2021-02-24 13:51:47 -05:00
Kornel
04010978a0 Use optimized copy 2021-01-20 14:33:27 -05:00
Kornel
3163a92594 Ignore broken tRNS 2021-01-20 14:33:27 -05:00
Kornel
53ddd721a7 Reject truncated image data instead of panicking 2021-01-20 14:33:27 -05:00
Kornel
17212477c5 Avoid asserts panicking on broken files 2021-01-20 14:33:27 -05:00
Josh Holmer
9b5cd9a1a4 Fix a new clippy lint 2021-01-04 16:12:46 -05:00
Ingvar Stepanyan
e38c759563
Switch to crossbeam-channel + rayon::spawn (#327)
* Switch to crossbeam-channel + rayon::spawn

* Remove thread_spawn for evaluation altogether

This allows to avoid a deadlock when there is only one Rayon thread, and doesn't sacrifice performance, since the caller of .get_result() had to always block on the iterator to be finished anyway, and all the messages are already sent from separate threads.

* Fix `verbose_mode` test

This one is easier to "fix", since we're in control of the rayon pool - just adding one extra thread to the default number to make sure we always can one root "spawn" call without stealing from the actual pool.
2020-11-11 12:01:13 -05:00
Anhil
70f911fa3e
Make libdeflater and zopfli optional (#319)
* Make `libdeflater` and `zopfli` optional
2020-11-01 20:18:15 -05:00
Josh Holmer
b446a8a92e Optimize reading in files 2020-10-22 09:51:25 -04:00
Ingvar Stepanyan
7167a5e44d
Use the new stabilised fetch_min (#328)
A minor simplification using the corresponding new standard library function.

Bumps minimum Rust version to 1.45.0
2020-10-11 18:53:00 -04:00
Josh Holmer
0d9c23f4ce Fix new clippy lints from Rust 1.47 2020-10-09 20:20:52 -04:00
Josh Holmer
90c99e4509 Do not exit on first non-PNG file found in recursion
Closes #170
2020-08-12 10:59:43 -04:00
Josh Holmer
ad054cadb5 Fix new clippy lint 2020-07-20 20:23:04 -04:00
Josh Holmer
ea746da96c Readd the --force flag to the CLI
This was still present in the lib and options parsing,
but was not in the Clap args list for some reason.
2020-07-13 04:36:27 -04:00
Josh Holmer
fa11401eb1 Version 3.0.0 2020-05-06 10:11:47 -04:00
Ingvar Stepanyan
b06e077f8d
Add "max" level alias; various level-related warnings (#224)
* Update --help to exclude -a

* Add a deprecation warning to level 4 constructor

* Initialise logger earlier

* Add warning for level > 3 for non-zlib

It's not obvious immediately that these levels don't have any effect on libdeflater and Zopfli, since they don't iterate over zlib-specific fine-tuned options.

Hence, show warning so that user knows they're getting "downgraded" to level 3.

* Add "max" level alias; more level warnings

* Update --help trial numbers for non-zlib

* Fix incorrect trial numbers
2020-04-22 13:34:59 -04:00
Ingvar Stepanyan
fee76ca44f
Remove doc-hidden recursive option (#225)
As the comment mentions, this is used only in CLI interface, so there's no reason for it not to live directly in CLI code.

Ref: #220.
2020-04-20 08:51:18 -04:00