/*
 * jdhuff.c
 *
 * Copyright (C) 1991, 1992, Thomas G. Lane.
 * This file is part of the Independent JPEG Group's software.
 * For conditions of distribution and use, see the accompanying README file.
 *
 * This file contains Huffman entropy decoding routines.
 * These routines are invoked via the methods entropy_decode
 * and entropy_decode_init/term.
 */

#include "jinclude.h"

#include "time.h"


extern void huff_DECODE(JBLOCKROW *, short); /* RICK 2004/01/29 */


/*
 * Frankie !
 */
INT32 GetBuffer;                /* current bit-extraction buffer */
int BitsLeft;                   /* # of unused bits in it */
int * ByteInBuffer;             /* @ cinfo -> bytes_in_buffer */
char ** NextInputByte;          /* @ cinfo -> next_input_byte */
void * ReadJpegData;            /* @ cinfo ... read_jpeg_data */
decompress_info_ptr CInfo;      /* cinfo */
QUANT_TBL_PTR QuantTbl[3];
DC_HUFF_TBL * DCTbl[3];
AC_HUFF_TBL * ACTbl[3];
int * LastDCVal[3];
int * MCUMember;

LOCAL void fix_ac_huff_tbl(AC_HUFF_TBL * htbl)
/* Compute derived values for a AC Huffman table */
{
int p,
    i,
    l,
    si;

UINT16 huffcode[257];
UINT8 huffsize[257];
UINT16 code,
       rawindex;
INT32 rawelt;

    /* Figure C.1: make table of Huffman code length for each symbol */
    /* Note that this is in code-length order. */

    p = 0;
    for (l = 1; l <= 16; l++)
    {
        for (i = 1; i <= (int) htbl -> bits[l]; i++)
            huffsize[p++] = (char) l;
    }
    huffsize[p] = 0;

    /* Figure C.2: generate the codes themselves */
    /* Note that this is in code-length order. */

    code = 0;
    si = huffsize[0];
    p = 0;
    while (huffsize[p])
    {
        while (((int) huffsize[p]) == si)
        {
            huffcode[p++] = code;
            code++;
        }
        code <<= 1;
        si++;
    }

    /* We don't bother to fill in the encoding tables ehufco[] and ehufsi[], */
    /* since they are not used for decoding. */

    /* Figure F.15: generate decoding tables */

    p = 0;
    for (l = 1; l <= 16; l++)
    {
        if (htbl -> bits[l])
        {
            htbl -> valptr[l] = p;      /* huffval[] index of 1st sym of code len l */
            htbl -> mincode[l] = huffcode[p];   /* minimum code of length l */
            p += htbl -> bits[l];
            htbl -> maxcode[l] = huffcode[p - 1];       /* maximum code of length l */
        }
        else
        {
            htbl -> maxcode[l] = -1;
        }
    }
    htbl -> maxcode[17] = 0xFFFFFL;     /* ensures huff_DECODE terminates */

    /*
     * Frankie !
     */
    p = 0;
    /* huffcode in code length order ... , AC_TBL_SIZE bits in table for huff data */
    while(si=huffsize[p])
    {
        code = huffcode[p];
        if (si < AC_TBL_SIZE)
        {
            /* code length is < AC_TBL_SIZE bits */

            for (i = 0; i < (1 << (AC_TBL_SIZE - si)); i++)
            {
                /* code is up part */
                rawindex = code << (AC_TBL_SIZE - si);

                /* following data is down part */
                rawindex = rawindex | i;

                /* code is 31 - 13 */
                rawelt = code << 12;

                /* size is 12 - 8 */
                rawelt = rawelt | ( si << 8 );

                /* value is 7 - 0 */
                rawelt = rawelt | htbl -> huffval[p];

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;
            }
        }
        else
        {
            if (si == AC_TBL_SIZE)
            {
                /* code length is = AC_TBL_SIZE bits */

                /* code is whole index */
                rawindex = code;

                /* code is 31 - 13 */
                rawelt = code << 12;

                /* size is 12 - 8 */
                rawelt = rawelt | ( si << 8 );

                /* value is 7 - 0 */
                rawelt = rawelt | htbl -> huffval[p];

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;
            }

            else
            {
                /* code length is > AC_TBL_SIZE bits */
                /* can be exec several time for same first AC_TBL_SIZE bits codes */

                /* index ( AC_TBL_SIZE bits ) is beginning of the code */
                rawindex = code >> (si - AC_TBL_SIZE);

                /* code is 31 - 13 */
                rawelt = rawindex << 12;

                /* size is 12 - 8 ( AC_TBL_SIZE + 1 special number ) */
                rawelt = rawelt | ( ( AC_TBL_SIZE + 1 ) << 8 );

                /* can't provide the value */

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;

            };

        };
p++;

    };

}


