1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
//! See [Little CMS full documentation](https://kornelski.github.io/rust-lcms2-sys/) for more in-depth information about LCMS functions.
//!
//! The main types you need to use in this crate are `Profile` and `Transform`
#![doc(html_logo_url = "https://kornelski.github.io/rust-lcms2/lcms_logo.png")]
#![doc(html_root_url = "https://kornelski.github.io/rust-lcms2")]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::enum_glob_use)]
#![allow(clippy::if_not_else)]
#![allow(clippy::map_unwrap_or)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::missing_panics_doc)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::redundant_closure_for_method_calls)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::unreadable_literal)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wildcard_imports)]

use lcms2_sys as ffi;

mod ciecam;
mod context;
mod error;
mod eval;
mod ext;
mod flags;
mod locale;
mod mlu;
mod namedcolorlist;
mod pipeline;
mod profile;
mod stage;
mod tag;
mod tonecurve;
mod transform;
use std::marker::PhantomData;

/// `Transform` requires pixel types to implement these traits.
///
/// This is necesary to prevent unsafe writes to abitrary types with pointers or padding.
pub use bytemuck::{Pod, Zeroable};

pub use crate::ciecam::*;
pub use crate::context::{GlobalContext, ThreadContext};
pub use crate::error::*;
pub use crate::ext::*;
pub use crate::flags::*;
pub use crate::locale::*;
pub use crate::mlu::*;
pub use crate::namedcolorlist::*;
pub use crate::pipeline::*;
pub use crate::profile::*;
pub use crate::stage::*;
pub use crate::tonecurve::*;
pub use crate::transform::*;

pub use crate::ffi::CIELab;
/// Part of [`CIExyYTRIPLE`]
pub use crate::ffi::CIExyY;
/// For [`Profile::new_rgb`]
pub use crate::ffi::CIExyYTRIPLE;
#[doc(hidden)]
pub use crate::ffi::JCh;
pub use crate::ffi::CIEXYZ;

pub use crate::ffi::ColorSpaceSignature;
pub use crate::ffi::InfoType;
pub use crate::ffi::Intent;
pub use crate::ffi::PixelFormat;
pub use crate::ffi::ProfileClassSignature;
pub use crate::ffi::TagSignature;
pub use crate::ffi::VideoSignalType;
pub use crate::ffi::ViewingConditions;

#[derive(Debug)]
#[non_exhaustive]
/// Value of a tag in an ICC profile
pub enum Tag<'a> {
    CIExyYTRIPLE(&'a ffi::CIExyYTRIPLE),
    CIEXYZ(&'a ffi::CIEXYZ),
    ICCData(&'a ffi::ICCData),
    ICCMeasurementConditions(&'a ffi::ICCMeasurementConditions),
    ICCViewingConditions(&'a ffi::ICCViewingConditions),
    /// Unicode string
    MLU(&'a mlu::MLURef),
    /// A palette
    NamedColorList(&'a NamedColorListRef),
    Pipeline(&'a PipelineRef),
    Screening(&'a ffi::Screening),
    SEQ(&'a ffi::SEQ),
    Intent(Intent),
    ColorimetricIntentImageState(ffi::ColorimetricIntentImageState),
    Technology(ffi::TechnologySignature),
    ToneCurve(&'a ToneCurveRef),
    UcrBg(&'a ffi::UcrBg),
    VcgtCurves([&'a ToneCurveRef; 3]),
    VideoSignal(&'a ffi::VideoSignalType),
    MHC2(&'a ffi::MHC2Type),
    /// Unknown format or missing data
    None,
}

/// LCMS version
#[must_use]
pub fn version() -> u32 {
    unsafe { ffi::cmsGetEncodedCMMversion() as u32 }
}

/// Temperature <-> Chromaticity (Black body)
/// Color temperature is a characteristic of visible light that has important applications.
///
/// The color temperature of a light source is determined by comparing its chromaticity with that of an ideal black-body radiator.
/// The temperature (usually measured in kelvin, K) is that source's color temperature at which the heated black-body radiator matches the color of the light source for a black body source.
/// Higher color temperatures (5,000 K or more) are cool (bluish white) colors, and lower color temperatures (2,700–3,000 K) warm (yellowish white through red) colors.
///
/// See `CIExzYExt::temp()`
#[must_use] pub fn white_point_from_temp(temp: f64) -> Option<CIExyY> {
    let mut res = CIExyY{x:0.,y:0.,Y:0.};
    let ok = unsafe {
        ffi::cmsWhitePointFromTemp(&mut res, temp) != 0
    };
    if ok { Some(res) } else { None }
}

#[allow(non_snake_case)]
#[must_use]
pub fn xyY2XYZ(xyY: &CIExyY) -> CIEXYZ {
    let mut xyz = CIEXYZ::default();
    unsafe {
        crate::ffi::cmsxyY2XYZ(&mut xyz, xyY);
    }
    xyz
}

#[allow(non_snake_case)]
#[must_use]
pub fn XYZ2xyY(xyz: &CIEXYZ) -> CIExyY {
    let mut xyY = CIExyY::default();
    unsafe {
        crate::ffi::cmsXYZ2xyY(&mut xyY, xyz);
    }
    xyY
}