Skip to main content

IccCache

Struct IccCache 

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

ICC color profile cache and transform manager.

Implementations§

Source§

impl IccCache

Source

pub fn new() -> Self

Create an empty ICC cache with default options (BPC Auto, no pre-supplied source CMYK profile).

Source

pub fn new_with_options(opts: IccCacheOptions) -> Self

Create an ICC cache with the given options.

When opts.source_cmyk_profile is Some, the bytes are registered as the system CMYK profile (overriding any later Self::search_system_cmyk_profile call). Otherwise the cache starts empty and the caller is expected to supply a profile separately.

Examples found in repository?
examples/icc_probe.rs (line 92)
58fn main() {
59    let path = std::env::args()
60        .nth(1)
61        .expect("usage: icc_probe <profile.icc>");
62    let bytes = std::fs::read(&path).expect("read profile");
63    dump_profile_shape(&bytes);
64    let cases: &[(f64, f64, f64, f64)] = &[
65        (0.15, 1.0, 1.0, 0.0),
66        (0.0, 0.6, 1.0, 0.0),
67        (0.0, 0.5, 0.9, 0.0),
68        (0.0, 0.7, 1.0, 0.0),
69        (0.15, 0.7, 1.0, 0.0),
70        (0.0, 1.0, 1.0, 0.0),
71        (0.0, 0.0, 0.0, 1.0),
72        (0.0, 0.0, 0.0, 0.0),
73        // Medium-light green range — covers the 0001056.pdf glove regression.
74        (0.15, 0.05, 0.30, 0.0),
75        (0.25, 0.10, 0.40, 0.0),
76        (0.40, 0.15, 0.50, 0.0),
77        (0.40, 0.0, 1.0, 0.0),
78        (0.60, 0.0, 0.80, 0.0),
79        (0.20, 0.20, 0.20, 0.0),
80        // Process primaries — likely out of sRGB gamut.
81        (1.0, 0.0, 0.0, 0.0),
82        (0.0, 1.0, 0.0, 0.0),
83        (0.0, 0.0, 1.0, 0.0),
84        (1.0, 1.0, 0.0, 0.0),
85    ];
86    for mode in [BpcMode::Off, BpcMode::On] {
87        println!("\n== BPC {:?} ==", mode);
88        let opts = IccCacheOptions {
89            bpc_mode: mode,
90            source_cmyk_profile: Some(bytes.clone()),
91        };
92        let cache = IccCache::new_with_options(opts);
93        for &(c, m, y, k) in cases {
94            let rgb = cache.convert_cmyk_readonly(c, m, y, k).expect("convert");
95            println!(
96                "  CMYK({:.2},{:.2},{:.2},{:.2}) -> ({}, {}, {})",
97                c,
98                m,
99                y,
100                k,
101                (rgb.0 * 255.0).round() as u8,
102                (rgb.1 * 255.0).round() as u8,
103                (rgb.2 * 255.0).round() as u8,
104            );
105        }
106    }
107}
Source

pub fn bpc_mode(&self) -> BpcMode

Current Black Point Compensation mode.

Source

pub fn hash_profile(bytes: &[u8]) -> ProfileHash

Compute the SHA-256 hash of an ICC profile without registering it.

Source

pub fn register_profile(&mut self, bytes: &[u8]) -> Option<ProfileHash>

Register an ICC profile from raw bytes. Returns the SHA-256 hash on success.

Source

pub fn register_profile_with_n( &mut self, bytes: &[u8], expected_n: Option<u32>, ) -> Option<ProfileHash>

Register an ICC profile, validating that its color space matches the expected component count expected_n. When the profile’s actual color space has a different number of components (e.g. an RGB profile stored with PDF /N 1), the profile is rejected so the caller can fall back to the alternate color space.

Source

pub fn convert_to_oi_cmyk( &self, hash: &ProfileHash, components: &[f64], intent: RenderingIntent, ) -> Option<[f64; 4]>

Convert RGB components through the proofing chain’s stage 1 to the OutputIntent’s CMYK ink values. Returns None when no hand-rolled chain exists for this profile (the document isn’t PDF/X, or the profile shape is unsupported), in which case the caller should leave DeviceColor::native_cmyk as None and the renderer falls back to its sRGB-derived approximation. The intent parameter selects which per-intent chain to use; falls back to the Perceptual chain when the requested intent slot is empty.

Source

pub fn convert_color( &mut self, hash: &ProfileHash, components: &[f64], ) -> Option<(f64, f64, f64)>

Convert a single color through an ICC profile to sRGB. Returns (r, g, b) in [0, 1] range.

Source

pub fn convert_color_with_intent( &mut self, hash: &ProfileHash, components: &[f64], intent: RenderingIntent, ) -> Option<(f64, f64, f64)>

Cached single-color conversion under a specific rendering intent. Delegates to the legacy Self::convert_color for Perceptual (which uses the Perceptual chain stored in transform_f64 and the Perceptual-keyed cache); for the other intents it goes through Self::convert_color_readonly_with_intent and caches per-intent.

