// -----------------------------------------------------------------------------
// 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;
}