Skip to main content

ConvertPlan

Struct ConvertPlan 

Source
pub struct ConvertPlan { /* private fields */ }
Expand description

Pre-computed conversion plan.

Stores the chain of steps needed to convert from one format to another. Created once, applied to every row.

Implementations§

Source§

impl ConvertPlan

Source

pub fn new( from: PixelDescriptor, to: PixelDescriptor, ) -> Result<Self, At<ConvertError>>

Create a conversion plan from from to to.

Returns Err if no conversion path exists. A SignalRange mismatch always refuses (ConvertError::NoPath): there are no Narrow↔Full conversion kernels, and relabeling without rescaling would corrupt pixels — see the signal-range notes on the crate docs.

CMYK (and any other non-native color model) returns ConvertError::NeedsCms so the caller can re-issue via RowConverter::new_explicit_with_cms with a PluggableCms backend attached. ConvertPlan itself never dispatches through CMS — wire the call through RowConverter for that.

Source

pub fn new_with_hdr_peak( from: PixelDescriptor, to: PixelDescriptor, source_peak_nits: f32, ) -> Result<Self, At<ConvertError>>

Create an HDR→SDR conversion plan with the given source-peak luminance.

Equivalent to ConvertPlan::new_with_hdr_config called with HdrConfig::for_source_peak(source_peak_nits) (target_peak_nits = 100.0, gamut_knee = 0.96).

The plan inserts a Bt2446A tone-map step (and an OKLch soft-compress step for non-BT.2020 targets) into the usual transfer / depth / gamut chain. Non-HDR conversions go through the same path as ConvertPlan::new.

§Errors

Same as ConvertPlan::new for non-HDR conversions. HdrSourceRequiresPeak is raised only when source_peak_nits is not a positive, finite number — a supplied-but-degenerate peak would otherwise tone-map every pixel to black.

§Panics

Same panics as ConvertPlan::new (CMYK descriptors).

Source

pub fn new_with_hdr_config( from: PixelDescriptor, to: PixelDescriptor, hdr: HdrConfig, ) -> Result<Self, At<ConvertError>>

Create an HDR→SDR conversion plan with full knob control.

On HDR→SDR conversions (Pq / Hlg source → SDR target, OR a Linear source where the caller declares HDR semantics via this constructor) inserts:

  1. HDR transfer decode (PQ/HLG → linear) — same kernels as ConvertPlan::new. Skipped when the source is already Linear.
  2. Source primaries → BT.2020 matrix (skipped when source is BT.2020).
  3. ToneMapBt2446A step (the BT.2446 Method A curve operating in BT.2020 RGB).
  4. BT.2020 → target primaries matrix (skipped when target is BT.2020).
  5. SoftCompressOklch step (skipped when target is BT.2020 — wide-gamut output mode preserves chroma).
  6. Linear → target transfer encode + any depth conversion (sRGB u8, BT.1886 f32, etc.) — same kernels as ConvertPlan::new.

For sources that are obviously SDR (Srgb / Bt709 / Gamma22) the hdr argument is ignored and this returns the same plan ConvertPlan::new would build — no tone-map gets injected into a path that doesn’t need one.

§Errors

Same as ConvertPlan::new for non-HDR conversions. For HDR sources, HdrSourceRequiresPeak is raised when hdr.source_peak_nits or hdr.target_peak_nits is not a positive, finite number (including the unset HdrConfig::default value 0.0) — degenerate peaks would otherwise flow into the BT.2446-A constants as inf/NaN and the kernel’s NaN scrub would silently emit an all-black image.

CMYK (and any other non-native color model) returns ConvertError::NeedsCms — same posture as ConvertPlan::new. HDR tone-mapping is RGB-only; a CMS is the right tool for CMYK↔RGB even on the HDR construction path.

Source

pub fn new_explicit( from: PixelDescriptor, to: PixelDescriptor, options: &ConvertOptions, ) -> Result<Self, At<ConvertError>>

Create a conversion plan with explicit policy enforcement.

Validates that the planned conversion steps are allowed by the given policies before creating the plan. Returns an error if a forbidden operation would be required.

CMYK (and any other non-native color model) returns ConvertError::NeedsCms — same posture as ConvertPlan::new. To dispatch CMYK ↔ RGB through a CMS, build the converter via RowConverter::new_explicit_with_cms with a PluggableCms plugin attached.

