@thi.ng/pixel
Version:
Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution
119 lines (118 loc) • 3.06 kB
JavaScript
import { identity } from "@thi.ng/api/fn";
import { clamp01 } from "@thi.ng/math/interval";
import { Lane } from "../api.js";
import { __luminanceABGR } from "../internal/utils.js";
const defFloatFormat = (fmt) => {
const chan = fmt.channels;
const chanShift = chan.reduce(
(acc, ch) => (acc[ch] = 3 - ch << 3, acc),
{}
);
const res = {
...fmt,
__float: true,
size: chan.length,
shift: chanShift,
range: [0, 1],
normalized: clamp01,
fromNormalized: identity
};
if (fmt.convert) {
Object.assign(res, fmt.convert);
return res;
}
const to = (col, i) => (clamp01(col[i]) * 255 + 0.5 | 0) << chanShift[chan[i]];
const from = (col, i) => (col >>> chanShift[chan[i]] & 255) / 255;
switch (chan.length) {
case 1:
fmt.gray ? __defConvert1Gray(res) : __defConvert1(res, from, to);
break;
case 2:
fmt.gray ? __defConvert2Gray(res, from) : __defConvert2(res, from, to);
break;
case 3:
__defConvert3(res, from, to);
break;
case 4:
__defConvert4(res, from, to);
break;
}
return res;
};
const __defConvert1 = (res, from, to) => {
res.toABGR = (col) => {
let out = res.alpha ? 0 : 4278190080;
out |= to(col, 0);
return out >>> 0;
};
res.fromABGR = (col, out = []) => {
out[0] = from(col, 0);
return out;
};
};
const __defConvert1Gray = (res) => {
res.toABGR = (col) => ((clamp01(col[0]) * 255 + 0.5 | 0) * 65793 | 4278190080) >>> 0;
res.fromABGR = (col, out = []) => (out[0] = __luminanceABGR(col) / 255, out);
};
const __defConvert2 = (res, from, to) => {
res.toABGR = (col) => {
let out = res.alpha ? 0 : 4278190080;
out |= to(col, 0);
out |= to(col, 1);
return out >>> 0;
};
res.fromABGR = (col, out = []) => {
out[0] = from(col, 0);
out[1] = from(col, 1);
return out;
};
};
const __defConvert2Gray = (res, from) => {
const gray = ~~(res.channels[0] === Lane.ALPHA);
const alpha = gray ^ 1;
res.toABGR = (col) => {
let out = (clamp01(col[gray]) * 255 + 0.5 | 0) * 65793;
out |= (col[alpha] * 255 + 0.5 | 0) << 24;
return out >>> 0;
};
res.fromABGR = (col, out = []) => {
out[gray] = __luminanceABGR(col) / 255;
out[alpha] = from(col, alpha);
return out;
};
};
const __defConvert3 = (res, from, to) => {
res.toABGR = (col) => {
let out = res.alpha ? 0 : 4278190080;
out |= to(col, 0);
out |= to(col, 1);
out |= to(col, 2);
return out >>> 0;
};
res.fromABGR = (col, out = []) => {
out[0] = from(col, 0);
out[1] = from(col, 1);
out[2] = from(col, 2);
return out;
};
};
const __defConvert4 = (res, from, to) => {
res.toABGR = (col) => {
let out = res.alpha ? 0 : 4278190080;
out |= to(col, 0);
out |= to(col, 1);
out |= to(col, 2);
out |= to(col, 3);
return out >>> 0;
};
res.fromABGR = (col, out = []) => {
out[0] = from(col, 0);
out[1] = from(col, 1);
out[2] = from(col, 2);
out[3] = from(col, 3);
return out;
};
};
export {
defFloatFormat
};