/** * RGB color representation */ interface RGB { r: number; g: number; b: number; } /** * Image buffer in RGBA format * Compatible with Canvas ImageData and Node.js image libraries */ interface ImageBuffer { width: number; height: number; data: Uint8ClampedArray; } /** * Palette-indexed image output */ interface PaletteImageBuffer { width: number; height: number; indices: Uint8Array; palette: RGB[]; } /** * Color palette definition */ interface ColorPalette { readonly colors: Record; readonly accent: string; /** Canonical firmware color scheme value, if this is a measured palette. */ readonly scheme?: number; } /** * Dithering algorithm modes * Values match firmware conventions (0-9) */ declare enum DitherMode { /** * Direct nearest-color mapping with no error diffusion. Intended for * already-quantized graphics only. On limited palettes (especially BWR), * continuous-tone photos or large flat mid-tone areas can map to an * unexpected ink (e.g. a mid-gray region rendered as solid red); use an * error-diffusion mode (e.g. FLOYD_STEINBERG, BURKES) for photographic input. */ NONE = 0, BURKES = 1, ORDERED = 2, FLOYD_STEINBERG = 3, ATKINSON = 4, STUCKI = 5, SIERRA = 6, SIERRA_LITE = 7, JARVIS_JUDICE_NINKE = 8, /** * Error diffusion with pseudo-random traversal instead of a raster scan, * diffusing error only to not-yet-quantized neighbours. Produces no * directional structure. `serpentine` is ignored: there is no scan direction. */ DIZZY = 9 } declare const SPECTRA_7_3_6COLOR: ColorPalette; declare const SPECTRA_7_3_6COLOR_V2: ColorPalette; declare const MONO_4_26: ColorPalette; declare const BWRY_4_2: ColorPalette; declare const BWRY_3_97: ColorPalette; declare const SOLUM_BWR: ColorPalette; declare const HANSHOW_BWR: ColorPalette; declare const HANSHOW_BWY: ColorPalette; /** * E-paper display color schemes. * * Integer values are a firmware wire contract. Canonical source of truth: * `enum ColorScheme` in `opendisplay-protocol/src/opendisplay_structs.h`, which * names `packages/rust/core/src/palettes.rs` as its designated mirror. */ declare enum ColorScheme { MONO = 0, BWR = 1, BWY = 2, BWRY = 3, BWGBRY = 4, GRAYSCALE_4 = 5, GRAYSCALE_16 = 6, /** * 7-color Spectra/ACeP. Protocol v2 reassigned value 7 from the former * GRAYSCALE_8 to SEVEN_COLOR; GRAYSCALE_8 now lives at library-local value 9 * (below). Ink order is BWGBRY plus orange, matching the bb_epaper logical * ink indices. */ SEVEN_COLOR = 7, /** Spectra 6 nibbles, left-half plane then right-half plane (dual-CS panels). */ BWGBRY_SPLIT = 8, /** * 8-level grayscale dithering target, e.g. the Inkplate 10 (issue #19). * * Value 9 is NOT a firmware wire value. `opendisplay_structs.h` defines * `enum ColorScheme` values 0-8 and 100-102 only; it has no value 9 and none * is expected to be assigned here. This variant exists purely so the * dithering library can target 8-level-gray panels outside the OpenDisplay * ecosystem. Never send this value to a device as a `color_scheme` field. */ GRAYSCALE_8 = 9 } /** Get color palette for a color scheme */ declare function getPalette(scheme: ColorScheme): ColorPalette; /** Get number of colors in a color scheme */ declare function getColorCount(scheme: ColorScheme): number; declare function fromValue(value: number): ColorScheme; /** * Options for `ditherImage`. All fields are optional — defaults are sensible. * * Pre-processing pipeline (each step is a no-op at its identity value): * `exposure → saturation → shadows/highlights → tone → gamut → dither`. */ interface DitherOptions { /** Dithering algorithm. Default: `DitherMode.BURKES`. */ mode?: DitherMode; /** Alternate row scan direction for error diffusion. Default: `true`. */ serpentine?: boolean; /** Linear-RGB exposure multiplier. 1.0 = no change, 2.0 = +1 stop. Default: `1.0`. */ exposure?: number; /** OKLab saturation multiplier. 1.0 = no change, 0.0 = grayscale. Default: `1.0`. */ saturation?: number; /** Shadow lift strength (S-curve lower half). 0.0 = off, 1.0 = strong. Default: `0.0`. */ shadows?: number; /** Highlight compression strength (S-curve upper half). 0.0 = off, 1.0 = strong. Default: `0.0`. */ highlights?: number; /** Dynamic-range compression: `0.0`/`'off'` disables, `'auto'` opts in. Default: `0.0`. */ tone?: number | 'auto' | 'off'; /** Gamut compression: `0.0`/`'off'` disables, `'auto'` opts in. Default: `0.0`. */ gamut?: number | 'auto' | 'off'; } /** * Apply dithering to an RGBA image for an e-paper display. * * @param image Input RGBA image. Alpha is composited on white. * @param palette Target palette: `ColorScheme` enum (idealized) or `ColorPalette` (measured). * @param options Per-call overrides — see {@link DitherOptions}. * @returns Palette-indexed image buffer. */ declare function ditherImage(image: ImageBuffer, palette: ColorScheme | ColorPalette, options?: DitherOptions): PaletteImageBuffer; declare const VERSION = "0.1.0"; export { BWRY_3_97, BWRY_4_2, type ColorPalette, ColorScheme, DitherMode, type DitherOptions, HANSHOW_BWR, HANSHOW_BWY, type ImageBuffer, MONO_4_26, type PaletteImageBuffer, type RGB, SOLUM_BWR, SPECTRA_7_3_6COLOR, SPECTRA_7_3_6COLOR_V2, VERSION, ditherImage, fromValue, getColorCount, getPalette };