Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
workspaces: crate
- run: cargo check
- run: cargo check --workspace
working-directory: crate
- run: cargo clippy -- -D warnings
- run: cargo clippy --workspace --all-targets -- -D warnings
working-directory: crate
- run: cargo clippy -p corruption-corpus --all-targets --features driver -- -D warnings
working-directory: crate

test-unit:
Expand All @@ -68,7 +70,9 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
workspaces: crate
- run: cargo test
- run: cargo test --workspace
working-directory: crate
- run: cargo test -p corruption-corpus --features driver
working-directory: crate

wasm:
Expand All @@ -91,30 +95,30 @@ jobs:
echo "$HOME/.wasmtime/bin" >> $GITHUB_PATH

- name: Check (scalar)
run: cargo check --target wasm32-wasip1
run: cargo check --workspace --target wasm32-wasip1
working-directory: crate

- name: Check (SIMD128)
env:
RUSTFLAGS: "-C target-feature=+simd128"
run: cargo check --target wasm32-wasip1
run: cargo check --workspace --target wasm32-wasip1
working-directory: crate

- name: Clippy (wasm32)
run: cargo clippy --target wasm32-wasip1 -- -D warnings
run: cargo clippy --workspace --target wasm32-wasip1 -- -D warnings
working-directory: crate

- name: Test (SIMD128)
env:
RUSTFLAGS: "-C target-feature=+simd128"
CARGO_TARGET_WASM32_WASIP1_RUNNER: "wasmtime --dir ."
run: cargo test --lib --target wasm32-wasip1
run: cargo test --lib --workspace --target wasm32-wasip1
working-directory: crate

- name: Test (scalar)
env:
CARGO_TARGET_WASM32_WASIP1_RUNNER: "wasmtime --dir ."
run: cargo test --lib --target wasm32-wasip1
run: cargo test --lib --workspace --target wasm32-wasip1
working-directory: crate

test-integration:
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ qoi-benchmark/.tmp_download/

# wasm test temp directory (created by tests::wasm::test_read_only_cache)
crate/.corpus-test-tmp/

# Multi-agent coordination marker (never committed)
.workongoing

# Corruption-corpus driver output (generated PNGs/JPEGs)
crate/corruption-out/
5 changes: 5 additions & 0 deletions crate/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## [Unreleased]

### Changed
- Extracted the structural-corruption generator — which briefly lived here as the `corruptions` module + optional `driver` feature (never shipped in a tagged codec-corpus release) — into a new sibling workspace crate, [`corruption-corpus`](corruption-corpus/README.md), decoupling the corpus *fetcher* from the corruption *generator*. codec-corpus no longer depends on the `image` crate; the `driver` feature and the `corruption_corpus` example now live in `corruption-corpus`.

## [1.1.0] - 2026-04-14

### Added
Expand Down
145 changes: 145 additions & 0 deletions crate/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crate/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[workspace]
members = ["corruption-corpus"]

[package]
name = "codec-corpus"
Expand Down
10 changes: 10 additions & 0 deletions crate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,16 @@ let err = corpus.get("not-yet-cached").unwrap_err();

Calling `get()` for an uncached dataset on WASM returns `Error::DownloadUnsupported` (not `NetworkUnavailable`). This is intentional — downloads must happen host-side.

## Structural-corruption corpus

The structural-corruption *generator* — a held-out falsification set for a
perceptual metric's negative tail (channel swaps, dropped blocks, off-by-one
edges, and seven more deterministic distortion families) — lives in the sibling
**[`corruption-corpus`](corruption-corpus/)** workspace crate, decoupled from
this fetcher. See its [README](corruption-corpus/README.md) for the family
catalog, the `score(corruption) < score(q20-anchor)` gate, and the
`corruption_corpus` generator example.

## Dependencies

Four Rust crates, all small:
Expand Down
2 changes: 2 additions & 0 deletions crate/corruption-corpus/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
/corruption-out
21 changes: 21 additions & 0 deletions crate/corruption-corpus/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

## [Unreleased]

### Added
- **Initial extraction** from `codec-corpus` — this crate was the
`codec_corpus::corruptions` module through codec-corpus 1.1.x, now split into
its own workspace member so the structural-corruption *generator* is decoupled
from the corpus *fetcher*. The module was self-contained (it depended only on
`image`, `serde`, and its own `prng`), so the split is a clean move; no logic
changed.
- Structural-corruption distortion corpus: ten deterministic (SplitMix64-seeded,
dependency-free) distortion families parameterized by region size + severity,
plus a `ManifestEntry` schema and the `catalog()` / `manifest_for_reference()`
sweep generators. Pure RGB-buffer math; stays in the default build and
compiles to WASM.
- **`driver` feature** (optional `image` dep): the `driver` module builds the
score-ready quad `(reference, corruption, q20-anchor, q10-anchor)` for the
metric gate `score(corruption) < score(q20)`, plus the `corruption_corpus`
example that emits images + `_MANIFEST.json` on demand (no corrupted bytes
committed).
40 changes: 40 additions & 0 deletions crate/corruption-corpus/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[package]
name = "corruption-corpus"
version = "0.1.0"
edition = "2024"
description = "Deterministic structural-corruption image generator — a held-out falsification set for a perceptual metric's negative tail (channel swaps, dropped blocks, off-by-one edges, bit-flips, geometric, chroma-boundary, overlay, tone)"
license = "Apache-2.0"
repository = "https://github.com/imazen/codec-corpus"
readme = "README.md"
keywords = ["image", "corruption", "test-data", "perceptual", "metric"]
categories = ["development-tools::testing", "multimedia::images"]
rust-version = "1.85"

[lib]
name = "corruption_corpus"

[dependencies]
serde = { version = "1", features = ["derive"] }

# `image` is only needed by the `driver` feature (loading reference images +
# encoding/decoding JPEG anchors). The corruption generators themselves are pure
# RGB-buffer math with no decode dependency, so they stay in the default build
# and remain wasm-clean.
image = { version = "0.25.10", optional = true, default-features = false, features = [
"png",
"jpeg",
] }

[dev-dependencies]
serde_json = "1"

[features]
default = []
# Enables the corruption `driver` module which loads reference PNGs and emits
# JPEG q20/q10 honest-lq anchors via the `image` crate. Without it, only the
# seeded in-memory generators + manifest types are available.
driver = ["dep:image"]

[[example]]
name = "corruption_corpus"
required-features = ["driver"]
Loading