@thi.ng/pixel
Version:
Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution
49 lines (48 loc) • 1.3 kB
JavaScript
import { assert } from "@thi.ng/errors/assert";
import { clamp01 } from "@thi.ng/math/interval";
import { __compileFromABGR, __compileToABGR } from "../internal/codegen.js";
const __defChannel = (ch, idx, shift) => {
const num = 1 << ch.size;
const mask0 = num - 1;
const maskA = mask0 << shift >>> 0;
const invMask = ~maskA >>> 0;
const lane = ch.lane != null ? ch.lane : idx;
const int = (x) => x >>> shift & mask0;
const setInt = (src, x) => src & invMask | (x & mask0) << shift;
return {
size: ch.size,
num,
abgrShift: 24 - lane * 8 - shift,
lane,
shift,
mask0,
maskA,
int,
setInt,
float: (x) => int(x) / mask0,
setFloat: (src, x) => setInt(src, clamp01(x) * mask0)
};
};
const defIntFormat = (fmt) => {
assert(fmt.channels.length > 0, "no channel specs given");
const channels = fmt.channels.reduce(
([defs, shift], ch, i) => {
shift -= ch.size;
defs.push(__defChannel(ch, i, shift));
return [defs, shift];
},
[[], fmt.size]
)[0];
return {
__packed: true,
type: fmt.type,
size: fmt.size,
alpha: fmt.alpha || 0,
channels,
fromABGR: fmt.fromABGR || __compileFromABGR(channels),
toABGR: fmt.toABGR || __compileToABGR(channels, !!fmt.alpha)
};
};
export {
defIntFormat
};