@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
69 lines (61 loc) • 2.85 kB
JavaScript
// -----------------------------------------------------------------------------
// Constants for the AAN Fast IDCT Algorithm
// -----------------------------------------------------------------------------
// These are pre-calculated cosine values used in the butterfly operations
// of the fast 1D IDCT. Using constants avoids repeated calls to cos().
const a = .5 * Math.cos(Math.PI / 4);
const b = .5 * Math.cos(Math.PI / 16);
const c = .5 * Math.cos(Math.PI / 8);
const d = .5 * Math.cos(3 * Math.PI / 16);
const e = .5 * Math.cos(5 * Math.PI / 16);
const f = .5 * Math.cos(3 * Math.PI / 8);
const g = .5 * Math.cos(7 * Math.PI / 16);
/**
* Performs a 1D Inverse Discrete Cosine Transform on an 8-element block.
*
* This function implements a fast AAN (Arai-Agui-Nakajima) algorithm.
* It performs the transformation in-place, modifying the input array directly.
*
* NOTE: ported from ffmpeg https://github.com/RPi-Distro/ffmpeg/blob/3a48fe739a020d939a4e752684ef1eed901fd189/libavcodec/exr.c#L916
*
* @param {Float64Array} block A pointer to an array of 8 double-precision floating-point values.
* @param {number} offset
* @param {number} stride
*/
export function idct_1d(block, offset, stride) {
// Stage 1: Process even-indexed coefficients
const t0 = block[offset + 0 * stride];
const t1 = block[offset + 1 * stride];
const t2 = block[offset + 2 * stride];
const t3 = block[offset + 3 * stride];
const t4 = block[offset + 4 * stride];
const t5 = block[offset + 5 * stride];
const t6 = block[offset + 6 * stride];
const t7 = block[offset + 7 * stride];
const alpha_0 = c * t2;
const alpha_1 = f * t2;
const alpha_2 = c * t6;
const alpha_3 = f * t6;
const beta_0 = b * t1 + d * t3 + e * t5 + g * t7;
const beta_1 = d * t1 - g * t3 - b * t5 - e * t7;
const beta_2 = e * t1 - b * t3 + g * t5 + d * t7;
const beta_3 = g * t1 - e * t3 + d * t5 - b * t7;
const theta_0 = a * (t0 + t4);
const theta_3 = a * (t0 - t4);
const theta_1 = alpha_0 + alpha_3;
const theta_2 = alpha_1 - alpha_2;
const gamma_0 = theta_0 + theta_1;
const gamma_1 = theta_3 + theta_2;
const gamma_2 = theta_3 - theta_2;
const gamma_3 = theta_0 - theta_1;
// Stage 3: Final combination (butterflies)
// Combines the even and odd part results and stores them back in-place.
block[offset + 0 * stride] = gamma_0 + beta_0;
block[offset + 1 * stride] = gamma_1 + beta_1;
block[offset + 2 * stride] = gamma_2 + beta_2;
block[offset + 3 * stride] = gamma_3 + beta_3;
block[offset + 4 * stride] = gamma_3 - beta_3;
block[offset + 5 * stride] = gamma_2 - beta_2;
block[offset + 6 * stride] = gamma_1 - beta_1;
block[offset + 7 * stride] = gamma_0 - beta_0;
}