/*
 * Floating point AAN DCT
 * this implementation is based upon the IJG integer AAN DCT (see jfdctfst.c)
 *
 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
 * Copyright (c) 2003 Roman Shaposhnik
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/**
 * @file
 * @brief
 *     Floating point AAN DCT
 * @author Michael Niedermayer <michaelni@gmx.at>
 */

#include "faandct.h"
#include "libavutil/internal.h"
#include "libavutil/libm.h"

typedef float FLOAT;

/* numbers generated by arbitrary precision arithmetic followed by truncation
to 36 fractional digits (enough for a 128-bit IEEE quad, see /usr/include/math.h
for this approach). Unfortunately, long double is not always available correctly,
e.g ppc has issues.
TODO: add L suffixes when ppc and toolchains sort out their stuff.
*/
#define B0 1.000000000000000000000000000000000000
#define B1 0.720959822006947913789091890943021267 // (cos(pi*1/16)sqrt(2))^-1
#define B2 0.765366864730179543456919968060797734 // (cos(pi*2/16)sqrt(2))^-1
#define B3 0.850430094767256448766702844371412325 // (cos(pi*3/16)sqrt(2))^-1
#define B4 1.000000000000000000000000000000000000 // (cos(pi*4/16)sqrt(2))^-1
#define B5 1.272758580572833938461007018281767032 // (cos(pi*5/16)sqrt(2))^-1
#define B6 1.847759065022573512256366378793576574 // (cos(pi*6/16)sqrt(2))^-1
#define B7 3.624509785411551372409941227504289587 // (cos(pi*7/16)sqrt(2))^-1

#define A1 M_SQRT1_2              // cos(pi*4/16)
#define A2 0.54119610014619698435 // cos(pi*6/16)sqrt(2)
#define A5 0.38268343236508977170 // cos(pi*6/16)
#define A4 1.30656296487637652774 // cos(pi*2/16)sqrt(2)

static const FLOAT postscale[64]={
B0*B0, B0*B1, B0*B2, B0*B3, B0*B4, B0*B5, B0*B6, B0*B7,
B1*B0, B1*B1, B1*B2, B1*B3, B1*B4, B1*B5, B1*B6, B1*B7,
B2*B0, B2*B1, B2*B2, B2*B3, B2*B4, B2*B5, B2*B6, B2*B7,
B3*B0, B3*B1, B3*B2, B3*B3, B3*B4, B3*B5, B3*B6, B3*B7,
B4*B0, B4*B1, B4*B2, B4*B3, B4*B4, B4*B5, B4*B6, B4*B7,
B5*B0, B5*B1, B5*B2, B5*B3, B5*B4, B5*B5, B5*B6, B5*B7,
B6*B0, B6*B1, B6*B2, B6*B3, B6*B4, B6*B5, B6*B6, B6*B7,
B7*B0, B7*B1, B7*B2, B7*B3, B7*B4, B7*B5, B7*B6, B7*B7,
};

static av_always_inline void row_fdct(FLOAT temp[64], int16_t *data)
{
    FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    FLOAT tmp10, tmp11, tmp12, tmp13;
    FLOAT z2, z4, z11, z13;
    int i;

    for (i=0; i<8*8; i+=8) {
        tmp0= data[0 + i] + data[7 + i];
        tmp7= data[0 + i] - data[7 + i];
        tmp1= data[1 + i] + data[6 + i];
        tmp6= data[1 + i] - data[6 + i];
        tmp2= data[2 + i] + data[5 + i];
        tmp5= data[2 + i] - data[5 + i];
        tmp3= data[3 + i] + data[4 + i];
        tmp4= data[3 + i] - data[4 + i];

        tmp10= tmp0 + tmp3;
        tmp13= tmp0 - tmp3;
        tmp11= tmp1 + tmp2;
        tmp12= tmp1 - tmp2;

        temp[0 + i]= tmp10 + tmp11;
        temp[4 + i]= tmp10 - tmp11;

        tmp12 += tmp13;
        tmp12 *= A1;
        temp[2 + i]= tmp13 + tmp12;
        temp[6 + i]= tmp13 - tmp12;

        tmp4 += tmp5;
        tmp5 += tmp6;
        tmp6 += tmp7;

        z2= tmp4*(A2+A5) - tmp6*A5;
        z4= tmp6*(A4-A5) + tmp4*A5;

        tmp5*=A1;

        z11= tmp7 + tmp5;
        z13= tmp7 - tmp5;

        temp[5 + i]= z13 + z2;
        temp[3 + i]= z13 - z2;
        temp[1 + i]= z11 + z4;
        temp[7 + i]= z11 - z4;
    }
}

