Browse Source

Fix webp bpp parsing, normalize property naming.

pull/2751/head
James Jackson-South 2 years ago
parent
commit
0e54081232
  1. 14
      src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs
  2. 24
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  3. 30
      src/ImageSharp/Formats/Bmp/BmpMetadata.cs
  4. 4
      src/ImageSharp/Formats/Jpeg/JpegMetadata.cs
  5. 8
      src/ImageSharp/Formats/Tga/TgaBitsPerPixel.cs
  6. 2
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  7. 22
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  8. 18
      src/ImageSharp/Formats/Tga/TgaMetadata.cs
  9. 4
      src/ImageSharp/Formats/Webp/WebpBitsPerPixel.cs
  10. 37
      src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs
  11. 25
      src/ImageSharp/Formats/Webp/WebpColorType.cs
  12. 21
      src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
  13. 6
      src/ImageSharp/Formats/Webp/WebpImageInfo.cs
  14. 33
      src/ImageSharp/Formats/Webp/WebpMetadata.cs
  15. 90
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  16. 4
      tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs
  17. 32
      tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs
  18. 8
      tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs
  19. 4
      tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

14
src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs

@ -11,35 +11,35 @@ public enum BmpBitsPerPixel : short
/// <summary> /// <summary>
/// 1 bit per pixel. /// 1 bit per pixel.
/// </summary> /// </summary>
Pixel1 = 1, Bit1 = 1,
/// <summary> /// <summary>
/// 2 bits per pixel. /// 2 bits per pixel.
/// </summary> /// </summary>
Pixel2 = 2, Bit2 = 2,
/// <summary> /// <summary>
/// 4 bits per pixel. /// 4 bits per pixel.
/// </summary> /// </summary>
Pixel4 = 4, Bit4 = 4,
/// <summary> /// <summary>
/// 8 bits per pixel. Each pixel consists of 1 byte. /// 8 bits per pixel. Each pixel consists of 1 byte.
/// </summary> /// </summary>
Pixel8 = 8, Bit8 = 8,
/// <summary> /// <summary>
/// 16 bits per pixel. Each pixel consists of 2 bytes. /// 16 bits per pixel. Each pixel consists of 2 bytes.
/// </summary> /// </summary>
Pixel16 = 16, Bit16 = 16,
/// <summary> /// <summary>
/// 24 bits per pixel. Each pixel consists of 3 bytes. /// 24 bits per pixel. Each pixel consists of 3 bytes.
/// </summary> /// </summary>
Pixel24 = 24, Bit24 = 24,
/// <summary> /// <summary>
/// 32 bits per pixel. Each pixel consists of 4 bytes. /// 32 bits per pixel. Each pixel consists of 4 bytes.
/// </summary> /// </summary>
Pixel32 = 32 Bit32 = 32
} }

