diff --git a/src/decoder/image.rs b/src/decoder/image.rs index 6f97b01..c037e31 100644 --- a/src/decoder/image.rs +++ b/src/decoder/image.rs @@ -305,6 +305,15 @@ impl Image { ), )), }, + PhotometricInterpretation::YCbCr => match self.bits_per_sample[..] { + [y, cb, cr] if [y, y] == [cb, cr] => Ok(ColorType::YCbCr(y)), + _ => Err(TiffError::UnsupportedError( + TiffUnsupportedError::InterpretationWithBits( + self.photometric_interpretation, + self.bits_per_sample.clone(), + ), + )), + }, PhotometricInterpretation::BlackIsZero | PhotometricInterpretation::WhiteIsZero if self.bits_per_sample.len() == 1 => { @@ -464,6 +473,7 @@ impl Image { (ColorType::RGB(n), _) | (ColorType::RGBA(n), _) | (ColorType::CMYK(n), _) + | (ColorType::YCbCr(n), _) | (ColorType::Gray(n), _) if usize::from(n) == buffer.byte_len() * 8 => {} (ColorType::Gray(n), DecodingBuffer::U8(_)) if n < 8 => match self.predictor { diff --git a/src/encoder/colortype.rs b/src/encoder/colortype.rs index f6c775a..1946daf 100644 --- a/src/encoder/colortype.rs +++ b/src/encoder/colortype.rs @@ -235,3 +235,11 @@ impl ColorType for CMYK64Float { const BITS_PER_SAMPLE: &'static [u16] = &[64, 64, 64, 64]; const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::IEEEFP; 4]; } + +pub struct YCbCr8; +impl ColorType for YCbCr8 { + type Inner = u8; + const TIFF_VALUE: PhotometricInterpretation = PhotometricInterpretation::YCbCr; + const BITS_PER_SAMPLE: &'static [u16] = &[8, 8, 8]; + const SAMPLE_FORMAT: &'static [SampleFormat] = &[SampleFormat::Uint; 3]; +} diff --git a/src/lib.rs b/src/lib.rs index b763fc0..8f23f35 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -37,4 +37,7 @@ pub enum ColorType { /// Pixel is CMYK CMYK(u8), + + /// Pixel is YCbCr + YCbCr(u8), } diff --git a/tests/encode_images.rs b/tests/encode_images.rs index 0e5360e..57c569f 100644 --- a/tests/encode_images.rs +++ b/tests/encode_images.rs @@ -264,6 +264,11 @@ fn test_gray_f64_roundtrip() { test_f64_roundtrip::("gradient-1c-64b-float.tiff", ColorType::Gray(64)); } +#[test] +fn test_ycbcr_u8_roundtrip() { + test_u8_roundtrip::("tiled-jpeg-ycbcr.tif", ColorType::YCbCr(8)); +} + trait AssertDecode { fn assert_tag_u32(&mut self, tag: u16) -> u32; fn assert_tag_u32_vec(&mut self, tag: u16) -> Vec; diff --git a/tests/images/tiled-jpeg-ycbcr.tif b/tests/images/tiled-jpeg-ycbcr.tif new file mode 100644 index 0000000..a8303e6 Binary files /dev/null and b/tests/images/tiled-jpeg-ycbcr.tif differ