@opendisplay/epaper-dithering 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -61,10 +61,10 @@ var PALETTES = {
61
61
  colors: {
62
62
  black: { r: 0, g: 0, b: 0 },
63
63
  white: { r: 255, g: 255, b: 255 },
64
- green: { r: 0, g: 255, b: 0 },
65
- blue: { r: 0, g: 0, b: 255 },
64
+ yellow: { r: 255, g: 255, b: 0 },
66
65
  red: { r: 255, g: 0, b: 0 },
67
- yellow: { r: 255, g: 255, b: 0 }
66
+ blue: { r: 0, g: 0, b: 255 },
67
+ green: { r: 0, g: 255, b: 0 }
68
68
  },
69
69
  accent: "red"
70
70
  },
@@ -124,9 +124,9 @@ function errorDiffusionDither(image, colorScheme, kernel) {
124
124
  const idx = y * width + x;
125
125
  const pixelIdx = idx * 3;
126
126
  const oldPixel = {
127
- r: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx]))),
128
- g: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 1]))),
129
- b: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 2])))
127
+ r: Math.trunc(pixels[pixelIdx]),
128
+ g: Math.trunc(pixels[pixelIdx + 1]),
129
+ b: Math.trunc(pixels[pixelIdx + 2])
130
130
  };
131
131
  const newIdx = findClosestPaletteColor(oldPixel, palette);
132
132
  const newPixel = palette[newIdx];
@@ -190,9 +190,9 @@ function orderedDither(image, colorScheme) {
190
190
  const dataIdx = idx * 4;
191
191
  const threshold = bayerMatrix[y % 4 * 4 + x % 4];
192
192
  const rgb = {
193
- r: Math.min(255, image.data[dataIdx] + threshold),
194
- g: Math.min(255, image.data[dataIdx + 1] + threshold),
195
- b: Math.min(255, image.data[dataIdx + 2] + threshold)
193
+ r: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx] + threshold))),
194
+ g: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 1] + threshold))),
195
+ b: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 2] + threshold)))
196
196
  };
197
197
  indices[idx] = findClosestPaletteColor(rgb, palette);