24
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -130,10 +130,10 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
int colorPaletteSize = this.bitsPerPixel switch int colorPaletteSize = this.bitsPerPixel switch
{ {
BmpBitsPerPixel.Pixel8 => ColorPaletteSize8Bit, BmpBitsPerPixel.Bit8 => ColorPaletteSize8Bit,
BmpBitsPerPixel.Pixel4 => ColorPaletteSize4Bit, BmpBitsPerPixel.Bit4 => ColorPaletteSize4Bit,
BmpBitsPerPixel.Pixel2 => ColorPaletteSize2Bit, BmpBitsPerPixel.Bit2 => ColorPaletteSize2Bit,
BmpBitsPerPixel.Pixel1 => ColorPaletteSize1Bit, BmpBitsPerPixel.Bit1 => ColorPaletteSize1Bit,
_ => 0 _ => 0
}; };
@ -220,7 +220,7 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
clrUsed: 0, clrUsed: 0,
clrImportant: 0); clrImportant: 0);
if ((this.infoHeaderType is BmpInfoHeaderType.WinVersion4 or BmpInfoHeaderType.WinVersion5) && this.bitsPerPixel == BmpBitsPerPixel.Pixel32) if ((this.infoHeaderType is BmpInfoHeaderType.WinVersion4 or BmpInfoHeaderType.WinVersion5) && this.bitsPerPixel == BmpBitsPerPixel.Bit32)
{ {
infoHeader.AlphaMask = Rgba32AlphaMask; infoHeader.AlphaMask = Rgba32AlphaMask;
infoHeader.RedMask = Rgba32RedMask; infoHeader.RedMask = Rgba32RedMask;
@ -319,31 +319,31 @@ internal sealed class BmpEncoderCore : IImageEncoderInternals
Buffer2D<TPixel> pixels = image.Frames.RootFrame.PixelBuffer; Buffer2D<TPixel> pixels = image.Frames.RootFrame.PixelBuffer;
switch (this.bitsPerPixel) switch (this.bitsPerPixel)
{ {
case BmpBitsPerPixel.Pixel32: case BmpBitsPerPixel.Bit32:
this.Write32BitPixelData(configuration, stream, pixels); this.Write32BitPixelData(configuration, stream, pixels);
break; break;
case BmpBitsPerPixel.Pixel24: case BmpBitsPerPixel.Bit24:
this.Write24BitPixelData(configuration, stream, pixels); this.Write24BitPixelData(configuration, stream, pixels);
break; break;
case BmpBitsPerPixel.Pixel16: case BmpBitsPerPixel.Bit16:
this.Write16BitPixelData(configuration, stream, pixels); this.Write16BitPixelData(configuration, stream, pixels);
break; break;
case BmpBitsPerPixel.Pixel8: case BmpBitsPerPixel.Bit8:
this.Write8BitPixelData(configuration, stream, image); this.Write8BitPixelData(configuration, stream, image);
break; break;
case BmpBitsPerPixel.Pixel4: case BmpBitsPerPixel.Bit4:
this.Write4BitPixelData(configuration, stream, image); this.Write4BitPixelData(configuration, stream, image);
break; break;
case BmpBitsPerPixel.Pixel2: case BmpBitsPerPixel.Bit2:
this.Write2BitPixelData(configuration, stream, image); this.Write2BitPixelData(configuration, stream, image);
break; break;
case BmpBitsPerPixel.Pixel1: case BmpBitsPerPixel.Bit1:
this.Write1BitPixelData(configuration, stream, image); this.Write1BitPixelData(configuration, stream, image);
break; break;
} }

30
src/ImageSharp/Formats/Bmp/BmpMetadata.cs

@ -36,7 +36,7 @@ public class BmpMetadata : IFormatMetadata<BmpMetadata>, IFormatFrameMetadata<Bm
/// <summary> /// <summary>
/// Gets or sets the number of bits per pixel. /// Gets or sets the number of bits per pixel.
/// </summary> /// </summary>
public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24; public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Bit24;
/// <inheritdoc/> /// <inheritdoc/>
public static BmpMetadata FromFormatConnectingMetadata(FormatConnectingMetadata metadata) public static BmpMetadata FromFormatConnectingMetadata(FormatConnectingMetadata metadata)
@ -44,23 +44,23 @@ public class BmpMetadata : IFormatMetadata<BmpMetadata>, IFormatFrameMetadata<Bm
int bpp = metadata.PixelTypeInfo.BitsPerPixel; int bpp = metadata.PixelTypeInfo.BitsPerPixel;
return bpp switch return bpp switch
{ {
1 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Pixel1 }, 1 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Bit1 },
2 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Pixel2 }, 2 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Bit2 },
<= 4 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Pixel4 }, <= 4 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Bit4 },
<= 8 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Pixel8 }, <= 8 => new BmpMetadata { BitsPerPixel = BmpBitsPerPixel.Bit8 },
<= 16 => new BmpMetadata <= 16 => new BmpMetadata
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel16, BitsPerPixel = BmpBitsPerPixel.Bit16,
InfoHeaderType = BmpInfoHeaderType.WinVersion3 InfoHeaderType = BmpInfoHeaderType.WinVersion3
}, },
<= 24 => new BmpMetadata <= 24 => new BmpMetadata
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel24, BitsPerPixel = BmpBitsPerPixel.Bit24,
InfoHeaderType = BmpInfoHeaderType.WinVersion4 InfoHeaderType = BmpInfoHeaderType.WinVersion4
}, },
_ => new BmpMetadata _ => new BmpMetadata
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel32, BitsPerPixel = BmpBitsPerPixel.Bit32,
InfoHeaderType = BmpInfoHeaderType.WinVersion5 InfoHeaderType = BmpInfoHeaderType.WinVersion5
} }
}; };
@ -92,34 +92,34 @@ public class BmpMetadata : IFormatMetadata<BmpMetadata>, IFormatFrameMetadata<Bm
PixelColorType color; PixelColorType color;
switch (this.BitsPerPixel) switch (this.BitsPerPixel)
{ {
case BmpBitsPerPixel.Pixel1: case BmpBitsPerPixel.Bit1:
info = PixelComponentInfo.Create(1, bpp, 1); info = PixelComponentInfo.Create(1, bpp, 1);
color = PixelColorType.Indexed; color = PixelColorType.Indexed;
break; break;
case BmpBitsPerPixel.Pixel2: case BmpBitsPerPixel.Bit2:
info = PixelComponentInfo.Create(1, bpp, 2); info = PixelComponentInfo.Create(1, bpp, 2);
color = PixelColorType.Indexed; color = PixelColorType.Indexed;
break; break;
case BmpBitsPerPixel.Pixel4: case BmpBitsPerPixel.Bit4:
info = PixelComponentInfo.Create(1, bpp, 4); info = PixelComponentInfo.Create(1, bpp, 4);
color = PixelColorType.Indexed; color = PixelColorType.Indexed;
break; break;
case BmpBitsPerPixel.Pixel8: case BmpBitsPerPixel.Bit8:
info = PixelComponentInfo.Create(1, bpp, 8); info = PixelComponentInfo.Create(1, bpp, 8);
color = PixelColorType.Indexed; color = PixelColorType.Indexed;
break; break;
// Could be 555 with padding but 565 is more common in newer bitmaps and offers // Could be 555 with padding but 565 is more common in newer bitmaps and offers
// greater accuracy due to extra green precision. // greater accuracy due to extra green precision.
case BmpBitsPerPixel.Pixel16: case BmpBitsPerPixel.Bit16:
info = PixelComponentInfo.Create(3, bpp, 5, 6, 5); info = PixelComponentInfo.Create(3, bpp, 5, 6, 5);
color = PixelColorType.RGB; color = PixelColorType.RGB;
break; break;
case BmpBitsPerPixel.Pixel24: case BmpBitsPerPixel.Bit24:
info = PixelComponentInfo.Create(3, bpp, 8, 8, 8); info = PixelComponentInfo.Create(3, bpp, 8, 8, 8);
color = PixelColorType.RGB; color = PixelColorType.RGB;
break; break;
case BmpBitsPerPixel.Pixel32 or _: case BmpBitsPerPixel.Bit32 or _:
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8);
color = PixelColorType.RGB | PixelColorType.Alpha; color = PixelColorType.RGB | PixelColorType.Alpha;
break; break;

4
src/ImageSharp/Formats/Jpeg/JpegMetadata.cs

@ -14,7 +14,9 @@ public class JpegMetadata : IFormatMetadata<JpegMetadata>
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JpegMetadata"/> class. /// Initializes a new instance of the <see cref="JpegMetadata"/> class.
/// </summary> /// </summary>
public JpegMetadata() => this.Comments = []; public JpegMetadata()
{
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="JpegMetadata"/> class. /// Initializes a new instance of the <see cref="JpegMetadata"/> class.

8
src/ImageSharp/Formats/Tga/TgaBitsPerPixel.cs

@ -11,20 +11,20 @@ public enum TgaBitsPerPixel : byte
/// <summary> /// <summary>
/// 8 bits per pixel. Each pixel consists of 1 byte. /// 8 bits per pixel. Each pixel consists of 1 byte.
/// </summary> /// </summary>
Pixel8 = 8, Bit8 = 8,
/// <summary> /// <summary>
/// 16 bits per pixel. Each pixel consists of 2 bytes. /// 16 bits per pixel. Each pixel consists of 2 bytes.
/// </summary> /// </summary>
Pixel16 = 16, Bit16 = 16,
/// <summary> /// <summary>
/// 24 bits per pixel. Each pixel consists of 3 bytes. /// 24 bits per pixel. Each pixel consists of 3 bytes.
/// </summary> /// </summary>
Pixel24 = 24, Bit24 = 24,
/// <summary> /// <summary>
/// 32 bits per pixel. Each pixel consists of 4 bytes. /// 32 bits per pixel. Each pixel consists of 4 bytes.
/// </summary> /// </summary>
Pixel32 = 32 Bit32 = 32
} }

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

@ -934,7 +934,7 @@ internal sealed class TgaDecoderCore : IImageDecoderInternals
return (TgaImageOrigin)((this.fileHeader.ImageDescriptor & 0x30) >> 4); return (TgaImageOrigin)((this.fileHeader.ImageDescriptor & 0x30) >> 4);
} }
private bool IsTrueColor32BitPerPixel(TgaBitsPerPixel bitsPerPixel) => bitsPerPixel == TgaBitsPerPixel.Pixel32 && private bool IsTrueColor32BitPerPixel(TgaBitsPerPixel bitsPerPixel) => bitsPerPixel == TgaBitsPerPixel.Bit32 &&
(this.fileHeader.ImageType == TgaImageType.TrueColor || (this.fileHeader.ImageType == TgaImageType.TrueColor ||
this.fileHeader.ImageType == TgaImageType.RleTrueColor); this.fileHeader.ImageType == TgaImageType.RleTrueColor);
} }