void ff_faandct(int16_t *data)
{
    FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    FLOAT tmp10, tmp11, tmp12, tmp13;
    FLOAT z2, z4, z11, z13;
    FLOAT temp[64];
    int i;

    emms_c();

    row_fdct(temp, data);

    for (i=0; i<8; i++) {
        tmp0= temp[8*0 + i] + temp[8*7 + i];
        tmp7= temp[8*0 + i] - temp[8*7 + i];
        tmp1= temp[8*1 + i] + temp[8*6 + i];
        tmp6= temp[8*1 + i] - temp[8*6 + i];
        tmp2= temp[8*2 + i] + temp[8*5 + i];
        tmp5= temp[8*2 + i] - temp[8*5 + i];
        tmp3= temp[8*3 + i] + temp[8*4 + i];
        tmp4= temp[8*3 + i] - temp[8*4 + i];

        tmp10= tmp0 + tmp3;
        tmp13= tmp0 - tmp3;
        tmp11= tmp1 + tmp2;
        tmp12= tmp1 - tmp2;

        data[8*0 + i]= lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
        data[8*4 + i]= lrintf(postscale[8*4 + i] * (tmp10 - tmp11));

        tmp12 += tmp13;
        tmp12 *= A1;
        data[8*2 + i]= lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
        data[8*6 + i]= lrintf(postscale[8*6 + i] * (tmp13 - tmp12));

        tmp4 += tmp5;
        tmp5 += tmp6;
        tmp6 += tmp7;

        z2= tmp4*(A2+A5) - tmp6*A5;
        z4= tmp6*(A4-A5) + tmp4*A5;

        tmp5*=A1;

        z11= tmp7 + tmp5;
        z13= tmp7 - tmp5;

        data[8*5 + i]= lrintf(postscale[8*5 + i] * (z13 + z2));
        data[8*3 + i]= lrintf(postscale[8*3 + i] * (z13 - z2));
        data[8*1 + i]= lrintf(postscale[8*1 + i] * (z11 + z4));
        data[8*7 + i]= lrintf(postscale[8*7 + i] * (z11 - z4));
    }
}

void ff_faandct248(int16_t *data)
{
    FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
    FLOAT tmp10, tmp11, tmp12, tmp13;
    FLOAT temp[64];
    int i;

    emms_c();

    row_fdct(temp, data);

    for (i=0; i<8; i++) {
        tmp0 = temp[8*0 + i] + temp[8*1 + i];
        tmp1 = temp[8*2 + i] + temp[8*3 + i];
        tmp2 = temp[8*4 + i] + temp[8*5 + i];
        tmp3 = temp[8*6 + i] + temp[8*7 + i];
        tmp4 = temp[8*0 + i] - temp[8*1 + i];
        tmp5 = temp[8*2 + i] - temp[8*3 + i];
        tmp6 = temp[8*4 + i] - temp[8*5 + i];
        tmp7 = temp[8*6 + i] - temp[8*7 + i];

        tmp10 = tmp0 + tmp3;
        tmp11 = tmp1 + tmp2;
        tmp12 = tmp1 - tmp2;
        tmp13 = tmp0 - tmp3;

        data[8*0 + i] = lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
        data[8*4 + i] = lrintf(postscale[8*4 + i] * (tmp10 - tmp11));

        tmp12 += tmp13;
        tmp12 *= A1;
        data[8*2 + i] = lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
        data[8*6 + i] = lrintf(postscale[8*6 + i] * (tmp13 - tmp12));

        tmp10 = tmp4 + tmp7;
        tmp11 = tmp5 + tmp6;
        tmp12 = tmp5 - tmp6;
        tmp13 = tmp4 - tmp7;

        data[8*1 + i] = lrintf(postscale[8*0 + i] * (tmp10 + tmp11));
        data[8*5 + i] = lrintf(postscale[8*4 + i] * (tmp10 - tmp11));

        tmp12 += tmp13;
        tmp12 *= A1;
        data[8*3 + i] = lrintf(postscale[8*2 + i] * (tmp13 + tmp12));
        data[8*7 + i] = lrintf(postscale[8*6 + i] * (tmp13 - tmp12));
    }
}
