123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /* ***** BEGIN LICENSE BLOCK *****
- * Source last modified: $Id: huffman.c,v 1.2 2005/05/24 16:01:55 albertofloyd Exp $
- *
- * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file,
- * are subject to the current version of the RealNetworks Public
- * Source License (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the current version of the RealNetworks Community
- * Source License (the "RCSL") available at
- * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
- * will apply. You may also obtain the license terms directly from
- * RealNetworks. You may not use this file except in compliance with
- * the RPSL or, if you have a valid RCSL with RealNetworks applicable
- * to this file, the RCSL. Please see the applicable RPSL or RCSL for
- * the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the
- * portions it created.
- *
- * This file, and the files included with this file, is distributed
- * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
- * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
- * ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /**************************************************************************************
- * Fixed-point HE-AAC decoder
- * Jon Recker (jrecker@real.com)
- * February 2005
- *
- * huffman.c - Huffman decoding
- **************************************************************************************/
- #include "coder.h"
- /**************************************************************************************
- * Function: DecodeHuffmanScalar
- *
- * Description: decode one Huffman symbol from bitstream
- *
- * Inputs: pointers to Huffman table and info struct
- * left-aligned bit buffer with >= huffTabInfo->maxBits bits
- *
- * Outputs: decoded symbol in *val
- *
- * Return: number of bits in symbol
- *
- * Notes: assumes canonical Huffman codes:
- * first CW always 0, we have "count" CW's of length "nBits" bits
- * starting CW for codes of length nBits+1 =
- * (startCW[nBits] + count[nBits]) << 1
- * if there are no codes at nBits, then we just keep << 1 each time
- * (since count[nBits] = 0)
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ int DecodeHuffmanScalar(const signed short *huffTab, const HuffInfo *huffTabInfo, unsigned int bitBuf, signed int *val)
- {
- unsigned int count, start, shift, t;
- const unsigned /*char*/ int *countPtr;
- const signed short *map;
- map = huffTab + huffTabInfo->offset;
- countPtr = huffTabInfo->count;
- start = 0;
- count = 0;
- shift = 32;
- do {
- start += count;
- start <<= 1;
- map += count;
- count = *countPtr++;
- shift--;
- t = (bitBuf >> shift) - start;
- } while (t >= count);
-
- *val = (signed int)pgm_read_word(&map[t]);
- return (countPtr - huffTabInfo->count);
- }
- #define APPLY_SIGN(v, s) {(v) ^= ((signed int)(s) >> 31); (v) -= ((signed int)(s) >> 31);}
- #define GET_QUAD_SIGNBITS(v) (((unsigned int)(v) << 17) >> 29) /* bits 14-12, unsigned */
- #define GET_QUAD_W(v) (((signed int)(v) << 20) >> 29) /* bits 11-9, sign-extend */
- #define GET_QUAD_X(v) (((signed int)(v) << 23) >> 29) /* bits 8-6, sign-extend */
- #define GET_QUAD_Y(v) (((signed int)(v) << 26) >> 29) /* bits 5-3, sign-extend */
- #define GET_QUAD_Z(v) (((signed int)(v) << 29) >> 29) /* bits 2-0, sign-extend */
- #define GET_PAIR_SIGNBITS(v) (((unsigned int)(v) << 20) >> 30) /* bits 11-10, unsigned */
- #define GET_PAIR_Y(v) (((signed int)(v) << 22) >> 27) /* bits 9-5, sign-extend */
- #define GET_PAIR_Z(v) (((signed int)(v) << 27) >> 27) /* bits 4-0, sign-extend */
- #define GET_ESC_SIGNBITS(v) (((unsigned int)(v) << 18) >> 30) /* bits 13-12, unsigned */
- #define GET_ESC_Y(v) (((signed int)(v) << 20) >> 26) /* bits 11-6, sign-extend */
- #define GET_ESC_Z(v) (((signed int)(v) << 26) >> 26) /* bits 5-0, sign-extend */
- /**************************************************************************************
- * Function: UnpackZeros
- *
- * Description: fill a section of coefficients with zeros
- *
- * Inputs: number of coefficients
- *
- * Outputs: nVals zeros, starting at coef
- *
- * Return: none
- *
- * Notes: assumes nVals is always a multiple of 4 because all scalefactor bands
- * are a multiple of 4 coefficients long
- **************************************************************************************/
- static void UnpackZeros(int nVals, int *coef)
- {
- while (nVals > 0) {
- *coef++ = 0;
- *coef++ = 0;
- *coef++ = 0;
- *coef++ = 0;
- nVals -= 4;
- }
- }
- /**************************************************************************************
- * Function: UnpackQuads
- *
- * Description: decode a section of 4-way vector Huffman coded coefficients
- *
- * Inputs BitStreamInfo struct pointing to start of codewords for this section
- * index of Huffman codebook
- * number of coefficients
- *
- * Outputs: nVals coefficients, starting at coef
- *
- * Return: none
- *
- * Notes: assumes nVals is always a multiple of 4 because all scalefactor bands
- * are a multiple of 4 coefficients long
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ static void UnpackQuads(BitStreamInfo *bsi, int cb, int nVals, int *coef)
- {
- int w, x, y, z, maxBits, nCodeBits, nSignBits, val;
- unsigned int bitBuf;
- maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 4;
- while (nVals > 0) {
- /* decode quad */
- bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits);
- nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET], bitBuf, &val);
- w = GET_QUAD_W(val);
- x = GET_QUAD_X(val);
- y = GET_QUAD_Y(val);
- z = GET_QUAD_Z(val);
- bitBuf <<= nCodeBits;
- nSignBits = (int)GET_QUAD_SIGNBITS(val);
- AdvanceBitstream(bsi, nCodeBits + nSignBits);
- if (nSignBits) {
- if (w) {APPLY_SIGN(w, bitBuf); bitBuf <<= 1;}
- if (x) {APPLY_SIGN(x, bitBuf); bitBuf <<= 1;}
- if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;}
- if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;}
- }
- *coef++ = w; *coef++ = x; *coef++ = y; *coef++ = z;
- nVals -= 4;
- }
- }
- /**************************************************************************************
- * Function: UnpackPairsNoEsc
- *
- * Description: decode a section of 2-way vector Huffman coded coefficients,
- * using non-esc tables (5 through 10)
- *
- * Inputs BitStreamInfo struct pointing to start of codewords for this section
- * index of Huffman codebook (must not be the escape codebook)
- * number of coefficients
- *
- * Outputs: nVals coefficients, starting at coef
- *
- * Return: none
- *
- * Notes: assumes nVals is always a multiple of 2 because all scalefactor bands
- * are a multiple of 4 coefficients long
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ static void UnpackPairsNoEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef)
- {
- int y, z, maxBits, nCodeBits, nSignBits, val;
- unsigned int bitBuf;
- maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2;
- while (nVals > 0) {
- /* decode pair */
- bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits);
- nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val);
- y = GET_PAIR_Y(val);
- z = GET_PAIR_Z(val);
- bitBuf <<= nCodeBits;
- nSignBits = GET_PAIR_SIGNBITS(val);
- AdvanceBitstream(bsi, nCodeBits + nSignBits);
- if (nSignBits) {
- if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;}
- if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;}
- }
- *coef++ = y; *coef++ = z;
- nVals -= 2;
- }
- }
- /**************************************************************************************
- * Function: UnpackPairsEsc
- *
- * Description: decode a section of 2-way vector Huffman coded coefficients,
- * using esc table (11)
- *
- * Inputs BitStreamInfo struct pointing to start of codewords for this section
- * index of Huffman codebook (must be the escape codebook)
- * number of coefficients
- *
- * Outputs: nVals coefficients, starting at coef
- *
- * Return: none
- *
- * Notes: assumes nVals is always a multiple of 2 because all scalefactor bands
- * are a multiple of 4 coefficients long
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ static void UnpackPairsEsc(BitStreamInfo *bsi, int cb, int nVals, int *coef)
- {
- int y, z, maxBits, nCodeBits, nSignBits, n, val;
- unsigned int bitBuf;
- maxBits = huffTabSpecInfo[cb - HUFFTAB_SPEC_OFFSET].maxBits + 2;
- while (nVals > 0) {
- /* decode pair with escape value */
- bitBuf = GetBitsNoAdvance(bsi, maxBits) << (32 - maxBits);
- nCodeBits = DecodeHuffmanScalar(huffTabSpec, &huffTabSpecInfo[cb-HUFFTAB_SPEC_OFFSET], bitBuf, &val);
- y = GET_ESC_Y(val);
- z = GET_ESC_Z(val);
- bitBuf <<= nCodeBits;
- nSignBits = GET_ESC_SIGNBITS(val);
- AdvanceBitstream(bsi, nCodeBits + nSignBits);
-
- if (y == 16) {
- n = 4;
- while (GetBits(bsi, 1) == 1)
- n++;
- y = (1 << n) + GetBits(bsi, n);
- }
- if (z == 16) {
- n = 4;
- while (GetBits(bsi, 1) == 1)
- n++;
- z = (1 << n) + GetBits(bsi, n);
- }
- if (nSignBits) {
- if (y) {APPLY_SIGN(y, bitBuf); bitBuf <<= 1;}
- if (z) {APPLY_SIGN(z, bitBuf); bitBuf <<= 1;}
- }
- *coef++ = y; *coef++ = z;
- nVals -= 2;
- }
- }
- /**************************************************************************************
- * Function: DecodeSpectrumLong
- *
- * Description: decode transform coefficients for frame with one long block
- *
- * Inputs: platform specific info struct
- * BitStreamInfo struct pointing to start of spectral data
- * (14496-3, table 4.4.29)
- * index of current channel
- *
- * Outputs: decoded, quantized coefficients for this channel
- *
- * Return: none
- *
- * Notes: adds in pulse data if present
- * fills coefficient buffer with zeros in any region not coded with
- * codebook in range [1, 11] (including sfb's above sfbMax)
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ void DecodeSpectrumLong(PSInfoBase *psi, BitStreamInfo *bsi, int ch)
- {
- int i, sfb, cb, nVals, offset;
- const /*short*/ int *sfbTab;
- unsigned char *sfbCodeBook;
- int *coef;
- ICSInfo *icsInfo;
- PulseInfo *pi;
- coef = psi->coef[ch];
- icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]);
- /* decode long block */
- sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx];
- sfbCodeBook = psi->sfbCodeBook[ch];
- for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
- cb = *sfbCodeBook++;
- nVals = sfbTab[sfb+1] - sfbTab[sfb];
-
- if (cb == 0)
- UnpackZeros(nVals, coef);
- else if (cb <= 4)
- UnpackQuads(bsi, cb, nVals, coef);
- else if (cb <= 10)
- UnpackPairsNoEsc(bsi, cb, nVals, coef);
- else if (cb == 11)
- UnpackPairsEsc(bsi, cb, nVals, coef);
- else
- UnpackZeros(nVals, coef);
- coef += nVals;
- }
- /* fill with zeros above maxSFB */
- nVals = NSAMPS_LONG - sfbTab[sfb];
- UnpackZeros(nVals, coef);
- /* add pulse data, if present */
- pi = &psi->pulseInfo[ch];
- if (pi->pulseDataPresent) {
- coef = psi->coef[ch];
- offset = sfbTab[pi->startSFB];
- for (i = 0; i < pi->numPulse; i++) {
- offset += pi->offset[i];
- if (coef[offset] > 0)
- coef[offset] += pi->amp[i];
- else
- coef[offset] -= pi->amp[i];
- }
- ASSERT(offset < NSAMPS_LONG);
- }
- }
- /**************************************************************************************
- * Function: DecodeSpectrumShort
- *
- * Description: decode transform coefficients for frame with eight short blocks
- *
- * Inputs: platform specific info struct
- * BitStreamInfo struct pointing to start of spectral data
- * (14496-3, table 4.4.29)
- * index of current channel
- *
- * Outputs: decoded, quantized coefficients for this channel
- *
- * Return: none
- *
- * Notes: fills coefficient buffer with zeros in any region not coded with
- * codebook in range [1, 11] (including sfb's above sfbMax)
- * deinterleaves window groups into 8 windows
- **************************************************************************************/
- /* __attribute__ ((section (".data"))) */ void DecodeSpectrumShort(PSInfoBase *psi, BitStreamInfo *bsi, int ch)
- {
- int gp, cb, nVals=0, win, offset, sfb;
- const /*short*/ int *sfbTab;
- unsigned char *sfbCodeBook;
- int *coef;
- ICSInfo *icsInfo;
- coef = psi->coef[ch];
- icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]);
- /* decode short blocks, deinterleaving in-place */
- sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx];
- sfbCodeBook = psi->sfbCodeBook[ch];
- for (gp = 0; gp < icsInfo->numWinGroup; gp++) {
- for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) {
- nVals = sfbTab[sfb+1] - sfbTab[sfb];
- cb = *sfbCodeBook++;
- for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
- offset = win*NSAMPS_SHORT;
- if (cb == 0)
- UnpackZeros(nVals, coef + offset);
- else if (cb <= 4)
- UnpackQuads(bsi, cb, nVals, coef + offset);
- else if (cb <= 10)
- UnpackPairsNoEsc(bsi, cb, nVals, coef + offset);
- else if (cb == 11)
- UnpackPairsEsc(bsi, cb, nVals, coef + offset);
- else
- UnpackZeros(nVals, coef + offset);
- }
- coef += nVals;
- }
- /* fill with zeros above maxSFB */
- for (win = 0; win < icsInfo->winGroupLen[gp]; win++) {
- offset = win*NSAMPS_SHORT;
- nVals = NSAMPS_SHORT - sfbTab[sfb];
- UnpackZeros(nVals, coef + offset);
- }
- coef += nVals;
- coef += (icsInfo->winGroupLen[gp] - 1)*NSAMPS_SHORT;
- }
- ASSERT(coef == psi->coef[ch] + NSAMPS_LONG);
- }
|