22
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -59,7 +59,7 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
this.bitsPerPixel ??= tgaMetadata.BitsPerPixel; this.bitsPerPixel ??= tgaMetadata.BitsPerPixel;
TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor; TgaImageType imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleTrueColor : TgaImageType.TrueColor;
if (this.bitsPerPixel == TgaBitsPerPixel.Pixel8) if (this.bitsPerPixel == TgaBitsPerPixel.Bit8)
{ {
imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite; imageType = this.compression is TgaCompression.RunLength ? TgaImageType.RleBlackAndWhite : TgaImageType.BlackAndWhite;
} }
@ -71,13 +71,13 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
imageDescriptor |= 0x20; imageDescriptor |= 0x20;
} }
if (this.bitsPerPixel is TgaBitsPerPixel.Pixel32) if (this.bitsPerPixel is TgaBitsPerPixel.Bit32)
{ {
// Indicate, that 8 bit are used for the alpha channel. // Indicate, that 8 bit are used for the alpha channel.
imageDescriptor |= 0x8; imageDescriptor |= 0x8;
} }
if (this.bitsPerPixel is TgaBitsPerPixel.Pixel16) if (this.bitsPerPixel is TgaBitsPerPixel.Bit16)
{ {
// Indicate, that 1 bit is used for the alpha channel. // Indicate, that 1 bit is used for the alpha channel.
imageDescriptor |= 0x1; imageDescriptor |= 0x1;
@ -130,19 +130,19 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
Buffer2D<TPixel> pixels = image.PixelBuffer; Buffer2D<TPixel> pixels = image.PixelBuffer;
switch (this.bitsPerPixel) switch (this.bitsPerPixel)
{ {
case TgaBitsPerPixel.Pixel8: case TgaBitsPerPixel.Bit8:
this.Write8Bit(configuration, stream, pixels); this.Write8Bit(configuration, stream, pixels);
break; break;
case TgaBitsPerPixel.Pixel16: case TgaBitsPerPixel.Bit16:
this.Write16Bit(configuration, stream, pixels); this.Write16Bit(configuration, stream, pixels);
break; break;
case TgaBitsPerPixel.Pixel24: case TgaBitsPerPixel.Bit24:
this.Write24Bit(configuration, stream, pixels); this.Write24Bit(configuration, stream, pixels);
break; break;
case TgaBitsPerPixel.Pixel32: case TgaBitsPerPixel.Bit32:
this.Write32Bit(configuration, stream, pixels); this.Write32Bit(configuration, stream, pixels);
break; break;
} }
@ -208,12 +208,12 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
{ {
switch (this.bitsPerPixel) switch (this.bitsPerPixel)
{ {
case TgaBitsPerPixel.Pixel8: case TgaBitsPerPixel.Bit8:
L8 l8 = L8.FromRgba32(color); L8 l8 = L8.FromRgba32(color);
stream.WriteByte(l8.PackedValue); stream.WriteByte(l8.PackedValue);
break; break;
case TgaBitsPerPixel.Pixel16: case TgaBitsPerPixel.Bit16:
Bgra5551 bgra5551 = Bgra5551.FromRgba32(color); Bgra5551 bgra5551 = Bgra5551.FromRgba32(color);
Span<byte> buffer = stackalloc byte[2]; Span<byte> buffer = stackalloc byte[2];
BinaryPrimitives.WriteInt16LittleEndian(buffer, (short)bgra5551.PackedValue); BinaryPrimitives.WriteInt16LittleEndian(buffer, (short)bgra5551.PackedValue);
@ -222,13 +222,13 @@ internal sealed class TgaEncoderCore : IImageEncoderInternals
break; break;
case TgaBitsPerPixel.Pixel24: case TgaBitsPerPixel.Bit24:
stream.WriteByte(color.B); stream.WriteByte(color.B);
stream.WriteByte(color.G); stream.WriteByte(color.G);
stream.WriteByte(color.R); stream.WriteByte(color.R);
break; break;
case TgaBitsPerPixel.Pixel32: case TgaBitsPerPixel.Bit32:
stream.WriteByte(color.B); stream.WriteByte(color.B);
stream.WriteByte(color.G); stream.WriteByte(color.G);
stream.WriteByte(color.R); stream.WriteByte(color.R);

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

@ -27,7 +27,7 @@ public class TgaMetadata : IFormatMetadata<TgaMetadata>
/// <summary> /// <summary>
/// Gets or sets the number of bits per pixel. /// Gets or sets the number of bits per pixel.
/// </summary> /// </summary>
public TgaBitsPerPixel BitsPerPixel { get; set; } = TgaBitsPerPixel.Pixel24; public TgaBitsPerPixel BitsPerPixel { get; set; } = TgaBitsPerPixel.Bit24;
/// <summary> /// <summary>
/// Gets or sets the number of alpha bits per pixel. /// Gets or sets the number of alpha bits per pixel.
@ -41,10 +41,10 @@ public class TgaMetadata : IFormatMetadata<TgaMetadata>
int bpp = metadata.PixelTypeInfo.BitsPerPixel; int bpp = metadata.PixelTypeInfo.BitsPerPixel;
return bpp switch return bpp switch
{ {
<= 8 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Pixel8 }, <= 8 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Bit8 },
<= 16 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Pixel16 }, <= 16 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Bit16 },
<= 24 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Pixel24 }, <= 24 => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Bit24 },
_ => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Pixel32 } _ => new TgaMetadata { BitsPerPixel = TgaBitsPerPixel.Bit32 }
}; };
} }
@ -57,22 +57,22 @@ public class TgaMetadata : IFormatMetadata<TgaMetadata>
PixelAlphaRepresentation alpha; PixelAlphaRepresentation alpha;
switch (this.BitsPerPixel) switch (this.BitsPerPixel)
{ {
case TgaBitsPerPixel.Pixel8: case TgaBitsPerPixel.Bit8:
info = PixelComponentInfo.Create(1, bpp, 8); info = PixelComponentInfo.Create(1, bpp, 8);
color = PixelColorType.Luminance; color = PixelColorType.Luminance;
alpha = PixelAlphaRepresentation.None; alpha = PixelAlphaRepresentation.None;
break; break;
case TgaBitsPerPixel.Pixel16: case TgaBitsPerPixel.Bit16:
info = PixelComponentInfo.Create(1, bpp, 5, 5, 5, 1); info = PixelComponentInfo.Create(1, bpp, 5, 5, 5, 1);
color = PixelColorType.BGR | PixelColorType.Alpha; color = PixelColorType.BGR | PixelColorType.Alpha;
alpha = PixelAlphaRepresentation.Unassociated; alpha = PixelAlphaRepresentation.Unassociated;
break; break;
case TgaBitsPerPixel.Pixel24: case TgaBitsPerPixel.Bit24:
info = PixelComponentInfo.Create(3, bpp, 8, 8, 8); info = PixelComponentInfo.Create(3, bpp, 8, 8, 8);
color = PixelColorType.RGB; color = PixelColorType.RGB;
alpha = PixelAlphaRepresentation.None; alpha = PixelAlphaRepresentation.None;
break; break;
case TgaBitsPerPixel.Pixel32 or _: case TgaBitsPerPixel.Bit32 or _:
info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8); info = PixelComponentInfo.Create(4, bpp, 8, 8, 8, 8);
color = PixelColorType.RGB | PixelColorType.Alpha; color = PixelColorType.RGB | PixelColorType.Alpha;
alpha = PixelAlphaRepresentation.Unassociated; alpha = PixelAlphaRepresentation.Unassociated;

4
src/ImageSharp/Formats/Webp/WebpBitsPerPixel.cs

@ -11,10 +11,10 @@ public enum WebpBitsPerPixel : short
/// <summary> /// <summary>
/// 24 bits per pixel. Each pixel consists of 3 bytes. /// 24 bits per pixel. Each pixel consists of 3 bytes.
/// </summary> /// </summary>
Pixel24 = 24, Bit24 = 24,
/// <summary> /// <summary>
/// 32 bits per pixel. Each pixel consists of 4 bytes (an alpha channel is present). /// 32 bits per pixel. Each pixel consists of 4 bytes (an alpha channel is present).
/// </summary> /// </summary>
Pixel32 = 32 Bit32 = 32
} }