198
198
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/enums.ts","../src/palettes.ts","../src/algorithms.ts","../src/core.ts","../src/index.ts"],"names":["DitherMode","ColorScheme"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Dithering algorithm modes\n * Values match firmware conventions (0-8)\n */\nexport enum DitherMode {\n NONE = 0,\n BURKES = 1,\n ORDERED = 2,\n FLOYD_STEINBERG = 3,\n ATKINSON = 4,\n STUCKI = 5,\n SIERRA = 6,\n SIERRA_LITE = 7,\n JARVIS_JUDICE_NINKE = 8,\n}","import type { RGB, ColorPalette } from './types';\n\n/**\n * E-paper display color schemes\n * Values match firmware conventions (0-5)\n */\nexport enum ColorScheme {\n MONO = 0,\n BWR = 1,\n BWY = 2,\n BWRY = 3,\n BWGBRY = 4,\n GRAYSCALE_4 = 5,\n}\n\nconst PALETTES: Record<ColorScheme, ColorPalette> = {\n [ColorScheme.MONO]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n [ColorScheme.BWR]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'yellow',\n },\n [ColorScheme.BWRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWGBRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n green: { r: 0, g: 255, b: 0 },\n blue: { r: 0, g: 0, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.GRAYSCALE_4]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n gray1: { r: 85, g: 85, b: 85 },\n gray2: { r: 170, g: 170, b: 170 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n};\n\n/**\n * Get color palette for a color scheme\n */\nexport function getPalette(scheme: ColorScheme): ColorPalette {\n return PALETTES[scheme];\n}\n\n/**\n * Get number of colors in a color scheme\n */\nexport function getColorCount(scheme: ColorScheme): number {\n return Object.keys(PALETTES[scheme].colors).length;\n}\n\n/**\n * Create ColorScheme from firmware integer value\n */\nexport function fromValue(value: number): ColorScheme {\n if (value < 0 || value > 5) {\n throw new Error(`Invalid color scheme value: ${value}`);\n }\n return value as ColorScheme;\n}","import type { RGB, ImageBuffer, PaletteImageBuffer } from './types';\nimport { ColorScheme, getPalette } from './palettes';\n\n/**\n * Get RGB palette colors from color scheme\n */\nexport function getPaletteColors(scheme: ColorScheme): RGB[] {\n const palette = getPalette(scheme);\n return Object.values(palette.colors);\n}\n\n/**\n * Find closest palette color using Euclidean distance\n */\nexport function findClosestPaletteColor(rgb: RGB, palette: RGB[]): number {\n let minDistance = Infinity;\n let closestIdx = 0;\n\n for (let i = 0; i < palette.length; i++) {\n const pal = palette[i];\n // Euclidean distance in RGB space\n const distance =\n (rgb.r - pal.r) ** 2 + (rgb.g - pal.g) ** 2 + (rgb.b - pal.b) ** 2;\n\n if (distance < minDistance) {\n minDistance = distance;\n closestIdx = i;\n }\n }\n\n return closestIdx;\n}\n\n/**\n * Error diffusion kernel entry\n */\ninterface ErrorKernel {\n dx: number;\n dy: number;\n weight: number;\n}\n\n/**\n * Apply error diffusion dithering with specified kernel\n */\nfunction errorDiffusionDither(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n kernel: ErrorKernel[]\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n\n // Convert RGBA to RGB float array for error accumulation\n const pixels = new Float32Array(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n pixels[i * 3] = image.data[i * 4]; // R\n pixels[i * 3 + 1] = image.data[i * 4 + 1]; // G\n pixels[i * 3 + 2] = image.data[i * 4 + 2]; // B\n }\n\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const pixelIdx = idx * 3;\n\n // Get old pixel (clamp to 0-255)\n const oldPixel: RGB = {\n r: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx]))),\n g: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 1]))),\n b: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 2]))),\n };\n\n // Find closest palette color\n const newIdx = findClosestPaletteColor(oldPixel, palette);\n const newPixel = palette[newIdx];\n indices[idx] = newIdx;\n\n // Calculate quantization error\n const errorR = oldPixel.r - newPixel.r;\n const errorG = oldPixel.g - newPixel.g;\n const errorB = oldPixel.b - newPixel.b;\n\n // Distribute error to neighbors using kernel\n for (const { dx, dy, weight } of kernel) {\n const nx = x + dx;\n const ny = y + dy;\n\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const neighborIdx = (ny * width + nx) * 3;\n pixels[neighborIdx] += errorR * weight;\n pixels[neighborIdx + 1] += errorG * weight;\n pixels[neighborIdx + 2] += errorB * weight;\n }\n }\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Direct palette mapping without dithering (NONE)\n */\nexport function directPaletteMap(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let i = 0; i < width * height; i++) {\n const rgb: RGB = {\n r: image.data[i * 4],\n g: image.data[i * 4 + 1],\n b: image.data[i * 4 + 2],\n };\n indices[i] = findClosestPaletteColor(rgb, palette);\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Ordered dithering using 4x4 Bayer matrix\n */\nexport function orderedDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const bayerMatrix = new Uint8Array([\n 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5,\n ]).map((v) => v * 16);\n\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const dataIdx = idx * 4;\n\n // Get threshold from Bayer matrix\n const threshold = bayerMatrix[(y % 4) * 4 + (x % 4)];\n\n // Add threshold noise\n const rgb: RGB = {\n r: Math.min(255, image.data[dataIdx] + threshold),\n g: Math.min(255, image.data[dataIdx + 1] + threshold),\n b: Math.min(255, image.data[dataIdx + 2] + threshold),\n };\n\n indices[idx] = findClosestPaletteColor(rgb, palette);\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Burkes dithering (divisor 200)\n * Kernel:\n * X 32 12\n * 5 12 26 12 5\n */\nexport function burkesDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 32 / 200 },\n { dx: 2, dy: 0, weight: 12 / 200 },\n { dx: -2, dy: 1, weight: 5 / 200 },\n { dx: -1, dy: 1, weight: 12 / 200 },\n { dx: 0, dy: 1, weight: 26 / 200 },\n { dx: 1, dy: 1, weight: 12 / 200 },\n { dx: 2, dy: 1, weight: 5 / 200 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Floyd-Steinberg dithering (divisor 16)\n * Most popular error diffusion algorithm\n * Kernel:\n * X 7\n * 3 5 1\n */\nexport function floydSteinbergDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 16 },\n { dx: -1, dy: 1, weight: 3 / 16 },\n { dx: 0, dy: 1, weight: 5 / 16 },\n { dx: 1, dy: 1, weight: 1 / 16 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra dithering (divisor 32)\n * Kernel:\n * X 5 3\n * 2 4 5 4 2\n * 2 3 2\n */\nexport function sierraDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 5 / 32 },\n { dx: 2, dy: 0, weight: 3 / 32 },\n { dx: -2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 1, weight: 4 / 32 },\n { dx: 0, dy: 1, weight: 5 / 32 },\n { dx: 1, dy: 1, weight: 4 / 32 },\n { dx: 2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 2, weight: 2 / 32 },\n { dx: 0, dy: 2, weight: 3 / 32 },\n { dx: 1, dy: 2, weight: 2 / 32 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra Lite dithering (divisor 4)\n * Fastest error diffusion algorithm\n * Kernel:\n * X 2\n * 1 1\n */\nexport function sierraLiteDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 2 / 4 },\n { dx: -1, dy: 1, weight: 1 / 4 },\n { dx: 0, dy: 1, weight: 1 / 4 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Atkinson dithering (divisor 8)\n * Created by Bill Atkinson for original Macintosh\n * Kernel:\n * X 1 1\n * 1 1 1\n * 1\n */\nexport function atkinsonDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 1 / 8 },\n { dx: 2, dy: 0, weight: 1 / 8 },\n { dx: -1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 1, weight: 1 / 8 },\n { dx: 1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 2, weight: 1 / 8 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Stucki dithering (divisor 42)\n * High quality error diffusion\n * Kernel:\n * X 8 4\n * 2 4 8 4 2\n * 1 2 4 2 1\n */\nexport function stuckiDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 8 / 42 },\n { dx: 2, dy: 0, weight: 4 / 42 },\n { dx: -2, dy: 1, weight: 2 / 42 },\n { dx: -1, dy: 1, weight: 4 / 42 },\n { dx: 0, dy: 1, weight: 8 / 42 },\n { dx: 1, dy: 1, weight: 4 / 42 },\n { dx: 2, dy: 1, weight: 2 / 42 },\n { dx: -2, dy: 2, weight: 1 / 42 },\n { dx: -1, dy: 2, weight: 2 / 42 },\n { dx: 0, dy: 2, weight: 4 / 42 },\n { dx: 1, dy: 2, weight: 2 / 42 },\n { dx: 2, dy: 2, weight: 1 / 42 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Jarvis-Judice-Ninke dithering (divisor 48)\n * Highest quality, slowest algorithm\n * Kernel:\n * X 7 5\n * 3 5 7 5 3\n * 1 3 5 3 1\n */\nexport function jarvisJudiceNinkeDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 48 },\n { dx: 2, dy: 0, weight: 5 / 48 },\n { dx: -2, dy: 1, weight: 3 / 48 },\n { dx: -1, dy: 1, weight: 5 / 48 },\n { dx: 0, dy: 1, weight: 7 / 48 },\n { dx: 1, dy: 1, weight: 5 / 48 },\n { dx: 2, dy: 1, weight: 3 / 48 },\n { dx: -2, dy: 2, weight: 1 / 48 },\n { dx: -1, dy: 2, weight: 3 / 48 },\n { dx: 0, dy: 2, weight: 5 / 48 },\n { dx: 1, dy: 2, weight: 3 / 48 },\n { dx: 2, dy: 2, weight: 1 / 48 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}","import type { ImageBuffer, PaletteImageBuffer } from './types';\nimport { DitherMode } from './enums';\nimport { ColorScheme } from './palettes';\nimport * as algorithms from './algorithms';\n\n/**\n * Apply dithering algorithm to image for e-paper display\n *\n * @param image - Input image buffer (RGBA format)\n * @param colorScheme - Target e-paper color scheme\n * @param mode - Dithering algorithm (default: BURKES)\n * @returns Palette-indexed image buffer\n *\n * @example\n * ```typescript\n * const dithered = ditherImage(imageBuffer, ColorScheme.BWR, DitherMode.FLOYD_STEINBERG);\n * ```\n */\nexport function ditherImage(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n mode: DitherMode = DitherMode.BURKES\n): PaletteImageBuffer {\n switch (mode) {\n case DitherMode.NONE:\n return algorithms.directPaletteMap(image, colorScheme);\n case DitherMode.ORDERED:\n return algorithms.orderedDither(image, colorScheme);\n case DitherMode.FLOYD_STEINBERG:\n return algorithms.floydSteinbergDither(image, colorScheme);\n case DitherMode.ATKINSON:\n return algorithms.atkinsonDither(image, colorScheme);\n case DitherMode.STUCKI:\n return algorithms.stuckiDither(image, colorScheme);\n case DitherMode.SIERRA:\n return algorithms.sierraDither(image, colorScheme);\n case DitherMode.SIERRA_LITE:\n return algorithms.sierraLiteDither(image, colorScheme);\n case DitherMode.JARVIS_JUDICE_NINKE:\n return algorithms.jarvisJudiceNinkeDither(image, colorScheme);\n case DitherMode.BURKES:\n default:\n return algorithms.burkesDither(image, colorScheme);\n }\n}","export { ditherImage } from './core';\nexport { DitherMode } from './enums';\nexport {\n ColorScheme,\n getPalette,\n getColorCount,\n fromValue,\n} from './palettes';\nexport type { RGB, ImageBuffer, PaletteImageBuffer, ColorPalette } from './types';\n\nexport const VERSION = '0.1.0';"]}
1
+ {"version":3,"sources":["../src/enums.ts","../src/palettes.ts","../src/algorithms.ts","../src/core.ts","../src/index.ts"],"names":["DitherMode","ColorScheme"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Dithering algorithm modes\n * Values match firmware conventions (0-8)\n */\nexport enum DitherMode {\n NONE = 0,\n BURKES = 1,\n ORDERED = 2,\n FLOYD_STEINBERG = 3,\n ATKINSON = 4,\n STUCKI = 5,\n SIERRA = 6,\n SIERRA_LITE = 7,\n JARVIS_JUDICE_NINKE = 8,\n}","import type { RGB, ColorPalette } from './types';\n\n/**\n * E-paper display color schemes\n * Values match firmware conventions (0-5)\n */\nexport enum ColorScheme {\n MONO = 0,\n BWR = 1,\n BWY = 2,\n BWRY = 3,\n BWGBRY = 4,\n GRAYSCALE_4 = 5,\n}\n\nconst PALETTES: Record<ColorScheme, ColorPalette> = {\n [ColorScheme.MONO]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n [ColorScheme.BWR]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'yellow',\n },\n [ColorScheme.BWRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWGBRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n red: { r: 255, g: 0, b: 0 },\n blue: { r: 0, g: 0, b: 255 },\n green: { r: 0, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.GRAYSCALE_4]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n gray1: { r: 85, g: 85, b: 85 },\n gray2: { r: 170, g: 170, b: 170 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n};\n\n/**\n * Get color palette for a color scheme\n */\nexport function getPalette(scheme: ColorScheme): ColorPalette {\n return PALETTES[scheme];\n}\n\n/**\n * Get number of colors in a color scheme\n */\nexport function getColorCount(scheme: ColorScheme): number {\n return Object.keys(PALETTES[scheme].colors).length;\n}\n\n/**\n * Create ColorScheme from firmware integer value\n */\nexport function fromValue(value: number): ColorScheme {\n if (value < 0 || value > 5) {\n throw new Error(`Invalid color scheme value: ${value}`);\n }\n return value as ColorScheme;\n}","import type { RGB, ImageBuffer, PaletteImageBuffer } from './types';\nimport { ColorScheme, getPalette } from './palettes';\n\n/**\n * Get RGB palette colors from color scheme\n */\nexport function getPaletteColors(scheme: ColorScheme): RGB[] {\n const palette = getPalette(scheme);\n return Object.values(palette.colors);\n}\n\n/**\n * Find closest palette color using Euclidean distance\n */\nexport function findClosestPaletteColor(rgb: RGB, palette: RGB[]): number {\n let minDistance = Infinity;\n let closestIdx = 0;\n\n for (let i = 0; i < palette.length; i++) {\n const pal = palette[i];\n // Euclidean distance in RGB space\n const distance =\n (rgb.r - pal.r) ** 2 + (rgb.g - pal.g) ** 2 + (rgb.b - pal.b) ** 2;\n\n if (distance < minDistance) {\n minDistance = distance;\n closestIdx = i;\n }\n }\n\n return closestIdx;\n}\n\n/**\n * Error diffusion kernel entry\n */\ninterface ErrorKernel {\n dx: number;\n dy: number;\n weight: number;\n}\n\n/**\n * Apply error diffusion dithering with specified kernel\n */\nfunction errorDiffusionDither(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n kernel: ErrorKernel[]\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n\n // Convert RGBA to RGB float array for error accumulation\n const pixels = new Float32Array(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n pixels[i * 3] = image.data[i * 4]; // R\n pixels[i * 3 + 1] = image.data[i * 4 + 1]; // G\n pixels[i * 3 + 2] = image.data[i * 4 + 2]; // B\n }\n\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const pixelIdx = idx * 3;\n\n // Get old pixel (truncate, no clamping - matches Python behavior)\n const oldPixel: RGB = {\n r: Math.trunc(pixels[pixelIdx]),\n g: Math.trunc(pixels[pixelIdx + 1]),\n b: Math.trunc(pixels[pixelIdx + 2]),\n };\n\n // Find closest palette color\n const newIdx = findClosestPaletteColor(oldPixel, palette);\n const newPixel = palette[newIdx];\n indices[idx] = newIdx;\n\n // Calculate quantization error\n const errorR = oldPixel.r - newPixel.r;\n const errorG = oldPixel.g - newPixel.g;\n const errorB = oldPixel.b - newPixel.b;\n\n // Distribute error to neighbors using kernel\n for (const { dx, dy, weight } of kernel) {\n const nx = x + dx;\n const ny = y + dy;\n\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const neighborIdx = (ny * width + nx) * 3;\n pixels[neighborIdx] += errorR * weight;\n pixels[neighborIdx + 1] += errorG * weight;\n pixels[neighborIdx + 2] += errorB * weight;\n }\n }\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Direct palette mapping without dithering (NONE)\n */\nexport function directPaletteMap(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let i = 0; i < width * height; i++) {\n const rgb: RGB = {\n r: image.data[i * 4],\n g: image.data[i * 4 + 1],\n b: image.data[i * 4 + 2],\n };\n indices[i] = findClosestPaletteColor(rgb, palette);\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Ordered dithering using 4x4 Bayer matrix\n */\nexport function orderedDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const bayerMatrix = new Uint8Array([\n 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5,\n ]).map((v) => v * 16);\n\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const dataIdx = idx * 4;\n\n // Get threshold from Bayer matrix\n const threshold = bayerMatrix[(y % 4) * 4 + (x % 4)];\n\n // Add threshold noise (clamp to 0-255 like Python's np.clip)\n const rgb: RGB = {\n r: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx] + threshold))),\n g: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 1] + threshold))),\n b: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 2] + threshold))),\n };\n\n indices[idx] = findClosestPaletteColor(rgb, palette);\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Burkes dithering (divisor 200)\n * Kernel:\n * X 32 12\n * 5 12 26 12 5\n */\nexport function burkesDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 32 / 200 },\n { dx: 2, dy: 0, weight: 12 / 200 },\n { dx: -2, dy: 1, weight: 5 / 200 },\n { dx: -1, dy: 1, weight: 12 / 200 },\n { dx: 0, dy: 1, weight: 26 / 200 },\n { dx: 1, dy: 1, weight: 12 / 200 },\n { dx: 2, dy: 1, weight: 5 / 200 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Floyd-Steinberg dithering (divisor 16)\n * Most popular error diffusion algorithm\n * Kernel:\n * X 7\n * 3 5 1\n */\nexport function floydSteinbergDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 16 },\n { dx: -1, dy: 1, weight: 3 / 16 },\n { dx: 0, dy: 1, weight: 5 / 16 },\n { dx: 1, dy: 1, weight: 1 / 16 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra dithering (divisor 32)\n * Kernel:\n * X 5 3\n * 2 4 5 4 2\n * 2 3 2\n */\nexport function sierraDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 5 / 32 },\n { dx: 2, dy: 0, weight: 3 / 32 },\n { dx: -2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 1, weight: 4 / 32 },\n { dx: 0, dy: 1, weight: 5 / 32 },\n { dx: 1, dy: 1, weight: 4 / 32 },\n { dx: 2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 2, weight: 2 / 32 },\n { dx: 0, dy: 2, weight: 3 / 32 },\n { dx: 1, dy: 2, weight: 2 / 32 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra Lite dithering (divisor 4)\n * Fastest error diffusion algorithm\n * Kernel:\n * X 2\n * 1 1\n */\nexport function sierraLiteDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 2 / 4 },\n { dx: -1, dy: 1, weight: 1 / 4 },\n { dx: 0, dy: 1, weight: 1 / 4 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Atkinson dithering (divisor 8)\n * Created by Bill Atkinson for original Macintosh\n * Kernel:\n * X 1 1\n * 1 1 1\n * 1\n */\nexport function atkinsonDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 1 / 8 },\n { dx: 2, dy: 0, weight: 1 / 8 },\n { dx: -1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 1, weight: 1 / 8 },\n { dx: 1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 2, weight: 1 / 8 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Stucki dithering (divisor 42)\n * High quality error diffusion\n * Kernel:\n * X 8 4\n * 2 4 8 4 2\n * 1 2 4 2 1\n */\nexport function stuckiDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 8 / 42 },\n { dx: 2, dy: 0, weight: 4 / 42 },\n { dx: -2, dy: 1, weight: 2 / 42 },\n { dx: -1, dy: 1, weight: 4 / 42 },\n { dx: 0, dy: 1, weight: 8 / 42 },\n { dx: 1, dy: 1, weight: 4 / 42 },\n { dx: 2, dy: 1, weight: 2 / 42 },\n { dx: -2, dy: 2, weight: 1 / 42 },\n { dx: -1, dy: 2, weight: 2 / 42 },\n { dx: 0, dy: 2, weight: 4 / 42 },\n { dx: 1, dy: 2, weight: 2 / 42 },\n { dx: 2, dy: 2, weight: 1 / 42 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Jarvis-Judice-Ninke dithering (divisor 48)\n * Highest quality, slowest algorithm\n * Kernel:\n * X 7 5\n * 3 5 7 5 3\n * 1 3 5 3 1\n */\nexport function jarvisJudiceNinkeDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 48 },\n { dx: 2, dy: 0, weight: 5 / 48 },\n { dx: -2, dy: 1, weight: 3 / 48 },\n { dx: -1, dy: 1, weight: 5 / 48 },\n { dx: 0, dy: 1, weight: 7 / 48 },\n { dx: 1, dy: 1, weight: 5 / 48 },\n { dx: 2, dy: 1, weight: 3 / 48 },\n { dx: -2, dy: 2, weight: 1 / 48 },\n { dx: -1, dy: 2, weight: 3 / 48 },\n { dx: 0, dy: 2, weight: 5 / 48 },\n { dx: 1, dy: 2, weight: 3 / 48 },\n { dx: 2, dy: 2, weight: 1 / 48 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}","import type { ImageBuffer, PaletteImageBuffer } from './types';\nimport { DitherMode } from './enums';\nimport { ColorScheme } from './palettes';\nimport * as algorithms from './algorithms';\n\n/**\n * Apply dithering algorithm to image for e-paper display\n *\n * @param image - Input image buffer (RGBA format)\n * @param colorScheme - Target e-paper color scheme\n * @param mode - Dithering algorithm (default: BURKES)\n * @returns Palette-indexed image buffer\n *\n * @example\n * ```typescript\n * const dithered = ditherImage(imageBuffer, ColorScheme.BWR, DitherMode.FLOYD_STEINBERG);\n * ```\n */\nexport function ditherImage(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n mode: DitherMode = DitherMode.BURKES\n): PaletteImageBuffer {\n switch (mode) {\n case DitherMode.NONE:\n return algorithms.directPaletteMap(image, colorScheme);\n case DitherMode.ORDERED:\n return algorithms.orderedDither(image, colorScheme);\n case DitherMode.FLOYD_STEINBERG:\n return algorithms.floydSteinbergDither(image, colorScheme);\n case DitherMode.ATKINSON:\n return algorithms.atkinsonDither(image, colorScheme);\n case DitherMode.STUCKI:\n return algorithms.stuckiDither(image, colorScheme);\n case DitherMode.SIERRA:\n return algorithms.sierraDither(image, colorScheme);\n case DitherMode.SIERRA_LITE:\n return algorithms.sierraLiteDither(image, colorScheme);\n case DitherMode.JARVIS_JUDICE_NINKE:\n return algorithms.jarvisJudiceNinkeDither(image, colorScheme);\n case DitherMode.BURKES:\n default:\n return algorithms.burkesDither(image, colorScheme);\n }\n}","export { ditherImage } from './core';\nexport { DitherMode } from './enums';\nexport {\n ColorScheme,\n getPalette,\n getColorCount,\n fromValue,\n} from './palettes';\nexport type { RGB, ImageBuffer, PaletteImageBuffer, ColorPalette } from './types';\n\nexport const VERSION = '0.1.0';"]}
package/dist/index.js CHANGED
@@ -59,10 +59,10 @@ var PALETTES = {
59
59
  colors: {
60
60
  black: { r: 0, g: 0, b: 0 },
61
61
  white: { r: 255, g: 255, b: 255 },
62
- green: { r: 0, g: 255, b: 0 },
63
- blue: { r: 0, g: 0, b: 255 },
62
+ yellow: { r: 255, g: 255, b: 0 },
64
63
  red: { r: 255, g: 0, b: 0 },
65
- yellow: { r: 255, g: 255, b: 0 }
64
+ blue: { r: 0, g: 0, b: 255 },
65
+ green: { r: 0, g: 255, b: 0 }
66
66
  },
67
67
  accent: "red"
68
68
  },
@@ -122,9 +122,9 @@ function errorDiffusionDither(image, colorScheme, kernel) {
122
122
  const idx = y * width + x;
123
123
  const pixelIdx = idx * 3;
124
124
  const oldPixel = {
125
- r: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx]))),
126
- g: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 1]))),
127
- b: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 2])))
125
+ r: Math.trunc(pixels[pixelIdx]),
126
+ g: Math.trunc(pixels[pixelIdx + 1]),
127
+ b: Math.trunc(pixels[pixelIdx + 2])
128
128
  };
