SkillAgentSearch skills...

Libdither

A C library for color and black-and-white image dithering

Install / Use

/learn @robertkist/Libdither

README

Libdither

Overview

Libdither is a library for black-and-white and color image dithering, written in C (ANSI C99 standard). Libdither has no external dependencies and should compile easily on most current systems (e.g. Windows, Linux, MacOS). All you need is a C compiler.

<b>This version of libdither is a Release Candidate</b>: it has been tested and is working, but minor code cleanup is still required.

The black-and-white only libdither version can now be found in the libdither_mono branch.

Features

  • Color ditherers: error diffusion, ordered dithering
  • Mono ditherers: grid dithering, ordered dithering, error diffusion, variable error diffusion (Ostromoukhov, Zhou Fang), pattern dithering, Direct Binary Search (DBS), dot diffusion, Kacker and Allebach dithering, Riemersma dithering, thresholding
  • Support for color comparison modes: LAB76, LAB94, LAB2000, sRGB, linear, HSV, luminance, Tetrapal
  • Support for color reduction: Median-Cut, Wu, KD-Tree
  • Support for images with transparent background
  • Libdither works in linear color space
  • Dither matrices and inputs can be easily extended without having to change the dither code itself
  • no external dependencies on other libraries
  • works with C and C++ projects
  • supports Windows, Linux, MacOS (universal binary support Intel / Apple silicon), and possible others

License Changes and 3rd-Party Code

Libdither MIT licensed, but the following code parts have their own permissive license:

  • kdtree license: requires inclusion of license terms in source and binary distributions (more)
  • uthash license: requires inclusion of license terms in source distributions (more)

Examples Color

Palettes:

<table> <tr> <td><b>Original</b></td> <td><b>EGA palette (16 colors)<br>error diffusion</b></td> <td><b>C64 palette (16 colors)<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/bike_small.png" width=233 height=255></td> <td><img src="extra/examples/errordiff_dither_EGA.png" width=233 height=255></td> <td><img src="extra/examples/errordiff_dither_C64.png" width=233 height=255></td> </tr><tr> <td><b>Pico8 palette (16 colors)<br>error diffusion</b></td> <td><b>EGA palette (16 colors)<br>ordered dithering</b></td> <td><b>C64 palette (16 colors)<br>ordered dithering</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_Pico8.png" width=233 height=255></td> <td><img src="extra/examples/ordered_void-dispersed-dots_dither_EGA.png" width=233 height=255></td> <td><img src="extra/examples/ordered_void-dispersed-dots_dither_C64.png" width=233 height=255></td> </tr> </table>

Note: Palettes with a good range of hues and brightness, which matches the source image work best. If the overall palette is too dark, or too bright, the image, too, will be darker or brighte.

Color Quantization:

<table> <tr> <td><b>Median-Cut: 16 colors<br>error diffusion</b></td> <td><b>Wu: 16 colors<br>error diffusion</b></td> <td><b>KD-Tree: 16 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_mediancut.png" width=233 height=255></td> <td><img src="extra/examples/errordiff_dither_wu.png" width=233 height=255></td> <td><img src="extra/examples/errordiff_dither_kd.png" width=233 height=255></td> </tr> </table>

Note: Median-Cut and Wu are fairly fast, compared to KD-Tree. However, KD-Tree often gives the best results.

Color Reduction:

<table> <tr> <td><b>Original</b></td> <td><b>Median-Cut: 2 colors<br>error diffusion</b></td> <td><b>Median-Cut: 4 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/david.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_2.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_4.png" width=220 height=262></td> </tr><tr> <td><b>Median-Cut: 8 colors<br>error diffusion</b></td> <td><b>Median-Cut: 16 colors<br>error diffusion</b></td> <td><b>Median-Cut: 32 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_8.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_16.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_32.png" width=220 height=262></td> </tr> </table>

Note: With a palette that matches the original palette well, 32 colors are often sufficient.

Color Matching / Color Distance function:

