Browse Source

Merge pull request #1781 from SixLabors/js/png-palette-filter

Use correct default scanline filter for indexed Pngs.
pull/1785/head
James Jackson-South 4 years ago
committed by GitHub
parent
commit
dbfb698b19
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 38
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  2. 8
      src/ImageSharp/Formats/Png/PngEncoderOptions.cs
  3. 12
      src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs

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

@ -268,35 +268,27 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.use16Bit)
{
// 16 bit grayscale + alpha
// TODO: Should we consider in the future a GrayAlpha32 type.
using (IMemoryOwner<Rgba64> rgbaBuffer = this.memoryAllocator.Allocate<Rgba64>(rowSpan.Length))
{
Span<Rgba64> rgbaSpan = rgbaBuffer.GetSpan();
ref Rgba64 rgbaRef = ref MemoryMarshal.GetReference(rgbaSpan);
PixelOperations<TPixel>.Instance.ToRgba64(this.configuration, rowSpan, rgbaSpan);
using IMemoryOwner<La32> laBuffer = this.memoryAllocator.Allocate<La32>(rowSpan.Length);
Span<La32> laSpan = laBuffer.GetSpan();
ref La32 laRef = ref MemoryMarshal.GetReference(laSpan);
PixelOperations<TPixel>.Instance.ToLa32(this.configuration, rowSpan, laSpan);
// Can't map directly to byte array as it's big endian.
for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4)
{
Rgba64 rgba = Unsafe.Add(ref rgbaRef, x);
ushort luminance = ColorNumerics.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.A);
}
// Can't map directly to byte array as it's big endian.
for (int x = 0, o = 0; x < laSpan.Length; x++, o += 4)
{
La32 la = Unsafe.Add(ref laRef, x);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), la.L);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), la.A);
}
}
else
{
// 8 bit grayscale + alpha
// TODO: Should we consider in the future a GrayAlpha16 type.
Rgba32 rgba = default;
for (int x = 0, o = 0; x < rowSpan.Length; x++, o += 2)
{
Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba);
Unsafe.Add(ref rawScanlineSpanRef, o) =
ColorNumerics.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A;
}
PixelOperations<TPixel>.Instance.ToLa16Bytes(
this.configuration,
rowSpan,
rawScanlineSpan,
rowSpan.Length);
}
}
}

8
src/ImageSharp/Formats/Png/PngEncoderOptions.cs

@ -18,11 +18,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
this.BitDepth = source.BitDepth;
this.ColorType = source.ColorType;
// Specification recommends default filter method None for paletted images and Paeth for others.
this.FilterMethod = source.FilterMethod ?? (source.ColorType == PngColorType.Palette
? PngFilterMethod.None
: PngFilterMethod.Paeth);
this.FilterMethod = source.FilterMethod;
this.CompressionLevel = source.CompressionLevel;
this.TextCompressionThreshold = source.TextCompressionThreshold;
this.Gamma = source.Gamma;
@ -41,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public PngColorType? ColorType { get; set; }
/// <inheritdoc/>
public PngFilterMethod? FilterMethod { get; }
public PngFilterMethod? FilterMethod { get; set; }
/// <inheritdoc/>
public PngCompressionLevel CompressionLevel { get; } = PngCompressionLevel.DefaultCompression;

12
src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs

@ -34,6 +34,18 @@ namespace SixLabors.ImageSharp.Formats.Png
// a sensible default based upon the pixel format.
options.ColorType ??= pngMetadata.ColorType ?? SuggestColorType<TPixel>();
options.BitDepth ??= pngMetadata.BitDepth ?? SuggestBitDepth<TPixel>();
if (!options.FilterMethod.HasValue)
{
// Specification recommends default filter method None for paletted images and Paeth for others.
if (options.ColorType == PngColorType.Palette)
{
options.FilterMethod = PngFilterMethod.None;
}
else
{
options.FilterMethod = PngFilterMethod.Paeth;
}
}
// Ensure bit depth and color type are a supported combination.
// Bit8 is the only bit depth supported by all color types.

Loading…
Cancel
Save