Skip to content

Commit

Permalink
feat(pixel): add 8/16/32bit support for defIndexed()
Browse files Browse the repository at this point in the history
- add defIndexed8/16/32()
- update defIndexed() to decide about required bitdepth
- add/update docs strings
  • Loading branch information
postspectacular committed Dec 12, 2021
1 parent e5f564e commit b20a924
Showing 1 changed file with 41 additions and 13 deletions.
54 changes: 41 additions & 13 deletions packages/pixel/src/format/indexed.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
import type { NumericArray } from "@thi.ng/api";
import type { NumericArray, UintType } from "@thi.ng/api";
import { swapLane13 } from "@thi.ng/binary/swizzle";
import { argminN } from "@thi.ng/distance/argmin";
import { assert } from "@thi.ng/errors/assert";
import { Lane } from "../api.js";
import { defIntFormat } from "./int-format.js";

const __defIndexed =
(type: UintType, size: number) =>
(palette: NumericArray, isABGR = false) => {
const n = palette.length;
assert(n > 0 && n <= 2 ** size, `invalid palette size: ${n}`);
palette = isABGR ? palette : palette.map(swapLane13);
return defIntFormat({
type,
size,
channels: [{ size, lane: Lane.RED }],
fromABGR: (x) => argminN(x, palette, distBGR),
toABGR: (x) => palette[x],
});
};

/**
* Creates an indexed color {@link IntFormat} using the provided palette (in
* {@link ARGB8888} or {@link ABGR8888} formats, max. 256 colors).
Expand All @@ -17,18 +32,31 @@ import { defIntFormat } from "./int-format.js";
* @param palette
* @param isABGR
*/
export const defIndexed = (palette: NumericArray, isABGR = false) => {
const n = palette.length;
assert(n > 0 && n <= 256, `invalid palette size: ${n}`);
palette = isABGR ? palette : palette.map(swapLane13);
return defIntFormat({
type: "u8",
size: 8,
channels: [{ size: 8, lane: Lane.RED }],
fromABGR: (x) => argminN(x, palette, distBGR),
toABGR: (x) => palette[x],
});
};
export const defIndexed8 = __defIndexed("u8", 8);

/**
* Similar to {@link defIndexed8}, but for 16bit palette sizes and pixel buffers.
*/
export const defIndexed16 = __defIndexed("u16", 16);

/**
* Similar to {@link defIndexed8}, but for 32bit palette sizes and pixel buffers.
*/
export const defIndexed32 = __defIndexed("u32", 32);

/**
* Similar to {@link defIndexed8}, but dynamically decides about pixel buffer
* bit depth based on size of given palette.
*
* @param palette
* @param isABGR
*/
export const defIndexed = (palette: NumericArray, isABGR = false) =>
palette.length <= 0x100
? defIndexed8(palette, isABGR)
: palette.length < 0x10000
? defIndexed16(palette, isABGR)
: defIndexed32(palette, isABGR);

const distBGR = (a: number, b: number) =>
Math.hypot(
Expand Down

0 comments on commit b20a924

Please sign in to comment.