Skip to content

Commit 18f0210

Browse files
committed
Add support for TIFF in CMYK-16bit
1 parent 9afe256 commit 18f0210

File tree

2 files changed

+30
-5
lines changed

2 files changed

+30
-5
lines changed

src/codecs/tiff.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ where
8282
tiff::ColorType::RGBA(8) => ColorType::Rgba8,
8383
tiff::ColorType::RGBA(16) => ColorType::Rgba16,
8484
tiff::ColorType::CMYK(8) => ColorType::Rgb8,
85+
tiff::ColorType::CMYK(16) => ColorType::Rgb16,
8586
tiff::ColorType::RGB(32) => ColorType::Rgb32F,
8687
tiff::ColorType::RGBA(32) => ColorType::Rgba32F,
8788

@@ -108,6 +109,7 @@ where
108109
let original_color_type = match tiff_color_type {
109110
tiff::ColorType::Gray(1) => ExtendedColorType::L1,
110111
tiff::ColorType::CMYK(8) => ExtendedColorType::Cmyk8,
112+
tiff::ColorType::CMYK(16) => ExtendedColorType::Cmyk16,
111113
_ => color_type.into(),
112114
};
113115

@@ -123,10 +125,11 @@ where
123125
fn total_bytes_buffer(&self) -> u64 {
124126
let dimensions = self.dimensions();
125127
let total_pixels = u64::from(dimensions.0) * u64::from(dimensions.1);
126-
let bytes_per_pixel = if self.original_color_type == ExtendedColorType::Cmyk8 {
127-
16
128-
} else {
129-
u64::from(self.color_type().bytes_per_pixel())
128+
129+
let bytes_per_pixel = match self.original_color_type {
130+
ExtendedColorType::Cmyk8 => 4,
131+
ExtendedColorType::Cmyk16 => 8,
132+
_ => u64::from(self.color_type().bytes_per_pixel()),
130133
};
131134
total_pixels.saturating_mul(bytes_per_pixel)
132135
}
@@ -331,6 +334,12 @@ impl<R: BufRead + Seek> ImageDecoder for TiffDecoder<R> {
331334
out_cur.write_all(&cmyk_to_rgb(cmyk))?;
332335
}
333336
}
337+
DecodingResult::U16(v) if self.original_color_type == ExtendedColorType::Cmyk16 => {
338+
let mut out_cur = Cursor::new(buf);
339+
for cmyk in v.chunks_exact(4) {
340+
out_cur.write_all(bytemuck::cast_slice(&cmyk_to_rgb16(cmyk)))?;
341+
}
342+
}
334343
DecodingResult::U8(v) if self.original_color_type == ExtendedColorType::L1 => {
335344
let width = self.dimensions.0;
336345
let row_bytes = width.div_ceil(8);
@@ -399,6 +408,18 @@ fn cmyk_to_rgb(cmyk: &[u8]) -> [u8; 3] {
399408
]
400409
}
401410

411+
fn cmyk_to_rgb16(cmyk: &[u16]) -> [u16; 3] {
412+
let c = f32::from(cmyk[0]);
413+
let m = f32::from(cmyk[1]);
414+
let y = f32::from(cmyk[2]);
415+
let kf = 1. - f32::from(cmyk[3]) / 65535.;
416+
[
417+
((65535. - c) * kf) as u16,
418+
((65535. - m) * kf) as u16,
419+
((65535. - y) * kf) as u16
420+
]
421+
}
422+
402423
/// Convert a slice of sample bytes to its semantic type, being a `Pod`.
403424
fn u8_slice_as_pod<P: bytemuck::Pod>(buf: &[u8]) -> ImageResult<std::borrow::Cow<'_, [P]>> {
404425
bytemuck::try_cast_slice(buf)

src/color.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ pub enum ExtendedColorType {
154154

155155
/// Pixel is 8-bit CMYK
156156
Cmyk8,
157+
/// Pixel is 16-bit CMYK
158+
Cmyk16,
157159

158160
/// Pixel is of unknown color type with the specified bits per pixel. This can apply to pixels
159161
/// which are associated with an external palette. In that case, the pixel value is an index
@@ -195,7 +197,8 @@ impl ExtendedColorType {
195197
| ExtendedColorType::Rgba16
196198
| ExtendedColorType::Rgba32F
197199
| ExtendedColorType::Bgra8
198-
| ExtendedColorType::Cmyk8 => 4,
200+
| ExtendedColorType::Cmyk8
201+
| ExtendedColorType::Cmyk16 => 4,
199202
}
200203
}
201204

@@ -229,6 +232,7 @@ impl ExtendedColorType {
229232
ExtendedColorType::Bgr8 => 24,
230233
ExtendedColorType::Bgra8 => 32,
231234
ExtendedColorType::Cmyk8 => 32,
235+
ExtendedColorType::Cmyk16 => 64,
232236
ExtendedColorType::Unknown(bpp) => bpp as u16,
233237
}
234238
}

0 commit comments

Comments
 (0)