Browse Source

Fix trns preservation and add tests

af/merge-core
James Jackson-South 7 years ago
parent
commit
3235ce41b8
  1. 11
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  2. 5
      src/ImageSharp/Formats/Png/PngMetaData.cs
  3. 67
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  4. 3
      tests/ImageSharp.Tests/TestImages.cs
  5. 3
      tests/Images/Input/Png/gray-2-tRNS.png
  6. 3
      tests/Images/Input/Png/gray-4-tRNS.png
  7. 3
      tests/Images/Input/Png/gray-8-tRNS.png

11
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -760,9 +760,9 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="pngMetaData">The image meta data.</param>
private void WriteTransparencyChunk(Stream stream, PngMetaData pngMetaData)
{
Span<byte> alpha = this.chunkDataBuffer.AsSpan();
if (pngMetaData.ColorType.Equals(PngColorType.Rgb))
{
Span<byte> alpha = this.buffer.AsSpan();
if (pngMetaData.TransparentRgb48.HasValue && this.use16Bit)
{
Rgb48 rgb = pngMetaData.TransparentRgb48.Value;
@ -770,7 +770,7 @@ namespace SixLabors.ImageSharp.Formats.Png
BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(2, 2), rgb.G);
BinaryPrimitives.WriteUInt16LittleEndian(alpha.Slice(4, 2), rgb.B);
this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6);
this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6);
}
else if (pngMetaData.TransparentRgb24.HasValue)
{
@ -779,22 +779,21 @@ namespace SixLabors.ImageSharp.Formats.Png
alpha[1] = rgb.R;
alpha[3] = rgb.G;
alpha[5] = rgb.B;
this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 6);
this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 6);
}
}
else if (pngMetaData.ColorType.Equals(PngColorType.Grayscale))
{
Span<byte> alpha = this.buffer.AsSpan();
if (pngMetaData.TransparentGray16.HasValue && this.use16Bit)
{
BinaryPrimitives.WriteUInt16LittleEndian(alpha, pngMetaData.TransparentGray16.Value.PackedValue);
this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2);
this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2);
}
else if (pngMetaData.TransparentGray8.HasValue)
{
alpha.Clear();
alpha[1] = pngMetaData.TransparentGray8.Value.PackedValue;
this.WriteChunk(stream, PngChunkType.Transparency, this.buffer, 0, 2);
this.WriteChunk(stream, PngChunkType.Transparency, this.chunkDataBuffer, 0, 2);
}
}
}

5
src/ImageSharp/Formats/Png/PngMetaData.cs

@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Formats.Png
this.BitDepth = other.BitDepth;
this.ColorType = other.ColorType;
this.Gamma = other.Gamma;
this.HasTrans = other.HasTrans;
this.TransparentGray8 = other.TransparentGray8;
this.TransparentGray16 = other.TransparentGray16;
this.TransparentRgb24 = other.TransparentRgb24;
this.TransparentRgb48 = other.TransparentRgb48;
}
/// <summary>

67
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -25,6 +25,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
{ TestImages.Png.Bpp1, PngBitDepth.Bit1 }
};
public static readonly TheoryData<string, PngBitDepth, PngColorType> PngTrnsFiles =
new TheoryData<string, PngBitDepth, PngColorType>
{
{ TestImages.Png.Gray1BitTrans, PngBitDepth.Bit1, PngColorType.Grayscale },
{ TestImages.Png.Gray2BitTrans, PngBitDepth.Bit2, PngColorType.Grayscale },
{ TestImages.Png.Gray4BitTrans, PngBitDepth.Bit4, PngColorType.Grayscale },
{ TestImages.Png.Gray8BitTrans, PngBitDepth.Bit8, PngColorType.Grayscale },
{ TestImages.Png.GrayTrns16BitInterlaced, PngBitDepth.Bit16, PngColorType.Grayscale },
{ TestImages.Png.Rgb24BppTrans, PngBitDepth.Bit8, PngColorType.Rgb },
{ TestImages.Png.Rgb48BppTrans, PngBitDepth.Bit16, PngColorType.Rgb }
};
/// <summary>
/// All types except Palette
/// </summary>
@ -249,6 +261,61 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
}
}
[Theory]
[MemberData(nameof(PngTrnsFiles))]
public void Encode_PreserveTrns(string imagePath, PngBitDepth pngBitDepth, PngColorType pngColorType)
{
var options = new PngEncoder();
var testFile = TestFile.Create(imagePath);
using (Image<Rgba32> input = testFile.CreateImage())
{
PngMetaData inMeta = input.MetaData.GetFormatMetaData(PngFormat.Instance);
Assert.True(inMeta.HasTrans);
using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
{
PngMetaData outMeta = output.MetaData.GetFormatMetaData(PngFormat.Instance);
Assert.True(outMeta.HasTrans);
switch (pngColorType)
{
case PngColorType.Grayscale:
if (pngBitDepth.Equals(PngBitDepth.Bit16))
{
Assert.True(outMeta.TransparentGray16.HasValue);
Assert.Equal(inMeta.TransparentGray16, outMeta.TransparentGray16);
}
else
{
Assert.True(outMeta.TransparentGray8.HasValue);
Assert.Equal(inMeta.TransparentGray8, outMeta.TransparentGray8);
}
break;
case PngColorType.Rgb:
if (pngBitDepth.Equals(PngBitDepth.Bit16))
{
Assert.True(outMeta.TransparentRgb48.HasValue);
Assert.Equal(inMeta.TransparentRgb48, outMeta.TransparentRgb48);
}
else
{
Assert.True(outMeta.TransparentRgb24.HasValue);
Assert.Equal(inMeta.TransparentRgb24, outMeta.TransparentRgb24);
}
break;
}
}
}
}
}
private static void TestPngEncoderCore<TPixel>(
TestImageProvider<TPixel> provider,
PngColorType pngColorType,

3
tests/ImageSharp.Tests/TestImages.cs

@ -46,6 +46,9 @@ namespace SixLabors.ImageSharp.Tests
public const string PDSrc = "Png/pd-source.png";
public const string PDDest = "Png/pd-dest.png";
public const string Gray1BitTrans = "Png/gray-1-trns.png";
public const string Gray2BitTrans = "Png/gray-2-tRNS.png";
public const string Gray4BitTrans = "Png/gray-4-tRNS.png";
public const string Gray8BitTrans = "Png/gray-8-tRNS.png";
// Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html
public const string Filter0 = "Png/filter0.png";

3
tests/Images/Input/Png/gray-2-tRNS.png

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

3
tests/Images/Input/Png/gray-4-tRNS.png

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

3
tests/Images/Input/Png/gray-8-tRNS.png

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6e14dce9350fc40f7ee542d1dc788fbf6c1c0178515ea8b76ffa0b18bcf54e8a
size 267
Loading…
Cancel
Save