37
src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs

@ -17,6 +17,10 @@ internal static class WebpChunkParsingUtils
/// <summary> /// <summary>
/// Reads the header of a lossy webp image. /// Reads the header of a lossy webp image.
/// </summary> /// </summary>
/// <param name="memoryAllocator">The memory allocator.</param>
/// <param name="stream">The buffered read stream.</param>
/// <param name="buffer">The scratch buffer to use while reading.</param>
/// <param name="features">The webp features to parse.</param>
/// <returns>Information about this webp image.</returns> /// <returns>Information about this webp image.</returns>
public static WebpImageInfo ReadVp8Header(MemoryAllocator memoryAllocator, BufferedReadStream stream, Span<byte> buffer, WebpFeatures features) public static WebpImageInfo ReadVp8Header(MemoryAllocator memoryAllocator, BufferedReadStream stream, Span<byte> buffer, WebpFeatures features)
{ {
@ -114,13 +118,15 @@ internal static class WebpChunkParsingUtils
Vp8BitReader bitReader = new(stream, remaining, memoryAllocator, partitionLength) { Remaining = remaining }; Vp8BitReader bitReader = new(stream, remaining, memoryAllocator, partitionLength) { Remaining = remaining };
return new WebpImageInfo return new()
{ {
Width = width, Width = width,
Height = height, Height = height,
XScale = xScale, XScale = xScale,
YScale = yScale, YScale = yScale,
BitsPerPixel = features?.Alpha == true ? WebpBitsPerPixel.Pixel32 : WebpBitsPerPixel.Pixel24,
// Vp8 header can be parsed during the processing of the Vp8X header.
BitsPerPixel = features?.Alpha == true ? WebpBitsPerPixel.Bit32 : WebpBitsPerPixel.Bit24,
IsLossless = false, IsLossless = false,
Features = features, Features = features,
Vp8Profile = (sbyte)version, Vp8Profile = (sbyte)version,
@ -132,7 +138,10 @@ internal static class WebpChunkParsingUtils
/// <summary> /// <summary>
/// Reads the header of a lossless webp image. /// Reads the header of a lossless webp image.
/// </summary> /// </summary>
/// <returns>Information about this image.</returns> /// <param name="memoryAllocator">The memory allocator.</param>
/// <param name="stream">The buffered read stream.</param>
/// <param name="buffer">The scratch buffer to use while reading.</param>
/// <param name="features">The webp features to parse.</param>
public static WebpImageInfo ReadVp8LHeader(MemoryAllocator memoryAllocator, BufferedReadStream stream, Span<byte> buffer, WebpFeatures features) public static WebpImageInfo ReadVp8LHeader(MemoryAllocator memoryAllocator, BufferedReadStream stream, Span<byte> buffer, WebpFeatures features)
{ {
// VP8 data size. // VP8 data size.
@ -156,8 +165,8 @@ internal static class WebpChunkParsingUtils
} }
// The alphaIsUsed flag should be set to 0 when all alpha values are 255 in the picture, and 1 otherwise. // The alphaIsUsed flag should be set to 0 when all alpha values are 255 in the picture, and 1 otherwise.
// TODO: this flag value is not used yet // Alpha may have already been set by the VP8X chunk.
bool alphaIsUsed = bitReader.ReadBit(); features.Alpha |= bitReader.ReadBit();
// The next 3 bits are the version. The version number is a 3 bit code that must be set to 0. // The next 3 bits are the version. The version number is a 3 bit code that must be set to 0.
// Any other value should be treated as an error. // Any other value should be treated as an error.
@ -167,11 +176,11 @@ internal static class WebpChunkParsingUtils
WebpThrowHelper.ThrowNotSupportedException($"Unexpected version number {version} found in VP8L header"); WebpThrowHelper.ThrowNotSupportedException($"Unexpected version number {version} found in VP8L header");
} }
return new WebpImageInfo return new()
{ {
Width = width, Width = width,
Height = height, Height = height,
BitsPerPixel = WebpBitsPerPixel.Pixel32, BitsPerPixel = features.Alpha ? WebpBitsPerPixel.Bit32 : WebpBitsPerPixel.Bit24,
IsLossless = true, IsLossless = true,
Features = features, Features = features,
Vp8LBitReader = bitReader Vp8LBitReader = bitReader
@ -187,6 +196,9 @@ internal static class WebpChunkParsingUtils
/// - An optional 'ALPH' chunk with alpha channel data. /// - An optional 'ALPH' chunk with alpha channel data.
/// After the image header, image data will follow. After that optional image metadata chunks (EXIF and XMP) can follow. /// After the image header, image data will follow. After that optional image metadata chunks (EXIF and XMP) can follow.
/// </summary> /// </summary>
/// <param name="stream">The buffered read stream.</param>
/// <param name="buffer">The scratch buffer to use while reading.</param>
/// <param name="features">The webp features to parse.</param>
/// <returns>Information about this webp image.</returns> /// <returns>Information about this webp image.</returns>
public static WebpImageInfo ReadVp8XHeader(BufferedReadStream stream, Span<byte> buffer, WebpFeatures features) public static WebpImageInfo ReadVp8XHeader(BufferedReadStream stream, Span<byte> buffer, WebpFeatures features)
{ {
@ -217,11 +229,8 @@ internal static class WebpChunkParsingUtils
features.Animation = (imageFeatures & (1 << 1)) != 0; features.Animation = (imageFeatures & (1 << 1)) != 0;
// 3 reserved bytes should follow which are supposed to be zero. // 3 reserved bytes should follow which are supposed to be zero.
// No other decoder actually checks this though.
stream.Read(buffer, 0, 3); stream.Read(buffer, 0, 3);
if (buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 0)
{
WebpThrowHelper.ThrowImageFormatException("reserved bytes should be zero");
}
// 3 bytes for the width. // 3 bytes for the width.
uint width = ReadUInt24LittleEndian(stream, buffer) + 1; uint width = ReadUInt24LittleEndian(stream, buffer) + 1;
@ -230,14 +239,14 @@ internal static class WebpChunkParsingUtils
uint height = ReadUInt24LittleEndian(stream, buffer) + 1; uint height = ReadUInt24LittleEndian(stream, buffer) + 1;
// Read all the chunks in the order they occur. // Read all the chunks in the order they occur.
WebpImageInfo info = new() return new()
{ {
Width = width, Width = width,
Height = height, Height = height,
Features = features Features = features
};
return info; // Additional properties are set during the parsing of the VP8 or VP8L headers.
};
} }
/// <summary> /// <summary>

25
src/ImageSharp/Formats/Webp/WebpColorType.cs

@ -0,0 +1,25 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
namespace SixLabors.ImageSharp.Formats.Webp;
/// <summary>
/// Provides enumeration of the various webp color types.
/// </summary>
public enum WebpColorType
{
/// <summary>
/// Yuv (luminance, blue chroma, red chroma) as defined in the ITU-R Rec. BT.709 specification.
/// </summary>
Yuv,
/// <summary>
/// Rgb color space.
/// </summary>
Rgb,
/// <summary>
/// Rgba color space.
/// </summary>
Rgba
}

21
src/ImageSharp/Formats/Webp/WebpDecoderCore.cs

@ -186,36 +186,43 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
Span<byte> buffer = stackalloc byte[4]; Span<byte> buffer = stackalloc byte[4];
WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(stream, buffer); WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(stream, buffer);
WebpImageInfo? info = null;
WebpFeatures features = new(); WebpFeatures features = new();
switch (chunkType) switch (chunkType)
{ {
case WebpChunkType.Vp8: case WebpChunkType.Vp8:
info = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, buffer, features);
webpMetadata.FileFormat = WebpFileFormatType.Lossy; webpMetadata.FileFormat = WebpFileFormatType.Lossy;
return WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, buffer, features); webpMetadata.ColorType = WebpColorType.Yuv;
return info;
case WebpChunkType.Vp8L: case WebpChunkType.Vp8L:
info = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, buffer, features);
webpMetadata.FileFormat = WebpFileFormatType.Lossless; webpMetadata.FileFormat = WebpFileFormatType.Lossless;
return WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, buffer, features); webpMetadata.ColorType = info.Features?.Alpha == true ? WebpColorType.Rgba : WebpColorType.Rgb;
return info;
case WebpChunkType.Vp8X: case WebpChunkType.Vp8X:
WebpImageInfo webpInfos = WebpChunkParsingUtils.ReadVp8XHeader(stream, buffer, features); info = WebpChunkParsingUtils.ReadVp8XHeader(stream, buffer, features);
while (stream.Position < stream.Length) while (stream.Position < stream.Length)
{ {
chunkType = WebpChunkParsingUtils.ReadChunkType(stream, buffer); chunkType = WebpChunkParsingUtils.ReadChunkType(stream, buffer);
if (chunkType == WebpChunkType.Vp8) if (chunkType == WebpChunkType.Vp8)
{ {
info = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, buffer, features);
webpMetadata.FileFormat = WebpFileFormatType.Lossy; webpMetadata.FileFormat = WebpFileFormatType.Lossy;
webpInfos = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, buffer, features); webpMetadata.ColorType = info.Features?.Alpha == true ? WebpColorType.Rgba : WebpColorType.Rgb;
} }
else if (chunkType == WebpChunkType.Vp8L) else if (chunkType == WebpChunkType.Vp8L)
{ {
info = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, buffer, features);
webpMetadata.FileFormat = WebpFileFormatType.Lossless; webpMetadata.FileFormat = WebpFileFormatType.Lossless;
webpInfos = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, buffer, features); webpMetadata.ColorType = info.Features?.Alpha == true ? WebpColorType.Rgba : WebpColorType.Rgb;
} }
else if (WebpChunkParsingUtils.IsOptionalVp8XChunk(chunkType)) else if (WebpChunkParsingUtils.IsOptionalVp8XChunk(chunkType))
{ {
bool isAnimationChunk = this.ParseOptionalExtendedChunks(stream, metadata, chunkType, features, ignoreAlpha, buffer); bool isAnimationChunk = this.ParseOptionalExtendedChunks(stream, metadata, chunkType, features, ignoreAlpha, buffer);
if (isAnimationChunk) if (isAnimationChunk)
{ {
return webpInfos; return info;
} }
} }
else else
@ -226,7 +233,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
} }
} }
return webpInfos; return info;
default: default:
WebpThrowHelper.ThrowImageFormatException("Unrecognized VP8 header"); WebpThrowHelper.ThrowImageFormatException("Unrecognized VP8 header");
return return