Source

pub fn compose(&self, other: &Self) -> Option<Self>

Compose two plans into one: apply self then other.

The composed plan executes both conversions in a single convert_row call, using one intermediate buffer instead of two. Adjacent inverse steps are cancelled (e.g., SrgbU8ToLinearF32 + LinearF32ToSrgbU8 → identity).

Returns None if self.to != other.from (incompatible plans).

Source

pub fn is_identity(&self) -> bool

True if conversion is a no-op.

Source

pub fn from(&self) -> PixelDescriptor

Source descriptor.

Source

pub fn to(&self) -> PixelDescriptor

Target descriptor.

Source

pub fn estimate_in( &self, image: &ImageCharacteristics, compute: &ComputeEnvironment, ) -> ResourceEstimate

Estimate resources for executing this plan on image under the given ComputeEnvironment. Returns a ResourceEstimate whose type shape matches zencodec::estimate::ResourceEstimate so codec-side encode/decode estimates can be wired through a multi- stage pipeline at the codec boundary with a trivial conversion.

Calibrated from benches/t1_layout, t2_depth, t3_tf_fused, t4_tf_f32, t5_alpha, t6_oklab, t7_gamut steady-state throughput; best-effort, ±30 % on the reference machine (Ryzen 9 7950X, AVX2). Real wall time varies with contention, frequency scaling, and CPU model. Identity at 0×0 returns a zero-cost estimate.

peak_memory_bytes_est is the destination buffer plus row-sized ping-pong scratch (multi-step plans). It does NOT include the caller’s persistent state. intermediate_buffer_count reports the number of full-image intermediate buffers held simultaneously (0 for identity / single-step plans; 2 for multi-step plans using ping-pong scratch) so schedulers can distinguish 1-giant-buffer plans from N-medium-buffer plans for paging-pressure decisions. wall_ms is divided down by compute.cores() via the plan’s internal threading-bottleneck model (see the estimate module docs): any SERIAL step forces the whole plan SERIAL; otherwise the smallest per-step knee — rows / 64 clamped to [1, 16] — caps the useful thread count.

compute.simd_tier() applies a coarse per-tier wall-time multiplier on top of the AVX2 baseline (see the estimate module docs for the per-tier ratios; TODO per-tier calibration).

Cheap to call — walks the plan’s steps once and does no allocation. Safe to call repeatedly per-frame in throttled pipelines.

For a quick estimate using ComputeEnvironment::new() defaults on a width × height image, see estimate.

§Example
use zenpixels::PixelDescriptor;
use zenpixels_convert::{ComputeEnvironment, ConvertPlan, ImageCharacteristics};

let plan = ConvertPlan::new(
    PixelDescriptor::RGB8_SRGB,
    PixelDescriptor::RGBA8_SRGB,
).unwrap();
let image = ImageCharacteristics::new(1920, 1080, PixelDescriptor::RGB8_SRGB);
let compute = ComputeEnvironment::new().with_cores(8);
let est = plan.estimate_in(&image, &compute);
assert!(est.peak_memory_bytes_est().unwrap_or(0) > 0);
// wall_ms is `Some(_)` once the plan has measurable work (it can
// round to 0 ms for trivial plans, but the field is populated).
assert!(est.wall_ms().is_some());
Source

pub fn estimate(&self, width: u32, height: u32) -> ResourceEstimate

Shortcut: estimate with ComputeEnvironment::new() defaults (single core, unknown RAM, unspecified SIMD tier) on a width × height image. Builds the ImageCharacteristics from the plan’s from() descriptor and calls estimate_in. Use estimate_in directly when the caller has a populated compute environment (e.g. available_parallelism() + archmage tier).

§Example
use zenpixels::PixelDescriptor;
use zenpixels_convert::ConvertPlan;

let plan = ConvertPlan::new(
    PixelDescriptor::RGB8_SRGB,
    PixelDescriptor::RGBA8_SRGB,
).unwrap();
let est = plan.estimate(1920, 1080);
assert!(est.peak_memory_bytes_est().unwrap_or(0) > 0);
assert!(est.wall_ms().is_some());

Trait Implementations§

Source§

impl Clone for ConvertPlan

Source§

fn clone(&self) -> ConvertPlan

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ConvertPlan

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.