@@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression;
16
16
internal static class HorizontalPredictor
17
17
{
18
18
/// <summary>
19
- /// Inverts the horizontal prediction .
19
+ /// Inverts the horizontal predictor .
20
20
/// </summary>
21
21
/// <param name="pixelBytes">Buffer with decompressed pixel data.</param>
22
22
/// <param name="width">The width of the image or strip.</param>
@@ -62,9 +62,16 @@ public static void Undo(Span<byte> pixelBytes, int width, TiffColorType colorTyp
62
62
}
63
63
}
64
64
65
+ /// <summary>
66
+ /// Inverts the horizontal predictor for one row.
67
+ /// </summary>
68
+ /// <param name="pixelBytes">Buffer with decompressed pixel data.</param>
69
+ /// <param name="width">The width in pixels of the row.</param>
70
+ /// <param name="y">The row index.</param>
71
+ /// <param name="colorType">The color type of the pixel data.</param>
72
+ /// <param name="isBigEndian">If set to <c>true</c> decodes the pixel data as big endian, otherwise as little endian.</param>
65
73
public static void UndoRow ( Span < byte > pixelBytes , int width , int y , TiffColorType colorType , bool isBigEndian )
66
74
{
67
- // TODO: Implement missing colortypes, see above.
68
75
switch ( colorType )
69
76
{
70
77
case TiffColorType . BlackIsZero8 :
@@ -143,6 +150,18 @@ public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorTyp
143
150
UndoRgb96BitLittleEndianRow ( pixelBytes , width , y ) ;
144
151
}
145
152
153
+ break ;
154
+
155
+ case TiffColorType . Rgba32323232 :
156
+ if ( isBigEndian )
157
+ {
158
+ UndoRgba128BitBigEndianRow ( pixelBytes , width , y ) ;
159
+ }
160
+ else
161
+ {
162
+ UndoRgba128BitLittleEndianRow ( pixelBytes , width , y ) ;
163
+ }
164
+
146
165
break ;
147
166
}
148
167
}
@@ -729,6 +748,92 @@ private static void UndoRgb96Bit(Span<byte> pixelBytes, int width, bool isBigEnd
729
748
}
730
749
}
731
750
751
+ private static void UndoRgba128BitBigEndianRow ( Span < byte > pixelBytes , int width , int y )
752
+ {
753
+ int rowBytesCount = width * 16 ;
754
+
755
+ int offset = 0 ;
756
+ Span < byte > rowBytes = pixelBytes . Slice ( y * rowBytesCount , rowBytesCount ) ;
757
+ uint r = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
758
+ offset += 4 ;
759
+ uint g = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
760
+ offset += 4 ;
761
+ uint b = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
762
+ offset += 4 ;
763
+ uint a = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
764
+ offset += 4 ;
765
+
766
+ for ( int x = 1 ; x < width ; x ++ )
767
+ {
768
+ Span < byte > rowSpan = rowBytes . Slice ( offset , 4 ) ;
769
+ uint deltaR = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
770
+ r += deltaR ;
771
+ BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , r ) ;
772
+ offset += 4 ;
773
+
774
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
775
+ uint deltaG = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
776
+ g += deltaG ;
777
+ BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , g ) ;
778
+ offset += 4 ;
779
+
780
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
781
+ uint deltaB = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
782
+ b += deltaB ;
783
+ BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , b ) ;
784
+ offset += 4 ;
785
+
786
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
787
+ uint deltaA = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
788
+ a += deltaA ;
789
+ BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , a ) ;
790
+ offset += 4 ;
791
+ }
792
+ }
793
+
794
+ private static void UndoRgba128BitLittleEndianRow ( Span < byte > pixelBytes , int width , int y )
795
+ {
796
+ int rowBytesCount = width * 16 ;
797
+
798
+ int offset = 0 ;
799
+ Span < byte > rowBytes = pixelBytes . Slice ( y * rowBytesCount , rowBytesCount ) ;
800
+ uint r = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
801
+ offset += 4 ;
802
+ uint g = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
803
+ offset += 4 ;
804
+ uint b = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
805
+ offset += 4 ;
806
+ uint a = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
807
+ offset += 4 ;
808
+
809
+ for ( int x = 1 ; x < width ; x ++ )
810
+ {
811
+ Span < byte > rowSpan = rowBytes . Slice ( offset , 4 ) ;
812
+ uint deltaR = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
813
+ r += deltaR ;
814
+ BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , r ) ;
815
+ offset += 4 ;
816
+
817
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
818
+ uint deltaG = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
819
+ g += deltaG ;
820
+ BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , g ) ;
821
+ offset += 4 ;
822
+
823
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
824
+ uint deltaB = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
825
+ b += deltaB ;
826
+ BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , b ) ;
827
+ offset += 4 ;
828
+
829
+ rowSpan = rowBytes . Slice ( offset , 4 ) ;
830
+ uint deltaA = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
831
+ a += deltaA ;
832
+ BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , a ) ;
833
+ offset += 4 ;
834
+ }
835
+ }
836
+
732
837
private static void UndoRgba128Bit ( Span < byte > pixelBytes , int width , bool isBigEndian )
733
838
{
734
839
int rowBytesCount = width * 16 ;
@@ -737,86 +842,14 @@ private static void UndoRgba128Bit(Span<byte> pixelBytes, int width, bool isBigE
737
842
{
738
843
for ( int y = 0 ; y < height ; y ++ )
739
844
{
740
- int offset = 0 ;
741
- Span < byte > rowBytes = pixelBytes . Slice ( y * rowBytesCount , rowBytesCount ) ;
742
- uint r = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
743
- offset += 4 ;
744
- uint g = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
745
- offset += 4 ;
746
- uint b = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
747
- offset += 4 ;
748
- uint a = TiffUtilities . ConvertToUIntBigEndian ( rowBytes . Slice ( offset , 4 ) ) ;
749
- offset += 4 ;
750
-
751
- for ( int x = 1 ; x < width ; x ++ )
752
- {
753
- Span < byte > rowSpan = rowBytes . Slice ( offset , 4 ) ;
754
- uint deltaR = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
755
- r += deltaR ;
756
- BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , r ) ;
757
- offset += 4 ;
758
-
759
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
760
- uint deltaG = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
761
- g += deltaG ;
762
- BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , g ) ;
763
- offset += 4 ;
764
-
765
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
766
- uint deltaB = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
767
- b += deltaB ;
768
- BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , b ) ;
769
- offset += 4 ;
770
-
771
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
772
- uint deltaA = TiffUtilities . ConvertToUIntBigEndian ( rowSpan ) ;
773
- a += deltaA ;
774
- BinaryPrimitives . WriteUInt32BigEndian ( rowSpan , a ) ;
775
- offset += 4 ;
776
- }
845
+ UndoRgba128BitBigEndianRow ( pixelBytes , width , y ) ;
777
846
}
778
847
}
779
848
else
780
849
{
781
850
for ( int y = 0 ; y < height ; y ++ )
782
851
{
783
- int offset = 0 ;
784
- Span < byte > rowBytes = pixelBytes . Slice ( y * rowBytesCount , rowBytesCount ) ;
785
- uint r = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
786
- offset += 4 ;
787
- uint g = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
788
- offset += 4 ;
789
- uint b = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
790
- offset += 4 ;
791
- uint a = TiffUtilities . ConvertToUIntLittleEndian ( rowBytes . Slice ( offset , 4 ) ) ;
792
- offset += 4 ;
793
-
794
- for ( int x = 1 ; x < width ; x ++ )
795
- {
796
- Span < byte > rowSpan = rowBytes . Slice ( offset , 4 ) ;
797
- uint deltaR = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
798
- r += deltaR ;
799
- BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , r ) ;
800
- offset += 4 ;
801
-
802
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
803
- uint deltaG = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
804
- g += deltaG ;
805
- BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , g ) ;
806
- offset += 4 ;
807
-
808
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
809
- uint deltaB = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
810
- b += deltaB ;
811
- BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , b ) ;
812
- offset += 4 ;
813
-
814
- rowSpan = rowBytes . Slice ( offset , 4 ) ;
815
- uint deltaA = TiffUtilities . ConvertToUIntLittleEndian ( rowSpan ) ;
816
- a += deltaA ;
817
- BinaryPrimitives . WriteUInt32LittleEndian ( rowSpan , a ) ;
818
- offset += 4 ;
819
- }
852
+ UndoRgba128BitLittleEndianRow ( pixelBytes , width , y ) ;
820
853
}
821
854
}
822
855
}
0 commit comments