Compare commits
No commits in common. "master" and "v10.1.0" have entirely different histories.
17 changed files with 365 additions and 255 deletions
|
|
@ -1,7 +1,4 @@
|
|||
scripts
|
||||
.github
|
||||
.editorconfig
|
||||
.gitignore
|
||||
/.git/
|
||||
/.github/
|
||||
/.pre-commit-hooks.yaml
|
||||
/scripts/
|
||||
/target/
|
||||
.pre-commit-hooks.yaml
|
||||
|
|
|
|||
19
.github/workflows/deploy.yml
vendored
19
.github/workflows/deploy.yml
vendored
|
|
@ -3,12 +3,7 @@ name: deploy
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
|
||||
concurrency:
|
||||
# If we ever end up with two concurrent jobs for releasing the same tag, the former should be cancelled
|
||||
group: release-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
- "v*.*.*"
|
||||
|
||||
permissions:
|
||||
actions: read
|
||||
|
|
@ -59,15 +54,15 @@ jobs:
|
|||
|
||||
- name: Get the Oxipng version
|
||||
id: oxipngMeta
|
||||
run: >
|
||||
echo "version=$(cargo metadata --format-version 1 --no-deps |
|
||||
jq -r '.packages[] | select(.name == "oxipng").version')" >> "$GITHUB_OUTPUT"
|
||||
run:
|
||||
echo "version=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "oxipng").version')"
|
||||
>> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Retrieve ${{ matrix.target }} binary
|
||||
uses: dawidd6/action-download-artifact@v21
|
||||
uses: dawidd6/action-download-artifact@v12
|
||||
with:
|
||||
workflow: oxipng.yml
|
||||
commit: ${{ github.sha }}
|
||||
commit: ${{ env.GITHUB_SHA }}
|
||||
name: Oxipng binary (${{ matrix.target }})
|
||||
path: target
|
||||
|
||||
|
|
@ -128,7 +123,7 @@ jobs:
|
|||
run: tail -n +3 CHANGELOG.md | sed -e '/^$/,$d' > RELEASE_NOTES.txt
|
||||
|
||||
- name: Create release
|
||||
uses: softprops/action-gh-release@v3
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: v${{ steps.oxipngMeta.outputs.version }}
|
||||
body_path: RELEASE_NOTES.txt
|
||||
|
|
|
|||
96
.github/workflows/docker.yml
vendored
96
.github/workflows/docker.yml
vendored
|
|
@ -2,9 +2,9 @@ name: docker
|
|||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'master'
|
||||
tags:
|
||||
- v*.*.*
|
||||
- 'v*.*.*'
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
|
|
@ -17,44 +17,76 @@ on:
|
|||
type: boolean
|
||||
default: true
|
||||
|
||||
concurrency:
|
||||
# If we ever end up with two concurrent Docker build jobs for the same commit
|
||||
# and same versioning context, the former should be cancelled
|
||||
group: docker-${{ github.sha }}-${{ github.ref_type }}-${{ github.head_ref }}
|
||||
cancel-in-progress: true
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
# ghcr.io/OWNER/REPO
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
uses: docker/github-builder/.github/workflows/build.yml@v1
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
id-token: write
|
||||
attestations: write
|
||||
with:
|
||||
output: image
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
cache: ${{ github.event_name != 'workflow_dispatch' || inputs.use_cache }}
|
||||
# We don't sign the image because ghcr.io doesn't support OCI Referrers API yet, and the fallback relies on pushing new tags on each build
|
||||
# https://github.com/docker/github-builder/issues/109#issuecomment-3885082486
|
||||
# https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#backwards-compatibility
|
||||
sign: false
|
||||
sbom: true
|
||||
meta-images: ghcr.io/${{ github.repository }}
|
||||
meta-tags: |
|
||||
type=ref,event=branch
|
||||
type=ref,event=pr
|
||||
type=semver,pattern={{raw}}
|
||||
set-meta-annotations: true
|
||||
set-meta-labels: true
|
||||
labels: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
annotations: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
|
||||
secrets:
|
||||
registry-auths: |
|
||||
- registry: ghcr.io
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
# Workaround: https://github.com/docker/build-push-action/issues/461
|
||||
- name: Setup Docker buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
# Login against a Docker registry except on PR
|
||||
# https://github.com/docker/login-action
|
||||
- name: Log into registry ${{ env.REGISTRY }}
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Extract metadata (tags, labels) for Docker
|
||||
# For some reason the title have to be set manually
|
||||
# https://github.com/docker/metadata-action
|
||||
- name: Extract Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
labels: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
annotations: |
|
||||
org.opencontainers.image.title=Oxipng
|
||||
|
||||
# Build and push Docker image with Buildx (don't push on PR)
|
||||
# Cache isn't used for tags and on workflow_dispatch if specified
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
no-cache: ${{ (github.event_name == 'workflow_dispatch' && !inputs.use_cache) || startsWith(github.ref, 'refs/tags/') }}
|
||||
|
||||
# Attest the build provenance
|
||||
# TODO: enable push to registry when referrers API will be supported by ghcr.io
|
||||
- name: Attest Build Provenance
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: actions/attest-build-provenance@v3
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
subject-digest: ${{ steps.build-and-push.outputs.digest }}
|
||||
push-to-registry: false
|
||||
|
|
|
|||
14
.github/workflows/oxipng.yml
vendored
14
.github/workflows/oxipng.yml
vendored
|
|
@ -8,11 +8,6 @@ on:
|
|||
- synchronize
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
# If we ever end up with two concurrent CI jobs for the same commit, the former should be cancelled
|
||||
group: ci-${{ github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
name: CI
|
||||
|
|
@ -60,6 +55,7 @@ jobs:
|
|||
|
||||
env:
|
||||
CARGO_BUILD_TARGET: ${{ matrix.target }}
|
||||
RUSTFLAGS: '-Zlocation-detail=none'
|
||||
|
||||
steps:
|
||||
- name: Checkout source
|
||||
|
|
@ -78,7 +74,7 @@ jobs:
|
|||
with:
|
||||
toolchain: nightly
|
||||
target: ${{ env.CARGO_BUILD_TARGET }}
|
||||
components: clippy, rustfmt, rust-src
|
||||
components: clippy, rustfmt
|
||||
cache-bin: false
|
||||
cache-shared-key: cache
|
||||
|
||||
|
|
@ -129,12 +125,10 @@ jobs:
|
|||
run: cargo doc --release --no-deps
|
||||
|
||||
- name: Build CLI binary
|
||||
run: cargo build --release -Zbuild-std
|
||||
env:
|
||||
RUSTFLAGS: "-Zlocation-detail=none -Zunstable-options -Cpanic=immediate-abort"
|
||||
run: cargo build --release
|
||||
|
||||
- name: Upload CLI binary as artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: Oxipng binary (${{ matrix.target }})
|
||||
path: |
|
||||
|
|
|
|||
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -1,6 +1,6 @@
|
|||
.DS_Store
|
||||
target
|
||||
*.bk
|
||||
.DS_Store
|
||||
*.out.png
|
||||
/.idea/
|
||||
/node_modules/
|
||||
/target/
|
||||
/.idea
|
||||
/node_modules
|
||||
|
|
|
|||
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -1,11 +1,3 @@
|
|||
## Version 10.1.1
|
||||
|
||||
- [Performance] Improve Bigrams performance, giving notably faster results at lower levels.
|
||||
- [Improvement] Change `--np` flag to also prevent conversion to indexed from other color types.
|
||||
- [Improvement] Improve support for recompressing ICC profiles with high compression ratios.
|
||||
- [Misc] Add warning when `--ziwi` exceeds `--zi`.
|
||||
- [Build] Further reduce size of binaries.
|
||||
|
||||
## Version 10.1.0
|
||||
|
||||
- [Feature] Add `--json` option for machine-readable output.
|
||||
|
|
@ -15,7 +7,7 @@
|
|||
## Version 10.0.0
|
||||
|
||||
- [Breaking] CLI: Change short zopfli flag from `-Z` to `-z`.
|
||||
- [Breaking] CLI: Change `--pretend`/`-P` to `--dry-run`/`-d`.
|
||||
- [Breaking] CLI: Change `--pretend`/`-P` to `--dry-run`/`-D`.
|
||||
- [Breaking] CLI: Change `--interlace` options from `1`/`0` to `on`/`off`.
|
||||
- [Breaking] API: Change `Options.interlace: Option<Interlacing>` to `Options.interlace: Option<bool>`.
|
||||
- [Breaking] API: Change `Options.filter: IndexSet<RowFilter>` to `Options.filters: IndexSet<FilterStrategy>`.
|
||||
|
|
|
|||
295
Cargo.lock
generated
295
Cargo.lock
generated
|
|
@ -10,9 +10,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "1.0.0"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
|
@ -25,37 +25,37 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.14"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "1.0.0"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.5"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.11"
|
||||
version = "3.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -66,9 +66,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.1"
|
||||
version = "2.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
|
|
@ -84,15 +84,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.20.2"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.25.0"
|
||||
version = "1.23.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
||||
checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder-lite"
|
||||
|
|
@ -102,9 +102,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
|||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.60"
|
||||
version = "1.2.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
|
||||
checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
|
|
@ -112,24 +112,24 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.6.1"
|
||||
version = "4.5.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
|
||||
checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.6.0"
|
||||
version = "4.5.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
|
||||
checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -140,15 +140,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "1.1.0"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.5"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
|
|
@ -159,6 +159,15 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.6"
|
||||
|
|
@ -192,18 +201,18 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "1.0.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef"
|
||||
checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.10"
|
||||
version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a"
|
||||
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
|
@ -224,7 +233,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -238,15 +247,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.9"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
||||
checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
|
|
@ -266,9 +275,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.0"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
|
||||
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
|
|
@ -285,9 +294,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.0"
|
||||
version = "2.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
|
|
@ -296,27 +305,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.185"
|
||||
version = "0.2.175"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
|
||||
|
||||
[[package]]
|
||||
name = "libdeflate-sys"
|
||||
version = "1.25.2"
|
||||
version = "1.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72753e0008ea87963d2f0770042d0df7abe51fafbb8dcaf618ac440f2f1fec0a"
|
||||
checksum = "23bd6304ebf75390d8a99b88bdf2a266f62647838140cb64af8e6702f6e3fddc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
|
|
@ -324,30 +333,30 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libdeflater"
|
||||
version = "1.25.2"
|
||||
version = "1.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1ee41cf6fb1bb6030dfb59ffb7bc01ab26aade44142084c87f0fc7a1658fe71"
|
||||
checksum = "d5d4880e6d634d3d029d65fa016038e788cc728a17b782684726fb34ee140caf"
|
||||
dependencies = [
|
||||
"libdeflate-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.12.1"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.30"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
|
|
@ -361,9 +370,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "moxcms"
|
||||
version = "0.7.11"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac9557c559cd6fc9867e122e20d2cbefc9ca29d80d027a8e39310920ed2f0a97"
|
||||
checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"pxfm",
|
||||
|
|
@ -380,16 +389,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.2"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "10.1.1"
|
||||
version = "10.1.0"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"clap",
|
||||
"crossbeam-channel",
|
||||
"env_logger",
|
||||
"glob",
|
||||
"image",
|
||||
|
|
@ -412,15 +422,15 @@ checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.33"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.18.1"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61"
|
||||
checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
|
|
@ -431,24 +441,27 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pxfm"
|
||||
version = "0.1.29"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0c5ccf5294c6ccd63a74f1565028353830a9c2f5eb0c682c355c471726a6e3f"
|
||||
checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
|
@ -461,9 +474,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
|||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.12.0"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d"
|
||||
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
|
|
@ -481,30 +494,30 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rgb"
|
||||
version = "0.8.53"
|
||||
version = "0.8.52"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
|
||||
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.2"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
"windows-sys 0.61.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -538,9 +551,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.150"
|
||||
version = "1.0.147"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
|
||||
checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
|
|
@ -557,9 +570,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.9"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
|
|
@ -569,9 +582,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
version = "2.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
@ -586,19 +599,19 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
|||
|
||||
[[package]]
|
||||
name = "terminal_size"
|
||||
version = "0.4.4"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874"
|
||||
checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
|
|
@ -608,19 +621,99 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link 0.1.3",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
|
|
@ -632,9 +725,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
checksum = "4af59da1029247450b54ba43e0b62c8e376582464bbe5504dd525fe521e7e8fd"
|
||||
|
||||
[[package]]
|
||||
name = "zopfli"
|
||||
|
|
|
|||
21
Cargo.toml
21
Cargo.toml
|
|
@ -20,7 +20,7 @@ homepage = "https://github.com/oxipng/oxipng"
|
|||
license = "MIT"
|
||||
name = "oxipng"
|
||||
repository = "https://github.com/oxipng/oxipng"
|
||||
version = "10.1.1"
|
||||
version = "10.1.0"
|
||||
rust-version = "1.85.1"
|
||||
|
||||
[badges]
|
||||
|
|
@ -39,28 +39,29 @@ required-features = ["zopfli"]
|
|||
|
||||
[dependencies]
|
||||
bitvec = "1.0.1"
|
||||
clap = { version = "4.6.0", optional = true, features = ["wrap_help"] }
|
||||
env_logger = { version = "0.11.10", optional = true, default-features = false, features = ["auto-color"] }
|
||||
clap = { version = "4.5.53", optional = true, features = ["wrap_help"] }
|
||||
crossbeam-channel = { version = "0.5.15", optional = true }
|
||||
env_logger = { version = "0.11.8", optional = true, default-features = false, features = ["auto-color"] }
|
||||
image = { version = "0.25.9", optional = true, default-features = false, features = ["png"] }
|
||||
indexmap = "2.14.0"
|
||||
libdeflater = "1.25.2"
|
||||
log = "0.4.30"
|
||||
indexmap = "2.13.0"
|
||||
libdeflater = "1.25.0"
|
||||
log = "0.4.29"
|
||||
parse-size = { version = "1.1.0", optional = true }
|
||||
rayon = { version = "1.11.0", optional = true }
|
||||
rgb = "0.8.53"
|
||||
rustc-hash = "2.1.2"
|
||||
rgb = "0.8.52"
|
||||
rustc-hash = "2.1.1"
|
||||
zopfli = { version = "0.8.3", optional = true, default-features = false, features = ["std", "zlib"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
glob = { version = "0.3.3", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_json = "1.0.150"
|
||||
serde_json = "1.0.147"
|
||||
|
||||
[features]
|
||||
binary = ["dep:clap", "dep:glob", "dep:env_logger", "dep:parse-size"]
|
||||
default = ["binary", "parallel", "zopfli"]
|
||||
parallel = ["dep:rayon", "indexmap/rayon"]
|
||||
parallel = ["dep:rayon", "indexmap/rayon", "dep:crossbeam-channel"]
|
||||
freestanding = ["libdeflater/freestanding"]
|
||||
sanity-checks = ["dep:image"]
|
||||
zopfli = ["dep:zopfli"]
|
||||
|
|
|
|||
66
README.md
66
README.md
|
|
@ -8,7 +8,7 @@
|
|||
## Overview
|
||||
|
||||
Oxipng is a multithreaded lossless PNG/APNG compression optimizer. It can be used via a command-line
|
||||
interface or as a library in other Rust programs. It is fast and highly effective.
|
||||
interface or as a library in other Rust programs.
|
||||
|
||||
## Installing
|
||||
|
||||
|
|
@ -76,14 +76,7 @@ All options are case-sensitive.
|
|||
\* Note that oxipng is not a brute-force optimizer. This means that while higher optimization levels
|
||||
are almost always better or equal to lower levels, this is not guaranteed and it is possible in
|
||||
rare circumstances that a lower level may give a marginally smaller output. Similarly, using Zopfli
|
||||
compression (`-z`) is not guaranteed to always be better than default compression.
|
||||
|
||||
## APNG support
|
||||
|
||||
Oxipng currently only supports limited optimization of animated PNGs (APNGs). It can perform
|
||||
alpha-optimization, refiltering and recompression of all frames, but all transformations will be
|
||||
disabled. For best results, it is recommended to use another tool such as
|
||||
[apngopt](https://sourceforge.net/projects/apng/files/APNG_Optimizer/) before running Oxipng.
|
||||
compression (`-z`) is not guaranteed to always be better than without.
|
||||
|
||||
## Git integration via [pre-commit]
|
||||
|
||||
|
|
@ -138,13 +131,17 @@ and specifying the desired ones, for example:
|
|||
|
||||
## History
|
||||
|
||||
Oxipng began in 2015 as a rewrite of the OptiPNG project. The core goal was to implement
|
||||
multithreading, which would have been very difficult to do within the existing C codebase of OptiPNG.
|
||||
Oxipng began as a complete rewrite of the OptiPNG project,
|
||||
which was assumed to be dead as no commit had been made to it since March 2014.
|
||||
(OptiPNG has since released a new version, after Oxipng was first released.)
|
||||
The name has been changed to avoid confusion and potential legal issues.
|
||||
|
||||
The core goal of rewriting OptiPNG was to implement multithreading,
|
||||
which would be very difficult to do within the existing C codebase of OptiPNG.
|
||||
This also served as an opportunity to choose a more modern, safer language (Rust).
|
||||
|
||||
However, Oxipng has evolved considerably since then. While some of the options remain similar to
|
||||
OptiPNG, the architecture and capabilities are now quite different. It is not a drop-in
|
||||
replacement - if you are migrating from OptiPNG, please check the [help](MANUAL.txt) before use.
|
||||
Note that, while similar, Oxipng is not a drop-in replacement for OptiPNG.
|
||||
If you are migrating from OptiPNG, please check the [help](MANUAL.txt) before using.
|
||||
|
||||
## Contributing
|
||||
|
||||
|
|
@ -154,11 +151,42 @@ to submit a fix with the bug report, it is preferred that you do so via pull req
|
|||
however you do not need to be a Rust developer to contribute.
|
||||
Other contributions (such as improving documentation or translations) are also welcome via GitHub.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
An independent benchmark is linked here with permission by the author:\
|
||||
[oxipng and friends: A comparison of PNG optimization tools](https://op111.net/posts/2025/09/png-compression-oxipng-optipng-fileoptimizer-cwebp/)
|
||||
|
||||
## License
|
||||
|
||||
Oxipng is open-source software, distributed under the MIT license.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Tested Oxipng 9.0.0 (commit `c16519b38b0519988db625913be919d4f0e42f5d`, compiled
|
||||
on `rustc 1.74.0-nightly (7b4d9e155 2023-09-28)`) against OptiPNG version 0.7.7,
|
||||
as packaged by Debian unstable, on a Linux 6.5.0-2-amd64 kernel, Intel Core
|
||||
i7-12700 CPU (8 performance cores, 4 efficiency cores, 20 threads), DDR5-5200
|
||||
RAM in dual channel configuration.
|
||||
|
||||
```
|
||||
|
||||
Benchmark 1: ./target/release/oxipng -P ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
Time (mean ± σ): 59.6 ms ± 7.7 ms [User: 77.4 ms, System: 3.6 ms]
|
||||
Range (min … max): 53.3 ms … 89.9 ms 32 runs
|
||||
|
||||
Benchmark 2: optipng -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
Time (mean ± σ): 132.4 ms ± 0.8 ms [User: 132.5 ms, System: 0.6 ms]
|
||||
Range (min … max): 131.8 ms … 134.4 ms 22 runs
|
||||
|
||||
Summary
|
||||
./target/release/oxipng -P ./tests/files/rgb_16_should_be_grayscale_8.png ran
|
||||
2.22 ± 0.29 times faster than optipng -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
|
||||
Benchmark 1: ./target/release/oxipng -o4 -P ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
Time (mean ± σ): 88.7 ms ± 4.3 ms [User: 270.3 ms, System: 11.0 ms]
|
||||
Range (min … max): 86.8 ms … 109.4 ms 26 runs
|
||||
|
||||
Benchmark 2: optipng -o 4 -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
Time (mean ± σ): 444.9 ms ± 0.3 ms [User: 444.8 ms, System: 0.7 ms]
|
||||
Range (min … max): 444.4 ms … 445.6 ms 10 runs
|
||||
|
||||
Summary
|
||||
./target/release/oxipng -o4 -P ./tests/files/rgb_16_should_be_grayscale_8.png ran
|
||||
5.01 ± 0.25 times faster than optipng -o 4 -simulate ./tests/files/rgb_16_should_be_grayscale_8.png
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -298,8 +298,6 @@ The default value depends on the optimization level preset.")
|
|||
.arg(
|
||||
Arg::new("no-palette-reduction")
|
||||
.help("Do not change color palette")
|
||||
.long_help("\
|
||||
Do not convert to indexed and do not modify an existing color palette.")
|
||||
.long("np")
|
||||
.action(ArgAction::SetTrue),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ use std::sync::{
|
|||
atomic::{AtomicUsize, Ordering::*},
|
||||
};
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
||||
use deflate::Deflater;
|
||||
use indexmap::IndexSet;
|
||||
use log::trace;
|
||||
use rayon::prelude::*;
|
||||
#[cfg(feature = "parallel")]
|
||||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
use crate::rayon;
|
||||
|
|
@ -73,7 +73,7 @@ impl Evaluator {
|
|||
final_round: bool,
|
||||
) -> Self {
|
||||
#[cfg(feature = "parallel")]
|
||||
let eval_channel = channel();
|
||||
let eval_channel = unbounded();
|
||||
Self {
|
||||
deadline,
|
||||
filters,
|
||||
|
|
|
|||
|
|
@ -263,11 +263,11 @@ pub fn extract_icc(iccp: &Chunk, max_size: Option<usize>) -> Option<Vec<u8>> {
|
|||
if compression_method != 0 {
|
||||
return None; // The profile is supposed to be compressed (method 0)
|
||||
}
|
||||
// Libdeflate works with a fixed size buffer. Since the decompressed size is unknown we have to
|
||||
// guess the required buffer size. We allow a fairly generous 10x factor with a minimum of 1000.
|
||||
let mut out_size = (compressed_data.len() * 10).max(1000);
|
||||
// For sanity, impose a default limit of 1MB.
|
||||
out_size = out_size.min(max_size.unwrap_or(1_000_000));
|
||||
// The decompressed size is unknown so we have to guess the required buffer size
|
||||
let mut out_size = compressed_data.len() * 2 + 1000;
|
||||
if let Some(max) = max_size {
|
||||
out_size = out_size.min(max);
|
||||
}
|
||||
match inflate(compressed_data, out_size) {
|
||||
Ok(icc) => Some(icc),
|
||||
Err(e) => {
|
||||
|
|
|
|||
10
src/main.rs
10
src/main.rs
|
|
@ -430,16 +430,6 @@ fn parse_opts_into_struct(
|
|||
let iterations_without_improvement = *matches
|
||||
.get_one::<NonZeroU64>("iterations-without-improvement")
|
||||
.unwrap_or(&NonZeroU64::MAX);
|
||||
|
||||
if iterations_without_improvement > iteration_count
|
||||
&& iterations_without_improvement != NonZeroU64::MAX
|
||||
{
|
||||
warn!(
|
||||
"--ziwi ({}) is higher than --zi ({}) and will never be reached.",
|
||||
iterations_without_improvement, iteration_count
|
||||
);
|
||||
}
|
||||
|
||||
opts.deflater = Deflater::Zopfli(ZopfliOptions {
|
||||
iteration_count,
|
||||
iterations_without_improvement,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
use std::{fs, path::Path, sync::Arc};
|
||||
|
||||
use bitvec::bitarr;
|
||||
use libdeflater::{CompressionLvl, Compressor};
|
||||
use log::warn;
|
||||
use rgb::ComponentSlice;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -190,7 +192,7 @@ impl PngData {
|
|||
ColorType::Indexed { palette } => {
|
||||
let mut palette_data = Vec::with_capacity(palette.len() * 3);
|
||||
for px in palette {
|
||||
palette_data.extend_from_slice(px.rgb().as_ref());
|
||||
palette_data.extend_from_slice(px.rgb().as_slice());
|
||||
}
|
||||
write_png_block(b"PLTE", &palette_data, &mut output);
|
||||
if let Some(last_trns) = palette.iter().rposition(|px| px.a != 255) {
|
||||
|
|
@ -372,12 +374,6 @@ impl PngImage {
|
|||
let mut f_buf = Vec::new();
|
||||
// For heuristic strategies, keep track of the actual filter used for each line
|
||||
let mut filters_used = Vec::new();
|
||||
// Pre-allocate buffers for the Bigrams strategy to avoid per-line allocations
|
||||
let (mut bigram_seen, mut bigram_touched) = if matches!(strategy, FilterStrategy::Bigrams) {
|
||||
(vec![false; 0x10000], Vec::<u16>::new())
|
||||
} else {
|
||||
(Vec::new(), Vec::new())
|
||||
};
|
||||
for (i, line) in self.scan_lines(false).enumerate() {
|
||||
if prev_pass != line.pass || line.data.len() != prev_line.len() {
|
||||
prev_line = vec![0; line.data.len()];
|
||||
|
|
@ -469,29 +465,18 @@ impl PngImage {
|
|||
let mut best_size = usize::MAX;
|
||||
for f in try_filters {
|
||||
f.filter_line(bpp, &mut line_data, &prev_line, &mut f_buf, alpha_bytes);
|
||||
let mut count = 0;
|
||||
let mut set = bitarr![0; 0x10000];
|
||||
for pair in f_buf.windows(2) {
|
||||
let bigram = ((pair[0] as usize) << 8) | pair[1] as usize;
|
||||
if !bigram_seen[bigram] {
|
||||
count += 1;
|
||||
if count >= best_size {
|
||||
break;
|
||||
}
|
||||
bigram_seen[bigram] = true;
|
||||
bigram_touched.push(bigram as u16);
|
||||
}
|
||||
set.set(bigram, true);
|
||||
}
|
||||
if count < best_size {
|
||||
best_size = count;
|
||||
let size = set.count_ones();
|
||||
if size < best_size {
|
||||
best_size = size;
|
||||
std::mem::swap(&mut best_line, &mut f_buf);
|
||||
best_line_raw.clone_from(&line_data);
|
||||
best_filter = *f;
|
||||
}
|
||||
// Clear only the entries that were touched
|
||||
for &idx in &bigram_touched {
|
||||
bigram_seen[idx as usize] = false;
|
||||
}
|
||||
bigram_touched.clear();
|
||||
}
|
||||
}
|
||||
FilterStrategy::BigEnt => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::hash::{BuildHasherDefault, Hash};
|
||||
|
||||
use indexmap::IndexSet;
|
||||
use rgb::{ComponentMap, FromSlice, RGB, RGBA, alt::Gray};
|
||||
use rgb::{ComponentMap, ComponentSlice, FromSlice, RGB, RGBA, alt::Gray};
|
||||
use rustc_hash::FxHasher;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -193,7 +193,7 @@ pub fn indexed_to_channels(
|
|||
let mut data = Vec::with_capacity(out_size);
|
||||
for b in &png.data {
|
||||
let color = palette.get(*b as usize).unwrap_or(&black);
|
||||
data.extend_from_slice(&color.as_ref()[ch_start..=ch_end]);
|
||||
data.extend_from_slice(&color.as_slice()[ch_start..=ch_end]);
|
||||
}
|
||||
|
||||
Some(PngImage {
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ pub(crate) fn perform_reductions(
|
|||
// Attempt to reduce to indexed
|
||||
// Keep the existing `png` var in case it is grayscale - we can test both for depth reduction later
|
||||
let mut indexed = None;
|
||||
if opts.color_type_reduction && opts.palette_reduction && !deadline.passed() {
|
||||
if opts.color_type_reduction && !deadline.passed() {
|
||||
if let Some(reduced) = reduced_to_indexed(&png, opts.grayscale_reduction) {
|
||||
// Make sure the palette gets sorted (but don't bother evaluating both results)
|
||||
let new = Arc::new(sorted_palette(&reduced).unwrap_or(reduced));
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use indexmap::indexset;
|
||||
use oxipng::{internal_tests::*, *};
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
fs::remove_file,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
|
||||
use indexmap::indexset;
|
||||
use oxipng::{internal_tests::*, *};
|
||||
use serde_json::Value;
|
||||
|
||||
const GRAY: u8 = 0;
|
||||
const RGB: u8 = 2;
|
||||
const INDEXED: u8 = 3;
|
||||
|
|
@ -96,9 +97,13 @@ fn test_it_converts(
|
|||
|
||||
#[test]
|
||||
fn verbose_mode() {
|
||||
use log::{Level, LevelFilter, Log, Metadata, Record, set_logger, set_max_level};
|
||||
use std::cell::RefCell;
|
||||
use std::sync::mpsc::{Sender, channel};
|
||||
#[cfg(not(feature = "parallel"))]
|
||||
use std::sync::mpsc::{Sender, channel as unbounded};
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
use crossbeam_channel::{Sender, unbounded};
|
||||
use log::{Level, LevelFilter, Log, Metadata, Record, set_logger, set_max_level};
|
||||
|
||||
// Rust runs tests in parallel by default.
|
||||
// We want to make sure that we verify only logs from our test.
|
||||
|
|
@ -138,7 +143,7 @@ fn verbose_mode() {
|
|||
let input = PathBuf::from("tests/files/verbose_mode.png");
|
||||
let (output, opts) = get_opts(&input);
|
||||
|
||||
let (sender, receiver) = channel();
|
||||
let (sender, receiver) = unbounded();
|
||||
|
||||
let thread_init = move || {
|
||||
// Initialise logs storage for all threads within our test.
|
||||
|
|
|
|||
Loading…
Reference in a new issue