@@ -95,6 +95,19 @@ pub(crate) struct ReadoutLayout {
9595 pub planar_config : PlanarConfiguration ,
9696
9797 /// The sample interpretation (interpret with planar_config).
98+ ///
99+ /// FIXME: we should not require this here. The ability to turn out the raw bytes from the
100+ /// sample arrays is very different from turning out interpretable color. Firstly we can always
101+ /// readout `Multiband` but currently only use that ColorType in special circumstances (it must
102+ /// not overlap cases where actually want to use a ColorType).
103+ ///
104+ /// And then we have CIE Lab, which uses a tuple of `(u8, i8, i8)`, that is still filterable
105+ /// but still not represented by any of our `DecoderResult` variants. Other color variants
106+ /// depend on extra tags (YCbCrCoefficients/0x0211) and we don't have a good side channel to
107+ /// tag the output with all that TIFF specific information, so arguably we should process and
108+ /// apply those to the data so it becomes a self-contained representation.
109+ ///
110+ /// This should be computed at a higher level, in `Decoder`, instead.
98111 pub color : ColorType ,
99112 /// The number of bytes from one row to another.
100113 pub minimum_row_stride : usize ,
@@ -435,15 +448,60 @@ impl Image {
435448 } ) ,
436449 }
437450 }
438- // TODO: this is bad we should not fail at this point
439- PhotometricInterpretation :: RGBPalette
440- | PhotometricInterpretation :: TransparencyMask
441- | PhotometricInterpretation :: CIELab => Err ( TiffError :: UnsupportedError (
451+ // ```
452+ // struct IccLab /* Interpretation 9* {
453+ // pub L: u8, // SampleFormat::Uint
454+ // pub a: u8, // SampleFormat::Uint, defined as TiffLab::a + 128
455+ // pub b: u8, // SampleFormat::Uint, defined as TiffLab::b + 128
456+ // }
457+ // ```
458+ PhotometricInterpretation :: IccLab => match self . photometric_samples {
459+ 3 if matches ! ( self . sample_format, SampleFormat :: Uint ) => {
460+ Ok ( ColorType :: Lab ( self . bits_per_sample ) )
461+ }
462+ _ => Err ( TiffError :: UnsupportedError (
463+ TiffUnsupportedError :: InterpretationWithBits (
464+ self . photometric_interpretation ,
465+ vec ! [ self . bits_per_sample; self . samples as usize ] ,
466+ ) ,
467+ ) ) ,
468+ } ,
469+ // Unsupported due to inherently heterogeneous sample types. This is represented as:
470+ // ```
471+ // struct TiffLab /* Interpretation 8* {
472+ // pub L: u8, // SampleFormat::Uint
473+ // pub a: i8, // SampleFormat::Int
474+ // pub b: i8, // SampleFormat::Int
475+ // }
476+ // ```
477+ PhotometricInterpretation :: CIELab => Err ( TiffError :: UnsupportedError (
442478 TiffUnsupportedError :: InterpretationWithBits (
443- self . photometric_interpretation ,
479+ PhotometricInterpretation :: CIELab ,
444480 vec ! [ self . bits_per_sample; self . samples as usize ] ,
445481 ) ,
446482 ) ) ,
483+ // Unsupported due to extra unfiltering and conversion steps. We need to find the
484+ // Decode tag (SRATIONAL; 2 * SamplesPerPixel) and apply the following conversion:
485+ //
486+ // L* = Decode[0] + Lsample x (Decode[1] - Decode[0]) / (2^n -1)
487+ // …
488+ //
489+ // So we'll have a larger depth in the output and either worry about reducing fractions
490+ // or turn everything into floats. That's a lot of decisions.
491+ PhotometricInterpretation :: ItuLab => Err ( TiffError :: UnsupportedError (
492+ TiffUnsupportedError :: InterpretationWithBits (
493+ PhotometricInterpretation :: CIELab ,
494+ vec ! [ self . bits_per_sample; self . samples as usize ] ,
495+ ) ,
496+ ) ) ,
497+ PhotometricInterpretation :: RGBPalette | PhotometricInterpretation :: TransparencyMask => {
498+ Err ( TiffError :: UnsupportedError (
499+ TiffUnsupportedError :: InterpretationWithBits (
500+ self . photometric_interpretation ,
501+ vec ! [ self . bits_per_sample; self . samples as usize ] ,
502+ ) ,
503+ ) )
504+ }
447505 }
448506 }
449507
0 commit comments