use super::*;
pub(super) fn cmyk_to_rgb_in_chunk8(s: &mut Scratch, w: usize, h: usize, icc: Option<&[u8]>) {
if let Some(profile) = icc
&& icc_convert_in_chunk8(s, w, h, profile)
{
return;
}
for i in 0..w * h {
naive_px(&mut s.chunk8, i);
}
}
fn naive_px(chunk8: &mut [u8], i: usize) {
let px: [u8; 4] = chunk8[i * 4..i * 4 + 4].try_into().unwrap();
let k = px[3] as u32;
for (c, &v) in px[..3].iter().enumerate() {
chunk8[i * 3 + c] = ((v as u32 * k + 127) / 255) as u8;
}
}
fn icc_convert_in_chunk8(s: &mut Scratch, w: usize, h: usize, profile: &[u8]) -> bool {
let Ok(src) = moxcms::ColorProfile::new_from_slice(profile) else {
return false;
};
if src.color_space != moxcms::DataColorSpace::Cmyk {
return false;
}
let opts = moxcms::TransformOptions {
rendering_intent: moxcms::RenderingIntent::RelativeColorimetric,
..Default::default()
};
let Ok(transform) = src.create_transform_8bit(
moxcms::Layout::Rgba,
&moxcms::ColorProfile::new_srgb(),
moxcms::Layout::Rgb,
opts,
) else {
return false;
};
let mut ink = vec![0u8; w * 4];
let mut rgb = vec![0u8; w * 3];
for y in 0..h {
for (d, &v) in ink.iter_mut().zip(&s.chunk8[y * w * 4..(y + 1) * w * 4]) {
*d = 255 - v;
}
if transform.transform(&ink, &mut rgb).is_ok() {
s.chunk8[y * w * 3..(y + 1) * w * 3].copy_from_slice(&rgb);
} else {
for i in y * w..(y + 1) * w {
naive_px(&mut s.chunk8, i);
}
}
}
true
}