6
src/ImageSharp/Formats/Webp/WebpImageInfo.cs

@ -18,8 +18,14 @@ internal class WebpImageInfo : IDisposable
/// </summary> /// </summary>
public uint Height { get; set; } public uint Height { get; set; }
/// <summary>
/// Gets or sets the horizontal scale.
/// </summary>
public sbyte XScale { get; set; } public sbyte XScale { get; set; }
/// <summary>
/// Gets or sets the vertical scale.
/// </summary>
public sbyte YScale { get; set; } public sbyte YScale { get; set; }
/// <summary> /// <summary>

33
src/ImageSharp/Formats/Webp/WebpMetadata.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Webp;
/// <summary> /// <summary>
/// Provides Webp specific metadata information for the image. /// Provides Webp specific metadata information for the image.
/// </summary> /// </summary>
public class WebpMetadata : IDeepCloneable public class WebpMetadata : IFormatFrameMetadata<WebpMetadata>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="WebpMetadata"/> class. /// Initializes a new instance of the <see cref="WebpMetadata"/> class.
@ -21,15 +21,27 @@ public class WebpMetadata : IDeepCloneable
/// <param name="other">The metadata to create an instance from.</param> /// <param name="other">The metadata to create an instance from.</param>
private WebpMetadata(WebpMetadata other) private WebpMetadata(WebpMetadata other)
{ {
this.BitsPerPixel = other.BitsPerPixel;
this.ColorType = other.ColorType;
this.FileFormat = other.FileFormat; this.FileFormat = other.FileFormat;
this.RepeatCount = other.RepeatCount; this.RepeatCount = other.RepeatCount;
this.BackgroundColor = other.BackgroundColor; this.BackgroundColor = other.BackgroundColor;
} }
/// <summary>
/// Gets or sets the number of bits per pixel.
/// </summary>
public WebpBitsPerPixel BitsPerPixel { get; set; } = WebpBitsPerPixel.Bit32;
/// <summary>
/// Gets or sets the color type.
/// </summary>
public WebpColorType ColorType { get; set; } = WebpColorType.Rgba;
/// <summary> /// <summary>
/// Gets or sets the webp file format used. Either lossless or lossy. /// Gets or sets the webp file format used. Either lossless or lossy.
/// </summary> /// </summary>
public WebpFileFormatType? FileFormat { get; set; } public WebpFileFormatType FileFormat { get; set; } = WebpFileFormatType.Lossless;
/// <summary> /// <summary>
/// Gets or sets the loop count. The number of times to loop the animation. 0 means infinitely. /// Gets or sets the loop count. The number of times to loop the animation. 0 means infinitely.
@ -44,9 +56,6 @@ public class WebpMetadata : IDeepCloneable
/// </summary> /// </summary>
public Color BackgroundColor { get; set; } public Color BackgroundColor { get; set; }
/// <inheritdoc/>
public IDeepCloneable DeepClone() => new WebpMetadata(this);
internal static WebpMetadata FromAnimatedMetadata(AnimatedImageMetadata metadata) internal static WebpMetadata FromAnimatedMetadata(AnimatedImageMetadata metadata)
=> new() => new()
{ {
@ -54,4 +63,18 @@ public class WebpMetadata : IDeepCloneable
BackgroundColor = metadata.BackgroundColor, BackgroundColor = metadata.BackgroundColor,
RepeatCount = metadata.RepeatCount RepeatCount = metadata.RepeatCount
}; };
/// <inheritdoc/>
public static WebpMetadata FromFormatConnectingFrameMetadata(FormatConnectingFrameMetadata metadata)
=> throw new NotImplementedException();
/// <inheritdoc/>
public FormatConnectingFrameMetadata ToFormatConnectingFrameMetadata()
=> throw new NotImplementedException();
/// <inheritdoc/>
IDeepCloneable IDeepCloneable.DeepClone() => this.DeepClone();
/// <inheritdoc/>
public WebpMetadata DeepClone() => new(this);
} }

