SIGN IN SIGN UP

savers/gif: separate color quantization from the palette search structure

Palette entries were split in half at every k-d tree node. This did
not depend on how many colors each subtree had. A subtree with only
a few colors got the same number of entries as a subtree with many
colors.

So duplicate colors filled the palette. Colors that were actually
different got merged together and lost. The exported GIF could not
reproduce these colors.

Solution: Palette colors are now chosen by splitting the box that holds the
highest SSE (Sum of Squared Errors), not by half.

But splitting by a ratio other than half can make the tree very deep.
The old tree had a fixed depth of 8. A deeper tree causes
a big bottleneck during search.

To fix this, we now separate two stages in _makePalette:
1. Color quantization
2. k-d tree construction

The structure built during color quantization is no longer reused
for palette search.

1. Color quantization
- Picks up to 255 colors for the palette.
- Splits the box with the largest SSE. The split axis is the one
  with the highest squared error.
- The split point could also use SSE. But we use the median value
  instead, as a simple trade-off.

2. k-d tree construction
- Builds a separate k-d tree, used for palette search.
- Selects the axis with the widest range. Splits the colors in half.
- Before splitting, elements must be sorted into three groups:
  values less than splitVal, equal to splitVal, and greater than
  splitVal. This is done using the Dutch National Flag (DNF)
  algorithm.

issue: #4669
A
alpakaDurumi committed
5ebb85a81423fe72acbc6305bb0f2d27806b7b5f
Parent: bc71d10
Committed by Hermet Park <hermetpark@gmail.com> on 8/20/2026, 1:08:51 AM