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 makes 3 changes that together reduce binary size by around 25%:
- Sets lto="fat" in cargo.toml
- Sets panic="abort" in cargo.toml
- Sets location-detail=none in RUSTFLAGS
Closes#571
An unrelated change: I've replaced the zopfli test file with a smaller
one that runs much faster, as well as removing the slow test for
issue-133 which was related to an older alpha optimisation that is no
longer relevant.
There was an incorrect glob `bench/*` that was doing nothing, since the
benchmarks are in `benches/`; when I corrected it to `benches/*`, `cargo
publish --dry-run` failed:
```
error: failed to verify package tarball
Caused by:
failed to parse manifest at `/home/ben/src/forks/oxipng/target/package/oxipng-9.0.0/Cargo.toml`
Caused by:
can't find `zopfli` bench at `benches/zopfli.rs` or `benches/zopfli/main.rs`. Please specify bench.path if you want to use a non-default path.
```
…so I stopped trying to exclude the benchmarks from published crates at
all.
-----
Then, I added `Dockerfile`, `index.html`, and `scripts/` to the list of
paths to exclude from published crates.
Finally, I added some unnecessary “dotfiles” to the list of paths to
exclude from published crates.
-----
Some of this was suggested in a [package review for Fedora
Linux](https://bugzilla.redhat.com/show_bug.cgi?id=2259760).
After the PR:
```
$ cargo package --list
.cargo/config.toml
.cargo_vcs_info.json
CHANGELOG.md
Cargo.lock
Cargo.toml
Cargo.toml.orig
LICENSE
MANUAL.txt
README.md
benches/deflate.rs
[…]
benches/zopfli.rs
src/atomicmin.rs
[…]
src/sanity_checks.rs
$ cargo publish --dry-run
[…]
Compiling oxipng v9.0.0 (/home/ben/src/forks/oxipng/target/package/oxipng-9.0.0)
Finished dev [optimized + debuginfo] target(s) in 15.76s
Packaged 37 files, 255.4KiB (61.6KiB compressed)
Uploading oxipng v9.0.0 (/home/ben/src/forks/oxipng)
warning: aborting upload due to dry run
```
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.
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>
* 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.
* 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
`crossbeam-channel` is only used if the `parallel` flag is enabled, so
it can be gated behind that feature flag to potentially reduce the size
of the build dependency tree for dependent projects.
While at it, I've fixed several warnings emmitted in tests/flags.rs.
The `itertools` dependency became unused at a3b104a2ed, so there is no point in declaring it as a dependency any longer.
This was detected with the help of the
[`cargo-udeps`](https://github.com/est31/cargo-udeps) tool. I then
verified that it was not a false positive.
* 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