use alloc::borrow::Cow;
use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use once_cell::race::OnceBox;
use super::cicp_bundle_index::{
BUNDLE_GROUPS, BUNDLE_PROFILES, CICP_BUNDLE_LZ4, GRAY_BUNDLE_PROFILES, NUM_GROUPS,
};
static GROUP_CACHE: [OnceBox<Vec<u8>>; NUM_GROUPS] = [const { OnceBox::new() }; NUM_GROUPS];
fn decode_group(group_index: usize) -> &'static [u8] {
GROUP_CACHE[group_index].get_or_init(|| {
let g = &BUNDLE_GROUPS[group_index];
let block = &CICP_BUNDLE_LZ4[g.blob_offset..g.blob_offset + g.compressed_len];
let mut out = vec![0u8; g.decompressed_len];
let written = lz4_flex::block::decompress_into(block, &mut out)
.expect("bundled CICP ICC group failed to LZ4-decode (corrupt committed asset)");
debug_assert_eq!(
written, g.decompressed_len,
"decoded length disagrees with the index — regenerate the bundle"
);
Box::new(out)
})
}
pub(crate) fn bundled_profile_for_cicp(primaries: u8, transfer: u8) -> Option<Cow<'static, [u8]>> {
let idx = BUNDLE_PROFILES
.binary_search_by(|p| (p.primaries, p.transfer).cmp(&(primaries, transfer)))
.ok()?;
let p = &BUNDLE_PROFILES[idx];
debug_assert_eq!(
BUNDLE_GROUPS[p.group_index].transfer, p.transfer,
"profile→group transfer mismatch in the generated index"
);
let group = decode_group(p.group_index);
let bytes = &group[p.offset_in_group..p.offset_in_group + p.len];
Some(Cow::Borrowed(bytes))
}
pub(crate) fn bundled_gray_profile_for_cicp(
primaries: u8,
transfer: u8,
) -> Option<Cow<'static, [u8]>> {
let idx = GRAY_BUNDLE_PROFILES
.binary_search_by(|p| (p.primaries, p.transfer).cmp(&(primaries, transfer)))
.ok()?;
let p = &GRAY_BUNDLE_PROFILES[idx];
debug_assert_eq!(
BUNDLE_GROUPS[p.group_index].transfer, p.transfer,
"gray profile→group transfer mismatch in the generated index"
);
let group = decode_group(p.group_index);
let bytes = &group[p.offset_in_group..p.offset_in_group + p.len];
Some(Cow::Borrowed(bytes))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn blob_offsets_and_lengths_are_consistent() {
let mut expected_offset = 0usize;
for g in &BUNDLE_GROUPS {
assert_eq!(
g.blob_offset, expected_offset,
"group blob offsets must be contiguous"
);
expected_offset += g.compressed_len;
}
assert_eq!(
expected_offset,
CICP_BUNDLE_LZ4.len(),
"groups must exactly cover the blob"
);
}
#[test]
fn every_group_decodes_to_its_declared_length() {
for (i, g) in BUNDLE_GROUPS.iter().enumerate() {
let decoded = decode_group(i);
assert_eq!(
decoded.len(),
g.decompressed_len,
"group {i} decoded length mismatch"
);
}
}
#[test]
fn every_profile_slice_is_in_bounds_and_is_a_valid_icc() {
for p in &BUNDLE_PROFILES {
let got = bundled_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed profile must resolve");
assert_eq!(got.len(), p.len, "profile length mismatch");
assert!(got.len() >= 40, "profile too short to be an ICC");
assert_eq!(
&got[36..40],
b"acsp",
"({}, {}) is not a valid ICC profile (missing 'acsp')",
p.primaries,
p.transfer
);
}
}
#[test]
fn miss_returns_none() {
assert!(bundled_profile_for_cicp(2, 13).is_none());
assert!(bundled_profile_for_cicp(1, 13).is_none());
assert!(bundled_profile_for_cicp(1, 1).is_none());
}
#[test]
fn every_gray_profile_is_a_valid_gray_class_icc() {
for p in &GRAY_BUNDLE_PROFILES {
let got = bundled_gray_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed gray profile must resolve");
assert_eq!(got.len(), p.len, "gray profile length mismatch");
assert!(got.len() >= 132, "gray profile too short to be an ICC");
assert_eq!(
&got[36..40],
b"acsp",
"gray ({}, {}) missing 'acsp' signature",
p.primaries,
p.transfer
);
assert_eq!(
&got[16..20],
b"GRAY",
"({}, {}) is not a GRAY-class profile",
p.primaries,
p.transfer
);
assert_eq!(
&got[12..16],
b"mntr",
"gray ({}, {}) expected 'mntr' profile class",
p.primaries,
p.transfer
);
}
}
#[test]
fn gray_primaries_sharing_a_white_point_share_bytes() {
let bt709 = bundled_gray_profile_for_cicp(1, 4).expect("(1, 4) in bundle");
let p3d65 = bundled_gray_profile_for_cicp(12, 4).expect("(12, 4) in bundle");
let ill_c = bundled_gray_profile_for_cicp(4, 4).expect("(4, 4) in bundle");
assert_eq!(
bt709.as_ref(),
p3d65.as_ref(),
"D65-white primaries must dedup to identical gray bytes"
);
assert_ne!(
bt709.as_ref(),
ill_c.as_ref(),
"Illuminant-C white must differ from D65"
);
}
#[test]
fn gray_miss_returns_none() {
assert!(bundled_gray_profile_for_cicp(2, 13).is_none());
assert!(bundled_gray_profile_for_cicp(1, 13).is_none());
assert!(bundled_gray_profile_for_cicp(1, 1).is_none());
}
#[cfg(feature = "cms-moxcms")]
#[test]
fn gray_blob_decodes_byte_identical_to_moxcms() {
use crate::Cicp;
fn mask_timestamp(bytes: &[u8]) -> alloc::vec::Vec<u8> {
let mut v = bytes.to_vec();
if v.len() >= 36 {
v[24..36].fill(0);
}
v
}
let mut checked = 0usize;
for p in &GRAY_BUNDLE_PROFILES {
let from_blob = bundled_gray_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed gray profile must resolve");
let from_moxcms = crate::cms_moxcms::gray_icc_bytes_for_cicp(&Cicp::new(
p.primaries,
p.transfer,
0,
true,
))
.unwrap_or_else(|| {
panic!(
"moxcms could not regenerate gray ({}, {}) — index/grid desync",
p.primaries, p.transfer
)
});
assert_eq!(
from_blob.as_ref(),
mask_timestamp(&from_moxcms).as_slice(),
"gray blob bytes for ({}, {}) diverge from a fresh moxcms generation",
p.primaries,
p.transfer
);
checked += 1;
}
assert_eq!(checked, 174, "expected to roundtrip all 174 gray combos");
}
#[test]
fn every_bundled_profile_roundtrips_through_extract_cicp() {
for p in &BUNDLE_PROFILES {
let icc = bundled_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed profile must resolve");
let got = zenpixels::icc::extract_cicp(&icc).unwrap_or_else(|| {
panic!(
"RGB profile ({}, {}) has no recoverable cicp tag",
p.primaries, p.transfer
)
});
assert_eq!(
(got.color_primaries, got.transfer_characteristics),
(p.primaries, p.transfer),
"RGB profile cicp tag drifted from its identity"
);
}
const GRAY_HASH_RECOGNIZED_TC: &[u8] = &[1, 4, 6, 8, 11, 12, 13, 14, 15, 16];
const GRAY_HASH_GAP_TC: &[u8] = &[5, 7, 9, 10, 17, 18];
for p in &GRAY_BUNDLE_PROFILES {
let icc = bundled_gray_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed gray profile must resolve");
assert!(
zenpixels::icc::extract_cicp(&icc).is_none(),
"GRAY profiles must not carry a cicp tag (ICC.1 forbids it \
outside RGB/YCbCr/XYZ); ({}, {}) has one",
p.primaries,
p.transfer
);
let identified = zenpixels::icc::identify_common(&icc);
if GRAY_HASH_RECOGNIZED_TC.contains(&p.transfer) {
assert!(
identified.is_some(),
"GRAY ({}, {}) fell out of the identification table — \
regenerate with `just icc-gen` or update the pinned sets",
p.primaries,
p.transfer
);
} else {
assert!(
GRAY_HASH_GAP_TC.contains(&p.transfer),
"transfer {} missing from both pinned sets",
p.transfer
);
assert!(
identified.is_none(),
"GRAY ({}, {}) became hash-identifiable — move its \
transfer into GRAY_HASH_RECOGNIZED_TC",
p.primaries,
p.transfer
);
}
}
}
#[test]
fn bundled_consts_are_hash_identified() {
for (bytes, name) in [
(crate::icc_profiles::DISPLAY_P3_V4, "DisplayP3Compat v4"),
(crate::icc_profiles::DISPLAY_P3_V2, "DisplayP3Compat v2"),
(crate::icc_profiles::ADOBE_RGB, "AdobeCompat v2"),
(crate::icc_profiles::REC2020_V4, "Rec2020Compat v4"),
] {
assert!(
zenpixels::icc::identify_common(bytes).is_some(),
"{name} fell out of the zenpixels identification table"
);
}
}
#[test]
fn golden_blob_sha256_is_pinned() {
use sha2::{Digest, Sha256};
const EXPECTED: &str = "b4a8f12c039f8b904844136e09cc37147f3b869f5b52bce56630872d4a9d3264";
let digest = Sha256::digest(CICP_BUNDLE_LZ4);
let hex: alloc::string::String = digest.iter().map(|b| alloc::format!("{b:02x}")).collect();
assert_eq!(
hex,
EXPECTED,
"committed cicp_bundle.lz4 sha256 changed — was the blob regenerated? \
(len = {})",
CICP_BUNDLE_LZ4.len()
);
}
#[cfg(feature = "cms-moxcms")]
#[test]
fn blob_decodes_byte_identical_to_moxcms() {
use crate::Cicp;
fn mask_timestamp(bytes: &[u8]) -> alloc::vec::Vec<u8> {
let mut v = bytes.to_vec();
if v.len() >= 36 {
v[24..36].fill(0);
}
v
}
let mut checked = 0usize;
for p in &BUNDLE_PROFILES {
let from_blob = bundled_profile_for_cicp(p.primaries, p.transfer)
.expect("indexed profile must resolve");
let from_moxcms =
crate::cms_moxcms::icc_bytes_for_cicp(&Cicp::new(p.primaries, p.transfer, 0, true))
.unwrap_or_else(|| {
panic!(
"moxcms could not regenerate ({}, {}) — index/grid desync",
p.primaries, p.transfer
)
});
assert_eq!(
from_blob.as_ref(),
mask_timestamp(&from_moxcms).as_slice(),
"blob bytes for ({}, {}) diverge from a fresh moxcms generation \
(moxcms version bump or generator drift)",
p.primaries,
p.transfer
);
checked += 1;
}
assert_eq!(
checked, 174,
"expected to roundtrip all 174 bundled profiles"
);
}
}