90
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -22,8 +22,8 @@ public class BmpEncoderTests
public static readonly TheoryData<BmpBitsPerPixel> BitsPerPixel = public static readonly TheoryData<BmpBitsPerPixel> BitsPerPixel =
new() new()
{ {
BmpBitsPerPixel.Pixel24, BmpBitsPerPixel.Bit24,
BmpBitsPerPixel.Pixel32 BmpBitsPerPixel.Bit32
}; };
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles = public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
@ -37,13 +37,13 @@ public class BmpEncoderTests
public static readonly TheoryData<string, BmpBitsPerPixel> BmpBitsPerPixelFiles = public static readonly TheoryData<string, BmpBitsPerPixel> BmpBitsPerPixelFiles =
new() new()
{ {
{ Bit1, BmpBitsPerPixel.Pixel1 }, { Bit1, BmpBitsPerPixel.Bit1 },
{ Bit2, BmpBitsPerPixel.Pixel2 }, { Bit2, BmpBitsPerPixel.Bit2 },
{ Bit4, BmpBitsPerPixel.Pixel4 }, { Bit4, BmpBitsPerPixel.Bit4 },
{ Bit8, BmpBitsPerPixel.Pixel8 }, { Bit8, BmpBitsPerPixel.Bit8 },
{ Rgb16, BmpBitsPerPixel.Pixel16 }, { Rgb16, BmpBitsPerPixel.Bit16 },
{ Car, BmpBitsPerPixel.Pixel24 }, { Car, BmpBitsPerPixel.Bit24 },
{ Bit32Rgb, BmpBitsPerPixel.Pixel32 } { Bit32Rgb, BmpBitsPerPixel.Bit32 }
}; };
[Fact] [Fact]
@ -97,61 +97,61 @@ public class BmpEncoderTests
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel);
[Theory] [Theory]
[WithFile(Bit32Rgb, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(Bit32Rgb, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(Bit32Rgba, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(Bit32Rgba, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(WinBmpv4, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(WinBmpv4, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(WinBmpv5, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(WinBmpv5, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
public void Encode_32Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_32Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
// If supportTransparency is false, a v3 bitmap header will be written. // If supportTransparency is false, a v3 bitmap header will be written.
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false);
[Theory] [Theory]
[WithFile(Bit32Rgb, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(Bit32Rgb, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(Bit32Rgba, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(Bit32Rgba, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(WinBmpv4, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(WinBmpv4, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
[WithFile(WinBmpv5, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Pixel32)] [WithFile(WinBmpv5, PixelTypes.Rgba32 | PixelTypes.Rgb24, BmpBitsPerPixel.Bit32)]
public void Encode_32Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_32Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
[Theory] [Theory]
[WithFile(WinBmpv3, PixelTypes.Rgb24, BmpBitsPerPixel.Pixel24)] // WinBmpv3 is a 24 bits per pixel image. [WithFile(WinBmpv3, PixelTypes.Rgb24, BmpBitsPerPixel.Bit24)] // WinBmpv3 is a 24 bits per pixel image.
[WithFile(F, PixelTypes.Rgb24, BmpBitsPerPixel.Pixel24)] [WithFile(F, PixelTypes.Rgb24, BmpBitsPerPixel.Bit24)]
public void Encode_24Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_24Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false);
[Theory] [Theory]
[WithFile(WinBmpv3, PixelTypes.Rgb24, BmpBitsPerPixel.Pixel24)] [WithFile(WinBmpv3, PixelTypes.Rgb24, BmpBitsPerPixel.Bit24)]
[WithFile(F, PixelTypes.Rgb24, BmpBitsPerPixel.Pixel24)] [WithFile(F, PixelTypes.Rgb24, BmpBitsPerPixel.Bit24)]
public void Encode_24Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_24Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
[Theory] [Theory]
[WithFile(Rgb16, PixelTypes.Bgra5551, BmpBitsPerPixel.Pixel16)] [WithFile(Rgb16, PixelTypes.Bgra5551, BmpBitsPerPixel.Bit16)]
[WithFile(Bit16, PixelTypes.Bgra5551, BmpBitsPerPixel.Pixel16)] [WithFile(Bit16, PixelTypes.Bgra5551, BmpBitsPerPixel.Bit16)]
public void Encode_16Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_16Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false);
[Theory] [Theory]
[WithFile(Rgb16, PixelTypes.Bgra5551, BmpBitsPerPixel.Pixel16)] [WithFile(Rgb16, PixelTypes.Bgra5551, BmpBitsPerPixel.Bit16)]
[WithFile(Bit16, PixelTypes.Bgra5551, BmpBitsPerPixel.Pixel16)] [WithFile(Bit16, PixelTypes.Bgra5551, BmpBitsPerPixel.Bit16)]
public void Encode_16Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_16Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
[Theory] [Theory]
[WithFile(WinBmpv5, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel8)] [WithFile(WinBmpv5, PixelTypes.Rgba32, BmpBitsPerPixel.Bit8)]
[WithFile(Bit8Palette4, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel8)] [WithFile(Bit8Palette4, PixelTypes.Rgba32, BmpBitsPerPixel.Bit8)]
public void Encode_8Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_8Bit_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false);
[Theory] [Theory]
[WithFile(WinBmpv5, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel8)] [WithFile(WinBmpv5, PixelTypes.Rgba32, BmpBitsPerPixel.Bit8)]
[WithFile(Bit8Palette4, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel8)] [WithFile(Bit8Palette4, PixelTypes.Rgba32, BmpBitsPerPixel.Bit8)]
public void Encode_8Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_8Bit_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
[Theory] [Theory]
[WithFile(Bit8Gs, PixelTypes.L8, BmpBitsPerPixel.Pixel8)] [WithFile(Bit8Gs, PixelTypes.L8, BmpBitsPerPixel.Bit8)]
public void Encode_8BitGray_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_8BitGray_WithV3Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => where TPixel : unmanaged, IPixel<TPixel> =>
TestBmpEncoderCore( TestBmpEncoderCore(
@ -160,7 +160,7 @@ public class BmpEncoderTests
supportTransparency: false); supportTransparency: false);
[Theory] [Theory]
[WithFile(Bit4, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel4)] [WithFile(Bit4, PixelTypes.Rgba32, BmpBitsPerPixel.Bit4)]
public void Encode_4Bit_WithV3Header_Works<TPixel>( public void Encode_4Bit_WithV3Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
@ -176,7 +176,7 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(Bit4, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel4)] [WithFile(Bit4, PixelTypes.Rgba32, BmpBitsPerPixel.Bit4)]
public void Encode_4Bit_WithV4Header_Works<TPixel>( public void Encode_4Bit_WithV4Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
@ -192,7 +192,7 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(Bit2, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel2)] [WithFile(Bit2, PixelTypes.Rgba32, BmpBitsPerPixel.Bit2)]
public void Encode_2Bit_WithV3Header_Works<TPixel>( public void Encode_2Bit_WithV3Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
@ -214,7 +214,7 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(Bit2, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel2)] [WithFile(Bit2, PixelTypes.Rgba32, BmpBitsPerPixel.Bit2)]
public void Encode_2Bit_WithV4Header_Works<TPixel>( public void Encode_2Bit_WithV4Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
@ -236,21 +236,21 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(Bit1, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel1)] [WithFile(Bit1, PixelTypes.Rgba32, BmpBitsPerPixel.Bit1)]
public void Encode_1Bit_WithV3Header_Works<TPixel>( public void Encode_1Bit_WithV3Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: false);
[Theory] [Theory]
[WithFile(Bit1, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel1)] [WithFile(Bit1, PixelTypes.Rgba32, BmpBitsPerPixel.Bit1)]
public void Encode_1Bit_WithV4Header_Works<TPixel>( public void Encode_1Bit_WithV4Header_Works<TPixel>(
TestImageProvider<TPixel> provider, TestImageProvider<TPixel> provider,
BmpBitsPerPixel bitsPerPixel) BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
[Theory] [Theory]
[WithFile(Bit8Gs, PixelTypes.L8, BmpBitsPerPixel.Pixel8)] [WithFile(Bit8Gs, PixelTypes.L8, BmpBitsPerPixel.Bit8)]
public void Encode_8BitGray_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_8BitGray_WithV4Header_Works<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => where TPixel : unmanaged, IPixel<TPixel> =>
TestBmpEncoderCore( TestBmpEncoderCore(
@ -271,7 +271,7 @@ public class BmpEncoderTests
using Image<TPixel> image = provider.GetImage(); using Image<TPixel> image = provider.GetImage();
BmpEncoder encoder = new() BmpEncoder encoder = new()
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel8, BitsPerPixel = BmpBitsPerPixel.Bit8,
Quantizer = new WuQuantizer() Quantizer = new WuQuantizer()
}; };
@ -303,7 +303,7 @@ public class BmpEncoderTests
using Image<TPixel> image = provider.GetImage(); using Image<TPixel> image = provider.GetImage();
BmpEncoder encoder = new() BmpEncoder encoder = new()
{ {
BitsPerPixel = BmpBitsPerPixel.Pixel8, BitsPerPixel = BmpBitsPerPixel.Bit8,
Quantizer = new OctreeQuantizer() Quantizer = new OctreeQuantizer()
}; };
string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false); string actualOutputFile = provider.Utility.SaveTestOutputFile(image, "bmp", encoder, appendPixelTypeToFileName: false);
@ -322,8 +322,8 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(TestImages.Png.GrayAlpha2BitInterlaced, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] [WithFile(TestImages.Png.GrayAlpha2BitInterlaced, PixelTypes.Rgba32, BmpBitsPerPixel.Bit32)]
[WithFile(Bit32Rgba, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] [WithFile(Bit32Rgba, PixelTypes.Rgba32, BmpBitsPerPixel.Bit32)]
public void Encode_PreservesAlpha<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_PreservesAlpha<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true); where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
@ -364,8 +364,8 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(Car, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] [WithFile(Car, PixelTypes.Rgba32, BmpBitsPerPixel.Bit32)]
[WithFile(V5Header, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)] [WithFile(V5Header, PixelTypes.Rgba32, BmpBitsPerPixel.Bit32)]
public void Encode_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
@ -374,7 +374,7 @@ public class BmpEncoderTests
} }
[Theory] [Theory]
[WithFile(BlackWhitePalletDataMatrix, PixelTypes.Rgb24, BmpBitsPerPixel.Pixel1)] [WithFile(BlackWhitePalletDataMatrix, PixelTypes.Rgb24, BmpBitsPerPixel.Bit1)]
public void Encode_Issue2467<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel) public void Encode_Issue2467<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
@ -409,7 +409,7 @@ public class BmpEncoderTests
using Image<TPixel> image = provider.GetImage(); using Image<TPixel> image = provider.GetImage();
// There is no alpha in bmp with less then 32 bits per pixels, so the reference image will be made opaque. // There is no alpha in bmp with less then 32 bits per pixels, so the reference image will be made opaque.
if (bitsPerPixel != BmpBitsPerPixel.Pixel32) if (bitsPerPixel != BmpBitsPerPixel.Bit32)
{ {
image.Mutate(c => c.MakeOpaque()); image.Mutate(c => c.MakeOpaque());
} }

4
tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs

@ -15,10 +15,10 @@ public class BmpMetadataTests
public void CloneIsDeep() public void CloneIsDeep()
{ {
BmpMetadata meta = new() BmpMetadata meta = new()
{ BitsPerPixel = BmpBitsPerPixel.Pixel24, InfoHeaderType = BmpInfoHeaderType.Os2Version2 }; { BitsPerPixel = BmpBitsPerPixel.Bit24, InfoHeaderType = BmpInfoHeaderType.Os2Version2 };
BmpMetadata clone = (BmpMetadata)meta.DeepClone(); BmpMetadata clone = (BmpMetadata)meta.DeepClone();
clone.BitsPerPixel = BmpBitsPerPixel.Pixel32; clone.BitsPerPixel = BmpBitsPerPixel.Bit32;
clone.InfoHeaderType = BmpInfoHeaderType.WinVersion2; clone.InfoHeaderType = BmpInfoHeaderType.WinVersion2;
Assert.False(meta.BitsPerPixel.Equals(clone.BitsPerPixel)); Assert.False(meta.BitsPerPixel.Equals(clone.BitsPerPixel));

32
tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs

@ -15,17 +15,17 @@ public class TgaEncoderTests
public static readonly TheoryData<TgaBitsPerPixel> BitsPerPixel = public static readonly TheoryData<TgaBitsPerPixel> BitsPerPixel =
new() new()
{ {
TgaBitsPerPixel.Pixel24, TgaBitsPerPixel.Bit24,
TgaBitsPerPixel.Pixel32 TgaBitsPerPixel.Bit32
}; };
public static readonly TheoryData<string, TgaBitsPerPixel> TgaBitsPerPixelFiles = public static readonly TheoryData<string, TgaBitsPerPixel> TgaBitsPerPixelFiles =
new() new()
{ {
{ Gray8BitBottomLeft, TgaBitsPerPixel.Pixel8 }, { Gray8BitBottomLeft, TgaBitsPerPixel.Bit8 },
{ Bit16BottomLeft, TgaBitsPerPixel.Pixel16 }, { Bit16BottomLeft, TgaBitsPerPixel.Bit16 },
{ Bit24BottomLeft, TgaBitsPerPixel.Pixel24 }, { Bit24BottomLeft, TgaBitsPerPixel.Bit24 },
{ Bit32BottomLeft, TgaBitsPerPixel.Pixel32 }, { Bit32BottomLeft, TgaBitsPerPixel.Bit32 },
}; };
[Theory] [Theory]
@ -73,46 +73,46 @@ public class TgaEncoderTests
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit8_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8) public void TgaEncoder_Bit8_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit8)
// Using tolerant comparer here. The results from magick differ slightly. Maybe a different ToGrey method is used. The image looks otherwise ok. // 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); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false, compareTolerance: 0.03f);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit16_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16) public void TgaEncoder_Bit16_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit16)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None, useExactComparer: false);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit24_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24) public void TgaEncoder_Bit24_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit24)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit32_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32) public void TgaEncoder_Bit32_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit32)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.None);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit8_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel8) public void TgaEncoder_Bit8_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit8)
// Using tolerant comparer here. The results from magick differ slightly. Maybe a different ToGrey method is used. The image looks otherwise ok. // 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); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false, compareTolerance: 0.03f);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit16_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel16) public void TgaEncoder_Bit16_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit16)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength, useExactComparer: false);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit24_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel24) public void TgaEncoder_Bit24_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit24)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength);
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32)]
public void TgaEncoder_Bit32_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Pixel32) public void TgaEncoder_Bit32_WithRunLengthEncoding_Works<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel = TgaBitsPerPixel.Bit32)
where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength); where TPixel : unmanaged, IPixel<TPixel> => TestTgaEncoderCore(provider, bitsPerPixel, TgaCompression.RunLength);
[Theory] [Theory]
@ -152,8 +152,8 @@ public class TgaEncoderTests
} }
[Theory] [Theory]
[WithFile(Bit32BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel32)] [WithFile(Bit32BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Bit32)]
[WithFile(Bit24BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Pixel24)] [WithFile(Bit24BottomLeft, PixelTypes.Rgba32, TgaBitsPerPixel.Bit24)]
public void TgaEncoder_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel) public void TgaEncoder_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, TgaBitsPerPixel bitsPerPixel)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {

8
tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs

@ -33,10 +33,10 @@ public class TgaFileHeaderTests
} }
[Theory] [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[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 0, 195, 0, 32, 8 }, 250, 195, TgaBitsPerPixel.Bit32)]
[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[] { 26, 1, 9, 0, 0, 0, 1, 16, 0, 0, 0, 0, 128, 0, 128, 0, 8, 0 }, 128, 128, TgaBitsPerPixel.Bit8)]
[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, 220, 0, 220, 0, 16, 0 }, 220, 220, TgaBitsPerPixel.Bit16)]
[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)] [InlineData(new byte[] { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 124, 0, 24, 32 }, 124, 124, TgaBitsPerPixel.Bit24)]
public void Identify_WithValidData_Works(byte[] data, int width, int height, TgaBitsPerPixel bitsPerPixel) public void Identify_WithValidData_Works(byte[] data, int width, int height, TgaBitsPerPixel bitsPerPixel)
{ {
using MemoryStream stream = new(data); using MemoryStream stream = new(data);

4
tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs

@ -30,8 +30,8 @@ public class WebpDecoderTests
[Theory] [Theory]
[InlineData(Lossless.GreenTransform1, 1000, 307, 32)] [InlineData(Lossless.GreenTransform1, 1000, 307, 32)]
[InlineData(Lossless.BikeThreeTransforms, 250, 195, 32)] [InlineData(Lossless.BikeThreeTransforms, 250, 195, 24)]
[InlineData(Lossless.NoTransform2, 128, 128, 32)] [InlineData(Lossless.NoTransform2, 128, 128, 24)]
[InlineData(Lossy.Alpha1, 1000, 307, 32)] [InlineData(Lossy.Alpha1, 1000, 307, 32)]
[InlineData(Lossy.Alpha2, 1000, 307, 32)] [InlineData(Lossy.Alpha2, 1000, 307, 32)]
[InlineData(Lossy.BikeWithExif, 250, 195, 24)] [InlineData(Lossy.BikeWithExif, 250, 195, 24)]

Loading…
Cancel
Save