xref: /aosp_15_r20/external/aac/libAACdec/src/aacdec_hcr.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
5*e5436536SAndroid Build Coastguard Worker Forschung e.V. All rights reserved.
6*e5436536SAndroid Build Coastguard Worker 
7*e5436536SAndroid Build Coastguard Worker  1.    INTRODUCTION
8*e5436536SAndroid Build Coastguard Worker The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9*e5436536SAndroid Build Coastguard Worker that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10*e5436536SAndroid Build Coastguard Worker scheme for digital audio. This FDK AAC Codec software is intended to be used on
11*e5436536SAndroid Build Coastguard Worker a wide variety of Android devices.
12*e5436536SAndroid Build Coastguard Worker 
13*e5436536SAndroid Build Coastguard Worker AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14*e5436536SAndroid Build Coastguard Worker general perceptual audio codecs. AAC-ELD is considered the best-performing
15*e5436536SAndroid Build Coastguard Worker full-bandwidth communications codec by independent studies and is widely
16*e5436536SAndroid Build Coastguard Worker deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17*e5436536SAndroid Build Coastguard Worker specifications.
18*e5436536SAndroid Build Coastguard Worker 
19*e5436536SAndroid Build Coastguard Worker Patent licenses for necessary patent claims for the FDK AAC Codec (including
20*e5436536SAndroid Build Coastguard Worker those of Fraunhofer) may be obtained through Via Licensing
21*e5436536SAndroid Build Coastguard Worker (www.vialicensing.com) or through the respective patent owners individually for
22*e5436536SAndroid Build Coastguard Worker the purpose of encoding or decoding bit streams in products that are compliant
23*e5436536SAndroid Build Coastguard Worker with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24*e5436536SAndroid Build Coastguard Worker Android devices already license these patent claims through Via Licensing or
25*e5436536SAndroid Build Coastguard Worker directly from the patent owners, and therefore FDK AAC Codec software may
26*e5436536SAndroid Build Coastguard Worker already be covered under those patent licenses when it is used for those
27*e5436536SAndroid Build Coastguard Worker licensed purposes only.
28*e5436536SAndroid Build Coastguard Worker 
29*e5436536SAndroid Build Coastguard Worker Commercially-licensed AAC software libraries, including floating-point versions
30*e5436536SAndroid Build Coastguard Worker with enhanced sound quality, are also available from Fraunhofer. Users are
31*e5436536SAndroid Build Coastguard Worker encouraged to check the Fraunhofer website for additional applications
32*e5436536SAndroid Build Coastguard Worker information and documentation.
33*e5436536SAndroid Build Coastguard Worker 
34*e5436536SAndroid Build Coastguard Worker 2.    COPYRIGHT LICENSE
35*e5436536SAndroid Build Coastguard Worker 
36*e5436536SAndroid Build Coastguard Worker Redistribution and use in source and binary forms, with or without modification,
37*e5436536SAndroid Build Coastguard Worker are permitted without payment of copyright license fees provided that you
38*e5436536SAndroid Build Coastguard Worker satisfy the following conditions:
39*e5436536SAndroid Build Coastguard Worker 
40*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in redistributions of
41*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec or your modifications thereto in source code form.
42*e5436536SAndroid Build Coastguard Worker 
43*e5436536SAndroid Build Coastguard Worker You must retain the complete text of this software license in the documentation
44*e5436536SAndroid Build Coastguard Worker and/or other materials provided with redistributions of the FDK AAC Codec or
45*e5436536SAndroid Build Coastguard Worker your modifications thereto in binary form. You must make available free of
46*e5436536SAndroid Build Coastguard Worker charge copies of the complete source code of the FDK AAC Codec and your
47*e5436536SAndroid Build Coastguard Worker modifications thereto to recipients of copies in binary form.
48*e5436536SAndroid Build Coastguard Worker 
49*e5436536SAndroid Build Coastguard Worker The name of Fraunhofer may not be used to endorse or promote products derived
50*e5436536SAndroid Build Coastguard Worker from this library without prior written permission.
51*e5436536SAndroid Build Coastguard Worker 
52*e5436536SAndroid Build Coastguard Worker You may not charge copyright license fees for anyone to use, copy or distribute
53*e5436536SAndroid Build Coastguard Worker the FDK AAC Codec software or your modifications thereto.
54*e5436536SAndroid Build Coastguard Worker 
55*e5436536SAndroid Build Coastguard Worker Your modified versions of the FDK AAC Codec must carry prominent notices stating
56*e5436536SAndroid Build Coastguard Worker that you changed the software and the date of any change. For modified versions
57*e5436536SAndroid Build Coastguard Worker of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58*e5436536SAndroid Build Coastguard Worker must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59*e5436536SAndroid Build Coastguard Worker AAC Codec Library for Android."
60*e5436536SAndroid Build Coastguard Worker 
61*e5436536SAndroid Build Coastguard Worker 3.    NO PATENT LICENSE
62*e5436536SAndroid Build Coastguard Worker 
63*e5436536SAndroid Build Coastguard Worker NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64*e5436536SAndroid Build Coastguard Worker limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65*e5436536SAndroid Build Coastguard Worker Fraunhofer provides no warranty of patent non-infringement with respect to this
66*e5436536SAndroid Build Coastguard Worker software.
67*e5436536SAndroid Build Coastguard Worker 
68*e5436536SAndroid Build Coastguard Worker You may use this FDK AAC Codec software or modifications thereto only for
69*e5436536SAndroid Build Coastguard Worker purposes that are authorized by appropriate patent licenses.
70*e5436536SAndroid Build Coastguard Worker 
71*e5436536SAndroid Build Coastguard Worker 4.    DISCLAIMER
72*e5436536SAndroid Build Coastguard Worker 
73*e5436536SAndroid Build Coastguard Worker This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74*e5436536SAndroid Build Coastguard Worker holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75*e5436536SAndroid Build Coastguard Worker including but not limited to the implied warranties of merchantability and
76*e5436536SAndroid Build Coastguard Worker fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77*e5436536SAndroid Build Coastguard Worker CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78*e5436536SAndroid Build Coastguard Worker or consequential damages, including but not limited to procurement of substitute
79*e5436536SAndroid Build Coastguard Worker goods or services; loss of use, data, or profits, or business interruption,
80*e5436536SAndroid Build Coastguard Worker however caused and on any theory of liability, whether in contract, strict
81*e5436536SAndroid Build Coastguard Worker liability, or tort (including negligence), arising in any way out of the use of
82*e5436536SAndroid Build Coastguard Worker this software, even if advised of the possibility of such damage.
83*e5436536SAndroid Build Coastguard Worker 
84*e5436536SAndroid Build Coastguard Worker 5.    CONTACT INFORMATION
85*e5436536SAndroid Build Coastguard Worker 
86*e5436536SAndroid Build Coastguard Worker Fraunhofer Institute for Integrated Circuits IIS
87*e5436536SAndroid Build Coastguard Worker Attention: Audio and Multimedia Departments - FDK AAC LL
88*e5436536SAndroid Build Coastguard Worker Am Wolfsmantel 33
89*e5436536SAndroid Build Coastguard Worker 91058 Erlangen, Germany
90*e5436536SAndroid Build Coastguard Worker 
91*e5436536SAndroid Build Coastguard Worker www.iis.fraunhofer.de/amm
92*e5436536SAndroid Build Coastguard Worker [email protected]
93*e5436536SAndroid Build Coastguard Worker ----------------------------------------------------------------------------- */
94*e5436536SAndroid Build Coastguard Worker 
95*e5436536SAndroid Build Coastguard Worker /**************************** AAC decoder library ******************************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Robert Weidner (DSP Solutions)
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: HCR Decoder: HCR initialization, preprocess HCR sideinfo,
100*e5436536SAndroid Build Coastguard Worker                 decode priority codewords (PCWs)
101*e5436536SAndroid Build Coastguard Worker 
102*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
103*e5436536SAndroid Build Coastguard Worker 
104*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
105*e5436536SAndroid Build Coastguard Worker 
106*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr_types.h"
107*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr_bit.h"
108*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcrs.h"
109*e5436536SAndroid Build Coastguard Worker #include "aac_ram.h"
110*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
111*e5436536SAndroid Build Coastguard Worker #include "channel.h"
112*e5436536SAndroid Build Coastguard Worker #include "block.h"
113*e5436536SAndroid Build Coastguard Worker 
114*e5436536SAndroid Build Coastguard Worker #include "aacdecoder.h" /* for ID_CPE, ID_SCE ... */
115*e5436536SAndroid Build Coastguard Worker #include "FDK_bitstream.h"
116*e5436536SAndroid Build Coastguard Worker 
117*e5436536SAndroid Build Coastguard Worker extern int mlFileChCurr;
118*e5436536SAndroid Build Coastguard Worker 
119*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
120*e5436536SAndroid Build Coastguard Worker                                          UINT *errorWord);
121*e5436536SAndroid Build Coastguard Worker 
122*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
123*e5436536SAndroid Build Coastguard Worker                                     SHORT lengthOfReorderedSpectralData,
124*e5436536SAndroid Build Coastguard Worker                                     UINT *errorWord);
125*e5436536SAndroid Build Coastguard Worker 
126*e5436536SAndroid Build Coastguard Worker static void HcrCalcNumCodeword(H_HCR_INFO pHcr);
127*e5436536SAndroid Build Coastguard Worker static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr);
128*e5436536SAndroid Build Coastguard Worker static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr);
129*e5436536SAndroid Build Coastguard Worker static void HcrExtendedSectionInfo(H_HCR_INFO pHcr);
130*e5436536SAndroid Build Coastguard Worker 
131*e5436536SAndroid Build Coastguard Worker static void DeriveNumberOfExtendedSortedSectionsInSets(
132*e5436536SAndroid Build Coastguard Worker     UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
133*e5436536SAndroid Build Coastguard Worker     int numExtendedSortedCodewordInSectionIdx,
134*e5436536SAndroid Build Coastguard Worker     USHORT *pNumExtendedSortedSectionsInSets,
135*e5436536SAndroid Build Coastguard Worker     int numExtendedSortedSectionsInSetsIdx);
136*e5436536SAndroid Build Coastguard Worker 
137*e5436536SAndroid Build Coastguard Worker static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
138*e5436536SAndroid Build Coastguard Worker                                 INT quantSpecCoef, INT *pLeftStartOfSegment,
139*e5436536SAndroid Build Coastguard Worker                                 SCHAR *pRemainingBitsInSegment,
140*e5436536SAndroid Build Coastguard Worker                                 int *pNumDecodedBits, UINT *errorWord);
141*e5436536SAndroid Build Coastguard Worker 
142*e5436536SAndroid Build Coastguard Worker static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
143*e5436536SAndroid Build Coastguard Worker                           UINT codebookDim, const SCHAR *pQuantVal,
144*e5436536SAndroid Build Coastguard Worker                           FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
145*e5436536SAndroid Build Coastguard Worker                           INT *pLeftStartOfSegment,
146*e5436536SAndroid Build Coastguard Worker                           SCHAR *pRemainingBitsInSegment, int *pNumDecodedBits);
147*e5436536SAndroid Build Coastguard Worker 
148*e5436536SAndroid Build Coastguard Worker static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
149*e5436536SAndroid Build Coastguard Worker                                    const UINT *pCurrentTree,
150*e5436536SAndroid Build Coastguard Worker                                    const SCHAR *pQuantValBase,
151*e5436536SAndroid Build Coastguard Worker                                    INT *pLeftStartOfSegment,
152*e5436536SAndroid Build Coastguard Worker                                    SCHAR *pRemainingBitsInSegment,
153*e5436536SAndroid Build Coastguard Worker                                    int *pNumDecodedBits);
154*e5436536SAndroid Build Coastguard Worker 
155*e5436536SAndroid Build Coastguard Worker static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr);
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker static void HcrReorderQuantizedSpectralCoefficients(
158*e5436536SAndroid Build Coastguard Worker     H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
159*e5436536SAndroid Build Coastguard Worker     const SamplingRateInfo *pSamplingRateInfo);
160*e5436536SAndroid Build Coastguard Worker 
161*e5436536SAndroid Build Coastguard Worker static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
162*e5436536SAndroid Build Coastguard Worker                                       H_HCR_INFO pHcr, PCW_TYPE kind,
163*e5436536SAndroid Build Coastguard Worker                                       FIXP_DBL *qsc_base_of_cw,
164*e5436536SAndroid Build Coastguard Worker                                       UCHAR dimension);
165*e5436536SAndroid Build Coastguard Worker 
166*e5436536SAndroid Build Coastguard Worker static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr);
167*e5436536SAndroid Build Coastguard Worker 
168*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
169*e5436536SAndroid Build Coastguard Worker      description:   Check if codebook and numSect are within allowed range
170*e5436536SAndroid Build Coastguard Worker (short only)
171*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
172*e5436536SAndroid Build Coastguard Worker */
errDetectorInHcrSideinfoShrt(SCHAR cb,SHORT numLine,UINT * errorWord)173*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrSideinfoShrt(SCHAR cb, SHORT numLine,
174*e5436536SAndroid Build Coastguard Worker                                          UINT *errorWord) {
175*e5436536SAndroid Build Coastguard Worker   if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
176*e5436536SAndroid Build Coastguard Worker     *errorWord |= CB_OUT_OF_RANGE_SHORT_BLOCK;
177*e5436536SAndroid Build Coastguard Worker   }
178*e5436536SAndroid Build Coastguard Worker   if (numLine < 0 || numLine > 1024) {
179*e5436536SAndroid Build Coastguard Worker     *errorWord |= LINE_IN_SECT_OUT_OF_RANGE_SHORT_BLOCK;
180*e5436536SAndroid Build Coastguard Worker   }
181*e5436536SAndroid Build Coastguard Worker }
182*e5436536SAndroid Build Coastguard Worker 
183*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
184*e5436536SAndroid Build Coastguard Worker      description:   Check both HCR lengths
185*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
186*e5436536SAndroid Build Coastguard Worker */
errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,SHORT lengthOfReorderedSpectralData,UINT * errorWord)187*e5436536SAndroid Build Coastguard Worker static void errDetectorInHcrLengths(SCHAR lengthOfLongestCodeword,
188*e5436536SAndroid Build Coastguard Worker                                     SHORT lengthOfReorderedSpectralData,
189*e5436536SAndroid Build Coastguard Worker                                     UINT *errorWord) {
190*e5436536SAndroid Build Coastguard Worker   if (lengthOfReorderedSpectralData < lengthOfLongestCodeword) {
191*e5436536SAndroid Build Coastguard Worker     *errorWord |= HCR_SI_LENGTHS_FAILURE;
192*e5436536SAndroid Build Coastguard Worker   }
193*e5436536SAndroid Build Coastguard Worker }
194*e5436536SAndroid Build Coastguard Worker 
195*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
196*e5436536SAndroid Build Coastguard Worker      description:   Decode (and adapt if necessary) the two HCR sideinfo
197*e5436536SAndroid Build Coastguard Worker components: 'reordered_spectral_data_length' and 'longest_codeword_length'
198*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
199*e5436536SAndroid Build Coastguard Worker */
200*e5436536SAndroid Build Coastguard Worker 
CHcr_Read(HANDLE_FDK_BITSTREAM bs,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const MP4_ELEMENT_ID globalHcrType)201*e5436536SAndroid Build Coastguard Worker void CHcr_Read(HANDLE_FDK_BITSTREAM bs,
202*e5436536SAndroid Build Coastguard Worker                CAacDecoderChannelInfo *pAacDecoderChannelInfo,
203*e5436536SAndroid Build Coastguard Worker                const MP4_ELEMENT_ID globalHcrType) {
204*e5436536SAndroid Build Coastguard Worker   SHORT lengOfReorderedSpectralData;
205*e5436536SAndroid Build Coastguard Worker   SCHAR lengOfLongestCodeword;
206*e5436536SAndroid Build Coastguard Worker 
207*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfReorderedSpectralData =
208*e5436536SAndroid Build Coastguard Worker       0;
209*e5436536SAndroid Build Coastguard Worker   pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword = 0;
210*e5436536SAndroid Build Coastguard Worker 
211*e5436536SAndroid Build Coastguard Worker   /* ------- SI-Value No 1 ------- */
212*e5436536SAndroid Build Coastguard Worker   lengOfReorderedSpectralData = FDKreadBits(bs, 14) + ERROR_LORSD;
213*e5436536SAndroid Build Coastguard Worker   if (globalHcrType == ID_CPE) {
214*e5436536SAndroid Build Coastguard Worker     if ((lengOfReorderedSpectralData >= 0) &&
215*e5436536SAndroid Build Coastguard Worker         (lengOfReorderedSpectralData <= CPE_TOP_LENGTH)) {
216*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac
217*e5436536SAndroid Build Coastguard Worker           .lenOfReorderedSpectralData =
218*e5436536SAndroid Build Coastguard Worker           lengOfReorderedSpectralData; /* the decoded value is within range */
219*e5436536SAndroid Build Coastguard Worker     } else {
220*e5436536SAndroid Build Coastguard Worker       if (lengOfReorderedSpectralData > CPE_TOP_LENGTH) {
221*e5436536SAndroid Build Coastguard Worker         pAacDecoderChannelInfo->pDynData->specificTo.aac
222*e5436536SAndroid Build Coastguard Worker             .lenOfReorderedSpectralData =
223*e5436536SAndroid Build Coastguard Worker             CPE_TOP_LENGTH; /* use valid maximum */
224*e5436536SAndroid Build Coastguard Worker       }
225*e5436536SAndroid Build Coastguard Worker     }
226*e5436536SAndroid Build Coastguard Worker   } else if (globalHcrType == ID_SCE || globalHcrType == ID_LFE ||
227*e5436536SAndroid Build Coastguard Worker              globalHcrType == ID_CCE) {
228*e5436536SAndroid Build Coastguard Worker     if ((lengOfReorderedSpectralData >= 0) &&
229*e5436536SAndroid Build Coastguard Worker         (lengOfReorderedSpectralData <= SCE_TOP_LENGTH)) {
230*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac
231*e5436536SAndroid Build Coastguard Worker           .lenOfReorderedSpectralData =
232*e5436536SAndroid Build Coastguard Worker           lengOfReorderedSpectralData; /* the decoded value is within range */
233*e5436536SAndroid Build Coastguard Worker     } else {
234*e5436536SAndroid Build Coastguard Worker       if (lengOfReorderedSpectralData > SCE_TOP_LENGTH) {
235*e5436536SAndroid Build Coastguard Worker         pAacDecoderChannelInfo->pDynData->specificTo.aac
236*e5436536SAndroid Build Coastguard Worker             .lenOfReorderedSpectralData =
237*e5436536SAndroid Build Coastguard Worker             SCE_TOP_LENGTH; /* use valid maximum */
238*e5436536SAndroid Build Coastguard Worker       }
239*e5436536SAndroid Build Coastguard Worker     }
240*e5436536SAndroid Build Coastguard Worker   }
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   /* ------- SI-Value No 2 ------- */
243*e5436536SAndroid Build Coastguard Worker   lengOfLongestCodeword = FDKreadBits(bs, 6) + ERROR_LOLC;
244*e5436536SAndroid Build Coastguard Worker   if ((lengOfLongestCodeword >= 0) &&
245*e5436536SAndroid Build Coastguard Worker       (lengOfLongestCodeword <= LEN_OF_LONGEST_CW_TOP_LENGTH)) {
246*e5436536SAndroid Build Coastguard Worker     pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
247*e5436536SAndroid Build Coastguard Worker         lengOfLongestCodeword; /* the decoded value is within range */
248*e5436536SAndroid Build Coastguard Worker   } else {
249*e5436536SAndroid Build Coastguard Worker     if (lengOfLongestCodeword > LEN_OF_LONGEST_CW_TOP_LENGTH) {
250*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword =
251*e5436536SAndroid Build Coastguard Worker           LEN_OF_LONGEST_CW_TOP_LENGTH; /* use valid maximum */
252*e5436536SAndroid Build Coastguard Worker     }
253*e5436536SAndroid Build Coastguard Worker   }
254*e5436536SAndroid Build Coastguard Worker }
255*e5436536SAndroid Build Coastguard Worker 
256*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
257*e5436536SAndroid Build Coastguard Worker      description:   Set up HCR - must be called before every call to
258*e5436536SAndroid Build Coastguard Worker HcrDecoder(). For short block a sorting algorithm is applied to get the SI in
259*e5436536SAndroid Build Coastguard Worker the order that HCR could assemble the qsc's as if it is a long block.
260*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
261*e5436536SAndroid Build Coastguard Worker         return:     error log
262*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
263*e5436536SAndroid Build Coastguard Worker */
264*e5436536SAndroid Build Coastguard Worker 
HcrInit(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,HANDLE_FDK_BITSTREAM bs)265*e5436536SAndroid Build Coastguard Worker UINT HcrInit(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
266*e5436536SAndroid Build Coastguard Worker              const SamplingRateInfo *pSamplingRateInfo,
267*e5436536SAndroid Build Coastguard Worker              HANDLE_FDK_BITSTREAM bs) {
268*e5436536SAndroid Build Coastguard Worker   CIcsInfo *pIcsInfo = &pAacDecoderChannelInfo->icsInfo;
269*e5436536SAndroid Build Coastguard Worker   SHORT *pNumLinesInSec;
270*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodeBk;
271*e5436536SAndroid Build Coastguard Worker   SHORT numSection;
272*e5436536SAndroid Build Coastguard Worker   SCHAR cb;
273*e5436536SAndroid Build Coastguard Worker   int numLine;
274*e5436536SAndroid Build Coastguard Worker   int i;
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.lengthOfReorderedSpectralData =
277*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac
278*e5436536SAndroid Build Coastguard Worker           .lenOfReorderedSpectralData;
279*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.lengthOfLongestCodeword =
280*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.lenOfLongestCodeword;
281*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.pQuantizedSpectralCoefficientsBase =
282*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pSpectralCoefficient;
283*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.quantizedSpectralCoefficientsIdx = 0;
284*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.pCodebook =
285*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.aCodeBooks4Hcr;
286*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.pNumLineInSect =
287*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.aNumLineInSec4Hcr;
288*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.numSection =
289*e5436536SAndroid Build Coastguard Worker       pAacDecoderChannelInfo->pDynData->specificTo.aac.numberSection;
290*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.errorLog = 0;
291*e5436536SAndroid Build Coastguard Worker   pHcr->nonPcwSideinfo.pResultBase =
292*e5436536SAndroid Build Coastguard Worker       SPEC_LONG(pAacDecoderChannelInfo->pSpectralCoefficient);
293*e5436536SAndroid Build Coastguard Worker 
294*e5436536SAndroid Build Coastguard Worker   FDKsyncCache(bs);
295*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.bitstreamAnchor = (INT)FDKgetValidBits(bs);
296*e5436536SAndroid Build Coastguard Worker 
297*e5436536SAndroid Build Coastguard Worker   if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) /* short block */
298*e5436536SAndroid Build Coastguard Worker   {
299*e5436536SAndroid Build Coastguard Worker     SHORT band;
300*e5436536SAndroid Build Coastguard Worker     SHORT maxBand;
301*e5436536SAndroid Build Coastguard Worker     SCHAR group;
302*e5436536SAndroid Build Coastguard Worker     SCHAR winGroupLen;
303*e5436536SAndroid Build Coastguard Worker     SCHAR window;
304*e5436536SAndroid Build Coastguard Worker     SCHAR numUnitInBand;
305*e5436536SAndroid Build Coastguard Worker     SCHAR cntUnitInBand;
306*e5436536SAndroid Build Coastguard Worker     SCHAR groupWin;
307*e5436536SAndroid Build Coastguard Worker     SCHAR cb_prev;
308*e5436536SAndroid Build Coastguard Worker 
309*e5436536SAndroid Build Coastguard Worker     UCHAR *pCodeBook;
310*e5436536SAndroid Build Coastguard Worker     const SHORT *BandOffsets;
311*e5436536SAndroid Build Coastguard Worker     SCHAR numOfGroups;
312*e5436536SAndroid Build Coastguard Worker 
313*e5436536SAndroid Build Coastguard Worker     pCodeBook = pAacDecoderChannelInfo->pDynData->aCodeBook; /* in */
314*e5436536SAndroid Build Coastguard Worker     pNumLinesInSec = pHcr->decInOut.pNumLineInSect;          /* out */
315*e5436536SAndroid Build Coastguard Worker     pCodeBk = pHcr->decInOut.pCodebook;                      /* out */
316*e5436536SAndroid Build Coastguard Worker     BandOffsets =
317*e5436536SAndroid Build Coastguard Worker         GetScaleFactorBandOffsets(pIcsInfo, pSamplingRateInfo); /* aux */
318*e5436536SAndroid Build Coastguard Worker     numOfGroups = GetWindowGroups(pIcsInfo);
319*e5436536SAndroid Build Coastguard Worker 
320*e5436536SAndroid Build Coastguard Worker     numLine = 0;
321*e5436536SAndroid Build Coastguard Worker     numSection = 0;
322*e5436536SAndroid Build Coastguard Worker     cb = pCodeBook[0];
323*e5436536SAndroid Build Coastguard Worker     cb_prev = pCodeBook[0];
324*e5436536SAndroid Build Coastguard Worker 
325*e5436536SAndroid Build Coastguard Worker     /* convert HCR-sideinfo into a unitwise manner: When the cb changes, a new
326*e5436536SAndroid Build Coastguard Worker      * section starts */
327*e5436536SAndroid Build Coastguard Worker 
328*e5436536SAndroid Build Coastguard Worker     *pCodeBk++ = cb_prev;
329*e5436536SAndroid Build Coastguard Worker 
330*e5436536SAndroid Build Coastguard Worker     maxBand = GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
331*e5436536SAndroid Build Coastguard Worker     for (band = 0; band < maxBand;
332*e5436536SAndroid Build Coastguard Worker          band++) { /* from low to high sfbs i.e. from low to high frequencies */
333*e5436536SAndroid Build Coastguard Worker       numUnitInBand =
334*e5436536SAndroid Build Coastguard Worker           ((BandOffsets[band + 1] - BandOffsets[band]) >>
335*e5436536SAndroid Build Coastguard Worker            FOUR_LOG_DIV_TWO_LOG); /* get the number of units in current sfb */
336*e5436536SAndroid Build Coastguard Worker       for (cntUnitInBand = numUnitInBand; cntUnitInBand != 0;
337*e5436536SAndroid Build Coastguard Worker            cntUnitInBand--) { /* for every unit in the band */
338*e5436536SAndroid Build Coastguard Worker         for (window = 0, group = 0; group < numOfGroups; group++) {
339*e5436536SAndroid Build Coastguard Worker           winGroupLen = (SCHAR)GetWindowGroupLength(
340*e5436536SAndroid Build Coastguard Worker               &pAacDecoderChannelInfo->icsInfo, group);
341*e5436536SAndroid Build Coastguard Worker           for (groupWin = winGroupLen; groupWin != 0; groupWin--, window++) {
342*e5436536SAndroid Build Coastguard Worker             cb = pCodeBook[group * 16 + band];
343*e5436536SAndroid Build Coastguard Worker             if (cb != cb_prev) {
344*e5436536SAndroid Build Coastguard Worker               errDetectorInHcrSideinfoShrt(cb, numLine,
345*e5436536SAndroid Build Coastguard Worker                                            &pHcr->decInOut.errorLog);
346*e5436536SAndroid Build Coastguard Worker               if (pHcr->decInOut.errorLog != 0) {
347*e5436536SAndroid Build Coastguard Worker                 return (pHcr->decInOut.errorLog);
348*e5436536SAndroid Build Coastguard Worker               }
349*e5436536SAndroid Build Coastguard Worker               *pCodeBk++ = cb;
350*e5436536SAndroid Build Coastguard Worker               *pNumLinesInSec++ = numLine;
351*e5436536SAndroid Build Coastguard Worker               numSection++;
352*e5436536SAndroid Build Coastguard Worker 
353*e5436536SAndroid Build Coastguard Worker               cb_prev = cb;
354*e5436536SAndroid Build Coastguard Worker               numLine = LINES_PER_UNIT;
355*e5436536SAndroid Build Coastguard Worker             } else {
356*e5436536SAndroid Build Coastguard Worker               numLine += LINES_PER_UNIT;
357*e5436536SAndroid Build Coastguard Worker             }
358*e5436536SAndroid Build Coastguard Worker           }
359*e5436536SAndroid Build Coastguard Worker         }
360*e5436536SAndroid Build Coastguard Worker       }
361*e5436536SAndroid Build Coastguard Worker     }
362*e5436536SAndroid Build Coastguard Worker 
363*e5436536SAndroid Build Coastguard Worker     numSection++;
364*e5436536SAndroid Build Coastguard Worker 
365*e5436536SAndroid Build Coastguard Worker     errDetectorInHcrSideinfoShrt(cb, numLine, &pHcr->decInOut.errorLog);
366*e5436536SAndroid Build Coastguard Worker     if (numSection <= 0 || numSection > 1024 / 2) {
367*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_SHORT_BLOCK;
368*e5436536SAndroid Build Coastguard Worker     }
369*e5436536SAndroid Build Coastguard Worker     errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
370*e5436536SAndroid Build Coastguard Worker                             pHcr->decInOut.lengthOfReorderedSpectralData,
371*e5436536SAndroid Build Coastguard Worker                             &pHcr->decInOut.errorLog);
372*e5436536SAndroid Build Coastguard Worker     if (pHcr->decInOut.errorLog != 0) {
373*e5436536SAndroid Build Coastguard Worker       return (pHcr->decInOut.errorLog);
374*e5436536SAndroid Build Coastguard Worker     }
375*e5436536SAndroid Build Coastguard Worker 
376*e5436536SAndroid Build Coastguard Worker     *pCodeBk = cb;
377*e5436536SAndroid Build Coastguard Worker     *pNumLinesInSec = numLine;
378*e5436536SAndroid Build Coastguard Worker     pHcr->decInOut.numSection = numSection;
379*e5436536SAndroid Build Coastguard Worker 
380*e5436536SAndroid Build Coastguard Worker   } else /* end short block prepare SI */
381*e5436536SAndroid Build Coastguard Worker   {      /* long block */
382*e5436536SAndroid Build Coastguard Worker     errDetectorInHcrLengths(pHcr->decInOut.lengthOfLongestCodeword,
383*e5436536SAndroid Build Coastguard Worker                             pHcr->decInOut.lengthOfReorderedSpectralData,
384*e5436536SAndroid Build Coastguard Worker                             &pHcr->decInOut.errorLog);
385*e5436536SAndroid Build Coastguard Worker     numSection = pHcr->decInOut.numSection;
386*e5436536SAndroid Build Coastguard Worker     pNumLinesInSec = pHcr->decInOut.pNumLineInSect;
387*e5436536SAndroid Build Coastguard Worker     pCodeBk = pHcr->decInOut.pCodebook;
388*e5436536SAndroid Build Coastguard Worker     if (numSection <= 0 || numSection > 64) {
389*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.errorLog |= NUM_SECT_OUT_OF_RANGE_LONG_BLOCK;
390*e5436536SAndroid Build Coastguard Worker       numSection = 0;
391*e5436536SAndroid Build Coastguard Worker     }
392*e5436536SAndroid Build Coastguard Worker 
393*e5436536SAndroid Build Coastguard Worker     for (i = numSection; i != 0; i--) {
394*e5436536SAndroid Build Coastguard Worker       cb = *pCodeBk++;
395*e5436536SAndroid Build Coastguard Worker 
396*e5436536SAndroid Build Coastguard Worker       if (cb < ZERO_HCB || cb >= MAX_CB_CHECK || cb == BOOKSCL) {
397*e5436536SAndroid Build Coastguard Worker         pHcr->decInOut.errorLog |= CB_OUT_OF_RANGE_LONG_BLOCK;
398*e5436536SAndroid Build Coastguard Worker       }
399*e5436536SAndroid Build Coastguard Worker 
400*e5436536SAndroid Build Coastguard Worker       numLine = *pNumLinesInSec++;
401*e5436536SAndroid Build Coastguard Worker       /* FDK_ASSERT(numLine > 0); */
402*e5436536SAndroid Build Coastguard Worker 
403*e5436536SAndroid Build Coastguard Worker       if ((numLine <= 0) || (numLine > 1024)) {
404*e5436536SAndroid Build Coastguard Worker         pHcr->decInOut.errorLog |= LINE_IN_SECT_OUT_OF_RANGE_LONG_BLOCK;
405*e5436536SAndroid Build Coastguard Worker       }
406*e5436536SAndroid Build Coastguard Worker     }
407*e5436536SAndroid Build Coastguard Worker     if (pHcr->decInOut.errorLog != 0) {
408*e5436536SAndroid Build Coastguard Worker       return (pHcr->decInOut.errorLog);
409*e5436536SAndroid Build Coastguard Worker     }
410*e5436536SAndroid Build Coastguard Worker   }
411*e5436536SAndroid Build Coastguard Worker 
412*e5436536SAndroid Build Coastguard Worker   pCodeBk = pHcr->decInOut.pCodebook;
413*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < numSection; i++) {
414*e5436536SAndroid Build Coastguard Worker     if ((*pCodeBk == NOISE_HCB) || (*pCodeBk == INTENSITY_HCB2) ||
415*e5436536SAndroid Build Coastguard Worker         (*pCodeBk == INTENSITY_HCB)) {
416*e5436536SAndroid Build Coastguard Worker       *pCodeBk = 0;
417*e5436536SAndroid Build Coastguard Worker     }
418*e5436536SAndroid Build Coastguard Worker     pCodeBk++;
419*e5436536SAndroid Build Coastguard Worker   }
420*e5436536SAndroid Build Coastguard Worker 
421*e5436536SAndroid Build Coastguard Worker   /* HCR-sideinfo-input is complete and seems to be valid */
422*e5436536SAndroid Build Coastguard Worker 
423*e5436536SAndroid Build Coastguard Worker   return (pHcr->decInOut.errorLog);
424*e5436536SAndroid Build Coastguard Worker }
425*e5436536SAndroid Build Coastguard Worker 
426*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
427*e5436536SAndroid Build Coastguard Worker      description:   This function decodes the codewords of the spectral
428*e5436536SAndroid Build Coastguard Worker coefficients from the bitstream according to the HCR algorithm and stores the
429*e5436536SAndroid Build Coastguard Worker quantized spectral coefficients in correct order in the output buffer.
430*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
431*e5436536SAndroid Build Coastguard Worker */
432*e5436536SAndroid Build Coastguard Worker 
HcrDecoder(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo,HANDLE_FDK_BITSTREAM bs)433*e5436536SAndroid Build Coastguard Worker UINT HcrDecoder(H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
434*e5436536SAndroid Build Coastguard Worker                 const SamplingRateInfo *pSamplingRateInfo,
435*e5436536SAndroid Build Coastguard Worker                 HANDLE_FDK_BITSTREAM bs) {
436*e5436536SAndroid Build Coastguard Worker   int pTmp1, pTmp2, pTmp3, pTmp4;
437*e5436536SAndroid Build Coastguard Worker   int pTmp5;
438*e5436536SAndroid Build Coastguard Worker 
439*e5436536SAndroid Build Coastguard Worker   INT bitCntOffst;
440*e5436536SAndroid Build Coastguard Worker   INT saveBitCnt = (INT)FDKgetValidBits(bs); /* save bitstream position */
441*e5436536SAndroid Build Coastguard Worker 
442*e5436536SAndroid Build Coastguard Worker   HcrCalcNumCodeword(pHcr);
443*e5436536SAndroid Build Coastguard Worker 
444*e5436536SAndroid Build Coastguard Worker   HcrSortCodebookAndNumCodewordInSection(pHcr);
445*e5436536SAndroid Build Coastguard Worker 
446*e5436536SAndroid Build Coastguard Worker   HcrPrepareSegmentationGrid(pHcr);
447*e5436536SAndroid Build Coastguard Worker 
448*e5436536SAndroid Build Coastguard Worker   HcrExtendedSectionInfo(pHcr);
449*e5436536SAndroid Build Coastguard Worker 
450*e5436536SAndroid Build Coastguard Worker   if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) != 0) {
451*e5436536SAndroid Build Coastguard Worker     return (pHcr->decInOut.errorLog); /* sideinfo is massively corrupt, return
452*e5436536SAndroid Build Coastguard Worker                                          from HCR without having decoded
453*e5436536SAndroid Build Coastguard Worker                                          anything */
454*e5436536SAndroid Build Coastguard Worker   }
455*e5436536SAndroid Build Coastguard Worker 
456*e5436536SAndroid Build Coastguard Worker   DeriveNumberOfExtendedSortedSectionsInSets(
457*e5436536SAndroid Build Coastguard Worker       pHcr->segmentInfo.numSegment,
458*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumExtendedSortedCodewordInSection,
459*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx,
460*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumExtendedSortedSectionsInSets,
461*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx);
462*e5436536SAndroid Build Coastguard Worker 
463*e5436536SAndroid Build Coastguard Worker   /* store */
464*e5436536SAndroid Build Coastguard Worker   pTmp1 = pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
465*e5436536SAndroid Build Coastguard Worker   pTmp2 = pHcr->sectionInfo.extendedSortedCodebookIdx;
466*e5436536SAndroid Build Coastguard Worker   pTmp3 = pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
467*e5436536SAndroid Build Coastguard Worker   pTmp4 = pHcr->decInOut.quantizedSpectralCoefficientsIdx;
468*e5436536SAndroid Build Coastguard Worker   pTmp5 = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
469*e5436536SAndroid Build Coastguard Worker 
470*e5436536SAndroid Build Coastguard Worker   /* ------- decode meaningful PCWs ------ */
471*e5436536SAndroid Build Coastguard Worker   DecodePCWs(bs, pHcr);
472*e5436536SAndroid Build Coastguard Worker 
473*e5436536SAndroid Build Coastguard Worker   if ((pHcr->decInOut.errorLog & HCR_FATAL_PCW_ERROR_MASK) == 0) {
474*e5436536SAndroid Build Coastguard Worker     /* ------ decode the non-PCWs -------- */
475*e5436536SAndroid Build Coastguard Worker     DecodeNonPCWs(bs, pHcr);
476*e5436536SAndroid Build Coastguard Worker   }
477*e5436536SAndroid Build Coastguard Worker 
478*e5436536SAndroid Build Coastguard Worker   errDetectWithinSegmentationFinal(pHcr);
479*e5436536SAndroid Build Coastguard Worker 
480*e5436536SAndroid Build Coastguard Worker   /* restore */
481*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx = pTmp1;
482*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.extendedSortedCodebookIdx = pTmp2;
483*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx = pTmp3;
484*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.quantizedSpectralCoefficientsIdx = pTmp4;
485*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = pTmp5;
486*e5436536SAndroid Build Coastguard Worker 
487*e5436536SAndroid Build Coastguard Worker   HcrReorderQuantizedSpectralCoefficients(pHcr, pAacDecoderChannelInfo,
488*e5436536SAndroid Build Coastguard Worker                                           pSamplingRateInfo);
489*e5436536SAndroid Build Coastguard Worker 
490*e5436536SAndroid Build Coastguard Worker   /* restore bitstream position */
491*e5436536SAndroid Build Coastguard Worker   bitCntOffst = (INT)FDKgetValidBits(bs) - saveBitCnt;
492*e5436536SAndroid Build Coastguard Worker   if (bitCntOffst) {
493*e5436536SAndroid Build Coastguard Worker     FDKpushBiDirectional(bs, bitCntOffst);
494*e5436536SAndroid Build Coastguard Worker   }
495*e5436536SAndroid Build Coastguard Worker 
496*e5436536SAndroid Build Coastguard Worker   return (pHcr->decInOut.errorLog);
497*e5436536SAndroid Build Coastguard Worker }
498*e5436536SAndroid Build Coastguard Worker 
499*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
500*e5436536SAndroid Build Coastguard Worker      description:   This function reorders the quantized spectral coefficients
501*e5436536SAndroid Build Coastguard Worker sectionwise for long- and short-blocks and compares to the LAV (Largest Absolute
502*e5436536SAndroid Build Coastguard Worker Value of the current codebook) -- a counter is incremented if there is an error
503*e5436536SAndroid Build Coastguard Worker                     detected.
504*e5436536SAndroid Build Coastguard Worker                     Additional for short-blocks a unit-based-deinterleaving is
505*e5436536SAndroid Build Coastguard Worker applied. Moreover (for short blocks) the scaling is derived (compare plain
506*e5436536SAndroid Build Coastguard Worker huffman decoder).
507*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
508*e5436536SAndroid Build Coastguard Worker */
509*e5436536SAndroid Build Coastguard Worker 
HcrReorderQuantizedSpectralCoefficients(H_HCR_INFO pHcr,CAacDecoderChannelInfo * pAacDecoderChannelInfo,const SamplingRateInfo * pSamplingRateInfo)510*e5436536SAndroid Build Coastguard Worker static void HcrReorderQuantizedSpectralCoefficients(
511*e5436536SAndroid Build Coastguard Worker     H_HCR_INFO pHcr, CAacDecoderChannelInfo *pAacDecoderChannelInfo,
512*e5436536SAndroid Build Coastguard Worker     const SamplingRateInfo *pSamplingRateInfo) {
513*e5436536SAndroid Build Coastguard Worker   INT qsc;
514*e5436536SAndroid Build Coastguard Worker   UINT abs_qsc;
515*e5436536SAndroid Build Coastguard Worker   UINT i, j;
516*e5436536SAndroid Build Coastguard Worker   USHORT numSpectralValuesInSection;
517*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pTeVa;
518*e5436536SAndroid Build Coastguard Worker   USHORT lavErrorCnt = 0;
519*e5436536SAndroid Build Coastguard Worker 
520*e5436536SAndroid Build Coastguard Worker   UINT numSection = pHcr->decInOut.numSection;
521*e5436536SAndroid Build Coastguard Worker   SPECTRAL_PTR pQuantizedSpectralCoefficientsBase =
522*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.pQuantizedSpectralCoefficientsBase;
523*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pQuantizedSpectralCoefficients =
524*e5436536SAndroid Build Coastguard Worker       SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
525*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbDimShift = aDimCbShift;
526*e5436536SAndroid Build Coastguard Worker   const USHORT *pLargestAbsVal = aLargestAbsoluteValue;
527*e5436536SAndroid Build Coastguard Worker   UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
528*e5436536SAndroid Build Coastguard Worker   USHORT *pNumSortedCodewordInSection =
529*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumSortedCodewordInSection;
530*e5436536SAndroid Build Coastguard Worker   USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
531*e5436536SAndroid Build Coastguard Worker   FIXP_DBL pTempValues[1024];
532*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pBak = pTempValues;
533*e5436536SAndroid Build Coastguard Worker 
534*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pTempValues, 1024 * sizeof(FIXP_DBL));
535*e5436536SAndroid Build Coastguard Worker 
536*e5436536SAndroid Build Coastguard Worker   /* long and short: check if decoded huffman-values (quantized spectral
537*e5436536SAndroid Build Coastguard Worker    * coefficients) are within range */
538*e5436536SAndroid Build Coastguard Worker   for (i = numSection; i != 0; i--) {
539*e5436536SAndroid Build Coastguard Worker     numSpectralValuesInSection = *pNumSortedCodewordInSection++
540*e5436536SAndroid Build Coastguard Worker                                  << pCbDimShift[*pSortedCodebook];
541*e5436536SAndroid Build Coastguard Worker     pTeVa = &pTempValues[*pReorderOffset++];
542*e5436536SAndroid Build Coastguard Worker     for (j = numSpectralValuesInSection; j != 0; j--) {
543*e5436536SAndroid Build Coastguard Worker       qsc = *pQuantizedSpectralCoefficients++;
544*e5436536SAndroid Build Coastguard Worker       abs_qsc = fAbs(qsc);
545*e5436536SAndroid Build Coastguard Worker       if (abs_qsc <= pLargestAbsVal[*pSortedCodebook]) {
546*e5436536SAndroid Build Coastguard Worker         *pTeVa++ = (FIXP_DBL)qsc; /* the qsc value is within range */
547*e5436536SAndroid Build Coastguard Worker       } else {                    /* line is too high .. */
548*e5436536SAndroid Build Coastguard Worker         if (abs_qsc ==
549*e5436536SAndroid Build Coastguard Worker             Q_VALUE_INVALID) { /* .. because of previous marking --> dont set
550*e5436536SAndroid Build Coastguard Worker                                   LAV flag (would be confusing), just copy out
551*e5436536SAndroid Build Coastguard Worker                                   the already marked value */
552*e5436536SAndroid Build Coastguard Worker           *pTeVa++ = (FIXP_DBL)qsc;
553*e5436536SAndroid Build Coastguard Worker         } else { /* .. because a too high value was decoded for this cb --> set
554*e5436536SAndroid Build Coastguard Worker                     LAV flag */
555*e5436536SAndroid Build Coastguard Worker           *pTeVa++ = (FIXP_DBL)Q_VALUE_INVALID;
556*e5436536SAndroid Build Coastguard Worker           lavErrorCnt += 1;
557*e5436536SAndroid Build Coastguard Worker         }
558*e5436536SAndroid Build Coastguard Worker       }
559*e5436536SAndroid Build Coastguard Worker     }
560*e5436536SAndroid Build Coastguard Worker     pSortedCodebook++;
561*e5436536SAndroid Build Coastguard Worker   }
562*e5436536SAndroid Build Coastguard Worker 
563*e5436536SAndroid Build Coastguard Worker   if (!IsLongBlock(&pAacDecoderChannelInfo->icsInfo)) {
564*e5436536SAndroid Build Coastguard Worker     FIXP_DBL *pOut;
565*e5436536SAndroid Build Coastguard Worker     FIXP_DBL locMax;
566*e5436536SAndroid Build Coastguard Worker     FIXP_DBL tmp;
567*e5436536SAndroid Build Coastguard Worker     SCHAR groupoffset;
568*e5436536SAndroid Build Coastguard Worker     SCHAR group;
569*e5436536SAndroid Build Coastguard Worker     SCHAR band;
570*e5436536SAndroid Build Coastguard Worker     SCHAR groupwin;
571*e5436536SAndroid Build Coastguard Worker     SCHAR window;
572*e5436536SAndroid Build Coastguard Worker     SCHAR numWinGroup;
573*e5436536SAndroid Build Coastguard Worker     SHORT interm;
574*e5436536SAndroid Build Coastguard Worker     SCHAR numSfbTransm;
575*e5436536SAndroid Build Coastguard Worker     SCHAR winGroupLen;
576*e5436536SAndroid Build Coastguard Worker     SHORT index;
577*e5436536SAndroid Build Coastguard Worker     INT msb;
578*e5436536SAndroid Build Coastguard Worker     INT lsb;
579*e5436536SAndroid Build Coastguard Worker 
580*e5436536SAndroid Build Coastguard Worker     SHORT *pScaleFacHcr = pAacDecoderChannelInfo->pDynData->aScaleFactor;
581*e5436536SAndroid Build Coastguard Worker     SHORT *pSfbSclHcr = pAacDecoderChannelInfo->pDynData->aSfbScale;
582*e5436536SAndroid Build Coastguard Worker     const SHORT *BandOffsets = GetScaleFactorBandOffsets(
583*e5436536SAndroid Build Coastguard Worker         &pAacDecoderChannelInfo->icsInfo, pSamplingRateInfo);
584*e5436536SAndroid Build Coastguard Worker 
585*e5436536SAndroid Build Coastguard Worker     pBak = pTempValues;
586*e5436536SAndroid Build Coastguard Worker     /* deinterleave unitwise for short blocks */
587*e5436536SAndroid Build Coastguard Worker     for (window = 0; window < (8); window++) {
588*e5436536SAndroid Build Coastguard Worker       pOut = SPEC(pQuantizedSpectralCoefficientsBase, window,
589*e5436536SAndroid Build Coastguard Worker                   pAacDecoderChannelInfo->granuleLength);
590*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < (LINES_PER_UNIT_GROUP); i++) {
591*e5436536SAndroid Build Coastguard Worker         pTeVa = pBak + (window << FOUR_LOG_DIV_TWO_LOG) +
592*e5436536SAndroid Build Coastguard Worker                 i * 32; /* distance of lines between unit groups has to be
593*e5436536SAndroid Build Coastguard Worker                            constant for every framelength (32)!  */
594*e5436536SAndroid Build Coastguard Worker         for (j = (LINES_PER_UNIT); j != 0; j--) {
595*e5436536SAndroid Build Coastguard Worker           *pOut++ = *pTeVa++;
596*e5436536SAndroid Build Coastguard Worker         }
597*e5436536SAndroid Build Coastguard Worker       }
598*e5436536SAndroid Build Coastguard Worker     }
599*e5436536SAndroid Build Coastguard Worker 
600*e5436536SAndroid Build Coastguard Worker     /* short blocks only */
601*e5436536SAndroid Build Coastguard Worker     /* derive global scaling-value for every sfb and every window (as it is done
602*e5436536SAndroid Build Coastguard Worker      * in plain-huffman-decoder at short blocks) */
603*e5436536SAndroid Build Coastguard Worker     groupoffset = 0;
604*e5436536SAndroid Build Coastguard Worker 
605*e5436536SAndroid Build Coastguard Worker     numWinGroup = GetWindowGroups(&pAacDecoderChannelInfo->icsInfo);
606*e5436536SAndroid Build Coastguard Worker     numSfbTransm =
607*e5436536SAndroid Build Coastguard Worker         GetScaleFactorBandsTransmitted(&pAacDecoderChannelInfo->icsInfo);
608*e5436536SAndroid Build Coastguard Worker 
609*e5436536SAndroid Build Coastguard Worker     for (group = 0; group < numWinGroup; group++) {
610*e5436536SAndroid Build Coastguard Worker       winGroupLen =
611*e5436536SAndroid Build Coastguard Worker           GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
612*e5436536SAndroid Build Coastguard Worker       for (band = 0; band < numSfbTransm; band++) {
613*e5436536SAndroid Build Coastguard Worker         interm = group * 16 + band;
614*e5436536SAndroid Build Coastguard Worker         msb = pScaleFacHcr[interm] >> 2;
615*e5436536SAndroid Build Coastguard Worker         lsb = pScaleFacHcr[interm] & 3;
616*e5436536SAndroid Build Coastguard Worker         for (groupwin = 0; groupwin < winGroupLen; groupwin++) {
617*e5436536SAndroid Build Coastguard Worker           window = groupoffset + groupwin;
618*e5436536SAndroid Build Coastguard Worker           pBak = SPEC(pQuantizedSpectralCoefficientsBase, window,
619*e5436536SAndroid Build Coastguard Worker                       pAacDecoderChannelInfo->granuleLength);
620*e5436536SAndroid Build Coastguard Worker           locMax = FL2FXCONST_DBL(0.0f);
621*e5436536SAndroid Build Coastguard Worker           for (index = BandOffsets[band]; index < BandOffsets[band + 1];
622*e5436536SAndroid Build Coastguard Worker                index += LINES_PER_UNIT) {
623*e5436536SAndroid Build Coastguard Worker             pTeVa = &pBak[index];
624*e5436536SAndroid Build Coastguard Worker             for (i = LINES_PER_UNIT; i != 0; i--) {
625*e5436536SAndroid Build Coastguard Worker               tmp = (*pTeVa < FL2FXCONST_DBL(0.0f)) ? -*pTeVa++ : *pTeVa++;
626*e5436536SAndroid Build Coastguard Worker               locMax = fixMax(tmp, locMax);
627*e5436536SAndroid Build Coastguard Worker             }
628*e5436536SAndroid Build Coastguard Worker           }
629*e5436536SAndroid Build Coastguard Worker           if (fixp_abs(locMax) > (FIXP_DBL)MAX_QUANTIZED_VALUE) {
630*e5436536SAndroid Build Coastguard Worker             locMax = (FIXP_DBL)MAX_QUANTIZED_VALUE;
631*e5436536SAndroid Build Coastguard Worker           }
632*e5436536SAndroid Build Coastguard Worker           pSfbSclHcr[window * 16 + band] =
633*e5436536SAndroid Build Coastguard Worker               msb - GetScaleFromValue(
634*e5436536SAndroid Build Coastguard Worker                         locMax, lsb); /* save global scale maxima in this sfb */
635*e5436536SAndroid Build Coastguard Worker         }
636*e5436536SAndroid Build Coastguard Worker       }
637*e5436536SAndroid Build Coastguard Worker       groupoffset +=
638*e5436536SAndroid Build Coastguard Worker           GetWindowGroupLength(&pAacDecoderChannelInfo->icsInfo, group);
639*e5436536SAndroid Build Coastguard Worker     }
640*e5436536SAndroid Build Coastguard Worker   } else {
641*e5436536SAndroid Build Coastguard Worker     /* copy straight for long-blocks */
642*e5436536SAndroid Build Coastguard Worker     pQuantizedSpectralCoefficients =
643*e5436536SAndroid Build Coastguard Worker         SPEC_LONG(pQuantizedSpectralCoefficientsBase);
644*e5436536SAndroid Build Coastguard Worker     for (i = 1024; i != 0; i--) {
645*e5436536SAndroid Build Coastguard Worker       *pQuantizedSpectralCoefficients++ = *pBak++;
646*e5436536SAndroid Build Coastguard Worker     }
647*e5436536SAndroid Build Coastguard Worker   }
648*e5436536SAndroid Build Coastguard Worker 
649*e5436536SAndroid Build Coastguard Worker   if (lavErrorCnt != 0) {
650*e5436536SAndroid Build Coastguard Worker     pHcr->decInOut.errorLog |= LAV_VIOLATION;
651*e5436536SAndroid Build Coastguard Worker   }
652*e5436536SAndroid Build Coastguard Worker }
653*e5436536SAndroid Build Coastguard Worker 
654*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
655*e5436536SAndroid Build Coastguard Worker      description:   This function calculates the number of codewords
656*e5436536SAndroid Build Coastguard Worker                     for each section (numCodewordInSection) and the number of
657*e5436536SAndroid Build Coastguard Worker codewords for all sections (numCodeword). For zero and intensity codebooks a
658*e5436536SAndroid Build Coastguard Worker entry is also done in the variable numCodewordInSection. It is assumed that the
659*e5436536SAndroid Build Coastguard Worker codebook is a two tuples codebook. This is needed later for the calculation of
660*e5436536SAndroid Build Coastguard Worker the base addresses for the reordering of the quantize spectral coefficients at
661*e5436536SAndroid Build Coastguard Worker the end of the hcr tool. The variable numCodeword contain the number of
662*e5436536SAndroid Build Coastguard Worker codewords which are really in the bitstream. Zero or intensity codebooks does
663*e5436536SAndroid Build Coastguard Worker not increase the variable numCodewords.
664*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
665*e5436536SAndroid Build Coastguard Worker         return:   -
666*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
667*e5436536SAndroid Build Coastguard Worker */
668*e5436536SAndroid Build Coastguard Worker 
HcrCalcNumCodeword(H_HCR_INFO pHcr)669*e5436536SAndroid Build Coastguard Worker static void HcrCalcNumCodeword(H_HCR_INFO pHcr) {
670*e5436536SAndroid Build Coastguard Worker   int hcrSection;
671*e5436536SAndroid Build Coastguard Worker   UINT numCodeword;
672*e5436536SAndroid Build Coastguard Worker 
673*e5436536SAndroid Build Coastguard Worker   UINT numSection = pHcr->decInOut.numSection;
674*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodebook = pHcr->decInOut.pCodebook;
675*e5436536SAndroid Build Coastguard Worker   SHORT *pNumLineInSection = pHcr->decInOut.pNumLineInSect;
676*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbDimShift = aDimCbShift;
677*e5436536SAndroid Build Coastguard Worker 
678*e5436536SAndroid Build Coastguard Worker   USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
679*e5436536SAndroid Build Coastguard Worker 
680*e5436536SAndroid Build Coastguard Worker   numCodeword = 0;
681*e5436536SAndroid Build Coastguard Worker   for (hcrSection = numSection; hcrSection != 0; hcrSection--) {
682*e5436536SAndroid Build Coastguard Worker     *pNumCodewordInSection = *pNumLineInSection++ >> pCbDimShift[*pCodebook];
683*e5436536SAndroid Build Coastguard Worker     if (*pCodebook != 0) {
684*e5436536SAndroid Build Coastguard Worker       numCodeword += *pNumCodewordInSection;
685*e5436536SAndroid Build Coastguard Worker     }
686*e5436536SAndroid Build Coastguard Worker     pNumCodewordInSection++;
687*e5436536SAndroid Build Coastguard Worker     pCodebook++;
688*e5436536SAndroid Build Coastguard Worker   }
689*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numCodeword = numCodeword;
690*e5436536SAndroid Build Coastguard Worker }
691*e5436536SAndroid Build Coastguard Worker 
692*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
693*e5436536SAndroid Build Coastguard Worker      description:   This function calculates the number
694*e5436536SAndroid Build Coastguard Worker                     of sorted codebooks and sorts the codebooks and the
695*e5436536SAndroid Build Coastguard Worker numCodewordInSection according to the priority.
696*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
697*e5436536SAndroid Build Coastguard Worker */
698*e5436536SAndroid Build Coastguard Worker 
HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr)699*e5436536SAndroid Build Coastguard Worker static void HcrSortCodebookAndNumCodewordInSection(H_HCR_INFO pHcr) {
700*e5436536SAndroid Build Coastguard Worker   UINT i, j, k;
701*e5436536SAndroid Build Coastguard Worker   UCHAR temp;
702*e5436536SAndroid Build Coastguard Worker   UINT counter;
703*e5436536SAndroid Build Coastguard Worker   UINT startOffset;
704*e5436536SAndroid Build Coastguard Worker   UINT numZeroSection;
705*e5436536SAndroid Build Coastguard Worker   UCHAR *pDest;
706*e5436536SAndroid Build Coastguard Worker   UINT numSectionDec;
707*e5436536SAndroid Build Coastguard Worker 
708*e5436536SAndroid Build Coastguard Worker   UINT numSection = pHcr->decInOut.numSection;
709*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodebook = pHcr->decInOut.pCodebook;
710*e5436536SAndroid Build Coastguard Worker   UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
711*e5436536SAndroid Build Coastguard Worker   USHORT *pNumCodewordInSection = pHcr->sectionInfo.pNumCodewordInSection;
712*e5436536SAndroid Build Coastguard Worker   USHORT *pNumSortedCodewordInSection =
713*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumSortedCodewordInSection;
714*e5436536SAndroid Build Coastguard Worker   UCHAR *pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
715*e5436536SAndroid Build Coastguard Worker   USHORT *pReorderOffset = pHcr->sectionInfo.pReorderOffset;
716*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbPriority = aCbPriority;
717*e5436536SAndroid Build Coastguard Worker   const UCHAR *pMinOfCbPair = aMinOfCbPair;
718*e5436536SAndroid Build Coastguard Worker   const UCHAR *pMaxOfCbPair = aMaxOfCbPair;
719*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbDimShift = aDimCbShift;
720*e5436536SAndroid Build Coastguard Worker 
721*e5436536SAndroid Build Coastguard Worker   UINT searchStart = 0;
722*e5436536SAndroid Build Coastguard Worker 
723*e5436536SAndroid Build Coastguard Worker   /* calculate *pNumSortedSection and store the priorities in array
724*e5436536SAndroid Build Coastguard Worker    * pSortedCdebook */
725*e5436536SAndroid Build Coastguard Worker   pDest = pSortedCodebook;
726*e5436536SAndroid Build Coastguard Worker   numZeroSection = 0;
727*e5436536SAndroid Build Coastguard Worker   for (i = numSection; i != 0; i--) {
728*e5436536SAndroid Build Coastguard Worker     if (pCbPriority[*pCodebook] == 0) {
729*e5436536SAndroid Build Coastguard Worker       numZeroSection += 1;
730*e5436536SAndroid Build Coastguard Worker     }
731*e5436536SAndroid Build Coastguard Worker     *pDest++ = pCbPriority[*pCodebook++];
732*e5436536SAndroid Build Coastguard Worker   }
733*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numSortedSection =
734*e5436536SAndroid Build Coastguard Worker       numSection - numZeroSection; /* numSortedSection contains no zero or
735*e5436536SAndroid Build Coastguard Worker                                       intensity section */
736*e5436536SAndroid Build Coastguard Worker   pCodebook = pHcr->decInOut.pCodebook;
737*e5436536SAndroid Build Coastguard Worker 
738*e5436536SAndroid Build Coastguard Worker   /* sort priorities of the codebooks in array pSortedCdebook[] */
739*e5436536SAndroid Build Coastguard Worker   numSectionDec = numSection - 1;
740*e5436536SAndroid Build Coastguard Worker   if (numSectionDec > 0) {
741*e5436536SAndroid Build Coastguard Worker     counter = numSectionDec;
742*e5436536SAndroid Build Coastguard Worker     for (j = numSectionDec; j != 0; j--) {
743*e5436536SAndroid Build Coastguard Worker       for (i = 0; i < counter; i++) {
744*e5436536SAndroid Build Coastguard Worker         /* swap priorities */
745*e5436536SAndroid Build Coastguard Worker         if (pSortedCodebook[i + 1] > pSortedCodebook[i]) {
746*e5436536SAndroid Build Coastguard Worker           temp = pSortedCodebook[i];
747*e5436536SAndroid Build Coastguard Worker           pSortedCodebook[i] = pSortedCodebook[i + 1];
748*e5436536SAndroid Build Coastguard Worker           pSortedCodebook[i + 1] = temp;
749*e5436536SAndroid Build Coastguard Worker         }
750*e5436536SAndroid Build Coastguard Worker       }
751*e5436536SAndroid Build Coastguard Worker       counter -= 1;
752*e5436536SAndroid Build Coastguard Worker     }
753*e5436536SAndroid Build Coastguard Worker   }
754*e5436536SAndroid Build Coastguard Worker 
755*e5436536SAndroid Build Coastguard Worker   /* clear codebookSwitch array */
756*e5436536SAndroid Build Coastguard Worker   for (i = numSection; i != 0; i--) {
757*e5436536SAndroid Build Coastguard Worker     *pCodebookSwitch++ = 0;
758*e5436536SAndroid Build Coastguard Worker   }
759*e5436536SAndroid Build Coastguard Worker   pCodebookSwitch = pHcr->sectionInfo.pCodebookSwitch;
760*e5436536SAndroid Build Coastguard Worker 
761*e5436536SAndroid Build Coastguard Worker   /* sort sectionCodebooks and numCodwordsInSection and calculate
762*e5436536SAndroid Build Coastguard Worker    * pReorderOffst[j] */
763*e5436536SAndroid Build Coastguard Worker   for (j = 0; j < numSection; j++) {
764*e5436536SAndroid Build Coastguard Worker     for (i = searchStart; i < numSection; i++) {
765*e5436536SAndroid Build Coastguard Worker       if (pCodebookSwitch[i] == 0 &&
766*e5436536SAndroid Build Coastguard Worker           (pMinOfCbPair[pSortedCodebook[j]] == pCodebook[i] ||
767*e5436536SAndroid Build Coastguard Worker            pMaxOfCbPair[pSortedCodebook[j]] == pCodebook[i])) {
768*e5436536SAndroid Build Coastguard Worker         pCodebookSwitch[i] = 1;
769*e5436536SAndroid Build Coastguard Worker         pSortedCodebook[j] = pCodebook[i]; /* sort codebook */
770*e5436536SAndroid Build Coastguard Worker         pNumSortedCodewordInSection[j] =
771*e5436536SAndroid Build Coastguard Worker             pNumCodewordInSection[i]; /* sort NumCodewordInSection */
772*e5436536SAndroid Build Coastguard Worker 
773*e5436536SAndroid Build Coastguard Worker         startOffset = 0;
774*e5436536SAndroid Build Coastguard Worker         for (k = 0; k < i; k++) { /* make entry in pReorderOffst */
775*e5436536SAndroid Build Coastguard Worker           startOffset += pNumCodewordInSection[k] << pCbDimShift[pCodebook[k]];
776*e5436536SAndroid Build Coastguard Worker         }
777*e5436536SAndroid Build Coastguard Worker         pReorderOffset[j] =
778*e5436536SAndroid Build Coastguard Worker             startOffset; /* offset for reordering the codewords */
779*e5436536SAndroid Build Coastguard Worker 
780*e5436536SAndroid Build Coastguard Worker         if (i == searchStart) {
781*e5436536SAndroid Build Coastguard Worker           k = i;
782*e5436536SAndroid Build Coastguard Worker           while (pCodebookSwitch[k++] == 1) searchStart++;
783*e5436536SAndroid Build Coastguard Worker         }
784*e5436536SAndroid Build Coastguard Worker         break;
785*e5436536SAndroid Build Coastguard Worker       }
786*e5436536SAndroid Build Coastguard Worker     }
787*e5436536SAndroid Build Coastguard Worker   }
788*e5436536SAndroid Build Coastguard Worker }
789*e5436536SAndroid Build Coastguard Worker 
790*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
791*e5436536SAndroid Build Coastguard Worker      description:   This function calculates the segmentation, which includes
792*e5436536SAndroid Build Coastguard Worker numSegment, leftStartOfSegment, rightStartOfSegment and remainingBitsInSegment.
793*e5436536SAndroid Build Coastguard Worker                     The segmentation could be visualized a as kind of
794*e5436536SAndroid Build Coastguard Worker 'overlay-grid' for the bitstream-block holding the HCR-encoded
795*e5436536SAndroid Build Coastguard Worker quantized-spectral-coefficients.
796*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
797*e5436536SAndroid Build Coastguard Worker */
798*e5436536SAndroid Build Coastguard Worker 
HcrPrepareSegmentationGrid(H_HCR_INFO pHcr)799*e5436536SAndroid Build Coastguard Worker static void HcrPrepareSegmentationGrid(H_HCR_INFO pHcr) {
800*e5436536SAndroid Build Coastguard Worker   USHORT i, j;
801*e5436536SAndroid Build Coastguard Worker   USHORT numSegment = 0;
802*e5436536SAndroid Build Coastguard Worker   INT segmentStart = 0;
803*e5436536SAndroid Build Coastguard Worker   UCHAR segmentWidth;
804*e5436536SAndroid Build Coastguard Worker   UCHAR lastSegmentWidth;
805*e5436536SAndroid Build Coastguard Worker   UCHAR sortedCodebook;
806*e5436536SAndroid Build Coastguard Worker   UCHAR endFlag = 0;
807*e5436536SAndroid Build Coastguard Worker   INT intermediateResult;
808*e5436536SAndroid Build Coastguard Worker 
809*e5436536SAndroid Build Coastguard Worker   SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
810*e5436536SAndroid Build Coastguard Worker   SHORT lengthOfReorderedSpectralData =
811*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.lengthOfReorderedSpectralData;
812*e5436536SAndroid Build Coastguard Worker   UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
813*e5436536SAndroid Build Coastguard Worker   UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
814*e5436536SAndroid Build Coastguard Worker   USHORT *pNumSortedCodewordInSection =
815*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumSortedCodewordInSection;
816*e5436536SAndroid Build Coastguard Worker   INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
817*e5436536SAndroid Build Coastguard Worker   INT *pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
818*e5436536SAndroid Build Coastguard Worker   SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
819*e5436536SAndroid Build Coastguard Worker   const UCHAR *pMaxCwLength = aMaxCwLen;
820*e5436536SAndroid Build Coastguard Worker 
821*e5436536SAndroid Build Coastguard Worker   for (i = numSortedSection; i != 0; i--) {
822*e5436536SAndroid Build Coastguard Worker     sortedCodebook = *pSortedCodebook++;
823*e5436536SAndroid Build Coastguard Worker     segmentWidth =
824*e5436536SAndroid Build Coastguard Worker         fMin((INT)pMaxCwLength[sortedCodebook], (INT)lengthOfLongestCodeword);
825*e5436536SAndroid Build Coastguard Worker 
826*e5436536SAndroid Build Coastguard Worker     for (j = *pNumSortedCodewordInSection; j != 0; j--) {
827*e5436536SAndroid Build Coastguard Worker       /* width allows a new segment */
828*e5436536SAndroid Build Coastguard Worker       intermediateResult = segmentStart;
829*e5436536SAndroid Build Coastguard Worker       if ((segmentStart + segmentWidth) <= lengthOfReorderedSpectralData) {
830*e5436536SAndroid Build Coastguard Worker         /* store segment start, segment length and increment the number of
831*e5436536SAndroid Build Coastguard Worker          * segments */
832*e5436536SAndroid Build Coastguard Worker         *pLeftStartOfSegment++ = intermediateResult;
833*e5436536SAndroid Build Coastguard Worker         *pRightStartOfSegment++ = intermediateResult + segmentWidth - 1;
834*e5436536SAndroid Build Coastguard Worker         *pRemainingBitsInSegment++ = segmentWidth;
835*e5436536SAndroid Build Coastguard Worker         segmentStart += segmentWidth;
836*e5436536SAndroid Build Coastguard Worker         numSegment += 1;
837*e5436536SAndroid Build Coastguard Worker       }
838*e5436536SAndroid Build Coastguard Worker       /* width does not allow a new segment */
839*e5436536SAndroid Build Coastguard Worker       else {
840*e5436536SAndroid Build Coastguard Worker         /* correct the last segment length */
841*e5436536SAndroid Build Coastguard Worker         pLeftStartOfSegment--;
842*e5436536SAndroid Build Coastguard Worker         pRightStartOfSegment--;
843*e5436536SAndroid Build Coastguard Worker         pRemainingBitsInSegment--;
844*e5436536SAndroid Build Coastguard Worker         segmentStart = *pLeftStartOfSegment;
845*e5436536SAndroid Build Coastguard Worker 
846*e5436536SAndroid Build Coastguard Worker         lastSegmentWidth = lengthOfReorderedSpectralData - segmentStart;
847*e5436536SAndroid Build Coastguard Worker         *pRemainingBitsInSegment = lastSegmentWidth;
848*e5436536SAndroid Build Coastguard Worker         *pRightStartOfSegment = segmentStart + lastSegmentWidth - 1;
849*e5436536SAndroid Build Coastguard Worker         endFlag = 1;
850*e5436536SAndroid Build Coastguard Worker         break;
851*e5436536SAndroid Build Coastguard Worker       }
852*e5436536SAndroid Build Coastguard Worker     }
853*e5436536SAndroid Build Coastguard Worker     pNumSortedCodewordInSection++;
854*e5436536SAndroid Build Coastguard Worker     if (endFlag != 0) {
855*e5436536SAndroid Build Coastguard Worker       break;
856*e5436536SAndroid Build Coastguard Worker     }
857*e5436536SAndroid Build Coastguard Worker   }
858*e5436536SAndroid Build Coastguard Worker   pHcr->segmentInfo.numSegment = numSegment;
859*e5436536SAndroid Build Coastguard Worker }
860*e5436536SAndroid Build Coastguard Worker 
861*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
862*e5436536SAndroid Build Coastguard Worker      description:   This function adapts the sorted section boundaries to the
863*e5436536SAndroid Build Coastguard Worker boundaries of segmentation. If the section lengths does not fit completely into
864*e5436536SAndroid Build Coastguard Worker the current segment, the section is spitted into two so called 'extended
865*e5436536SAndroid Build Coastguard Worker                     sections'. The extended-section-info
866*e5436536SAndroid Build Coastguard Worker (pNumExtendedSortedCodewordInSectin and pExtendedSortedCodebook) is updated in
867*e5436536SAndroid Build Coastguard Worker this case.
868*e5436536SAndroid Build Coastguard Worker 
869*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
870*e5436536SAndroid Build Coastguard Worker */
871*e5436536SAndroid Build Coastguard Worker 
HcrExtendedSectionInfo(H_HCR_INFO pHcr)872*e5436536SAndroid Build Coastguard Worker static void HcrExtendedSectionInfo(H_HCR_INFO pHcr) {
873*e5436536SAndroid Build Coastguard Worker   UINT srtSecCnt = 0; /* counter for sorted sections */
874*e5436536SAndroid Build Coastguard Worker   UINT xSrtScCnt = 0; /* counter for extended sorted sections */
875*e5436536SAndroid Build Coastguard Worker   UINT remainNumCwInSortSec;
876*e5436536SAndroid Build Coastguard Worker   UINT inSegmentRemainNumCW;
877*e5436536SAndroid Build Coastguard Worker 
878*e5436536SAndroid Build Coastguard Worker   UINT numSortedSection = pHcr->sectionInfo.numSortedSection;
879*e5436536SAndroid Build Coastguard Worker   UCHAR *pSortedCodebook = pHcr->sectionInfo.pSortedCodebook;
880*e5436536SAndroid Build Coastguard Worker   USHORT *pNumSortedCodewordInSection =
881*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumSortedCodewordInSection;
882*e5436536SAndroid Build Coastguard Worker   UCHAR *pExtendedSortedCoBo = pHcr->sectionInfo.pExtendedSortedCodebook;
883*e5436536SAndroid Build Coastguard Worker   USHORT *pNumExtSortCwInSect =
884*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
885*e5436536SAndroid Build Coastguard Worker   UINT numSegment = pHcr->segmentInfo.numSegment;
886*e5436536SAndroid Build Coastguard Worker   UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
887*e5436536SAndroid Build Coastguard Worker   SCHAR lengthOfLongestCodeword = pHcr->decInOut.lengthOfLongestCodeword;
888*e5436536SAndroid Build Coastguard Worker   const UCHAR *pMaxCwLength = aMaxCwLen;
889*e5436536SAndroid Build Coastguard Worker 
890*e5436536SAndroid Build Coastguard Worker   remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
891*e5436536SAndroid Build Coastguard Worker   inSegmentRemainNumCW = numSegment;
892*e5436536SAndroid Build Coastguard Worker 
893*e5436536SAndroid Build Coastguard Worker   while (srtSecCnt < numSortedSection) {
894*e5436536SAndroid Build Coastguard Worker     if (inSegmentRemainNumCW < remainNumCwInSortSec) {
895*e5436536SAndroid Build Coastguard Worker       pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
896*e5436536SAndroid Build Coastguard Worker       pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
897*e5436536SAndroid Build Coastguard Worker 
898*e5436536SAndroid Build Coastguard Worker       remainNumCwInSortSec -= inSegmentRemainNumCW;
899*e5436536SAndroid Build Coastguard Worker       inSegmentRemainNumCW = numSegment;
900*e5436536SAndroid Build Coastguard Worker       /* data of a sorted section was not integrated in extended sorted section
901*e5436536SAndroid Build Coastguard Worker        */
902*e5436536SAndroid Build Coastguard Worker     } else if (inSegmentRemainNumCW == remainNumCwInSortSec) {
903*e5436536SAndroid Build Coastguard Worker       pNumExtSortCwInSect[xSrtScCnt] = inSegmentRemainNumCW;
904*e5436536SAndroid Build Coastguard Worker       pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
905*e5436536SAndroid Build Coastguard Worker 
906*e5436536SAndroid Build Coastguard Worker       srtSecCnt++;
907*e5436536SAndroid Build Coastguard Worker       remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
908*e5436536SAndroid Build Coastguard Worker       inSegmentRemainNumCW = numSegment;
909*e5436536SAndroid Build Coastguard Worker       /* data of a sorted section was integrated in extended sorted section */
910*e5436536SAndroid Build Coastguard Worker     } else { /* inSegmentRemainNumCW > remainNumCwInSortSec */
911*e5436536SAndroid Build Coastguard Worker       pNumExtSortCwInSect[xSrtScCnt] = remainNumCwInSortSec;
912*e5436536SAndroid Build Coastguard Worker       pExtendedSortedCoBo[xSrtScCnt] = pSortedCodebook[srtSecCnt];
913*e5436536SAndroid Build Coastguard Worker 
914*e5436536SAndroid Build Coastguard Worker       inSegmentRemainNumCW -= remainNumCwInSortSec;
915*e5436536SAndroid Build Coastguard Worker       srtSecCnt++;
916*e5436536SAndroid Build Coastguard Worker       remainNumCwInSortSec = pNumSortedCodewordInSection[srtSecCnt];
917*e5436536SAndroid Build Coastguard Worker       /* data of a sorted section was integrated in extended sorted section */
918*e5436536SAndroid Build Coastguard Worker     }
919*e5436536SAndroid Build Coastguard Worker     pMaxLenOfCbInExtSrtSec[xSrtScCnt] =
920*e5436536SAndroid Build Coastguard Worker         fMin((INT)pMaxCwLength[pExtendedSortedCoBo[xSrtScCnt]],
921*e5436536SAndroid Build Coastguard Worker              (INT)lengthOfLongestCodeword);
922*e5436536SAndroid Build Coastguard Worker 
923*e5436536SAndroid Build Coastguard Worker     xSrtScCnt += 1;
924*e5436536SAndroid Build Coastguard Worker 
925*e5436536SAndroid Build Coastguard Worker     if (xSrtScCnt >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
926*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.errorLog |= EXTENDED_SORTED_COUNTER_OVERFLOW;
927*e5436536SAndroid Build Coastguard Worker       return;
928*e5436536SAndroid Build Coastguard Worker     }
929*e5436536SAndroid Build Coastguard Worker   }
930*e5436536SAndroid Build Coastguard Worker   pNumExtSortCwInSect[xSrtScCnt] = 0;
931*e5436536SAndroid Build Coastguard Worker }
932*e5436536SAndroid Build Coastguard Worker 
933*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
934*e5436536SAndroid Build Coastguard Worker      description:   This function calculates the number of extended sorted
935*e5436536SAndroid Build Coastguard Worker sections which belong to the sets. Each set from set 0 (one and only set for the
936*e5436536SAndroid Build Coastguard Worker PCWs) till to the last set gets a entry in the array to which
937*e5436536SAndroid Build Coastguard Worker                     'pNumExtendedSortedSectinsInSets' points to.
938*e5436536SAndroid Build Coastguard Worker 
939*e5436536SAndroid Build Coastguard Worker                     Calculation: The entrys in
940*e5436536SAndroid Build Coastguard Worker pNumExtendedSortedCodewordInSectin are added untill the value numSegment is
941*e5436536SAndroid Build Coastguard Worker reached. Then the sum_variable is cleared and the calculation starts from the
942*e5436536SAndroid Build Coastguard Worker beginning. As much extended sorted Sections are summed up to reach the value
943*e5436536SAndroid Build Coastguard Worker numSegment, as much is the current entry in *pNumExtendedSortedCodewordInSectin.
944*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
945*e5436536SAndroid Build Coastguard Worker */
DeriveNumberOfExtendedSortedSectionsInSets(UINT numSegment,USHORT * pNumExtendedSortedCodewordInSection,int numExtendedSortedCodewordInSectionIdx,USHORT * pNumExtendedSortedSectionsInSets,int numExtendedSortedSectionsInSetsIdx)946*e5436536SAndroid Build Coastguard Worker static void DeriveNumberOfExtendedSortedSectionsInSets(
947*e5436536SAndroid Build Coastguard Worker     UINT numSegment, USHORT *pNumExtendedSortedCodewordInSection,
948*e5436536SAndroid Build Coastguard Worker     int numExtendedSortedCodewordInSectionIdx,
949*e5436536SAndroid Build Coastguard Worker     USHORT *pNumExtendedSortedSectionsInSets,
950*e5436536SAndroid Build Coastguard Worker     int numExtendedSortedSectionsInSetsIdx) {
951*e5436536SAndroid Build Coastguard Worker   USHORT counter = 0;
952*e5436536SAndroid Build Coastguard Worker   UINT cwSum = 0;
953*e5436536SAndroid Build Coastguard Worker   USHORT *pNumExSortCwInSec = pNumExtendedSortedCodewordInSection;
954*e5436536SAndroid Build Coastguard Worker   USHORT *pNumExSortSecInSets = pNumExtendedSortedSectionsInSets;
955*e5436536SAndroid Build Coastguard Worker 
956*e5436536SAndroid Build Coastguard Worker   while (pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx] != 0) {
957*e5436536SAndroid Build Coastguard Worker     cwSum += pNumExSortCwInSec[numExtendedSortedCodewordInSectionIdx];
958*e5436536SAndroid Build Coastguard Worker     numExtendedSortedCodewordInSectionIdx++;
959*e5436536SAndroid Build Coastguard Worker     if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
960*e5436536SAndroid Build Coastguard Worker       return;
961*e5436536SAndroid Build Coastguard Worker     }
962*e5436536SAndroid Build Coastguard Worker     if (cwSum > numSegment) {
963*e5436536SAndroid Build Coastguard Worker       return;
964*e5436536SAndroid Build Coastguard Worker     }
965*e5436536SAndroid Build Coastguard Worker     counter++;
966*e5436536SAndroid Build Coastguard Worker     if (counter > 1024 / 4) {
967*e5436536SAndroid Build Coastguard Worker       return;
968*e5436536SAndroid Build Coastguard Worker     }
969*e5436536SAndroid Build Coastguard Worker     if (cwSum == numSegment) {
970*e5436536SAndroid Build Coastguard Worker       pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] = counter;
971*e5436536SAndroid Build Coastguard Worker       numExtendedSortedSectionsInSetsIdx++;
972*e5436536SAndroid Build Coastguard Worker       if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
973*e5436536SAndroid Build Coastguard Worker         return;
974*e5436536SAndroid Build Coastguard Worker       }
975*e5436536SAndroid Build Coastguard Worker       counter = 0;
976*e5436536SAndroid Build Coastguard Worker       cwSum = 0;
977*e5436536SAndroid Build Coastguard Worker     }
978*e5436536SAndroid Build Coastguard Worker   }
979*e5436536SAndroid Build Coastguard Worker   pNumExSortSecInSets[numExtendedSortedSectionsInSetsIdx] =
980*e5436536SAndroid Build Coastguard Worker       counter; /* save last entry for the last - probably shorter - set */
981*e5436536SAndroid Build Coastguard Worker }
982*e5436536SAndroid Build Coastguard Worker 
983*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
984*e5436536SAndroid Build Coastguard Worker      description:   This function decodes all priority codewords (PCWs) in a
985*e5436536SAndroid Build Coastguard Worker spectrum (within set 0). The calculation of the PCWs is managed in two loops.
986*e5436536SAndroid Build Coastguard Worker The loopcounter of the outer loop is set to the first value pointer
987*e5436536SAndroid Build Coastguard Worker                     pNumExtendedSortedSectionsInSets points to. This value
988*e5436536SAndroid Build Coastguard Worker represents the number of extended sorted sections within set 0. The loopcounter
989*e5436536SAndroid Build Coastguard Worker of the inner loop is set to the first value pointer
990*e5436536SAndroid Build Coastguard Worker                     pNumExtendedSortedCodewordInSectin points to. The value
991*e5436536SAndroid Build Coastguard Worker represents the number of extended sorted codewords in sections (the original
992*e5436536SAndroid Build Coastguard Worker sections have been splitted to go along with the borders of the sets). Each time
993*e5436536SAndroid Build Coastguard Worker the number of the extended sorted codewords in sections are de- coded, the
994*e5436536SAndroid Build Coastguard Worker pointer 'pNumExtendedSortedCodewordInSectin' is incremented by one.
995*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
996*e5436536SAndroid Build Coastguard Worker */
DecodePCWs(HANDLE_FDK_BITSTREAM bs,H_HCR_INFO pHcr)997*e5436536SAndroid Build Coastguard Worker static void DecodePCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
998*e5436536SAndroid Build Coastguard Worker   UINT i;
999*e5436536SAndroid Build Coastguard Worker   USHORT extSortSec;
1000*e5436536SAndroid Build Coastguard Worker   USHORT curExtSortCwInSec;
1001*e5436536SAndroid Build Coastguard Worker   UCHAR codebook;
1002*e5436536SAndroid Build Coastguard Worker   UCHAR dimension;
1003*e5436536SAndroid Build Coastguard Worker   const UINT *pCurrentTree;
1004*e5436536SAndroid Build Coastguard Worker   const SCHAR *pQuantValBase;
1005*e5436536SAndroid Build Coastguard Worker   const SCHAR *pQuantVal;
1006*e5436536SAndroid Build Coastguard Worker 
1007*e5436536SAndroid Build Coastguard Worker   USHORT *pNumExtendedSortedCodewordInSection =
1008*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
1009*e5436536SAndroid Build Coastguard Worker   int numExtendedSortedCodewordInSectionIdx =
1010*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
1011*e5436536SAndroid Build Coastguard Worker   UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
1012*e5436536SAndroid Build Coastguard Worker   int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
1013*e5436536SAndroid Build Coastguard Worker   USHORT *pNumExtendedSortedSectionsInSets =
1014*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
1015*e5436536SAndroid Build Coastguard Worker   int numExtendedSortedSectionsInSetsIdx =
1016*e5436536SAndroid Build Coastguard Worker       pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
1017*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *pQuantizedSpectralCoefficients =
1018*e5436536SAndroid Build Coastguard Worker       SPEC_LONG(pHcr->decInOut.pQuantizedSpectralCoefficientsBase);
1019*e5436536SAndroid Build Coastguard Worker   int quantizedSpectralCoefficientsIdx =
1020*e5436536SAndroid Build Coastguard Worker       pHcr->decInOut.quantizedSpectralCoefficientsIdx;
1021*e5436536SAndroid Build Coastguard Worker   INT *pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
1022*e5436536SAndroid Build Coastguard Worker   SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1023*e5436536SAndroid Build Coastguard Worker   UCHAR *pMaxLenOfCbInExtSrtSec = pHcr->sectionInfo.pMaxLenOfCbInExtSrtSec;
1024*e5436536SAndroid Build Coastguard Worker   int maxLenOfCbInExtSrtSecIdx = pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx;
1025*e5436536SAndroid Build Coastguard Worker   UCHAR maxAllowedCwLen;
1026*e5436536SAndroid Build Coastguard Worker   int numDecodedBits;
1027*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbDimension = aDimCb;
1028*e5436536SAndroid Build Coastguard Worker   const UCHAR *pCbSign = aSignCb;
1029*e5436536SAndroid Build Coastguard Worker 
1030*e5436536SAndroid Build Coastguard Worker   /* clear result array */
1031*e5436536SAndroid Build Coastguard Worker   FDKmemclear(pQuantizedSpectralCoefficients + quantizedSpectralCoefficientsIdx,
1032*e5436536SAndroid Build Coastguard Worker               1024 * sizeof(FIXP_DBL));
1033*e5436536SAndroid Build Coastguard Worker 
1034*e5436536SAndroid Build Coastguard Worker   /* decode all PCWs in the extended sorted section(s) belonging to set 0 */
1035*e5436536SAndroid Build Coastguard Worker   for (extSortSec =
1036*e5436536SAndroid Build Coastguard Worker            pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
1037*e5436536SAndroid Build Coastguard Worker        extSortSec != 0; extSortSec--) {
1038*e5436536SAndroid Build Coastguard Worker     codebook =
1039*e5436536SAndroid Build Coastguard Worker         pExtendedSortedCodebook[extendedSortedCodebookIdx]; /* get codebook for
1040*e5436536SAndroid Build Coastguard Worker                                                                this extended
1041*e5436536SAndroid Build Coastguard Worker                                                                sorted section
1042*e5436536SAndroid Build Coastguard Worker                                                                and increment ptr
1043*e5436536SAndroid Build Coastguard Worker                                                                to cb of next
1044*e5436536SAndroid Build Coastguard Worker                                                                ext. sort sec */
1045*e5436536SAndroid Build Coastguard Worker     extendedSortedCodebookIdx++;
1046*e5436536SAndroid Build Coastguard Worker     if (extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
1047*e5436536SAndroid Build Coastguard Worker       return;
1048*e5436536SAndroid Build Coastguard Worker     }
1049*e5436536SAndroid Build Coastguard Worker     dimension = pCbDimension[codebook]; /* get dimension of codebook of this
1050*e5436536SAndroid Build Coastguard Worker                                            extended sort. sec. */
1051*e5436536SAndroid Build Coastguard Worker     pCurrentTree =
1052*e5436536SAndroid Build Coastguard Worker         aHuffTable[codebook]; /* convert codebook to pointer to QSCs */
1053*e5436536SAndroid Build Coastguard Worker     pQuantValBase =
1054*e5436536SAndroid Build Coastguard Worker         aQuantTable[codebook]; /* convert codebook to index to table of QSCs */
1055*e5436536SAndroid Build Coastguard Worker     maxAllowedCwLen = pMaxLenOfCbInExtSrtSec[maxLenOfCbInExtSrtSecIdx];
1056*e5436536SAndroid Build Coastguard Worker     maxLenOfCbInExtSrtSecIdx++;
1057*e5436536SAndroid Build Coastguard Worker     if (maxLenOfCbInExtSrtSecIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
1058*e5436536SAndroid Build Coastguard Worker       return;
1059*e5436536SAndroid Build Coastguard Worker     }
1060*e5436536SAndroid Build Coastguard Worker 
1061*e5436536SAndroid Build Coastguard Worker     /* switch for decoding with different codebooks: */
1062*e5436536SAndroid Build Coastguard Worker     if (pCbSign[codebook] ==
1063*e5436536SAndroid Build Coastguard Worker         0) { /* no sign bits follow after the codeword-body */
1064*e5436536SAndroid Build Coastguard Worker       /* PCW_BodyONLY */
1065*e5436536SAndroid Build Coastguard Worker       /*==============*/
1066*e5436536SAndroid Build Coastguard Worker 
1067*e5436536SAndroid Build Coastguard Worker       for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1068*e5436536SAndroid Build Coastguard Worker                [numExtendedSortedCodewordInSectionIdx];
1069*e5436536SAndroid Build Coastguard Worker            curExtSortCwInSec != 0; curExtSortCwInSec--) {
1070*e5436536SAndroid Build Coastguard Worker         numDecodedBits = 0;
1071*e5436536SAndroid Build Coastguard Worker 
1072*e5436536SAndroid Build Coastguard Worker         /* decode PCW_BODY */
1073*e5436536SAndroid Build Coastguard Worker         pQuantVal = DecodePCW_Body(
1074*e5436536SAndroid Build Coastguard Worker             bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1075*e5436536SAndroid Build Coastguard Worker             pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1076*e5436536SAndroid Build Coastguard Worker 
1077*e5436536SAndroid Build Coastguard Worker         /* result is written out here because NO sign bits follow the body */
1078*e5436536SAndroid Build Coastguard Worker         for (i = dimension; i != 0; i--) {
1079*e5436536SAndroid Build Coastguard Worker           pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1080*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)*pQuantVal++; /* write quant. spec. coef. into
1081*e5436536SAndroid Build Coastguard Worker                                          spectrum; sign is already valid */
1082*e5436536SAndroid Build Coastguard Worker           quantizedSpectralCoefficientsIdx++;
1083*e5436536SAndroid Build Coastguard Worker           if (quantizedSpectralCoefficientsIdx >= 1024) {
1084*e5436536SAndroid Build Coastguard Worker             return;
1085*e5436536SAndroid Build Coastguard Worker           }
1086*e5436536SAndroid Build Coastguard Worker         }
1087*e5436536SAndroid Build Coastguard Worker 
1088*e5436536SAndroid Build Coastguard Worker         /* one more PCW should be decoded */
1089*e5436536SAndroid Build Coastguard Worker 
1090*e5436536SAndroid Build Coastguard Worker         if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_ONLY_TOO_LONG)) {
1091*e5436536SAndroid Build Coastguard Worker           pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_BITS_DECODED;
1092*e5436536SAndroid Build Coastguard Worker         }
1093*e5436536SAndroid Build Coastguard Worker 
1094*e5436536SAndroid Build Coastguard Worker         if (1 == errDetectPcwSegmentation(
1095*e5436536SAndroid Build Coastguard Worker                      *pRemainingBitsInSegment - ERROR_PCW_BODY, pHcr, PCW_BODY,
1096*e5436536SAndroid Build Coastguard Worker                      pQuantizedSpectralCoefficients +
1097*e5436536SAndroid Build Coastguard Worker                          quantizedSpectralCoefficientsIdx - dimension,
1098*e5436536SAndroid Build Coastguard Worker                      dimension)) {
1099*e5436536SAndroid Build Coastguard Worker           return;
1100*e5436536SAndroid Build Coastguard Worker         }
1101*e5436536SAndroid Build Coastguard Worker         pLeftStartOfSegment++; /* update pointer for decoding the next PCW */
1102*e5436536SAndroid Build Coastguard Worker         pRemainingBitsInSegment++; /* update pointer for decoding the next PCW
1103*e5436536SAndroid Build Coastguard Worker                                     */
1104*e5436536SAndroid Build Coastguard Worker       }
1105*e5436536SAndroid Build Coastguard Worker     } else if ((codebook < 11) && (pCbSign[codebook] ==
1106*e5436536SAndroid Build Coastguard Worker                                    1)) { /* possibly there follow 1,2,3 or 4
1107*e5436536SAndroid Build Coastguard Worker                                             sign bits after the codeword-body */
1108*e5436536SAndroid Build Coastguard Worker       /* PCW_Body and PCW_Sign */
1109*e5436536SAndroid Build Coastguard Worker       /*=======================*/
1110*e5436536SAndroid Build Coastguard Worker 
1111*e5436536SAndroid Build Coastguard Worker       for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1112*e5436536SAndroid Build Coastguard Worker                [numExtendedSortedCodewordInSectionIdx];
1113*e5436536SAndroid Build Coastguard Worker            curExtSortCwInSec != 0; curExtSortCwInSec--) {
1114*e5436536SAndroid Build Coastguard Worker         int err;
1115*e5436536SAndroid Build Coastguard Worker         numDecodedBits = 0;
1116*e5436536SAndroid Build Coastguard Worker 
1117*e5436536SAndroid Build Coastguard Worker         pQuantVal = DecodePCW_Body(
1118*e5436536SAndroid Build Coastguard Worker             bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1119*e5436536SAndroid Build Coastguard Worker             pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1120*e5436536SAndroid Build Coastguard Worker 
1121*e5436536SAndroid Build Coastguard Worker         err = DecodePCW_Sign(
1122*e5436536SAndroid Build Coastguard Worker             bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
1123*e5436536SAndroid Build Coastguard Worker             pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
1124*e5436536SAndroid Build Coastguard Worker             pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1125*e5436536SAndroid Build Coastguard Worker         if (err != 0) {
1126*e5436536SAndroid Build Coastguard Worker           return;
1127*e5436536SAndroid Build Coastguard Worker         }
1128*e5436536SAndroid Build Coastguard Worker         /* one more PCW should be decoded */
1129*e5436536SAndroid Build Coastguard Worker 
1130*e5436536SAndroid Build Coastguard Worker         if (maxAllowedCwLen < (numDecodedBits + ERROR_PCW_BODY_SIGN_TOO_LONG)) {
1131*e5436536SAndroid Build Coastguard Worker           pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_BITS_DECODED;
1132*e5436536SAndroid Build Coastguard Worker         }
1133*e5436536SAndroid Build Coastguard Worker 
1134*e5436536SAndroid Build Coastguard Worker         if (1 == errDetectPcwSegmentation(
1135*e5436536SAndroid Build Coastguard Worker                      *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN, pHcr,
1136*e5436536SAndroid Build Coastguard Worker                      PCW_BODY_SIGN,
1137*e5436536SAndroid Build Coastguard Worker                      pQuantizedSpectralCoefficients +
1138*e5436536SAndroid Build Coastguard Worker                          quantizedSpectralCoefficientsIdx - dimension,
1139*e5436536SAndroid Build Coastguard Worker                      dimension)) {
1140*e5436536SAndroid Build Coastguard Worker           return;
1141*e5436536SAndroid Build Coastguard Worker         }
1142*e5436536SAndroid Build Coastguard Worker         pLeftStartOfSegment++;
1143*e5436536SAndroid Build Coastguard Worker         pRemainingBitsInSegment++;
1144*e5436536SAndroid Build Coastguard Worker       }
1145*e5436536SAndroid Build Coastguard Worker     } else if ((pCbSign[codebook] == 1) &&
1146*e5436536SAndroid Build Coastguard Worker                (codebook >= 11)) { /* possibly there follow some sign bits and
1147*e5436536SAndroid Build Coastguard Worker                                       maybe one or two escape sequences after
1148*e5436536SAndroid Build Coastguard Worker                                       the cw-body */
1149*e5436536SAndroid Build Coastguard Worker       /* PCW_Body, PCW_Sign and maybe PCW_Escape */
1150*e5436536SAndroid Build Coastguard Worker       /*=========================================*/
1151*e5436536SAndroid Build Coastguard Worker 
1152*e5436536SAndroid Build Coastguard Worker       for (curExtSortCwInSec = pNumExtendedSortedCodewordInSection
1153*e5436536SAndroid Build Coastguard Worker                [numExtendedSortedCodewordInSectionIdx];
1154*e5436536SAndroid Build Coastguard Worker            curExtSortCwInSec != 0; curExtSortCwInSec--) {
1155*e5436536SAndroid Build Coastguard Worker         int err;
1156*e5436536SAndroid Build Coastguard Worker         numDecodedBits = 0;
1157*e5436536SAndroid Build Coastguard Worker 
1158*e5436536SAndroid Build Coastguard Worker         /* decode PCW_BODY */
1159*e5436536SAndroid Build Coastguard Worker         pQuantVal = DecodePCW_Body(
1160*e5436536SAndroid Build Coastguard Worker             bs, pHcr->decInOut.bitstreamAnchor, pCurrentTree, pQuantValBase,
1161*e5436536SAndroid Build Coastguard Worker             pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1162*e5436536SAndroid Build Coastguard Worker 
1163*e5436536SAndroid Build Coastguard Worker         err = DecodePCW_Sign(
1164*e5436536SAndroid Build Coastguard Worker             bs, pHcr->decInOut.bitstreamAnchor, dimension, pQuantVal,
1165*e5436536SAndroid Build Coastguard Worker             pQuantizedSpectralCoefficients, &quantizedSpectralCoefficientsIdx,
1166*e5436536SAndroid Build Coastguard Worker             pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits);
1167*e5436536SAndroid Build Coastguard Worker         if (err != 0) {
1168*e5436536SAndroid Build Coastguard Worker           return;
1169*e5436536SAndroid Build Coastguard Worker         }
1170*e5436536SAndroid Build Coastguard Worker 
1171*e5436536SAndroid Build Coastguard Worker         /* decode PCW_ESCAPE if present */
1172*e5436536SAndroid Build Coastguard Worker         quantizedSpectralCoefficientsIdx -= DIMENSION_OF_ESCAPE_CODEBOOK;
1173*e5436536SAndroid Build Coastguard Worker 
1174*e5436536SAndroid Build Coastguard Worker         if (fixp_abs(pQuantizedSpectralCoefficients
1175*e5436536SAndroid Build Coastguard Worker                          [quantizedSpectralCoefficientsIdx]) ==
1176*e5436536SAndroid Build Coastguard Worker             (FIXP_DBL)ESCAPE_VALUE) {
1177*e5436536SAndroid Build Coastguard Worker           pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1178*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)DecodeEscapeSequence(
1179*e5436536SAndroid Build Coastguard Worker                   bs, pHcr->decInOut.bitstreamAnchor,
1180*e5436536SAndroid Build Coastguard Worker                   pQuantizedSpectralCoefficients
1181*e5436536SAndroid Build Coastguard Worker                       [quantizedSpectralCoefficientsIdx],
1182*e5436536SAndroid Build Coastguard Worker                   pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
1183*e5436536SAndroid Build Coastguard Worker                   &pHcr->decInOut.errorLog);
1184*e5436536SAndroid Build Coastguard Worker         }
1185*e5436536SAndroid Build Coastguard Worker         quantizedSpectralCoefficientsIdx++;
1186*e5436536SAndroid Build Coastguard Worker         if (quantizedSpectralCoefficientsIdx >= 1024) {
1187*e5436536SAndroid Build Coastguard Worker           return;
1188*e5436536SAndroid Build Coastguard Worker         }
1189*e5436536SAndroid Build Coastguard Worker 
1190*e5436536SAndroid Build Coastguard Worker         if (fixp_abs(pQuantizedSpectralCoefficients
1191*e5436536SAndroid Build Coastguard Worker                          [quantizedSpectralCoefficientsIdx]) ==
1192*e5436536SAndroid Build Coastguard Worker             (FIXP_DBL)ESCAPE_VALUE) {
1193*e5436536SAndroid Build Coastguard Worker           pQuantizedSpectralCoefficients[quantizedSpectralCoefficientsIdx] =
1194*e5436536SAndroid Build Coastguard Worker               (FIXP_DBL)DecodeEscapeSequence(
1195*e5436536SAndroid Build Coastguard Worker                   bs, pHcr->decInOut.bitstreamAnchor,
1196*e5436536SAndroid Build Coastguard Worker                   pQuantizedSpectralCoefficients
1197*e5436536SAndroid Build Coastguard Worker                       [quantizedSpectralCoefficientsIdx],
1198*e5436536SAndroid Build Coastguard Worker                   pLeftStartOfSegment, pRemainingBitsInSegment, &numDecodedBits,
1199*e5436536SAndroid Build Coastguard Worker                   &pHcr->decInOut.errorLog);
1200*e5436536SAndroid Build Coastguard Worker         }
1201*e5436536SAndroid Build Coastguard Worker         quantizedSpectralCoefficientsIdx++;
1202*e5436536SAndroid Build Coastguard Worker         if (quantizedSpectralCoefficientsIdx >= 1024) {
1203*e5436536SAndroid Build Coastguard Worker           return;
1204*e5436536SAndroid Build Coastguard Worker         }
1205*e5436536SAndroid Build Coastguard Worker 
1206*e5436536SAndroid Build Coastguard Worker         /* one more PCW should be decoded */
1207*e5436536SAndroid Build Coastguard Worker 
1208*e5436536SAndroid Build Coastguard Worker         if (maxAllowedCwLen <
1209*e5436536SAndroid Build Coastguard Worker             (numDecodedBits + ERROR_PCW_BODY_SIGN_ESC_TOO_LONG)) {
1210*e5436536SAndroid Build Coastguard Worker           pHcr->decInOut.errorLog |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
1211*e5436536SAndroid Build Coastguard Worker         }
1212*e5436536SAndroid Build Coastguard Worker 
1213*e5436536SAndroid Build Coastguard Worker         if (1 == errDetectPcwSegmentation(
1214*e5436536SAndroid Build Coastguard Worker                      *pRemainingBitsInSegment - ERROR_PCW_BODY_SIGN_ESC, pHcr,
1215*e5436536SAndroid Build Coastguard Worker                      PCW_BODY_SIGN_ESC,
1216*e5436536SAndroid Build Coastguard Worker                      pQuantizedSpectralCoefficients +
1217*e5436536SAndroid Build Coastguard Worker                          quantizedSpectralCoefficientsIdx -
1218*e5436536SAndroid Build Coastguard Worker                          DIMENSION_OF_ESCAPE_CODEBOOK,
1219*e5436536SAndroid Build Coastguard Worker                      DIMENSION_OF_ESCAPE_CODEBOOK)) {
1220*e5436536SAndroid Build Coastguard Worker           return;
1221*e5436536SAndroid Build Coastguard Worker         }
1222*e5436536SAndroid Build Coastguard Worker         pLeftStartOfSegment++;
1223*e5436536SAndroid Build Coastguard Worker         pRemainingBitsInSegment++;
1224*e5436536SAndroid Build Coastguard Worker       }
1225*e5436536SAndroid Build Coastguard Worker     }
1226*e5436536SAndroid Build Coastguard Worker 
1227*e5436536SAndroid Build Coastguard Worker     /* all PCWs belonging to this extended section should be decoded */
1228*e5436536SAndroid Build Coastguard Worker     numExtendedSortedCodewordInSectionIdx++;
1229*e5436536SAndroid Build Coastguard Worker     if (numExtendedSortedCodewordInSectionIdx >= MAX_SFB_HCR + MAX_HCR_SETS) {
1230*e5436536SAndroid Build Coastguard Worker       return;
1231*e5436536SAndroid Build Coastguard Worker     }
1232*e5436536SAndroid Build Coastguard Worker   }
1233*e5436536SAndroid Build Coastguard Worker   /* all PCWs should be decoded */
1234*e5436536SAndroid Build Coastguard Worker 
1235*e5436536SAndroid Build Coastguard Worker   numExtendedSortedSectionsInSetsIdx++;
1236*e5436536SAndroid Build Coastguard Worker   if (numExtendedSortedSectionsInSetsIdx >= MAX_HCR_SETS) {
1237*e5436536SAndroid Build Coastguard Worker     return;
1238*e5436536SAndroid Build Coastguard Worker   }
1239*e5436536SAndroid Build Coastguard Worker 
1240*e5436536SAndroid Build Coastguard Worker   /* Write back indexes into structure */
1241*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
1242*e5436536SAndroid Build Coastguard Worker       numExtendedSortedCodewordInSectionIdx;
1243*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
1244*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
1245*e5436536SAndroid Build Coastguard Worker       numExtendedSortedSectionsInSetsIdx;
1246*e5436536SAndroid Build Coastguard Worker   pHcr->decInOut.quantizedSpectralCoefficientsIdx =
1247*e5436536SAndroid Build Coastguard Worker       quantizedSpectralCoefficientsIdx;
1248*e5436536SAndroid Build Coastguard Worker   pHcr->sectionInfo.maxLenOfCbInExtSrtSecIdx = maxLenOfCbInExtSrtSecIdx;
1249*e5436536SAndroid Build Coastguard Worker }
1250*e5436536SAndroid Build Coastguard Worker 
1251*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1252*e5436536SAndroid Build Coastguard Worker      description:   This function checks immediately after every decoded PCW,
1253*e5436536SAndroid Build Coastguard Worker whether out of the current segment too many bits have been read or not. If an
1254*e5436536SAndroid Build Coastguard Worker error occurrs, probably the sideinfo or the HCR-bitstream block holding the
1255*e5436536SAndroid Build Coastguard Worker huffman encoded quantized spectral coefficients is distorted. In this case the
1256*e5436536SAndroid Build Coastguard Worker two or four quantized spectral coefficients belonging to the current codeword
1257*e5436536SAndroid Build Coastguard Worker                     are marked (for being detected by concealment later).
1258*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1259*e5436536SAndroid Build Coastguard Worker */
errDetectPcwSegmentation(SCHAR remainingBitsInSegment,H_HCR_INFO pHcr,PCW_TYPE kind,FIXP_DBL * qsc_base_of_cw,UCHAR dimension)1260*e5436536SAndroid Build Coastguard Worker static UCHAR errDetectPcwSegmentation(SCHAR remainingBitsInSegment,
1261*e5436536SAndroid Build Coastguard Worker                                       H_HCR_INFO pHcr, PCW_TYPE kind,
1262*e5436536SAndroid Build Coastguard Worker                                       FIXP_DBL *qsc_base_of_cw,
1263*e5436536SAndroid Build Coastguard Worker                                       UCHAR dimension) {
1264*e5436536SAndroid Build Coastguard Worker   SCHAR i;
1265*e5436536SAndroid Build Coastguard Worker   if (remainingBitsInSegment < 0) {
1266*e5436536SAndroid Build Coastguard Worker     /* log the error */
1267*e5436536SAndroid Build Coastguard Worker     switch (kind) {
1268*e5436536SAndroid Build Coastguard Worker       case PCW_BODY:
1269*e5436536SAndroid Build Coastguard Worker         pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY;
1270*e5436536SAndroid Build Coastguard Worker         break;
1271*e5436536SAndroid Build Coastguard Worker       case PCW_BODY_SIGN:
1272*e5436536SAndroid Build Coastguard Worker         pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN;
1273*e5436536SAndroid Build Coastguard Worker         break;
1274*e5436536SAndroid Build Coastguard Worker       case PCW_BODY_SIGN_ESC:
1275*e5436536SAndroid Build Coastguard Worker         pHcr->decInOut.errorLog |= SEGMENT_OVERRIDE_ERR_PCW_BODY_SIGN_ESC;
1276*e5436536SAndroid Build Coastguard Worker         break;
1277*e5436536SAndroid Build Coastguard Worker     }
1278*e5436536SAndroid Build Coastguard Worker     /* mark the erred lines */
1279*e5436536SAndroid Build Coastguard Worker     for (i = dimension; i != 0; i--) {
1280*e5436536SAndroid Build Coastguard Worker       *qsc_base_of_cw++ = (FIXP_DBL)Q_VALUE_INVALID;
1281*e5436536SAndroid Build Coastguard Worker     }
1282*e5436536SAndroid Build Coastguard Worker     return 1;
1283*e5436536SAndroid Build Coastguard Worker   }
1284*e5436536SAndroid Build Coastguard Worker   return 0;
1285*e5436536SAndroid Build Coastguard Worker }
1286*e5436536SAndroid Build Coastguard Worker 
1287*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1288*e5436536SAndroid Build Coastguard Worker      description:   This function checks if all segments are empty after
1289*e5436536SAndroid Build Coastguard Worker decoding. There are _no lines markded_ as invalid because it could not be traced
1290*e5436536SAndroid Build Coastguard Worker back where from the remaining bits are.
1291*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1292*e5436536SAndroid Build Coastguard Worker */
errDetectWithinSegmentationFinal(H_HCR_INFO pHcr)1293*e5436536SAndroid Build Coastguard Worker static void errDetectWithinSegmentationFinal(H_HCR_INFO pHcr) {
1294*e5436536SAndroid Build Coastguard Worker   UCHAR segmentationErrorFlag = 0;
1295*e5436536SAndroid Build Coastguard Worker   USHORT i;
1296*e5436536SAndroid Build Coastguard Worker   SCHAR *pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1297*e5436536SAndroid Build Coastguard Worker   UINT numSegment = pHcr->segmentInfo.numSegment;
1298*e5436536SAndroid Build Coastguard Worker 
1299*e5436536SAndroid Build Coastguard Worker   for (i = numSegment; i != 0; i--) {
1300*e5436536SAndroid Build Coastguard Worker     if (*pRemainingBitsInSegment++ != 0) {
1301*e5436536SAndroid Build Coastguard Worker       segmentationErrorFlag = 1;
1302*e5436536SAndroid Build Coastguard Worker     }
1303*e5436536SAndroid Build Coastguard Worker   }
1304*e5436536SAndroid Build Coastguard Worker   if (segmentationErrorFlag == 1) {
1305*e5436536SAndroid Build Coastguard Worker     pHcr->decInOut.errorLog |= BIT_IN_SEGMENTATION_ERROR;
1306*e5436536SAndroid Build Coastguard Worker   }
1307*e5436536SAndroid Build Coastguard Worker }
1308*e5436536SAndroid Build Coastguard Worker 
1309*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1310*e5436536SAndroid Build Coastguard Worker      description:   This function walks one step within the decoding tree. Which
1311*e5436536SAndroid Build Coastguard Worker branch is taken depends on the decoded carryBit input parameter.
1312*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1313*e5436536SAndroid Build Coastguard Worker */
CarryBitToBranchValue(UCHAR carryBit,UINT treeNode,UINT * branchValue,UINT * branchNode)1314*e5436536SAndroid Build Coastguard Worker void CarryBitToBranchValue(UCHAR carryBit, UINT treeNode, UINT *branchValue,
1315*e5436536SAndroid Build Coastguard Worker                            UINT *branchNode) {
1316*e5436536SAndroid Build Coastguard Worker   if (carryBit == 0) {
1317*e5436536SAndroid Build Coastguard Worker     *branchNode =
1318*e5436536SAndroid Build Coastguard Worker         (treeNode & MASK_LEFT) >> LEFT_OFFSET; /* MASK_LEFT:  00FFF000 */
1319*e5436536SAndroid Build Coastguard Worker   } else {
1320*e5436536SAndroid Build Coastguard Worker     *branchNode = treeNode & MASK_RIGHT; /* MASK_RIGHT: 00000FFF */
1321*e5436536SAndroid Build Coastguard Worker   }
1322*e5436536SAndroid Build Coastguard Worker 
1323*e5436536SAndroid Build Coastguard Worker   *branchValue = *branchNode & CLR_BIT_10; /* clear bit 10 (if set) */
1324*e5436536SAndroid Build Coastguard Worker }
1325*e5436536SAndroid Build Coastguard Worker 
1326*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1327*e5436536SAndroid Build Coastguard Worker      description:   Decodes the body of a priority codeword (PCW)
1328*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1329*e5436536SAndroid Build Coastguard Worker         return:   - return value is pointer to first of two or four quantized
1330*e5436536SAndroid Build Coastguard Worker spectral coefficients
1331*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1332*e5436536SAndroid Build Coastguard Worker */
DecodePCW_Body(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,const UINT * pCurrentTree,const SCHAR * pQuantValBase,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits)1333*e5436536SAndroid Build Coastguard Worker static const SCHAR *DecodePCW_Body(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1334*e5436536SAndroid Build Coastguard Worker                                    const UINT *pCurrentTree,
1335*e5436536SAndroid Build Coastguard Worker                                    const SCHAR *pQuantValBase,
1336*e5436536SAndroid Build Coastguard Worker                                    INT *pLeftStartOfSegment,
1337*e5436536SAndroid Build Coastguard Worker                                    SCHAR *pRemainingBitsInSegment,
1338*e5436536SAndroid Build Coastguard Worker                                    int *pNumDecodedBits) {
1339*e5436536SAndroid Build Coastguard Worker   UCHAR carryBit;
1340*e5436536SAndroid Build Coastguard Worker   UINT branchNode;
1341*e5436536SAndroid Build Coastguard Worker   UINT treeNode;
1342*e5436536SAndroid Build Coastguard Worker   UINT branchValue;
1343*e5436536SAndroid Build Coastguard Worker   const SCHAR *pQuantVal;
1344*e5436536SAndroid Build Coastguard Worker 
1345*e5436536SAndroid Build Coastguard Worker   /* decode PCW_BODY */
1346*e5436536SAndroid Build Coastguard Worker   treeNode = *pCurrentTree; /* get first node of current tree belonging to
1347*e5436536SAndroid Build Coastguard Worker                                current codebook */
1348*e5436536SAndroid Build Coastguard Worker 
1349*e5436536SAndroid Build Coastguard Worker   /* decode whole PCW-codeword-body */
1350*e5436536SAndroid Build Coastguard Worker   while (1) {
1351*e5436536SAndroid Build Coastguard Worker     carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1352*e5436536SAndroid Build Coastguard Worker                                        pLeftStartOfSegment, /* dummy */
1353*e5436536SAndroid Build Coastguard Worker                                        FROM_LEFT_TO_RIGHT);
1354*e5436536SAndroid Build Coastguard Worker     *pRemainingBitsInSegment -= 1;
1355*e5436536SAndroid Build Coastguard Worker     *pNumDecodedBits += 1;
1356*e5436536SAndroid Build Coastguard Worker 
1357*e5436536SAndroid Build Coastguard Worker     CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
1358*e5436536SAndroid Build Coastguard Worker 
1359*e5436536SAndroid Build Coastguard Worker     if ((branchNode & TEST_BIT_10) ==
1360*e5436536SAndroid Build Coastguard Worker         TEST_BIT_10) { /* test bit 10 ; if set --> codeword-body is complete */
1361*e5436536SAndroid Build Coastguard Worker       break; /* end of branch in tree reached  i.e. a whole PCW-Body is decoded
1362*e5436536SAndroid Build Coastguard Worker               */
1363*e5436536SAndroid Build Coastguard Worker     } else {
1364*e5436536SAndroid Build Coastguard Worker       treeNode = *(
1365*e5436536SAndroid Build Coastguard Worker           pCurrentTree +
1366*e5436536SAndroid Build Coastguard Worker           branchValue); /* update treeNode for further step in decoding tree */
1367*e5436536SAndroid Build Coastguard Worker     }
1368*e5436536SAndroid Build Coastguard Worker   }
1369*e5436536SAndroid Build Coastguard Worker 
1370*e5436536SAndroid Build Coastguard Worker   pQuantVal =
1371*e5436536SAndroid Build Coastguard Worker       pQuantValBase + branchValue; /* update pointer to valid first of 2 or 4
1372*e5436536SAndroid Build Coastguard Worker                                       quantized values */
1373*e5436536SAndroid Build Coastguard Worker 
1374*e5436536SAndroid Build Coastguard Worker   return pQuantVal;
1375*e5436536SAndroid Build Coastguard Worker }
1376*e5436536SAndroid Build Coastguard Worker 
1377*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1378*e5436536SAndroid Build Coastguard Worker      description:   This function decodes one escape sequence. In case of a
1379*e5436536SAndroid Build Coastguard Worker escape codebook and in case of the absolute value of the quantized spectral
1380*e5436536SAndroid Build Coastguard Worker value == 16, a escapeSequence is decoded in two steps:
1381*e5436536SAndroid Build Coastguard Worker                       1. escape prefix
1382*e5436536SAndroid Build Coastguard Worker                       2. escape word
1383*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1384*e5436536SAndroid Build Coastguard Worker */
1385*e5436536SAndroid Build Coastguard Worker 
DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,INT quantSpecCoef,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits,UINT * errorWord)1386*e5436536SAndroid Build Coastguard Worker static INT DecodeEscapeSequence(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1387*e5436536SAndroid Build Coastguard Worker                                 INT quantSpecCoef, INT *pLeftStartOfSegment,
1388*e5436536SAndroid Build Coastguard Worker                                 SCHAR *pRemainingBitsInSegment,
1389*e5436536SAndroid Build Coastguard Worker                                 int *pNumDecodedBits, UINT *errorWord) {
1390*e5436536SAndroid Build Coastguard Worker   UINT i;
1391*e5436536SAndroid Build Coastguard Worker   INT sign;
1392*e5436536SAndroid Build Coastguard Worker   UINT escapeOnesCounter = 0;
1393*e5436536SAndroid Build Coastguard Worker   UINT carryBit;
1394*e5436536SAndroid Build Coastguard Worker   INT escape_word = 0;
1395*e5436536SAndroid Build Coastguard Worker 
1396*e5436536SAndroid Build Coastguard Worker   /* decode escape prefix */
1397*e5436536SAndroid Build Coastguard Worker   while (1) {
1398*e5436536SAndroid Build Coastguard Worker     carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1399*e5436536SAndroid Build Coastguard Worker                                        pLeftStartOfSegment, /* dummy */
1400*e5436536SAndroid Build Coastguard Worker                                        FROM_LEFT_TO_RIGHT);
1401*e5436536SAndroid Build Coastguard Worker     *pRemainingBitsInSegment -= 1;
1402*e5436536SAndroid Build Coastguard Worker     *pNumDecodedBits += 1;
1403*e5436536SAndroid Build Coastguard Worker     if (*pRemainingBitsInSegment < 0) {
1404*e5436536SAndroid Build Coastguard Worker       return Q_VALUE_INVALID;
1405*e5436536SAndroid Build Coastguard Worker     }
1406*e5436536SAndroid Build Coastguard Worker 
1407*e5436536SAndroid Build Coastguard Worker     if (carryBit != 0) {
1408*e5436536SAndroid Build Coastguard Worker       escapeOnesCounter += 1;
1409*e5436536SAndroid Build Coastguard Worker     } else {
1410*e5436536SAndroid Build Coastguard Worker       escapeOnesCounter += 4;
1411*e5436536SAndroid Build Coastguard Worker       break;
1412*e5436536SAndroid Build Coastguard Worker     }
1413*e5436536SAndroid Build Coastguard Worker   }
1414*e5436536SAndroid Build Coastguard Worker 
1415*e5436536SAndroid Build Coastguard Worker   /* decode escape word */
1416*e5436536SAndroid Build Coastguard Worker   for (i = escapeOnesCounter; i != 0; i--) {
1417*e5436536SAndroid Build Coastguard Worker     carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1418*e5436536SAndroid Build Coastguard Worker                                        pLeftStartOfSegment, /* dummy */
1419*e5436536SAndroid Build Coastguard Worker                                        FROM_LEFT_TO_RIGHT);
1420*e5436536SAndroid Build Coastguard Worker     *pRemainingBitsInSegment -= 1;
1421*e5436536SAndroid Build Coastguard Worker     *pNumDecodedBits += 1;
1422*e5436536SAndroid Build Coastguard Worker     if (*pRemainingBitsInSegment < 0) {
1423*e5436536SAndroid Build Coastguard Worker       return Q_VALUE_INVALID;
1424*e5436536SAndroid Build Coastguard Worker     }
1425*e5436536SAndroid Build Coastguard Worker 
1426*e5436536SAndroid Build Coastguard Worker     escape_word <<= 1;
1427*e5436536SAndroid Build Coastguard Worker     escape_word = escape_word | carryBit;
1428*e5436536SAndroid Build Coastguard Worker   }
1429*e5436536SAndroid Build Coastguard Worker 
1430*e5436536SAndroid Build Coastguard Worker   sign = (quantSpecCoef >= 0) ? 1 : -1;
1431*e5436536SAndroid Build Coastguard Worker 
1432*e5436536SAndroid Build Coastguard Worker   if (escapeOnesCounter < 13) {
1433*e5436536SAndroid Build Coastguard Worker     quantSpecCoef = sign * (((INT)1 << escapeOnesCounter) + escape_word);
1434*e5436536SAndroid Build Coastguard Worker   } else {
1435*e5436536SAndroid Build Coastguard Worker     *errorWord |= TOO_MANY_PCW_BODY_SIGN_ESC_BITS_DECODED;
1436*e5436536SAndroid Build Coastguard Worker     quantSpecCoef = Q_VALUE_INVALID;
1437*e5436536SAndroid Build Coastguard Worker   }
1438*e5436536SAndroid Build Coastguard Worker   return quantSpecCoef;
1439*e5436536SAndroid Build Coastguard Worker }
1440*e5436536SAndroid Build Coastguard Worker 
1441*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1442*e5436536SAndroid Build Coastguard Worker      description:   Decodes the Signbits of a priority codeword (PCW) and writes
1443*e5436536SAndroid Build Coastguard Worker out the resulting quantized spectral values into unsorted sections
1444*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1445*e5436536SAndroid Build Coastguard Worker         output:   - two or four lines at position in corresponding section
1446*e5436536SAndroid Build Coastguard Worker (which are not located at the desired position, i.e. they must be reordered in
1447*e5436536SAndroid Build Coastguard Worker the last of eight function of HCR)
1448*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1449*e5436536SAndroid Build Coastguard Worker         return:   - updated pQuantSpecCoef pointer (to next empty storage for a
1450*e5436536SAndroid Build Coastguard Worker line)
1451*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1452*e5436536SAndroid Build Coastguard Worker */
DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs,const INT bsAnchor,UINT codebookDim,const SCHAR * pQuantVal,FIXP_DBL * pQuantSpecCoef,int * quantSpecCoefIdx,INT * pLeftStartOfSegment,SCHAR * pRemainingBitsInSegment,int * pNumDecodedBits)1453*e5436536SAndroid Build Coastguard Worker static int DecodePCW_Sign(HANDLE_FDK_BITSTREAM bs, const INT bsAnchor,
1454*e5436536SAndroid Build Coastguard Worker                           UINT codebookDim, const SCHAR *pQuantVal,
1455*e5436536SAndroid Build Coastguard Worker                           FIXP_DBL *pQuantSpecCoef, int *quantSpecCoefIdx,
1456*e5436536SAndroid Build Coastguard Worker                           INT *pLeftStartOfSegment,
1457*e5436536SAndroid Build Coastguard Worker                           SCHAR *pRemainingBitsInSegment,
1458*e5436536SAndroid Build Coastguard Worker                           int *pNumDecodedBits) {
1459*e5436536SAndroid Build Coastguard Worker   UINT i;
1460*e5436536SAndroid Build Coastguard Worker   UINT carryBit;
1461*e5436536SAndroid Build Coastguard Worker   INT quantSpecCoef;
1462*e5436536SAndroid Build Coastguard Worker 
1463*e5436536SAndroid Build Coastguard Worker   for (i = codebookDim; i != 0; i--) {
1464*e5436536SAndroid Build Coastguard Worker     quantSpecCoef = *pQuantVal++;
1465*e5436536SAndroid Build Coastguard Worker     if (quantSpecCoef != 0) {
1466*e5436536SAndroid Build Coastguard Worker       carryBit = HcrGetABitFromBitstream(bs, bsAnchor, pLeftStartOfSegment,
1467*e5436536SAndroid Build Coastguard Worker                                          pLeftStartOfSegment, /* dummy */
1468*e5436536SAndroid Build Coastguard Worker                                          FROM_LEFT_TO_RIGHT);
1469*e5436536SAndroid Build Coastguard Worker       *pRemainingBitsInSegment -= 1;
1470*e5436536SAndroid Build Coastguard Worker       *pNumDecodedBits += 1;
1471*e5436536SAndroid Build Coastguard Worker       if (*pRemainingBitsInSegment < 0 || *pNumDecodedBits >= (1024 >> 1)) {
1472*e5436536SAndroid Build Coastguard Worker         return -1;
1473*e5436536SAndroid Build Coastguard Worker       }
1474*e5436536SAndroid Build Coastguard Worker 
1475*e5436536SAndroid Build Coastguard Worker       /* adapt sign of values according to the decoded sign bit */
1476*e5436536SAndroid Build Coastguard Worker       if (carryBit != 0) {
1477*e5436536SAndroid Build Coastguard Worker         pQuantSpecCoef[*quantSpecCoefIdx] = -(FIXP_DBL)quantSpecCoef;
1478*e5436536SAndroid Build Coastguard Worker       } else {
1479*e5436536SAndroid Build Coastguard Worker         pQuantSpecCoef[*quantSpecCoefIdx] = (FIXP_DBL)quantSpecCoef;
1480*e5436536SAndroid Build Coastguard Worker       }
1481*e5436536SAndroid Build Coastguard Worker     } else {
1482*e5436536SAndroid Build Coastguard Worker       pQuantSpecCoef[*quantSpecCoefIdx] = FL2FXCONST_DBL(0.0f);
1483*e5436536SAndroid Build Coastguard Worker     }
1484*e5436536SAndroid Build Coastguard Worker     *quantSpecCoefIdx += 1;
1485*e5436536SAndroid Build Coastguard Worker     if (*quantSpecCoefIdx >= 1024) {
1486*e5436536SAndroid Build Coastguard Worker       return -1;
1487*e5436536SAndroid Build Coastguard Worker     }
1488*e5436536SAndroid Build Coastguard Worker   }
1489*e5436536SAndroid Build Coastguard Worker   return 0;
1490*e5436536SAndroid Build Coastguard Worker }
1491*e5436536SAndroid Build Coastguard Worker 
1492*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1493*e5436536SAndroid Build Coastguard Worker      description:   Mutes spectral lines which have been marked as erroneous
1494*e5436536SAndroid Build Coastguard Worker (Q_VALUE_INVALID)
1495*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1496*e5436536SAndroid Build Coastguard Worker */
HcrMuteErroneousLines(H_HCR_INFO hHcr)1497*e5436536SAndroid Build Coastguard Worker void HcrMuteErroneousLines(H_HCR_INFO hHcr) {
1498*e5436536SAndroid Build Coastguard Worker   int c;
1499*e5436536SAndroid Build Coastguard Worker   FIXP_DBL *RESTRICT pLong =
1500*e5436536SAndroid Build Coastguard Worker       SPEC_LONG(hHcr->decInOut.pQuantizedSpectralCoefficientsBase);
1501*e5436536SAndroid Build Coastguard Worker 
1502*e5436536SAndroid Build Coastguard Worker   /* if there is a line with value Q_VALUE_INVALID mute it */
1503*e5436536SAndroid Build Coastguard Worker   for (c = 0; c < 1024; c++) {
1504*e5436536SAndroid Build Coastguard Worker     if (pLong[c] == (FIXP_DBL)Q_VALUE_INVALID) {
1505*e5436536SAndroid Build Coastguard Worker       pLong[c] = FL2FXCONST_DBL(0.0f); /* muting */
1506*e5436536SAndroid Build Coastguard Worker     }
1507*e5436536SAndroid Build Coastguard Worker   }
1508*e5436536SAndroid Build Coastguard Worker }
1509