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.3.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
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_placevoid_and_cluster_in_place
Custom map:
custom_ordered_in_placeadaptive_ordered_dither_in_placespace_filling_curve_ordered_dither_in_placeranked_dither_in_placeimage_based_dither_screen_in_placepolyomino_ordered_dither_in_placestochastic_clustered_dot_in_placeam_fm_hybrid_halftoning_in_placeclustered_am_fm_halftoning_in_placeblue_noise_multitone_dither_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_placeblock_error_diffusion_in_place
Scope note: block_error_diffusion_in_place is grayscale-only.
Variable diffusion
Tone-dependent coefficient families.
ostromoukhov_in_placezhou_fang_in_placehvs_optimized_error_diffusion_in_placegradient_based_error_diffusion_in_placemultiscale_error_diffusion_in_placefeature_preserving_msed_in_placegreen_noise_msed_in_placelinear_pixel_shuffling_in_placetone_dependent_error_diffusion_in_placestructure_aware_error_diffusion_in_placeadaptive_vector_error_diffusion_in_placevector_error_diffusion_in_placesemivector_error_diffusion_in_placehierarchical_error_diffusion_in_placembvq_color_error_diffusion_in_placeneugebauer_color_error_diffusion_in_placemultichannel_green_noise_error_diffusion_in_place
Scope note: variable diffusion methods are grayscale-only except
adaptive_vector_error_diffusion_in_place, vector_error_diffusion_in_place,
semivector_error_diffusion_in_place, and
hierarchical_error_diffusion_in_place,
mbvq_color_error_diffusion_in_place, and
neugebauer_color_error_diffusion_in_place, and
multichannel_green_noise_error_diffusion_in_place, which support Rgb/Rgba
with alpha preservation on Rgba.
Advanced halftoning
Specialized methods with narrower scope than the ordered/diffusion baseline.
riemersma_in_placeknuth_dot_diffusion_in_placeoptimized_dot_diffusion_in_placedirect_binary_search_in_placeclustered_dot_direct_multibit_search_in_placedirect_pattern_control_in_placehierarchical_colorant_dbs_in_placelattice_boltzmann_in_placeelectrostatic_halftoning_in_placemodel_based_med_in_placeleast_squares_model_based_in_place
Scope notes:
direct_binary_search_in_place,clustered_dot_direct_multibit_search_in_place,lattice_boltzmann_in_place,electrostatic_halftoning_in_place,model_based_med_in_place, andleast_squares_model_based_in_placerequire integer grayscale buffers.direct_pattern_control_in_placesupports integerRgb/Rgbabuffers; alpha is preserved forRgba.hierarchical_colorant_dbs_in_placesupports integerRgbbuffers.riemersma_in_place,knuth_dot_diffusion_in_place, andoptimized_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.
am_fm_hybrid_halftoning_in_placeandclustered_am_fm_halftoning_in_placeare grayscale-only.blue_noise_multitone_dither_in_placeis grayscale-only.- Variable diffusion methods are grayscale-only except
adaptive_vector_error_diffusion_in_place,vector_error_diffusion_in_place,semivector_error_diffusion_in_place,mbvq_color_error_diffusion_in_place, andneugebauer_color_error_diffusion_in_place, andmultichannel_green_noise_error_diffusion_in_placefor Rgb/Rgba. block_error_diffusion_in_placeis grayscale-only.direct_binary_search_in_place,clustered_dot_direct_multibit_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/
- Multiscale error diffusion: https://doi.org/10.1109/83.557360, https://mcl.usc.edu/wp-content/uploads/2014/01/1997-03-A-multiscale-error-diffusion-technique-for-digital-Halftoning.pdf
- Feature-preserving multiscale error diffusion: https://ira.lib.polyu.edu.hk/bitstream/10397/1524/1/J-JEI-Feature-preserving%20multiscale%20error%20diffusion_04.pdf, https://doi.org/10.1117/1.1758728
- Green-noise multiscale error diffusion: https://pubmed.ncbi.nlm.nih.gov/20215075/, https://www.eie.polyu.edu.hk/~enyhchan/J-TIP-Green_noise_digital_halftoning_with_MED.pdf
- Multichannel green-noise error diffusion: https://doi.org/10.1109/83.841537, https://doi.org/10.1364/JOSAA.16.001575
- Adaptive vector error diffusion: https://pubmed.ncbi.nlm.nih.gov/18282985/, https://doi.org/10.1109/83.597270
- HVS-optimized error diffusion (Kolpatzik-Bouman): https://engineering.purdue.edu/~bouman/publications/pdf/jei1scan.pdf, https://engineering.purdue.edu/~bouman/publications/pub_doc.html
- Vector and semivector color error diffusion: https://pubmed.ncbi.nlm.nih.gov/18255498/, https://doi.org/10.1109/83.951540, https://users.ece.utexas.edu/~bevans/papers/2003/colorDiffusion/index.html
- MBVQ/Neugebauer color error diffusion: https://www.mdpi.com/2313-433X/6/4/23, https://doi.org/10.3390/jimaging6040023, https://patents.google.com/patent/US5991438A/en, https://patents.google.com/patent/EP0895408A2/en
- Block error diffusion: https://doi.org/10.1109/TIP.2005.859776, https://shiftleft.com/mirrors/www.hpl.hp.com/personal/Niranjan_Damera-Venkata/files/ibc.pdf
- Hierarchical error diffusion: https://pubmed.ncbi.nlm.nih.gov/19473943/, https://doi.org/10.1109/TIP.2009.2019778
- Tone-dependent error diffusion: https://pubmed.ncbi.nlm.nih.gov/15376941/, https://pubmed.ncbi.nlm.nih.gov/17283778/
- Structure-aware error diffusion: https://perso.liris.cnrs.fr/ostrom/publications/pdf/SIGGRAPH-ASIA09_saed.pdf
- Linear pixel shuffling error diffusion: https://repository.rit.edu/other/391/, https://www.imaging.org/common/uploaded%20files/pdfs/Papers/2000/PICS-0-81/1625.pdf
- Riemersma dithering: https://www.compuphase.com/riemer.htm
- Knuth dot diffusion: https://dl.acm.org/doi/10.1145/35039.35040
- Optimized dot diffusion: https://doi.org/10.1109/83.841944
- Direct binary search halftoning: https://doi.org/10.1117/12.135959
- Model-based halftoning (MED + LSMB): https://pubmed.ncbi.nlm.nih.gov/18282991/, https://doi.org/10.1117/12.135965, https://users.eecs.northwestern.edu/~pappas/papers/pappas_neuhoff_tip99.pdf
- 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
- Void-and-cluster dithering: https://docslib.org/doc/9596963/the-void-and-cluster-method-for-dither-array-generation, https://cv.ulichney.com/papers/1994-filter-design.pdf
- Adaptive ordered dither: https://doi.org/10.1006/gmip.1996.0414, https://www.sciencedirect.com/science/article/pii/S1077316996904141
- Space-filling curve ordered dither: https://doi.org/10.1016/S0097-8493(98)00043-0, https://www.sciencedirect.com/science/article/pii/S0097849398000430
- Ranked dither: https://www.mayagupta.org/publications/GuptaBowenSPIE07.pdf
- Image-based dither screens: https://graphicsinterface.org/wp-content/uploads/gi1999-22.pdf, https://doi.org/10.20380/GI1999.22
- Polyomino-based digital halftoning: https://arxiv.org/abs/0812.1647, https://doi.org/10.48550/arXiv.0812.1647
- Stochastic clustered-dot dithering: https://perso.liris.cnrs.fr/victor.ostromoukhov/publications/pdf/SPIE99_StochasticClust.pdf, https://pubmed.ncbi.nlm.nih.gov/18255440/
- AM/FM hybrid halftoning: https://engineering.purdue.edu/~bouman/publications/orig-pdf/jei8.pdf, https://doi.org/10.1117/12.643690
- Clustered AM/FM halftoning: https://doi.org/10.2352/ISSN.2169-4451.2004.20.1.art00025_2, https://dblp.org/db/conf/clrimg/clrimg2006.html
- Blue-noise multitone dithering: https://doi.org/10.1109/TIP.2008.926145, https://www.eecis.udel.edu/~arce/files/Publications/5-Multitone.pdf
- Clustered-dot direct multibit search: https://pubmed.ncbi.nlm.nih.gov/28113172/, https://doi.org/10.1109/TIP.2016.2552723, https://research.ibm.com/publications/hybrid-halftoning-using-direct-multi-bit-search-dms-screen-algorithm
- Direct pattern control halftoning: https://pubmed.ncbi.nlm.nih.gov/28613170/, https://doi.org/10.1109/TIP.2017.2713939, https://cv.ulichney.com/papers/2017-PARAWACS-IEEE.pdf
- Hierarchical colorant DBS (MBVQ-guided): https://pubmed.ncbi.nlm.nih.gov/20236895/, https://doi.org/10.1109/TIP.2010.2045690, https://pubmed.ncbi.nlm.nih.gov/28613170/
License
MIT. See LICENSE.

