Three colour quantization algorithms integrated into a single av_quantize_* API. Quality and performance data on representative subtitle images.
All measurements from a 128×64 test image with quality=10. PSNR computed per-pixel in sRGB against the original, averaged over RGB channels.
Enhanced LBG vector quantizer. Iteratively refines codebook entries by splitting high-distortion cells and merging low-utility ones. General N-dimensional; wrapped here for 4D RGBA.
Recursively splits colour space along the axis of greatest variance. Deterministic and predictable. Extracted from FFmpeg's vf_palettegen filter. Uses OkLab perceptual space internally.
Kohonen self-organising map in colour space. Neurons compete to represent input colours via competitive learning. Fast, but non-deterministic and quality-sensitive to learning rate.
Higher is better. ≥40 dB is visually lossless for subtitles. Measured on five test images at three palette sizes.
| Image | ELBG | Median Cut | NeuQuant |
|---|---|---|---|
| Simple white text | 99.99 | 99.99 | 99.99 |
| Multicolour (4 regions) | 42.40 | 33.95 | 32.83 |
| Karaoke highlight | 99.99 | 99.99 | 99.99 |
| RGB gradient | 23.38 | 21.77 | 20.72 |
| HSV colour sweep | 20.73 | 19.14 | 15.32 |
| Image | ELBG | Median Cut | NeuQuant |
|---|---|---|---|
| Simple white text | 99.99 | 99.99 | 99.99 |
| Multicolour (4 regions) | 53.73 | 54.51 | 42.00 |
| Karaoke highlight | 99.99 | 99.99 | 99.99 |
| RGB gradient | 29.38 | 27.36 | 24.97 |
| HSV colour sweep | 26.37 | 24.14 | 20.06 |
| Image | ELBG | Median Cut | NeuQuant |
|---|---|---|---|
| Simple white text | 99.99 | 99.99 | 99.99 |
| Multicolour (4 regions) | 64.93 | 69.20 | 41.76 |
| Karaoke highlight | 99.99 | 99.99 | 99.99 |
| RGB gradient | 35.31 | 33.27 | 24.78 |
| HSV colour sweep | 32.31 | 29.46 | 20.84 |
PSNR on the hardest test cases. The "simple" cases are all 99.99 dB and omitted.
Generate palette + map pixels for 8,192 pixels (128×64). Lower is better.
| Palette size | ELBG | Median Cut | NeuQuant |
|---|---|---|---|
| 16 colours | 2.54 | 8.41 | 2.16 |
| 64 colours | 7.30 | 10.90 | 2.86 |
| 256 colours | 24.59 | 17.91 | 5.06 |
| Palette size | ELBG | Median Cut | NeuQuant |
|---|---|---|---|
| 16 colours | 1.51 | 0.74 | 0.49 |
| 64 colours | 4.33 | 0.72 | 0.67 |
| 256 colours | 15.98 | 0.76 | 1.40 |
For most subtitle work: use the default (NeuQuant). Subtitles typically have fewer than 100 unique colours. All three algorithms achieve perfect or near-perfect PSNR at this complexity. NeuQuant is the fastest and produces excellent results.
For complex ASS with gradients or many colours: consider Median Cut or ELBG. The data shows 10–15 dB improvement on gradient stress tests. ELBG is best on pure gradients; Median Cut is best on structured multi-region images and runs faster.
clock_gettime(CLOCK_MONOTONIC), includes both palette generation and pixel mapping