Skip to content

Commit

Permalink
feat(arrays): add blit1d/2d() functions
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jul 8, 2022
1 parent 4c4aeb0 commit 56e8373
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/arrays/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@
"./bisect": {
"default": "./bisect.js"
},
"./blit": {
"default": "./blit.js"
},
"./ends-with": {
"default": "./ends-with.js"
},
Expand Down
118 changes: 118 additions & 0 deletions packages/arrays/src/blit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import type { TypedArray } from "@thi.ng/api";

/**
* Selectively copies all non-`mask` values from `src` into `dest` starting from
* destination position `dx`. Returns `dest`.
*
* @remarks
* Where `src` values are the same as `mask`, the corresponding `dest` values
* will be left unchanged. Performs region clipping, i.e. `dx` can be outside
* the [0..dest.length) interval.
*
* @example
* ```ts
* blit1d(
* // dest array
* [1, 1, 1, 1, 1, 1, 1, 1, 1],
* // paste from index 2
* 2,
* // source array
* [2, 3, 2, 3, 2],
* // mask value
* 3
* )
* //[1, 1, 2, 1, 2, 1, 2, 1, 1]
* ```
*
* @param dest
* @param src
* @param dx
* @param mask
*/
export function blit1d<T extends TypedArray>(
dest: T,
dx: number,
src: ArrayLike<number>,
mask: number
): T;
export function blit1d<T>(
dest: T[],
dx: number,
src: ArrayLike<T>,
mask: T
): T[];
export function blit1d(dest: any[], x: number, src: ArrayLike<any>, mask: any) {
const [sx, sw, dx, dw] = __clip(0, src.length, x, dest.length);
if (sw < 1 || dx >= dw) return dest;
for (let i = 0; i < sw; i++) {
const val = src[sx + i];
val !== mask && (dest[dx + i] = val);
}
return dest;
}

/**
* 2D version of {@link blit1d} (also with region clipping). Positions and sizes
* are given as 2D vectors.
*
* @param dest
* @param dpos
* @param dsize
* @param src
* @param ssize
* @param mask
*/
export function blit2d<T extends TypedArray>(
dest: T,
dpos: ArrayLike<number>,
dsize: ArrayLike<number>,
src: ArrayLike<number>,
ssize: ArrayLike<number>,
mask: number
): T;
export function blit2d<T>(
dest: T[],
dpos: ArrayLike<number>,
dsize: ArrayLike<number>,
src: ArrayLike<T>,
ssize: ArrayLike<number>,
mask: T
): T[];
export function blit2d(
dest: any[],
dpos: ArrayLike<number>,
dsize: ArrayLike<number>,
src: ArrayLike<any>,
ssize: ArrayLike<number>,
mask: any
) {
const [sx, sw, dx, dw] = __clip(0, ssize[0], dpos[0], dsize[0]);
const [sy, sh, dy, dh] = __clip(0, ssize[1], dpos[1], dsize[1]);
if (sw < 1 || sh < 1 || dx >= dw || dy >= dh) return dest;
const sstride = ssize[0];
const dstride = dsize[0];
for (let y = 0; y < sh; y++) {
for (
let x = 0,
soff = (sy + y) * sstride + sx,
doff = (dy + y) * dstride + dx;
x < sw;
x++
) {
const val = src[soff + x];
val !== mask && (dest[doff + x] = val);
}
}
return dest;
}

const __clip = (sx: number, sw: number, dx: number, dw: number) => {
if (dx < 0) {
sx -= dx;
sw += dx;
dx = 0;
} else if (dx + sw > dw) {
sw = dw - dx;
}
return [sx, sw, dx, dw];
};
1 change: 1 addition & 0 deletions packages/arrays/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export * from "./api.js";
export * from "./arg-sort.js";
export * from "./binary-search.js";
export * from "./bisect.js";
export * from "./blit.js";
export * from "./ends-with.js";
export * from "./ensure-array.js";
export * from "./ensure-iterable.js";
Expand Down

0 comments on commit 56e8373

Please sign in to comment.