extern crate alloc;
use alloc::string::String;
use crate::color_space::ColorSpace;
use crate::error::{ColorError, ColorResult};
#[derive(Debug, Clone)]
pub struct IccProfile {
pub(crate) inner: moxcms::ColorProfile,
}
impl IccProfile {
pub fn from_bytes(bytes: &[u8]) -> ColorResult<Self> {
let inner = moxcms::ColorProfile::new_from_slice(bytes)
.map_err(|e| ColorError::ProfileParse(alloc::format!("{:?}", e)))?;
Ok(Self { inner })
}
#[cfg(feature = "std")]
pub fn from_path(path: impl AsRef<std::path::Path>) -> ColorResult<Self> {
let bytes = std::fs::read(path.as_ref()).map_err(ColorError::from_io)?;
Self::from_bytes(&bytes)
}
pub fn new_srgb() -> Self {
Self {
inner: moxcms::ColorProfile::new_srgb(),
}
}
pub fn new_adobe_rgb() -> Self {
Self {
inner: moxcms::ColorProfile::new_adobe_rgb(),
}
}
pub fn new_display_p3() -> Self {
Self {
inner: moxcms::ColorProfile::new_display_p3(),
}
}
pub fn new_lab() -> Self {
Self {
inner: moxcms::ColorProfile::new_lab(),
}
}
pub fn new_gray(gamma: f32) -> Self {
Self {
inner: moxcms::ColorProfile::new_gray_with_gamma(gamma),
}
}
pub fn color_space(&self) -> ColorResult<ColorSpace> {
ColorSpace::from_moxcms(self.inner.color_space)
}
pub fn description(&self) -> Option<String> {
self.inner
.description
.as_ref()
.map(|t| alloc::format!("{:?}", t))
}
pub fn as_moxcms(&self) -> &moxcms::ColorProfile {
&self.inner
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn srgb_profile_is_rgb() {
let p = IccProfile::new_srgb();
assert_eq!(p.color_space().unwrap(), ColorSpace::Rgb);
}
#[test]
fn lab_profile_is_lab() {
let p = IccProfile::new_lab();
assert_eq!(p.color_space().unwrap(), ColorSpace::Lab);
}
#[test]
fn gray_profile_is_gray() {
let p = IccProfile::new_gray(2.2);
assert_eq!(p.color_space().unwrap(), ColorSpace::Gray);
}
#[test]
fn from_empty_bytes_returns_error() {
let result = IccProfile::from_bytes(&[]);
assert!(matches!(result, Err(ColorError::ProfileParse(_))));
}
#[test]
fn from_garbage_bytes_returns_error() {
let result = IccProfile::from_bytes(&[0xFF, 0x00, 0xAB, 0xCD]);
assert!(matches!(result, Err(ColorError::ProfileParse(_))));
}
}