99using SixLabors . ImageSharp . Formats . Tiff . Constants ;
1010using SixLabors . ImageSharp . IO ;
1111using SixLabors . ImageSharp . Memory ;
12- using SixLabors . ImageSharp . Metadata ;
1312using SixLabors . ImageSharp . PixelFormats ;
1413
1514namespace SixLabors . ImageSharp . Formats . Tiff . Compression . Decompressors
@@ -55,17 +54,41 @@ protected override void Decompress(BufferedReadStream stream, int byteCount, int
5554 {
5655 using var jpegDecoder = new JpegDecoderCore ( this . configuration , new JpegDecoder ( ) ) ;
5756
58- // If the PhotometricInterpretation is YCbCr we explicitly assume the JPEG data is in RGB color space.
59- // There seems no other way to determine that the JPEG data is RGB colorspace (no APP14 marker, componentId's are not RGB).
60- using SpectralConverter < Rgb24 > spectralConverter = this . photometricInterpretation == TiffPhotometricInterpretation . YCbCr ?
61- new RgbJpegSpectralConverter < Rgb24 > ( this . configuration ) : new SpectralConverter < Rgb24 > ( this . configuration ) ;
62- var scanDecoder = new HuffmanScanDecoder ( stream , spectralConverter , CancellationToken . None ) ;
63- jpegDecoder . LoadTables ( this . jpegTables , scanDecoder ) ;
64- scanDecoder . ResetInterval = 0 ;
65- jpegDecoder . ParseStream ( stream , scanDecoder , CancellationToken . None ) ;
57+ switch ( this . photometricInterpretation )
58+ {
59+ case TiffPhotometricInterpretation . BlackIsZero :
60+ case TiffPhotometricInterpretation . WhiteIsZero :
61+ {
62+ using SpectralConverter < L8 > spectralConverterGray = new GrayJpegSpectralConverter < L8 > ( this . configuration ) ;
63+ var scanDecoderGray = new HuffmanScanDecoder ( stream , spectralConverterGray , CancellationToken . None ) ;
64+ jpegDecoder . LoadTables ( this . jpegTables , scanDecoderGray ) ;
65+ jpegDecoder . ParseStream ( stream , scanDecoderGray , CancellationToken . None ) ;
6666
67- // TODO: Should we pass through the CancellationToken from the tiff decoder?
68- CopyImageBytesToBuffer ( buffer , spectralConverter . GetPixelBuffer ( CancellationToken . None ) ) ;
67+ // TODO: Should we pass through the CancellationToken from the tiff decoder?
68+ CopyImageBytesToBuffer ( buffer , spectralConverterGray . GetPixelBuffer ( CancellationToken . None ) ) ;
69+ break ;
70+ }
71+
72+ // If the PhotometricInterpretation is YCbCr we explicitly assume the JPEG data is in RGB color space.
73+ // There seems no other way to determine that the JPEG data is RGB colorspace (no APP14 marker, componentId's are not RGB).
74+ case TiffPhotometricInterpretation . YCbCr :
75+ case TiffPhotometricInterpretation . Rgb :
76+ {
77+ using SpectralConverter < Rgb24 > spectralConverter = this . photometricInterpretation == TiffPhotometricInterpretation . YCbCr ?
78+ new RgbJpegSpectralConverter < Rgb24 > ( this . configuration ) : new SpectralConverter < Rgb24 > ( this . configuration ) ;
79+ var scanDecoder = new HuffmanScanDecoder ( stream , spectralConverter , CancellationToken . None ) ;
80+ jpegDecoder . LoadTables ( this . jpegTables , scanDecoder ) ;
81+ jpegDecoder . ParseStream ( stream , scanDecoder , CancellationToken . None ) ;
82+
83+ // TODO: Should we pass through the CancellationToken from the tiff decoder?
84+ CopyImageBytesToBuffer ( buffer , spectralConverter . GetPixelBuffer ( CancellationToken . None ) ) ;
85+ break ;
86+ }
87+
88+ default :
89+ TiffThrowHelper . ThrowNotSupported ( $ "Jpeg compressed tiff with photometric interpretation { this . photometricInterpretation } is not supported") ;
90+ break ;
91+ }
6992 }
7093 else
7194 {
@@ -86,6 +109,18 @@ private static void CopyImageBytesToBuffer(Span<byte> buffer, Buffer2D<Rgb24> pi
86109 }
87110 }
88111
112+ private static void CopyImageBytesToBuffer ( Span < byte > buffer , Buffer2D < L8 > pixelBuffer )
113+ {
114+ int offset = 0 ;
115+ for ( int y = 0 ; y < pixelBuffer . Height ; y ++ )
116+ {
117+ Span < L8 > pixelRowSpan = pixelBuffer . DangerousGetRowSpan ( y ) ;
118+ Span < byte > rgbBytes = MemoryMarshal . AsBytes ( pixelRowSpan ) ;
119+ rgbBytes . CopyTo ( buffer . Slice ( offset ) ) ;
120+ offset += rgbBytes . Length ;
121+ }
122+ }
123+
89124 /// <inheritdoc/>
90125 protected override void Dispose ( bool disposing )
91126 {
0 commit comments