@thi.ng/pixel
Advanced tools
Comparing version 3.0.0 to 3.1.0
@@ -165,2 +165,4 @@ import type { FloatArray, Fn, Fn2, Fn3, FnN, FnU2, IGrid2D, IObjectOf, NumericArray, TypedArray, UintType } from "@thi.ng/api"; | ||
export interface IPixelBuffer<T extends TypedArray = TypedArray, P = any> extends IGrid2D<T, P> { | ||
readonly width: number; | ||
readonly height: number; | ||
readonly format: IABGRConvert<any>; | ||
@@ -167,0 +169,0 @@ /** |
@@ -6,2 +6,13 @@ # Change Log | ||
# [3.1.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@3.0.0...@thi.ng/pixel@3.1.0) (2021-11-10) | ||
### Features | ||
* **pixel:** add IGrid2D impls, update ctors ([3ac0327](https://github.com/thi-ng/umbrella/commit/3ac032784d35ff180451550f976abd563c0928ef)) | ||
# [3.0.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/pixel@2.2.0...@thi.ng/pixel@3.0.0) (2021-11-04) | ||
@@ -8,0 +19,0 @@ |
@@ -77,3 +77,3 @@ import { isFunction } from "@thi.ng/checks/is-function"; | ||
assert(strideX >= 1 && strideY >= 1, `illegal stride: ${sampleStride}`); | ||
const { width, height, stride: srcStride, rowStride } = src; | ||
const { size: [width, height], stride: [srcStride, rowStride], } = src; | ||
const dwidth = Math.floor(width / strideX); | ||
@@ -157,3 +157,3 @@ const dheight = Math.floor(height / strideY); | ||
"const { min, max } = Math;", | ||
"const { data: pix, stride, rowStride } = src;", | ||
"const { data: pix, stride: [stride, rowStride] } = src;", | ||
"const maxX = (src.width - 1) * stride;", | ||
@@ -179,3 +179,3 @@ "const maxY = (src.height - 1) * rowStride;", | ||
return (src) => { | ||
const { data, rowStride, stride } = src; | ||
const { data, stride: [stride, rowStride], } = src; | ||
const x0 = -(w >> 1) * stride; | ||
@@ -182,0 +182,0 @@ const x1 = -x0 + (w & 1 ? stride : 0); |
@@ -20,3 +20,3 @@ import { kmeans } from "@thi.ng/k-means/kmeans"; | ||
const filter = opts.filter || (() => true); | ||
for (let i = 0, j = 0, s = img.stride; i < n; i++, j += s) { | ||
for (let i = 0, j = 0, s = img.stride[0]; i < n; i++, j += s) { | ||
const p = img.data.subarray(j, j + s); | ||
@@ -23,0 +23,0 @@ if (filter(p, i)) |
@@ -12,4 +12,4 @@ import type { Fn2, ICopy, IEmpty, NumericArray } from "@thi.ng/api"; | ||
*/ | ||
export declare function floatBuffer(w: number, h: number, fmt: FloatFormat | FloatFormatSpec, data?: Float32Array): FloatBuffer; | ||
export declare function floatBuffer(src: IntBuffer, fmt: FloatFormat | FloatFormatSpec): FloatBuffer; | ||
export declare function floatBuffer(w: number, h: number, fmt?: FloatFormat | FloatFormatSpec, data?: Float32Array): FloatBuffer; | ||
export declare function floatBuffer(src: IntBuffer, fmt?: FloatFormat | FloatFormatSpec): FloatBuffer; | ||
/** | ||
@@ -25,23 +25,29 @@ * Creates a new `FloatBuffer` from given {@link IntBuffer} and using | ||
*/ | ||
export declare const floatBufferFromInt: (src: IntBuffer, fmt: FloatFormat | FloatFormatSpec) => FloatBuffer; | ||
export declare const floatBufferFromImage: (img: HTMLImageElement, fmt?: FloatFormat | FloatFormatSpec, width?: number | undefined, height?: number | undefined) => FloatBuffer; | ||
export declare const floatBufferFromCanvas: (canvas: HTMLCanvasElement, fmt?: FloatFormat) => FloatBuffer; | ||
export declare const floatBufferFromInt: (src: IntBuffer, fmt?: FloatFormatSpec | FloatFormat | undefined) => FloatBuffer; | ||
export declare const floatBufferFromImage: (img: HTMLImageElement, fmt?: FloatFormatSpec | FloatFormat | undefined, width?: number | undefined, height?: number | undefined) => FloatBuffer; | ||
export declare const floatBufferFromCanvas: (canvas: HTMLCanvasElement, fmt?: FloatFormat | undefined) => FloatBuffer; | ||
export declare class FloatBuffer implements IPixelBuffer<Float32Array, NumericArray>, IToImageData, IResizable<FloatBuffer, FloatSampler>, IBlend<FloatBuffer, BlendFnFloat>, IBlit<FloatBuffer>, IInvert<FloatBuffer>, ICopy<FloatBuffer>, IEmpty<FloatBuffer> { | ||
readonly width: number; | ||
readonly height: number; | ||
readonly stride: number; | ||
readonly rowStride: number; | ||
readonly size: [number, number]; | ||
readonly stride: [number, number]; | ||
readonly data: Float32Array; | ||
readonly format: FloatFormat; | ||
protected __empty: NumericArray; | ||
constructor(w: number, h: number, fmt: FloatFormat | FloatFormatSpec, data?: Float32Array); | ||
constructor(w: number, h: number, fmt?: FloatFormat | FloatFormatSpec, data?: Float32Array); | ||
/** @deprecated use `.data` instead */ | ||
get pixels(): Float32Array; | ||
get width(): number; | ||
get height(): number; | ||
get offset(): number; | ||
get dim(): 2; | ||
as(fmt: IntFormat): IntBuffer; | ||
copy(): FloatBuffer; | ||
empty(): FloatBuffer; | ||
order(): number[]; | ||
includes(x: number, y: number): boolean; | ||
indexAt(x: number, y: number): number; | ||
indexAtUnsafe(x: number, y: number): number; | ||
getAt(x: number, y: number): NumericArray; | ||
getAtUnsafe(x: number, y: number): Float32Array; | ||
setAt(x: number, y: number, col: NumericArray): this; | ||
setAtUnsafe(x: number, y: number, col: NumericArray): this; | ||
setAt(x: number, y: number, col: NumericArray): boolean; | ||
setAtUnsafe(x: number, y: number, col: NumericArray): boolean; | ||
getChannelAt(x: number, y: number, id: number): number | undefined; | ||
@@ -48,0 +54,0 @@ setChannelAt(x: number, y: number, id: number, col: number): this; |
151
float.js
@@ -0,1 +1,5 @@ | ||
var FloatBuffer_1; | ||
import { __decorate } from "tslib"; | ||
import { nomixin } from "@thi.ng/api/decorators/nomixin"; | ||
import { IGrid2DMixin } from "@thi.ng/api/mixins/igrid"; | ||
import { isNumber } from "@thi.ng/checks/is-number"; | ||
@@ -31,5 +35,5 @@ import { isString } from "@thi.ng/checks/is-string"; | ||
const dest = new FloatBuffer(src.width, src.height, fmt); | ||
const { data: dbuf, format: dfmt, stride } = dest; | ||
const { data: dbuf, format: dfmt, stride: [stride], } = dest; | ||
const { data: sbuf, format: sfmt } = src; | ||
for (let i = sbuf.length; --i >= 0;) { | ||
for (let i = sbuf.length; i-- > 0;) { | ||
dbuf.set(dfmt.fromABGR(sfmt.toABGR(sbuf[i])), i * stride); | ||
@@ -39,15 +43,15 @@ } | ||
}; | ||
export const floatBufferFromImage = (img, fmt = FLOAT_RGBA, width, height = width) => floatBufferFromInt(intBufferFromImage(img, undefined, width, height), fmt); | ||
export const floatBufferFromCanvas = (canvas, fmt = FLOAT_RGBA) => floatBufferFromInt(intBufferFromCanvas(canvas), fmt); | ||
export class FloatBuffer { | ||
constructor(w, h, fmt, data) { | ||
this.width = w; | ||
this.height = h; | ||
export const floatBufferFromImage = (img, fmt, width, height = width) => floatBufferFromInt(intBufferFromImage(img, undefined, width, height), fmt); | ||
export const floatBufferFromCanvas = (canvas, fmt) => floatBufferFromInt(intBufferFromCanvas(canvas), fmt); | ||
let FloatBuffer = FloatBuffer_1 = class FloatBuffer { | ||
constructor(w, h, fmt = FLOAT_RGBA, data) { | ||
this.size = [w, h]; | ||
this.format = fmt.__float | ||
? fmt | ||
: defFloatFormat(fmt); | ||
this.stride = fmt.channels.length; | ||
this.rowStride = w * this.stride; | ||
this.data = data || new Float32Array(w * h * this.stride); | ||
this.__empty = (Object.freeze(new Array(this.stride).fill(0))); | ||
// TODO support custom strides (via ctor arg) | ||
const stride = this.format.channels.length; | ||
this.stride = [stride, w * stride]; | ||
this.data = data || new Float32Array(w * h * stride); | ||
this.__empty = (Object.freeze(new Array(stride).fill(0))); | ||
} | ||
@@ -58,4 +62,17 @@ /** @deprecated use `.data` instead */ | ||
} | ||
get width() { | ||
return this.size[0]; | ||
} | ||
get height() { | ||
return this.size[1]; | ||
} | ||
// TODO support custom offsets (via ctor arg) | ||
get offset() { | ||
return 0; | ||
} | ||
get dim() { | ||
return 2; | ||
} | ||
as(fmt) { | ||
const { width, height, stride, data, format: sfmt } = this; | ||
const { width, height, stride: [stride], data, format: sfmt, } = this; | ||
const dest = new IntBuffer(width, height, fmt); | ||
@@ -74,39 +91,37 @@ const dpixels = dest.data; | ||
empty() { | ||
return new FloatBuffer(this.width, this.height, this.format); | ||
return new FloatBuffer_1(this.width, this.height, this.format); | ||
} | ||
// @ts-ignore mixin | ||
order() { } | ||
// @ts-ignore mixin | ||
includes(x, y) { } | ||
// @ts-ignore mixin | ||
indexAt(x, y) { } | ||
// @ts-ignore mixin | ||
indexAtUnsafe(x, y) { } | ||
getAt(x, y) { | ||
return x >= 0 && x < this.width && y >= 0 && y < this.height | ||
? this.getAtUnsafe(x, y) | ||
: this.__empty; | ||
return this.includes(x, y) ? this.getAtUnsafe(x, y) : this.__empty; | ||
} | ||
getAtUnsafe(x, y) { | ||
const stride = this.stride; | ||
const idx = (x | 0) * stride + (y | 0) * this.rowStride; | ||
return this.data.subarray(idx, idx + stride); | ||
const idx = this.indexAtUnsafe(x, y); | ||
return this.data.subarray(idx, idx + this.stride[0]); | ||
} | ||
setAt(x, y, col) { | ||
x >= 0 && | ||
x < this.width && | ||
y >= 0 && | ||
y < this.height && | ||
this.data.set(col, (x | 0) * this.stride + (y | 0) * this.rowStride); | ||
return this; | ||
return this.includes(x, y) | ||
? (this.data.set(col, this.indexAtUnsafe(x, y)), true) | ||
: false; | ||
} | ||
setAtUnsafe(x, y, col) { | ||
this.data.set(col, (x | 0) * this.stride + (y | 0) * this.rowStride); | ||
return this; | ||
this.data.set(col, this.indexAtUnsafe(x, y)); | ||
return true; | ||
} | ||
getChannelAt(x, y, id) { | ||
ensureChannel(this.format, id); | ||
const { width, stride } = this; | ||
if (x >= 0 && x < width && y >= 0 && y < this.height) { | ||
return this.data[(x | 0) * stride + (y | 0) * this.rowStride + id]; | ||
} | ||
return this.includes(x, y) | ||
? this.data[this.indexAtUnsafe(x, y) + id] | ||
: undefined; | ||
} | ||
setChannelAt(x, y, id, col) { | ||
ensureChannel(this.format, id); | ||
const { width, stride } = this; | ||
if (x >= 0 && x < width && y >= 0 && y < this.height) { | ||
this.data[(x | 0) * stride + (y | 0) * this.rowStride + id] = col; | ||
} | ||
this.includes(x, y) && (this.data[this.indexAtUnsafe(x, y) + id] = col); | ||
return this; | ||
@@ -116,3 +131,3 @@ } | ||
ensureChannel(this.format, id); | ||
const { data, stride } = this; | ||
const { data, stride: [stride], } = this; | ||
const dest = new Float32Array(this.width * this.height); | ||
@@ -122,7 +137,7 @@ for (let i = id, j = 0, n = data.length; i < n; i += stride, j++) { | ||
} | ||
return new FloatBuffer(this.width, this.height, FLOAT_GRAY, dest); | ||
return new FloatBuffer_1(this.width, this.height, FLOAT_GRAY, dest); | ||
} | ||
setChannel(id, src) { | ||
ensureChannel(this.format, id); | ||
const { data: dest, stride } = this; | ||
const { data: dest, stride: [stride], } = this; | ||
if (isNumber(src)) { | ||
@@ -134,3 +149,3 @@ for (let i = id, n = dest.length; i < n; i += stride) { | ||
else { | ||
const { data: sbuf, stride: sstride } = src; | ||
const { data: sbuf, stride: [sstride], } = src; | ||
ensureSize(sbuf, this.width, this.height, sstride); | ||
@@ -150,7 +165,6 @@ for (let i = id, j = 0, n = dest.length; i < n; i += stride, j += sstride) { | ||
const dbuf = dest.data; | ||
const sw = this.rowStride; | ||
const dw = dest.rowStride; | ||
const stride = this.stride; | ||
const [stride, sw] = this.stride; | ||
const dw = dest.stride[1]; | ||
for (let si = (sx | 0) * stride + (sy | 0) * sw, di = (dx | 0) * stride + (dy | 0) * dw, yy = 0; yy < rh; yy++, si += sw, di += dw) { | ||
for (let xx = rw, sii = si, dii = di; --xx >= 0; sii += stride, dii += stride) { | ||
for (let xx = rw, sii = si, dii = di; xx-- > 0; sii += stride, dii += stride) { | ||
const out = dbuf.subarray(dii, dii + stride); | ||
@@ -169,6 +183,6 @@ op(out, sbuf.subarray(sii, sii + stride), out); | ||
const dbuf = dest.data; | ||
const sw = this.rowStride; | ||
const dw = dest.rowStride; | ||
const rww = rw * this.stride; | ||
for (let si = (sx | 0) * this.stride + (sy | 0) * sw, di = (dx | 0) * this.stride + (dy | 0) * dw, yy = 0; yy < rh; yy++, si += sw, di += dw) { | ||
const [stride, sw] = this.stride; | ||
const dw = dest.stride[1]; | ||
const rww = rw * stride; | ||
for (let si = (sx | 0) * stride + (sy | 0) * sw, di = (dx | 0) * stride + (dy | 0) * dw, yy = 0; yy < rh; yy++, si += sw, di += dw) { | ||
dbuf.set(sbuf.subarray(si, si + rww), di); | ||
@@ -187,3 +201,3 @@ } | ||
const dest = new Uint32Array(idata.data.buffer); | ||
const { stride, data, format } = this; | ||
const { stride: [stride], data, format, } = this; | ||
for (let i = 0, j = 0, n = data.length; i < n; i += stride, j++) { | ||
@@ -196,3 +210,3 @@ dest[j] = format.toABGR(data.subarray(i, i + stride)); | ||
const [sx, sy, w, h] = __clampRegion(x, y, width, height, this.width, this.height); | ||
return this.blit(new FloatBuffer(w, h, this.format), { | ||
return this.blit(new FloatBuffer_1(w, h, this.format), { | ||
sx, | ||
@@ -205,3 +219,3 @@ sy, | ||
forEach(f) { | ||
const { data, stride } = this; | ||
const { data, stride: [stride], } = this; | ||
for (let i = 0, j = 0, n = data.length; i < n; i += stride, j++) { | ||
@@ -214,3 +228,3 @@ data.set(f(data.subarray(i, i + stride), j), i); | ||
const data = this.data; | ||
for (let i = data.length; --i >= 0;) { | ||
for (let i = data.length; i-- > 0;) { | ||
data[i] = clamp01(data[i]); | ||
@@ -222,3 +236,3 @@ } | ||
ensureChannel(this.format, id); | ||
const { data, stride } = this; | ||
const { data, stride: [stride], } = this; | ||
for (let i = id, n = data.length; i < n; i += stride) { | ||
@@ -232,3 +246,4 @@ data[i] = clamp01(data[i]); | ||
flipY() { | ||
const { data, rowStride } = this; | ||
const data = this.data; | ||
const rowStride = this.stride[1]; | ||
const tmp = new Float32Array(rowStride); | ||
@@ -243,3 +258,3 @@ for (let i = 0, j = data.length - rowStride; i < j; i += rowStride, j -= rowStride) { | ||
invert() { | ||
const { data, format, stride } = this; | ||
const { data, format, stride: [stride], } = this; | ||
for (let i = 0, n = data.length, m = format.alpha ? stride - 1 : stride; i < n; i += stride) { | ||
@@ -263,3 +278,3 @@ for (let j = 0; j < m; j++) | ||
const scaleY = h > 0 ? this.height / h : 0; | ||
const stride = this.stride; | ||
const stride = this.stride[0]; | ||
sampler = isString(sampler) | ||
@@ -277,8 +292,8 @@ ? defSampler(this, sampler, "repeat") | ||
upsize() { | ||
const { width, height, data, stride, rowStride } = this; | ||
const dstride = stride * 2; | ||
const { width, height, data, stride: [stride, rowStride], } = this; | ||
const stride2x = stride * 2; | ||
const dest = floatBuffer(width * 2, height * 2, this.format); | ||
const dpix = dest.data; | ||
for (let y = 0, si = 0; y < height; y++) { | ||
for (let x = 0, di = y * rowStride * 4; x < width; x++, si += stride, di += dstride) { | ||
for (let x = 0, di = y * rowStride * 4; x < width; x++, si += stride, di += stride2x) { | ||
dpix.set(data.subarray(si, si + stride), di); | ||
@@ -292,2 +307,18 @@ } | ||
} | ||
} | ||
}; | ||
__decorate([ | ||
nomixin | ||
], FloatBuffer.prototype, "getAt", null); | ||
__decorate([ | ||
nomixin | ||
], FloatBuffer.prototype, "getAtUnsafe", null); | ||
__decorate([ | ||
nomixin | ||
], FloatBuffer.prototype, "setAt", null); | ||
__decorate([ | ||
nomixin | ||
], FloatBuffer.prototype, "setAtUnsafe", null); | ||
FloatBuffer = FloatBuffer_1 = __decorate([ | ||
IGrid2DMixin | ||
], FloatBuffer); | ||
export { FloatBuffer }; |
24
int.d.ts
@@ -12,4 +12,4 @@ import type { Fn2, ICopy, IEmpty } from "@thi.ng/api"; | ||
*/ | ||
export declare function intBuffer(w: number, h: number, fmt: IntFormat | IntFormatSpec, data?: UIntArray): IntBuffer; | ||
export declare function intBuffer(src: IntBuffer, fmt: IntFormat | IntFormatSpec): IntBuffer; | ||
export declare function intBuffer(w: number, h: number, fmt?: IntFormat | IntFormatSpec, data?: UIntArray): IntBuffer; | ||
export declare function intBuffer(src: IntBuffer, fmt?: IntFormat | IntFormatSpec): IntBuffer; | ||
/** | ||
@@ -34,18 +34,24 @@ * Creates a new pixel buffer from given HTML image element with optional | ||
export declare class IntBuffer implements IPixelBuffer<UIntArray, number>, IToImageData, IResizable<IntBuffer, IntSampler>, IBlend<IntBuffer, BlendFnInt>, IBlit<IntBuffer>, IInvert<IntBuffer>, ICopy<IntBuffer>, IEmpty<IntBuffer> { | ||
readonly width: number; | ||
readonly height: number; | ||
readonly size: [number, number]; | ||
readonly stride: [number, number]; | ||
readonly format: IntFormat; | ||
readonly data: UIntArray; | ||
constructor(w: number, h: number, fmt: IntFormat | IntFormatSpec, data?: UIntArray); | ||
constructor(w: number, h: number, fmt?: IntFormat | IntFormatSpec, data?: UIntArray); | ||
/** @deprecated use `.data` instead */ | ||
get pixels(): UIntArray; | ||
get stride(): number; | ||
get rowStride(): number; | ||
get width(): number; | ||
get height(): number; | ||
get offset(): number; | ||
get dim(): 2; | ||
as(fmt: IntFormat): IntBuffer; | ||
copy(): IntBuffer; | ||
empty(): IntBuffer; | ||
order(): number[]; | ||
includes(x: number, y: number): boolean; | ||
indexAt(x: number, y: number): number; | ||
indexAtUnsafe(x: number, y: number): number; | ||
getAt(x: number, y: number): number; | ||
getAtUnsafe(x: number, y: number): number; | ||
setAt(x: number, y: number, col: number): this; | ||
setAtUnsafe(x: number, y: number, col: number): this; | ||
setAt(x: number, y: number, col: number): boolean; | ||
setAtUnsafe(x: number, y: number, col: number): boolean; | ||
getChannelAt(x: number, y: number, id: number, normalized?: boolean): number; | ||
@@ -52,0 +58,0 @@ setChannelAt(x: number, y: number, id: number, col: number, normalized?: boolean): this; |
89
int.js
@@ -0,1 +1,4 @@ | ||
var IntBuffer_1; | ||
import { __decorate } from "tslib"; | ||
import { IGrid2DMixin } from "@thi.ng/api/mixins/igrid"; | ||
import { typedArray, uintTypeForBits } from "@thi.ng/api/typedarray"; | ||
@@ -49,3 +52,3 @@ import { isNumber } from "@thi.ng/checks/is-number"; | ||
const from = fmt.fromABGR; | ||
for (let i = dest.length; --i >= 0;) { | ||
for (let i = dest.length; i-- > 0;) { | ||
dest[i] = from(src[i]); | ||
@@ -56,6 +59,7 @@ } | ||
}; | ||
export class IntBuffer { | ||
constructor(w, h, fmt, data) { | ||
this.width = w; | ||
this.height = h; | ||
let IntBuffer = IntBuffer_1 = class IntBuffer { | ||
constructor(w, h, fmt = ABGR8888, data) { | ||
this.size = [w, h]; | ||
// TODO support custom strides (via ctor arg) | ||
this.stride = [1, w]; | ||
this.format = fmt.__packed ? fmt : defIntFormat(fmt); | ||
@@ -68,8 +72,15 @@ this.data = data || typedArray(fmt.type, w * h); | ||
} | ||
get stride() { | ||
return 1; | ||
get width() { | ||
return this.size[0]; | ||
} | ||
get rowStride() { | ||
return this.width; | ||
get height() { | ||
return this.size[1]; | ||
} | ||
// TODO support custom offsets (via ctor arg) | ||
get offset() { | ||
return 0; | ||
} | ||
get dim() { | ||
return 2; | ||
} | ||
as(fmt) { | ||
@@ -84,24 +95,20 @@ return this.getRegion(0, 0, this.width, this.height, fmt); | ||
empty() { | ||
return new IntBuffer(this.width, this.height, this.format); | ||
return new IntBuffer_1(this.width, this.height, this.format); | ||
} | ||
getAt(x, y) { | ||
return x >= 0 && x < this.width && y >= 0 && y < this.height | ||
? this.data[(x | 0) + (y | 0) * this.width] | ||
: 0; | ||
} | ||
getAtUnsafe(x, y) { | ||
return this.data[(x | 0) + (y | 0) * this.width]; | ||
} | ||
setAt(x, y, col) { | ||
x >= 0 && | ||
x < this.width && | ||
y >= 0 && | ||
y < this.height && | ||
(this.data[(x | 0) + (y | 0) * this.width] = col); | ||
return this; | ||
} | ||
setAtUnsafe(x, y, col) { | ||
this.data[(x | 0) + (y | 0) * this.width] = col; | ||
return this; | ||
} | ||
// @ts-ignore mixin | ||
order() { } | ||
// @ts-ignore mixin | ||
includes(x, y) { } | ||
// @ts-ignore mixin | ||
indexAt(x, y) { } | ||
// @ts-ignore mixin | ||
indexAtUnsafe(x, y) { } | ||
// @ts-ignore mixin | ||
getAt(x, y) { } | ||
// @ts-ignore mixin | ||
getAtUnsafe(x, y) { } | ||
// @ts-ignore mixin | ||
setAt(x, y, col) { } | ||
// @ts-ignore mixin | ||
setAtUnsafe(x, y, col) { } | ||
getChannelAt(x, y, id, normalized = false) { | ||
@@ -169,3 +176,3 @@ const chan = ensureChannel(this.format, id); | ||
const fmt = this.format.toABGR; | ||
for (let i = dest.length; --i >= 0;) { | ||
for (let i = dest.length; i-- > 0;) { | ||
dest[i] = fmt(src[i]); | ||
@@ -177,3 +184,3 @@ } | ||
const [sx, sy, w, h] = __clampRegion(x, y, width, height, this.width, this.height); | ||
return this.blit(new IntBuffer(w, h, fmt || this.format), { | ||
return this.blit(new IntBuffer_1(w, h, fmt || this.format), { | ||
sx, | ||
@@ -187,3 +194,3 @@ sy, | ||
const chan = ensureChannel(this.format, id); | ||
const buf = new IntBuffer(this.width, this.height, { | ||
const buf = new IntBuffer_1(this.width, this.height, { | ||
type: uintTypeForBits(chan.size), | ||
@@ -198,3 +205,3 @@ size: chan.size, | ||
const get = chan.int; | ||
for (let i = src.length; --i >= 0;) { | ||
for (let i = src.length; i-- > 0;) { | ||
dest[i] = get(src[i]); | ||
@@ -227,3 +234,3 @@ } | ||
const mask = Math.pow(2, format.size - format.alpha) - 1; | ||
for (let i = data.length; --i >= 0;) { | ||
for (let i = data.length; i-- > 0;) { | ||
data[i] ^= mask; | ||
@@ -244,3 +251,3 @@ } | ||
const to = this.format.toABGR; | ||
for (let i = pix.length; --i >= 0;) { | ||
for (let i = pix.length; i-- > 0;) { | ||
if (!isPremultipliedInt(to(pix[i]))) { | ||
@@ -254,3 +261,3 @@ return false; | ||
const pix = this.data; | ||
for (let i = pix.length; --i >= 0;) { | ||
for (let i = pix.length; i-- > 0;) { | ||
pix[i] = f(pix[i], i); | ||
@@ -305,3 +312,3 @@ } | ||
const { width, height, data } = this; | ||
const dest = new IntBuffer(width * 2, height * 2, this.format); | ||
const dest = new IntBuffer_1(width * 2, height * 2, this.format); | ||
const dpix = dest.data; | ||
@@ -315,2 +322,6 @@ for (let y = 0, si = 0; y < height; y++) { | ||
} | ||
} | ||
}; | ||
IntBuffer = IntBuffer_1 = __decorate([ | ||
IGrid2DMixin | ||
], IntBuffer); | ||
export { IntBuffer }; |
@@ -17,4 +17,4 @@ import { isNumber } from "@thi.ng/checks/is-number"; | ||
export const __prepRegions = (src, dest, opts = {}) => { | ||
let sw = src.width; | ||
let dw = dest.width; | ||
const sw = src.width; | ||
const dw = dest.width; | ||
let sx, sy; | ||
@@ -29,3 +29,3 @@ let dx, dy; | ||
export const __setChannelUni = (dbuf, src, set) => { | ||
for (let i = dbuf.length; --i >= 0;) { | ||
for (let i = dbuf.length; i-- > 0;) { | ||
dbuf[i] = set(dbuf[i], src); | ||
@@ -36,3 +36,3 @@ } | ||
export const __setChannelSame = (dbuf, sbuf, get, set) => { | ||
for (let i = dbuf.length; --i >= 0;) { | ||
for (let i = dbuf.length; i-- > 0;) { | ||
dbuf[i] = set(dbuf[i], get(sbuf[i])); | ||
@@ -44,3 +44,3 @@ } | ||
const invMask = ~mask; | ||
for (let i = dbuf.length; --i >= 0;) { | ||
for (let i = dbuf.length; i-- > 0;) { | ||
dbuf[i] = (dbuf[i] & invMask) | (from(sto(sbuf[i])) & mask); | ||
@@ -52,3 +52,3 @@ } | ||
const to = format.toABGR; | ||
for (let i = pix.length; --i >= 0;) { | ||
for (let i = pix.length; i-- > 0;) { | ||
pix[i] = from(fn(to(pix[i]))); | ||
@@ -55,0 +55,0 @@ } |
{ | ||
"name": "@thi.ng/pixel", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"description": "Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution", | ||
@@ -37,10 +37,10 @@ "type": "module", | ||
"dependencies": { | ||
"@thi.ng/api": "^8.1.0", | ||
"@thi.ng/binary": "^3.0.7", | ||
"@thi.ng/checks": "^3.0.6", | ||
"@thi.ng/distance": "^2.0.8", | ||
"@thi.ng/api": "^8.2.0", | ||
"@thi.ng/binary": "^3.0.8", | ||
"@thi.ng/checks": "^3.0.7", | ||
"@thi.ng/distance": "^2.0.9", | ||
"@thi.ng/errors": "^2.0.6", | ||
"@thi.ng/k-means": "^0.4.8", | ||
"@thi.ng/math": "^5.0.7", | ||
"@thi.ng/porter-duff": "^2.0.7" | ||
"@thi.ng/k-means": "^0.4.9", | ||
"@thi.ng/math": "^5.0.8", | ||
"@thi.ng/porter-duff": "^2.0.8" | ||
}, | ||
@@ -210,3 +210,3 @@ "devDependencies": { | ||
}, | ||
"gitHead": "d6aca4b4edb697613ed6635b1c0b12f0bf27b1f0" | ||
"gitHead": "5fe52419af63984ebe53032201b2a6174b9cb159" | ||
} |
@@ -201,3 +201,3 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
See | ||
[ConvolveOpts](https://docs.thi.ng/umbrella/pixel/interfaces/convolveopts.html) | ||
[ConvolveOpts](https://docs.thi.ng/umbrella/pixel/interfaces/ConvolveOpts.html) | ||
for config options. | ||
@@ -337,3 +337,3 @@ | ||
Package sizes (gzipped, pre-treeshake): ESM: 8.91 KB | ||
Package sizes (gzipped, pre-treeshake): ESM: 9.15 KB | ||
@@ -340,0 +340,0 @@ ## Dependencies |
@@ -62,3 +62,3 @@ import { assert } from "@thi.ng/errors/assert"; | ||
}; | ||
const sampleFNC = ({ data, width, height, rowStride, stride }) => (x, y) => { | ||
const sampleFNC = ({ data, width, height, stride: [stride, rowStride], }) => (x, y) => { | ||
let i; | ||
@@ -70,7 +70,7 @@ return x >= 0 && x < width && y >= 0 && y < height | ||
}; | ||
const sampleFNW = ({ data, width, height, rowStride, stride }) => (x, y) => { | ||
const sampleFNW = ({ data, width, height, stride: [stride, rowStride], }) => (x, y) => { | ||
let i = mod(y | 0, height) * rowStride + mod(x | 0, width) * stride; | ||
return data.slice(i, i + stride); | ||
}; | ||
const sampleFNR = ({ data, width, height, rowStride, stride, }) => { | ||
const sampleFNR = ({ data, width, height, stride: [stride, rowStride], }) => { | ||
const w1 = width - 1; | ||
@@ -112,3 +112,3 @@ const h1 = height - 1; | ||
}; | ||
const bilinearFloat = ({ stride }, sample1) => { | ||
const bilinearFloat = ({ stride: [stride] }, sample1) => { | ||
const f32 = new Float32Array(stride * 4); | ||
@@ -190,3 +190,3 @@ return (x, y) => { | ||
}; | ||
const bicubicFloat = ({ stride }, sample) => { | ||
const bicubicFloat = ({ stride: [stride] }, sample) => { | ||
const f32 = new Float32Array(stride * 16); | ||
@@ -193,0 +193,0 @@ return (x, y) => { |
152456
2817
Updated@thi.ng/api@^8.2.0
Updated@thi.ng/binary@^3.0.8
Updated@thi.ng/checks@^3.0.7
Updated@thi.ng/distance@^2.0.9
Updated@thi.ng/k-means@^0.4.9
Updated@thi.ng/math@^5.0.8
Updated@thi.ng/porter-duff@^2.0.8