This need was raised in https://bugs.gentoo.org/944285. Can be enabled
with `--features system-libdeflate` to use the libdeflate located on the
user's system instead of building our own.
Just as a point of interest, I observed a 3-4% performance improvement
from the BigEnt strategy benchmark as a result of the upgrade to
rustc-hash 2.0. This has zero impact on overall performance.
PR #596 brought forward automatic generation of Linux manual pages for
Oxipng, which is executed every time Oxipng is built. However, while
building manpages on every build is convenient for Oxipng development
and doing so didn't catch my attention initially, it introduces
noticeable inefficiencies for crates using Oxipng as a library: during
their build, Oxipng manpages are also built, even though most dependent
crates won't use such artifacts, as they are not considered part of the
public Oxipng crate API or even appropriate for non-human consumption.
Moreover, generating manpages depends on `clap`, which is a heavyweight
dependency: according to a fresh `cargo build --timings --release` on my
development workstation, its `clap_builder` dependency is the third most
time consuming unit to build, totalling 1.5 s (out of 11.7 s, or 12.8%).
And there is no way for dependent crates to turn this off:
[`build-dependencies` cannot be conditional on crate
features](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies).
Potentially using other `cfg` hacks to either enable or disable manpage
generation is unergonomic, if not outright disallowed. Besides reducing
their compilation time cost, dependent crates may also want to trim the
size of their dependency tree, avoiding unnecessary dependency downloads
in the process.
Therefore, a better solution to conditionally build manpages in a way
convenient for both Oxipng maintainers and downstream consumers is
needed. My proposal implemented in this PR is to leverage the
[`cargo-xtask`](https://github.com/matklad/cargo-xtask) convention to
define an auxiliary crate to move the manpage generation logic and
dependencies to, which is not part of the `oxipng` crate published on
`crates.io`. That way Oxipng maintainers and packagers can still
generate manpages at request with ease, without any automation being
noticeable to uninterested crate consumers. And as a side benefit,
Oxipng maintainers can also benefit from slightly faster iteration times
due to the lack of a build script for the main crate.
The new `mangen` xtask can be run at any time with `cargo xtask mangen`.
The generated manpages are now available at
`target/xtask/mangen/manpages`. Existing deployment scripts were updated
accordingly.
This PR adds a build script to generate a man page using clap_mangen, as
per this example:
https://github.com/sondr3/clap-man-example/blob/main/build.rs
I'm not sure what to actually do with the man file from here, I guess
it's up to the packaging process to do something with it?
See
https://github.com/shssoichiro/oxipng/issues/69#issuecomment-1963352536
Note I couldn't see a way to include the `DISPLAY` chunk names from the
constant as we did before. They're now just hardcoded into the help and
will require manually updating if the list changes.
Closes#526
---------
Co-authored-by: Alejandro González <me@alegon.dev>
This PR brings a big overhaul to oxipng's help, with new long form
descriptions of many options.
The full output (--help) is added as a text file MANUAL.txt. Critiques
welcome.
The short output (-h) is simplified and appears as follows:
```
Losslessly improve compression of PNG files
Usage: oxipng [OPTIONS] <files>...
Arguments:
<files>... File(s) to compress (use '-' for stdin)
Options:
-o, --opt <level> Optimization level (0-6, or max) [default: 2]
-r, --recursive Recurse input directories, optimizing all PNG files
--dir <directory> Write output file(s) to <directory>
--out <file> Write output file to <file>
--stdout Write output to stdout
-p, --preserve Preserve file permissions and timestamps if possible
-P, --pretend Do not write any files, only show compression results
-s Strip safely-removable chunks, same as '--strip safe'
--strip <mode> Strip metadata (safe, all, or comma-separated list)
CAUTION: 'all' will convert APNGs to standard PNGs
--keep <list> Strip all metadata except in the comma-separated list
-a, --alpha Perform additional alpha channel optimization
-i, --interlace <type> Set PNG interlacing type (0, 1, keep) [default: 0]
--scale16 Forcibly reduce 16-bit images to 8-bit (lossy)
-v, --verbose... Run in verbose mode (use twice to increase verbosity)
-q, --quiet Run in quiet mode
-f, --filters <list> Filters to try (0-9; see '--help' for details)
--fast Use fast filter evaluation
--zc <level> Deflate compression level (1-12)
--nb Do not change bit depth
--nc Do not change color type
--np Do not change color palette
--ng Do not change to or from grayscale
--nx Do not perform any transformations
--nz Do not recompress unless transformations occur
--fix Disable checksum validation
--force Write the output even if it is larger than the input
-Z, --zopfli Use the much slower but stronger Zopfli compressor
--timeout <secs> Maximum amount of time to spend on optimizations
-t, --threads <num> Set number of threads to use [default: num CPU cores]
-h, --help Print help (see more with '--help')
-V, --version Print version
Run `oxipng --help` to see full details of all options
```
---------
Co-authored-by: Alejandro González <me@alegon.dev>
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.
* 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>
* Update Zopfli and several other depenencies
I've just published a new Zopfli release, v0.7.3, which includes several
new features and internal refactors. Performance should be a tad bit
better, but I didn't test it throughly, so YMMV. Perhaps more
importantly for OxiPNG, its dependency tree is smaller, and
Gzip-exclusive compression code can be excluded at compile time thanks
to new feature switches. As I mentioned on
https://github.com/shssoichiro/oxipng/pull/495#issuecomment-1552669505,
I plan on delivering more significant Zopfli performance improvements at
some point, but for now I think it's good to give the new release more
real-world usage and testing 😄
While at it, I've upgraded other dependencies that are not
performance-critical to their latest semver-compatible versions. This
excludes `libdeflater` on purpose, as its performance characteristics
are said to be somewhat different.
* Update Zopfli to v0.7.4
v0.7.3 was superseeded shortly after v0.7.3 was released to address a
last minute change to the new API it introduced. OxiPNG is not affected
by this, but I think it's good practice to update Zopfli anyway.
* 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
* 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
* 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.
Oxipng has an optional dependency on stderrlog, which itself has a
dependency on thread_local. Versions of thread_local < 1.1.4 have a
vulnerability caused by a data race in Iter and IterMut. Updating to
stderrlog v0.5.1 ensures that Oxipng uses a patched version of
thread_local.
https://rustsec.org/advisories/RUSTSEC-2022-0006.html