/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ /* Pathname: ./src/decode_huff_cw_binary.c Funtions: decode_huff_cw_tab1 decode_huff_cw_tab2 decode_huff_cw_tab3 decode_huff_cw_tab4 decode_huff_cw_tab5 decode_huff_cw_tab6 decode_huff_cw_tab7 decode_huff_cw_tab8 decode_huff_cw_tab9 decode_huff_cw_tab10 decode_huff_cw_tab11 decode_huff_cw_scl ------------------------------------------------------------------------------ REVISION HISTORY Description: Updated per review comments (1) make cw sgined and change "if(cw&0x80000000)" to if(cw<0) (2) Description: Create specific functions for different huffman tables. Description: Added ( Int16) castings to eliminate several compiler warnings Description: Modified huffman tables to allocate int32 variables instead of int16, which lead to data missaligned for some compiler. Eliminated casting and unused variables Who: Date: Description: ------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: BITS *pInputStream = pointer to input bit stream Local Stores/Buffers/Pointers Needed: Global Stores/Buffers/Pointers Needed: Outputs: idx = bit field extracted from a leaf entry of packed Huffman Tables Pointers and Buffers Modified: Local Stores Modified: Global Stores Modified: ------------------------------------------------------------------------------ FUNCTION DESCRIPTION These functions are used to decode huffman codewords from the input bitstream using combined binary search and look-up table approach. First the codewords are grouped and the input symbol is determined which group it belongs. Then within that group, a look-up table is used to determine which codeword the symbol is. The table is created by ordering the codeword in the table according to their normalized shifted binary value, i.e., all the codewords are left shifted to meet the maximum codelength. Example, max codelength is 10, the codeword with lenth 3 will left shift by 7. The binary values of after the shift are sorted. Then the sorted table is divided into several partition. At the VLC decoding period, input is read in at max codelenght. The partition is decided using if-else logic. Inside each partition, a look-up table is used to map the input value to a correct symbol. Table entries can appear to be repeated according to the humming distance between adjacent codewords. ------------------------------------------------------------------------------ REQUIREMENTS ------------------------------------------------------------------------------ REFERENCES (1) MPEG-2 NBC Audio Decoder "This software module was originally developed by AT&T, Dolby Laboratories, Fraunhofer Gesellschaft IIS in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4 Audio standards. Those intending to use this software module in hardware or software products are advised that this use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-2 NBC/MPEG-4 Audio conforming products.The original developer retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third party from using the code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice must be included in all copies or derivative works." Copyright(c)1996. (2) Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest. The MIT press, 1990 (3) "Selecting an Optimal Huffman Decoder for AAC", Vladimir Z. Mesarovic, et al. AES 111th Convention, September 21-24, 2001, New York, USA ------------------------------------------------------------------------------ PSEUDO-CODE ------------------------------------------------------------------------------ RESOURCES USED When the code is written for a specific target processor the the resources used should be documented below. STACK USAGE: DATA MEMORY USED: x words PROGRAM MEMORY USED: x words CLOCK CYCLES: ------------------------------------------------------------------------------ */ /*---------------------------------------------------------------------------- ; INCLUDES ----------------------------------------------------------------------------*/ #include "pv_audio_type_defs.h" #include "huffman.h" /*---------------------------------------------------------------------------- ; MACROS ; Define module specific macros here ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; DEFINES ; Include all pre-processor statements here. Include conditional ; compile variables also. ----------------------------------------------------------------------------*/ #define MAX_CW_LEN (19) #define MASK_IDX (0x1FF) #define MASK_RIGHT (0xFE00) #define UPPER16 (16) #define MASK_LOW16 (0xFFFF) /*---------------------------------------------------------------------------- ; LOCAL FUNCTION DEFINITIONS ; Function Prototype declaration ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; LOCAL STORE/BUFFER/POINTER DEFINITIONS ; Variable declaration - defined here and used outside this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL FUNCTION REFERENCES ; Declare functions defined elsewhere and referenced in this module ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES ; Declare variables used in this module but defined elsewhere ----------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------- ; FUNCTION CODE ----------------------------------------------------------------------------*/ Int decode_huff_cw_tab1( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 11, pInputStream); if ((cw >> 10) == 0) { pInputStream->usedBits -= (11 - 1); return 40; /* idx is 40 */ } else if ((cw >> 6) <= 23) { tab = (cw >> 6) - 16; } else if ((cw >> 4) <= 119) { tab = (cw >> 4) - 96 + 8; } else if ((cw >> 2) <= 503) { tab = (cw >> 2) - 480 + 32; } else { tab = cw - 2016 + 56; } tab = *(huff_tab1 + tab); pInputStream->usedBits -= (11 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab2( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get9_n_lessbits( 9, pInputStream); if ((cw >> 6) == 0) { pInputStream->usedBits -= (9 - 3); /* used 3 bits */ return 40; /* idx is 40 */ } else if ((cw >> 3) <= 49) { tab = (cw >> 3) - 8; } else if ((cw >> 2) <= 114) { tab = (cw >> 2) - 100 + 42; } else if ((cw >> 1) <= 248) { tab = (cw >> 1) - 230 + 57; } else { tab = cw - 498 + 76; } tab = *(huff_tab2 + tab); pInputStream->usedBits -= (9 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab3( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 16, pInputStream); if ((cw >> 15) == 0) { pInputStream->usedBits -= (16 - 1); /* used 1 bits */ return 0; /* idx is 0 */ } else if ((cw >> 10) <= 57) { tab = (cw >> 10) - 32; } else if ((cw >> 7) <= 500) { tab = (cw >> 7) - 464 + 26; } else if ((cw >> 6) <= 1016) { tab = (cw >> 6) - 1002 + 63; } else if ((cw >> 4) <= 4092) { tab = (cw >> 4) - 4068 + 78; } else { tab = cw - 65488 + 103; } tab = *(huff_tab3 + tab); pInputStream->usedBits -= (16 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab4( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 12, pInputStream); if ((cw >> 7) <= 25) { tab = (cw >> 7); } else if ((cw >> 4) <= 246) { tab = (cw >> 4) - 208 + 26; } else if ((cw >> 2) <= 1017) { tab = (cw >> 2) - 988 + 65; } else { tab = cw - 4072 + 95; } tab = *(huff_tab4 + tab); pInputStream->usedBits -= (12 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab5( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 13, pInputStream); if ((cw >> 12) == 0) { pInputStream->usedBits -= (13 - 1); /* used 1 bits */ return 40; /* idx is 40 */ } else if ((cw >> 8) <= 27) { tab = (cw >> 8) - 16; } else if ((cw >> 5) <= 243) { tab = (cw >> 5) - 224 + 12; } else if ((cw >> 3) <= 1011) { tab = (cw >> 3) - 976 + 32; } else if ((cw >> 2) <= 2041) { tab = (cw >> 2) - 2024 + 68; } else { tab = cw - 8168 + 86; } tab = *(huff_tab5 + tab); pInputStream->usedBits -= (13 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab6( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 11, pInputStream); if ((cw >> 7) <= 8) { tab = (cw >> 7); } else if ((cw >> 4) <= 116) { tab = (cw >> 4) - 72 + 9; } else if ((cw >> 2) <= 506) { tab = (cw >> 2) - 468 + 54; } else { tab = cw - 2028 + 93; } tab = *(huff_tab6 + tab); pInputStream->usedBits -= (11 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab7( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 12, pInputStream); if ((cw >> 11) == 0) { pInputStream->usedBits -= (12 - 1); /* used 1 bits */ return 0; /* idx is 0 */ } else if ((cw >> 6) <= 55) { tab = (cw >> 6) - 32; } else if ((cw >> 4) <= 243) { tab = (cw >> 4) - 224 + 24; } else if ((cw >> 2) <= 1018) { tab = (cw >> 2) - 976 + 44; } else { tab = cw - 4076 + 87; } tab = *(huff_tab7 + tab); pInputStream->usedBits -= (12 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab8( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 10, pInputStream); if ((cw >> 5) <= 20) { tab = (cw >> 5); } else if ((cw >> 3) <= 117) { tab = (cw >> 3) - 84 + 21; } else if ((cw >> 2) <= 250) { tab = (cw >> 2) - 236 + 55; } else { tab = cw - 1004 + 70; } tab = *(huff_tab8 + tab); pInputStream->usedBits -= (10 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab9( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 15, pInputStream); if ((cw >> 11) <= 12) { tab = (cw >> 11); } else if ((cw >> 8) <= 114) { tab = (cw >> 8) - 104 + 13; } else if ((cw >> 6) <= 486) { tab = (cw >> 6) - 460 + 24; } else if ((cw >> 5) <= 993) { tab = (cw >> 5) - 974 + 51; } else if ((cw >> 4) <= 2018) { tab = (cw >> 4) - 1988 + 71; } else if ((cw >> 3) <= 4075) { tab = (cw >> 3) - 4038 + 102; } else if ((cw >> 2) <= 8183) { tab = (cw >> 2) - 8152 + 140; } else { tab = cw - 32736 + 172; } tab = *(huff_tab9 + tab); pInputStream->usedBits -= (15 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab10( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 12, pInputStream); if ((cw >> 6) <= 41) { tab = (cw >> 6); } else if ((cw >> 5) <= 100) { tab = (cw >> 5) - 84 + 42; } else if ((cw >> 4) <= 226) { tab = (cw >> 4) - 202 + 59; } else if ((cw >> 3) <= 484) { tab = (cw >> 3) - 454 + 84; } else if ((cw >> 2) <= 1010) { tab = (cw >> 2) - 970 + 115; } else if ((cw >> 1) <= 2043) { tab = (cw >> 1) - 2022 + 156; } else { tab = cw - 4088 + 178; } tab = *(huff_tab10 + tab); pInputStream->usedBits -= (12 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_cw_tab11( BITS *pInputStream) { Int32 tab; Int32 cw; cw = get17_n_lessbits( 12, pInputStream); if ((cw >> 6) <= 26) { tab = (cw >> 6); } else if ((cw >> 5) <= 69) { tab = (cw >> 5) - 54 + 27; } else if ((cw >> 4) <= 198) { tab = (cw >> 4) - 140 + 43; } else if ((cw >> 3) <= 452) { tab = (cw >> 3) - 398 + 102; } else if ((cw >> 2) <= 1000) { tab = (cw >> 2) - 906 + 157; } else if ((cw >> 1) <= 2044) { tab = (cw >> 1) - 2002 + 252; } else { tab = cw - 4090 + 295; } tab = *(huff_tab11 + tab); pInputStream->usedBits -= (12 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); } Int decode_huff_scl( BITS *pInputStream) { Int32 tab; Int32 cw; cw = getbits( 19, pInputStream); if ((cw >> 18) == 0) { pInputStream->usedBits -= (19 - 1); /* used 1 bits */ return 60; /* idx is 60 */ } else if ((cw >> 13) <= 59) { tab = (cw >> 13) - 32; } else if ((cw >> 10) <= 505) { tab = (cw >> 10) - 480 + 28; } else if ((cw >> 7) <= 4089) { tab = (cw >> 7) - 4048 + 54; } else if ((cw >> 5) <= 16377) { tab = (cw >> 5) - 16360 + 96; } else if ((cw >> 3) <= 65526) { tab = (cw >> 3) - 65512 + 114; } else if ((cw >> 1) <= 262120) { tab = (cw >> 1) - 262108 + 129; } else { tab = cw - 524242 + 142; } tab = *(huff_tab_scl + tab); pInputStream->usedBits -= (19 - (tab & MASK_LOW16)); return ((Int)(tab >> UPPER16)); }