129
129
  const newIdx = findClosestPaletteColor(oldPixel, palette);
130
130
  const newPixel = palette[newIdx];
@@ -188,9 +188,9 @@ function orderedDither(image, colorScheme) {
188
188
  const dataIdx = idx * 4;
189
189
  const threshold = bayerMatrix[y % 4 * 4 + x % 4];
190
190
  const rgb = {
191
- r: Math.min(255, image.data[dataIdx] + threshold),
192
- g: Math.min(255, image.data[dataIdx + 1] + threshold),
193
- b: Math.min(255, image.data[dataIdx + 2] + threshold)
191
+ r: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx] + threshold))),
192
+ g: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 1] + threshold))),
193
+ b: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 2] + threshold)))
194
194
  };
195
195
  indices[idx] = findClosestPaletteColor(rgb, palette);
196
196
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/enums.ts","../src/palettes.ts","../src/algorithms.ts","../src/core.ts","../src/index.ts"],"names":["DitherMode","ColorScheme"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Dithering algorithm modes\n * Values match firmware conventions (0-8)\n */\nexport enum DitherMode {\n NONE = 0,\n BURKES = 1,\n ORDERED = 2,\n FLOYD_STEINBERG = 3,\n ATKINSON = 4,\n STUCKI = 5,\n SIERRA = 6,\n SIERRA_LITE = 7,\n JARVIS_JUDICE_NINKE = 8,\n}","import type { RGB, ColorPalette } from './types';\n\n/**\n * E-paper display color schemes\n * Values match firmware conventions (0-5)\n */\nexport enum ColorScheme {\n MONO = 0,\n BWR = 1,\n BWY = 2,\n BWRY = 3,\n BWGBRY = 4,\n GRAYSCALE_4 = 5,\n}\n\nconst PALETTES: Record<ColorScheme, ColorPalette> = {\n [ColorScheme.MONO]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n [ColorScheme.BWR]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'yellow',\n },\n [ColorScheme.BWRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWGBRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n green: { r: 0, g: 255, b: 0 },\n blue: { r: 0, g: 0, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.GRAYSCALE_4]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n gray1: { r: 85, g: 85, b: 85 },\n gray2: { r: 170, g: 170, b: 170 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n};\n\n/**\n * Get color palette for a color scheme\n */\nexport function getPalette(scheme: ColorScheme): ColorPalette {\n return PALETTES[scheme];\n}\n\n/**\n * Get number of colors in a color scheme\n */\nexport function getColorCount(scheme: ColorScheme): number {\n return Object.keys(PALETTES[scheme].colors).length;\n}\n\n/**\n * Create ColorScheme from firmware integer value\n */\nexport function fromValue(value: number): ColorScheme {\n if (value < 0 || value > 5) {\n throw new Error(`Invalid color scheme value: ${value}`);\n }\n return value as ColorScheme;\n}","import type { RGB, ImageBuffer, PaletteImageBuffer } from './types';\nimport { ColorScheme, getPalette } from './palettes';\n\n/**\n * Get RGB palette colors from color scheme\n */\nexport function getPaletteColors(scheme: ColorScheme): RGB[] {\n const palette = getPalette(scheme);\n return Object.values(palette.colors);\n}\n\n/**\n * Find closest palette color using Euclidean distance\n */\nexport function findClosestPaletteColor(rgb: RGB, palette: RGB[]): number {\n let minDistance = Infinity;\n let closestIdx = 0;\n\n for (let i = 0; i < palette.length; i++) {\n const pal = palette[i];\n // Euclidean distance in RGB space\n const distance =\n (rgb.r - pal.r) ** 2 + (rgb.g - pal.g) ** 2 + (rgb.b - pal.b) ** 2;\n\n if (distance < minDistance) {\n minDistance = distance;\n closestIdx = i;\n }\n }\n\n return closestIdx;\n}\n\n/**\n * Error diffusion kernel entry\n */\ninterface ErrorKernel {\n dx: number;\n dy: number;\n weight: number;\n}\n\n/**\n * Apply error diffusion dithering with specified kernel\n */\nfunction errorDiffusionDither(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n kernel: ErrorKernel[]\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n\n // Convert RGBA to RGB float array for error accumulation\n const pixels = new Float32Array(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n pixels[i * 3] = image.data[i * 4]; // R\n pixels[i * 3 + 1] = image.data[i * 4 + 1]; // G\n pixels[i * 3 + 2] = image.data[i * 4 + 2]; // B\n }\n\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const pixelIdx = idx * 3;\n\n // Get old pixel (clamp to 0-255)\n const oldPixel: RGB = {\n r: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx]))),\n g: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 1]))),\n b: Math.max(0, Math.min(255, Math.round(pixels[pixelIdx + 2]))),\n };\n\n // Find closest palette color\n const newIdx = findClosestPaletteColor(oldPixel, palette);\n const newPixel = palette[newIdx];\n indices[idx] = newIdx;\n\n // Calculate quantization error\n const errorR = oldPixel.r - newPixel.r;\n const errorG = oldPixel.g - newPixel.g;\n const errorB = oldPixel.b - newPixel.b;\n\n // Distribute error to neighbors using kernel\n for (const { dx, dy, weight } of kernel) {\n const nx = x + dx;\n const ny = y + dy;\n\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const neighborIdx = (ny * width + nx) * 3;\n pixels[neighborIdx] += errorR * weight;\n pixels[neighborIdx + 1] += errorG * weight;\n pixels[neighborIdx + 2] += errorB * weight;\n }\n }\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Direct palette mapping without dithering (NONE)\n */\nexport function directPaletteMap(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let i = 0; i < width * height; i++) {\n const rgb: RGB = {\n r: image.data[i * 4],\n g: image.data[i * 4 + 1],\n b: image.data[i * 4 + 2],\n };\n indices[i] = findClosestPaletteColor(rgb, palette);\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Ordered dithering using 4x4 Bayer matrix\n */\nexport function orderedDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const bayerMatrix = new Uint8Array([\n 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5,\n ]).map((v) => v * 16);\n\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const dataIdx = idx * 4;\n\n // Get threshold from Bayer matrix\n const threshold = bayerMatrix[(y % 4) * 4 + (x % 4)];\n\n // Add threshold noise\n const rgb: RGB = {\n r: Math.min(255, image.data[dataIdx] + threshold),\n g: Math.min(255, image.data[dataIdx + 1] + threshold),\n b: Math.min(255, image.data[dataIdx + 2] + threshold),\n };\n\n indices[idx] = findClosestPaletteColor(rgb, palette);\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Burkes dithering (divisor 200)\n * Kernel:\n * X 32 12\n * 5 12 26 12 5\n */\nexport function burkesDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 32 / 200 },\n { dx: 2, dy: 0, weight: 12 / 200 },\n { dx: -2, dy: 1, weight: 5 / 200 },\n { dx: -1, dy: 1, weight: 12 / 200 },\n { dx: 0, dy: 1, weight: 26 / 200 },\n { dx: 1, dy: 1, weight: 12 / 200 },\n { dx: 2, dy: 1, weight: 5 / 200 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Floyd-Steinberg dithering (divisor 16)\n * Most popular error diffusion algorithm\n * Kernel:\n * X 7\n * 3 5 1\n */\nexport function floydSteinbergDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 16 },\n { dx: -1, dy: 1, weight: 3 / 16 },\n { dx: 0, dy: 1, weight: 5 / 16 },\n { dx: 1, dy: 1, weight: 1 / 16 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra dithering (divisor 32)\n * Kernel:\n * X 5 3\n * 2 4 5 4 2\n * 2 3 2\n */\nexport function sierraDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 5 / 32 },\n { dx: 2, dy: 0, weight: 3 / 32 },\n { dx: -2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 1, weight: 4 / 32 },\n { dx: 0, dy: 1, weight: 5 / 32 },\n { dx: 1, dy: 1, weight: 4 / 32 },\n { dx: 2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 2, weight: 2 / 32 },\n { dx: 0, dy: 2, weight: 3 / 32 },\n { dx: 1, dy: 2, weight: 2 / 32 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra Lite dithering (divisor 4)\n * Fastest error diffusion algorithm\n * Kernel:\n * X 2\n * 1 1\n */\nexport function sierraLiteDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 2 / 4 },\n { dx: -1, dy: 1, weight: 1 / 4 },\n { dx: 0, dy: 1, weight: 1 / 4 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Atkinson dithering (divisor 8)\n * Created by Bill Atkinson for original Macintosh\n * Kernel:\n * X 1 1\n * 1 1 1\n * 1\n */\nexport function atkinsonDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 1 / 8 },\n { dx: 2, dy: 0, weight: 1 / 8 },\n { dx: -1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 1, weight: 1 / 8 },\n { dx: 1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 2, weight: 1 / 8 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Stucki dithering (divisor 42)\n * High quality error diffusion\n * Kernel:\n * X 8 4\n * 2 4 8 4 2\n * 1 2 4 2 1\n */\nexport function stuckiDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 8 / 42 },\n { dx: 2, dy: 0, weight: 4 / 42 },\n { dx: -2, dy: 1, weight: 2 / 42 },\n { dx: -1, dy: 1, weight: 4 / 42 },\n { dx: 0, dy: 1, weight: 8 / 42 },\n { dx: 1, dy: 1, weight: 4 / 42 },\n { dx: 2, dy: 1, weight: 2 / 42 },\n { dx: -2, dy: 2, weight: 1 / 42 },\n { dx: -1, dy: 2, weight: 2 / 42 },\n { dx: 0, dy: 2, weight: 4 / 42 },\n { dx: 1, dy: 2, weight: 2 / 42 },\n { dx: 2, dy: 2, weight: 1 / 42 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Jarvis-Judice-Ninke dithering (divisor 48)\n * Highest quality, slowest algorithm\n * Kernel:\n * X 7 5\n * 3 5 7 5 3\n * 1 3 5 3 1\n */\nexport function jarvisJudiceNinkeDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 48 },\n { dx: 2, dy: 0, weight: 5 / 48 },\n { dx: -2, dy: 1, weight: 3 / 48 },\n { dx: -1, dy: 1, weight: 5 / 48 },\n { dx: 0, dy: 1, weight: 7 / 48 },\n { dx: 1, dy: 1, weight: 5 / 48 },\n { dx: 2, dy: 1, weight: 3 / 48 },\n { dx: -2, dy: 2, weight: 1 / 48 },\n { dx: -1, dy: 2, weight: 3 / 48 },\n { dx: 0, dy: 2, weight: 5 / 48 },\n { dx: 1, dy: 2, weight: 3 / 48 },\n { dx: 2, dy: 2, weight: 1 / 48 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}","import type { ImageBuffer, PaletteImageBuffer } from './types';\nimport { DitherMode } from './enums';\nimport { ColorScheme } from './palettes';\nimport * as algorithms from './algorithms';\n\n/**\n * Apply dithering algorithm to image for e-paper display\n *\n * @param image - Input image buffer (RGBA format)\n * @param colorScheme - Target e-paper color scheme\n * @param mode - Dithering algorithm (default: BURKES)\n * @returns Palette-indexed image buffer\n *\n * @example\n * ```typescript\n * const dithered = ditherImage(imageBuffer, ColorScheme.BWR, DitherMode.FLOYD_STEINBERG);\n * ```\n */\nexport function ditherImage(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n mode: DitherMode = DitherMode.BURKES\n): PaletteImageBuffer {\n switch (mode) {\n case DitherMode.NONE:\n return algorithms.directPaletteMap(image, colorScheme);\n case DitherMode.ORDERED:\n return algorithms.orderedDither(image, colorScheme);\n case DitherMode.FLOYD_STEINBERG:\n return algorithms.floydSteinbergDither(image, colorScheme);\n case DitherMode.ATKINSON:\n return algorithms.atkinsonDither(image, colorScheme);\n case DitherMode.STUCKI:\n return algorithms.stuckiDither(image, colorScheme);\n case DitherMode.SIERRA:\n return algorithms.sierraDither(image, colorScheme);\n case DitherMode.SIERRA_LITE:\n return algorithms.sierraLiteDither(image, colorScheme);\n case DitherMode.JARVIS_JUDICE_NINKE:\n return algorithms.jarvisJudiceNinkeDither(image, colorScheme);\n case DitherMode.BURKES:\n default:\n return algorithms.burkesDither(image, colorScheme);\n }\n}","export { ditherImage } from './core';\nexport { DitherMode } from './enums';\nexport {\n ColorScheme,\n getPalette,\n getColorCount,\n fromValue,\n} from './palettes';\nexport type { RGB, ImageBuffer, PaletteImageBuffer, ColorPalette } from './types';\n\nexport const VERSION = '0.1.0';"]}
1
+ {"version":3,"sources":["../src/enums.ts","../src/palettes.ts","../src/algorithms.ts","../src/core.ts","../src/index.ts"],"names":["DitherMode","ColorScheme"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Dithering algorithm modes\n * Values match firmware conventions (0-8)\n */\nexport enum DitherMode {\n NONE = 0,\n BURKES = 1,\n ORDERED = 2,\n FLOYD_STEINBERG = 3,\n ATKINSON = 4,\n STUCKI = 5,\n SIERRA = 6,\n SIERRA_LITE = 7,\n JARVIS_JUDICE_NINKE = 8,\n}","import type { RGB, ColorPalette } from './types';\n\n/**\n * E-paper display color schemes\n * Values match firmware conventions (0-5)\n */\nexport enum ColorScheme {\n MONO = 0,\n BWR = 1,\n BWY = 2,\n BWRY = 3,\n BWGBRY = 4,\n GRAYSCALE_4 = 5,\n}\n\nconst PALETTES: Record<ColorScheme, ColorPalette> = {\n [ColorScheme.MONO]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n [ColorScheme.BWR]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'yellow',\n },\n [ColorScheme.BWRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n red: { r: 255, g: 0, b: 0 },\n yellow: { r: 255, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.BWGBRY]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n white: { r: 255, g: 255, b: 255 },\n yellow: { r: 255, g: 255, b: 0 },\n red: { r: 255, g: 0, b: 0 },\n blue: { r: 0, g: 0, b: 255 },\n green: { r: 0, g: 255, b: 0 },\n },\n accent: 'red',\n },\n [ColorScheme.GRAYSCALE_4]: {\n colors: {\n black: { r: 0, g: 0, b: 0 },\n gray1: { r: 85, g: 85, b: 85 },\n gray2: { r: 170, g: 170, b: 170 },\n white: { r: 255, g: 255, b: 255 },\n },\n accent: 'black',\n },\n};\n\n/**\n * Get color palette for a color scheme\n */\nexport function getPalette(scheme: ColorScheme): ColorPalette {\n return PALETTES[scheme];\n}\n\n/**\n * Get number of colors in a color scheme\n */\nexport function getColorCount(scheme: ColorScheme): number {\n return Object.keys(PALETTES[scheme].colors).length;\n}\n\n/**\n * Create ColorScheme from firmware integer value\n */\nexport function fromValue(value: number): ColorScheme {\n if (value < 0 || value > 5) {\n throw new Error(`Invalid color scheme value: ${value}`);\n }\n return value as ColorScheme;\n}","import type { RGB, ImageBuffer, PaletteImageBuffer } from './types';\nimport { ColorScheme, getPalette } from './palettes';\n\n/**\n * Get RGB palette colors from color scheme\n */\nexport function getPaletteColors(scheme: ColorScheme): RGB[] {\n const palette = getPalette(scheme);\n return Object.values(palette.colors);\n}\n\n/**\n * Find closest palette color using Euclidean distance\n */\nexport function findClosestPaletteColor(rgb: RGB, palette: RGB[]): number {\n let minDistance = Infinity;\n let closestIdx = 0;\n\n for (let i = 0; i < palette.length; i++) {\n const pal = palette[i];\n // Euclidean distance in RGB space\n const distance =\n (rgb.r - pal.r) ** 2 + (rgb.g - pal.g) ** 2 + (rgb.b - pal.b) ** 2;\n\n if (distance < minDistance) {\n minDistance = distance;\n closestIdx = i;\n }\n }\n\n return closestIdx;\n}\n\n/**\n * Error diffusion kernel entry\n */\ninterface ErrorKernel {\n dx: number;\n dy: number;\n weight: number;\n}\n\n/**\n * Apply error diffusion dithering with specified kernel\n */\nfunction errorDiffusionDither(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n kernel: ErrorKernel[]\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n\n // Convert RGBA to RGB float array for error accumulation\n const pixels = new Float32Array(width * height * 3);\n for (let i = 0; i < width * height; i++) {\n pixels[i * 3] = image.data[i * 4]; // R\n pixels[i * 3 + 1] = image.data[i * 4 + 1]; // G\n pixels[i * 3 + 2] = image.data[i * 4 + 2]; // B\n }\n\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const pixelIdx = idx * 3;\n\n // Get old pixel (truncate, no clamping - matches Python behavior)\n const oldPixel: RGB = {\n r: Math.trunc(pixels[pixelIdx]),\n g: Math.trunc(pixels[pixelIdx + 1]),\n b: Math.trunc(pixels[pixelIdx + 2]),\n };\n\n // Find closest palette color\n const newIdx = findClosestPaletteColor(oldPixel, palette);\n const newPixel = palette[newIdx];\n indices[idx] = newIdx;\n\n // Calculate quantization error\n const errorR = oldPixel.r - newPixel.r;\n const errorG = oldPixel.g - newPixel.g;\n const errorB = oldPixel.b - newPixel.b;\n\n // Distribute error to neighbors using kernel\n for (const { dx, dy, weight } of kernel) {\n const nx = x + dx;\n const ny = y + dy;\n\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const neighborIdx = (ny * width + nx) * 3;\n pixels[neighborIdx] += errorR * weight;\n pixels[neighborIdx + 1] += errorG * weight;\n pixels[neighborIdx + 2] += errorB * weight;\n }\n }\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Direct palette mapping without dithering (NONE)\n */\nexport function directPaletteMap(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let i = 0; i < width * height; i++) {\n const rgb: RGB = {\n r: image.data[i * 4],\n g: image.data[i * 4 + 1],\n b: image.data[i * 4 + 2],\n };\n indices[i] = findClosestPaletteColor(rgb, palette);\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Ordered dithering using 4x4 Bayer matrix\n */\nexport function orderedDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const bayerMatrix = new Uint8Array([\n 0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5,\n ]).map((v) => v * 16);\n\n const { width, height } = image;\n const palette = getPaletteColors(colorScheme);\n const indices = new Uint8Array(width * height);\n\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n const idx = y * width + x;\n const dataIdx = idx * 4;\n\n // Get threshold from Bayer matrix\n const threshold = bayerMatrix[(y % 4) * 4 + (x % 4)];\n\n // Add threshold noise (clamp to 0-255 like Python's np.clip)\n const rgb: RGB = {\n r: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx] + threshold))),\n g: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 1] + threshold))),\n b: Math.max(0, Math.min(255, Math.trunc(image.data[dataIdx + 2] + threshold))),\n };\n\n indices[idx] = findClosestPaletteColor(rgb, palette);\n }\n }\n\n return { width, height, indices, palette };\n}\n\n/**\n * Burkes dithering (divisor 200)\n * Kernel:\n * X 32 12\n * 5 12 26 12 5\n */\nexport function burkesDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 32 / 200 },\n { dx: 2, dy: 0, weight: 12 / 200 },\n { dx: -2, dy: 1, weight: 5 / 200 },\n { dx: -1, dy: 1, weight: 12 / 200 },\n { dx: 0, dy: 1, weight: 26 / 200 },\n { dx: 1, dy: 1, weight: 12 / 200 },\n { dx: 2, dy: 1, weight: 5 / 200 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Floyd-Steinberg dithering (divisor 16)\n * Most popular error diffusion algorithm\n * Kernel:\n * X 7\n * 3 5 1\n */\nexport function floydSteinbergDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 16 },\n { dx: -1, dy: 1, weight: 3 / 16 },\n { dx: 0, dy: 1, weight: 5 / 16 },\n { dx: 1, dy: 1, weight: 1 / 16 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra dithering (divisor 32)\n * Kernel:\n * X 5 3\n * 2 4 5 4 2\n * 2 3 2\n */\nexport function sierraDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 5 / 32 },\n { dx: 2, dy: 0, weight: 3 / 32 },\n { dx: -2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 1, weight: 4 / 32 },\n { dx: 0, dy: 1, weight: 5 / 32 },\n { dx: 1, dy: 1, weight: 4 / 32 },\n { dx: 2, dy: 1, weight: 2 / 32 },\n { dx: -1, dy: 2, weight: 2 / 32 },\n { dx: 0, dy: 2, weight: 3 / 32 },\n { dx: 1, dy: 2, weight: 2 / 32 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Sierra Lite dithering (divisor 4)\n * Fastest error diffusion algorithm\n * Kernel:\n * X 2\n * 1 1\n */\nexport function sierraLiteDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 2 / 4 },\n { dx: -1, dy: 1, weight: 1 / 4 },\n { dx: 0, dy: 1, weight: 1 / 4 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Atkinson dithering (divisor 8)\n * Created by Bill Atkinson for original Macintosh\n * Kernel:\n * X 1 1\n * 1 1 1\n * 1\n */\nexport function atkinsonDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 1 / 8 },\n { dx: 2, dy: 0, weight: 1 / 8 },\n { dx: -1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 1, weight: 1 / 8 },\n { dx: 1, dy: 1, weight: 1 / 8 },\n { dx: 0, dy: 2, weight: 1 / 8 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Stucki dithering (divisor 42)\n * High quality error diffusion\n * Kernel:\n * X 8 4\n * 2 4 8 4 2\n * 1 2 4 2 1\n */\nexport function stuckiDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 8 / 42 },\n { dx: 2, dy: 0, weight: 4 / 42 },\n { dx: -2, dy: 1, weight: 2 / 42 },\n { dx: -1, dy: 1, weight: 4 / 42 },\n { dx: 0, dy: 1, weight: 8 / 42 },\n { dx: 1, dy: 1, weight: 4 / 42 },\n { dx: 2, dy: 1, weight: 2 / 42 },\n { dx: -2, dy: 2, weight: 1 / 42 },\n { dx: -1, dy: 2, weight: 2 / 42 },\n { dx: 0, dy: 2, weight: 4 / 42 },\n { dx: 1, dy: 2, weight: 2 / 42 },\n { dx: 2, dy: 2, weight: 1 / 42 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}\n\n/**\n * Jarvis-Judice-Ninke dithering (divisor 48)\n * Highest quality, slowest algorithm\n * Kernel:\n * X 7 5\n * 3 5 7 5 3\n * 1 3 5 3 1\n */\nexport function jarvisJudiceNinkeDither(\n image: ImageBuffer,\n colorScheme: ColorScheme\n): PaletteImageBuffer {\n const kernel: ErrorKernel[] = [\n { dx: 1, dy: 0, weight: 7 / 48 },\n { dx: 2, dy: 0, weight: 5 / 48 },\n { dx: -2, dy: 1, weight: 3 / 48 },\n { dx: -1, dy: 1, weight: 5 / 48 },\n { dx: 0, dy: 1, weight: 7 / 48 },\n { dx: 1, dy: 1, weight: 5 / 48 },\n { dx: 2, dy: 1, weight: 3 / 48 },\n { dx: -2, dy: 2, weight: 1 / 48 },\n { dx: -1, dy: 2, weight: 3 / 48 },\n { dx: 0, dy: 2, weight: 5 / 48 },\n { dx: 1, dy: 2, weight: 3 / 48 },\n { dx: 2, dy: 2, weight: 1 / 48 },\n ];\n\n return errorDiffusionDither(image, colorScheme, kernel);\n}","import type { ImageBuffer, PaletteImageBuffer } from './types';\nimport { DitherMode } from './enums';\nimport { ColorScheme } from './palettes';\nimport * as algorithms from './algorithms';\n\n/**\n * Apply dithering algorithm to image for e-paper display\n *\n * @param image - Input image buffer (RGBA format)\n * @param colorScheme - Target e-paper color scheme\n * @param mode - Dithering algorithm (default: BURKES)\n * @returns Palette-indexed image buffer\n *\n * @example\n * ```typescript\n * const dithered = ditherImage(imageBuffer, ColorScheme.BWR, DitherMode.FLOYD_STEINBERG);\n * ```\n */\nexport function ditherImage(\n image: ImageBuffer,\n colorScheme: ColorScheme,\n mode: DitherMode = DitherMode.BURKES\n): PaletteImageBuffer {\n switch (mode) {\n case DitherMode.NONE:\n return algorithms.directPaletteMap(image, colorScheme);\n case DitherMode.ORDERED:\n return algorithms.orderedDither(image, colorScheme);\n case DitherMode.FLOYD_STEINBERG:\n return algorithms.floydSteinbergDither(image, colorScheme);\n case DitherMode.ATKINSON:\n return algorithms.atkinsonDither(image, colorScheme);\n case DitherMode.STUCKI:\n return algorithms.stuckiDither(image, colorScheme);\n case DitherMode.SIERRA:\n return algorithms.sierraDither(image, colorScheme);\n case DitherMode.SIERRA_LITE:\n return algorithms.sierraLiteDither(image, colorScheme);\n case DitherMode.JARVIS_JUDICE_NINKE:\n return algorithms.jarvisJudiceNinkeDither(image, colorScheme);\n case DitherMode.BURKES:\n default:\n return algorithms.burkesDither(image, colorScheme);\n }\n}","export { ditherImage } from './core';\nexport { DitherMode } from './enums';\nexport {\n ColorScheme,\n getPalette,\n getColorCount,\n fromValue,\n} from './palettes';\nexport type { RGB, ImageBuffer, PaletteImageBuffer, ColorPalette } from './types';\n\nexport const VERSION = '0.1.0';"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opendisplay/epaper-dithering",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Dithering algorithms for e-paper/e-ink displays (JavaScript/TypeScript)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",