Browse Source

Merge pull request #1157 from SixLabors/bp/tgaAlphaBits

TGA dont ignore alpha channel bits
pull/1574/head
James Jackson-South 6 years ago
committed by GitHub
parent
commit
9fece40328
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/ImageSharp/Formats/Tga/TgaDecoder.cs
  2. 138
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  3. 20
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  4. 5
      src/ImageSharp/Formats/Tga/TgaMetadata.cs
  5. 29
      tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs
  6. 22
      tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
  7. 4
      tests/ImageSharp.Tests/TestImages.cs
  8. 2
      tests/Images/External
  9. 3
      tests/Images/Input/Tga/16bit_noalphabits.tga
  10. 3
      tests/Images/Input/Tga/16bit_rle_noalphabits.tga
  11. 3
      tests/Images/Input/Tga/32bit_no_alphabits.tga
  12. 3
      tests/Images/Input/Tga/32bit_rle_no_alphabits.tga

1
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;

138
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -12,6 +12,9 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tga
{
/// <summary>
/// Performs the tga decoding operation.
/// </summary>
internal sealed class TgaDecoderCore
{
/// <summary>
@ -49,6 +52,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// </summary>
private readonly ITgaDecoderOptions options;
/// <summary>
/// Indicates whether there is a alpha channel present.
/// </summary>
private bool hasAlpha;
/// <summary>
/// Initializes a new instance of the <see cref="TgaDecoderCore"/> class.
/// </summary>
@ -97,7 +105,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
var image = Image.CreateUninitialized<TPixel>(this.configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata);
Buffer2D<TPixel> 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<byte, Bgra5551>(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<byte> buffer = this.memoryAllocator.Allocate<byte>(width * height * bytesPerPixel, AllocationOptions.Clean))
{
TPixel color = default;
var alphaBits = this.tgaMetadata.AlphaChannelBits;
Span<byte> bufferSpan = buffer.GetSpan();
this.UncompressRle(width, height, bufferSpan, bytesPerPixel: 1);
@ -308,16 +321,30 @@ namespace SixLabors.ImageSharp.Formats.Tga
color.FromL8(Unsafe.As<byte, L8>(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
break;
case 2:
// Set alpha value to 1, to treat it as opaque for Bgra5551.
Bgra5551 bgra = Unsafe.As<byte, Bgra5551>(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<byte, Bgr24>(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
break;
case 4:
color.FromBgra32(Unsafe.As<byte, Bgra32>(ref palette[bufferSpan[idx] * colorMapPixelSizeInBytes]));
if (this.hasAlpha)
{
color.FromBgra32(Unsafe.As<byte, Bgra32>(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<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.Instance.FromL8Bytes(
this.configuration,
row.GetSpan(),
pixelSpan,
width);
PixelOperations<TPixel>.Instance.FromL8Bytes(this.configuration, row.GetSpan(), pixelSpan, width);
}
}
}
@ -372,19 +395,18 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.currentStream.Read(row);
Span<byte> 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<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.Instance.FromBgra5551Bytes(
this.configuration,
rowSpan,
pixelSpan,
width);
PixelOperations<TPixel>.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<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.Instance.FromBgr24Bytes(
this.configuration,
row.GetSpan(),
pixelSpan,
width);
PixelOperations<TPixel>.Instance.FromBgr24Bytes(this.configuration, row.GetSpan(), pixelSpan, width);
}
}
}
@ -427,18 +445,41 @@ namespace SixLabors.ImageSharp.Formats.Tga
private void ReadBgra32<TPixel>(int width, int height, Buffer2D<TPixel> pixels, bool inverted)
where TPixel : unmanaged, IPixel<TPixel>
{
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<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.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<TPixel> pixelSpan = pixels.GetRowSpan(newY);
PixelOperations<TPixel>.Instance.FromBgra32Bytes(
this.configuration,
row.GetSpan(),
pixelSpan,
width);
Span<TPixel> pixelRow = pixels.GetRowSpan(newY);
Span<byte> 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>
{
TPixel color = default;
var alphaBits = this.tgaMetadata.AlphaChannelBits;
using (IMemoryOwner<byte> buffer = this.memoryAllocator.Allocate<byte>(width * height * bytesPerPixel, AllocationOptions.Clean))
{
Span<byte> bufferSpan = buffer.GetSpan();
@ -474,15 +516,28 @@ namespace SixLabors.ImageSharp.Formats.Tga
color.FromL8(Unsafe.As<byte, L8>(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<byte, Bgra5551>(ref bufferSpan[idx]));
break;
case 3:
color.FromBgr24(Unsafe.As<byte, Bgr24>(ref bufferSpan[idx]));
break;
case 4:
color.FromBgra32(Unsafe.As<byte, Bgra32>(ref bufferSpan[idx]));
if (this.hasAlpha)
{
color.FromBgra32(Unsafe.As<byte, Bgra32>(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;

20
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,

5
src/ImageSharp/Formats/Tga/TgaMetadata.cs

@ -29,6 +29,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// </summary>
public TgaBitsPerPixel BitsPerPixel { get; set; } = TgaBitsPerPixel.Pixel24;
/// <summary>
/// Gets or sets the the number of alpha bits per pixel.
/// </summary>
public byte AlphaChannelBits { get; set; } = 0;
/// <inheritdoc/>
public IDeepCloneable DeepClone() => new TgaMetadata(this);
}

29
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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> 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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> 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)]

22
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<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8)
public void TgaEncoder_Bit8_Works<TPixel>(TestImageProvider<TPixel> 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<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false, compareTolerance: 0.03f);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit16_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
public void TgaEncoder_Bit16_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit24_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
public void TgaEncoder_Bit24_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit32_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
public void TgaEncoder_Bit32_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit8_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8)
public void TgaEncoder_Bit8_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> 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<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false, compareTolerance: 0.03f);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit16_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
public void TgaEncoder_Bit16_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit24_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
public void TgaEncoder_Bit24_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32)]
public void Encode_Bit32_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
public void TgaEncoder_Bit32_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength);
[Theory]
[WithFile(Bit32, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel32)]
[WithFile(Bit24, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)]
public void Encode_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel)
public void TgaEncoder_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel>
{
provider.LimitAllocatorBufferCapacity().InPixelsSqrt(100);

4
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";
}
}
}

2
tests/Images/External

@ -1 +1 @@
Subproject commit d809551931858cd3873bad49d2fe915fddff7a26
Subproject commit 985e050aa7ac11830ae7a178ca2283f8b6307e4c

3
tests/Images/Input/Tga/16bit_noalphabits.tga

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f7a71e04cb2c335fb46bb91c6bf71e32deafe6a65b701e9fbdb1f95ec69a432c
size 96818

3
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

3
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

3
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
Loading…
Cancel
Save