Browse Source

Merge branch 'main' into sn/promote-pixeltype

pull/2601/head
James Jackson-South 2 years ago
committed by GitHub
parent
commit
c80a7919b1
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .github/workflows/build-and-test.yml
  2. 2
      .github/workflows/code-coverage.yml
  3. 19
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  4. 3
      src/ImageSharp/Formats/Gif/MetadataExtensions.cs
  5. 2
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  6. 4
      tests/ImageSharp.Tests/TestImages.cs
  7. 3
      tests/Images/Input/Gif/global-256-no-trans.gif

4
.github/workflows/build-and-test.yml

@ -89,14 +89,14 @@ jobs:
- name: DotNet Setup
if: ${{ matrix.options.sdk-preview != true }}
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
- name: DotNet Setup Preview
if: ${{ matrix.options.sdk-preview == true }}
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x

2
.github/workflows/code-coverage.yml

@ -55,7 +55,7 @@ jobs:
restore-keys: ${{ runner.os }}-nuget-
- name: DotNet Setup
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x

19
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -103,7 +103,14 @@ internal sealed class GifEncoderCore : IImageEncoderInternals
{
// We avoid dithering by default to preserve the original colors.
int transparencyIndex = GetTransparentIndex(quantized, frameMetadata);
this.quantizer = new PaletteQuantizer(gifMetadata.GlobalColorTable.Value, new() { Dither = null }, transparencyIndex);
if (transparencyIndex >= 0 || gifMetadata.GlobalColorTable.Value.Length < 256)
{
this.quantizer = new PaletteQuantizer(gifMetadata.GlobalColorTable.Value, new() { Dither = null }, transparencyIndex);
}
else
{
this.quantizer = KnownQuantizers.Octree;
}
}
else
{
@ -198,19 +205,17 @@ internal sealed class GifEncoderCore : IImageEncoderInternals
private static GifFrameMetadata GetGifFrameMetadata<TPixel>(ImageFrame<TPixel> frame, int transparencyIndex)
where TPixel : unmanaged, IPixel<TPixel>
{
GifFrameMetadata? metadata = null;
if (frame.Metadata.TryGetGifMetadata(out GifFrameMetadata? gif))
{
return (GifFrameMetadata)gif.DeepClone();
metadata = (GifFrameMetadata)gif.DeepClone();
}
GifFrameMetadata? metadata = null;
if (frame.Metadata.TryGetPngMetadata(out PngFrameMetadata? png))
else if (frame.Metadata.TryGetPngMetadata(out PngFrameMetadata? png))
{
AnimatedImageFrameMetadata ani = png.ToAnimatedImageFrameMetadata();
metadata = GifFrameMetadata.FromAnimatedMetadata(ani);
}
if (frame.Metadata.TryGetWebpFrameMetadata(out WebpFrameMetadata? webp))
else if (frame.Metadata.TryGetWebpFrameMetadata(out WebpFrameMetadata? webp))
{
AnimatedImageFrameMetadata ani = webp.ToAnimatedImageFrameMetadata();
metadata = GifFrameMetadata.FromAnimatedMetadata(ani);

3
src/ImageSharp/Formats/Gif/MetadataExtensions.cs

@ -82,6 +82,9 @@ public static partial class MetadataExtensions
// has a local palette with 256 colors and is not transparent we should use 'Source'.
bool blendSource = source.DisposalMethod == GifDisposalMethod.RestoreToBackground || (source.LocalColorTable?.Length == 256 && !source.HasTransparency);
// If the color table is global and frame has no transparency. Consider it 'Source' also.
blendSource |= source.ColorTableMode == GifColorTableMode.Global && !source.HasTransparency;
return new()
{
ColorTable = source.LocalColorTable,

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

@ -499,7 +499,7 @@ public partial class PngEncoderTests
// TODO: Find a better way to compare.
// The image has been visually checked but the quantization pattern used in the png encoder
// means we cannot use an exact comparison nor replicate using the quantizing processor.
ImageComparer.TolerantPercentage(0.46f).VerifySimilarity(output, image);
ImageComparer.TolerantPercentage(0.613f).VerifySimilarity(output, image);
GifMetadata gif = image.Metadata.GetGifMetadata();
PngMetadata png = output.Metadata.GetPngMetadata();

4
tests/ImageSharp.Tests/TestImages.cs

@ -488,6 +488,7 @@ public static class TestImages
public const string MixedDisposal = "Gif/mixed-disposal.gif";
public const string M4nb = "Gif/m4nb.gif";
public const string Bit18RGBCube = "Gif/18-bit_RGB_Cube.gif";
public const string Global256NoTrans = "Gif/global-256-no-trans.gif";
// Test images from https://github.com/robert-ancell/pygif/tree/master/test-suite
public const string ZeroSize = "Gif/image-zero-size.gif";
@ -535,7 +536,8 @@ public static class TestImages
Issues.Issue2450_B,
Issues.BadDescriptorWidth,
Issues.Issue1530,
Bit18RGBCube
Bit18RGBCube,
Global256NoTrans
};
}

3
tests/Images/Input/Gif/global-256-no-trans.gif

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