mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-01 08:16:43 +00:00
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.
30 lines
1.0 KiB
Rust
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());
|
|
}
|