Commit graph

946 commits

Author SHA1 Message Date
Alejandro González
5f0a0d6938
Fix new Clippy lints 2025-01-30 18:39:23 +01:00
andrews05
2632be2034
Fix size passed to fast filter evaluator (#672)
The evaluator uses the `estimated_output_size` internally but we were
passing only the idat size in the fast filter evaluator. At level `o2`,
or higher levels when using `--fast`, this could cause a slight bias
towards the None and Bigrams filters for indexed images. The actual
impact to results is incredibly minor but it's definitely incorrect so
we should fix it.
2025-01-30 18:28:42 +01:00
andrews05
bbde68ddce
Refactor optimize_raw (#670)
Code always tends to get messy over time. I've found the `optimize_raw`
function increasingly harder to read, particularly after the addition of
fast mode, so I've taken some time to refactor and simplify it.

One change of note here is the main compression trials now use the
Evaluator. This means verbose output is a little different which is
shown below.

There is no change to performance or output size.

`-vvo2`: master
```
Processing: tests/files/rgba_8_should_be_palette_4.png
    500x400 pixels, PNG format
    8-bit RGB + Alpha, non-interlaced
    IDAT size = 2757 bytes
    File size = 18109 bytes
Eval: 4-bit Indexed (5 colors)      None       1837 bytes
Eval: 8-bit Indexed (5 colors)      None       1988 bytes
Eval: 4-bit Indexed (5 colors)      Bigrams   >1837 bytes
Eval: 8-bit Indexed (5 colors)      Bigrams   >1837 bytes
Transformed image to 4-bit Indexed (5 colors), non-interlaced
Evaluating: 2 filters
Eval: 4-bit Indexed (5 colors)      Sub       >1810 bytes
Eval: 4-bit Indexed (5 colors)      Entropy   >1810 bytes
Trying: None
    zc = 11  f = None      1583 bytes
Found better combination:
    zc = 11  f = None      1583 bytes
    IDAT size = 1583 bytes (1174 bytes decrease)
    file size = 16962 bytes (1147 bytes = 6.33% decrease)
16962 bytes (6.33% smaller): Running in pretend mode, no output
```

`-vvo2`: PR
```
Processing: tests/files/rgba_8_should_be_palette_4.png
    500x400 pixels, PNG format
    8-bit RGB + Alpha, non-interlaced
    IDAT size = 2757 bytes
    File size = 18109 bytes
Eval: 4-bit Indexed (5 colors)      None       1837 bytes
Eval: 8-bit Indexed (5 colors)      None       1988 bytes
Eval: 4-bit Indexed (5 colors)      Bigrams   >1837 bytes
Eval: 8-bit Indexed (5 colors)      Bigrams   >1837 bytes
Transformed image to 4-bit Indexed (5 colors), non-interlaced
Evaluating 2 filters
Eval: 4-bit Indexed (5 colors)      Sub       >1810 bytes
Eval: 4-bit Indexed (5 colors)      Entropy   >1810 bytes
Trying filter None with zc = 11
1610 bytes
Found better result:
    zc = 11, f = None
    IDAT size = 1583 bytes (1174 bytes decrease)
    file size = 16962 bytes (1147 bytes = 6.33% decrease)
16962 bytes (6.33% smaller): Running in pretend mode, no output
```

`-vvZo5`: master
```
Processing: tests/files/rgba_8_should_be_palette_4.png
    500x400 pixels, PNG format
    8-bit RGB + Alpha, non-interlaced
    IDAT size = 2757 bytes
    File size = 18109 bytes
Eval: 8-bit Indexed (battiato sort) None       1821 bytes
Eval: 4-bit Indexed (5 colors)      None       1657 bytes
Eval: 8-bit Indexed (mzeng sort)    None       1821 bytes
Eval: 8-bit Indexed (5 colors)      None       1821 bytes
Eval: 8-bit Indexed (battiato sort) Bigrams   >1821 bytes
Eval: 4-bit Indexed (5 colors)      Bigrams   >1657 bytes
Eval: 8-bit Indexed (mzeng sort)    Bigrams   >1657 bytes
Eval: 8-bit Indexed (5 colors)      Bigrams   >1657 bytes
Transformed image to 4-bit Indexed (5 colors), non-interlaced
Trying: 8 filters
    zc = zopfli  f = Brute     1562 bytes
    zc = zopfli  f = Sub      >1562 bytes
    zc = zopfli  f = Bigrams  >1562 bytes
    zc = zopfli  f = None      1407 bytes
    zc = zopfli  f = Up       >1407 bytes
    zc = zopfli  f = MinSum   >1407 bytes
    zc = zopfli  f = BigEnt   >1407 bytes
    zc = zopfli  f = Entropy  >1407 bytes
Found better combination:
    zc = zopfli  f = None      1407 bytes
    IDAT size = 1407 bytes (1350 bytes decrease)
    file size = 16786 bytes (1323 bytes = 7.31% decrease)
16786 bytes (7.31% smaller): Running in pretend mode, no output
```

`-vvZo5`: PR
```
Processing: tests/files/rgba_8_should_be_palette_4.png
    500x400 pixels, PNG format
    8-bit RGB + Alpha, non-interlaced
    IDAT size = 2757 bytes
    File size = 18109 bytes
Eval: 8-bit Indexed (battiato sort) None       1821 bytes
Eval: 4-bit Indexed (5 colors)      None       1657 bytes
Eval: 8-bit Indexed (mzeng sort)    None       1821 bytes
Eval: 8-bit Indexed (5 colors)      None       1821 bytes
Eval: 8-bit Indexed (battiato sort) Bigrams   >1657 bytes
Eval: 4-bit Indexed (5 colors)      Bigrams   >1657 bytes
Eval: 8-bit Indexed (mzeng sort)    Bigrams   >1657 bytes
Eval: 8-bit Indexed (5 colors)      Bigrams   >1657 bytes
Transformed image to 4-bit Indexed (5 colors), non-interlaced
Trying 8 filters with zopfli, zi = 15
Eval: 4-bit Indexed (5 colors)      Brute      1589 bytes
Eval: 4-bit Indexed (5 colors)      Bigrams    1641 bytes
Eval: 4-bit Indexed (5 colors)      Sub        1711 bytes
Eval: 4-bit Indexed (5 colors)      None       1434 bytes
Eval: 4-bit Indexed (5 colors)      Up         1764 bytes
Eval: 4-bit Indexed (5 colors)      MinSum     1760 bytes
Eval: 4-bit Indexed (5 colors)      BigEnt     1742 bytes
Eval: 4-bit Indexed (5 colors)      Entropy    1748 bytes
Found better result:
    zopfli, zi = 15, f = None
    IDAT size = 1407 bytes (1350 bytes decrease)
    file size = 16786 bytes (1323 bytes = 7.31% decrease)
16786 bytes (7.31% smaller): Running in pretend mode, no output
```
2025-01-29 20:53:11 +01:00
andrews05
8a44cdbc84
Tweak eval cmp key for more consistent results (#671)
This changes the evaluator to prefer a later image instead of an earlier
one in the case of a tie. This gives more consistent results since the
baseline is always added last.

I also removed bit depth from the key since the uncompressed size should
cover that.

Fixes #649.
(Mostly. I did discover another possible but very rare issue: if
multiple colours tie for "most popular edge colour" in the luma sort,
the sort may affect which one is actually picked and multiple runs may
flip-flop back and forth)
2025-01-29 19:56:27 +01:00
Andrew
14b8b0e93a Error if fdAT invalid 2025-01-26 00:16:24 +01:00
Andrew
cca23b5479 Refilter frames 2025-01-26 00:16:24 +01:00
Andrew
09c4851118 Retain filter applied 2025-01-26 00:16:24 +01:00
Andrew
5fdaa12c96 Recompress frames 2025-01-26 00:16:24 +01:00
Andrew
fec6b2b9f3 Parse fcTL/fdAT into frames 2025-01-26 00:16:24 +01:00
Andrew
60911977f6 Add read_be_u16 and tidy parse_next_chunk 2025-01-26 00:16:24 +01:00
Andrew
6c7ab5d79f Add warning when interlacing was not enabled as requested 2025-01-16 12:37:33 +01:00
dependabot[bot]
3a6b792ca1 Bump actions/attest-build-provenance from 1 to 2
Bumps [actions/attest-build-provenance](https://github.com/actions/attest-build-provenance) from 1 to 2.
- [Release notes](https://github.com/actions/attest-build-provenance/releases)
- [Changelog](https://github.com/actions/attest-build-provenance/blob/main/RELEASE.md)
- [Commits](https://github.com/actions/attest-build-provenance/compare/v1...v2)

---
updated-dependencies:
- dependency-name: actions/attest-build-provenance
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-02 00:28:34 +01:00
Kornel
ffbd927d82 Remove obsolete flag warning 2025-01-02 09:40:52 +13:00
Kornel
a72bc945fc Clippy 2025-01-02 09:15:24 +13:00
Kornel
8270c6a034 Skip signed files or remove C2PA metadata 2024-12-26 19:03:03 +01:00
Kornel
910e779b09 Use ExitCode in main 2024-12-26 19:03:03 +01:00
Frank Elsinga
8740f475d7
docs: added the defaults for some Options (#661)
There are some parts of the `Options`-struct that miss the defaults.
I also made sure that `Interlacing` is a link
2024-12-20 17:08:13 +01:00
Josh Holmer
4df1464f39
Add feature flag to use system libdeflate (#659)
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.
2024-12-03 20:02:03 +01:00
andrews05
8ebb5e6dfd
Cleanup tests (#656)
I've replaced a few tests with synthetic images and removed a number
that I don't believe are relevant anymore.

I've also removed the #553 test without replacement as I don't know how
to synthesise a replacement and the issue is still open anyway.

Going forward I think we should avoid adding any new "issue" tests and
instead synthesise something suitable in one of the other collections.

Closes #655.
2024-12-02 20:58:01 +01:00
dependabot[bot]
3b7467a5da
Bump dawidd6/action-download-artifact from 6 to 7 (#657)
Bumps
[dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
from 6 to 7.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/dawidd6/action-download-artifact/releases">dawidd6/action-download-artifact's
releases</a>.</em></p>
<blockquote>
<h2>v7</h2>
<h2>What's Changed</h2>
<ul>
<li>build(deps): bump fast-xml-parser from 4.4.0 to 4.4.1 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/299">dawidd6/action-download-artifact#299</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.7 to
2.1.9 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/300">dawidd6/action-download-artifact#300</a></li>
<li>build(deps): bump adm-zip from 0.5.14 to 0.5.15 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/301">dawidd6/action-download-artifact#301</a></li>
<li>build(deps): bump adm-zip from 0.5.15 to 0.5.16 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/306">dawidd6/action-download-artifact#306</a></li>
<li>build(deps): bump path-to-regexp from 6.2.2 to 6.3.0 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/307">dawidd6/action-download-artifact#307</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.9 to
2.1.10 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/311">dawidd6/action-download-artifact#311</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.0
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/310">dawidd6/action-download-artifact#310</a></li>
<li>build(deps): bump <code>@​actions/core</code> from 1.11.0 to 1.11.1
by <a href="https://github.com/dependabot"><code>@​dependabot</code></a>
in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/312">dawidd6/action-download-artifact#312</a></li>
<li>build(deps): bump <code>@​actions/artifact</code> from 2.1.10 to
2.1.11 by <a
href="https://github.com/dependabot"><code>@​dependabot</code></a> in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/313">dawidd6/action-download-artifact#313</a></li>
<li>build(deps): Fix cross-spawn &gt;=7.0.0 &lt;= 7.0.5 vulnerability by
<a href="https://github.com/alexcouret"><code>@​alexcouret</code></a> in
<a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/317">dawidd6/action-download-artifact#317</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a
href="https://github.com/alexcouret"><code>@​alexcouret</code></a> made
their first contribution in <a
href="https://redirect.github.com/dawidd6/action-download-artifact/pull/317">dawidd6/action-download-artifact#317</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/dawidd6/action-download-artifact/compare/v6...v7">https://github.com/dawidd6/action-download-artifact/compare/v6...v7</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="80620a5d27"><code>80620a5</code></a>
node_modules: update</li>
<li><a
href="b15e003f46"><code>b15e003</code></a>
node_modules: install</li>
<li><a
href="1ee9a455fd"><code>1ee9a45</code></a>
build(deps): Fix cross-spawn &gt;=7.0.0 &lt;= 7.0.5 vulnerability (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/317">#317</a>)</li>
<li><a
href="b2f2706ac4"><code>b2f2706</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.10 to 2.1.11
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/313">#313</a>)</li>
<li><a
href="fdbeba027c"><code>fdbeba0</code></a>
build(deps): bump <code>@​actions/core</code> from 1.11.0 to 1.11.1 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/312">#312</a>)</li>
<li><a
href="a74b42987a"><code>a74b429</code></a>
build(deps): bump <code>@​actions/core</code> from 1.10.1 to 1.11.0 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/310">#310</a>)</li>
<li><a
href="24e807a70c"><code>24e807a</code></a>
build(deps): bump <code>@​actions/artifact</code> from 2.1.9 to 2.1.10
(<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/311">#311</a>)</li>
<li><a
href="9592e3c4ab"><code>9592e3c</code></a>
build(deps): bump path-to-regexp from 6.2.2 to 6.3.0 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/307">#307</a>)</li>
<li><a
href="5f966b63eb"><code>5f966b6</code></a>
build(deps): bump adm-zip from 0.5.15 to 0.5.16 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/306">#306</a>)</li>
<li><a
href="db9477a3eb"><code>db9477a</code></a>
build(deps): bump adm-zip from 0.5.14 to 0.5.15 (<a
href="https://redirect.github.com/dawidd6/action-download-artifact/issues/301">#301</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/dawidd6/action-download-artifact/compare/v6...v7">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=dawidd6/action-download-artifact&package-manager=github_actions&previous-version=6&new-version=7)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-02 20:32:44 +01:00
andrews05
262082f546
Fix manpage for --zi (#653)
I don't know if this is a bug in the mangen but it seems to require
explicitly setting the value name to display correctly.
Before:
```
       --zi [default: 15]
              Set the number of iterations to use for Zopfli compression.
```

After:
```
       --zi=iterations [default: 15]
              Set the number of iterations to use for Zopfli compression.
```

This does not affect MANUAL.txt or the built-in help.
2024-12-02 12:34:52 +01:00
Kornel
f8c84c258d API docs 2024-11-30 13:28:05 +13:00
andrews05
e8e8309c2d
Bump version to 9.1.3 (#647)
Some checks failed
deploy / Deploy release (push) Has been cancelled
docker / build (push) Has been cancelled
oxipng / CI (push) Has been cancelled
oxipng / MSRV check (push) Has been cancelled
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.
2024-11-29 17:36:50 +01:00
Alejandro González
e638807d33
Add keywords to Cargo package manifest
This was recommended by `lib.rs`'s maintainer dashboard, and it's
actually a good idea for making the crate more discoverable, I think.
2024-11-28 21:33:37 +01:00
andrews05
ca05d99be4
Assume None if the line is all zeros (#650)
#648 may have been a bit hasty - I realised afterward that there's a
simpler way to achieve the same thing, and include the Brute filter as
well.

This reverts #648 and instead just picks None up front if the line is
all zeros. This is guaranteed to be the chosen filter for MinSum,
Entropy, Bigrams and BigEnt. It's almost certainly true for Brute as
well but this is harder to prove. I've tested this across hundreds of
images and found no change in output.
2024-11-28 17:21:10 +01:00
andrews05
1efacace9f
Break when best possible filter result found 2024-11-27 00:52:21 +13:00
andrews05
1936861b91
Workaround weird regression with &[u8] and zopfli (#595)
Fixes #579. In lack of a proper understanding of what's going on here
and why the issue is happening, this workaround will do for now.
2024-11-26 12:41:18 +01:00
Alejandro González
f602e84fa6
Remove obsolete extern crate oxipng advice in lib usage instructions
This syntax hasn't been required since at least Rust's 2018 edition,
except in very specialized scenarios where you want to convince the
compiler that a crate is actually used to guarantee that the
side-effects of its build script (e.g., library linking) are visible,
which do not apply to Oxipng in any case.
2024-11-25 18:59:38 +01:00
Alejandro González
e367f23c01
Upgrade x64 macOS CI workflows from macOS 12 to macOS 13
macOS 12 runners are scheduled for removal by GitHub: https://github.com/actions/runner-images/issues/10721
2024-11-25 18:56:31 +01:00
andrews05
cb97e69074
Add list of software using oxipng (#646)
This adds a short list of software using Oxipng to the read me. It's not
intended to be an exhaustive list, just some ones that I'm aware of that
may have broad general interest.

I've also removed the long section about Trunk which I'm not sure is
appropriate to include in this read me. Trunk users can find
documentation on this from Trunk directly.

Lastly, I've removed the older benchmark which I'm sure has no relevance
any more.
2024-11-25 18:42:48 +01:00
Karl Horky
490a4691cb
Fix name capitalization (#630)
Hi, thanks for Oxipng!

I saw further down in the readme that Oxipng was being used in the
middle of a sentence with a capital O, so I adjusted the other lowercase
usages (other than the usages in backticks, which may instead refer to
the command line program itself) from "oxipng" to also use "Oxipng"
2024-11-24 14:17:53 +01:00
AFCMS
ef64dd0768
Improved Docker image + publish on ghcr.io (#642)
Fix #610

- [x] Native cross-compilation support in Dockerfile. Only `linux/amd64`
and `linux/arm64` supported and tested (Tier 1 platform support from
Rust)
- [x] Cache support for cargo downloads and compilation results in
Dockerfile
- [x] Open Container's
[annotations](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
in Dockerfile
- [x] GitHub Actions workflow to build the image for both platforms,
publishing to ghcr.io on tags and master branch pushes.
- [x] Disable use of GitHub Actions cache for tags build, allow manually
triggering the workflow with or without cache.
- [x] [Attestation
artifacts](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds)
for builds
- [x] Add basic informations about the use of the Docker image in README

I also changed the WORKDIR from `/src` to `/work`, because if got me
confused with the use of the src folder for the project source in the
first stage of the Dockerfile. It doesn't impact anything anyways since
you can mount the file where you want and have the program options point
to it.

**How to test?**
_After checking out the branch and making sure you have QEMU installed
to build/test_
```shell
# Docker sadly doesn't have yet the way to have locally a tag with multiple platforms
# despite being able to pass multiple platforms to the build command, so we have to use two distinct tags.
docker build --platform=linux/amd64 --tag test-oxipng-amd:latest --load .
docker build --platform=linux/arm64 --tag test-oxipng-arm:latest --load .

docker run --rm test-oxipng-amd:latest --version
docker run --rm test-oxipng-arm:latest --version

# Run on some files
docker run --rm -it -v $(pwd):/work test-oxipng-amd:latest -a /work/tests/files/apng_file.png
docker run --rm -it -v $(pwd):/work test-oxipng-arm:latest -a /work/tests/files/apng_file.png

# Remove the images
docker image rm test-oxipng-amd:latest
docker image rm test-oxipng-arm:latest
```

For the workflow, see the GitHub Actions logs. If you want to test the
ghcr.io publishing you can merge the branch into a fork and see the
result.

---------

Co-authored-by: Alejandro González <me@alegon.dev>
2024-11-24 14:08:11 +01:00
Alejandro González
c81a863e69
Move manpages generation to an xtask (#645)
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.
2024-11-24 13:57:29 +01:00
Alejandro González
e7f1c04488
Update dependency declarations and lockfile to the latest versions 2024-11-19 22:46:00 +01:00
Alejandro González
e83c6725dc
Tweak Cargo config comment placement 2024-11-19 22:40:26 +01:00
Alejandro González
95eea28c82
Tweak README wording on installer to mention Windows package managers 2024-11-19 22:03:27 +01:00
Alejandro González
ac943da875
Remove unused build dependency
It's been like that for a while!
2024-11-19 21:36:06 +01:00
Alejandro González
59e0509a58
Fix new Clippy lint 2024-11-19 21:36:06 +01:00
Alejandro González
44619fd24d
Fix new Clippy lint about manual div_ceil implementation
This numeric method was added on Rust 1.73, which is below our MSRV.
2024-09-28 15:42:02 +02:00
Alejandro González
7a29741f18
Run cargo fmt 2024-09-28 15:41:54 +02:00
Galaxy4594
0d60e8b7c6
Expose zc level 0 (uncompressed) 🚀 (#641)
Allow the creation of PNGs with uncompressed deflate streams via level 0
of libdeflate. If you want a glorified BMP with delta filters, this
change will make your dreams come true 🙂.
2024-09-05 00:32:28 +02:00
Matthew House
0f24120c9a
Add option for Zopfli iteration count (#640)
This PR extends the `--zopfli` argument with an optional iteration
count. In my case, I have a bunch of very small images (a few kB or
less), and I often like to use hundreds of iterations to squeeze off the
last several bytes. (I know that this crate isn't intended for
brute-force optimization, but I've found that some of its
transformations and filter strategies can be more creative than
`zopflipng`.) But this is also useful in the opposite direction, for
allowing Zopfli compression on large images where 15 iterations would be
prohibitive.
2024-08-07 21:09:47 +02:00
Alejandro González
1bb7109804
Another AArch64 Linux musl build fix attempt
After testing more thoroughly on my box, it turned out that the libgcc
linking workaround should indeed fix our build errors, but on CI that
did not happen because the `RUSTFLAGS` environment variable is set,
which takes precedence over any configuration at `.cargo/config.toml`.
Therefore, let's also add the workaround to `RUSTFLAGS` on the CI
workflow definition.

This should be a satisfactory enough stopgap solution that does not
require ourselves to be pinned to a specific nightly or drop these
builds until https://github.com/rust-lang/rust/issues/128401 is sorted
out.
2024-08-07 20:54:30 +02:00
Alejandro González
e2d58c112b
Fix CI AArch64 Linux musl builds
This is required to get PR #640 and further work on the repository
moving.
2024-08-07 16:12:06 +02:00
Alejandro González
61deab369b
Fix Clippy lints not causing CI workflow failure
It's easy to miss them out if CI is not aborted on a Clippy lint, and
this behavior change was an unintended regression when CodeQL
integration was added, so let's change it back.
2024-07-28 16:11:36 +02:00
andrews05
d30da6e8a0
Note that higher levels are not guaranteed to be better (#639)
Closes #638
2024-07-22 11:50:15 +02:00
Andrew
e8366882ad Bump version to 9.1.2
Some checks failed
oxipng / CI (push) Has been cancelled
deploy / Deploy release (push) Has been cancelled
oxipng / MSRV check (push) Has been cancelled
2024-07-13 09:39:25 +12:00
Alejandro González
664b27c4ca Do not fail workflow on static analysis results upload failures
When Clippy finds lints, it already aborts the workflow. No double
failure is needed.
2024-07-11 15:20:53 +12:00
Alejandro González
0506418157 Remove some now unnecessary Clippy lints allowances 2024-07-11 15:20:53 +12:00
Alejandro González
a8846b897d Make CI Clippy static analysis checks more robust
I have identified two potential improvements for how we perform static analysis
on our code in our CI pipeline:

- The `giraffate/clippy-action` we currently use has not been updated to Node
  20, and GitHub has repeatedly indicated that they will phase out actions that
  do not support the latest Node versions. Despite my efforts to help with the
  update by submitting a pull request upstream, it has been ignored for months
  despite its perceived ease of review, raising concerns about the ongoing
  maintenance of the action. This situation suggests we should explore
  alternative methods for integrating Clippy with GitHub's UI.
- As evidenced by PR 632, thoroughly testing Rust crates for every possible
  feature combination is often overlooked due to the tedious nature of the task.
  Our current CI setup only checks two feature combinations, which is far from
  comprehensive.

To address the first improvement, these changes drop `clippy-action` entirely in
favor of utilizing GitHub's native CodeQL SARIF (Static Analysis Results
Interchange Format) file integration. Since Clippy cannot directly output lints
in SARIF, `clippy-sarif` is used to convert Clippy's JSON output to SARIF.
Additionally, `sarif-fmt` is added to turn SARIF into a human-friendly display
format in the workflow run logs.

For the second improvement, let's use `cargo hack` with the `--feature-powerset`
flag to run Clippy for every possible feature combination. This approach strikes
a good balance between CI runtime and thoroughness, as the number of feature
combinations grows superlinearly with the number of features: running `cargo
nextest` for every powerset element would lead to excessively long CI times.
2024-07-11 15:20:53 +12:00