diff --git a/src/ImageSharp/Formats/Tga/TgaDecoder.cs b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
index 2249c86bf..c3b8526ce 100644
--- a/src/ImageSharp/Formats/Tga/TgaDecoder.cs
+++ b/src/ImageSharp/Formats/Tga/TgaDecoder.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
using System.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
diff --git a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
index ead004003..cca34c9b0 100644
--- a/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
+++ b/src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
@@ -12,6 +12,9 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tga
{
+ ///
+ /// Performs the tga decoding operation.
+ ///
internal sealed class TgaDecoderCore
{
///
@@ -49,6 +52,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
///
private readonly ITgaDecoderOptions options;
+ ///
+ /// Indicates whether there is a alpha channel present.
+ ///
+ private bool hasAlpha;
+
///
/// Initializes a new instance of the class.
///
@@ -97,7 +105,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
var image = Image.CreateUninitialized(this.configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata);
Buffer2D pixels = image.GetRootFramePixelBuffer();
- if (this.fileHeader.ColorMapType is 1)
+ if (this.fileHeader.ColorMapType == 1)
{
if (this.fileHeader.CMapLength <= 0)
{
@@ -115,7 +123,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
{
this.currentStream.Read(palette.Array, this.fileHeader.CMapStart, colorMapSizeInBytes);
- if (this.fileHeader.ImageType is TgaImageType.RleColorMapped)
+ if (this.fileHeader.ImageType == TgaImageType.RleColorMapped)
{
this.ReadPalettedRle(
this.fileHeader.Width,
@@ -199,7 +207,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
break;
default:
- TgaThrowHelper.ThrowNotSupportedException("Does not support this kind of tga files.");
+ TgaThrowHelper.ThrowNotSupportedException("ImageSharp does not support this kind of tga files.");
break;
}
@@ -241,9 +249,13 @@ namespace SixLabors.ImageSharp.Formats.Tga
{
int colorIndex = rowSpan[x];
- // Set alpha value to 1, to treat it as opaque for Bgra5551.
Bgra5551 bgra = Unsafe.As(ref palette[colorIndex * colorMapPixelSizeInBytes]);
- bgra.PackedValue = (ushort)(bgra.PackedValue | 0x8000);
+ 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;
}
@@ -291,6 +303,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
using (IMemoryOwner buffer = this.memoryAllocator.Allocate(width * height * bytesPerPixel, AllocationOptions.Clean))
{
TPixel color = default;
+ var alphaBits = this.tgaMetadata.AlphaChannelBits;
Span bufferSpan = buffer.GetSpan();
this.UncompressRle(width, height, bufferSpan, bytesPerPixel: 1);
@@ -308,16 +321,30 @@ namespace SixLabors.ImageSharp.Formats.Tga
color.FromL8(Unsafe.As(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
break;
case 2:
- // Set alpha value to 1, to treat it as opaque for Bgra5551.
+
Bgra5551 bgra = Unsafe.As(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]);
- bgra.PackedValue = (ushort)(bgra.PackedValue | 0x8000);
+ if (!this.hasAlpha)
+ {
+ // Set alpha value to 1, to treat it as opaque for Bgra5551.
+ bgra.PackedValue = (ushort)(bgra.PackedValue | 0x8000);
+ }
+
color.FromBgra5551(bgra);
break;
case 3:
color.FromBgr24(Unsafe.As(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
break;
case 4:
- color.FromBgra32(Unsafe.As(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
+ if (this.hasAlpha)
+ {
+ color.FromBgra32(Unsafe.As(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
+ }
+ else
+ {
+ var alpha = alphaBits == 0 ? byte.MaxValue : bufferSpan[idx + 3];
+ color.FromBgra32(new Bgra32(bufferSpan[idx + 2], bufferSpan[idx + 1], bufferSpan[idx], (byte)alpha));
+ }
+
break;
}
@@ -345,11 +372,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.currentStream.Read(row);
int newY = Invert(y, height, inverted);
Span pixelSpan = pixels.GetRowSpan(newY);
- PixelOperations.Instance.FromL8Bytes(
- this.configuration,
- row.GetSpan(),
- pixelSpan,
- width);
+ PixelOperations.Instance.FromL8Bytes(this.configuration, row.GetSpan(), pixelSpan, width);
}
}
}
@@ -372,19 +395,18 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.currentStream.Read(row);
Span rowSpan = row.GetSpan();
- // We need to set each alpha component value to fully opaque.
- for (int x = 1; x < rowSpan.Length; x += 2)
+ if (!this.hasAlpha)
{
- rowSpan[x] = (byte)(rowSpan[x] | (1 << 7));
+ // We need to set the alpha component value to fully opaque.
+ for (int x = 1; x < rowSpan.Length; x += 2)
+ {
+ rowSpan[x] = (byte)(rowSpan[x] | (1 << 7));
+ }
}
int newY = Invert(y, height, inverted);
Span pixelSpan = pixels.GetRowSpan(newY);
- PixelOperations.Instance.FromBgra5551Bytes(
- this.configuration,
- rowSpan,
- pixelSpan,
- width);
+ PixelOperations.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width);
}
}
}
@@ -407,11 +429,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.currentStream.Read(row);
int newY = Invert(y, height, inverted);
Span pixelSpan = pixels.GetRowSpan(newY);
- PixelOperations.Instance.FromBgr24Bytes(
- this.configuration,
- row.GetSpan(),
- pixelSpan,
- width);
+ PixelOperations.Instance.FromBgr24Bytes(this.configuration, row.GetSpan(), pixelSpan, width);
}
}
}
@@ -427,18 +445,41 @@ namespace SixLabors.ImageSharp.Formats.Tga
private void ReadBgra32(int width, int height, Buffer2D pixels, bool inverted)
where TPixel : unmanaged, IPixel
{
+ if (this.tgaMetadata.AlphaChannelBits == 8)
+ {
+ 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);
+ Span pixelSpan = pixels.GetRowSpan(newY);
+
+ PixelOperations.Instance.FromBgra32Bytes(this.configuration, row.GetSpan(), pixelSpan, width);
+ }
+ }
+
+ 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);
- Span pixelSpan = pixels.GetRowSpan(newY);
- PixelOperations.Instance.FromBgra32Bytes(
- this.configuration,
- row.GetSpan(),
- pixelSpan,
- width);
+ 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));
+ pixelRow[x] = color;
+ }
}
}
}
@@ -456,6 +497,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
where TPixel : unmanaged, IPixel
{
TPixel color = default;
+ var alphaBits = this.tgaMetadata.AlphaChannelBits;
using (IMemoryOwner buffer = this.memoryAllocator.Allocate(width * height * bytesPerPixel, AllocationOptions.Clean))
{
Span bufferSpan = buffer.GetSpan();
@@ -474,15 +516,28 @@ namespace SixLabors.ImageSharp.Formats.Tga
color.FromL8(Unsafe.As(ref bufferSpan[idx]));
break;
case 2:
- // Set alpha value to 1, to treat it as opaque for Bgra5551.
- bufferSpan[idx + 1] = (byte)(bufferSpan[idx + 1] | 128);
+ if (!this.hasAlpha)
+ {
+ // Set alpha value to 1, to treat it as opaque for Bgra5551.
+ bufferSpan[idx + 1] = (byte)(bufferSpan[idx + 1] | 128);
+ }
+
color.FromBgra5551(Unsafe.As(ref bufferSpan[idx]));
break;
case 3:
color.FromBgr24(Unsafe.As(ref bufferSpan[idx]));
break;
case 4:
- color.FromBgra32(Unsafe.As(ref bufferSpan[idx]));
+ if (this.hasAlpha)
+ {
+ color.FromBgra32(Unsafe.As(ref bufferSpan[idx]));
+ }
+ else
+ {
+ var alpha = alphaBits == 0 ? byte.MaxValue : bufferSpan[idx + 3];
+ color.FromBgra32(new Bgra32(bufferSpan[idx + 2], bufferSpan[idx + 1], bufferSpan[idx], (byte)alpha));
+ }
+
break;
}
@@ -577,7 +632,18 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.tgaMetadata = this.metadata.GetTgaMetadata();
this.tgaMetadata.BitsPerPixel = (TgaBitsPerPixel)this.fileHeader.PixelDepth;
- // Bit at position 5 of the descriptor indicates, that the origin is top left instead of bottom right.
+ var alphaBits = this.fileHeader.ImageDescriptor & 0xf;
+ if (alphaBits != 0 && alphaBits != 1 && alphaBits != 8)
+ {
+ TgaThrowHelper.ThrowImageFormatException("Invalid alpha channel bits");
+ }
+
+ 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;
diff --git a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
index d5d7ce49e..94bd367aa 100644
--- a/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
+++ b/src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
@@ -78,8 +78,24 @@ namespace SixLabors.ImageSharp.Formats.Tga
imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite;
}
- // If compression is used, set bit 5 of the image descriptor to indicate an left top origin.
- byte imageDescriptor = (byte)(this.compression is TgaCompression.RunLength ? 32 : 0);
+ byte imageDescriptor = 0;
+ if (this.compression is TgaCompression.RunLength)
+ {
+ // If compression is used, set bit 5 of the image descriptor to indicate a left top origin.
+ imageDescriptor |= 0x20;
+ }
+
+ if (this.bitsPerPixel is TgaBitsPerPixel.Pixel32)
+ {
+ // Indicate, that 8 bit are used for the alpha channel.
+ imageDescriptor |= 0x8;
+ }
+
+ if (this.bitsPerPixel is TgaBitsPerPixel.Pixel16)
+ {
+ // Indicate, that 1 bit is used for the alpha channel.
+ imageDescriptor |= 0x1;
+ }
var fileHeader = new TgaFileHeader(
idLength: 0,
diff --git a/src/ImageSharp/Formats/Tga/TgaMetadata.cs b/src/ImageSharp/Formats/Tga/TgaMetadata.cs
index 4ce61d2e4..69dee768a 100644
--- a/src/ImageSharp/Formats/Tga/TgaMetadata.cs
+++ b/src/ImageSharp/Formats/Tga/TgaMetadata.cs
@@ -29,6 +29,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
///
public TgaBitsPerPixel BitsPerPixel { get; set; } = TgaBitsPerPixel.Pixel24;
+ ///
+ /// Gets or sets the the number of alpha bits per pixel.
+ ///
+ public byte AlphaChannelBits { get; set; } = 0;
+
///
public IDeepCloneable DeepClone() => new TgaMetadata(this);
}
diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs
index bcd98d714..767b3b954 100644
--- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs
@@ -7,6 +7,7 @@ using SixLabors.ImageSharp.Formats.Tga;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities;
+using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
// ReSharper disable InconsistentNaming
@@ -198,6 +199,34 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
}
}
+ [Theory]
+ [WithFile(NoAlphaBits16Bit, PixelTypes.Rgba32)]
+ [WithFile(NoAlphaBits16BitRle, PixelTypes.Rgba32)]
+ public void TgaDecoder_CanDecode_WhenAlphaBitsNotSet_16Bit(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using (Image image = provider.GetImage(TgaDecoder))
+ {
+ image.DebugSave(provider);
+ TgaTestUtils.CompareWithReferenceDecoder(provider, image);
+ }
+ }
+
+ [Theory]
+ [WithFile(NoAlphaBits32Bit, PixelTypes.Rgba32)]
+ [WithFile(NoAlphaBits32BitRle, PixelTypes.Rgba32)]
+ public void TgaDecoder_CanDecode_WhenAlphaBitsNotSet(TestImageProvider provider)
+ where TPixel : unmanaged, IPixel
+ {
+ using (Image image = provider.GetImage(TgaDecoder))
+ {
+ // Using here the reference output instead of the the reference decoder,
+ // because the reference decoder does not ignore the alpha data here.
+ image.DebugSave(provider);
+ image.CompareToReferenceOutput(ImageComparer.Exact, provider);
+ }
+ }
+
[Theory]
[WithFile(Bit16, PixelTypes.Rgba32)]
[WithFile(Bit24, PixelTypes.Rgba32)]
diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
index f123370d1..00664de6e 100644
--- a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
@@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
[Theory]
[MemberData(nameof(TgaBitsPerPixelFiles))]
- public void Encode_PreserveBitsPerPixel(string imagePath, TgaBitsPerPixel bmpBitsPerPixel)
+ public void TgaEncoder_PreserveBitsPerPixel(string imagePath, TgaBitsPerPixel bmpBitsPerPixel)
{
var options = new TgaEncoder();
@@ -55,7 +55,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
[Theory]
[MemberData(nameof(TgaBitsPerPixelFiles))]
- public void Encode_WithCompression_PreserveBitsPerPixel(string imagePath, TgaBitsPerPixel bmpBitsPerPixel)
+ public void TgaEncoder_WithCompression_PreserveBitsPerPixel(string imagePath, TgaBitsPerPixel bmpBitsPerPixel)
{
var options = new TgaEncoder()
{
@@ -80,52 +80,52 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tga
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
- public void Encode_Bit8_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8)
+ 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)]
- public void Encode_Bit16_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
+ 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)]
- public void Encode_Bit24_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
+ 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)]
- public void Encode_Bit32_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
+ 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)]
- public void Encode_Bit8_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8)
+ 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)]
- public void Encode_Bit16_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
+ 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)]
- public void Encode_Bit24_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
+ 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)]
- public void Encode_Bit32_WithRunLengthEncoding_Works(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
+ 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(Bit24, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)]
- public void Encode_WorksWithDiscontiguousBuffers(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel)
+ public void TgaEncoder_WorksWithDiscontiguousBuffers(TestImageProvider provider, TgaBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel
{
provider.LimitAllocatorBufferCapacity().InPixelsSqrt(100);
diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs
index 2e58ac970..3e2f4aa6f 100644
--- a/tests/ImageSharp.Tests/TestImages.cs
+++ b/tests/ImageSharp.Tests/TestImages.cs
@@ -390,6 +390,10 @@ namespace SixLabors.ImageSharp.Tests
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";
+ public const string NoAlphaBits32BitRle = "Tga/32bit_rle_no_alphabits.tga";
}
}
}
diff --git a/tests/Images/External b/tests/Images/External
index d80955193..985e050aa 160000
--- a/tests/Images/External
+++ b/tests/Images/External
@@ -1 +1 @@
-Subproject commit d809551931858cd3873bad49d2fe915fddff7a26
+Subproject commit 985e050aa7ac11830ae7a178ca2283f8b6307e4c
diff --git a/tests/Images/Input/Tga/16bit_noalphabits.tga b/tests/Images/Input/Tga/16bit_noalphabits.tga
new file mode 100644
index 000000000..cff4abf94
--- /dev/null
+++ b/tests/Images/Input/Tga/16bit_noalphabits.tga
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7a71e04cb2c335fb46bb91c6bf71e32deafe6a65b701e9fbdb1f95ec69a432c
+size 96818
diff --git a/tests/Images/Input/Tga/16bit_rle_noalphabits.tga b/tests/Images/Input/Tga/16bit_rle_noalphabits.tga
new file mode 100644
index 000000000..b1bbb8c54
--- /dev/null
+++ b/tests/Images/Input/Tga/16bit_rle_noalphabits.tga
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4c605b2ef72f8e54530cb3f0922527ee2754adab8d158276931ec7e2842f2644
+size 138354
diff --git a/tests/Images/Input/Tga/32bit_no_alphabits.tga b/tests/Images/Input/Tga/32bit_no_alphabits.tga
new file mode 100644
index 000000000..903eca459
--- /dev/null
+++ b/tests/Images/Input/Tga/32bit_no_alphabits.tga
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0aea1128a1bd7477dfa0d007a1eba25907be24847284c48a5f9fbd61bcea3cf0
+size 61522
diff --git a/tests/Images/Input/Tga/32bit_rle_no_alphabits.tga b/tests/Images/Input/Tga/32bit_rle_no_alphabits.tga
new file mode 100644
index 000000000..b21dad5e0
--- /dev/null
+++ b/tests/Images/Input/Tga/32bit_rle_no_alphabits.tga
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98a198392bd527523f8649d6126af81e5a588ad7265dc3d48a1da7b5a6cb6ff7
+size 230578