@@ -62,43 +62,74 @@ function outputRow(cur: Float32Array[], out: Float32Array[], y: number, w: numbe
6262 // (rows 2 away from the edges: the taps without mirroring)
6363 const innerRow = rows [ 0 ] === ( y - 2 ) * w && rows [ 4 ] === ( y + 2 ) * w ;
6464 const row = y * w ;
65- for ( let x = 0 ; x < w ; x ++ ) {
66- const i = row + x ;
67- const sg = sigma ? sigma [ sigmaRow + ( x >> 3 ) ] : sigmaModular ;
65+ // per tap pair: the offsets of +u in the sums and in the row
66+ const sumOff = TAPS . subarray ( 0 , n ) , srcOff = TAPS . subarray ( 8 , 8 + n ) ;
67+ for ( let k = 0 ; k < n ; k ++ ) {
68+ sumOff [ k ] = u [ 2 * k + 1 ] * pw + u [ 2 * k ] ;
69+ srcOff [ k ] = u [ 2 * k + 1 ] * w + u [ 2 * k ] ;
70+ }
71+ for ( let x0 = 0 ; x0 < w ; x0 += 8 ) {
72+ const x1 = Math . min ( x0 + 8 , w ) ;
73+ const sg = sigma ? sigma [ sigmaRow + ( x0 >> 3 ) ] : sigmaModular ;
6874 if ( sg < 0.3 ) {
69- o0 [ i ] = i0 [ i ] ;
70- o1 [ i ] = i1 [ i ] ;
71- o2 [ i ] = i2 [ i ] ;
75+ o0 . set ( i0 . subarray ( row + x0 , row + x1 ) , row + x0 ) ;
76+ o1 . set ( i1 . subarray ( row + x0 , row + x1 ) , row + x0 ) ;
77+ o2 . set ( i2 . subarray ( row + x0 , row + x1 ) , row + x0 ) ;
7278 continue ;
7379 }
74- const sm = yBorder || ( x & 7 ) === 0 || ( x & 7 ) === 7 ? stepMul * borderMul : stepMul ;
75- const negInvSigma = 6.6 * ( Math . SQRT1_2 - 1 ) / sg * sm ;
76- let sumW = 1 , sum0 = i0 [ i ] , sum1 = i1 [ i ] , sum2 = i2 [ i ] ;
77- const p = p0 + x , inner = innerRow && x >= 2 && x < w - 2 ;
78- for ( let k = 0 ; k < n ; k ++ ) {
79- const ux = u [ 2 * k ] , uy = u [ 2 * k + 1 ] , sum = sums [ k ] ;
80- let weight = 1 + sum [ p ] * negInvSigma ;
81- if ( weight > 0 ) {
82- const t = inner ? i + uy * w + ux : rows [ 2 + uy ] + xs [ x + 5 + ux ] ;
83- sumW += weight ;
84- sum0 += weight * i0 [ t ] ;
85- sum1 += weight * i1 [ t ] ;
86- sum2 += weight * i2 [ t ] ;
87- }
88- weight = 1 + sum [ p - uy * pw - ux ] * negInvSigma ;
89- if ( weight > 0 ) {
90- const t = inner ? i - uy * w - ux : rows [ 2 - uy ] + xs [ x + 5 - ux ] ;
91- sumW += weight ;
92- sum0 += weight * i0 [ t ] ;
93- sum1 += weight * i1 [ t ] ;
94- sum2 += weight * i2 [ t ] ;
80+ // (the block's columns 0 and 7, and its rows 0 and 7, are weighted by borderMul)
81+ const borderInvSigma = 6.6 * ( Math . SQRT1_2 - 1 ) / sg * ( stepMul * borderMul ) , innerInvSigma = 6.6 * ( Math . SQRT1_2 - 1 ) / sg * stepMul ;
82+ for ( let x = x0 ; x < x1 ; x ++ ) {
83+ const i = row + x ;
84+ const negInvSigma = yBorder || ( x & 7 ) === 0 || ( x & 7 ) === 7 ? borderInvSigma : innerInvSigma ;
85+ let sumW = 1 , sum0 = i0 [ i ] , sum1 = i1 [ i ] , sum2 = i2 [ i ] ;
86+ const p = p0 + x ;
87+ if ( innerRow && x >= 2 && x < w - 2 ) {
88+ for ( let k = 0 ; k < n ; k ++ ) {
89+ const sum = sums [ k ] , so = sumOff [ k ] , to = srcOff [ k ] ;
90+ let weight = 1 + sum [ p ] * negInvSigma ;
91+ if ( weight > 0 ) {
92+ sumW += weight ;
93+ sum0 += weight * i0 [ i + to ] ;
94+ sum1 += weight * i1 [ i + to ] ;
95+ sum2 += weight * i2 [ i + to ] ;
96+ }
97+ weight = 1 + sum [ p - so ] * negInvSigma ;
98+ if ( weight > 0 ) {
99+ sumW += weight ;
100+ sum0 += weight * i0 [ i - to ] ;
101+ sum1 += weight * i1 [ i - to ] ;
102+ sum2 += weight * i2 [ i - to ] ;
103+ }
104+ }
105+ } else {
106+ for ( let k = 0 ; k < n ; k ++ ) {
107+ const ux = u [ 2 * k ] , uy = u [ 2 * k + 1 ] , sum = sums [ k ] ;
108+ let weight = 1 + sum [ p ] * negInvSigma ;
109+ if ( weight > 0 ) {
110+ const t = rows [ 2 + uy ] + xs [ x + 5 + ux ] ;
111+ sumW += weight ;
112+ sum0 += weight * i0 [ t ] ;
113+ sum1 += weight * i1 [ t ] ;
114+ sum2 += weight * i2 [ t ] ;
115+ }
116+ weight = 1 + sum [ p - uy * pw - ux ] * negInvSigma ;
117+ if ( weight > 0 ) {
118+ const t = rows [ 2 - uy ] + xs [ x + 5 - ux ] ;
119+ sumW += weight ;
120+ sum0 += weight * i0 [ t ] ;
121+ sum1 += weight * i1 [ t ] ;
122+ sum2 += weight * i2 [ t ] ;
123+ }
124+ }
95125 }
126+ o0 [ i ] = sum0 / sumW ;
127+ o1 [ i ] = sum1 / sumW ;
128+ o2 [ i ] = sum2 / sumW ;
96129 }
97- o0 [ i ] = sum0 / sumW ;
98- o1 [ i ] = sum1 / sumW ;
99- o2 [ i ] = sum2 / sumW ;
100130 }
101131}
132+ const TAPS = new Int32Array ( 16 ) ;
102133
103134/**
104135 * The edge-preserving filter on 3 w x h channels
0 commit comments