UNPKG

@thi.ng/pixel

Version:

Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution

119 lines (118 loc) 3.06 kB
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 };