@thi.ng/pixel
Advanced tools
Comparing version 0.1.20 to 0.2.0
import type { CanvasContext, RawPixelBuffer } from "./api"; | ||
/** | ||
* Creates a canvas element of given size, obtains its 2D drawing | ||
* context and returns object of both. | ||
* context and returns object of both. If `parent` is given, the canvas | ||
* is appended to it as child. | ||
* | ||
* @param width - | ||
* @param height - | ||
* @param parent - | ||
*/ | ||
export declare const canvas2d: (width: number, height?: number) => CanvasContext; | ||
export declare const canvas2d: (width: number, height?: number, parent?: HTMLElement | undefined) => CanvasContext; | ||
/** | ||
@@ -20,3 +22,4 @@ * Accepts either an existing canvas or creates a new one of given size. | ||
* new size. If no width/height is given, the canvas will be of same | ||
* size as image. | ||
* size as image. If `parent` is given, the canvas is appended to it as | ||
* child. | ||
* | ||
@@ -26,4 +29,5 @@ * @param img - | ||
* @param height - | ||
* @param parent - | ||
*/ | ||
export declare const imageCanvas: (img: HTMLImageElement, width?: number | undefined, height?: number | undefined) => CanvasContext; | ||
export declare const imageCanvas: (img: HTMLImageElement, width?: number | undefined, height?: number | undefined, parent?: HTMLElement | undefined) => CanvasContext; | ||
/** | ||
@@ -30,0 +34,0 @@ * Async function. Loads image from given `src` URL. |
import { isNumber } from "@thi.ng/checks"; | ||
/** | ||
* Creates a canvas element of given size, obtains its 2D drawing | ||
* context and returns object of both. | ||
* context and returns object of both. If `parent` is given, the canvas | ||
* is appended to it as child. | ||
* | ||
* @param width - | ||
* @param height - | ||
* @param parent - | ||
*/ | ||
export const canvas2d = (width, height = width) => { | ||
export const canvas2d = (width, height = width, parent) => { | ||
const canvas = document.createElement("canvas"); | ||
canvas.width = width; | ||
canvas.height = height; | ||
parent && parent.appendChild(canvas); | ||
return { | ||
canvas, | ||
ctx: canvas.getContext("2d") | ||
ctx: canvas.getContext("2d"), | ||
}; | ||
@@ -43,3 +46,4 @@ }; | ||
* new size. If no width/height is given, the canvas will be of same | ||
* size as image. | ||
* size as image. If `parent` is given, the canvas is appended to it as | ||
* child. | ||
* | ||
@@ -49,7 +53,8 @@ * @param img - | ||
* @param height - | ||
* @param parent - | ||
*/ | ||
export const imageCanvas = (img, width, height = width) => { | ||
export const imageCanvas = (img, width, height = width, parent) => { | ||
const ctx = isNumber(width) | ||
? canvas2d(width, height) | ||
: canvas2d(img.width, img.height); | ||
? canvas2d(width, height, parent) | ||
: canvas2d(img.width, img.height, parent); | ||
ctx.ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); | ||
@@ -56,0 +61,0 @@ return ctx; |
@@ -6,66 +6,14 @@ # Change Log | ||
## [0.1.20](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.19...@thi.ng/pixel@0.1.20) (2020-05-14) | ||
# [0.2.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.20...@thi.ng/pixel@0.2.0) (2020-05-19) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
### Features | ||
* **pixel:** add .copy(), update .blitCanvas() ([f4b2c3e](https://github.com/thi-ng/umbrella/commit/f4b2c3e374b45bd26396e436f3e71e9d3afbc131)) | ||
* **pixel:** update canvas2d(), imageCanvas() ([65929a2](https://github.com/thi-ng/umbrella/commit/65929a2ee6be9915e14bf69389520739073af5ee)) | ||
## [0.1.19](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.18...@thi.ng/pixel@0.1.19) (2020-05-03) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.18](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.17...@thi.ng/pixel@0.1.18) (2020-04-28) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.17](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.16...@thi.ng/pixel@0.1.17) (2020-04-27) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.16](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.15...@thi.ng/pixel@0.1.16) (2020-04-11) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.15](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.14...@thi.ng/pixel@0.1.15) (2020-04-06) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.14](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.13...@thi.ng/pixel@0.1.14) (2020-04-05) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.13](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.12...@thi.ng/pixel@0.1.13) (2020-03-28) | ||
**Note:** Version bump only for package @thi.ng/pixel | ||
## [0.1.4](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@0.1.3...@thi.ng/pixel@0.1.4) (2019-09-21) | ||
@@ -72,0 +20,0 @@ |
@@ -27,9 +27,10 @@ 'use strict'; | ||
const canvas2d = (width, height = width) => { | ||
const canvas2d = (width, height = width, parent) => { | ||
const canvas = document.createElement("canvas"); | ||
canvas.width = width; | ||
canvas.height = height; | ||
parent && parent.appendChild(canvas); | ||
return { | ||
canvas, | ||
ctx: canvas.getContext("2d") | ||
ctx: canvas.getContext("2d"), | ||
}; | ||
@@ -58,6 +59,6 @@ }; | ||
} | ||
const imageCanvas = (img, width, height = width) => { | ||
const imageCanvas = (img, width, height = width, parent) => { | ||
const ctx = checks.isNumber(width) | ||
? canvas2d(width, height) | ||
: canvas2d(img.width, img.height); | ||
? canvas2d(width, height, parent) | ||
: canvas2d(img.width, img.height, parent); | ||
ctx.ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height); | ||
@@ -328,3 +329,3 @@ return ctx; | ||
[api.Type.U16]: Uint16Array, | ||
[api.Type.U32]: Uint32Array | ||
[api.Type.U32]: Uint32Array, | ||
}; | ||
@@ -358,2 +359,7 @@ class PackedBuffer { | ||
} | ||
copy() { | ||
const dest = new PackedBuffer(this.width, this.height, this.format); | ||
dest.pixels.set(this.pixels); | ||
return dest; | ||
} | ||
getAt(x, y) { | ||
@@ -433,2 +439,3 @@ return x >= 0 && x < this.width && y >= 0 && y < this.height | ||
ctx.putImageData(idata, x, y); | ||
return canvas; | ||
} | ||
@@ -441,3 +448,3 @@ getRegion(x, y, width, height, fmt) { | ||
w, | ||
h | ||
h, | ||
}); | ||
@@ -452,3 +459,3 @@ } | ||
fromABGR: compileGrayFromABGR(chan.size), | ||
toABGR: compileGrayToABGR(chan.size) | ||
toABGR: compileGrayToABGR(chan.size), | ||
}); | ||
@@ -455,0 +462,0 @@ const src = this.pixels; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/checks"),require("@thi.ng/api"),require("@thi.ng/math"),require("@thi.ng/porter-duff")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/checks","@thi.ng/api","@thi.ng/math","@thi.ng/porter-duff"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.pixel={}),e.thi.ng.checks,e.thi.ng.api,e.thi.ng.math,e.thi.ng.porterDuff)}(this,(function(e,t,n,i,s){"use strict";var a,r,h;(a=e.Lane||(e.Lane={}))[a.ALPHA=0]="ALPHA",a[a.RED=3]="RED",a[a.GREEN=2]="GREEN",a[a.BLUE=1]="BLUE",(r=e.Wrap||(e.Wrap={}))[r.NONE=0]="NONE",r[r.U=1]="U",r[r.V=2]="V",r[r.UV=3]="UV",(h=e.Filter||(e.Filter={}))[h.NEAREST=0]="NEAREST",h[h.LINEAR=1]="LINEAR";const l=(e,t=e)=>{const n=document.createElement("canvas");return n.width=e,n.height=t,{canvas:n,ctx:n.getContext("2d")}};function o(e,n){let i,s;if(t.isNumber(e)){const t=l(e,n);i=t.canvas,s=t.ctx}else i=e,s=i.getContext("2d");const a=s.getImageData(0,0,i.width,i.height);return{canvas:i,ctx:s,img:a,pixels:new Uint32Array(a.data.buffer)}}const c=(e,n,i=n)=>{const s=t.isNumber(n)?l(n,i):l(e.width,e.height);return s.ctx.drawImage(e,0,0,s.canvas.width,s.canvas.height),s},p=(e,t,i,s=1)=>n.assert(e.length>=t*i*s,"pixel buffer too small"),f=(e,t)=>{const i=e.channels[t];return n.assert(null!=i,"invalid channel ID: "+t),i},m=e=>(29*(e>>>16&255)+150*(e>>>8&255)+76*(255&e))/255,u=(e,t,n,s,a,r,h=0,l=0)=>(e<0&&(n+=e,h-=e,e=0),t<0&&(s+=t,l-=t,t=0),[e,t,i.clamp(n,0,a-e),i.clamp(s,0,r-t),h,l]),A=(e,t,n={})=>{let i,s,a,r,h,l,o=e.width,c=t.width;return[i,s,h,l]=u(n.sx||0,n.sy||0,n.w||o,n.h||e.height,o,e.height),[a,r,h,l,i,s]=u(n.dx||0,n.dy||0,h,l,c,t.height,i,s),{sx:i,sy:s,dx:a,dy:r,rw:h,rh:l}},R=(e,t,n)=>{for(let i=e.length;--i>=0;)e[i]=n(e[i],t)},g=(e,t,n,i)=>{for(let s=e.length;--s>=0;)e[s]=i(e[s],n(t[s]))},z=(e,t,n,i,s)=>{const a=~s;for(let r=e.length;--r>=0;)e[r]=e[r]&a|n(i(t[r]))&s},d=(e,t,n)=>{const i=t.fromABGR,s=t.toABGR;for(let t=e.length;--t>=0;)e[t]=i(n(s(e[t])))},y=(e,t)=>t>0?`(${e} << ${t})`:t<0?`(${e} >>> ${-t})`:""+e,G=(e,t)=>y(e,-t),x=e=>"0x"+e.toString(16),L=e=>{const t=(1<<e)-1;return new Function("luma",`return (x) => ${G("luma(x)",8-e)} & ${t};`)(m)},B=e=>{let t;if(8!==e){const n=(1<<e)-1;t=`(((x & ${n}) * ${255/n}) | 0)`}else t="x";return new Function("x",`return 0xff000000 | (${t} * 0x010101);`)},E=e=>new Function("x","return ("+e.map(e=>{const t=e.abgrShift+(8-e.size);return`(${G("x",t)} & ${x(e.maskA)})`}).join(" | ")+") >>> 0;"),w=(e,t)=>{const n=e.map(e=>{if(8!==e.size){const t=e.mask0,n=255/t,i=G("x",e.shift);return y(`((${i} & ${t}) * ${n})`,24-8*e.lane)}return y(`(x & ${x(e.maskA)})`,e.abgrShift)}).join(" | ");return new Function("x",`return (${t?"":"0xff000000 | "}${n}) >>> 0;`)},U=e=>{n.assert(e.channels.length>0,"no channel specs given");const t=e.channels.reduce(([e,t],n,s)=>(t-=n.size,e.push(((e,t,n)=>{const s=(1<<e.size)-1,a=s<<n>>>0,r=~a>>>0,h=null!=e.lane?e.lane:t,l=e=>e>>>n&s,o=(e,t)=>e&r|(t&s)<<n;return{size:e.size,abgrShift:24-8*h-n,lane:h,shift:n,mask0:s,maskA:a,int:l,setInt:o,float:e=>l(e)/s,setFloat:(e,t)=>o(e,i.clamp01(t)*s)}})(n,s,t)),[e,t]),[[],e.size])[0];return{__compiled:!0,type:e.type,size:e.size,alpha:e.alpha||0,channels:t,fromABGR:e.fromABGR||E(t),toABGR:e.toABGR||w(t,!!e.alpha)}},T=U({type:n.Type.U8,size:8,alpha:8,channels:[{size:8,lane:0}]}),D=U({type:n.Type.U8,size:8,channels:[{size:8,lane:e.Lane.RED}],fromABGR:e=>m(e),toABGR:e=>4278190080|65793*(255&e)}),N=U({type:n.Type.U16,size:16,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.RED}],fromABGR:e=>m(e)|e>>>16&65280,toABGR:e=>(65280&e)<<16|65793*(255&e)}),v=U({type:n.Type.U16,size:16,channels:[{size:16,lane:e.Lane.RED}],fromABGR:e=>257*(m(e)+.5|0),toABGR:e=>4278190080|65793*(e>>>8)}),b=U({type:n.Type.U32,size:32,channels:[{size:8,lane:e.Lane.ALPHA},{size:16,lane:e.Lane.RED}],fromABGR:e=>257*(m(e)+.5|0)|257*(e>>>8&16711680),toABGR:e=>4278190080&e|65793*(e>>>8&255)}),P=U({type:n.Type.U16,size:16,channels:[{size:5,lane:e.Lane.RED},{size:6,lane:e.Lane.GREEN},{size:5,lane:e.Lane.BLUE}]}),$=U({type:n.Type.U16,size:16,alpha:1,channels:[{size:1,lane:e.Lane.ALPHA},{size:5,lane:e.Lane.RED},{size:5,lane:e.Lane.GREEN},{size:5,lane:e.Lane.BLUE}]}),I=U({type:n.Type.U16,size:16,alpha:4,channels:[{size:4,lane:e.Lane.ALPHA},{size:4,lane:e.Lane.RED},{size:4,lane:e.Lane.GREEN},{size:4,lane:e.Lane.BLUE}]}),C=U({type:n.Type.U32,size:24,channels:[{size:8,lane:e.Lane.RED},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.BLUE}]}),k=U({type:n.Type.U32,size:32,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.RED},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.BLUE}]}),F=U({type:n.Type.U32,size:24,channels:[{size:8,lane:e.Lane.BLUE},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.RED}],fromABGR:e=>16777215&e,toABGR:e=>4278190080|e}),H=U({type:n.Type.U32,size:32,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.BLUE},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.RED}],fromABGR:e=>e,toABGR:e=>e}),S={[n.Type.U8]:Uint8Array,[n.Type.U16]:Uint16Array,[n.Type.U32]:Uint32Array};class _{constructor(e,t,n,i){this.width=e,this.height=t,this.format=n.__compiled?n:U(n),this.pixels=i||new S[n.type](e*t)}static fromImage(e,t,n,i=n){const s=c(e,n,i),a=s.canvas.width,r=s.canvas.height,h=new Uint32Array(s.ctx.getImageData(0,0,a,r).data.buffer),l=new S[t.type](a*r),o=t.fromABGR;for(let e=l.length;--e>=0;)l[e]=o(h[e]);return new _(a,r,t,l)}static fromCanvas(e){return new _(e.width,e.height,H,o(e).pixels)}as(e){return this.getRegion(0,0,this.width,this.height,e)}getAt(e,t){return e>=0&&e<this.width&&t>=0&&t<this.height?this.pixels[(0|e)+(0|t)*this.width]:0}setAt(e,t,n){return e>=0&&e<this.width&&t>=0&&t<this.height&&(this.pixels[(0|e)+(0|t)*this.width]=n),this}getChannelAt(e,t,n,i=!1){const s=f(this.format,n),a=this.getAt(e,t);return i?s.float(a):s.int(a)}setChannelAt(e,t,n,i,s=!1){const a=f(this.format,n),r=this.getAt(e,t);return s?a.setFloat(r,i):a.setInt(r,i),this}blend(e,t,n){let i=this.width,s=t.width;const{sx:a,sy:r,dx:h,dy:l,rw:o,rh:c}=A(this,t,n);if(o<1||c<1)return t;const p=this.pixels,f=t.pixels,m=this.format.toABGR,u=t.format.toABGR,R=t.format.fromABGR;for(let t=(0|a)+(0|r)*i,n=(0|h)+(0|l)*s,A=0;A<c;A++,t+=i,n+=s)for(let i=0;i<o;i++)f[n+i]=R(e(m(p[t+i]),u(f[n+i])));return t}blit(e,t){let n=this.width,i=e.width;const{sx:s,sy:a,dx:r,dy:h,rw:l,rh:o}=A(this,e,t);if(l<1||o<1)return e;const c=this.pixels,p=e.pixels,f=this.format.toABGR,m=e.format.fromABGR,u=this.format!==e.format?(e,t)=>{for(let n=0;n<l;n++)p[t+n]=m(f(c[e+n]))}:(e,t)=>p.set(c.subarray(e,e+l),t);for(let e=(0|s)+(0|a)*n,t=(0|r)+(0|h)*i,l=0;l<o;l++,e+=n,t+=i)u(e,t);return e}blitCanvas(e,t=0,n=0){const i=e.getContext("2d"),s=i.getImageData(t,n,this.width,this.height),a=new Uint32Array(s.data.buffer),r=this.pixels,h=this.format.toABGR;for(let e=a.length;--e>=0;)a[e]=h(r[e]);i.putImageData(s,t,n)}getRegion(e,t,n,i,s){const[a,r,h,l]=u(e,t,n,i,this.width,this.height);return this.blit(new _(h,l,s||this.format),{sx:a,sy:r,w:h,h:l})}getChannel(t){const i=f(this.format,t),s=new _(this.width,this.height,{type:i.size>16?n.Type.U32:i.size>8?n.Type.U16:n.Type.U8,size:i.size,channels:[{size:i.size,lane:e.Lane.RED}],fromABGR:L(i.size),toABGR:B(i.size)}),a=this.pixels,r=s.pixels,h=i.int;for(let e=a.length;--e>=0;)r[e]=h(a[e]);return s}setChannel(e,n){const i=f(this.format,e),s=this.pixels,a=i.setInt;if(t.isNumber(n))R(s,n,a);else{const e=n.pixels,t=n.format.channels[0];p(e,this.width,this.height),i.size===t.size?g(s,e,t.int,a):z(s,e,this.format.fromABGR,n.format.toABGR,i.maskA)}return this}invert(){const e=this.pixels,t=this.format,n=Math.pow(2,t.size-t.alpha)-1;for(let t=e.length;--t>=0;)e[t]^=n;return this}premultiply(){return d(this.pixels,this.format,s.premultiplyInt),this}postmultiply(){return d(this.pixels,this.format,s.postmultiplyInt),this}isPremultiplied(){const e=this.pixels,t=this.format.toABGR;for(let n=e.length;--n>=0;)if(!s.isPremultipliedInt(t(e[n])))return!1;return!0}forEach(e){const t=this.pixels;for(let n=t.length;--n>=0;)t[n]=e(t[n]);return this}}e.ABGR8888=H,e.ALPHA8=T,e.ARGB1555=$,e.ARGB4444=I,e.ARGB8888=k,e.BGR888=F,e.GRAY16=v,e.GRAY8=D,e.GRAY_ALPHA16=b,e.GRAY_ALPHA8=N,e.PackedBuffer=_,e.RGB565=P,e.RGB888=C,e.buffer=(e,t,n,i)=>new _(e,t,n,i),e.canvas2d=l,e.canvasPixels=o,e.clampRegion=u,e.compileFromABGR=E,e.compileGrayFromABGR=L,e.compileGrayToABGR=B,e.compileToABGR=w,e.defPackedFormat=U,e.ensureChannel=f,e.ensureSize=p,e.imageCanvas=c,e.imagePromise=async e=>{const t=new Image;return t.src=e,await t.decode(),t},e.luminanceABGR=m,e.prepRegions=A,e.setChannelConvert=z,e.setChannelSame=g,e.setChannelUni=R,e.transformABGR=d,Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@thi.ng/checks"),require("@thi.ng/api"),require("@thi.ng/math"),require("@thi.ng/porter-duff")):"function"==typeof define&&define.amd?define(["exports","@thi.ng/checks","@thi.ng/api","@thi.ng/math","@thi.ng/porter-duff"],t):t(((e=e||self).thi=e.thi||{},e.thi.ng=e.thi.ng||{},e.thi.ng.pixel={}),e.thi.ng.checks,e.thi.ng.api,e.thi.ng.math,e.thi.ng.porterDuff)}(this,(function(e,t,n,i,s){"use strict";var a,r,h;(a=e.Lane||(e.Lane={}))[a.ALPHA=0]="ALPHA",a[a.RED=3]="RED",a[a.GREEN=2]="GREEN",a[a.BLUE=1]="BLUE",(r=e.Wrap||(e.Wrap={}))[r.NONE=0]="NONE",r[r.U=1]="U",r[r.V=2]="V",r[r.UV=3]="UV",(h=e.Filter||(e.Filter={}))[h.NEAREST=0]="NEAREST",h[h.LINEAR=1]="LINEAR";const l=(e,t=e,n)=>{const i=document.createElement("canvas");return i.width=e,i.height=t,n&&n.appendChild(i),{canvas:i,ctx:i.getContext("2d")}};function o(e,n){let i,s;if(t.isNumber(e)){const t=l(e,n);i=t.canvas,s=t.ctx}else i=e,s=i.getContext("2d");const a=s.getImageData(0,0,i.width,i.height);return{canvas:i,ctx:s,img:a,pixels:new Uint32Array(a.data.buffer)}}const p=(e,n,i=n,s)=>{const a=t.isNumber(n)?l(n,i,s):l(e.width,e.height,s);return a.ctx.drawImage(e,0,0,a.canvas.width,a.canvas.height),a},c=(e,t,i,s=1)=>n.assert(e.length>=t*i*s,"pixel buffer too small"),f=(e,t)=>{const i=e.channels[t];return n.assert(null!=i,"invalid channel ID: "+t),i},m=e=>(29*(e>>>16&255)+150*(e>>>8&255)+76*(255&e))/255,u=(e,t,n,s,a,r,h=0,l=0)=>(e<0&&(n+=e,h-=e,e=0),t<0&&(s+=t,l-=t,t=0),[e,t,i.clamp(n,0,a-e),i.clamp(s,0,r-t),h,l]),A=(e,t,n={})=>{let i,s,a,r,h,l,o=e.width,p=t.width;return[i,s,h,l]=u(n.sx||0,n.sy||0,n.w||o,n.h||e.height,o,e.height),[a,r,h,l,i,s]=u(n.dx||0,n.dy||0,h,l,p,t.height,i,s),{sx:i,sy:s,dx:a,dy:r,rw:h,rh:l}},R=(e,t,n)=>{for(let i=e.length;--i>=0;)e[i]=n(e[i],t)},g=(e,t,n,i)=>{for(let s=e.length;--s>=0;)e[s]=i(e[s],n(t[s]))},d=(e,t,n,i,s)=>{const a=~s;for(let r=e.length;--r>=0;)e[r]=e[r]&a|n(i(t[r]))&s},z=(e,t,n)=>{const i=t.fromABGR,s=t.toABGR;for(let t=e.length;--t>=0;)e[t]=i(n(s(e[t])))},y=(e,t)=>t>0?`(${e} << ${t})`:t<0?`(${e} >>> ${-t})`:""+e,x=(e,t)=>y(e,-t),G=e=>"0x"+e.toString(16),L=e=>{const t=(1<<e)-1;return new Function("luma",`return (x) => ${x("luma(x)",8-e)} & ${t};`)(m)},B=e=>{let t;if(8!==e){const n=(1<<e)-1;t=`(((x & ${n}) * ${255/n}) | 0)`}else t="x";return new Function("x",`return 0xff000000 | (${t} * 0x010101);`)},E=e=>new Function("x","return ("+e.map(e=>{const t=e.abgrShift+(8-e.size);return`(${x("x",t)} & ${G(e.maskA)})`}).join(" | ")+") >>> 0;"),w=(e,t)=>{const n=e.map(e=>{if(8!==e.size){const t=e.mask0,n=255/t,i=x("x",e.shift);return y(`((${i} & ${t}) * ${n})`,24-8*e.lane)}return y(`(x & ${G(e.maskA)})`,e.abgrShift)}).join(" | ");return new Function("x",`return (${t?"":"0xff000000 | "}${n}) >>> 0;`)},U=e=>{n.assert(e.channels.length>0,"no channel specs given");const t=e.channels.reduce(([e,t],n,s)=>(t-=n.size,e.push(((e,t,n)=>{const s=(1<<e.size)-1,a=s<<n>>>0,r=~a>>>0,h=null!=e.lane?e.lane:t,l=e=>e>>>n&s,o=(e,t)=>e&r|(t&s)<<n;return{size:e.size,abgrShift:24-8*h-n,lane:h,shift:n,mask0:s,maskA:a,int:l,setInt:o,float:e=>l(e)/s,setFloat:(e,t)=>o(e,i.clamp01(t)*s)}})(n,s,t)),[e,t]),[[],e.size])[0];return{__compiled:!0,type:e.type,size:e.size,alpha:e.alpha||0,channels:t,fromABGR:e.fromABGR||E(t),toABGR:e.toABGR||w(t,!!e.alpha)}},T=U({type:n.Type.U8,size:8,alpha:8,channels:[{size:8,lane:0}]}),D=U({type:n.Type.U8,size:8,channels:[{size:8,lane:e.Lane.RED}],fromABGR:e=>m(e),toABGR:e=>4278190080|65793*(255&e)}),N=U({type:n.Type.U16,size:16,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.RED}],fromABGR:e=>m(e)|e>>>16&65280,toABGR:e=>(65280&e)<<16|65793*(255&e)}),v=U({type:n.Type.U16,size:16,channels:[{size:16,lane:e.Lane.RED}],fromABGR:e=>257*(m(e)+.5|0),toABGR:e=>4278190080|65793*(e>>>8)}),b=U({type:n.Type.U32,size:32,channels:[{size:8,lane:e.Lane.ALPHA},{size:16,lane:e.Lane.RED}],fromABGR:e=>257*(m(e)+.5|0)|257*(e>>>8&16711680),toABGR:e=>4278190080&e|65793*(e>>>8&255)}),P=U({type:n.Type.U16,size:16,channels:[{size:5,lane:e.Lane.RED},{size:6,lane:e.Lane.GREEN},{size:5,lane:e.Lane.BLUE}]}),$=U({type:n.Type.U16,size:16,alpha:1,channels:[{size:1,lane:e.Lane.ALPHA},{size:5,lane:e.Lane.RED},{size:5,lane:e.Lane.GREEN},{size:5,lane:e.Lane.BLUE}]}),C=U({type:n.Type.U16,size:16,alpha:4,channels:[{size:4,lane:e.Lane.ALPHA},{size:4,lane:e.Lane.RED},{size:4,lane:e.Lane.GREEN},{size:4,lane:e.Lane.BLUE}]}),I=U({type:n.Type.U32,size:24,channels:[{size:8,lane:e.Lane.RED},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.BLUE}]}),k=U({type:n.Type.U32,size:32,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.RED},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.BLUE}]}),F=U({type:n.Type.U32,size:24,channels:[{size:8,lane:e.Lane.BLUE},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.RED}],fromABGR:e=>16777215&e,toABGR:e=>4278190080|e}),H=U({type:n.Type.U32,size:32,alpha:8,channels:[{size:8,lane:e.Lane.ALPHA},{size:8,lane:e.Lane.BLUE},{size:8,lane:e.Lane.GREEN},{size:8,lane:e.Lane.RED}],fromABGR:e=>e,toABGR:e=>e}),S={[n.Type.U8]:Uint8Array,[n.Type.U16]:Uint16Array,[n.Type.U32]:Uint32Array};class _{constructor(e,t,n,i){this.width=e,this.height=t,this.format=n.__compiled?n:U(n),this.pixels=i||new S[n.type](e*t)}static fromImage(e,t,n,i=n){const s=p(e,n,i),a=s.canvas.width,r=s.canvas.height,h=new Uint32Array(s.ctx.getImageData(0,0,a,r).data.buffer),l=new S[t.type](a*r),o=t.fromABGR;for(let e=l.length;--e>=0;)l[e]=o(h[e]);return new _(a,r,t,l)}static fromCanvas(e){return new _(e.width,e.height,H,o(e).pixels)}as(e){return this.getRegion(0,0,this.width,this.height,e)}copy(){const e=new _(this.width,this.height,this.format);return e.pixels.set(this.pixels),e}getAt(e,t){return e>=0&&e<this.width&&t>=0&&t<this.height?this.pixels[(0|e)+(0|t)*this.width]:0}setAt(e,t,n){return e>=0&&e<this.width&&t>=0&&t<this.height&&(this.pixels[(0|e)+(0|t)*this.width]=n),this}getChannelAt(e,t,n,i=!1){const s=f(this.format,n),a=this.getAt(e,t);return i?s.float(a):s.int(a)}setChannelAt(e,t,n,i,s=!1){const a=f(this.format,n),r=this.getAt(e,t);return s?a.setFloat(r,i):a.setInt(r,i),this}blend(e,t,n){let i=this.width,s=t.width;const{sx:a,sy:r,dx:h,dy:l,rw:o,rh:p}=A(this,t,n);if(o<1||p<1)return t;const c=this.pixels,f=t.pixels,m=this.format.toABGR,u=t.format.toABGR,R=t.format.fromABGR;for(let t=(0|a)+(0|r)*i,n=(0|h)+(0|l)*s,A=0;A<p;A++,t+=i,n+=s)for(let i=0;i<o;i++)f[n+i]=R(e(m(c[t+i]),u(f[n+i])));return t}blit(e,t){let n=this.width,i=e.width;const{sx:s,sy:a,dx:r,dy:h,rw:l,rh:o}=A(this,e,t);if(l<1||o<1)return e;const p=this.pixels,c=e.pixels,f=this.format.toABGR,m=e.format.fromABGR,u=this.format!==e.format?(e,t)=>{for(let n=0;n<l;n++)c[t+n]=m(f(p[e+n]))}:(e,t)=>c.set(p.subarray(e,e+l),t);for(let e=(0|s)+(0|a)*n,t=(0|r)+(0|h)*i,l=0;l<o;l++,e+=n,t+=i)u(e,t);return e}blitCanvas(e,t=0,n=0){const i=e.getContext("2d"),s=i.getImageData(t,n,this.width,this.height),a=new Uint32Array(s.data.buffer),r=this.pixels,h=this.format.toABGR;for(let e=a.length;--e>=0;)a[e]=h(r[e]);return i.putImageData(s,t,n),e}getRegion(e,t,n,i,s){const[a,r,h,l]=u(e,t,n,i,this.width,this.height);return this.blit(new _(h,l,s||this.format),{sx:a,sy:r,w:h,h:l})}getChannel(t){const i=f(this.format,t),s=new _(this.width,this.height,{type:i.size>16?n.Type.U32:i.size>8?n.Type.U16:n.Type.U8,size:i.size,channels:[{size:i.size,lane:e.Lane.RED}],fromABGR:L(i.size),toABGR:B(i.size)}),a=this.pixels,r=s.pixels,h=i.int;for(let e=a.length;--e>=0;)r[e]=h(a[e]);return s}setChannel(e,n){const i=f(this.format,e),s=this.pixels,a=i.setInt;if(t.isNumber(n))R(s,n,a);else{const e=n.pixels,t=n.format.channels[0];c(e,this.width,this.height),i.size===t.size?g(s,e,t.int,a):d(s,e,this.format.fromABGR,n.format.toABGR,i.maskA)}return this}invert(){const e=this.pixels,t=this.format,n=Math.pow(2,t.size-t.alpha)-1;for(let t=e.length;--t>=0;)e[t]^=n;return this}premultiply(){return z(this.pixels,this.format,s.premultiplyInt),this}postmultiply(){return z(this.pixels,this.format,s.postmultiplyInt),this}isPremultiplied(){const e=this.pixels,t=this.format.toABGR;for(let n=e.length;--n>=0;)if(!s.isPremultipliedInt(t(e[n])))return!1;return!0}forEach(e){const t=this.pixels;for(let n=t.length;--n>=0;)t[n]=e(t[n]);return this}}e.ABGR8888=H,e.ALPHA8=T,e.ARGB1555=$,e.ARGB4444=C,e.ARGB8888=k,e.BGR888=F,e.GRAY16=v,e.GRAY8=D,e.GRAY_ALPHA16=b,e.GRAY_ALPHA8=N,e.PackedBuffer=_,e.RGB565=P,e.RGB888=I,e.buffer=(e,t,n,i)=>new _(e,t,n,i),e.canvas2d=l,e.canvasPixels=o,e.clampRegion=u,e.compileFromABGR=E,e.compileGrayFromABGR=L,e.compileGrayToABGR=B,e.compileToABGR=w,e.defPackedFormat=U,e.ensureChannel=f,e.ensureSize=c,e.imageCanvas=p,e.imagePromise=async e=>{const t=new Image;return t.src=e,await t.decode(),t},e.luminanceABGR=m,e.prepRegions=A,e.setChannelConvert=d,e.setChannelSame=g,e.setChannelUni=R,e.transformABGR=z,Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "@thi.ng/pixel", | ||
"version": "0.1.20", | ||
"version": "0.2.0", | ||
"description": "Typed array backed, packed pixel buffer w/ customizable formats, blitting, conversions", | ||
@@ -79,3 +79,3 @@ "module": "./index.js", | ||
}, | ||
"gitHead": "97c301379d830c1982c364cfbec8766ff14f73f5" | ||
"gitHead": "de57ac07679b4db5174771f740275eb93282b87e" | ||
} |
@@ -12,2 +12,3 @@ import { Fn, UIntArray } from "@thi.ng/api"; | ||
as(fmt: PackedFormat): PackedBuffer; | ||
copy(): PackedBuffer; | ||
getAt(x: number, y: number): number; | ||
@@ -19,3 +20,3 @@ setAt(x: number, y: number, col: number): this; | ||
blit(dest: PackedBuffer, opts?: Partial<BlitOpts>): PackedBuffer; | ||
blitCanvas(canvas: HTMLCanvasElement, x?: number, y?: number): void; | ||
blitCanvas(canvas: HTMLCanvasElement, x?: number, y?: number): HTMLCanvasElement; | ||
getRegion(x: number, y: number, width: number, height: number, fmt?: PackedFormat): PackedBuffer; | ||
@@ -22,0 +23,0 @@ getChannel(id: number): PackedBuffer; |
import { Type } from "@thi.ng/api"; | ||
import { isNumber } from "@thi.ng/checks"; | ||
import { isPremultipliedInt, postmultiplyInt, premultiplyInt } from "@thi.ng/porter-duff"; | ||
import { Lane } from "./api"; | ||
import { isPremultipliedInt, postmultiplyInt, premultiplyInt, } from "@thi.ng/porter-duff"; | ||
import { Lane, } from "./api"; | ||
import { canvasPixels, imageCanvas } from "./canvas"; | ||
import { compileGrayFromABGR, compileGrayToABGR } from "./codegen"; | ||
import { ABGR8888, defPackedFormat } from "./format"; | ||
import { clampRegion, ensureChannel, ensureSize, prepRegions, setChannelConvert, setChannelSame, setChannelUni, transformABGR } from "./utils"; | ||
import { clampRegion, ensureChannel, ensureSize, prepRegions, setChannelConvert, setChannelSame, setChannelUni, transformABGR, } from "./utils"; | ||
const CTORS = { | ||
[Type.U8]: Uint8Array, | ||
[Type.U16]: Uint16Array, | ||
[Type.U32]: Uint32Array | ||
[Type.U32]: Uint32Array, | ||
}; | ||
@@ -41,2 +41,7 @@ export class PackedBuffer { | ||
} | ||
copy() { | ||
const dest = new PackedBuffer(this.width, this.height, this.format); | ||
dest.pixels.set(this.pixels); | ||
return dest; | ||
} | ||
getAt(x, y) { | ||
@@ -116,2 +121,3 @@ return x >= 0 && x < this.width && y >= 0 && y < this.height | ||
ctx.putImageData(idata, x, y); | ||
return canvas; | ||
} | ||
@@ -124,3 +130,3 @@ getRegion(x, y, width, height, fmt) { | ||
w, | ||
h | ||
h, | ||
}); | ||
@@ -135,3 +141,3 @@ } | ||
fromABGR: compileGrayFromABGR(chan.size), | ||
toABGR: compileGrayToABGR(chan.size) | ||
toABGR: compileGrayToABGR(chan.size), | ||
}); | ||
@@ -138,0 +144,0 @@ const src = this.pixels; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
134837
1531