diff --git a/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs b/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
index 300172f6c..9074b3756 100644
--- a/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
+++ b/src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
public sealed class TgaImageFormatDetector : IImageFormatDetector
{
///
- public int HeaderSize => TgaConstants.FileHeaderLength;
+ public int HeaderSize => 16;
///
public IImageFormat DetectFormat(ReadOnlySpan header)
@@ -23,15 +23,38 @@ namespace SixLabors.ImageSharp.Formats.Tga
{
if (header.Length >= this.HeaderSize)
{
- // There are no magic bytes in a tga file, so at least the image type
- // and the colormap type in the header will be checked for a valid value.
+ // There are no magic bytes in the first few bytes of a tga file,
+ // so we try to figure out if its a valid tga by checking for valid tga header bytes.
+
+ // The color map type should be either 0 or 1, other values are not valid.
if (header[1] != 0 && header[1] != 1)
{
return false;
}
+ // The third byte is the image type.
var imageType = (TgaImageType)header[2];
- return imageType.IsValid();
+ if (!imageType.IsValid())
+ {
+ return false;
+ }
+
+ // If the color map typ is zero, all bytes of the color map specification should also be zeros.
+ if (header[1] == 0)
+ {
+ if (header[3] != 0 || header[4] != 0 || header[5] != 0 || header[6] != 0 || header[7] != 0)
+ {
+ return false;
+ }
+ }
+
+ // The height or the width of the image should not be zero.
+ if ((header[12] == 0 && header[13] == 0) || (header[14] == 0 && header[15] == 0))
+ {
+ return false;
+ }
+
+ return true;
}
return false;
diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs
index 2b0b088a1..a305e58b7 100644
--- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs
@@ -1,34 +1,54 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the GNU Affero General Public License, Version 3.
+using System.Collections.Generic;
using System.IO;
using SixLabors.ImageSharp.Formats;
-
+using SixLabors.ImageSharp.Formats.Tga;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Formats.Tga
{
public class TgaFileHeaderTests
{
- private static readonly byte[] Data =
+ [Theory]
+ [InlineData(new byte[] { 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // invalid tga image type.
+ [InlineData(new byte[] { 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // invalid colormap type.
+ [InlineData(new byte[] { 0, 0, 1, 5, 5, 5, 5, 5, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // valid colormap type (0), but colomap spec bytes should all be zero.
+ [InlineData(new byte[] { 0, 0, 1, 0, 0, 0, 0, 8, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // valid colormap type (0), but colomap spec bytes should all be zero.
+ [InlineData(new byte[] { 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // valid colormap type (0), but colomap spec bytes should all be zero.
+ [InlineData(new byte[] { 0, 0, 1, 0, 0, 6, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // valid colormap type (0), but colomap spec bytes should all be zero.
+ [InlineData(new byte[] { 0, 0, 1, 0, 5, 0, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 })] // valid colormap type (0), but colomap spec bytes should all be zero.
+ [InlineData(new byte[] { 0, 0, 0, 12, 106, 80, 32, 32, 13, 10, 135, 10, 0, 0, 0, 20, 102, 116 })] // jp2 image header
+ [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 0, 32, 8 })] // invalid width
+ [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 32, 8 })] // invalid height
+ public void ImageLoad_WithNoValidTgaHeaderBytes_Throws_UnknownImageFormatException(byte[] data)
{
- 0,
- 0,
- 15 // invalid tga image type
- };
-
- private MemoryStream Stream { get; } = new MemoryStream(Data);
+ using var stream = new MemoryStream(data);
- [Fact]
- public void ImageLoad_WithInvalidImageType_Throws_UnknownImageFormatException()
- {
Assert.Throws(() =>
{
- using (Image.Load(Configuration.Default, this.Stream, out IImageFormat _))
+ using (Image.Load(Configuration.Default, stream, out IImageFormat _))
{
}
});
}
+
+ [Theory]
+ [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 }, 250, 195, TgaBitsPerPixel.Pixel32)]
+ [InlineData(new byte[] { 26, 1, 9, 0, 0, 0, 1, 16, 0, 0, 0, 0, 128, 0, 128, 0, 8, 0 }, 128, 128, TgaBitsPerPixel.Pixel8)]
+ [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 220, 0, 16, 0 }, 220, 220, TgaBitsPerPixel.Pixel16)]
+ [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 124, 0, 24, 32 }, 124, 124, TgaBitsPerPixel.Pixel24)]
+ public void Identify_WithValidData_Works(byte[] data, int width, int height, TgaBitsPerPixel bitsPerPixel)
+ {
+ using var stream = new MemoryStream(data);
+
+ IImageInfo info = Image.Identify(stream);
+ TgaMetadata tgaData = info.Metadata.GetTgaMetadata();
+ Assert.Equal(bitsPerPixel, tgaData.BitsPerPixel);
+ Assert.Equal(width, info.Width);
+ Assert.Equal(height, info.Height);
+ }
}
}