/*
 * Copyright (C) 2004 the ffmpeg project
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file libavcodec/vp3dsp.c
 * Standard C DSP-oriented functions cribbed from the original VP3
 * source code.
 */

#include "avcodec.h"
#include "dsputil.h"

#define IdctAdjustBeforeShift 8
#define xC1S7 64277
#define xC2S6 60547
#define xC3S5 54491
#define xC4S4 46341
#define xC5S3 36410
#define xC6S2 25080
#define xC7S1 12785

#define M(a,b) (((a) * (b))>>16)

static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type)
{
    int16_t *ip = input;
    uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;

    int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
    int Ed, Gd, Add, Bdd, Fd, Hd;

    int i;

    /* Inverse DCT on the rows now */
    for (i = 0; i < 8; i++) {
        /* Check for non-zero values */
        if ( ip[0] | ip[1] | ip[2] | ip[3] | ip[4] | ip[5] | ip[6] | ip[7] ) {
            A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
            B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
            C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
            D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);

            Ad = M(xC4S4, (A - C));
            Bd = M(xC4S4, (B - D));

            Cd = A + C;
            Dd = B + D;

            E = M(xC4S4, (ip[0] + ip[4]));
            F = M(xC4S4, (ip[0] - ip[4]));

            G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
            H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);

            Ed = E - G;
            Gd = E + G;

            Add = F + Ad;
            Bdd = Bd - H;

            Fd = F - Ad;
            Hd = Bd + H;

            /*  Final sequence of operations over-write original inputs. */
            ip[0] = Gd + Cd ;
            ip[7] = Gd - Cd ;

            ip[1] = Add + Hd;
            ip[2] = Add - Hd;

            ip[3] = Ed + Dd ;
            ip[4] = Ed - Dd ;

            ip[5] = Fd + Bdd;
            ip[6] = Fd - Bdd;
        }

        ip += 8;            /* next row */
    }

    ip = input;

    for ( i = 0; i < 8; i++) {
        /* Check for non-zero values (bitwise or faster than ||) */
        if ( ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
             ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8] ) {

            A = M(xC1S7, ip[1*8]) + M(xC7S1, ip[7*8]);
            B = M(xC7S1, ip[1*8]) - M(xC1S7, ip[7*8]);
            C = M(xC3S5, ip[3*8]) + M(xC5S3, ip[5*8]);
            D = M(xC3S5, ip[5*8]) - M(xC5S3, ip[3*8]);

            Ad = M(xC4S4, (A - C));
            Bd = M(xC4S4, (B - D));

            Cd = A + C;
            Dd = B + D;

            E = M(xC4S4, (ip[0*8] + ip[4*8])) + 8;
            F = M(xC4S4, (ip[0*8] - ip[4*8])) + 8;

            if(type==1){  //HACK
                E += 16*128;
                F += 16*128;
            }

            G = M(xC2S6, ip[2*8]) + M(xC6S2, ip[6*8]);
            H = M(xC6S2, ip[2*8]) - M(xC2S6, ip[6*8]);

            Ed = E - G;
            Gd = E + G;

            Add = F + Ad;
            Bdd = Bd - H;

            Fd = F - Ad;
            Hd = Bd + H;

            /* Final sequence of operations over-write original inputs. */
            if(type==0){
                ip[0*8] = (Gd + Cd )  >> 4;
                ip[7*8] = (Gd - Cd )  >> 4;

                ip[1*8] = (Add + Hd ) >> 4;
                ip[2*8] = (Add - Hd ) >> 4;

                ip[3*8] = (Ed + Dd )  >> 4;
                ip[4*8] = (Ed - Dd )  >> 4;

                ip[5*8] = (Fd + Bdd ) >> 4;
                ip[6*8] = (Fd - Bdd ) >> 4;
            }else if(type==1){
                dst[0*stride] = cm[(Gd + Cd )  >> 4];
                dst[7*stride] = cm[(Gd - Cd )  >> 4];

                dst[1*stride] = cm[(Add + Hd ) >> 4];
                dst[2*stride] = cm[(Add - Hd ) >> 4];

                dst[3*stride] = cm[(Ed + Dd )  >> 4];
                dst[4*stride] = cm[(Ed - Dd )  >> 4];

                dst[5*stride] = cm[(Fd + Bdd ) >> 4];
                dst[6*stride] = cm[(Fd - Bdd ) >> 4];
            }else{
                dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd )  >> 4)];
                dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd )  >> 4)];

                dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)];
                dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)];

                dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd )  >> 4)];
                dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd )  >> 4)];

                dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)];
                dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)];
            }

        } else {
            if(type==0){
                ip[0*8] =
                ip[1*8] =
                ip[2*8] =
                ip[3*8] =
                ip[4*8] =
                ip[5*8] =
                ip[6*8] =
                ip[7*8] = ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
            }else if(type==1){
                dst[0*stride]=
                dst[1*stride]=
                dst[2*stride]=
                dst[3*stride]=
                dst[4*stride]=
                dst[5*stride]=
                dst[6*stride]=
                dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)];
            }else{
                if(ip[0*8]){
                    int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20);
                    dst[0*stride] = cm[dst[0*stride] + v];
                    dst[1*stride] = cm[dst[1*stride] + v];
                    dst[2*stride] = cm[dst[2*stride] + v];
                    dst[3*stride] = cm[dst[3*stride] + v];
                    dst[4*stride] = cm[dst[4*stride] + v];
                    dst[5*stride] = cm[dst[5*stride] + v];
                    dst[6*stride] = cm[dst[6*stride] + v];
                    dst[7*stride] = cm[dst[7*stride] + v];
                }
            }
        }

        ip++;            /* next column */
        dst++;
    }
}

void ff_vp3_idct_c(DCTELEM *block/* align 16*/){
    idct(NULL, 0, block, 0);
}

void ff_vp3_idct_put_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
    idct(dest, line_size, block, 1);
}

void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/*align 16*/){
    idct(dest, line_size, block, 2);
}

void ff_vp3_v_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
{
    unsigned char *end;
    int filter_value;
    const int nstride= -stride;

    for (end= first_pixel + 8; first_pixel < end; first_pixel++) {
        filter_value =
            (first_pixel[2 * nstride] - first_pixel[ stride])
         +3*(first_pixel[0          ] - first_pixel[nstride]);
        filter_value = bounding_values[(filter_value + 4) >> 3];
        first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
        first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
    }
}

void ff_vp3_h_loop_filter_c(uint8_t *first_pixel, int stride, int *bounding_values)
{
    unsigned char *end;
    int filter_value;

    for (end= first_pixel + 8*stride; first_pixel != end; first_pixel += stride) {
        filter_value =
            (first_pixel[-2] - first_pixel[ 1])
         +3*(first_pixel[ 0] - first_pixel[-1]);
        filter_value = bounding_values[(filter_value + 4) >> 3];
        first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
        first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
    }
}