<table> <tr> <td><b>LAB '76: 16 colors<br>error diffusion</b></td> <td><b>LAB '04: 16 colors<br>error diffusion</b></td> <td><b>LAB 2000: 16 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_lab76.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_lab94.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_lab2000.png" width=220 height=262></td> </tr><tr> <td><b>sRGB: 16 colors<br>error diffusion</b></td> <td><b>sRGB CCIR: 16 colors<br>error diffusion</b></td> <td><b>linear: 16 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_srgb.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_srgb_ccir.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_linear.png" width=220 height=262></td> </tr><tr> <td><b>linear: 16 colors<br>error diffusion</b></td> <td><b>linear CCIR: 16 colors<br>error diffusion</b></td> <td><b>HSV: 16 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_linear.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_tetrapal.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_hsv.png" width=220 height=262></td> </tr><tr> <td><b>luminance: 4 colors<br>error diffusion</b></td> <td><b>LAB 2000: 4 colors<br>error diffusion</b></td> <td><b>HSV: 4 colors<br>error diffusion</b></td> </tr><tr> <td><img src="extra/examples/errordiff_dither_gb_luminance.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_gb_lab2000.png" width=220 height=262></td> <td><img src="extra/examples/errordiff_dither_gb_hsv.png" width=220 height=262></td> </tr> </table>

Notes:

  • Different color distance measuring methods are supported for finding the closest color in the target palette.
  • sRGB distance is a good, universally applicable choice.
  • LAB2000 distance is the most accurate method. It works best with well balanced palettes, where it can pick up even subtle nuances, but it is slow.
  • Luminance distance works best for gradients.
  • CCIR distance methods take human perceptions into account and add a slight saturation boost.
  • Tetrapal: works best for ordered dithering and pre-composed palettes (i.e. non quantified), such as EGA, C64, MS Paint palettes.
  • Other distance methods may work better than others in certain cases - make sure to try them.

Examples Mono

<table> <tr> <td><b>Original</b></td> <td><b>Grid dither</b></td> <td><b>Xot error diffusion</b></td> </tr><tr> <td><img src="https://user-images.githubusercontent.com/9162068/186177975-7fff4143-5e60-4270-b1c3-43f517445abd.png" width=220 height=262></td> <td><img src="https://user-images.githubusercontent.com/9162068/186177999-d243145a-a5cf-44fa-81b7-95b59ab571cf.png" width=220 height=262></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178037-48177c6e-96f3-4a4b-a21a-72ed0ad57b7d.png" width=220 height=262></td> </tr><tr> <td><b>Diagonal error diffusion</b></td> <td><b>Floyd Steinberg error diffusion</td> <td><b>ShiauFan 3 error diffusion</b></td> </tr><tr> <td><img src="https://user-images.githubusercontent.com/9162068/186178045-5835631a-183b-473d-9925-fc43cb871c34.png" width=220 height=262></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178049-01f3b989-718a-47d5-bb9e-3b92d6987c58.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178053-72b48a34-24c2-49d1-989b-d13b6ebb310f.png"></td> </tr><tr> <td><b>ShiauFan 2 error diffusion</b></td> <td><b>ShiauFan 1 error diffusion</b></td> <td><b>Stucki error diffusion</td> </tr><tr> <td><img src="https://user-images.githubusercontent.com/9162068/186178056-7a36ec8f-a592-4a03-856d-b66c47b7ccd3.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178058-74d0ca18-f5a5-4d1d-afa1-d63711229b74.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178065-4e31cbd2-4ce3-4488-9fbf-977fc98d7ddc.png"></td> </tr><tr> <td><b>1D error diffusion</b></td> <td><b>2D error diffusion</b></td> <td><b>Fake Floyd Steinberg error diffusion</b></td> </tr><tr> <td><img src="https://user-images.githubusercontent.com/9162068/186178070-d5c3ee60-ec13-4e69-af89-b880614e51e6.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178075-9550fdab-3246-4a4f-8616-b18845a2a871.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178079-b78ae193-7028-4512-a98e-e413d8b7c86f.png"></td> </tr><tr> <td><b>Jarvis-Judice-Ninke error diffusion</td> <td><b>Atkinson error diffusion</b></td> <td><b>Burkes error diffusion</b></td> </tr><tr> <td><img src="https://user-images.githubusercontent.com/9162068/186178085-f22ed91e-f1d2-45fc-a7b0-b5e6ade6c6e8.png"></td> <td><img src="https://user-images.githubusercontent.com/9162068/186178086-1ed082fa-c55b-42a7-af59-39e4dd8751ad.png"
View on GitHub
GitHub Stars112
CategoryCustomer
Updated2d ago
Forks8

Languages

C

Security Score

85/100

Audited on Mar 30, 2026

No findings