@@ -20,6 +20,16 @@ function findSeams(data, width, height, removeCount, onRemoveSeam) {
2020 return workingData ;
2121}
2222exports . findSeams = findSeams ;
23+ // filthy branchless max and min
24+ // if x - y is positive, (x - y) >> 31 will be all 0s
25+ // if x - y is negative, (x - y) >> 31 will be all 1s
26+ // & that with x - y to either get 0 or x - y
27+ function fastMin ( x , y ) {
28+ return y + ( ( x - y ) & ( ( x - y ) >> 31 ) ) ;
29+ }
30+ function fastMax ( x , y ) {
31+ return x - ( ( x - y ) & ( ( x - y ) >> 31 ) ) ;
32+ }
2333// remove seams in remove from data, returning a new array.
2434function removeSeam ( data , width , height , remove ) {
2535 const data32 = new Uint32Array ( data . buffer ) ;
@@ -118,14 +128,23 @@ function calcEnergySum(energySum, energy, width, height) {
118128 }
119129 // populate the rest of the rows
120130 for ( let y = 1 ; y < height ; y ++ ) {
121- // const removex = remove[y];
122- // for (let x = Math.max(removex - y, 0); x < Math.min(removex + y, width); x++) {
123- for ( let x = 0 ; x < width ; x ++ ) {
124- const left = energySum [ ( y - 1 ) * width + Math . max ( x - 1 , 0 ) ] ;
125- const mid = energySum [ ( y - 1 ) * width + x ] ;
126- const right = energySum [ ( y - 1 ) * width + Math . min ( x + 1 , width - 1 ) ] ;
127- energySum [ y * width + x ] = energy [ y * width + x ] + Math . min ( left , mid , right ) ;
131+ let x = 0 ;
132+ // left edge
133+ const lmid = energySum [ ( y - 1 ) * width + x ] ;
134+ const lright = energySum [ ( y - 1 ) * width + x + 1 ] ;
135+ energySum [ y * width + x ] = energy [ y * width + x ] + fastMin ( lmid , lright ) ;
136+ for ( x = 1 ; x < width - 1 ; x ++ ) {
137+ const prev = energy [ y * width + x ] ;
138+ const index = ( y - 1 ) * width + x - 1 ;
139+ const left = energySum [ index ] ;
140+ const mid = energySum [ index + 1 ] ;
141+ const right = energySum [ index + 2 ] ;
142+ energySum [ y * width + x ] = prev + fastMin ( fastMin ( left , mid ) , right ) ;
128143 }
144+ // right edge
145+ const rleft = energySum [ ( y - 1 ) * width + x - 1 ] ;
146+ const rmid = energySum [ ( y - 1 ) * width + x ] ;
147+ energySum [ y * width + x ] = energy [ y * width + x ] + fastMin ( rleft , rmid ) ;
129148 }
130149}
131150function findMinSeam ( remove , energySum , width , height ) {
@@ -141,10 +160,10 @@ function findMinSeam(remove, energySum, width, height) {
141160 remove [ ( height - 1 ) ] = minx ;
142161 // walk from the bottom up picking the min each time
143162 for ( let y = height - 1 ; y >= 1 ; y -- ) {
144- const leftx = Math . max ( minx - 1 , 0 ) ;
163+ const leftx = fastMax ( minx - 1 , 0 ) ;
145164 const left = energySum [ ( y - 1 ) * width + leftx ] ;
146165 const mid = energySum [ ( y - 1 ) * width + minx ] ;
147- const rightx = Math . min ( minx + 1 , width - 1 ) ;
166+ const rightx = fastMin ( minx + 1 , width - 1 ) ;
148167 const right = energySum [ ( y - 1 ) * width + rightx ] ;
149168 if ( left < mid && left < right ) {
150169 minx = leftx ;
0 commit comments