dithr
| Original | Dithered |
|---|---|
![]() |
![]() |
Before (left) and after (right) using yliluoma_2_in_place.
Buffer-first rust dithering and halftoning library.
Quantizing grayscale/RGB/RGBA buffers without dithering creates visible
banding and contouring. dithr provides deterministic ordered dithering,
diffusion, stochastic binary methods, palette-constrained workflows, and
advanced halftoning methods over typed mutable slices.
Overview
- Buffer-first API: Works directly on mutable pixel slices with explicit width, height, and stride.
- Typed formats: Supports
u8,u16, andf32sample types across Gray, Rgb, and Rgba layouts. - Quantization control: Uses
QuantizeModefor grayscale levels, RGB levels, palette mapping, or single-color workflows. - Broad algorithm coverage: Includes stochastic, ordered, palette-oriented ordered, diffusion, variable diffusion, and advanced halftoning families.
- Palette workflow: Includes
Palette<S>andIndexedImage<S>for constrained output and indexed results. - Optional integrations:
imageadapters forDynamicImageworkflows andrayonparallel wrappers for selected families.
Installation
[]
= "0.2.0"
Quick Start
use ;
use bayer_8x8_in_place;
Core Data Model
dithr is organized around a small set of types that are shared across
algorithm families.
Buffer<'a, S, L>: Mutable typed view of image data (S= sample type,L= layout).BufferKind/PixelFormat: Runtime format metadata (PixelFormatis an alias ofBufferKind).Palette<S>: Palette storage for fixed-color workflows (1 to 256 entries).IndexedImage<S>: Indexed output (Vec<u8>indices) paired with a typed palette.QuantizeMode<'a, S>: Common quantization target model used by ordered/diffusion/stochastic/dot/Riemersma families.Error/Result<T>: Crate-level error and result surface.
Typed Buffers, Sample Types, and Layouts
Supported runtime kinds:
Gray8,Rgb8,Rgba8Gray16,Rgb16,Rgba16Gray32F,Rgb32F,Rgba32F
Typed buffer aliases:
GrayBuffer8,RgbBuffer8,RgbaBuffer8GrayBuffer16,RgbBuffer16,RgbaBuffer16GrayBuffer32F,RgbBuffer32F,RgbaBuffer32F
Constructor helpers:
- Gray:
gray_u8,gray_u16,gray_32f - Rgb:
rgb_u8,rgb_u16,rgb_32f - Rgba:
rgba_u8,rgba_u16,rgba_32f - Packed variants:
gray_u8_packed,rgb_u16_packed,rgba_32f_packed, etc.
Generic constructors remain available on Buffer:
Buffer::new_typed(...)Buffer::new_packed_typed(...)- Compatibility constructors with runtime kind checking:
Buffer::new(...)Buffer::new_packed(...)
Choosing a Quantization Mode
QuantizeMode<'a, S> is the canonical quantization model:
GrayLevels(u16)RgbLevels(u16)Palette(&Palette<S>)SingleColor { fg: [S; 3], levels: u16 }
Convenience constructors:
- Generic:
QuantizeMode::gray_levels(levels)QuantizeMode::rgb_levels(levels)QuantizeMode::palette(&palette)QuantizeMode::single_color(fg, levels)
u8compatibility helpers:QuantizeMode::gray_bits(bits)QuantizeMode::rgb_bits(bits)
- Shared conversion helper:
levels_from_bits(bits)
Use GrayLevels/gray_bits when output should be grayscale levels,
RgbLevels/rgb_bits for uniform per-channel color quantization, Palette
for strict membership in a fixed color set, and SingleColor for
foreground-scaled tonal output.
Dithering and Halftoning Method Families
Binary stochastic
Fast binary dithering with fixed or randomized threshold behavior.
threshold_binary_in_placerandom_binary_in_place- compatibility aliases:
threshold_in_place,random_in_place
Parallel variants (rayon feature):
threshold_binary_in_place_parrandom_binary_in_place_par
Ordered methods
Deterministic threshold-map methods with predictable structure and straightforward benchmarking.
Bayer:
bayer_2x2_in_placebayer_4x4_in_placebayer_8x8_in_placebayer_16x16_in_place
Cluster-dot:
cluster_dot_4x4_in_placecluster_dot_8x8_in_place
Custom map:
custom_ordered_in_place
Parallel variants (rayon feature):
bayer_2x2_in_place_parbayer_4x4_in_place_parbayer_8x8_in_place_parbayer_16x16_in_place_parcluster_dot_4x4_in_place_parcluster_dot_8x8_in_place_parcustom_ordered_in_place_par
Palette-oriented ordered (Yliluoma)
Ordered methods designed for fixed-palette workflows.
yliluoma_1_in_placeyliluoma_2_in_placeyliluoma_3_in_place
Classic diffusion
Scanline error diffusion kernels for higher local tonal quality.
floyd_steinberg_in_placefalse_floyd_steinberg_in_placejarvis_judice_ninke_in_placestucki_in_placeburkes_in_placesierra_in_placetwo_row_sierra_in_placesierra_lite_in_placestevenson_arce_in_placeatkinson_in_place
Extended diffusion
Additional diffusion kernels with different spread patterns.
fan_in_placeshiau_fan_in_placeshiau_fan_2_in_place
Variable diffusion
Tone-dependent coefficient families.
ostromoukhov_in_placezhou_fang_in_placegradient_based_error_diffusion_in_place
Scope note: variable diffusion methods are grayscale-only.
Advanced halftoning
Specialized methods with narrower scope than the ordered/diffusion baseline.
riemersma_in_placeknuth_dot_diffusion_in_placedirect_binary_search_in_placelattice_boltzmann_in_placeelectrostatic_halftoning_in_place
Scope notes:
direct_binary_search_in_place,lattice_boltzmann_in_place, andelectrostatic_halftoning_in_placerequire integer grayscale buffers.riemersma_in_placeandknuth_dot_diffusion_in_placesupport Gray/Rgb/Rgba layouts, with alpha preserved for Rgba paths.
Palette Workflow
dithr keeps palette workflows explicit: define a palette, dither into it, and
optionally build indexed output.
use ;
use yliluoma_1_in_place;
Built-in palette helpers are also exported:
cga_palette()grayscale_2()grayscale_4()grayscale_16()
Optional image Integration
Enable image to adapt image crate buffers into dithr buffers.
Typed adapters:
gray8_image_as_bufferrgb8_image_as_bufferrgba8_image_as_buffergray16_image_as_bufferrgb16_image_as_bufferrgba16_image_as_bufferrgb32f_image_as_bufferrgba32f_image_as_buffer
Dynamic adapter:
dynamic_image_as_buffer(&mut image::DynamicImage) -> Result<DynamicImageBuffer<'_>>
Dynamic variants:
DynamicImageBuffer::Gray8DynamicImageBuffer::Rgb8DynamicImageBuffer::Rgba8DynamicImageBuffer::Gray16DynamicImageBuffer::Rgb16DynamicImageBuffer::Rgba16DynamicImageBuffer::Rgb32FDynamicImageBuffer::Rgba32F
DynamicImage::ImageLumaA8 and DynamicImage::ImageLumaA16 are promoted to
DynamicImageBuffer::Rgba8 and DynamicImageBuffer::Rgba16 during adaptation.
Current manifest configuration enables PNG and JPEG codecs for the optional
image dependency.
Optional rayon Integration
Enable rayon for parallel wrappers where available.
Parallelized families:
- Ordered: all
*_in_place_parordered wrappers - Yliluoma:
yliluoma_1_in_place_par,yliluoma_2_in_place_par,yliluoma_3_in_place_par - Binary stochastic:
threshold_binary_in_place_par,random_binary_in_place_par
Current serial-only families:
- Diffusion (classic/extended/variable)
- Advanced halftoning
Example Programs
Raw buffer workflows:
Image workflows (image feature):
Benchmarks and Development
Bench families (criterion):
stochasticorderedyliluomadiffusionadvanced
Development checks:
Limitations and Scope
- Core processing is in-memory and buffer-first; it does not provide general image editing workflows.
- Not every algorithm supports every format/layout/sample combination.
- Variable diffusion methods are grayscale-only.
direct_binary_search_in_place,lattice_boltzmann_in_place, andelectrostatic_halftoning_in_placeare integer grayscale-only.- Parallel wrappers are currently provided for ordered, Yliluoma, and binary stochastic families.
References
- Dither: https://en.wikipedia.org/wiki/Dither
- Ordered dithering: https://en.wikipedia.org/wiki/Ordered_dithering
- Error diffusion: https://en.wikipedia.org/wiki/Error_diffusion
- Yliluoma positional dithering: http://bisqwit.iki.fi/story/howto/dither/jy/
- Dithering eleven algorithms: https://tannerhelland.com/2012/12/28/dithering-eleven-algorithms-source-code.html
- Ostromoukhov variable-coefficient diffusion: https://www.iro.umontreal.ca/~ostrom/publications/pdf/SIGGRAPH01_varcoeffED.pdf
- Zhou-Fang threshold modulation: https://history.siggraph.org/learning/improving-mid-tone-quality-of-variable-coefficient-error-diffusion-using-threshold-modulation-by-zhou-and-fang/
- Riemersma dithering: https://www.compuphase.com/riemer.htm
- Knuth dot diffusion: https://dl.acm.org/doi/10.1145/35039.35040
- Direct binary search halftoning: https://doi.org/10.1117/12.135959
- Lattice-Boltzmann halftoning: https://www.mia.uni-saarland.de/Publications/hagenburg-isvc09.pdf
- Electrostatic halftoning: https://onlinelibrary.wiley.com/doi/10.1111/j.1467-8659.2010.01716.x
License
MIT. See LICENSE.

