import type { Fn } from "@thi.ng/api" ; import { assert } from "@thi.ng/errors/assert" ; import { clamp , clamp01 } from "@thi.ng/math/interval" ; import { ABGR8888 } from "@thi.ng/pixel/format/abgr8888" ; import { IntBuffer , intBufferFromCanvas } from "@thi.ng/pixel/int" ; import type { ReadonlyVec , Vec } from "@thi.ng/vectors" ; const rgba2bgra = ( rgba ) => ( ( clamp01 ( rgba [ 0 ] ) * 255.5 ) << 0 ) | ( ( clamp01 ( rgba [ 1 ] ) * 255.5 ) << 8 ) | ( ( clamp01 ( rgba [ 2 ] ) * 255.5 ) << 16 ) | ( ( clamp01 ( rgba [ 3 ] ) * 255.5 ) << 24 ) ; const clampCoord = ( x , maxW , w ? ) => w !== undefined ? Math . min ( x + w , maxW ) : maxW ; /**
 * Low-level function used by  canvasRenderer and
 *  renderBuffer . Applies shader function `fn` to each pixel in
 * the given region of the `u32` raw ABGR buffer (a `Uint32Array`). The
 * region is defined by the top-left `x`, `y` coords and `w`, `h`
 * dimensions. The remaining parameters `bufW`, `bufH`, `bufOffsetX`,
 * `bufOffsetY` and `imgH` are used to define the actual location of the
 * given buffer in the full image to be computed and to support use
 * cases where the target array only defines a sub-region of the full
 * image (e.g. when splitting rendering over multiple workers, each with
 * their own buffer).
 *
 *  param fn param u32 param bufW param bufH param x param y param w param h param bufOffsetX param bufOffsetY param imgH export const renderPixels = ( fn , u32 , bufW , bufH , x , y , w ? , h ? , bufOffsetX = 0 , bufOffsetY = 0 , imgH = bufH ) => { const frag = [ ] ; x = clamp ( x , 0 , bufW ) ; y = clamp ( y , 0 , bufH ) ; const x2 = clampCoord ( x , bufW , w ) ; const y2 = clampCoord ( y , bufH , h ) ; for ( let yy = y ; yy < y2 ; yy ++ ) { frag [ 1 ] = imgH - 1 - yy - bufOffsetY ; let i = yy * bufW + x ; for ( let xx = x ; xx < x2 ; xx ++ ) { frag [ 0 ] = xx + bufOffsetX ; u32 [ i ++ ] = rgba2bgra ( fn ( frag ) ) ; } } return u32 ; } ; /**
 * Takes a  {@link @thi.ng/pixel#IntBuffer} pixel buffer from
 * thi.ng/pixel w/  {@link @thi.ng/pixel#ABGR8888} format, an optional
 * buffer local region defined by `x`, `y`, `w`, `h` and applies shader
 * function `fn` to each pixel in that region (or full buffer by
 * default).
 *
 * In case the buffer only defines a sub-region of a larger image,
 * `bufOffsetX`, `bufOffsetY` and `imgH` can be given to configure the
 * location and full image height.
 *
 *  param fn param buf param x param y param w param h param bufOffsetX param bufOffsetY param imgH export const renderBuffer = ( fn , buf , x = 0 , y = 0 , w ? , h ? , bufOffsetX = 0 , bufOffsetY = 0 , imgH = buf . height ) => { assert ( buf . format === ABGR8888 , `invalid buffer pixel format` ) ; renderPixels ( fn , < Uint32Array > buf . data , buf . width , buf . height , x , y , w , h , bufOffsetX , bufOffsetY , imgH ) ; return buf ; } ; param canvas export const canvasRenderer = ( canvas ) => { const buf = intBufferFromCanvas ( canvas ) ; return ( fn , x = 0 , y = 0 , w = canvas . width , h = canvas . height ) => { renderBuffer ( fn , buf , x , y , w , h ) ; buf . blitCanvas ( canvas ) ; } ; } ;