LOCAL void fix_dc_huff_tbl(DC_HUFF_TBL * htbl)
/* Compute derived values for a DC Huffman table */
{
int p,
    i,
    l,
    si;

UINT16 huffcode[257];
UINT8 huffsize[257];
UINT16 code,
       rawindex;
INT32 rawelt;
    /* Figure C.1: make table of Huffman code length for each symbol */
    /* Note that this is in code-length order. */

    p = 0;
    for (l = 1; l <= 16; l++)
    {
        for (i = 1; i <= (int) htbl -> bits[l]; i++)
            huffsize[p++] = (char) l;
    }
    huffsize[p] = 0;

    /* Figure C.2: generate the codes themselves */
    /* Note that this is in code-length order. */

    code = 0;
    si = huffsize[0];
    p = 0;
    while (huffsize[p])
    {
        while (((int) huffsize[p]) == si)
        {
            huffcode[p++] = code;
            code++;
        }
        code <<= 1;
        si++;
    }

    /* We don't bother to fill in the encoding tables ehufco[] and ehufsi[], */
    /* since they are not used for decoding. */

    /* Figure F.15: generate decoding tables */

    p = 0;
    for (l = 1; l <= 16; l++)
    {
        if (htbl -> bits[l])
        {
            htbl -> valptr[l] = p;      /* huffval[] index of 1st sym of code len l */
            htbl -> mincode[l] = huffcode[p];   /* minimum code of length l */
            p += htbl -> bits[l];
            htbl -> maxcode[l] = huffcode[p - 1];       /* maximum code of length l */
        }
        else
        {
            htbl -> maxcode[l] = -1;
        }
    }
    htbl -> maxcode[17] = 0xFFFFFL;     /* ensures huff_DECODE terminates */
    /*
     * Frankie !
     */
    p = 0;
    /* huffcode in code length order ... , 8 bits in table for huff data */
    while(si=huffsize[p])
    {
        code = huffcode[p];
        if (si < DC_TBL_SIZE)
        {
            /* code length is < DC_TBL_SIZE bits */

            for (i = 0; i < (1 << (DC_TBL_SIZE - si)); i++)
            {
                /* code is up part */
                rawindex = code << (DC_TBL_SIZE - si);

                /* following data is down part */
                rawindex = rawindex | i;

                /* code is 31 - 13 */
                rawelt = code << 12;

                /* size is 12 - 8 */
                rawelt = rawelt | ( si << 8 );

                /* value is 7 - 0 */
                rawelt = rawelt | htbl -> huffval[p];

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;

            }
        }
        else
        {
            if (si == DC_TBL_SIZE)
            {
                /* code length is = DC_TBL_SIZE bits */

                /* code is whole index */
                rawindex = code;

                /* code is 31 - 13 */
                rawelt = code << 12;

                /* size is 12 - 8 */
                rawelt = rawelt | ( si << 8 );

                /* value is 7 - 0 */
                rawelt = rawelt | htbl -> huffval[p];

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;
            }

            else
            {
                /* code length is > DC_TBL_SIZE bits */
                /* can be exec several time for same first DC_TBL_SIZE bits codes */

                /* index ( DC_TBL_SIZE bits ) is beginning of the code */
                rawindex = code >> (si - DC_TBL_SIZE);

                /* code is 31 - 13 */
                rawelt = rawindex << 12;

                /* size is 12 - 8 ( DC_TBL_SIZE + 1 special number ) */
                rawelt = rawelt | ( ( DC_TBL_SIZE + 1 ) << 8 );

                /* can't provide the value */

                /* fill the table */
                htbl -> raw_code20_size4_symbol8[rawindex] = rawelt;
            };

        };
p++;

    };

}


/*
 * Initialize for a Huffman-compressed scan.
 * This is invoked after reading the SOS marker.
 */

METHODDEF void
    huff_decoder_init(decompress_info_ptr cinfo)
{
short ci;
jpeg_component_info *compptr;

   /* Initialize static variables */
   BitsLeft = 0;
   ByteInBuffer = &(cinfo->bytes_in_buffer);
   NextInputByte = &(cinfo->next_input_byte);
   ReadJpegData = (void *)cinfo->methods->read_jpeg_data;
   CInfo = cinfo;
   MCUMember = cinfo->MCU_membership;

   for (ci = 0; ci < cinfo->comps_in_scan; ci++)
   {
      compptr = cinfo->cur_comp_info[ci];
      /* Make sure requested tables are present */
      if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
          cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
         ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
      /* Compute derived values for Huffman tables */
      /*
         We may do this more than once for same table, but it's not a big
         deal
      */
      fix_dc_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
      fix_ac_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
      /* Initialize DC predictions to 0 */
      cinfo->last_dc_val[ci] = 0;
   }

   /* Initialize restart stuff */
   cinfo->restarts_to_go = cinfo->restart_interval;
   cinfo->next_restart_num = 0;
}


