GIF: background handling & quantizer overflow fix

Merged
JI
5mo ago
+171-74

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules :cop:.
  • I have provided test coverage for my change (where applicable)

Description

See https://github.com/SixLabors/ImageSharp.Drawing/discussions/396

This pull request makes several significant improvements to GIF encoding and decoding, particularly around how background color is handled, quantization accuracy, and frame disposal behaviors. It also introduces a new regression test for a previously reported issue. The most important changes are grouped below:

GIF Background Color Handling:

  • The concept of background color in GifMetadata has been refactored: instead of storing a palette index (BackgroundColorIndex), the actual Color value is now stored and used throughout encoding and decoding. This change ensures more accurate and flexible background color management. [1] [2] [3] [4]
  • The encoder now determines the background color by first checking the encoder's setting, then falling back to the metadata's background color, and finally using transparent if neither is set. This color is then mapped to the palette for correct index assignment. [1] [2] [3]
  • The obsolete method for determining background index (GetBackgroundIndex) has been removed, simplifying the code and reducing potential for errors. [1] [2]

Quantization and Frame Encoding Enhancements:

  • The quantizer options are now adjusted for animated GIFs to reserve a color-table entry for transparency, improving color allocation for delta frames.
  • The quantization logic in the HexadecatreeQuantizer has been updated to use long instead of int for color channel sums and pixel counts, preventing overflow and improving accuracy for large images or many samples. [1] [2] [3]

Codebase and API Cleanups:

  • The now-unnecessary backgroundColor field in GifEncoderCore has been removed, and related constructor and method signatures have been updated for clarity and correctness. [1] [2] [3] [4]

Testing Improvements:

  • A new regression test (Issue_396) and supporting test images have been added to ensure correct handling of animated GIFs with frame disposal to background, verifying both encoding and decoding paths. [1] [2] [3] [4] [5]