@@ -102,7 +102,7 @@ const work = { row: new Float64Array(256), scratch: new Float64Array(256) };
102102const SEC8 = secHalf ( 8 ) ;
103103
104104// the inverse 8-point DCT of buf[o + k * step] in place (like dct's recursion, unrolled)
105- function idct8 ( buf : Float32Array , o : number , step : number ) : void {
105+ export function idct8 ( buf : Float32Array , o : number , step : number ) : void {
106106 const v0 = buf [ o ] , v1 = buf [ o + step ] , v2 = buf [ o + 2 * step ] , v3 = buf [ o + 3 * step ] ;
107107 const v4 = buf [ o + 4 * step ] , v5 = buf [ o + 5 * step ] , v6 = buf [ o + 6 * step ] , v7 = buf [ o + 7 * step ] ;
108108 // the even half: v0, v2, v4, v6
@@ -229,7 +229,28 @@ const set = (b: Block, x: number, y: number, v: number): void => {
229229 b . buf [ b . offset + y * b . stride + x ] = v ;
230230} ;
231231const tmp = { a : new Float32Array ( 64 ) , b : new Float32Array ( 64 ) } ;
232- const blockOf = ( buf : Float32Array , offset : number , w : number , h : number , stride = w ) : Block => ( { buf, offset, stride, w, h } ) ;
232+
233+ // the inverse 4-point DCT of buf[o + k * step] in place (dct4's)
234+ function idct4 ( buf : Float32Array , o : number , step : number ) : void {
235+ const i0 = buf [ o ] , i1 = buf [ o + step ] , i2 = buf [ o + 2 * step ] , i3 = buf [ o + 3 * step ] ;
236+ const t0 = i1 * Math . SQRT2 , t1 = i1 + i3 , out0 = ( t0 + t1 ) * SEC0 , out1 = ( t0 - t1 ) * SEC1 ;
237+ const sum02 = i0 + i2 , sub02 = i0 - i2 ;
238+ buf [ o ] = sum02 + out0 ;
239+ buf [ o + step ] = sub02 + out1 ;
240+ buf [ o + 2 * step ] = sub02 - out1 ;
241+ buf [ o + 3 * step ] = sum02 - out0 ;
242+ }
243+
244+ // the inverse 2D DCTs of 8x4 and 4x4 blocks at buf[o] (rows, then columns: dct2d's)
245+ function idct8x4 ( buf : Float32Array , o : number ) : void {
246+ for ( let y = 0 ; y < 4 ; y ++ ) idct8 ( buf , o + y * 8 , 1 ) ;
247+ for ( let x = 0 ; x < 8 ; x ++ ) idct4 ( buf , o + x , 8 ) ;
248+ }
249+
250+ function idct4x4 ( buf : Float32Array , o : number ) : void {
251+ for ( let y = 0 ; y < 4 ; y ++ ) idct4 ( buf , o + y * 4 , 1 ) ;
252+ for ( let x = 0 ; x < 4 ; x ++ ) idct4 ( buf , o + x , 4 ) ;
253+ }
233254
234255function idct2InPlace ( b : Block , size : number ) : void {
235256 const half = size / 2 , s = tmp . a ;
@@ -259,7 +280,7 @@ function dct4x4(b: Block): void {
259280 const o = ( y * 2 + x ) * 16 ;
260281 // (transposed)
261282 for ( let iy = 0 ; iy < 4 ; iy ++ ) for ( let ix = 0 ; ix < 4 ; ix ++ ) s [ o + ix * 4 + iy ] = get ( b , x + ix * 2 , y + iy * 2 ) ;
262- dct2d ( blockOf ( s , o , 4 , 4 ) , true ) ;
283+ idct4x4 ( s , o ) ;
263284 }
264285 }
265286 for ( let y = 0 ; y < 2 ; y ++ ) for ( let x = 0 ; x < 2 ; x ++ ) for ( let iy = 0 ; iy < 4 ; iy ++ ) for ( let ix = 0 ; ix < 4 ; ix ++ ) set ( b , x * 4 + ix , y * 4 + iy , s [ ( y * 2 + x ) * 16 + iy * 4 + ix ] ) ;
@@ -290,27 +311,28 @@ function dct4x8(b: Block, transposed: boolean): void {
290311 const s = tmp . b ;
291312 for ( let i = 0 ; i < 2 ; i ++ ) {
292313 for ( let iy = 0 ; iy < 4 ; iy ++ ) for ( let ix = 0 ; ix < 8 ; ix ++ ) s [ i * 32 + iy * 8 + ix ] = get ( b , ix , iy * 2 + i ) ;
293- dct2d ( blockOf ( s , i * 32 , 8 , 4 ) , true ) ;
314+ idct8x4 ( s , i * 32 ) ;
294315 }
295316 for ( let y = 0 ; y < 8 ; y ++ ) for ( let x = 0 ; x < 8 ; x ++ ) {
296317 if ( transposed ) set ( b , y , x , s [ y * 8 + x ] ) ;
297318 else set ( b , x , y , s [ y * 8 + x ] ) ;
298319 }
299320}
300321
322+ const afvScratch = { coeffs : new Float64Array ( 16 ) , samples : new Float64Array ( 16 ) , s4 : new Float32Array ( 16 ) , s8 : new Float32Array ( 32 ) } ;
323+
301324function afv ( b : Block , n : number ) : void {
302325 const flipX = n % 2 , flipY = n >> 1 ;
303- const coeffs = new Float64Array ( 16 ) , samples = new Float64Array ( 16 ) ;
326+ const coeffs = afvScratch . coeffs , samples = afvScratch . samples . fill ( 0 ) , s4 = afvScratch . s4 , s8 = afvScratch . s8 ;
304327 coeffs [ 0 ] = ( get ( b , 0 , 0 ) + get ( b , 1 , 0 ) + get ( b , 0 , 1 ) ) * 4 ;
305328 for ( let i = 1 ; i < 16 ; i ++ ) coeffs [ i ] = get ( b , 2 * ( i % 4 ) , 2 * ( i >> 2 ) ) ;
306329 for ( let i = 0 ; i < 16 ; i ++ ) for ( let k = 0 ; k < 16 ; k ++ ) samples [ k ] += coeffs [ i ] * AFV_BASIS [ i * 16 + k ] ;
307- const s4 = new Float32Array ( 16 ) , s8 = new Float32Array ( 32 ) ;
308330 s4 [ 0 ] = get ( b , 0 , 0 ) - get ( b , 1 , 0 ) + get ( b , 0 , 1 ) ;
309331 for ( let iy = 0 ; iy < 4 ; iy ++ ) for ( let ix = 0 ; ix < 4 ; ix ++ ) if ( ix | iy ) s4 [ ix * 4 + iy ] = get ( b , 2 * ix + 1 , 2 * iy ) ;
310- dct2d ( blockOf ( s4 , 0 , 4 , 4 ) , true ) ;
332+ idct4x4 ( s4 , 0 ) ;
311333 s8 [ 0 ] = get ( b , 0 , 0 ) - get ( b , 0 , 1 ) ;
312334 for ( let iy = 0 ; iy < 4 ; iy ++ ) for ( let ix = 0 ; ix < 8 ; ix ++ ) if ( ix | iy ) s8 [ iy * 8 + ix ] = get ( b , ix , 2 * iy + 1 ) ;
313- dct2d ( blockOf ( s8 , 0 , 8 , 4 ) , true ) ;
335+ idct8x4 ( s8 , 0 ) ;
314336 for ( let iy = 0 ; iy < 4 ; iy ++ ) {
315337 const ay = flipY ? 3 - iy : iy ;
316338 for ( let ix = 0 ; ix < 4 ; ix ++ ) set ( b , flipX * 4 + ix , flipY * 4 + iy , samples [ ay * 4 + ( flipX ? 3 - ix : ix ) ] ) ;
@@ -337,7 +359,7 @@ export function inverseTransform(b: Block, type: number): void {
337359export { sub as subBlock } ;
338360
339361// the AFV basis (16 x 16)
340- const AFV_BASIS = [
362+ export const AFV_BASIS = [
341363 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 , 0.25 ,
342364 0.876902929799142 , 0.2206518106944235 , - 0.10140050393753763 , - 0.1014005039375375 , 0.2206518106944236 , - 0.10140050393753777 , - 0.10140050393753772 , - 0.10140050393753763 , - 0.10140050393753758 , - 0.10140050393753769 , - 0.1014005039375375 , - 0.10140050393753768 , - 0.10140050393753768 , - 0.10140050393753759 , - 0.10140050393753763 , - 0.10140050393753741 ,
343365 0.0 , 0.0 , 0.40670075830260755 , 0.44444816619734445 , 0.0 , 0.0 , 0.19574399372042936 , 0.2929100136981264 , - 0.40670075830260716 , - 0.19574399372042872 , 0.0 , 0.11379074460448091 , - 0.44444816619734384 , - 0.29291001369812636 , - 0.1137907446044814 , 0.0 ,
0 commit comments