From ae1480c0c2dda2ccd62a2fe190bd2bb2da875d3c Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 28 Mar 2020 20:46:05 +0100 Subject: [PATCH 01/10] Add support for top right and bottom right image origin --- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 239 ++++++++++++++----- src/ImageSharp/Formats/Tga/TgaImageOrigin.cs | 28 +++ 2 files changed, 205 insertions(+), 62 deletions(-) create mode 100644 src/ImageSharp/Formats/Tga/TgaImageOrigin.cs diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index cca34c9b0..270dfb22b 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -17,6 +17,11 @@ namespace SixLabors.ImageSharp.Formats.Tga /// internal sealed class TgaDecoderCore { + /// + /// A scratch buffer to reduce allocations. + /// + private readonly byte[] buffer = new byte[4]; + /// /// The metadata. /// @@ -88,7 +93,7 @@ namespace SixLabors.ImageSharp.Formats.Tga { try { - bool inverted = this.ReadFileHeader(stream); + TgaImageOrigin origin = this.ReadFileHeader(stream); this.currentStream.Skip(this.fileHeader.IdLength); // Parse the color map, if present. @@ -131,7 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Tga pixels, palette.Array, colorMapPixelSizeInBytes, - inverted); + origin); } else { @@ -141,7 +146,7 @@ namespace SixLabors.ImageSharp.Formats.Tga pixels, palette.Array, colorMapPixelSizeInBytes, - inverted); + origin); } } @@ -160,11 +165,11 @@ namespace SixLabors.ImageSharp.Formats.Tga case 8: if (this.fileHeader.ImageType.IsRunLengthEncoded()) { - this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 1, inverted); + this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 1, origin); } else { - this.ReadMonoChrome(this.fileHeader.Width, this.fileHeader.Height, pixels, inverted); + this.ReadMonoChrome(this.fileHeader.Width, this.fileHeader.Height, pixels, origin); } break; @@ -173,11 +178,11 @@ namespace SixLabors.ImageSharp.Formats.Tga case 16: if (this.fileHeader.ImageType.IsRunLengthEncoded()) { - this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 2, inverted); + this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 2, origin); } else { - this.ReadBgra16(this.fileHeader.Width, this.fileHeader.Height, pixels, inverted); + this.ReadBgra16(this.fileHeader.Width, this.fileHeader.Height, pixels, origin); } break; @@ -185,11 +190,11 @@ namespace SixLabors.ImageSharp.Formats.Tga case 24: if (this.fileHeader.ImageType.IsRunLengthEncoded()) { - this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 3, inverted); + this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 3, origin); } else { - this.ReadBgr24(this.fileHeader.Width, this.fileHeader.Height, pixels, inverted); + this.ReadBgr24(this.fileHeader.Width, this.fileHeader.Height, pixels, origin); } break; @@ -197,11 +202,11 @@ namespace SixLabors.ImageSharp.Formats.Tga case 32: if (this.fileHeader.ImageType.IsRunLengthEncoded()) { - this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 4, inverted); + this.ReadRle(this.fileHeader.Width, this.fileHeader.Height, pixels, 4, origin); } else { - this.ReadBgra32(this.fileHeader.Width, this.fileHeader.Height, pixels, inverted); + this.ReadBgra32(this.fileHeader.Width, this.fileHeader.Height, pixels, origin); } break; @@ -228,8 +233,8 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The to assign the palette to. /// The color palette. /// Color map size of one entry in bytes. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadPaletted(int width, int height, Buffer2D pixels, byte[] palette, int colorMapPixelSizeInBytes, bool inverted) + /// The image origin. + private void ReadPaletted(int width, int height, Buffer2D pixels, byte[] palette, int colorMapPixelSizeInBytes, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { using (IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(width, AllocationOptions.Clean)) @@ -240,7 +245,7 @@ namespace SixLabors.ImageSharp.Formats.Tga for (int y = 0; y < height; y++) { this.currentStream.Read(row); - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelRow = pixels.GetRowSpan(newY); switch (colorMapPixelSizeInBytes) { @@ -257,7 +262,8 @@ namespace SixLabors.ImageSharp.Formats.Tga } color.FromBgra5551(bgra); - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } break; @@ -267,7 +273,8 @@ namespace SixLabors.ImageSharp.Formats.Tga { int colorIndex = rowSpan[x]; color.FromBgr24(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } break; @@ -277,7 +284,8 @@ namespace SixLabors.ImageSharp.Formats.Tga { int colorIndex = rowSpan[x]; color.FromBgra32(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } break; @@ -295,8 +303,8 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The to assign the palette to. /// The color palette. /// Color map size of one entry in bytes. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadPalettedRle(int width, int height, Buffer2D pixels, byte[] palette, int colorMapPixelSizeInBytes, bool inverted) + /// The image origin. + private void ReadPalettedRle(int width, int height, Buffer2D pixels, byte[] palette, int colorMapPixelSizeInBytes, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { int bytesPerPixel = 1; @@ -309,7 +317,7 @@ namespace SixLabors.ImageSharp.Formats.Tga for (int y = 0; y < height; y++) { - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelRow = pixels.GetRowSpan(newY); int rowStartIdx = y * width * bytesPerPixel; for (int x = 0; x < width; x++) @@ -348,7 +356,8 @@ namespace SixLabors.ImageSharp.Formats.Tga break; } - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } } } @@ -361,16 +370,36 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The width of the image. /// The height of the image. /// The to assign the palette to. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadMonoChrome(int width, int height, Buffer2D pixels, bool inverted) + /// the image origin. + private void ReadMonoChrome(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { + bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; + if (isXInverted) + { + TPixel color = default; + for (int y = 0; y < height; y++) + { + int newY = InvertY(y, height, origin); + Span pixelSpan = pixels.GetRowSpan(newY); + for (int x = 0; x < width; x++) + { + var pixelValue = (byte)this.currentStream.ReadByte(); + color.FromL8(Unsafe.As(ref pixelValue)); + int newX = InvertX(x, width, origin); + pixelSpan[newX] = color; + } + } + + return; + } + using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 1, 0)) { for (int y = 0; y < height; y++) { this.currentStream.Read(row); - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); PixelOperations.Instance.FromL8Bytes(this.configuration, row.GetSpan(), pixelSpan, width); } @@ -384,29 +413,50 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The width of the image. /// The height of the image. /// The to assign the palette to. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadBgra16(int width, int height, Buffer2D pixels, bool inverted) + /// The image origin. + private void ReadBgra16(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { + TPixel color = default; + bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 2, 0)) { for (int y = 0; y < height; y++) { - this.currentStream.Read(row); - Span rowSpan = row.GetSpan(); + int newY = InvertY(y, height, origin); + Span pixelSpan = pixels.GetRowSpan(newY); - if (!this.hasAlpha) + if (isXInverted) { - // We need to set the alpha component value to fully opaque. - for (int x = 1; x < rowSpan.Length; x += 2) + for (int x = 0; x < width; x++) { - rowSpan[x] = (byte)(rowSpan[x] | (1 << 7)); + this.currentStream.Read(this.buffer, 0, 2); + if (!this.hasAlpha) + { + this.buffer[1] |= 1 << 7; + } + + color.FromBgra5551(Unsafe.As(ref this.buffer[0])); + int newX = InvertX(x, width, origin); + pixelSpan[newX] = color; } } + else + { + this.currentStream.Read(row); + Span rowSpan = row.GetSpan(); - int newY = Invert(y, height, inverted); - Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width); + if (!this.hasAlpha) + { + // We need to set the alpha component value to fully opaque. + for (int x = 1; x < rowSpan.Length; x += 2) + { + rowSpan[x] |= (1 << 7); + } + } + + PixelOperations.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width); + } } } } @@ -418,16 +468,36 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The width of the image. /// The height of the image. /// The to assign the palette to. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadBgr24(int width, int height, Buffer2D pixels, bool inverted) + /// The image origin. + private void ReadBgr24(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { + bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; + if (isXInverted) + { + TPixel color = default; + for (int y = 0; y < height; y++) + { + int newY = InvertY(y, height, origin); + Span pixelSpan = pixels.GetRowSpan(newY); + for (int x = 0; x < width; x++) + { + this.currentStream.Read(this.buffer, 0, 3); + color.FromBgr24(Unsafe.As(ref this.buffer[0])); + int newX = InvertX(x, width, origin); + pixelSpan[newX] = color; + } + } + + return; + } + using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 3, 0)) { for (int y = 0; y < height; y++) { this.currentStream.Read(row); - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); PixelOperations.Instance.FromBgr24Bytes(this.configuration, row.GetSpan(), pixelSpan, width); } @@ -441,18 +511,38 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The width of the image. /// The height of the image. /// The to assign the palette to. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadBgra32(int width, int height, Buffer2D pixels, bool inverted) + /// The image origin. + private void ReadBgra32(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { + TPixel color = default; if (this.tgaMetadata.AlphaChannelBits == 8) { + bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; + if (isXInverted) + { + for (int y = 0; y < height; y++) + { + int newY = InvertY(y, height, origin); + Span pixelSpan = pixels.GetRowSpan(newY); + for (int x = 0; x < width; x++) + { + this.currentStream.Read(this.buffer, 0, 4); + color.FromBgra32(Unsafe.As(ref this.buffer[0])); + int newX = InvertX(x, width, origin); + pixelSpan[newX] = color; + } + } + + return; + } + using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, 0)) { for (int y = 0; y < height; y++) { this.currentStream.Read(row); - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); PixelOperations.Instance.FromBgra32Bytes(this.configuration, row.GetSpan(), pixelSpan, width); @@ -462,14 +552,13 @@ namespace SixLabors.ImageSharp.Formats.Tga return; } - TPixel color = default; var alphaBits = this.tgaMetadata.AlphaChannelBits; using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, 0)) { for (int y = 0; y < height; y++) { this.currentStream.Read(row); - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelRow = pixels.GetRowSpan(newY); Span rowSpan = row.GetSpan(); @@ -478,7 +567,8 @@ namespace SixLabors.ImageSharp.Formats.Tga int idx = x * 4; var alpha = alphaBits == 0 ? byte.MaxValue : rowSpan[idx + 3]; color.FromBgra32(new Bgra32(rowSpan[idx + 2], rowSpan[idx + 1], rowSpan[idx], (byte)alpha)); - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } } } @@ -492,8 +582,8 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The height of the image. /// The to assign the palette to. /// The bytes per pixel. - /// Indicates, if the origin of the image is top left rather the bottom left (the default). - private void ReadRle(int width, int height, Buffer2D pixels, int bytesPerPixel, bool inverted) + /// The image origin. + private void ReadRle(int width, int height, Buffer2D pixels, int bytesPerPixel, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { TPixel color = default; @@ -504,7 +594,7 @@ namespace SixLabors.ImageSharp.Formats.Tga this.UncompressRle(width, height, bufferSpan, bytesPerPixel); for (int y = 0; y < height; y++) { - int newY = Invert(y, height, inverted); + int newY = InvertY(y, height, origin); Span pixelRow = pixels.GetRowSpan(newY); int rowStartIdx = y * width * bytesPerPixel; for (int x = 0; x < width; x++) @@ -541,7 +631,8 @@ namespace SixLabors.ImageSharp.Formats.Tga break; } - pixelRow[x] = color; + int newX = InvertX(x, width, origin); + pixelRow[newX] = color; } } } @@ -609,18 +700,48 @@ namespace SixLabors.ImageSharp.Formats.Tga /// Returns the y- value based on the given height. /// /// The y- value representing the current row. - /// The height of the bitmap. - /// Whether the bitmap is inverted. + /// The height of the image. + /// The image origin. + /// The representing the inverted value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int InvertY(int y, int height, TgaImageOrigin origin) + { + switch (origin) + { + case TgaImageOrigin.BottomLeft: + case TgaImageOrigin.BottomRight: + return height - y - 1; + default: + return y; + } + } + + /// + /// Returns the x- value based on the given width. + /// + /// The x- value representing the current column. + /// The width of the image. + /// The image origin. /// The representing the inverted value. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int Invert(int y, int height, bool inverted) => (!inverted) ? height - y - 1 : y; + private static int InvertX(int x, int width, TgaImageOrigin origin) + { + switch (origin) + { + case TgaImageOrigin.TopRight: + case TgaImageOrigin.BottomRight: + return width - x - 1; + default: + return x; + } + } /// /// Reads the tga file header from the stream. /// /// The containing image data. - /// true, if the image origin is top left. - private bool ReadFileHeader(Stream stream) + /// The image origin. + private TgaImageOrigin ReadFileHeader(Stream stream) { this.currentStream = stream; @@ -641,15 +762,9 @@ namespace SixLabors.ImageSharp.Formats.Tga this.tgaMetadata.AlphaChannelBits = (byte)alphaBits; this.hasAlpha = alphaBits > 0; - // TODO: bits 4 and 5 describe the image origin. See spec page 9. bit 4 is currently ignored. - // Theoretically the origin could also be top right and bottom right. - // Bit at position 5 of the descriptor indicates, that the origin is top left instead of bottom left. - if ((this.fileHeader.ImageDescriptor & (1 << 5)) != 0) - { - return true; - } - - return false; + // Bits 4 and 5 describe the image origin. + var origin = (TgaImageOrigin)((this.fileHeader.ImageDescriptor & 0x30) >> 4); + return origin; } } } diff --git a/src/ImageSharp/Formats/Tga/TgaImageOrigin.cs b/src/ImageSharp/Formats/Tga/TgaImageOrigin.cs new file mode 100644 index 000000000..06d7b5945 --- /dev/null +++ b/src/ImageSharp/Formats/Tga/TgaImageOrigin.cs @@ -0,0 +1,28 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.ImageSharp.Formats.Tga +{ + internal enum TgaImageOrigin + { + /// + /// Bottom left origin. + /// + BottomLeft = 0, + + /// + /// Bottom right origin. + /// + BottomRight = 1, + + /// + /// Top left origin. + /// + TopLeft = 2, + + /// + /// Top right origin. + /// + TopRight = 3, + } +} From 74e1106f29cda6f1a13a73721fcf87231a9ab6f3 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 10:12:31 +0200 Subject: [PATCH 02/10] Add support for decoding 16bit monochrome images --- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 31 +++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index 270dfb22b..dd3b6a821 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -436,7 +436,15 @@ namespace SixLabors.ImageSharp.Formats.Tga this.buffer[1] |= 1 << 7; } - color.FromBgra5551(Unsafe.As(ref this.buffer[0])); + if (this.fileHeader.ImageType == TgaImageType.BlackAndWhite) + { + color.FromLa16(Unsafe.As(ref this.buffer[0])); + } + else + { + color.FromBgra5551(Unsafe.As(ref this.buffer[0])); + } + int newX = InvertX(x, width, origin); pixelSpan[newX] = color; } @@ -451,11 +459,18 @@ namespace SixLabors.ImageSharp.Formats.Tga // We need to set the alpha component value to fully opaque. for (int x = 1; x < rowSpan.Length; x += 2) { - rowSpan[x] |= (1 << 7); + rowSpan[x] |= 1 << 7; } } - PixelOperations.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width); + if (this.fileHeader.ImageType == TgaImageType.BlackAndWhite) + { + PixelOperations.Instance.FromLa16Bytes(this.configuration, rowSpan, pixelSpan, width); + } + else + { + PixelOperations.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width); + } } } } @@ -612,7 +627,15 @@ namespace SixLabors.ImageSharp.Formats.Tga bufferSpan[idx + 1] = (byte)(bufferSpan[idx + 1] | 128); } - color.FromBgra5551(Unsafe.As(ref bufferSpan[idx])); + if (this.fileHeader.ImageType == TgaImageType.RleBlackAndWhite) + { + color.FromLa16(Unsafe.As(ref bufferSpan[idx])); + } + else + { + color.FromBgra5551(Unsafe.As(ref bufferSpan[idx])); + } + break; case 3: color.FromBgr24(Unsafe.As(ref bufferSpan[idx])); From 4561af046c98a824b03d675e823141f480b3d498 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 10:13:20 +0200 Subject: [PATCH 03/10] Add additional tests for monochrome images --- .../Formats/Tga/TgaDecoderTests.cs | 112 +++++++++++++++--- .../Formats/Tga/TgaEncoderTests.cs | 10 +- tests/ImageSharp.Tests/TestImages.cs | 11 +- tests/Images/Input/Tga/grayscale_a_LL.tga | 3 + tests/Images/Input/Tga/grayscale_a_LR.tga | 3 + tests/Images/Input/Tga/grayscale_a_UL.tga | 3 + tests/Images/Input/Tga/grayscale_a_rle_LL.tga | 3 + tests/Images/Input/Tga/grayscale_a_rle_LR.tga | 3 + tests/Images/Input/Tga/grayscale_a_rle_UL.tga | 3 + tests/Images/Input/Tga/grayscale_a_rle_UR.tga | 3 + 10 files changed, 133 insertions(+), 21 deletions(-) create mode 100644 tests/Images/Input/Tga/grayscale_a_LL.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_LR.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_UL.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_rle_LL.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_rle_LR.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_rle_UL.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_rle_UR.tga diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index 767b3b954..2ce6eb3c2 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -20,8 +20,104 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga private static TgaDecoder TgaDecoder => new TgaDecoder(); [Theory] - [WithFile(Grey, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_MonoChrome(TestImageProvider provider) + [WithFile(Gray8Bit, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray8BitRle, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16Bit, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_WithBottomLeftOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_WithBottomRightOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitRle, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitRleBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithBottomLeftOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitRleBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithBottomRightOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitRleTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithTopRightOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -127,18 +223,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } - [Theory] - [WithFile(GreyRle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome(TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - using (Image image = provider.GetImage(TgaDecoder)) - { - image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); - } - } - [Theory] [WithFile(Bit16Rle, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_16Bit(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs index 00664de6e..c6b8b71f9 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs @@ -25,10 +25,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga public static readonly TheoryData TgaBitsPerPixelFiles = new TheoryData { - { Grey, TgaBitsPerPixel.Pixel8 }, - { Bit32, TgaBitsPerPixel.Pixel32 }, - { Bit24, TgaBitsPerPixel.Pixel24 }, + { Gray8Bit, TgaBitsPerPixel.Pixel8 }, { Bit16, TgaBitsPerPixel.Pixel16 }, + { Bit24, TgaBitsPerPixel.Pixel24 }, + { Bit32, TgaBitsPerPixel.Pixel32 }, }; [Theory] @@ -37,14 +37,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga { var options = new TgaEncoder(); - TestFile testFile = TestFile.Create(imagePath); + var testFile = TestFile.Create(imagePath); using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { input.Save(memStream, options); memStream.Position = 0; - using (Image output = Image.Load(memStream)) + using (var output = Image.Load(memStream)) { TgaMetadata meta = output.Metadata.GetTgaMetadata(); Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel); diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 3e2f4aa6f..0622222cf 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -383,8 +383,15 @@ namespace SixLabors.ImageSharp.Tests public const string Bit24TopLeft = "Tga/targa_24bit_pal_origin_topleft.tga"; public const string Bit24RleTopLeft = "Tga/targa_24bit_rle_origin_topleft.tga"; public const string Bit32 = "Tga/targa_32bit.tga"; - public const string Grey = "Tga/targa_8bit.tga"; - public const string GreyRle = "Tga/targa_8bit_rle.tga"; + public const string Gray8Bit = "Tga/targa_8bit.tga"; + public const string Gray8BitRle = "Tga/targa_8bit_rle.tga"; + public const string Gray16Bit = "Tga/grayscale_a_UL.tga"; + public const string Gray16BitBottomLeft = "Tga/grayscale_a_LL.tga"; + public const string Gray16BitBottomRight = "Tga/grayscale_a_LR.tga"; + public const string Gray16BitRle = "Tga/grayscale_a_rle_UL.tga"; + public const string Gray16BitRleBottomLeft = "Tga/grayscale_a_rle_LL.tga"; + public const string Gray16BitRleBottomRight = "Tga/grayscale_a_rle_LR.tga"; + public const string Gray16BitRleTopRight = "Tga/grayscale_a_rle_UR.tga"; public const string Bit16Rle = "Tga/targa_16bit_rle.tga"; public const string Bit24Rle = "Tga/targa_24bit_rle.tga"; public const string Bit32Rle = "Tga/targa_32bit_rle.tga"; diff --git a/tests/Images/Input/Tga/grayscale_a_LL.tga b/tests/Images/Input/Tga/grayscale_a_LL.tga new file mode 100644 index 000000000..ebc378134 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_LL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e90d280ddfde2d147dd68bacf7bb31e9133f8132adcbe50c841950d5a7834b8e +size 131116 diff --git a/tests/Images/Input/Tga/grayscale_a_LR.tga b/tests/Images/Input/Tga/grayscale_a_LR.tga new file mode 100644 index 000000000..1d142b5c1 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df0cd7261a98e87700e4f9c1328d73ee9f278c4e538895ab0a97b88392156523 +size 131116 diff --git a/tests/Images/Input/Tga/grayscale_a_UL.tga b/tests/Images/Input/Tga/grayscale_a_UL.tga new file mode 100644 index 000000000..bd6c25627 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:debc2bb439a72f5cae3f0fdb525dbc0b3488abc27cee81d1eb73cb97765a07f3 +size 131116 diff --git a/tests/Images/Input/Tga/grayscale_a_rle_LL.tga b/tests/Images/Input/Tga/grayscale_a_rle_LL.tga new file mode 100644 index 000000000..3434cc86c --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_rle_LL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d65c2b9caf83b2eb063e820e15944621dec324f8278ae6b60b088dc380a2c40b +size 54102 diff --git a/tests/Images/Input/Tga/grayscale_a_rle_LR.tga b/tests/Images/Input/Tga/grayscale_a_rle_LR.tga new file mode 100644 index 000000000..75850f39c --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_rle_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0f7e06f04de22ecbf8fea1da72c6a6feb45161e92580e96ca5c4482ec3bc00de +size 54237 diff --git a/tests/Images/Input/Tga/grayscale_a_rle_UL.tga b/tests/Images/Input/Tga/grayscale_a_rle_UL.tga new file mode 100644 index 000000000..ed77308e5 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_rle_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8555c8dcfa7ac65ad9f1d2389d82ee21dd90329b7200e10a457abc0f67d18ac8 +size 54295 diff --git a/tests/Images/Input/Tga/grayscale_a_rle_UR.tga b/tests/Images/Input/Tga/grayscale_a_rle_UR.tga new file mode 100644 index 000000000..04945dc61 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_rle_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9abc35a5e6ef0aaa29a5d0bd7cef30281b1d94fec669e884cc382a2d73b359a0 +size 54052 From 96ff5b8b146c6d86e6c39ddc500167e74102f240 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 13:24:00 +0200 Subject: [PATCH 04/10] Add additional tests for images which have bottom right and top right origin --- .../Formats/Tga/TgaDecoderTests.cs | 144 ++++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 12 ++ tests/Images/Input/Tga/indexed_a_LL.tga | 3 + tests/Images/Input/Tga/indexed_a_LR.tga | 3 + tests/Images/Input/Tga/indexed_a_UL.tga | 3 + tests/Images/Input/Tga/indexed_a_UR.tga | 3 + tests/Images/Input/Tga/rgb_LR.tga | 3 + tests/Images/Input/Tga/rgb_UR.tga | 3 + tests/Images/Input/Tga/rgb_a_LR.tga | 3 + tests/Images/Input/Tga/rgb_a_UR.tga | 3 + tests/Images/Input/Tga/rgb_a_rle_LR.tga | 3 + tests/Images/Input/Tga/rgb_a_rle_UR.tga | 3 + tests/Images/Input/Tga/rgb_rle_LR.tga | 3 + tests/Images/Input/Tga/rgb_rle_UR.tga | 3 + 14 files changed, 192 insertions(+) create mode 100644 tests/Images/Input/Tga/indexed_a_LL.tga create mode 100644 tests/Images/Input/Tga/indexed_a_LR.tga create mode 100644 tests/Images/Input/Tga/indexed_a_UL.tga create mode 100644 tests/Images/Input/Tga/indexed_a_UR.tga create mode 100644 tests/Images/Input/Tga/rgb_LR.tga create mode 100644 tests/Images/Input/Tga/rgb_UR.tga create mode 100644 tests/Images/Input/Tga/rgb_a_LR.tga create mode 100644 tests/Images/Input/Tga/rgb_a_UR.tga create mode 100644 tests/Images/Input/Tga/rgb_a_rle_LR.tga create mode 100644 tests/Images/Input/Tga/rgb_a_rle_UR.tga create mode 100644 tests/Images/Input/Tga/rgb_rle_LR.tga create mode 100644 tests/Images/Input/Tga/rgb_rle_UR.tga diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index 2ce6eb3c2..5bfb38b74 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -187,6 +187,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit24TopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_WithTopRightOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit24BottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_WithBottomRightOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit24RleTopLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopLeftOrigin_24Bit(TestImageProvider provider) @@ -199,6 +223,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit24RleTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopRightOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit24RleBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithBottomRightOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit24TopLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_Palette_WithTopLeftOrigin_24Bit(TestImageProvider provider) @@ -223,6 +271,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit32BottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_WithBottomRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32TopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Uncompressed_WithTopRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit16Rle, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_16Bit(TestImageProvider provider) @@ -259,6 +331,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit32RleTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32RleBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithBottomRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit16Pal, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithPalette_16Bit(TestImageProvider provider) @@ -283,6 +379,54 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit32Pal, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPalette_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32PalBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPalette_WithBottomLeftOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32PalBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPalette_WithBottomRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32PalTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPalette_WithTopRightOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(NoAlphaBits16Bit, PixelTypes.Rgba32)] [WithFile(NoAlphaBits16BitRle, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 0622222cf..197210f67 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -380,9 +380,21 @@ namespace SixLabors.ImageSharp.Tests public const string Bit16 = "Tga/targa_16bit.tga"; public const string Bit16PalRle = "Tga/ccm8.tga"; public const string Bit24 = "Tga/targa_24bit.tga"; + public const string Bit24TopRight = "Tga/rgb_UR.tga"; + public const string Bit24BottomRight = "Tga/rgb_LR.tga"; public const string Bit24TopLeft = "Tga/targa_24bit_pal_origin_topleft.tga"; public const string Bit24RleTopLeft = "Tga/targa_24bit_rle_origin_topleft.tga"; + public const string Bit24RleTopRight = "Tga/rgb_rle_UR.tga"; + public const string Bit24RleBottomRight = "Tga/rgb_rle_LR.tga"; public const string Bit32 = "Tga/targa_32bit.tga"; + public const string Bit32Pal = "Tga/indexed_a_UL.tga"; + public const string Bit32PalBottomLeft = "Tga/indexed_a_LL.tga"; + public const string Bit32PalBottomRight = "Tga/indexed_a_LR.tga"; + public const string Bit32PalTopRight = "Tga/indexed_a_UR.tga"; + public const string Bit32TopRight = "Tga/rgb_a_UR.tga"; + public const string Bit32BottomRight = "Tga/rgb_a_LR.tga"; + public const string Bit32RleTopRight = "Tga/rgb_a_rle_UR.tga"; + public const string Bit32RleBottomRight = "Tga/rgb_a_rle_LR.tga"; public const string Gray8Bit = "Tga/targa_8bit.tga"; public const string Gray8BitRle = "Tga/targa_8bit_rle.tga"; public const string Gray16Bit = "Tga/grayscale_a_UL.tga"; diff --git a/tests/Images/Input/Tga/indexed_a_LL.tga b/tests/Images/Input/Tga/indexed_a_LL.tga new file mode 100644 index 000000000..e074f253b --- /dev/null +++ b/tests/Images/Input/Tga/indexed_a_LL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1522f4513cadd35869f39e171b1dccda9181da5b812d487e2a3e17308722d7c0 +size 66604 diff --git a/tests/Images/Input/Tga/indexed_a_LR.tga b/tests/Images/Input/Tga/indexed_a_LR.tga new file mode 100644 index 000000000..aa361fa74 --- /dev/null +++ b/tests/Images/Input/Tga/indexed_a_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d01d5c89e772582a30ef9d528928cc313474a54b7f5530947a637adea95a4536 +size 66604 diff --git a/tests/Images/Input/Tga/indexed_a_UL.tga b/tests/Images/Input/Tga/indexed_a_UL.tga new file mode 100644 index 000000000..19b0b36fc --- /dev/null +++ b/tests/Images/Input/Tga/indexed_a_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa4d93b76ddcfa82a8ef02921e1c90dbd136de45608e7e7502c2d2256736f9ae +size 66604 diff --git a/tests/Images/Input/Tga/indexed_a_UR.tga b/tests/Images/Input/Tga/indexed_a_UR.tga new file mode 100644 index 000000000..9b783a88a --- /dev/null +++ b/tests/Images/Input/Tga/indexed_a_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feab3d418ab68eef0b40282de0e00c126fedff31f8657159799efef9b6f4a2af +size 66604 diff --git a/tests/Images/Input/Tga/rgb_LR.tga b/tests/Images/Input/Tga/rgb_LR.tga new file mode 100644 index 000000000..bb6a8a9c8 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a57a4f63dbe50b43e95cfcffff0ecf981de91268c44064b73c94c295f0909fea +size 196652 diff --git a/tests/Images/Input/Tga/rgb_UR.tga b/tests/Images/Input/Tga/rgb_UR.tga new file mode 100644 index 000000000..b7a7754fe --- /dev/null +++ b/tests/Images/Input/Tga/rgb_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dc5882241cd3513795cfcb207b7b4b6014585cf50504e01f968f1db9ad7d8d8 +size 196652 diff --git a/tests/Images/Input/Tga/rgb_a_LR.tga b/tests/Images/Input/Tga/rgb_a_LR.tga new file mode 100644 index 000000000..312af4c0d --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0b91c063644c2f21f74fa88687a05f8730366e75a896bf21630af280abc9950b +size 262188 diff --git a/tests/Images/Input/Tga/rgb_a_UR.tga b/tests/Images/Input/Tga/rgb_a_UR.tga new file mode 100644 index 000000000..12d7b5a79 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d88b70ad8878d44e29f680716670dd876771620264bdf2af9179284508fcc03 +size 262188 diff --git a/tests/Images/Input/Tga/rgb_a_rle_LR.tga b/tests/Images/Input/Tga/rgb_a_rle_LR.tga new file mode 100644 index 000000000..ceac831b8 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_rle_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bcfe104b6c56ddaa06bfaca4a2a9b070e7af8f74dc433736d6b0e536bf3c0b6 +size 98317 diff --git a/tests/Images/Input/Tga/rgb_a_rle_UR.tga b/tests/Images/Input/Tga/rgb_a_rle_UR.tga new file mode 100644 index 000000000..e6eebbdaf --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_rle_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cec69308cbfd13f1cae79462fcfd013655d27fb6386e60e6801a8fbb58685201 +size 97990 diff --git a/tests/Images/Input/Tga/rgb_rle_LR.tga b/tests/Images/Input/Tga/rgb_rle_LR.tga new file mode 100644 index 000000000..11146a812 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_rle_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c21355f73ed5f78ec2835c3e8bb11b1d48bc5b360a804555a49a435077e8bcb +size 73337 diff --git a/tests/Images/Input/Tga/rgb_rle_UR.tga b/tests/Images/Input/Tga/rgb_rle_UR.tga new file mode 100644 index 000000000..4c9e540d3 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_rle_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5d56b7e72b59624545b405406daeb9a578ff3da6e1ea99ee759ace6909da6d6 +size 73086 From 2b18c6c82e15684feb484c21adc2cfe2b936ca17 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 14:08:18 +0200 Subject: [PATCH 05/10] Update Magick.Net to 7.15.5 --- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 20 +++++++++---------- tests/Directory.Build.targets | 2 +- .../Formats/Tga/TgaTestUtils.cs | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index dd3b6a821..c8e23532f 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Tga /// /// A scratch buffer to reduce allocations. /// - private readonly byte[] buffer = new byte[4]; + private readonly byte[] scratchBuffer = new byte[4]; /// /// The metadata. @@ -430,19 +430,19 @@ namespace SixLabors.ImageSharp.Formats.Tga { for (int x = 0; x < width; x++) { - this.currentStream.Read(this.buffer, 0, 2); + this.currentStream.Read(this.scratchBuffer, 0, 2); if (!this.hasAlpha) { - this.buffer[1] |= 1 << 7; + this.scratchBuffer[1] |= 1 << 7; } if (this.fileHeader.ImageType == TgaImageType.BlackAndWhite) { - color.FromLa16(Unsafe.As(ref this.buffer[0])); + color.FromLa16(Unsafe.As(ref this.scratchBuffer[0])); } else { - color.FromBgra5551(Unsafe.As(ref this.buffer[0])); + color.FromBgra5551(Unsafe.As(ref this.scratchBuffer[0])); } int newX = InvertX(x, width, origin); @@ -497,8 +497,8 @@ namespace SixLabors.ImageSharp.Formats.Tga Span pixelSpan = pixels.GetRowSpan(newY); for (int x = 0; x < width; x++) { - this.currentStream.Read(this.buffer, 0, 3); - color.FromBgr24(Unsafe.As(ref this.buffer[0])); + this.currentStream.Read(this.scratchBuffer, 0, 3); + color.FromBgr24(Unsafe.As(ref this.scratchBuffer[0])); int newX = InvertX(x, width, origin); pixelSpan[newX] = color; } @@ -531,9 +531,9 @@ namespace SixLabors.ImageSharp.Formats.Tga where TPixel : unmanaged, IPixel { TPixel color = default; + bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; if (this.tgaMetadata.AlphaChannelBits == 8) { - bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; if (isXInverted) { for (int y = 0; y < height; y++) @@ -542,8 +542,8 @@ namespace SixLabors.ImageSharp.Formats.Tga Span pixelSpan = pixels.GetRowSpan(newY); for (int x = 0; x < width; x++) { - this.currentStream.Read(this.buffer, 0, 4); - color.FromBgra32(Unsafe.As(ref this.buffer[0])); + this.currentStream.Read(this.scratchBuffer, 0, 4); + color.FromBgra32(Unsafe.As(ref this.scratchBuffer[0])); int newX = InvertX(x, width, origin); pixelSpan[newX] = color; } diff --git a/tests/Directory.Build.targets b/tests/Directory.Build.targets index 3c3b3b5ec..df153c08b 100644 --- a/tests/Directory.Build.targets +++ b/tests/Directory.Build.targets @@ -29,7 +29,7 @@ - + diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs index cb3986b1f..c69cf2f20 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs @@ -44,6 +44,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga { using (var magickImage = new MagickImage(fileInfo)) { + magickImage.AutoOrient(); var result = new Image(configuration, magickImage.Width, magickImage.Height); Span resultPixels = result.GetPixelSpan(); From b89c099e714ebbb4200d98bf2862ee814dff7f92 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 14:15:21 +0200 Subject: [PATCH 06/10] Simplify ReadBgra32 --- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index c8e23532f..e9e7ce719 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -532,26 +532,8 @@ namespace SixLabors.ImageSharp.Formats.Tga { TPixel color = default; bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; - if (this.tgaMetadata.AlphaChannelBits == 8) + if (this.tgaMetadata.AlphaChannelBits == 8 && !isXInverted) { - if (isXInverted) - { - for (int y = 0; y < height; y++) - { - int newY = InvertY(y, height, origin); - Span pixelSpan = pixels.GetRowSpan(newY); - for (int x = 0; x < width; x++) - { - this.currentStream.Read(this.scratchBuffer, 0, 4); - color.FromBgra32(Unsafe.As(ref this.scratchBuffer[0])); - int newX = InvertX(x, width, origin); - pixelSpan[newX] = color; - } - } - - return; - } - using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, 0)) { for (int y = 0; y < height; y++) From 365c1661acba1301935c4e63a619026c81f974c8 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 29 Mar 2020 19:15:25 +0200 Subject: [PATCH 07/10] Update external for the 16bit gray tga images --- .../Formats/Tga/TgaDecoderTests.cs | 69 ++++++++++++------- tests/Images/External | 2 +- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index 5bfb38b74..d9f51701e 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Gray8Bit, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_8Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_Gray_8Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Gray8BitRle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_8Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_8Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -45,91 +45,112 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Gray16Bit, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_Gray_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitBottomLeft, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_WithBottomLeftOrigin_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_Gray_WithBottomLeftOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitBottomRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_MonoChrome_WithBottomRightOrigin_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_Gray_WithBottomRightOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitRle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitRleBottomLeft, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithBottomLeftOrigin_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithBottomLeftOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitRleBottomRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithBottomRightOrigin_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithBottomRightOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Gray16BitRleTopRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_MonoChrome_WithTopRightOrigin_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithTopRightOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) { image.DebugSave(provider); - TgaTestUtils.CompareWithReferenceDecoder(provider, image); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); } } [Theory] [WithFile(Bit15, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_15Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_15Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -153,7 +174,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit16, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_16Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -177,7 +198,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit24, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_24Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -189,7 +210,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit24TopRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_WithTopRightOrigin_24Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_WithTopRightOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -201,7 +222,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit24BottomRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_WithBottomRightOrigin_24Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_WithBottomRightOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -261,7 +282,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit32, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_32Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -273,7 +294,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit32BottomRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_WithBottomRightOrigin_32Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_WithBottomRightOrigin_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -285,7 +306,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit32TopRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Uncompressed_WithTopRightOrigin_32Bit(TestImageProvider provider) + public void TgaDecoder_CanDecode_WithTopRightOrigin_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) diff --git a/tests/Images/External b/tests/Images/External index 985e050aa..6f81d7a95 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 985e050aa7ac11830ae7a178ca2283f8b6307e4c +Subproject commit 6f81d7a95e285b1449efd4319a5cc7b071dec679 From 985c1805e9793e31f178caf946ac97cfba223575 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 30 Mar 2020 18:42:41 +0200 Subject: [PATCH 08/10] Add additional tga test cases --- .../Formats/Tga/TgaDecoderTests.cs | 85 +++++++++++++++++-- .../Formats/Tga/TgaEncoderTests.cs | 6 +- tests/ImageSharp.Tests/TestImages.cs | 42 ++++++--- tests/Images/External | 2 +- tests/Images/Input/Tga/grayscale_LL.tga | 3 + tests/Images/Input/Tga/grayscale_UR.tga | 3 + tests/Images/Input/Tga/grayscale_a_UR.tga | 3 + tests/Images/Input/Tga/rgb24_top_left.tga | 3 + tests/Images/Input/Tga/rgb_a_LL.tga | 3 + 9 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 tests/Images/Input/Tga/grayscale_LL.tga create mode 100644 tests/Images/Input/Tga/grayscale_UR.tga create mode 100644 tests/Images/Input/Tga/grayscale_a_UR.tga create mode 100644 tests/Images/Input/Tga/rgb24_top_left.tga create mode 100644 tests/Images/Input/Tga/rgb_a_LL.tga diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index d9f51701e..ccd00b49f 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -31,6 +31,42 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Gray8BitBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Gray_WithBottomLeftOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray8BitTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Gray_WithTopRightOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray8BitBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Gray_WithBottomRightOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Gray8BitRle, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_8Bit(TestImageProvider provider) @@ -88,6 +124,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Gray16BitTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Gray_WithTopRightOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + + // Using here the reference output instead of the the reference decoder, + // because the reference decoder output seems not to be correct for 16bit gray images. + image.CompareToReferenceOutput(ImageComparer.Exact, provider); + } + } + [Theory] [WithFile(Gray16BitRle, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_16Bit(TestImageProvider provider) @@ -173,8 +224,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit16, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_16Bit(TestImageProvider provider) + [WithFile(Bit16BottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithBottomLeftOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -208,6 +259,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit24BottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithBottomLeftOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit24TopRight, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithTopRightOrigin_24Bit(TestImageProvider provider) @@ -292,6 +355,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } } + [Theory] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithBottomLeftOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + [Theory] [WithFile(Bit32BottomRight, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithBottomRightOrigin_32Bit(TestImageProvider provider) @@ -477,8 +552,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit16, PixelTypes.Rgba32)] - [WithFile(Bit24, PixelTypes.Rgba32)] + [WithFile(Bit16BottomLeft, PixelTypes.Rgba32)] + [WithFile(Bit24BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32, PixelTypes.Rgba32)] public void TgaDecoder_DegenerateMemoryRequest_ShouldTranslateTo_ImageFormatException(TestImageProvider provider) where TPixel : unmanaged, IPixel @@ -489,7 +564,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit24, PixelTypes.Rgba32)] + [WithFile(Bit24BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithLimitedAllocatorBufferCapacity(TestImageProvider provider) where TPixel : unmanaged, IPixel diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs index c6b8b71f9..4e3e2d24c 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs @@ -26,8 +26,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga new TheoryData { { Gray8Bit, TgaBitsPerPixel.Pixel8 }, - { Bit16, TgaBitsPerPixel.Pixel16 }, - { Bit24, TgaBitsPerPixel.Pixel24 }, + { Bit16BottomLeft, TgaBitsPerPixel.Pixel16 }, + { Bit24BottomLeft, TgaBitsPerPixel.Pixel24 }, { Bit32, TgaBitsPerPixel.Pixel32 }, }; @@ -124,7 +124,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit32, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel32)] - [WithFile(Bit24, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)] + [WithFile(Bit24BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)] public void TgaEncoder_WorksWithDiscontiguousBuffers(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel) where TPixel : unmanaged, IPixel { diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 197210f67..38ef8d9e2 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -375,40 +375,54 @@ namespace SixLabors.ImageSharp.Tests public static class Tga { + public const string Gray8Bit = "Tga/targa_8bit.tga"; + public const string Gray8BitBottomLeft = "Tga/grayscale_LL.tga"; + public const string Gray8BitTopRight = "Tga/grayscale_UR.tga"; + public const string Gray8BitBottomRight = "Tga/grayscale_UR.tga"; + public const string Gray8BitRle = "Tga/targa_8bit_rle.tga"; + public const string Bit15 = "Tga/rgb15.tga"; public const string Bit15Rle = "Tga/rgb15rle.tga"; - public const string Bit16 = "Tga/targa_16bit.tga"; + public const string Bit16BottomLeft = "Tga/targa_16bit.tga"; public const string Bit16PalRle = "Tga/ccm8.tga"; - public const string Bit24 = "Tga/targa_24bit.tga"; - public const string Bit24TopRight = "Tga/rgb_UR.tga"; + + public const string Gray16Bit = "Tga/grayscale_a_UL.tga"; + public const string Gray16BitBottomLeft = "Tga/grayscale_a_LL.tga"; + public const string Gray16BitBottomRight = "Tga/grayscale_a_LR.tga"; + public const string Gray16BitTopRight = "Tga/grayscale_a_UR.tga"; + public const string Gray16BitRle = "Tga/grayscale_a_rle_UL.tga"; + public const string Gray16BitRleBottomLeft = "Tga/grayscale_a_rle_LL.tga"; + public const string Gray16BitRleBottomRight = "Tga/grayscale_a_rle_LR.tga"; + public const string Gray16BitRleTopRight = "Tga/grayscale_a_rle_UR.tga"; + + public const string Bit24 = "Tga/rgb24_top_left.tga"; + public const string Bit24BottomLeft = "Tga/targa_24bit.tga"; public const string Bit24BottomRight = "Tga/rgb_LR.tga"; + public const string Bit24TopRight = "Tga/rgb_UR.tga"; public const string Bit24TopLeft = "Tga/targa_24bit_pal_origin_topleft.tga"; + public const string Bit24RleTopLeft = "Tga/targa_24bit_rle_origin_topleft.tga"; public const string Bit24RleTopRight = "Tga/rgb_rle_UR.tga"; public const string Bit24RleBottomRight = "Tga/rgb_rle_LR.tga"; + public const string Bit32 = "Tga/targa_32bit.tga"; + public const string Bit32BottomLeft = "Tga/rgb_a_LL.tga"; + public const string Bit32TopRight = "Tga/rgb_a_UR.tga"; + public const string Bit32BottomRight = "Tga/rgb_a_LR.tga"; + public const string Bit32Pal = "Tga/indexed_a_UL.tga"; public const string Bit32PalBottomLeft = "Tga/indexed_a_LL.tga"; public const string Bit32PalBottomRight = "Tga/indexed_a_LR.tga"; public const string Bit32PalTopRight = "Tga/indexed_a_UR.tga"; - public const string Bit32TopRight = "Tga/rgb_a_UR.tga"; - public const string Bit32BottomRight = "Tga/rgb_a_LR.tga"; public const string Bit32RleTopRight = "Tga/rgb_a_rle_UR.tga"; public const string Bit32RleBottomRight = "Tga/rgb_a_rle_LR.tga"; - public const string Gray8Bit = "Tga/targa_8bit.tga"; - public const string Gray8BitRle = "Tga/targa_8bit_rle.tga"; - public const string Gray16Bit = "Tga/grayscale_a_UL.tga"; - public const string Gray16BitBottomLeft = "Tga/grayscale_a_LL.tga"; - public const string Gray16BitBottomRight = "Tga/grayscale_a_LR.tga"; - public const string Gray16BitRle = "Tga/grayscale_a_rle_UL.tga"; - public const string Gray16BitRleBottomLeft = "Tga/grayscale_a_rle_LL.tga"; - public const string Gray16BitRleBottomRight = "Tga/grayscale_a_rle_LR.tga"; - public const string Gray16BitRleTopRight = "Tga/grayscale_a_rle_UR.tga"; + public const string Bit16Rle = "Tga/targa_16bit_rle.tga"; public const string Bit24Rle = "Tga/targa_24bit_rle.tga"; public const string Bit32Rle = "Tga/targa_32bit_rle.tga"; public const string Bit16Pal = "Tga/targa_16bit_pal.tga"; public const string Bit24Pal = "Tga/targa_24bit_pal.tga"; + public const string NoAlphaBits16Bit = "Tga/16bit_noalphabits.tga"; public const string NoAlphaBits16BitRle = "Tga/16bit_rle_noalphabits.tga"; public const string NoAlphaBits32Bit = "Tga/32bit_no_alphabits.tga"; diff --git a/tests/Images/External b/tests/Images/External index 6f81d7a95..fe694a393 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 6f81d7a95e285b1449efd4319a5cc7b071dec679 +Subproject commit fe694a3938bea3565071a96cb1c90c4cbc586ff9 diff --git a/tests/Images/Input/Tga/grayscale_LL.tga b/tests/Images/Input/Tga/grayscale_LL.tga new file mode 100644 index 000000000..13ae52c37 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_LL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:74ef200d90078b5cd8ff6ddf714e0a082fc420684e2d7667fe158c5705b91946 +size 65580 diff --git a/tests/Images/Input/Tga/grayscale_UR.tga b/tests/Images/Input/Tga/grayscale_UR.tga new file mode 100644 index 000000000..a33d3aa2e --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8831036fdb79dbc9fa9d6940c6bb4bfc546b83f9caf55a65853e9a60639edece +size 65580 diff --git a/tests/Images/Input/Tga/grayscale_a_UR.tga b/tests/Images/Input/Tga/grayscale_a_UR.tga new file mode 100644 index 000000000..ce2bf4dc8 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_a_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff8cdd9cf4aa48f0df2d920483aeead476166e0e958d07aa5b8a3cd2babfd834 +size 131116 diff --git a/tests/Images/Input/Tga/rgb24_top_left.tga b/tests/Images/Input/Tga/rgb24_top_left.tga new file mode 100644 index 000000000..bfaeae686 --- /dev/null +++ b/tests/Images/Input/Tga/rgb24_top_left.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9c0aed8fb8c4e336fb1b9a6b76c9ba3e81554469191293e0b07d6afc8d9086a +size 12332 diff --git a/tests/Images/Input/Tga/rgb_a_LL.tga b/tests/Images/Input/Tga/rgb_a_LL.tga new file mode 100644 index 000000000..786eb7b7d --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_LL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eff46c35b08b02759b5e5cf4ba473b7714cf303e35cd93ae1404b8e3277014a1 +size 262188 From b44640033b467093461babee48c643c43d74d7aa Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 30 Mar 2020 18:51:16 +0200 Subject: [PATCH 09/10] Move calculation of x and y out of the for loops where possible --- src/ImageSharp/Formats/Tga/TgaDecoderCore.cs | 326 +++++++++++++----- .../Formats/Tga/TgaDecoderTests.cs | 134 +++++-- .../Formats/Tga/TgaEncoderTests.cs | 22 +- tests/ImageSharp.Tests/TestImages.cs | 43 ++- tests/Images/Input/Tga/grayscale_LR.tga | 3 + tests/Images/Input/Tga/grayscale_UL.tga | 3 + tests/Images/Input/Tga/grayscale_rle_LR.tga | 3 + tests/Images/Input/Tga/grayscale_rle_UL.tga | 3 + tests/Images/Input/Tga/grayscale_rle_UR.tga | 3 + tests/Images/Input/Tga/indexed_LR.tga | 3 + tests/Images/Input/Tga/indexed_UL.tga | 3 + tests/Images/Input/Tga/indexed_UR.tga | 3 + tests/Images/Input/Tga/rgb_a_UL.tga | 3 + tests/Images/Input/Tga/rgb_a_rle_UL.tga | 3 + 14 files changed, 412 insertions(+), 143 deletions(-) create mode 100644 tests/Images/Input/Tga/grayscale_LR.tga create mode 100644 tests/Images/Input/Tga/grayscale_UL.tga create mode 100644 tests/Images/Input/Tga/grayscale_rle_LR.tga create mode 100644 tests/Images/Input/Tga/grayscale_rle_UL.tga create mode 100644 tests/Images/Input/Tga/grayscale_rle_UR.tga create mode 100644 tests/Images/Input/Tga/indexed_LR.tga create mode 100644 tests/Images/Input/Tga/indexed_UL.tga create mode 100644 tests/Images/Input/Tga/indexed_UR.tga create mode 100644 tests/Images/Input/Tga/rgb_a_UL.tga create mode 100644 tests/Images/Input/Tga/rgb_a_rle_UL.tga diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs index e9e7ce719..a4e9bdcd7 100644 --- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs +++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs @@ -237,59 +237,69 @@ namespace SixLabors.ImageSharp.Formats.Tga private void ReadPaletted(int width, int height, Buffer2D pixels, byte[] palette, int colorMapPixelSizeInBytes, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { - using (IManagedByteBuffer row = this.memoryAllocator.AllocateManagedByteBuffer(width, AllocationOptions.Clean)) + TPixel color = default; + bool invertX = InvertX(origin); + + for (int y = 0; y < height; y++) { - TPixel color = default; - Span rowSpan = row.GetSpan(); + int newY = InvertY(y, height, origin); + Span pixelRow = pixels.GetRowSpan(newY); - for (int y = 0; y < height; y++) + switch (colorMapPixelSizeInBytes) { - this.currentStream.Read(row); - int newY = InvertY(y, height, origin); - Span pixelRow = pixels.GetRowSpan(newY); - switch (colorMapPixelSizeInBytes) - { - case 2: + case 2: + if (invertX) + { + for (int x = width - 1; x >= 0; x--) + { + this.ReadPalettedBgr16Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); + } + } + else + { for (int x = 0; x < width; x++) { - int colorIndex = rowSpan[x]; - - Bgra5551 bgra = Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes]); - if (!this.hasAlpha) - { - // Set alpha value to 1, to treat it as opaque for Bgra5551. - bgra.PackedValue = (ushort)(bgra.PackedValue | 0x8000); - } - - color.FromBgra5551(bgra); - int newX = InvertX(x, width, origin); - pixelRow[newX] = color; + this.ReadPalettedBgr16Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); } + } - break; + break; - case 3: + case 3: + if (invertX) + { + for (int x = width - 1; x >= 0; x--) + { + this.ReadPalettedBgr24Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); + } + } + else + { for (int x = 0; x < width; x++) { - int colorIndex = rowSpan[x]; - color.FromBgr24(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); - int newX = InvertX(x, width, origin); - pixelRow[newX] = color; + this.ReadPalettedBgr24Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); } + } - break; + break; - case 4: + case 4: + if (invertX) + { + for (int x = width - 1; x >= 0; x--) + { + this.ReadPalettedBgra32Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); + } + } + else + { for (int x = 0; x < width; x++) { - int colorIndex = rowSpan[x]; - color.FromBgra32(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); - int newX = InvertX(x, width, origin); - pixelRow[newX] = color; + this.ReadPalettedBgra32Pixel(palette, colorMapPixelSizeInBytes, x, color, pixelRow); } + } - break; - } + break; } } } @@ -374,20 +384,17 @@ namespace SixLabors.ImageSharp.Formats.Tga private void ReadMonoChrome(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { - bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; - if (isXInverted) + bool invertX = InvertX(origin); + if (invertX) { TPixel color = default; for (int y = 0; y < height; y++) { int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); - for (int x = 0; x < width; x++) + for (int x = width - 1; x >= 0; x--) { - var pixelValue = (byte)this.currentStream.ReadByte(); - color.FromL8(Unsafe.As(ref pixelValue)); - int newX = InvertX(x, width, origin); - pixelSpan[newX] = color; + this.ReadL8Pixel(color, x, pixelSpan); } } @@ -396,12 +403,20 @@ namespace SixLabors.ImageSharp.Formats.Tga using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 1, 0)) { - for (int y = 0; y < height; y++) + bool invertY = InvertY(origin); + if (invertY) { - this.currentStream.Read(row); - int newY = InvertY(y, height, origin); - Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.FromL8Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + for (int y = height - 1; y >= 0; y--) + { + this.ReadL8Row(width, pixels, row, y); + } + } + else + { + for (int y = 0; y < height; y++) + { + this.ReadL8Row(width, pixels, row, y); + } } } } @@ -418,7 +433,7 @@ namespace SixLabors.ImageSharp.Formats.Tga where TPixel : unmanaged, IPixel { TPixel color = default; - bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; + bool invertX = InvertX(origin); using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 2, 0)) { for (int y = 0; y < height; y++) @@ -426,9 +441,9 @@ namespace SixLabors.ImageSharp.Formats.Tga int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); - if (isXInverted) + if (invertX) { - for (int x = 0; x < width; x++) + for (int x = width - 1; x >= 0; x--) { this.currentStream.Read(this.scratchBuffer, 0, 2); if (!this.hasAlpha) @@ -445,8 +460,7 @@ namespace SixLabors.ImageSharp.Formats.Tga color.FromBgra5551(Unsafe.As(ref this.scratchBuffer[0])); } - int newX = InvertX(x, width, origin); - pixelSpan[newX] = color; + pixelSpan[x] = color; } } else @@ -487,20 +501,17 @@ namespace SixLabors.ImageSharp.Formats.Tga private void ReadBgr24(int width, int height, Buffer2D pixels, TgaImageOrigin origin) where TPixel : unmanaged, IPixel { - bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; - if (isXInverted) + bool invertX = InvertX(origin); + if (invertX) { TPixel color = default; for (int y = 0; y < height; y++) { int newY = InvertY(y, height, origin); Span pixelSpan = pixels.GetRowSpan(newY); - for (int x = 0; x < width; x++) + for (int x = width - 1; x >= 0; x--) { - this.currentStream.Read(this.scratchBuffer, 0, 3); - color.FromBgr24(Unsafe.As(ref this.scratchBuffer[0])); - int newX = InvertX(x, width, origin); - pixelSpan[newX] = color; + this.ReadBgr24Pixel(color, x, pixelSpan); } } @@ -509,12 +520,21 @@ namespace SixLabors.ImageSharp.Formats.Tga using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 3, 0)) { - for (int y = 0; y < height; y++) + bool invertY = InvertY(origin); + + if (invertY) { - this.currentStream.Read(row); - int newY = InvertY(y, height, origin); - Span pixelSpan = pixels.GetRowSpan(newY); - PixelOperations.Instance.FromBgr24Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + for (int y = height - 1; y >= 0; y--) + { + this.ReadBgr24Row(width, pixels, row, y); + } + } + else + { + for (int y = 0; y < height; y++) + { + this.ReadBgr24Row(width, pixels, row, y); + } } } } @@ -531,41 +551,46 @@ namespace SixLabors.ImageSharp.Formats.Tga where TPixel : unmanaged, IPixel { TPixel color = default; - bool isXInverted = origin == TgaImageOrigin.BottomRight || origin == TgaImageOrigin.TopRight; - if (this.tgaMetadata.AlphaChannelBits == 8 && !isXInverted) + bool invertX = InvertX(origin); + if (this.tgaMetadata.AlphaChannelBits == 8 && !invertX) { using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, 0)) { - for (int y = 0; y < height; y++) + if (InvertY(origin)) { - this.currentStream.Read(row); - int newY = InvertY(y, height, origin); - Span pixelSpan = pixels.GetRowSpan(newY); - - PixelOperations.Instance.FromBgra32Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + for (int y = height - 1; y >= 0; y--) + { + this.ReadBgra32Row(width, pixels, row, y); + } + } + else + { + for (int y = 0; y < height; y++) + { + this.ReadBgra32Row(width, pixels, row, y); + } } } return; } - var alphaBits = this.tgaMetadata.AlphaChannelBits; - using (IManagedByteBuffer row = this.memoryAllocator.AllocatePaddedPixelRowBuffer(width, 4, 0)) + for (int y = 0; y < height; y++) { - for (int y = 0; y < height; y++) + int newY = InvertY(y, height, origin); + Span pixelRow = pixels.GetRowSpan(newY); + if (invertX) + { + for (int x = width - 1; x >= 0; x--) + { + this.ReadBgra32Pixel(x, color, pixelRow); + } + } + else { - this.currentStream.Read(row); - int newY = InvertY(y, height, origin); - Span pixelRow = pixels.GetRowSpan(newY); - Span rowSpan = row.GetSpan(); - for (int x = 0; x < width; x++) { - int idx = x * 4; - var alpha = alphaBits == 0 ? byte.MaxValue : rowSpan[idx + 3]; - color.FromBgra32(new Bgra32(rowSpan[idx + 2], rowSpan[idx + 1], rowSpan[idx], (byte)alpha)); - int newX = InvertX(x, width, origin); - pixelRow[newX] = color; + this.ReadBgra32Pixel(x, color, pixelRow); } } } @@ -657,6 +682,95 @@ namespace SixLabors.ImageSharp.Formats.Tga this.metadata); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadL8Row(int width, Buffer2D pixels, IManagedByteBuffer row, int y) + where TPixel : unmanaged, IPixel + { + this.currentStream.Read(row); + Span pixelSpan = pixels.GetRowSpan(y); + PixelOperations.Instance.FromL8Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadL8Pixel(TPixel color, int x, Span pixelSpan) + where TPixel : unmanaged, IPixel + { + var pixelValue = (byte)this.currentStream.ReadByte(); + color.FromL8(Unsafe.As(ref pixelValue)); + pixelSpan[x] = color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadBgr24Pixel(TPixel color, int x, Span pixelSpan) + where TPixel : unmanaged, IPixel + { + this.currentStream.Read(this.scratchBuffer, 0, 3); + color.FromBgr24(Unsafe.As(ref this.scratchBuffer[0])); + pixelSpan[x] = color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadBgr24Row(int width, Buffer2D pixels, IManagedByteBuffer row, int y) + where TPixel : unmanaged, IPixel + { + this.currentStream.Read(row); + Span pixelSpan = pixels.GetRowSpan(y); + PixelOperations.Instance.FromBgr24Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadBgra32Pixel(int x, TPixel color, Span pixelRow) + where TPixel : unmanaged, IPixel + { + this.currentStream.Read(this.scratchBuffer, 0, 4); + var alpha = this.tgaMetadata.AlphaChannelBits == 0 ? byte.MaxValue : this.scratchBuffer[3]; + color.FromBgra32(new Bgra32(this.scratchBuffer[2], this.scratchBuffer[1], this.scratchBuffer[0], alpha)); + pixelRow[x] = color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadBgra32Row(int width, Buffer2D pixels, IManagedByteBuffer row, int y) + where TPixel : unmanaged, IPixel + { + this.currentStream.Read(row); + Span pixelSpan = pixels.GetRowSpan(y); + PixelOperations.Instance.FromBgra32Bytes(this.configuration, row.GetSpan(), pixelSpan, width); + } + + private void ReadPalettedBgr16Pixel(byte[] palette, int colorMapPixelSizeInBytes, int x, TPixel color, Span pixelRow) + where TPixel : unmanaged, IPixel + { + int colorIndex = this.currentStream.ReadByte(); + Bgra5551 bgra = default; + bgra.FromBgra5551(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); + if (!this.hasAlpha) + { + // Set alpha value to 1, to treat it as opaque for Bgra5551. + bgra.PackedValue = (ushort)(bgra.PackedValue | 0x8000); + } + + color.FromBgra5551(bgra); + pixelRow[x] = color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadPalettedBgr24Pixel(byte[] palette, int colorMapPixelSizeInBytes, int x, TPixel color, Span pixelRow) + where TPixel : unmanaged, IPixel + { + int colorIndex = this.currentStream.ReadByte(); + color.FromBgr24(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); + pixelRow[x] = color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ReadPalettedBgra32Pixel(byte[] palette, int colorMapPixelSizeInBytes, int x, TPixel color, Span pixelRow) + where TPixel : unmanaged, IPixel + { + int colorIndex = this.currentStream.ReadByte(); + color.FromBgra32(Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes])); + pixelRow[x] = color; + } + /// /// Produce uncompressed tga data from a run length encoded stream. /// @@ -710,14 +824,30 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The representing the inverted value. [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int InvertY(int y, int height, TgaImageOrigin origin) + { + if (InvertY(origin)) + { + return height - y - 1; + } + + return y; + } + + /// + /// Indicates whether the y coordinates needs to be inverted, to keep a top left origin. + /// + /// The image origin. + /// True, if y coordinate needs to be inverted. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool InvertY(TgaImageOrigin origin) { switch (origin) { case TgaImageOrigin.BottomLeft: case TgaImageOrigin.BottomRight: - return height - y - 1; + return true; default: - return y; + return false; } } @@ -730,14 +860,30 @@ namespace SixLabors.ImageSharp.Formats.Tga /// The representing the inverted value. [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int InvertX(int x, int width, TgaImageOrigin origin) + { + if (InvertX(origin)) + { + return width - x - 1; + } + + return x; + } + + /// + /// Indicates whether the x coordinates needs to be inverted, to keep a top left origin. + /// + /// The image origin. + /// True, if x coordinate needs to be inverted. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static bool InvertX(TgaImageOrigin origin) { switch (origin) { case TgaImageOrigin.TopRight: case TgaImageOrigin.BottomRight: - return width - x - 1; + return true; default: - return x; + return false; } } diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index ccd00b49f..f932f994d 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -20,8 +20,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga private static TgaDecoder TgaDecoder => new TgaDecoder(); [Theory] - [WithFile(Gray8Bit, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_Gray_8Bit(TestImageProvider provider) + [WithFile(Gray8BitTopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_Gray_WithTopLeftOrigin_8Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -68,8 +68,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Gray8BitRle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_8Bit(TestImageProvider provider) + [WithFile(Gray8BitRleTopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithTopLeftOrigin_8Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -80,7 +80,43 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Gray16Bit, PixelTypes.Rgba32)] + [WithFile(Gray8BitRleTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithTopRightOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray8BitRleBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithBottomLeftOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray8BitRleBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_WithBottomRightOrigin_8Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Gray16BitTopLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_Gray_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -140,7 +176,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Gray16BitRle, PixelTypes.Rgba32)] + [WithFile(Gray16BitRleTopLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_RunLengthEncoded_Gray_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -248,8 +284,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit24, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_24Bit(TestImageProvider provider) + [WithFile(Bit24TopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithTopLeftOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -344,8 +380,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_32Bit(TestImageProvider provider) + [WithFile(Bit32TopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithTopLeftOrigin_32Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32TopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithTopRightOrigin_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -380,8 +428,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit32TopRight, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_WithTopRightOrigin_32Bit(TestImageProvider provider) + [WithFile(Bit16RleBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithBottomLeftOrigin_16Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -392,8 +440,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit16Rle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_16Bit(TestImageProvider provider) + [WithFile(Bit24RleBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithBottomLeftOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -404,8 +452,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit24Rle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_24Bit(TestImageProvider provider) + [WithFile(Bit32RleTopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithTopLeftOrigin_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -416,8 +464,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit32Rle, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_RunLengthEncoded_32Bit(TestImageProvider provider) + [WithFile(Bit32RleBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_RunLengthEncoded_WithBottomLeftOrigin_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -452,8 +500,32 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit16Pal, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_WithPalette_16Bit(TestImageProvider provider) + [WithFile(Bit16PalBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPaletteBottomLeftOrigin_16Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit24PalTopLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPaletteTopLeftOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit24PalTopRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPaletteTopRightOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -464,8 +536,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit24Pal, PixelTypes.Rgba32)] - public void TgaDecoder_CanDecode_WithPalette_24Bit(TestImageProvider provider) + [WithFile(Bit24PalBottomLeft, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPaletteBottomLeftOrigin_24Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { using (Image image = provider.GetImage(TgaDecoder)) @@ -476,7 +548,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit32Pal, PixelTypes.Rgba32)] + [WithFile(Bit24PalBottomRight, PixelTypes.Rgba32)] + public void TgaDecoder_CanDecode_WithPaletteBottomRightOrigin_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(TgaDecoder)) + { + image.DebugSave(provider); + TgaTestUtils.CompareWithReferenceDecoder(provider, image); + } + } + + [Theory] + [WithFile(Bit32PalTopLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithPalette_32Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -554,7 +638,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit16BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit24BottomLeft, PixelTypes.Rgba32)] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaDecoder_DegenerateMemoryRequest_ShouldTranslateTo_ImageFormatException(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -565,7 +649,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga [Theory] [WithFile(Bit24BottomLeft, PixelTypes.Rgba32)] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaDecoder_CanDecode_WithLimitedAllocatorBufferCapacity(TestImageProvider provider) where TPixel : unmanaged, IPixel { diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs index 4e3e2d24c..6e0fa4a0e 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs @@ -25,10 +25,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga public static readonly TheoryData TgaBitsPerPixelFiles = new TheoryData { - { Gray8Bit, TgaBitsPerPixel.Pixel8 }, + { Gray8BitBottomLeft, TgaBitsPerPixel.Pixel8 }, { Bit16BottomLeft, TgaBitsPerPixel.Pixel16 }, { Bit24BottomLeft, TgaBitsPerPixel.Pixel24 }, - { Bit32, TgaBitsPerPixel.Pixel32 }, + { Bit32BottomLeft, TgaBitsPerPixel.Pixel32 }, }; [Theory] @@ -79,51 +79,51 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga } [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit8_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8) // Using tolerant comparer here. The results from magick differ slightly. Maybe a different ToGrey method is used. The image looks otherwise ok. where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false, compareTolerance: 0.03f); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit16_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit24_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit32_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit8_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8) // Using tolerant comparer here. The results from magick differ slightly. Maybe a different ToGrey method is used. The image looks otherwise ok. where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false, compareTolerance: 0.03f); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit16_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit24_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] public void TgaEncoder_Bit32_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32) where TPixel : unmanaged, IPixel => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength); [Theory] - [WithFile(Bit32, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel32)] + [WithFile(Bit32BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel32)] [WithFile(Bit24BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)] public void TgaEncoder_WorksWithDiscontiguousBuffers(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel) where TPixel : unmanaged, IPixel diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 38ef8d9e2..272998a89 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -375,53 +375,62 @@ namespace SixLabors.ImageSharp.Tests public static class Tga { - public const string Gray8Bit = "Tga/targa_8bit.tga"; - public const string Gray8BitBottomLeft = "Tga/grayscale_LL.tga"; + public const string Gray8BitTopLeft = "Tga/grayscale_UL.tga"; public const string Gray8BitTopRight = "Tga/grayscale_UR.tga"; - public const string Gray8BitBottomRight = "Tga/grayscale_UR.tga"; - public const string Gray8BitRle = "Tga/targa_8bit_rle.tga"; + public const string Gray8BitBottomLeft = "Tga/targa_8bit.tga"; + public const string Gray8BitBottomRight = "Tga/grayscale_LR.tga"; + + public const string Gray8BitRleTopLeft = "Tga/grayscale_rle_UL.tga"; + public const string Gray8BitRleTopRight = "Tga/grayscale_rle_UR.tga"; + public const string Gray8BitRleBottomLeft = "Tga/targa_8bit_rle.tga"; + public const string Gray8BitRleBottomRight = "Tga/grayscale_rle_LR.tga"; public const string Bit15 = "Tga/rgb15.tga"; public const string Bit15Rle = "Tga/rgb15rle.tga"; public const string Bit16BottomLeft = "Tga/targa_16bit.tga"; public const string Bit16PalRle = "Tga/ccm8.tga"; + public const string Bit16RleBottomLeft = "Tga/targa_16bit_rle.tga"; + public const string Bit16PalBottomLeft = "Tga/targa_16bit_pal.tga"; - public const string Gray16Bit = "Tga/grayscale_a_UL.tga"; + public const string Gray16BitTopLeft = "Tga/grayscale_a_UL.tga"; public const string Gray16BitBottomLeft = "Tga/grayscale_a_LL.tga"; public const string Gray16BitBottomRight = "Tga/grayscale_a_LR.tga"; public const string Gray16BitTopRight = "Tga/grayscale_a_UR.tga"; - public const string Gray16BitRle = "Tga/grayscale_a_rle_UL.tga"; + + public const string Gray16BitRleTopLeft = "Tga/grayscale_a_rle_UL.tga"; public const string Gray16BitRleBottomLeft = "Tga/grayscale_a_rle_LL.tga"; public const string Gray16BitRleBottomRight = "Tga/grayscale_a_rle_LR.tga"; public const string Gray16BitRleTopRight = "Tga/grayscale_a_rle_UR.tga"; - public const string Bit24 = "Tga/rgb24_top_left.tga"; + public const string Bit24TopLeft = "Tga/rgb24_top_left.tga"; public const string Bit24BottomLeft = "Tga/targa_24bit.tga"; public const string Bit24BottomRight = "Tga/rgb_LR.tga"; public const string Bit24TopRight = "Tga/rgb_UR.tga"; - public const string Bit24TopLeft = "Tga/targa_24bit_pal_origin_topleft.tga"; public const string Bit24RleTopLeft = "Tga/targa_24bit_rle_origin_topleft.tga"; + public const string Bit24RleBottomLeft = "Tga/targa_24bit_rle.tga"; public const string Bit24RleTopRight = "Tga/rgb_rle_UR.tga"; public const string Bit24RleBottomRight = "Tga/rgb_rle_LR.tga"; - public const string Bit32 = "Tga/targa_32bit.tga"; - public const string Bit32BottomLeft = "Tga/rgb_a_LL.tga"; + public const string Bit24PalTopLeft = "Tga/targa_24bit_pal_origin_topleft.tga"; + public const string Bit24PalTopRight = "Tga/indexed_UR.tga"; + public const string Bit24PalBottomLeft = "Tga/targa_24bit_pal.tga"; + public const string Bit24PalBottomRight = "Tga/indexed_LR.tga"; + + public const string Bit32TopLeft = "Tga/rgb_a_UL.tga"; + public const string Bit32BottomLeft = "Tga/targa_32bit.tga"; public const string Bit32TopRight = "Tga/rgb_a_UR.tga"; public const string Bit32BottomRight = "Tga/rgb_a_LR.tga"; - public const string Bit32Pal = "Tga/indexed_a_UL.tga"; + public const string Bit32PalTopLeft = "Tga/indexed_a_UL.tga"; public const string Bit32PalBottomLeft = "Tga/indexed_a_LL.tga"; public const string Bit32PalBottomRight = "Tga/indexed_a_LR.tga"; public const string Bit32PalTopRight = "Tga/indexed_a_UR.tga"; + + public const string Bit32RleTopLeft = "Tga/rgb_a_rle_UL.tga"; public const string Bit32RleTopRight = "Tga/rgb_a_rle_UR.tga"; public const string Bit32RleBottomRight = "Tga/rgb_a_rle_LR.tga"; - - public const string Bit16Rle = "Tga/targa_16bit_rle.tga"; - public const string Bit24Rle = "Tga/targa_24bit_rle.tga"; - public const string Bit32Rle = "Tga/targa_32bit_rle.tga"; - public const string Bit16Pal = "Tga/targa_16bit_pal.tga"; - public const string Bit24Pal = "Tga/targa_24bit_pal.tga"; + public const string Bit32RleBottomLeft = "Tga/targa_32bit_rle.tga"; public const string NoAlphaBits16Bit = "Tga/16bit_noalphabits.tga"; public const string NoAlphaBits16BitRle = "Tga/16bit_rle_noalphabits.tga"; diff --git a/tests/Images/Input/Tga/grayscale_LR.tga b/tests/Images/Input/Tga/grayscale_LR.tga new file mode 100644 index 000000000..01c71b81c --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ed269c8f3bb462d963188d7352ebe85ab20357ac7803e5ac4d7110a23b9e6ddb +size 65580 diff --git a/tests/Images/Input/Tga/grayscale_UL.tga b/tests/Images/Input/Tga/grayscale_UL.tga new file mode 100644 index 000000000..7670e83f1 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72c6e1e09b923455e0c8cd14c37b358eb578bc14a0a8fcedde3ab81769960eb7 +size 65580 diff --git a/tests/Images/Input/Tga/grayscale_rle_LR.tga b/tests/Images/Input/Tga/grayscale_rle_LR.tga new file mode 100644 index 000000000..766d3884c --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_rle_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a897be6870be2cd183e7678e954767fd12a763c7bfce0f2246f1b7cc1ad08804 +size 31165 diff --git a/tests/Images/Input/Tga/grayscale_rle_UL.tga b/tests/Images/Input/Tga/grayscale_rle_UL.tga new file mode 100644 index 000000000..699e7ae5b --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_rle_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f11be4af2283059e869543949588fe19db0e36dec64157ad9a61711cb5e6428 +size 31198 diff --git a/tests/Images/Input/Tga/grayscale_rle_UR.tga b/tests/Images/Input/Tga/grayscale_rle_UR.tga new file mode 100644 index 000000000..c61503db8 --- /dev/null +++ b/tests/Images/Input/Tga/grayscale_rle_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5aa67ec6d3408fd469ec8e7c5613daf130be893e0b76dee2994a2c32ddae471 +size 31054 diff --git a/tests/Images/Input/Tga/indexed_LR.tga b/tests/Images/Input/Tga/indexed_LR.tga new file mode 100644 index 000000000..659c3bcea --- /dev/null +++ b/tests/Images/Input/Tga/indexed_LR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6d5219fadf7d8b743d35c7e16f11e1182f76351757ff962e0a27f81c357b1fb +size 66315 diff --git a/tests/Images/Input/Tga/indexed_UL.tga b/tests/Images/Input/Tga/indexed_UL.tga new file mode 100644 index 000000000..da2a3f8ef --- /dev/null +++ b/tests/Images/Input/Tga/indexed_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f42dd07528f9e4f7914a570c027cc845edfe6d3fcdfa45ec8f21bc254cc1f1f +size 66315 diff --git a/tests/Images/Input/Tga/indexed_UR.tga b/tests/Images/Input/Tga/indexed_UR.tga new file mode 100644 index 000000000..a497383ab --- /dev/null +++ b/tests/Images/Input/Tga/indexed_UR.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90d8caa10d3a05f845f94b176a77a2ed85e25b3d460527c96abfe793870c89b8 +size 66315 diff --git a/tests/Images/Input/Tga/rgb_a_UL.tga b/tests/Images/Input/Tga/rgb_a_UL.tga new file mode 100644 index 000000000..7ee3a5212 --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1a167af1f8d64119e206593f8944c0b7901393a1b97d703c0121b8a59cae03f4 +size 262188 diff --git a/tests/Images/Input/Tga/rgb_a_rle_UL.tga b/tests/Images/Input/Tga/rgb_a_rle_UL.tga new file mode 100644 index 000000000..0ea58fd1d --- /dev/null +++ b/tests/Images/Input/Tga/rgb_a_rle_UL.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be1323021deead462ef38c17eea5d59aea7467ae33b91bd65b542085e74aa4e4 +size 98427 From a80c36ab3a4869b14ea056c76194f9403e19c246 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Tue, 31 Mar 2020 11:59:40 +0200 Subject: [PATCH 10/10] Fix build error due to renamed files --- tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs | 2 +- tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs b/tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs index 3c8f45edb..072bd53ed 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/DecodeTga.cs @@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs private byte[] data; - [Params(TestImages.Tga.Bit24)] + [Params(TestImages.Tga.Bit24BottomLeft)] public string TestImage { get; set; } [GlobalSetup] diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs index 7100ca6b7..f10eacb28 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs @@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); - [Params(TestImages.Tga.Bit24)] + [Params(TestImages.Tga.Bit24BottomLeft)] public string TestImage { get; set; } [GlobalSetup]