extern crate lopdf;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum IccProfileType {
Cmyk,
Rgb,
Greyscale,
}
#[derive(Debug, Clone, PartialEq)]
pub struct IccProfile {
icc: Vec<u8>,
icc_type: IccProfileType,
pub has_alternate: bool,
pub has_range: bool,
}
impl IccProfile {
pub fn new(icc: Vec<u8>, icc_type: IccProfileType)
-> Self
{
Self {
icc: icc,
icc_type: icc_type,
has_alternate: true,
has_range: false,
}
}
#[inline]
pub fn with_alternate_profile(mut self, has_alternate: bool)
-> Self
{
self.has_alternate = has_alternate;
self
}
#[inline]
pub fn with_range(mut self, has_range: bool)
-> Self
{
self.has_range = has_range;
self
}
}
impl Into<lopdf::Stream> for IccProfile {
fn into(self)
-> lopdf::Stream
{
use lopdf::{Dictionary as LoDictionary,
Stream as LoStream};
use lopdf::Object::*;
use std::iter::FromIterator;
let (num_icc_fields, alternate) = match self.icc_type {
IccProfileType::Cmyk => (4, "DeviceCMYK"),
IccProfileType::Rgb => (3, "DeviceRGB"),
IccProfileType::Greyscale => (1, "DeviceGray"),
};
let mut stream_dict = LoDictionary::from_iter(vec![
("N", Integer(num_icc_fields)).into(),
("Length", Integer(self.icc.len() as i64).into())]);
if self.has_alternate {
stream_dict.set("Alternate", Name(alternate.into()));
}
if self.has_range {
stream_dict.set("Range", Array(vec![
Real(0.0),
Real(1.0),
Real(0.0),
Real(1.0),
Real(0.0),
Real(1.0),
Real(0.0),
Real(1.0)]));
}
LoStream::new(stream_dict, self.icc)
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct IccProfileRef {
pub(crate) name: String,
}
impl IccProfileRef {
pub fn new(index: usize)
-> Self
{
Self {
name: format!("/ICC{}", index)
}
}
}
#[derive(Default, Clone, Debug, PartialEq)]
pub struct IccProfileList {
profiles: Vec<IccProfile>,
}
impl IccProfileList {
pub fn new()
-> Self
{
Self::default()
}
pub fn add_profile(&mut self, profile: IccProfile)
-> IccProfileRef
{
let cur_len = self.profiles.len();
self.profiles.push(profile);
IccProfileRef::new(cur_len)
}
}