/***************************************************************************#
# jpegenc: library to encode a jpeg frame from various input palette.       #
# jpegenc works for embedded device without libjpeg                         #
#.                                                                          #
#       Copyright (C) 2005 Michel Xhaard                            #
#                                                                           #
# This program is free software; you can redistribute it and/or modify      #
# it under the terms of the GNU General Public License as published by      #
# the Free Software Foundation; either version 2 of the License, or         #
# (at your option) any later version.                                       #
#                                                                           #
# This program 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 General Public License for more details.                              #
#                                                                           #
# You should have received a copy of the GNU General Public License         #
# along with this program; if not, write to the Free Software               #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#  CREDIT:                                  #
# Original code from Nitin Gupta India (?)                      #
#                                                                           #
#***************************************************************************/


#include "jdatatype.h"
#include "quant.h"
#include "encoder.h"
static UINT8 zigzag_table[] = {
    0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17,
    25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52,
    54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36,
    48, 49, 57, 58, 62, 63
};


/*  This function implements 16 Step division for Q.15 format data */
UINT16 DSP_Division(UINT32 numer, UINT32 denom)
{
    UINT16 i;
    denom <<= 15;
    for(i = 16; i > 0; i--)

    {
        if(numer > denom)

        {
            numer -= denom;
            numer <<= 1;
            numer++;
        }

        else
            numer <<= 1;
    }
    return (UINT16) numer;
}


/* Multiply Quantization table with quality factor to get LQT and CQT */
void
initialize_quantization_tables(UINT32 quality_factor)
{
    UINT16 i, index;
    UINT32 value;
    UINT8 luminance_quant_table[] = {
        16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13,
        16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37,
        56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78,
        87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99
    };
    UINT8 chrominance_quant_table[] = {
        17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26,
        56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99,
        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
        99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99
    };
    for(i = 0; i < 64; i++)

    {
        index = zigzag_table[i];

        /* luminance quantization table * quality factor */
        value = luminance_quant_table[i] * quality_factor;
        value = (value + 0x200) >> 10;
        if(value == 0)
            value = 1;

        else if(value > 255)
            value = 255;
        Lqt[index] = (UINT8) value;
        ILqt[i] = DSP_Division(0x8000, value);

        /* chrominance quantization table * quality factor */
        value = chrominance_quant_table[i] * quality_factor;
        value = (value + 0x200) >> 10;
        if(value == 0)
            value = 1;

        else if(value > 255)
            value = 255;
        Cqt[index] = (UINT8) value;
        ICqt[i] = DSP_Division(0x8000, value);
    }
}


/* multiply DCT Coefficients with Quantization table and store in ZigZag location */
void
quantization(INT16 * const data, UINT16 * const quant_table_ptr)
{
    INT16 i;
    INT32 value;
    for(i = 63; i >= 0; i--)

    {
        value = data[i] * quant_table_ptr[i];
        value = (value + 0x4000) >> 15;
        Temp[zigzag_table[i]] = (INT16) value;
    }
}


