Files
craft-libs/crates/cms/tests/bench.rs
aiongg d0107d1130 craft-cms: return errors instead of panicking on caller input
The crate denies panics, but asserts and slice indexing were reachable
from arguments: pixel strides, buffers that are not whole pixels or a
destination shorter than the source, single-colour slices shorter than
the channel count, CLUT and pipeline dimensions, and LUT sizes.

Every such check now returns CmsError::InvalidArgument. Buffer
conversions validate once per call, before any pixel is written, so the
per-pixel loops carry no extra checks; internal callers that already
guarantee lengths use crate-private unchecked evaluation.

Pipeline, Clut and Lut3d keep their fields private (read through
accessors) so a validated value cannot be changed into one that panics.
Pipeline::new checks matrix shapes and channel counts; Clut::new and
Clut::sample check grid, outputs and the table size limit.

API changes (unreleased crate):
- Transform::eval, eval_fast, convert_u8/u16/f32, apply,
  convert_bytes_many and from_pipeline return Result.
- Pipeline::new, extend and eval, Clut::new, sample, eval,
  eval_trilinear and eval_multilinear return Result.
- GamutCheck::delta_e and out_of_gamut, Lut3d::from_transform,
  LutFile::identity and from_fn, synth::cmyk_profile and coated_cmyk
  return Result.
- Pipeline, Clut and Lut3d fields are read through methods.
2026-10-13 01:33:07 +00:00

30 lines
1.0 KiB
Rust

//! Throughput check: `cargo test -p craft-cms --release --test bench -- --ignored --nocapture`.
use craft_cms::{Builtin, Intent, Transform};
#[test]
#[ignore]
fn bench_srgb8_to_cmyk8() {
let t0 = std::time::Instant::now();
let t = Transform::new(Builtin::Srgb.profile(), Builtin::CoatedCmyk.profile(), Intent::RelativeColorimetric, true).unwrap();
eprintln!("build: {:?}", t0.elapsed());
let n = 6016 * 6016;
let mut src = vec![0u8; n * 4];
let mut x = 1u32;
for v in src.iter_mut() {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
*v = x as u8;
}
let mut dst = vec![0u8; n * 5];
let t1 = std::time::Instant::now();
t.convert_u8(&src, 4, &mut dst, 5, true).unwrap();
eprintln!("convert 6016² RGBA8 → CMYKA8 (one buffer): {:?}", t1.elapsed());
let t2 = std::time::Instant::now();
for (s, d) in src.chunks(65536 * 4).zip(dst.chunks_mut(65536 * 5)) {
t.convert_u8(s, 4, d, 5, true).unwrap();
}
eprintln!("convert per 256² tile: {:?}", t2.elapsed());
}