From f7abea5125325234d5f5bb5e12d4f0f0c96e49d6 Mon Sep 17 00:00:00 2001 From: Lilith River Date: Tue, 16 Jun 2026 03:49:25 -0600 Subject: [PATCH] =?UTF-8?q?docs(codec-eval):=20make=20the=20API=20quick-st?= =?UTF-8?q?art=20compilable=20=E2=80=94=20real=20callback=20signature=20+?= =?UTF-8?q?=20report-read=20+=20quality=5Flevels=20semantics=20(insulated-?= =?UTF-8?q?dev=20usability=20test)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ README.md | 46 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75e6f36..353b736 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Versioned public-API surface snapshot at `docs/public-api/codec-eval.txt`, regenerated by `tests/public_api_doc.rs` on every `cargo test` (`ZEN_API_DOC=regen|check|off`); CI lint job verifies it is current +### Documentation + +- Made the README API quick-start compilable: real encode-callback signature (`Fn(&ImageData, &EncodeRequest) -> Result>`), the correct `evaluate_image` call (the prior `evaluate_corpus` does not exist), a results-reading snippet over `ImageReport::results`, clarified that `quality_levels`/`request.quality` are encoder quality (0-100) rather than target metric scores, and accurate crates.io vs git install lines (compile-verified) + ### Changed - Excluded dev-only files from published crate tarball (`.gitignore`, `CONTRIBUTING.md`, `INTEGRATION.md`, `baselines/`, `plans/`, `scripts/`, `corpus/sharpened-800px/`) diff --git a/README.md b/README.md index 75bc1ea..b772810 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,13 @@ A practical guide to comparing image codecs fairly, with metrics accuracy data, **Want to improve this tool?** See **[CONTRIBUTING.md](CONTRIBUTING.md)**. We actively want input from codec developers—you know your domain better than we do. ```bash -# Quick start +# Quick start: the library is published on crates.io +cargo add codec-eval + +# Track the latest unreleased changes from git instead cargo add codec-eval --git https://github.com/imazen/codec-eval -# Or use the CLI +# The companion CLI is git-only (not yet published) cargo install --git https://github.com/imazen/codec-eval codec-eval-cli ``` @@ -28,23 +31,54 @@ cargo install --git https://github.com/imazen/codec-eval codec-eval-cli **API-first design**: You provide encode/decode callbacks, the library handles everything else. ```rust -use codec_eval::{EvalSession, EvalConfig, ViewingCondition}; +use codec_eval::{EvalSession, EvalConfig, ViewingCondition, ImageData, Result}; +use codec_eval::eval::session::EncodeRequest; // not re-exported at the crate root let config = EvalConfig::builder() .report_dir("./reports") .viewing(ViewingCondition::desktop()) + // Encoder quality settings (0-100), swept per codec. NOT target metric + // scores — your callback maps `request.quality` onto your encoder's dial. .quality_levels(vec![60.0, 80.0, 95.0]) .build(); let mut session = EvalSession::new(config); -session.add_codec("my-codec", "1.0", Box::new(|image, request| { - my_codec::encode(image, request.quality) +// The encode callback is `Fn(&ImageData, &EncodeRequest) -> Result>`. +// `ImageData` is an enum (RGB8/RGBA8 imgref or raw slice + dims); `request.quality` +// is the f64 (0-100) drawn from `quality_levels`. Return the encoded bytes. +session.add_codec("my-codec", "1.0", Box::new(|image: &ImageData, request: &EncodeRequest| -> Result> { + let rgb: Vec = image.to_rgb8_vec(); // tightly-packed RGB8 + let (w, h) = (image.width(), image.height()); + my_codec::encode(&rgb, w, h, request.quality) // -> Result> })); -let report = session.evaluate_corpus("./test_images")?; +// Evaluate one decoded reference image across every registered codec and +// quality level. Returns an `ImageReport` whose `.results` is a `Vec`. +let reference: ImageData = load_png_as_image_data("test.png")?; +let report = session.evaluate_image("test.png", reference)?; + +// Read the results: each CodecResult carries the codec id, the quality used, +// encoded size, and the metric scores (all `Option`). +for r in &report.results { + println!( + "{} q{:>3} {:>7} bytes {:.3} bpp ssimulacra2={:?} dssim={:?}", + r.codec_id, r.quality, r.file_size, r.bits_per_pixel, + r.metrics.ssimulacra2, r.metrics.dssim, + ); +} + +// Persist JSON + CSV to the configured `report_dir`. +session.write_image_report(&report)?; ``` +> Pass an *already-decoded* `ImageData` to `evaluate_image` — the harness does not +> read files itself. For built-in research corpora, fetch one with +> `codec_eval::corpus::Corpus::get_dataset("kodak")?` (downloaded and cached via +> [codec-corpus](https://crates.io/crates/codec-corpus)) and decode each entry into +> an `ImageData`. Always start from lossless sources — see +> [Fair Comparison Principles](#fair-comparison-principles). + **Features:** - DSSIM, Butteraugli, and SSIMULACRA2 metrics (PSNR for legacy comparisons) - Viewing condition modeling (desktop, mobile, retina)