/*
 * Check for a restart marker & resynchronize decoder.
 */
LOCAL void process_restart(decompress_info_ptr cinfo)
{
int c, nbytes;
short ci;

   /* Throw away any unused bits remaining in bit buffer */
   nbytes = BitsLeft / 8;      /* count any full bytes loaded into buffer */
   BitsLeft = 0;

   /* Scan for next JPEG marker */
   do
   {
      do
      {                         /* skip any non-FF bytes */
         nbytes++;
         c = JGETC(cinfo);
      } while (c != 0xFF);
      do
      {                         /* skip any duplicate FFs */
         /* we don't increment nbytes here since extra FFs are legal */
         c = JGETC(cinfo);
      } while (c == 0xFF);
   } while (c == 0);            /* repeat if it was a stuffed FF/00 */

   if (nbytes != 1)
      WARNMS2(cinfo->emethods,
              "Corrupt JPEG data: %d extraneous bytes before marker 0x%02x",
              nbytes - 1, c);

   if (c != (RST0 + cinfo->next_restart_num))
   {
      /* Uh-oh, the restart markers have been messed up too. */
      /* Let the file-format module try to figure out how to resync. */
      (*cinfo->methods->resync_to_restart) (cinfo, c);
   } else
      TRACEMS1(cinfo->emethods, 2, "RST%d", cinfo->next_restart_num);

   /* Re-initialize DC predictions to 0 */
   for (ci = 0; ci < cinfo->comps_in_scan; ci++)
      cinfo->last_dc_val[ci] = 0;

   /* Update restart state */
   cinfo->restarts_to_go = cinfo->restart_interval;
   cinfo->next_restart_num = (cinfo->next_restart_num + 1) & 7;
}


/* ZAG[i] is the natural-order position of the i'th element of zigzag order.
 * If the incoming data is corrupted, huff_decode_mcu could attempt to
 * reference values beyond the end of the array.  To avoid a wild store,
 * we put some extra zeroes after the real entries.
 */

/*
 * Frankie !
 */
int ZAG[DCTSIZE2 + 16] =
{
   0, 1, 8, 16, 9, 2, 3, 10,
   17, 24, 32, 25, 18, 11, 4, 5,
   12, 19, 26, 33, 40, 48, 41, 34,
   27, 20, 13, 6, 7, 14, 21, 28,
   35, 42, 49, 56, 57, 50, 43, 36,
   29, 22, 15, 23, 30, 37, 44, 51,
   58, 59, 52, 45, 38, 31, 39, 46,
   53, 60, 61, 54, 47, 55, 62, 63,
   0, 0, 0, 0, 0, 0, 0, 0,      /* extra entries in case k>63 below */
   0, 0, 0, 0, 0, 0, 0, 0
};


/*
 * Decode and return one MCU's worth of Huffman-compressed coefficients.
 * This routine also handles quantization descaling and zigzag reordering
 * of coefficient values.
 *
 * The i'th block of the MCU is stored into the block pointed to by
 * MCU_data[i].  WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
 * (Wholesale zeroing is usually a little faster than retail...)
 */

METHODDEF void
    huff_decode_mcu(decompress_info_ptr cinfo, JBLOCKROW * MCU_data)
{
register int ci;
jpeg_component_info *compptr;


   /* Account for restart interval, process restart marker if needed */
   if (cinfo->restart_interval)
   {
      if (cinfo->restarts_to_go == 0)
         process_restart(cinfo);
      cinfo->restarts_to_go--;
   }

   /* Outer loop handles each block in the MCU */
   for(ci=0;ci < cinfo->comps_in_scan;ci++)
   {
      compptr = cinfo->cur_comp_info[ci];
      QuantTbl[ci] = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
      ACTbl[ci] = cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no];
      DCTbl[ci] = cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no];
      LastDCVal[ci] = &cinfo->last_dc_val[ci];
   };

   huff_DECODE(MCU_data,cinfo->blocks_in_MCU);
}


/*
 * Finish up at the end of a Huffman-compressed scan.
 */

METHODDEF void
    huff_decoder_term(decompress_info_ptr cinfo)
{
   /* No work needed */
}


/*
 * The method selection routine for Huffman entropy decoding.
 */

GLOBAL void
    jseldhuffman(decompress_info_ptr cinfo)
{
   if (!cinfo->arith_code)
   {
      cinfo->methods->entropy_decode_init = huff_decoder_init;
      cinfo->methods->entropy_decode = huff_decode_mcu;
      cinfo->methods->entropy_decode_term = huff_decoder_term;
   }
}
