|
|
@ -62,6 +62,22 @@ internal static class HorizontalPredictor |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static void UndoRow(Span<byte> pixelBytes, int width, int y, TiffColorType colorType) |
|
|
|
|
|
{ |
|
|
|
|
|
// TODO: Implement missing colortypes, see above.
|
|
|
|
|
|
switch (colorType) |
|
|
|
|
|
{ |
|
|
|
|
|
case TiffColorType.Rgb888: |
|
|
|
|
|
case TiffColorType.CieLab: |
|
|
|
|
|
UndoRgb24BitRow(pixelBytes, width, y); |
|
|
|
|
|
break; |
|
|
|
|
|
case TiffColorType.Rgba8888: |
|
|
|
|
|
case TiffColorType.Cmyk: |
|
|
|
|
|
UndoRgba32BitRow(pixelBytes, width, y); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
public static void ApplyHorizontalPrediction(Span<byte> rows, int width, int bitsPerPixel) |
|
|
public static void ApplyHorizontalPrediction(Span<byte> rows, int width, int bitsPerPixel) |
|
|
{ |
|
|
{ |
|
|
if (bitsPerPixel == 8) |
|
|
if (bitsPerPixel == 8) |
|
|
@ -257,12 +273,9 @@ internal static class HorizontalPredictor |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static void UndoRgb24Bit(Span<byte> pixelBytes, int width) |
|
|
private static void UndoRgb24BitRow(Span<byte> pixelBytes, int width, int y) |
|
|
{ |
|
|
{ |
|
|
int rowBytesCount = width * 3; |
|
|
int rowBytesCount = width * 3; |
|
|
int height = pixelBytes.Length / rowBytesCount; |
|
|
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
|
|
{ |
|
|
|
|
|
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); |
|
|
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); |
|
|
Span<Rgb24> rowRgb = MemoryMarshal.Cast<byte, Rgb24>(rowBytes)[..width]; |
|
|
Span<Rgb24> rowRgb = MemoryMarshal.Cast<byte, Rgb24>(rowBytes)[..width]; |
|
|
ref Rgb24 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); |
|
|
ref Rgb24 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); |
|
|
@ -279,14 +292,21 @@ internal static class HorizontalPredictor |
|
|
pixel = new Rgb24(r, g, b); |
|
|
pixel = new Rgb24(r, g, b); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void UndoRgba32Bit(Span<byte> pixelBytes, int width) |
|
|
private static void UndoRgb24Bit(Span<byte> pixelBytes, int width) |
|
|
{ |
|
|
{ |
|
|
int rowBytesCount = width * 4; |
|
|
int rowBytesCount = width * 3; |
|
|
int height = pixelBytes.Length / rowBytesCount; |
|
|
int height = pixelBytes.Length / rowBytesCount; |
|
|
for (int y = 0; y < height; y++) |
|
|
for (int y = 0; y < height; y++) |
|
|
{ |
|
|
{ |
|
|
|
|
|
UndoRgb24BitRow(pixelBytes, width, y); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void UndoRgba32BitRow(Span<byte> pixelBytes, int width, int y) |
|
|
|
|
|
{ |
|
|
|
|
|
int rowBytesCount = width * 4; |
|
|
|
|
|
|
|
|
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); |
|
|
Span<byte> rowBytes = pixelBytes.Slice(y * rowBytesCount, rowBytesCount); |
|
|
Span<Rgba32> rowRgb = MemoryMarshal.Cast<byte, Rgba32>(rowBytes)[..width]; |
|
|
Span<Rgba32> rowRgb = MemoryMarshal.Cast<byte, Rgba32>(rowBytes)[..width]; |
|
|
ref Rgba32 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); |
|
|
ref Rgba32 rowRgbBase = ref MemoryMarshal.GetReference(rowRgb); |
|
|
@ -305,6 +325,15 @@ internal static class HorizontalPredictor |
|
|
pixel = new Rgba32(r, g, b, a); |
|
|
pixel = new Rgba32(r, g, b, a); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static void UndoRgba32Bit(Span<byte> pixelBytes, int width) |
|
|
|
|
|
{ |
|
|
|
|
|
int rowBytesCount = width * 4; |
|
|
|
|
|
int height = pixelBytes.Length / rowBytesCount; |
|
|
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
|
|
{ |
|
|
|
|
|
UndoRgba32BitRow(pixelBytes, width, y); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static void UndoRgb48Bit(Span<byte> pixelBytes, int width, bool isBigEndian) |
|
|
private static void UndoRgb48Bit(Span<byte> pixelBytes, int width, bool isBigEndian) |
|
|
|