Source

pub fn convert_color_readonly_with_intent( &self, hash: &ProfileHash, components: &[f64], intent: RenderingIntent, ) -> Option<(f64, f64, f64)>

Convert a single color through an ICC profile using a specific rendering intent. Falls back to the cached default chain (built from the Perceptual tables) when no per-intent chain is available — that path matches Self::convert_color_readonly byte-for-byte and is the common case for non-PDF/X documents and CMYK source profiles.

Source

pub fn convert_color_readonly( &self, hash: &ProfileHash, components: &[f64], ) -> Option<(f64, f64, f64)>

Convert a single color through an ICC profile (read-only, no caching).

Same as convert_color but takes &self instead of &mut self, suitable for use from immutable contexts like rendering.

Source

pub fn convert_image_8bit_with_intent( &self, hash: &ProfileHash, samples: &[u8], pixel_count: usize, intent: RenderingIntent, ) -> Option<Vec<u8>>

Bulk-convert 8-bit image samples through an ICC profile to RGB using a specific rendering intent. Falls back to the cached default 8-bit transform (built from the Perceptual tables) when no per-intent chain is available — that path matches Self::convert_image_8bit byte-for-byte.

Source

pub fn convert_image_8bit( &self, hash: &ProfileHash, samples: &[u8], pixel_count: usize, ) -> Option<Vec<u8>>

Bulk-convert 8-bit image samples through an ICC profile to RGB. Input: packed samples (Gray/RGB/CMYK depending on profile). Output: packed RGB bytes (3 bytes per pixel).

Source

pub fn search_system_cmyk_profile(&mut self)

Search system paths for a CMYK ICC profile and register it.

Source

pub fn load_cmyk_profile_bytes(&mut self, bytes: &[u8])

Load a CMYK ICC profile from raw bytes (for environments without filesystem access).

Source

pub fn default_cmyk_hash(&self) -> Option<&ProfileHash>

Get the default CMYK profile hash, if a system CMYK profile was found.

Source

pub fn has_profile(&self, hash: &ProfileHash) -> bool

Check if a profile hash has been registered.

Source

pub fn get_profile_bytes(&self, hash: &ProfileHash) -> Option<Arc<Vec<u8>>>

Get the raw bytes of a registered ICC profile (for PDF embedding).

Source

pub fn system_cmyk_bytes(&self) -> Option<&Arc<Vec<u8>>>

Get the raw bytes of the system CMYK profile (for re-registration in render threads).

Source

pub fn set_system_cmyk(&mut self, bytes: &[u8], hash: ProfileHash)

Set the system CMYK profile from pre-loaded bytes and hash.

Used by --output-profile to substitute the auto-detected system CMYK profile with a user-specified one.

Source

pub fn set_proofing_enabled(&mut self, enabled: bool)

Enable PDF/X-style proofing: ICCBased profiles registered while this flag is set route through the default CMYK profile (the OutputIntent) before reaching sRGB. See Self::proofing_enabled.

Source

pub fn proofing_enabled(&self) -> bool

Whether PDF/X-style proofing is enabled. When true, source ICC profiles other than the default CMYK convert through the default CMYK (“OutputIntent”) instead of going directly to sRGB. This makes per-swatch ICC colours and surrounding DeviceCMYK paints converge through the same final OutputIntent → sRGB stage. When false, every profile converts directly (the historical behaviour).

Source

pub fn set_default_cmyk_hash(&mut self, hash: ProfileHash)

Set the default CMYK profile hash (used when building render-thread caches).

Source

pub fn suspend_default_cmyk(&mut self) -> Option<ProfileHash>

Temporarily remove the default CMYK hash, returning the old value. Used to disable ICC CMYK conversion inside soft mask form rendering, where PLRM formulas produce correct luminosity values (ICC profiles map 100% K to non-zero RGB, breaking luminosity soft masks).

Source

pub fn restore_default_cmyk(&mut self, hash: Option<ProfileHash>)

Restore a previously suspended default CMYK hash.

Source

pub fn convert_cmyk( &mut self, c: f64, m: f64, y: f64, k: f64, ) -> Option<(f64, f64, f64)>

Convert CMYK to (r, g, b) using the default system CMYK profile. Returns None if no system CMYK profile is loaded.

Source

pub fn convert_cmyk_readonly( &self, c: f64, m: f64, y: f64, k: f64, ) -> Option<(f64, f64, f64)>

Convert CMYK to (r, g, b) using the default system CMYK profile (read-only, no caching). Used by band renderers that only have &self access.

