Commit graph

344 commits

Author SHA1 Message Date
Alejandro González
904beeec6b
Update zopfli to v0.8.0 (#560)
This update brings several parameterization and usage flexibility
improvements on Zopfli, allowing users to choose to limit execution time
by a number of iterations without improvement, and exposing a more
advanced `ZlibEncoder` struct to tune compression block sizes and
DEFLATE block types. Some minor microoptimizations were also made.

For now, I don't expect this PR to substantially affect how OxiPNG
compresses images using its Zopfli mode, but the additional parameter
customization may come in handy for future work improving how Zopfli is
used in OxiPNG.
2023-10-09 23:14:22 +02:00
Andrew
8eb5a3f419 Remove libdeflate slack space no longer needed 2023-09-27 09:16:24 +13:00
andrews05
25d0685bdf
Remove backup and check options (#546)
Tidy up the API by removing a couple of options we don't really need.
Backup was discussed in #542
Check was discussed in  #439

@shssoichiro Just say if you prefer to keep either of these 🙂
2023-09-26 09:52:51 +02:00
Winterhuman
fa47c82617
Add --timeout notice (#557)
Closes: https://github.com/shssoichiro/oxipng/issues/556

Adds a statement saying that `--timeout` isn't as useful for compression
algorithms which use fewer and slower rounds, which OxiPNG tends to use
nowadays.

---------

Co-authored-by: andrews05 <andrew@digerati.co.nz>
2023-09-26 09:43:38 +13:00
LuckyTurtleDev
b6a238c67a
skip non png files, if --recursive is used (#548)
Fix #547
2023-09-26 09:28:22 +13:00
andrews05
462e982784
Move file-specific options under OutFile (#529)
This PR is addressing #220. It's not super important but it's a breaking
change, so if it's something we want to do then I thought I should get
it in now before the next release.

- [x] pretend can become another variant of OutFile, probably
OutFile::None, as that's what it essentially is - just another output
destination and not a separate option
- [x] ~~backup and~~ preserve_attrs should become properties of
OutFile::Path variant (so that it would contain Path { path, ~~backup,~~
preserve_attrs }) as they don't have any effect on any other output and
so semantically belong there best

Closes #220
2023-09-25 11:15:13 +02:00
Alejandro González
1f2e0f336a
Revamp CI workflow to upload artifacts, cross-compile ARM64 binaries, and more (#534)
As commented in issues https://github.com/shssoichiro/oxipng/issues/444
and https://github.com/shssoichiro/oxipng/issues/518, there is some user
interest for distributing binaries for each unstable commit, and target
ARM64 platforms. Personally, I think both suggestions are useful for the
project, as uploading binary artifacts for each commit might help
interested users to catch regressions and give feedback earlier, and
powerful ARM64 platforms are becoming increasingly popular due to some
cloud services (e.g., Amazon EC2, Azure VMs, Oracle Cloud) offering
cheaper plans for this hardware, in addition to the well-known push for
ARM by Apple with their custom M1 chips.

These changes make the CI target ARM64 as a first-class citizen. Because
the public GitHub actions runners can only be hosted on x64 for now, I
resorted to cross-compilation, [Debian's
multiarch](https://elinux.org/images/d/d8/Multiarch_and_Why_You_Should_Care-_Running%2C_Installing_and_Crossbuilding_With_Multiple_Architectures.pdf),
and QEMU to build, get ARM64 C library dependencies, and run tests,
respectively.

When the CI workflow finishes, a release CLI binary artifact is now
uploaded, which can be downloaded from the workflow run page on the
GitHub web interface.

In addition, these changes also introduce some cleanup and miscellaneous
improvements and changes to the CI workflow:

- Tests are run using [`nextest`](https://nexte.st/) instead of `cargo
test`, which substantially speeds up their execution. (On my development
workstation, `cargo test --release` takes around 10.67 s, while `cargo
nextest run --release` takes around 6.02 s.)
- The dependencies on unmaintained `actions-rs` actions were dropped in
favor of running Cargo commands directly, or using
`giraffate/clippy-action` for pretty inline annotations for Clippy. This
gets rid of the deprecation warnings for each workflow run.
- Most CI steps are run with a nightly Rust toolchain now, which allows
to take advantage of the latest Clippy lints and codegen improvements.
In my experience, when not relying on specific nightly features or
compiler internals, Rust does a pretty good job at making it possible to
rely on a rolling-release compiler for CI, as breakage is extremely rare
and thus offset by the improved features.
- The MSRV check was moved to a separate job with less steps, so that it
takes less of a toll on total workflow run minutes.

## Pending tasks

- [x] Generate universal macOS binaries with `lipo` (i.e., containing
both `aarch64` and `x64` code)
- [x] Tirelessly fix the stupid errors that tend to happen when
deploying a new CI workflow for the first time
- [x] Think what to do with the `deploy.yml` workflow. Should it fetch
artifacts from the CI job instead of building them again?
- [x] Maybe bring back 32-bit Windows binaries. Are they actually useful
for somebody, or just a way to remember the good old days?

---------

Co-authored-by: Josh Holmer <jholmer.in@gmail.com>
2023-09-02 11:09:20 -04:00
andrews05
aa956fbc47
Ensure --nx --nz disables all optimisations (#543)
This PR makes two changes:
- `--nz` (`idat_recoding`) now disables all zlib recompression,
including iCCP and fDAT chunks. (Perhaps we should rename the option to
`zlib_recompression`?)
- `--nx` now also disables the default deinterlacing, though it can
still be overridden with `-i`.

`--nx --nz` does disable all optimisations in the v8 release and we
should ensure it continues to do so in the next release. (This is
related to discussions around removing the `--check` option.)
2023-09-02 09:00:09 -04:00
Andrew
02bd47ba29 Don't style debug and trace output 2023-07-31 11:55:10 -04:00
Vladyslav Vladinov
708a019ce2
Added support for glob patterns in quotes (#536)
Added support for glob patterns in windows paths with spaces that
surrounded with quotes

closes #373
2023-07-31 11:35:00 -04:00
Andrew
0288cc38fc Don't fail recursion on read_dir error 2023-07-31 11:05:25 -04:00
Andrew
b4e98a4dd1 Switch from stderrlog to env_logger 2023-07-14 14:11:07 -04:00
andrews05
b883c660fc
Additional palette sorting algorithm (#514)
This adds a new palette sorting algorithm that attempts to minimise
entropy by an approximate solution to the Traveling Salesman Problem.
The algorithm comes from "An efficient Re-indexing algorithm for
color-mapped images" by Battiato et al
(https://ieeexplore.ieee.org/document/1344033).
It's fast and effective and works in addition to the luma sort (which
remains the single most effective sort). In order to keep lower presets
fast though, I've only enabled this for o3 and higher.

Results on a set of 190 indexed images at `-o5`:
18,932,727 bytes - master
18,578,306 bytes - PR
18,559,863 bytes - PR + #509
(These images may be particularly suited to alternative sorting methods
- the gains here are not necessarily what should be expected on average)

Note I looked into the 120 different palette sorting methods from
TruePNG, as mentioned in #74 (and seen in action in the Zopfli KrzYmod
fork). They're... largely ineffective. The combination of all 120
methods are outperformed by just the existing luma sort plus this new
one. That's not to say there's nothing further to be gained from them,
but trying to brute force all the combinations definitely seems like a
bad idea. There are other algorithms I hope to explore in future...

@ace-dent Thought this might interest you


UPDATE: I realised a quick tweak to alpha values in the luma sort can
provide a great improvement on images with transparency. The following
numbers were taken with PR #509 as base.
`-o2`:
19,065,549 bytes - base (luma sort)
18,949,747 bytes - modified luma sort

`-o5`:
18,922,165 bytes - base (luma sort)
18,559,863 bytes - new sorting algorithm + luma sort
18,544,813 bytes - new sorting algorithm + modified luma sort
2023-07-11 12:33:57 -04:00
andrews05
4ae64c568b
Process files in parallel (#531)
This PR makes the oxipng binary process multiple files in parallel,
finally fulfilling #275. There seemed to be some debate about whether
oxipng _should_ do this or not but there's a couple of reasons I think
it makes sense:
1. The concern seemed mostly around the complexity of such a feature.
Not to worry, it was trivial* 🙂
2. Since then, oxipng has dropped from a max of something like 180
simultaneous compression trials down to 10, which is very much a good
thing but it does mean it's not utilising any more cores than that.

Some benchmarks on around 100 files on a machine with 8 cores:
Level | Master time | PR time
-|-|-
2 | 28.303 | 19.005
3 | 36.507 | 23.089
5 | 1:10.86 | 1:16.01

*Some additional changes were required in order to make sure sensible
output is printed to the terminal, since things won't be in order
anymore. Here's some example output from before:
```
Processing: tests/files/fully_optimized.png
    file size = 67 bytes (0 bytes = 0.00% decrease)
File already optimized
Processing: tests/files/corrupted_header.png
Invalid PNG header detected
Processing: tests/files/verbose_mode.png
    file size = 102480 bytes (12228 bytes = 10.66% decrease)
Output: tests/files/verbose_mode.png
```
And after:
```
Processing: tests/files/verbose_mode.png
Processing: tests/files/fully_optimized.png
Processing: tests/files/corrupted_header.png
tests/files/corrupted_header.png: Invalid PNG header detected
tests/files/fully_optimized.png: Could not optimize further, no change written
102480 bytes (10.66% smaller): tests/files/verbose_mode.png
```

Closes #275, #84, #169, #196 and #419.

[edit] This is the last thing I wanted to land before the next release 🥳
2023-07-11 03:45:10 -04:00
Josh Holmer
31e796c4e8 Revert "Provide BufferedZopfliDeflater and allow user to pass in a custom Deflater (#530)"
This reverts commit 2a59419bdf.
2023-07-09 13:40:20 -04:00
Andrew
775e718dff Stop yielding once evaluations are done 2023-07-08 18:57:15 -04:00
andrews05
39b00910ae
Use stronger compression in eval (#509) 2023-07-08 18:54:58 -04:00
Josh Holmer
2a59419bdf
Provide BufferedZopfliDeflater and allow user to pass in a custom Deflater (#530)
* Add .whitesource configuration file

* Experimental: allow Zopfli to use any size BufWriter

* Allow user to specify the output buffer size as well

* Allow user to specify maximum block splits

* Reformat and fix warnings

* Use deflater on iCCP chunk as well

* Bug fix: need to implement Zlib format

* Make functions const when possible

* Switch to using zopfli::Options in prep for https://github.com/zopfli-rs/zopfli/pull/21

* Switch to using zopfli::Options in prep for https://github.com/zopfli-rs/zopfli/pull/21

* Cargo fmt

* Fix compilation

* Fix tests

* Fix more lints

* Fix more lints

* Fix compilation more

---------

Co-authored-by: mend-bolt-for-github[bot] <42819689+mend-bolt-for-github[bot]@users.noreply.github.com>
Co-authored-by: Chris Hennick <hennickc@amazon.com>
Co-authored-by: Chris Hennick <4961925+Pr0methean@users.noreply.github.com>
2023-07-07 22:35:01 -04:00
andrews05
b846a2e909
Try to pick tRNS value that's valid at low depth (#520) 2023-07-07 20:56:15 -04:00
andrews05
75a0f0de95
Allow APNG with reductions disabled (#511) 2023-07-05 00:47:43 -04:00
Andrew
129f1e6f76 Try to fix deadlock in parallel mode 2023-06-25 14:36:23 -04:00
andrews05
798fdfe24c
Update rust and dependencies (#525)
* Bump rust version

* Update Clap to v4

* Update other dependencies
2023-06-25 14:24:23 -04:00
andrews05
96122fa45a
Expand low depths to 8-bit (#516)
* Keep track of number of pixels in each scanline

* Expand depth to 8-bit

* Attempt expand bit depth

* Simplify tracking of reduction_occurred

* Fix test

* Simplify depth handling in reductions

* Add tests for disabled reductions
2023-06-18 01:32:47 -04:00
Andrew
c71fd44454 Prevent conversion from grayscale when disabled 2023-06-18 01:02:11 -04:00
Andrew
86fccf082a Fix grayscale_reduction option 2023-05-28 16:11:41 -04:00
Andrew
88b930b5b1 Add scale16 option to force 16-bit reduction 2023-05-24 10:21:42 -04:00
Andrew
c1222368b4 Deinterlace by default 2023-05-24 10:13:40 -04:00
andrews05
ea5f1884be
Refactor aux chunk handling (#505) 2023-05-21 15:34:23 -04:00
andrews05
d8b7ebaf47
Further small reduction improvements (#504) 2023-05-16 20:53:05 -04:00
andrews05
9a500941d8
Raw API (#482) 2023-05-15 08:37:49 -04:00
Andrew
a7be8751dc Don't force output due to interlacing flag 2023-05-09 09:59:45 -04:00
andrews05
2f622fc7bd
Minor reduction improvements (#502)
* Fix bKGD conversion from gray to palette

* Allow grayscale reduction from 16 to 4 or less

* Refactor reduction evaluation sequence

* Separate palette into new file
2023-05-07 17:46:58 -04:00
andrews05
a26d225d81
More flexible verbosity, improve verbose test (#501)
* More flexible verbosity, improve verbose test

* Tweak reporting format

* Add evaluation reporting at trace level
2023-05-06 10:45:31 -04:00
Andrew
798a120926 Include PLTE/tRNS size in evaluations 2023-04-29 01:20:22 -04:00
andrews05
c97572be3e
ColorType Refactor (#500)
* Refactor ColorType
Move transparency and palette data into the ColorType

* Fixup tests

* Make more use of helper functions

* Change BitDepth to u8 representation with TryFrom

* Fix clippy lints

* Don't use unstable language features

* Restore documentation on transparency/palette
2023-04-27 19:49:54 -04:00
Alejandro González
be19ed592d
Make dependency on image optional (#498)
* Make dependency on `image` optional

After PR https://github.com/shssoichiro/oxipng/pull/481 was merged, the
`image` dependency became unused when building with debug assertions
disabled, as it is only used to implement output sanity checks when such
assertions are enabled.

The `image` crate transitively pulls a significant amount of
dependencies, so it's useful for OxiPNG users to get rid of them when
not needed.

[Cargo does not allow specifying dependencies that are only pulled when
debug assertions are
enabled](https://github.com/rust-lang/cargo/issues/7634), so the next
best way to give users some flexibility is to gate those debug
assertions behind a feature flag.

These changes add a `sanity-checks` feature flag that controls whether
the `image` crate and the related sanity checks are compiled in. This
feature is enabled by default to keep debug builds useful to catch
problems during development.

* Fix Clippy lints

* Run tests with new sanity-checks feature enabled
2023-04-24 13:24:23 -04:00
Josh Holmer
a234c39e41 Fix new annoyingly pedantic clippy warnings 2023-04-22 22:25:59 -04:00
Douman
cc37f645ba
Refactoring to use appropriate log level for debug logs (#489) 2023-04-04 00:48:01 -04:00
Josh Holmer
5341de2163 Fix new clippy lints 2023-04-03 23:50:03 -04:00
Andrew
a874fe9cb7 Remove incorrect comment 2023-01-06 15:35:05 -05:00
Andrew
87ba51c936 Fix reduction reporting when no reduction occured 2023-01-06 15:35:05 -05:00
andrews05
91e29144b0
Change validation to a debug assert (#481) 2022-12-22 17:05:38 -05:00
andrews05
a3b104a2ed
Faster reductions (#479)
* Add grayscale depth tests and benches

* Don't include filter byte in PngImage.data

* Simplify reductions by not using scan lines

* Faster grayscale reduction

* Simplify reduce_color_type

* Faster depth reduction
2022-12-22 16:56:36 -05:00
andrews05
2008d09915
Reduce alpha to tRNS (#477) 2022-12-13 15:18:19 -05:00
andrews05
2599b9fe82
Tweaks to interlacing and format display (#476) 2022-12-12 09:54:35 -05:00
Andrew
815f12df46 Fix fast with zopfli 2022-12-10 21:47:49 -05:00
andrews05
131a3c6af7
🚀 Revamp alpha optimisation (#475) 2022-12-10 21:14:50 -05:00
andrews05
54ee621e41
Fix Grayscale depth reduction with tRNS (#470) 2022-12-08 06:11:26 -05:00
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