import { isNumber } from "@thi.ng/checks/is-number" ; import { clamp } from "@thi.ng/math/interval" ; import type { IntBuffer } from "@thi.ng/pixel" ; import type { BayerMatrix , BayerSize } from "./api.js" ; const init = ( x , y , size , val , step , mat ) => { if ( size === 1 ) { ! mat [ y ] && ( mat [ y ] = [ ] ) ; mat [ y ] [ x ] = val ; return mat ; } size >>= 1 ; const step4 = step << 2 ; init ( x , y , size , val , step4 , mat ) ; init ( x + size , y + size , size , val + step , step4 , mat ) ; init ( x + size , y , size , val + step * 2 , step4 , mat ) ; init ( x , y + size , size , val + step * 3 , step4 , mat ) ; return mat ; } ; /**
 * Creates a Bayer matrix of given kernel size (power of 2) for ordered
 * dithering and use with  ditherPixels remarks param size export const defBayer = ( size ) : BayerMatrix => ( { mat : init ( 0 , 0 , size , 0 , 1 , [ ] ) , invSize : 1 / ( size * size ) , mask : size - 1 , } ) ; param mat param dsteps param drange param srange param x param y param val internal const orderedDither1 = ( { mat , mask , invSize } , dsteps , drange , srange , x , y , val ) => { val = ( dsteps * ( val / srange ) + mat [ y & mask ] [ x & mask ] * invSize - 0.5 ) | 0 ; dsteps -- ; return clamp ( val , 0 , dsteps ) * ( ( drange - 1 ) / dsteps ) ; } ; remarks A `size` of 1 will result in simple posterization of each
 * channel. The `numColors` value(s) MUST be in the `[0 ..
 * numColorsInChannel]` interval.
 *
 * Also see:  defBayer param img param size param numColors export const orderedDither = ( img , size , numColors ) => { const { data , format , width } = img ; const steps = isNumber ( numColors ) ? new Array < number > ( format . channels . length ) . fill ( numColors ) : numColors ; const mat = isNumber ( size ) ? defBayer ( size ) : size ; for ( let i = 0 , n = data . length , nc = format . channels . length , x = 0 , y = 0 ; i < n ; i ++ ) { let col = data [ i ] ; for ( let j = 0 ; j < nc ; j ++ ) { const ch = format . channels [ j ] ; const num = ch . num ; const cs = steps [ j ] ; cs > 0 && ( col = ch . setInt ( col , orderedDither1 ( mat , cs , num , num , x , y , ch . int ( col ) ) ) ) ; } data [ i ] = col ; if ( ++ x === width ) { x = 0 ; y ++ ; } } return img ; } ;