@thi.ng/pixel
Version:
Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution
44 lines (43 loc) • 1.36 kB
JavaScript
import { assert } from "@thi.ng/errors/assert";
import { Lane } from "../api.js";
import { defIntFormat } from "./int-format.js";
import { __swapLane13 } from "../internal/utils.js";
const __defIndexed = (type, size) => (palette, 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) => __argmin(x, palette),
toABGR: (x) => palette[x]
});
};
const __argmin = (p, palette) => {
let minD = Infinity;
let minArg = -1;
for (let i = 0, n = palette.length; i < n; i++) {
const d = __distBGR(p, palette[i]);
if (d < minD) {
minD = d;
minArg = i;
}
}
return minArg;
};
const __distBGR = (a, b) => Math.hypot(
(a >> 16 & 255) - (b >> 16 & 255),
(a >> 8 & 255) - (b >> 8 & 255),
(a & 255) - (b & 255)
);
const defIndexed8 = __defIndexed("u8", 8);
const defIndexed16 = __defIndexed("u16", 16);
const defIndexed32 = __defIndexed("u32", 32);
const defIndexed = (palette, isABGR = false) => palette.length <= 256 ? defIndexed8(palette, isABGR) : palette.length < 65536 ? defIndexed16(palette, isABGR) : defIndexed32(palette, isABGR);
export {
defIndexed,
defIndexed16,
defIndexed32,
defIndexed8
};