Examples found in repository?
examples/icc_probe.rs (line 94)
58fn main() {
59    let path = std::env::args()
60        .nth(1)
61        .expect("usage: icc_probe <profile.icc>");
62    let bytes = std::fs::read(&path).expect("read profile");
63    dump_profile_shape(&bytes);
64    let cases: &[(f64, f64, f64, f64)] = &[
65        (0.15, 1.0, 1.0, 0.0),
66        (0.0, 0.6, 1.0, 0.0),
67        (0.0, 0.5, 0.9, 0.0),
68        (0.0, 0.7, 1.0, 0.0),
69        (0.15, 0.7, 1.0, 0.0),
70        (0.0, 1.0, 1.0, 0.0),
71        (0.0, 0.0, 0.0, 1.0),
72        (0.0, 0.0, 0.0, 0.0),
73        // Medium-light green range — covers the 0001056.pdf glove regression.
74        (0.15, 0.05, 0.30, 0.0),
75        (0.25, 0.10, 0.40, 0.0),
76        (0.40, 0.15, 0.50, 0.0),
77        (0.40, 0.0, 1.0, 0.0),
78        (0.60, 0.0, 0.80, 0.0),
79        (0.20, 0.20, 0.20, 0.0),
80        // Process primaries — likely out of sRGB gamut.
81        (1.0, 0.0, 0.0, 0.0),
82        (0.0, 1.0, 0.0, 0.0),
83        (0.0, 0.0, 1.0, 0.0),
84        (1.0, 1.0, 0.0, 0.0),
85    ];
86    for mode in [BpcMode::Off, BpcMode::On] {
87        println!("\n== BPC {:?} ==", mode);
88        let opts = IccCacheOptions {
89            bpc_mode: mode,
90            source_cmyk_profile: Some(bytes.clone()),
91        };
92        let cache = IccCache::new_with_options(opts);
93        for &(c, m, y, k) in cases {
94            let rgb = cache.convert_cmyk_readonly(c, m, y, k).expect("convert");
95            println!(
96                "  CMYK({:.2},{:.2},{:.2},{:.2}) -> ({}, {}, {})",
97                c,
98                m,
99                y,
100                k,
101                (rgb.0 * 255.0).round() as u8,
102                (rgb.1 * 255.0).round() as u8,
103                (rgb.2 * 255.0).round() as u8,
104            );
105        }
106    }
107}
Source

pub fn prepare_reverse_cmyk(&mut self)

Pre-warm the lazy sRGB→CMYK reverse transform. Should be called once on the build thread that owns &mut IccCache, after the system CMYK profile has been registered, so that band renderers (which only hold &IccCache) can use Self::convert_rgb_to_cmyk_readonly without having to mutate state.

Source

pub fn prepare_lab_to_oi_cmyk(&mut self)

Pre-build per-intent Lab → OutputIntent CMYK samplers from the document’s OutputIntent profile. Call once after the OI is registered so Self::convert_lab_to_oi_cmyk can run from &IccCache. No-op when no default CMYK profile is registered, when the profile shape doesn’t expose B2A LUTs (shaper-matrix CMYK with no LUT, etc.), or when proofing is disabled.

Source

pub fn convert_lab_to_oi_cmyk( &self, l_star: f64, a_star: f64, b_star: f64, intent: IccRenderingIntent, ) -> Option<[f64; 4]>

Convert a PDF Lab triplet (L* ∈ [0, 100], a*/b* ∈ [-128, 127]) to OutputIntent CMYK using the OI’s per-intent B2A table. Returns None when the per-intent sampler hasn’t been built (call Self::prepare_lab_to_oi_cmyk first) or when the intent slot is empty (falls back to Perceptual when available).

Used by lab_to_device_color to populate DeviceColor::native_cmyk so the renderer’s parallel CMYK buffer holds the same direct Lab → OI CMYK value Acrobat’s ACE produces. Without this, the renderer falls back to convert_rgb_to_cmyk_readonly (sRGB → ICC reverse), which drifts visibly under CMYK-group blends. GWG 22.1’s ColorBurn form over a Lab BG is the canonical surfacing case.

Source

pub fn convert_rgb_to_cmyk_readonly( &self, r: f64, g: f64, b: f64, ) -> Option<[f64; 4]>

Convert an sRGB color to CMYK using the system CMYK profile, without mutating any state. Returns None when the reverse transform has not been pre-built (call Self::prepare_reverse_cmyk first) or when no system CMYK profile is registered.

The returned components are clamped to [0, 1].

Source

pub fn round_trip_rgb_via_cmyk( &mut self, r: f64, g: f64, b: f64, ) -> Option<(f64, f64, f64)>

Round-trip an RGB color through the system CMYK profile: sRGB→CMYK→sRGB. Used when compositing in a DeviceCMYK page group — saturated RGB colors become more muted after passing through the CMYK gamut. Returns None if no CMYK profile is loaded.

Source

pub fn disable(&mut self)

Disable all ICC color management — clears all profiles, transforms, and caches. Equivalent to the CLI’s --no-icc flag.

Trait Implementations§

Source§

impl Clone for IccCache

Source§

fn clone(&self) -> IccCache

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 Default for IccCache

Source§

fn default() -> Self

Returns the “default value” for a type. 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> Same for T

Source§

type Output = T

Should always be Self
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.