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 - 2020 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: Prepare decoding of non-PCWs, segmentation- and
100*e5436536SAndroid Build Coastguard Worker bitfield-handling, HCR-Statemachine
101*e5436536SAndroid Build Coastguard Worker
102*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
103*e5436536SAndroid Build Coastguard Worker
104*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcrs.h"
105*e5436536SAndroid Build Coastguard Worker
106*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr.h"
107*e5436536SAndroid Build Coastguard Worker
108*e5436536SAndroid Build Coastguard Worker #include "aacdec_hcr_bit.h"
109*e5436536SAndroid Build Coastguard Worker #include "aac_rom.h"
110*e5436536SAndroid Build Coastguard Worker #include "aac_ram.h"
111*e5436536SAndroid Build Coastguard Worker
112*e5436536SAndroid Build Coastguard Worker static UINT InitSegmentBitfield(UINT *pNumSegment,
113*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
114*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield,
115*e5436536SAndroid Build Coastguard Worker UCHAR *pNumWordForBitfield,
116*e5436536SAndroid Build Coastguard Worker USHORT *pNumBitValidInLastWord);
117*e5436536SAndroid Build Coastguard Worker
118*e5436536SAndroid Build Coastguard Worker static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr);
119*e5436536SAndroid Build Coastguard Worker
120*e5436536SAndroid Build Coastguard Worker static INT ModuloValue(INT input, INT bufferlength);
121*e5436536SAndroid Build Coastguard Worker
122*e5436536SAndroid Build Coastguard Worker static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
123*e5436536SAndroid Build Coastguard Worker UINT *pBitfield);
124*e5436536SAndroid Build Coastguard Worker
125*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
126*e5436536SAndroid Build Coastguard Worker description: This function decodes all non-priority codewords (non-PCWs) by
127*e5436536SAndroid Build Coastguard Worker using a state-machine.
128*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
129*e5436536SAndroid Build Coastguard Worker */
DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs,H_HCR_INFO pHcr)130*e5436536SAndroid Build Coastguard Worker void DecodeNonPCWs(HANDLE_FDK_BITSTREAM bs, H_HCR_INFO pHcr) {
131*e5436536SAndroid Build Coastguard Worker UINT numValidSegment;
132*e5436536SAndroid Build Coastguard Worker INT segmentOffset;
133*e5436536SAndroid Build Coastguard Worker INT codewordOffsetBase;
134*e5436536SAndroid Build Coastguard Worker INT codewordOffset;
135*e5436536SAndroid Build Coastguard Worker UINT trial;
136*e5436536SAndroid Build Coastguard Worker
137*e5436536SAndroid Build Coastguard Worker UINT *pNumSegment;
138*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
139*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
140*e5436536SAndroid Build Coastguard Worker UCHAR *pNumWordForBitfield;
141*e5436536SAndroid Build Coastguard Worker USHORT *pNumBitValidInLastWord;
142*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
143*e5436536SAndroid Build Coastguard Worker INT bitfieldWord;
144*e5436536SAndroid Build Coastguard Worker INT bitInWord;
145*e5436536SAndroid Build Coastguard Worker UINT tempWord;
146*e5436536SAndroid Build Coastguard Worker UINT interMediateWord;
147*e5436536SAndroid Build Coastguard Worker INT tempBit;
148*e5436536SAndroid Build Coastguard Worker INT carry;
149*e5436536SAndroid Build Coastguard Worker
150*e5436536SAndroid Build Coastguard Worker UINT numCodeword;
151*e5436536SAndroid Build Coastguard Worker UCHAR numSet;
152*e5436536SAndroid Build Coastguard Worker UCHAR currentSet;
153*e5436536SAndroid Build Coastguard Worker UINT codewordInSet;
154*e5436536SAndroid Build Coastguard Worker UINT remainingCodewordsInSet;
155*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
156*e5436536SAndroid Build Coastguard Worker UINT ret;
157*e5436536SAndroid Build Coastguard Worker
158*e5436536SAndroid Build Coastguard Worker pNumSegment = &(pHcr->segmentInfo.numSegment);
159*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
160*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
161*e5436536SAndroid Build Coastguard Worker pNumWordForBitfield = &(pHcr->segmentInfo.numWordForBitfield);
162*e5436536SAndroid Build Coastguard Worker pNumBitValidInLastWord = &(pHcr->segmentInfo.pNumBitValidInLastWord);
163*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
164*e5436536SAndroid Build Coastguard Worker
165*e5436536SAndroid Build Coastguard Worker numValidSegment = InitSegmentBitfield(pNumSegment, pRemainingBitsInSegment,
166*e5436536SAndroid Build Coastguard Worker pSegmentBitfield, pNumWordForBitfield,
167*e5436536SAndroid Build Coastguard Worker pNumBitValidInLastWord);
168*e5436536SAndroid Build Coastguard Worker
169*e5436536SAndroid Build Coastguard Worker if (numValidSegment != 0) {
170*e5436536SAndroid Build Coastguard Worker numCodeword = pHcr->sectionInfo.numCodeword;
171*e5436536SAndroid Build Coastguard Worker numSet = ((numCodeword - 1) / *pNumSegment) + 1;
172*e5436536SAndroid Build Coastguard Worker
173*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.readDirection = FROM_RIGHT_TO_LEFT;
174*e5436536SAndroid Build Coastguard Worker
175*e5436536SAndroid Build Coastguard Worker /* Process sets subsequently */
176*e5436536SAndroid Build Coastguard Worker numSet = fMin(numSet, (UCHAR)MAX_HCR_SETS);
177*e5436536SAndroid Build Coastguard Worker for (currentSet = 1; currentSet < numSet; currentSet++) {
178*e5436536SAndroid Build Coastguard Worker
179*e5436536SAndroid Build Coastguard Worker /* step 1 */
180*e5436536SAndroid Build Coastguard Worker numCodeword -=
181*e5436536SAndroid Build Coastguard Worker *pNumSegment; /* number of remaining non PCWs [for all sets] */
182*e5436536SAndroid Build Coastguard Worker if (numCodeword < *pNumSegment) {
183*e5436536SAndroid Build Coastguard Worker codewordInSet = numCodeword; /* for last set */
184*e5436536SAndroid Build Coastguard Worker } else {
185*e5436536SAndroid Build Coastguard Worker codewordInSet = *pNumSegment; /* for all sets except last set */
186*e5436536SAndroid Build Coastguard Worker }
187*e5436536SAndroid Build Coastguard Worker
188*e5436536SAndroid Build Coastguard Worker /* step 2 */
189*e5436536SAndroid Build Coastguard Worker /* prepare array 'CodewordBitfield'; as much ones are written from left in
190*e5436536SAndroid Build Coastguard Worker * all words, as much decodedCodewordInSetCounter nonPCWs exist in this
191*e5436536SAndroid Build Coastguard Worker * set */
192*e5436536SAndroid Build Coastguard Worker tempWord = 0xFFFFFFFF;
193*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
194*e5436536SAndroid Build Coastguard Worker
195*e5436536SAndroid Build Coastguard Worker for (bitfieldWord = *pNumWordForBitfield; bitfieldWord != 0;
196*e5436536SAndroid Build Coastguard Worker bitfieldWord--) { /* loop over all used words */
197*e5436536SAndroid Build Coastguard Worker if (codewordInSet > NUMBER_OF_BIT_IN_WORD) { /* more codewords than
198*e5436536SAndroid Build Coastguard Worker number of bits => fill
199*e5436536SAndroid Build Coastguard Worker ones */
200*e5436536SAndroid Build Coastguard Worker /* fill a whole word with ones */
201*e5436536SAndroid Build Coastguard Worker *pCodewordBitfield++ = tempWord;
202*e5436536SAndroid Build Coastguard Worker codewordInSet -= NUMBER_OF_BIT_IN_WORD; /* subtract number of bits */
203*e5436536SAndroid Build Coastguard Worker } else {
204*e5436536SAndroid Build Coastguard Worker /* prepare last tempWord */
205*e5436536SAndroid Build Coastguard Worker for (remainingCodewordsInSet = codewordInSet;
206*e5436536SAndroid Build Coastguard Worker remainingCodewordsInSet < NUMBER_OF_BIT_IN_WORD;
207*e5436536SAndroid Build Coastguard Worker remainingCodewordsInSet++) {
208*e5436536SAndroid Build Coastguard Worker tempWord =
209*e5436536SAndroid Build Coastguard Worker tempWord &
210*e5436536SAndroid Build Coastguard Worker ~(1
211*e5436536SAndroid Build Coastguard Worker << (NUMBER_OF_BIT_IN_WORD - 1 -
212*e5436536SAndroid Build Coastguard Worker remainingCodewordsInSet)); /* set a zero at bit number
213*e5436536SAndroid Build Coastguard Worker (NUMBER_OF_BIT_IN_WORD-1-i)
214*e5436536SAndroid Build Coastguard Worker in tempWord */
215*e5436536SAndroid Build Coastguard Worker }
216*e5436536SAndroid Build Coastguard Worker *pCodewordBitfield++ = tempWord;
217*e5436536SAndroid Build Coastguard Worker tempWord = 0x00000000;
218*e5436536SAndroid Build Coastguard Worker }
219*e5436536SAndroid Build Coastguard Worker }
220*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
221*e5436536SAndroid Build Coastguard Worker
222*e5436536SAndroid Build Coastguard Worker /* step 3 */
223*e5436536SAndroid Build Coastguard Worker /* build non-PCW sideinfo for each non-PCW of the current set */
224*e5436536SAndroid Build Coastguard Worker InitNonPCWSideInformationForCurrentSet(pHcr);
225*e5436536SAndroid Build Coastguard Worker
226*e5436536SAndroid Build Coastguard Worker /* step 4 */
227*e5436536SAndroid Build Coastguard Worker /* decode all non-PCWs belonging to this set */
228*e5436536SAndroid Build Coastguard Worker
229*e5436536SAndroid Build Coastguard Worker /* loop over trials */
230*e5436536SAndroid Build Coastguard Worker codewordOffsetBase = 0;
231*e5436536SAndroid Build Coastguard Worker for (trial = *pNumSegment; trial > 0; trial--) {
232*e5436536SAndroid Build Coastguard Worker /* loop over number of words in bitfields */
233*e5436536SAndroid Build Coastguard Worker segmentOffset = 0; /* start at zero in every segment */
234*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.segmentOffset =
235*e5436536SAndroid Build Coastguard Worker segmentOffset; /* store in structure for states */
236*e5436536SAndroid Build Coastguard Worker codewordOffset = codewordOffsetBase;
237*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.codewordOffset =
238*e5436536SAndroid Build Coastguard Worker codewordOffset; /* store in structure for states */
239*e5436536SAndroid Build Coastguard Worker
240*e5436536SAndroid Build Coastguard Worker for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield;
241*e5436536SAndroid Build Coastguard Worker bitfieldWord++) {
242*e5436536SAndroid Build Coastguard Worker /* derive tempWord with bitwise and */
243*e5436536SAndroid Build Coastguard Worker tempWord =
244*e5436536SAndroid Build Coastguard Worker pSegmentBitfield[bitfieldWord] & pCodewordBitfield[bitfieldWord];
245*e5436536SAndroid Build Coastguard Worker
246*e5436536SAndroid Build Coastguard Worker /* if tempWord is not zero, decode something */
247*e5436536SAndroid Build Coastguard Worker if (tempWord != 0) {
248*e5436536SAndroid Build Coastguard Worker /* loop over all bits in tempWord; start state machine if & is true
249*e5436536SAndroid Build Coastguard Worker */
250*e5436536SAndroid Build Coastguard Worker for (bitInWord = NUMBER_OF_BIT_IN_WORD; bitInWord > 0;
251*e5436536SAndroid Build Coastguard Worker bitInWord--) {
252*e5436536SAndroid Build Coastguard Worker interMediateWord = ((UINT)1 << (bitInWord - 1));
253*e5436536SAndroid Build Coastguard Worker if ((tempWord & interMediateWord) == interMediateWord) {
254*e5436536SAndroid Build Coastguard Worker /* get state and start state machine */
255*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
256*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]];
257*e5436536SAndroid Build Coastguard Worker
258*e5436536SAndroid Build Coastguard Worker while (pHcr->nonPcwSideinfo.pState) {
259*e5436536SAndroid Build Coastguard Worker ret = ((STATEFUNC)pHcr->nonPcwSideinfo.pState)(bs, pHcr);
260*e5436536SAndroid Build Coastguard Worker if (ret != 0) {
261*e5436536SAndroid Build Coastguard Worker return;
262*e5436536SAndroid Build Coastguard Worker }
263*e5436536SAndroid Build Coastguard Worker }
264*e5436536SAndroid Build Coastguard Worker }
265*e5436536SAndroid Build Coastguard Worker
266*e5436536SAndroid Build Coastguard Worker /* update both offsets */
267*e5436536SAndroid Build Coastguard Worker segmentOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
268*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.segmentOffset = segmentOffset;
269*e5436536SAndroid Build Coastguard Worker codewordOffset += 1; /* add NUMBER_OF_BIT_IN_WORD times one */
270*e5436536SAndroid Build Coastguard Worker codewordOffset =
271*e5436536SAndroid Build Coastguard Worker ModuloValue(codewordOffset,
272*e5436536SAndroid Build Coastguard Worker *pNumSegment); /* index of the current codeword
273*e5436536SAndroid Build Coastguard Worker lies within modulo range */
274*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
275*e5436536SAndroid Build Coastguard Worker }
276*e5436536SAndroid Build Coastguard Worker } else {
277*e5436536SAndroid Build Coastguard Worker segmentOffset +=
278*e5436536SAndroid Build Coastguard Worker NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
279*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.segmentOffset = segmentOffset;
280*e5436536SAndroid Build Coastguard Worker codewordOffset +=
281*e5436536SAndroid Build Coastguard Worker NUMBER_OF_BIT_IN_WORD; /* add NUMBER_OF_BIT_IN_WORD at once */
282*e5436536SAndroid Build Coastguard Worker codewordOffset = ModuloValue(
283*e5436536SAndroid Build Coastguard Worker codewordOffset,
284*e5436536SAndroid Build Coastguard Worker *pNumSegment); /* index of the current codeword lies within
285*e5436536SAndroid Build Coastguard Worker modulo range */
286*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.codewordOffset = codewordOffset;
287*e5436536SAndroid Build Coastguard Worker }
288*e5436536SAndroid Build Coastguard Worker } /* end of bitfield word loop */
289*e5436536SAndroid Build Coastguard Worker
290*e5436536SAndroid Build Coastguard Worker /* decrement codeword - pointer */
291*e5436536SAndroid Build Coastguard Worker codewordOffsetBase -= 1;
292*e5436536SAndroid Build Coastguard Worker codewordOffsetBase =
293*e5436536SAndroid Build Coastguard Worker ModuloValue(codewordOffsetBase, *pNumSegment); /* index of the
294*e5436536SAndroid Build Coastguard Worker current codeword
295*e5436536SAndroid Build Coastguard Worker base lies within
296*e5436536SAndroid Build Coastguard Worker modulo range */
297*e5436536SAndroid Build Coastguard Worker
298*e5436536SAndroid Build Coastguard Worker /* rotate numSegment bits in codewordBitfield */
299*e5436536SAndroid Build Coastguard Worker /* rotation of *numSegment bits in bitfield of codewords
300*e5436536SAndroid Build Coastguard Worker * (circle-rotation) */
301*e5436536SAndroid Build Coastguard Worker /* get last valid bit */
302*e5436536SAndroid Build Coastguard Worker tempBit = pCodewordBitfield[*pNumWordForBitfield - 1] &
303*e5436536SAndroid Build Coastguard Worker (1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
304*e5436536SAndroid Build Coastguard Worker tempBit = tempBit >> (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord);
305*e5436536SAndroid Build Coastguard Worker
306*e5436536SAndroid Build Coastguard Worker /* write zero into place where tempBit was fetched from */
307*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[*pNumWordForBitfield - 1] =
308*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[*pNumWordForBitfield - 1] &
309*e5436536SAndroid Build Coastguard Worker ~(1 << (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord));
310*e5436536SAndroid Build Coastguard Worker
311*e5436536SAndroid Build Coastguard Worker /* rotate last valid word */
312*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[*pNumWordForBitfield - 1] =
313*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[*pNumWordForBitfield - 1] >> 1;
314*e5436536SAndroid Build Coastguard Worker
315*e5436536SAndroid Build Coastguard Worker /* transfare carry bit 0 from current word into bitposition 31 from next
316*e5436536SAndroid Build Coastguard Worker * word and rotate current word */
317*e5436536SAndroid Build Coastguard Worker for (bitfieldWord = *pNumWordForBitfield - 2; bitfieldWord > -1;
318*e5436536SAndroid Build Coastguard Worker bitfieldWord--) {
319*e5436536SAndroid Build Coastguard Worker /* get carry (=bit at position 0) from current word */
320*e5436536SAndroid Build Coastguard Worker carry = pCodewordBitfield[bitfieldWord] & 1;
321*e5436536SAndroid Build Coastguard Worker
322*e5436536SAndroid Build Coastguard Worker /* put the carry bit at position 31 into word right from current word
323*e5436536SAndroid Build Coastguard Worker */
324*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[bitfieldWord + 1] =
325*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[bitfieldWord + 1] |
326*e5436536SAndroid Build Coastguard Worker (carry << (NUMBER_OF_BIT_IN_WORD - 1));
327*e5436536SAndroid Build Coastguard Worker
328*e5436536SAndroid Build Coastguard Worker /* shift current word */
329*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[bitfieldWord] =
330*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[bitfieldWord] >> 1;
331*e5436536SAndroid Build Coastguard Worker }
332*e5436536SAndroid Build Coastguard Worker
333*e5436536SAndroid Build Coastguard Worker /* put tempBit into free bit-position 31 from first word */
334*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[0] =
335*e5436536SAndroid Build Coastguard Worker pCodewordBitfield[0] | (tempBit << (NUMBER_OF_BIT_IN_WORD - 1));
336*e5436536SAndroid Build Coastguard Worker
337*e5436536SAndroid Build Coastguard Worker } /* end of trial loop */
338*e5436536SAndroid Build Coastguard Worker
339*e5436536SAndroid Build Coastguard Worker /* toggle read direction */
340*e5436536SAndroid Build Coastguard Worker pHcr->segmentInfo.readDirection =
341*e5436536SAndroid Build Coastguard Worker ToggleReadDirection(pHcr->segmentInfo.readDirection);
342*e5436536SAndroid Build Coastguard Worker }
343*e5436536SAndroid Build Coastguard Worker /* end of set loop */
344*e5436536SAndroid Build Coastguard Worker
345*e5436536SAndroid Build Coastguard Worker /* all non-PCWs of this spectrum are decoded */
346*e5436536SAndroid Build Coastguard Worker }
347*e5436536SAndroid Build Coastguard Worker
348*e5436536SAndroid Build Coastguard Worker /* all PCWs and all non PCWs are decoded. They are unbacksorted in output
349*e5436536SAndroid Build Coastguard Worker * buffer. Here is the Interface with comparing QSCs to asm decoding */
350*e5436536SAndroid Build Coastguard Worker }
351*e5436536SAndroid Build Coastguard Worker
352*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
353*e5436536SAndroid Build Coastguard Worker description: This function prepares the bitfield used for the
354*e5436536SAndroid Build Coastguard Worker segments. The list is set up once to be used in all
355*e5436536SAndroid Build Coastguard Worker following sets. If a segment is decoded empty, the according bit from the
356*e5436536SAndroid Build Coastguard Worker Bitfield is removed.
357*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
358*e5436536SAndroid Build Coastguard Worker return: numValidSegment = the number of valid segments
359*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
360*e5436536SAndroid Build Coastguard Worker */
InitSegmentBitfield(UINT * pNumSegment,SCHAR * pRemainingBitsInSegment,UINT * pSegmentBitfield,UCHAR * pNumWordForBitfield,USHORT * pNumBitValidInLastWord)361*e5436536SAndroid Build Coastguard Worker static UINT InitSegmentBitfield(UINT *pNumSegment,
362*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment,
363*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield,
364*e5436536SAndroid Build Coastguard Worker UCHAR *pNumWordForBitfield,
365*e5436536SAndroid Build Coastguard Worker USHORT *pNumBitValidInLastWord) {
366*e5436536SAndroid Build Coastguard Worker SHORT i;
367*e5436536SAndroid Build Coastguard Worker USHORT r;
368*e5436536SAndroid Build Coastguard Worker UCHAR bitfieldWord;
369*e5436536SAndroid Build Coastguard Worker UINT tempWord;
370*e5436536SAndroid Build Coastguard Worker USHORT numValidSegment;
371*e5436536SAndroid Build Coastguard Worker
372*e5436536SAndroid Build Coastguard Worker *pNumWordForBitfield =
373*e5436536SAndroid Build Coastguard Worker (*pNumSegment == 0)
374*e5436536SAndroid Build Coastguard Worker ? 0
375*e5436536SAndroid Build Coastguard Worker : ((*pNumSegment - 1) >> THIRTYTWO_LOG_DIV_TWO_LOG) + 1;
376*e5436536SAndroid Build Coastguard Worker
377*e5436536SAndroid Build Coastguard Worker /* loop over all words, which are completely used or only partial */
378*e5436536SAndroid Build Coastguard Worker /* bit in pSegmentBitfield is zero if segment is empty; bit in
379*e5436536SAndroid Build Coastguard Worker * pSegmentBitfield is one if segment is not empty */
380*e5436536SAndroid Build Coastguard Worker numValidSegment = 0;
381*e5436536SAndroid Build Coastguard Worker *pNumBitValidInLastWord = *pNumSegment;
382*e5436536SAndroid Build Coastguard Worker
383*e5436536SAndroid Build Coastguard Worker /* loop over words */
384*e5436536SAndroid Build Coastguard Worker for (bitfieldWord = 0; bitfieldWord < *pNumWordForBitfield - 1;
385*e5436536SAndroid Build Coastguard Worker bitfieldWord++) {
386*e5436536SAndroid Build Coastguard Worker tempWord = 0xFFFFFFFF; /* set ones */
387*e5436536SAndroid Build Coastguard Worker r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
388*e5436536SAndroid Build Coastguard Worker for (i = 0; i < NUMBER_OF_BIT_IN_WORD; i++) {
389*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[r + i] == 0) {
390*e5436536SAndroid Build Coastguard Worker tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
391*e5436536SAndroid Build Coastguard Worker i)); /* set a zero at bit number
392*e5436536SAndroid Build Coastguard Worker (NUMBER_OF_BIT_IN_WORD-1-i) in
393*e5436536SAndroid Build Coastguard Worker tempWord */
394*e5436536SAndroid Build Coastguard Worker } else {
395*e5436536SAndroid Build Coastguard Worker numValidSegment += 1; /* count segments which are not empty */
396*e5436536SAndroid Build Coastguard Worker }
397*e5436536SAndroid Build Coastguard Worker }
398*e5436536SAndroid Build Coastguard Worker pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
399*e5436536SAndroid Build Coastguard Worker *pNumBitValidInLastWord -= NUMBER_OF_BIT_IN_WORD; /* calculate number of
400*e5436536SAndroid Build Coastguard Worker zeros on LSB side in
401*e5436536SAndroid Build Coastguard Worker the last word */
402*e5436536SAndroid Build Coastguard Worker }
403*e5436536SAndroid Build Coastguard Worker
404*e5436536SAndroid Build Coastguard Worker /* calculate last word: prepare special tempWord */
405*e5436536SAndroid Build Coastguard Worker tempWord = 0xFFFFFFFF;
406*e5436536SAndroid Build Coastguard Worker for (i = 0; i < (NUMBER_OF_BIT_IN_WORD - *pNumBitValidInLastWord); i++) {
407*e5436536SAndroid Build Coastguard Worker tempWord = tempWord & ~(1 << i); /* clear bit i in tempWord */
408*e5436536SAndroid Build Coastguard Worker }
409*e5436536SAndroid Build Coastguard Worker
410*e5436536SAndroid Build Coastguard Worker /* calculate last word */
411*e5436536SAndroid Build Coastguard Worker r = bitfieldWord << THIRTYTWO_LOG_DIV_TWO_LOG;
412*e5436536SAndroid Build Coastguard Worker for (i = 0; i < *pNumBitValidInLastWord; i++) {
413*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[r + i] == 0) {
414*e5436536SAndroid Build Coastguard Worker tempWord = tempWord & ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 -
415*e5436536SAndroid Build Coastguard Worker i)); /* set a zero at bit number
416*e5436536SAndroid Build Coastguard Worker (NUMBER_OF_BIT_IN_WORD-1-i) in
417*e5436536SAndroid Build Coastguard Worker tempWord */
418*e5436536SAndroid Build Coastguard Worker } else {
419*e5436536SAndroid Build Coastguard Worker numValidSegment += 1; /* count segments which are not empty */
420*e5436536SAndroid Build Coastguard Worker }
421*e5436536SAndroid Build Coastguard Worker }
422*e5436536SAndroid Build Coastguard Worker pSegmentBitfield[bitfieldWord] = tempWord; /* store result */
423*e5436536SAndroid Build Coastguard Worker
424*e5436536SAndroid Build Coastguard Worker return numValidSegment;
425*e5436536SAndroid Build Coastguard Worker }
426*e5436536SAndroid Build Coastguard Worker
427*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
428*e5436536SAndroid Build Coastguard Worker description: This function sets up sideinfo for the non-PCW decoder (for the
429*e5436536SAndroid Build Coastguard Worker current set).
430*e5436536SAndroid Build Coastguard Worker ---------------------------------------------------------------------------------------------*/
InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr)431*e5436536SAndroid Build Coastguard Worker static void InitNonPCWSideInformationForCurrentSet(H_HCR_INFO pHcr) {
432*e5436536SAndroid Build Coastguard Worker USHORT i, k;
433*e5436536SAndroid Build Coastguard Worker UCHAR codebookDim;
434*e5436536SAndroid Build Coastguard Worker UINT startNode;
435*e5436536SAndroid Build Coastguard Worker
436*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebook = pHcr->nonPcwSideinfo.pCodebook;
437*e5436536SAndroid Build Coastguard Worker UINT *iNode = pHcr->nonPcwSideinfo.iNode;
438*e5436536SAndroid Build Coastguard Worker UCHAR *pCntSign = pHcr->nonPcwSideinfo.pCntSign;
439*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
440*e5436536SAndroid Build Coastguard Worker UINT *pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
441*e5436536SAndroid Build Coastguard Worker SCHAR *pSta = pHcr->nonPcwSideinfo.pSta;
442*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedCodewordInSection =
443*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedCodewordInSection;
444*e5436536SAndroid Build Coastguard Worker int numExtendedSortedCodewordInSectionIdx =
445*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx;
446*e5436536SAndroid Build Coastguard Worker UCHAR *pExtendedSortedCodebook = pHcr->sectionInfo.pExtendedSortedCodebook;
447*e5436536SAndroid Build Coastguard Worker int extendedSortedCodebookIdx = pHcr->sectionInfo.extendedSortedCodebookIdx;
448*e5436536SAndroid Build Coastguard Worker USHORT *pNumExtendedSortedSectionsInSets =
449*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.pNumExtendedSortedSectionsInSets;
450*e5436536SAndroid Build Coastguard Worker int numExtendedSortedSectionsInSetsIdx =
451*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx;
452*e5436536SAndroid Build Coastguard Worker int quantizedSpectralCoefficientsIdx =
453*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx;
454*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimension = aDimCb;
455*e5436536SAndroid Build Coastguard Worker int iterationCounter = 0;
456*e5436536SAndroid Build Coastguard Worker
457*e5436536SAndroid Build Coastguard Worker /* loop over number of extended sorted sections in the current set so all
458*e5436536SAndroid Build Coastguard Worker * codewords sideinfo variables within this set can be prepared for decoding
459*e5436536SAndroid Build Coastguard Worker */
460*e5436536SAndroid Build Coastguard Worker for (i = pNumExtendedSortedSectionsInSets[numExtendedSortedSectionsInSetsIdx];
461*e5436536SAndroid Build Coastguard Worker i != 0; i--) {
462*e5436536SAndroid Build Coastguard Worker codebookDim =
463*e5436536SAndroid Build Coastguard Worker pCbDimension[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
464*e5436536SAndroid Build Coastguard Worker startNode = *aHuffTable[pExtendedSortedCodebook[extendedSortedCodebookIdx]];
465*e5436536SAndroid Build Coastguard Worker
466*e5436536SAndroid Build Coastguard Worker for (k = pNumExtendedSortedCodewordInSection
467*e5436536SAndroid Build Coastguard Worker [numExtendedSortedCodewordInSectionIdx];
468*e5436536SAndroid Build Coastguard Worker k != 0; k--) {
469*e5436536SAndroid Build Coastguard Worker iterationCounter++;
470*e5436536SAndroid Build Coastguard Worker if (iterationCounter > (1024 >> 2)) {
471*e5436536SAndroid Build Coastguard Worker return;
472*e5436536SAndroid Build Coastguard Worker }
473*e5436536SAndroid Build Coastguard Worker *pSta++ = aCodebook2StartInt
474*e5436536SAndroid Build Coastguard Worker [pExtendedSortedCodebook[extendedSortedCodebookIdx]];
475*e5436536SAndroid Build Coastguard Worker *pCodebook++ = pExtendedSortedCodebook[extendedSortedCodebookIdx];
476*e5436536SAndroid Build Coastguard Worker *iNode++ = startNode;
477*e5436536SAndroid Build Coastguard Worker *pCntSign++ = 0;
478*e5436536SAndroid Build Coastguard Worker *iResultPointer++ = quantizedSpectralCoefficientsIdx;
479*e5436536SAndroid Build Coastguard Worker *pEscapeSequenceInfo++ = 0;
480*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx +=
481*e5436536SAndroid Build Coastguard Worker codebookDim; /* update pointer by codebookDim --> point to next
482*e5436536SAndroid Build Coastguard Worker starting value for writing out */
483*e5436536SAndroid Build Coastguard Worker if (quantizedSpectralCoefficientsIdx >= 1024) {
484*e5436536SAndroid Build Coastguard Worker return;
485*e5436536SAndroid Build Coastguard Worker }
486*e5436536SAndroid Build Coastguard Worker }
487*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx++; /* inc ptr for next ext sort sec in
488*e5436536SAndroid Build Coastguard Worker current set */
489*e5436536SAndroid Build Coastguard Worker extendedSortedCodebookIdx++; /* inc ptr for next ext sort sec in current set
490*e5436536SAndroid Build Coastguard Worker */
491*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS) ||
492*e5436536SAndroid Build Coastguard Worker extendedSortedCodebookIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
493*e5436536SAndroid Build Coastguard Worker return;
494*e5436536SAndroid Build Coastguard Worker }
495*e5436536SAndroid Build Coastguard Worker }
496*e5436536SAndroid Build Coastguard Worker numExtendedSortedSectionsInSetsIdx++; /* inc ptr for next set of non-PCWs */
497*e5436536SAndroid Build Coastguard Worker if (numExtendedSortedCodewordInSectionIdx >= (MAX_SFB_HCR + MAX_HCR_SETS)) {
498*e5436536SAndroid Build Coastguard Worker return;
499*e5436536SAndroid Build Coastguard Worker }
500*e5436536SAndroid Build Coastguard Worker
501*e5436536SAndroid Build Coastguard Worker /* Write back indexes */
502*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
503*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx;
504*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.extendedSortedCodebookIdx = extendedSortedCodebookIdx;
505*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedSectionsInSetsIdx =
506*e5436536SAndroid Build Coastguard Worker numExtendedSortedSectionsInSetsIdx;
507*e5436536SAndroid Build Coastguard Worker pHcr->sectionInfo.numExtendedSortedCodewordInSectionIdx =
508*e5436536SAndroid Build Coastguard Worker numExtendedSortedCodewordInSectionIdx;
509*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.quantizedSpectralCoefficientsIdx =
510*e5436536SAndroid Build Coastguard Worker quantizedSpectralCoefficientsIdx;
511*e5436536SAndroid Build Coastguard Worker }
512*e5436536SAndroid Build Coastguard Worker
513*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
514*e5436536SAndroid Build Coastguard Worker description: This function returns the input value if the value is in the
515*e5436536SAndroid Build Coastguard Worker range of bufferlength. If <input> is smaller, one bufferlength
516*e5436536SAndroid Build Coastguard Worker is added, if <input> is bigger one bufferlength is subtracted.
517*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
518*e5436536SAndroid Build Coastguard Worker return: modulo result
519*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
520*e5436536SAndroid Build Coastguard Worker */
ModuloValue(INT input,INT bufferlength)521*e5436536SAndroid Build Coastguard Worker static INT ModuloValue(INT input, INT bufferlength) {
522*e5436536SAndroid Build Coastguard Worker if (input > (bufferlength - 1)) {
523*e5436536SAndroid Build Coastguard Worker return (input - bufferlength);
524*e5436536SAndroid Build Coastguard Worker }
525*e5436536SAndroid Build Coastguard Worker if (input < 0) {
526*e5436536SAndroid Build Coastguard Worker return (input + bufferlength);
527*e5436536SAndroid Build Coastguard Worker }
528*e5436536SAndroid Build Coastguard Worker return input;
529*e5436536SAndroid Build Coastguard Worker }
530*e5436536SAndroid Build Coastguard Worker
531*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
532*e5436536SAndroid Build Coastguard Worker description: This function clears a bit from current bitfield and
533*e5436536SAndroid Build Coastguard Worker switches off the statemachine.
534*e5436536SAndroid Build Coastguard Worker
535*e5436536SAndroid Build Coastguard Worker A bit is cleared in two cases:
536*e5436536SAndroid Build Coastguard Worker a) a codeword is decoded, then a bit is cleared in codeword
537*e5436536SAndroid Build Coastguard Worker bitfield b) a segment is decoded empty, then a bit is cleared in segment
538*e5436536SAndroid Build Coastguard Worker bitfield
539*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
540*e5436536SAndroid Build Coastguard Worker */
ClearBitFromBitfield(STATEFUNC * ptrState,UINT offset,UINT * pBitfield)541*e5436536SAndroid Build Coastguard Worker static void ClearBitFromBitfield(STATEFUNC *ptrState, UINT offset,
542*e5436536SAndroid Build Coastguard Worker UINT *pBitfield) {
543*e5436536SAndroid Build Coastguard Worker UINT numBitfieldWord;
544*e5436536SAndroid Build Coastguard Worker UINT numBitfieldBit;
545*e5436536SAndroid Build Coastguard Worker
546*e5436536SAndroid Build Coastguard Worker /* get both values needed for clearing the bit */
547*e5436536SAndroid Build Coastguard Worker numBitfieldWord = offset >> THIRTYTWO_LOG_DIV_TWO_LOG; /* int = wordNr */
548*e5436536SAndroid Build Coastguard Worker numBitfieldBit = offset - (numBitfieldWord
549*e5436536SAndroid Build Coastguard Worker << THIRTYTWO_LOG_DIV_TWO_LOG); /* fract = bitNr */
550*e5436536SAndroid Build Coastguard Worker
551*e5436536SAndroid Build Coastguard Worker /* clear a bit in bitfield */
552*e5436536SAndroid Build Coastguard Worker pBitfield[numBitfieldWord] =
553*e5436536SAndroid Build Coastguard Worker pBitfield[numBitfieldWord] &
554*e5436536SAndroid Build Coastguard Worker ~(1 << (NUMBER_OF_BIT_IN_WORD - 1 - numBitfieldBit));
555*e5436536SAndroid Build Coastguard Worker
556*e5436536SAndroid Build Coastguard Worker /* switch off state machine because codeword is decoded and/or because segment
557*e5436536SAndroid Build Coastguard Worker * is empty */
558*e5436536SAndroid Build Coastguard Worker *ptrState = NULL;
559*e5436536SAndroid Build Coastguard Worker }
560*e5436536SAndroid Build Coastguard Worker
561*e5436536SAndroid Build Coastguard Worker /* =========================================================================================
562*e5436536SAndroid Build Coastguard Worker the states of the statemachine
563*e5436536SAndroid Build Coastguard Worker =========================================================================================
564*e5436536SAndroid Build Coastguard Worker */
565*e5436536SAndroid Build Coastguard Worker
566*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
567*e5436536SAndroid Build Coastguard Worker description: Decodes the body of a codeword. This State is used for
568*e5436536SAndroid Build Coastguard Worker codebooks 1,2,5 and 6. No sign bits are decoded, because the table of the
569*e5436536SAndroid Build Coastguard Worker quantized spectral values has got a valid sign at the quantized spectral lines.
570*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
571*e5436536SAndroid Build Coastguard Worker output: Two or four quantizes spectral values written at position
572*e5436536SAndroid Build Coastguard Worker where pResultPointr points to
573*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
574*e5436536SAndroid Build Coastguard Worker return: 0
575*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
576*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs,void * ptr)577*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_ONLY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
578*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
579*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
580*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
581*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
582*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
583*e5436536SAndroid Build Coastguard Worker UINT *iNode;
584*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
585*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
586*e5436536SAndroid Build Coastguard Worker UINT branchNode;
587*e5436536SAndroid Build Coastguard Worker UINT branchValue;
588*e5436536SAndroid Build Coastguard Worker UINT iQSC;
589*e5436536SAndroid Build Coastguard Worker UINT treeNode;
590*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
591*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
592*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
593*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
594*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
595*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebook;
596*e5436536SAndroid Build Coastguard Worker UCHAR dimCntr;
597*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree;
598*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimension;
599*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantVal;
600*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase;
601*e5436536SAndroid Build Coastguard Worker
602*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
603*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
604*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
605*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
606*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
607*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
608*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
609*e5436536SAndroid Build Coastguard Worker
610*e5436536SAndroid Build Coastguard Worker pCodebook = pHcr->nonPcwSideinfo.pCodebook;
611*e5436536SAndroid Build Coastguard Worker iNode = pHcr->nonPcwSideinfo.iNode;
612*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
613*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
614*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
615*e5436536SAndroid Build Coastguard Worker
616*e5436536SAndroid Build Coastguard Worker pCbDimension = aDimCb;
617*e5436536SAndroid Build Coastguard Worker
618*e5436536SAndroid Build Coastguard Worker treeNode = iNode[codewordOffset];
619*e5436536SAndroid Build Coastguard Worker pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
620*e5436536SAndroid Build Coastguard Worker
621*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
622*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
623*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
624*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
625*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
626*e5436536SAndroid Build Coastguard Worker
627*e5436536SAndroid Build Coastguard Worker CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
628*e5436536SAndroid Build Coastguard Worker treeNode, &branchValue, &branchNode);
629*e5436536SAndroid Build Coastguard Worker
630*e5436536SAndroid Build Coastguard Worker /* if end of branch reached write out lines and count bits needed for sign,
631*e5436536SAndroid Build Coastguard Worker * otherwise store node in codeword sideinfo */
632*e5436536SAndroid Build Coastguard Worker if ((branchNode & TEST_BIT_10) ==
633*e5436536SAndroid Build Coastguard Worker TEST_BIT_10) { /* test bit 10 ; ==> body is complete */
634*e5436536SAndroid Build Coastguard Worker pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
635*e5436536SAndroid Build Coastguard Worker address of
636*e5436536SAndroid Build Coastguard Worker quantized
637*e5436536SAndroid Build Coastguard Worker values
638*e5436536SAndroid Build Coastguard Worker belonging to
639*e5436536SAndroid Build Coastguard Worker current
640*e5436536SAndroid Build Coastguard Worker codebook */
641*e5436536SAndroid Build Coastguard Worker pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
642*e5436536SAndroid Build Coastguard Worker line [of 2 or 4 quantized
643*e5436536SAndroid Build Coastguard Worker values] */
644*e5436536SAndroid Build Coastguard Worker
645*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset]; /* get position of first line for
646*e5436536SAndroid Build Coastguard Worker writing out result */
647*e5436536SAndroid Build Coastguard Worker
648*e5436536SAndroid Build Coastguard Worker for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
649*e5436536SAndroid Build Coastguard Worker dimCntr--) {
650*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC++] =
651*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)*pQuantVal++; /* write out 2 or 4 lines into
652*e5436536SAndroid Build Coastguard Worker spectrum; no Sign bits
653*e5436536SAndroid Build Coastguard Worker available in this state */
654*e5436536SAndroid Build Coastguard Worker }
655*e5436536SAndroid Build Coastguard Worker
656*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
657*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and
658*e5436536SAndroid Build Coastguard Worker switch off statemachine */
659*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
660*e5436536SAndroid Build Coastguard Worker for loop counter (see
661*e5436536SAndroid Build Coastguard Worker above) is done here */
662*e5436536SAndroid Build Coastguard Worker break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
663*e5436536SAndroid Build Coastguard Worker decoded */
664*e5436536SAndroid Build Coastguard Worker } else { /* body is not decoded completely: */
665*e5436536SAndroid Build Coastguard Worker treeNode = *(
666*e5436536SAndroid Build Coastguard Worker pCurrentTree +
667*e5436536SAndroid Build Coastguard Worker branchValue); /* update treeNode for further step in decoding tree */
668*e5436536SAndroid Build Coastguard Worker }
669*e5436536SAndroid Build Coastguard Worker }
670*e5436536SAndroid Build Coastguard Worker iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
671*e5436536SAndroid Build Coastguard Worker decoding of codeword body not finished
672*e5436536SAndroid Build Coastguard Worker yet */
673*e5436536SAndroid Build Coastguard Worker
674*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
675*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
676*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
677*e5436536SAndroid Build Coastguard Worker switch off statemachine */
678*e5436536SAndroid Build Coastguard Worker
679*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
680*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_ONLY;
681*e5436536SAndroid Build Coastguard Worker return BODY_ONLY;
682*e5436536SAndroid Build Coastguard Worker }
683*e5436536SAndroid Build Coastguard Worker }
684*e5436536SAndroid Build Coastguard Worker
685*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
686*e5436536SAndroid Build Coastguard Worker }
687*e5436536SAndroid Build Coastguard Worker
688*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
689*e5436536SAndroid Build Coastguard Worker description: Decodes the codeword body, writes out result and counts the
690*e5436536SAndroid Build Coastguard Worker number of quantized spectral values, which are different form zero. For those
691*e5436536SAndroid Build Coastguard Worker values sign bits are needed.
692*e5436536SAndroid Build Coastguard Worker
693*e5436536SAndroid Build Coastguard Worker If sign bit counter cntSign is different from zero, switch to
694*e5436536SAndroid Build Coastguard Worker next state to decode sign Bits there. If sign bit counter cntSign is zero, no
695*e5436536SAndroid Build Coastguard Worker sign bits are needed and codeword is decoded.
696*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
697*e5436536SAndroid Build Coastguard Worker output: Two or four written quantizes spectral values written at
698*e5436536SAndroid Build Coastguard Worker position where pResultPointr points to. The signs of those lines may be wrong.
699*e5436536SAndroid Build Coastguard Worker If the signs [on just one signle sign] is wrong, the next state will correct it.
700*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
701*e5436536SAndroid Build Coastguard Worker return: 0
702*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
703*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs,void * ptr)704*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
705*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
706*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
707*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
708*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
709*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
710*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
711*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
712*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
713*e5436536SAndroid Build Coastguard Worker
714*e5436536SAndroid Build Coastguard Worker UCHAR *pCodebook;
715*e5436536SAndroid Build Coastguard Worker UINT *iNode;
716*e5436536SAndroid Build Coastguard Worker UCHAR *pCntSign;
717*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
718*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
719*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
720*e5436536SAndroid Build Coastguard Worker
721*e5436536SAndroid Build Coastguard Worker UINT iQSC;
722*e5436536SAndroid Build Coastguard Worker UINT cntSign;
723*e5436536SAndroid Build Coastguard Worker UCHAR dimCntr;
724*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
725*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
726*e5436536SAndroid Build Coastguard Worker UINT treeNode;
727*e5436536SAndroid Build Coastguard Worker UINT branchValue;
728*e5436536SAndroid Build Coastguard Worker UINT branchNode;
729*e5436536SAndroid Build Coastguard Worker const UCHAR *pCbDimension;
730*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree;
731*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase;
732*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantVal;
733*e5436536SAndroid Build Coastguard Worker
734*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
735*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
736*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
737*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
738*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
739*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
740*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
741*e5436536SAndroid Build Coastguard Worker
742*e5436536SAndroid Build Coastguard Worker pCodebook = pHcr->nonPcwSideinfo.pCodebook;
743*e5436536SAndroid Build Coastguard Worker iNode = pHcr->nonPcwSideinfo.iNode;
744*e5436536SAndroid Build Coastguard Worker pCntSign = pHcr->nonPcwSideinfo.pCntSign;
745*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
746*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
747*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
748*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
749*e5436536SAndroid Build Coastguard Worker
750*e5436536SAndroid Build Coastguard Worker pCbDimension = aDimCb;
751*e5436536SAndroid Build Coastguard Worker
752*e5436536SAndroid Build Coastguard Worker treeNode = iNode[codewordOffset];
753*e5436536SAndroid Build Coastguard Worker pCurrentTree = aHuffTable[pCodebook[codewordOffset]];
754*e5436536SAndroid Build Coastguard Worker
755*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
756*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
757*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
758*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
759*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
760*e5436536SAndroid Build Coastguard Worker
761*e5436536SAndroid Build Coastguard Worker CarryBitToBranchValue(carryBit, /* make a step in decoding tree */
762*e5436536SAndroid Build Coastguard Worker treeNode, &branchValue, &branchNode);
763*e5436536SAndroid Build Coastguard Worker
764*e5436536SAndroid Build Coastguard Worker /* if end of branch reached write out lines and count bits needed for sign,
765*e5436536SAndroid Build Coastguard Worker * otherwise store node in codeword sideinfo */
766*e5436536SAndroid Build Coastguard Worker if ((branchNode & TEST_BIT_10) ==
767*e5436536SAndroid Build Coastguard Worker TEST_BIT_10) { /* test bit 10 ; if set body complete */
768*e5436536SAndroid Build Coastguard Worker /* body completely decoded; branchValue is valid, set pQuantVal to first
769*e5436536SAndroid Build Coastguard Worker * (of two or four) quantized spectral coefficients */
770*e5436536SAndroid Build Coastguard Worker pQuantValBase = aQuantTable[pCodebook[codewordOffset]]; /* get base
771*e5436536SAndroid Build Coastguard Worker address of
772*e5436536SAndroid Build Coastguard Worker quantized
773*e5436536SAndroid Build Coastguard Worker values
774*e5436536SAndroid Build Coastguard Worker belonging to
775*e5436536SAndroid Build Coastguard Worker current
776*e5436536SAndroid Build Coastguard Worker codebook */
777*e5436536SAndroid Build Coastguard Worker pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
778*e5436536SAndroid Build Coastguard Worker line [of 2 or 4 quantized
779*e5436536SAndroid Build Coastguard Worker values] */
780*e5436536SAndroid Build Coastguard Worker
781*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset]; /* get position of first line for
782*e5436536SAndroid Build Coastguard Worker writing result */
783*e5436536SAndroid Build Coastguard Worker
784*e5436536SAndroid Build Coastguard Worker /* codeword decoding result is written out here: Write out 2 or 4
785*e5436536SAndroid Build Coastguard Worker * quantized spectral values with probably */
786*e5436536SAndroid Build Coastguard Worker /* wrong sign and count number of values which are different from zero for
787*e5436536SAndroid Build Coastguard Worker * sign bit decoding [which happens in next state] */
788*e5436536SAndroid Build Coastguard Worker cntSign = 0;
789*e5436536SAndroid Build Coastguard Worker for (dimCntr = pCbDimension[pCodebook[codewordOffset]]; dimCntr != 0;
790*e5436536SAndroid Build Coastguard Worker dimCntr--) {
791*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC++] =
792*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
793*e5436536SAndroid Build Coastguard Worker if (*pQuantVal++ != 0) {
794*e5436536SAndroid Build Coastguard Worker cntSign += 1;
795*e5436536SAndroid Build Coastguard Worker }
796*e5436536SAndroid Build Coastguard Worker }
797*e5436536SAndroid Build Coastguard Worker
798*e5436536SAndroid Build Coastguard Worker if (cntSign == 0) {
799*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(
800*e5436536SAndroid Build Coastguard Worker &(pHcr->nonPcwSideinfo.pState), segmentOffset,
801*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and switch off
802*e5436536SAndroid Build Coastguard Worker statemachine */
803*e5436536SAndroid Build Coastguard Worker } else {
804*e5436536SAndroid Build Coastguard Worker pCntSign[codewordOffset] = cntSign; /* write sign count result into
805*e5436536SAndroid Build Coastguard Worker codewordsideinfo of current
806*e5436536SAndroid Build Coastguard Worker codeword */
807*e5436536SAndroid Build Coastguard Worker pSta[codewordOffset] = BODY_SIGN__SIGN; /* change state */
808*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
809*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]]; /* get state from
810*e5436536SAndroid Build Coastguard Worker separate array of
811*e5436536SAndroid Build Coastguard Worker cw-sideinfo */
812*e5436536SAndroid Build Coastguard Worker }
813*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
814*e5436536SAndroid Build Coastguard Worker for loop counter (see
815*e5436536SAndroid Build Coastguard Worker above) is done here */
816*e5436536SAndroid Build Coastguard Worker break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
817*e5436536SAndroid Build Coastguard Worker decoded */
818*e5436536SAndroid Build Coastguard Worker } else { /* body is not decoded completely: */
819*e5436536SAndroid Build Coastguard Worker treeNode = *(
820*e5436536SAndroid Build Coastguard Worker pCurrentTree +
821*e5436536SAndroid Build Coastguard Worker branchValue); /* update treeNode for further step in decoding tree */
822*e5436536SAndroid Build Coastguard Worker }
823*e5436536SAndroid Build Coastguard Worker }
824*e5436536SAndroid Build Coastguard Worker iNode[codewordOffset] = treeNode; /* store updated treeNode because maybe
825*e5436536SAndroid Build Coastguard Worker decoding of codeword body not finished
826*e5436536SAndroid Build Coastguard Worker yet */
827*e5436536SAndroid Build Coastguard Worker
828*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
829*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
830*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
831*e5436536SAndroid Build Coastguard Worker switch off statemachine */
832*e5436536SAndroid Build Coastguard Worker
833*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
834*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__BODY;
835*e5436536SAndroid Build Coastguard Worker return BODY_SIGN__BODY;
836*e5436536SAndroid Build Coastguard Worker }
837*e5436536SAndroid Build Coastguard Worker }
838*e5436536SAndroid Build Coastguard Worker
839*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
840*e5436536SAndroid Build Coastguard Worker }
841*e5436536SAndroid Build Coastguard Worker
842*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
843*e5436536SAndroid Build Coastguard Worker description: This state decodes the sign bits belonging to a codeword. The
844*e5436536SAndroid Build Coastguard Worker state is called as often in different "trials" until pCntSgn[codewordOffset] is
845*e5436536SAndroid Build Coastguard Worker zero.
846*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
847*e5436536SAndroid Build Coastguard Worker output: The two or four quantizes spectral values (written in previous
848*e5436536SAndroid Build Coastguard Worker state) have now the correct sign.
849*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
850*e5436536SAndroid Build Coastguard Worker return: 0
851*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
852*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs,void * ptr)853*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
854*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
855*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
856*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
857*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
858*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
859*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
860*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
861*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
862*e5436536SAndroid Build Coastguard Worker
863*e5436536SAndroid Build Coastguard Worker UCHAR *pCntSign;
864*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
865*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
866*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
867*e5436536SAndroid Build Coastguard Worker
868*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
869*e5436536SAndroid Build Coastguard Worker UINT iQSC;
870*e5436536SAndroid Build Coastguard Worker UCHAR cntSign;
871*e5436536SAndroid Build Coastguard Worker
872*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
873*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
874*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
875*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
876*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
877*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
878*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
879*e5436536SAndroid Build Coastguard Worker
880*e5436536SAndroid Build Coastguard Worker /*pCodebook = */
881*e5436536SAndroid Build Coastguard Worker pCntSign = pHcr->nonPcwSideinfo.pCntSign;
882*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
883*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
884*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
885*e5436536SAndroid Build Coastguard Worker
886*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset];
887*e5436536SAndroid Build Coastguard Worker cntSign = pCntSign[codewordOffset];
888*e5436536SAndroid Build Coastguard Worker
889*e5436536SAndroid Build Coastguard Worker /* loop for sign bit decoding */
890*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
891*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
892*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
893*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
894*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
895*e5436536SAndroid Build Coastguard Worker cntSign -=
896*e5436536SAndroid Build Coastguard Worker 1; /* decrement sign counter because one sign bit has been read */
897*e5436536SAndroid Build Coastguard Worker
898*e5436536SAndroid Build Coastguard Worker /* search for a line (which was decoded in previous state) which is not
899*e5436536SAndroid Build Coastguard Worker * zero. [This value will get a sign] */
900*e5436536SAndroid Build Coastguard Worker while (pResultBase[iQSC] == (FIXP_DBL)0) {
901*e5436536SAndroid Build Coastguard Worker if (++iQSC >= 1024) { /* points to current value different from zero */
902*e5436536SAndroid Build Coastguard Worker return BODY_SIGN__SIGN;
903*e5436536SAndroid Build Coastguard Worker }
904*e5436536SAndroid Build Coastguard Worker }
905*e5436536SAndroid Build Coastguard Worker
906*e5436536SAndroid Build Coastguard Worker /* put sign together with line; if carryBit is zero, the sign is ok already;
907*e5436536SAndroid Build Coastguard Worker * no write operation necessary in this case */
908*e5436536SAndroid Build Coastguard Worker if (carryBit != 0) {
909*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
910*e5436536SAndroid Build Coastguard Worker }
911*e5436536SAndroid Build Coastguard Worker
912*e5436536SAndroid Build Coastguard Worker iQSC++; /* update pointer to next (maybe valid) value */
913*e5436536SAndroid Build Coastguard Worker
914*e5436536SAndroid Build Coastguard Worker if (cntSign == 0) { /* if (cntSign==0) ==> set state CODEWORD_DECODED */
915*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
916*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and
917*e5436536SAndroid Build Coastguard Worker switch off statemachine */
918*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
919*e5436536SAndroid Build Coastguard Worker for loop counter (see
920*e5436536SAndroid Build Coastguard Worker above) is done here */
921*e5436536SAndroid Build Coastguard Worker break; /* whole nonPCW-Body and according sign bits are decoded */
922*e5436536SAndroid Build Coastguard Worker }
923*e5436536SAndroid Build Coastguard Worker }
924*e5436536SAndroid Build Coastguard Worker pCntSign[codewordOffset] = cntSign;
925*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iQSC; /* store updated pResultPointer */
926*e5436536SAndroid Build Coastguard Worker
927*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
928*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
929*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
930*e5436536SAndroid Build Coastguard Worker switch off statemachine */
931*e5436536SAndroid Build Coastguard Worker
932*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
933*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN__SIGN;
934*e5436536SAndroid Build Coastguard Worker return BODY_SIGN__SIGN;
935*e5436536SAndroid Build Coastguard Worker }
936*e5436536SAndroid Build Coastguard Worker }
937*e5436536SAndroid Build Coastguard Worker
938*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
939*e5436536SAndroid Build Coastguard Worker }
940*e5436536SAndroid Build Coastguard Worker
941*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
942*e5436536SAndroid Build Coastguard Worker description: Decodes the codeword body in case of codebook is 11. Writes
943*e5436536SAndroid Build Coastguard Worker out resulting two or four lines [with probably wrong sign] and counts the number
944*e5436536SAndroid Build Coastguard Worker of lines, which are different form zero. This information is needed in next
945*e5436536SAndroid Build Coastguard Worker state where sign bits will be decoded, if necessary.
946*e5436536SAndroid Build Coastguard Worker If sign bit counter cntSign is zero, no sign bits are needed
947*e5436536SAndroid Build Coastguard Worker and codeword is decoded completely.
948*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
949*e5436536SAndroid Build Coastguard Worker output: Two lines (quantizes spectral coefficients) which are probably
950*e5436536SAndroid Build Coastguard Worker wrong. The sign may be wrong and if one or two values is/are 16, the following
951*e5436536SAndroid Build Coastguard Worker states will decode the escape sequence to correct the values which are wirtten
952*e5436536SAndroid Build Coastguard Worker here.
953*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
954*e5436536SAndroid Build Coastguard Worker return: 0
955*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
956*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs,void * ptr)957*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN_ESC__BODY(HANDLE_FDK_BITSTREAM bs, void *ptr) {
958*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
959*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
960*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
961*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
962*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
963*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
964*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
965*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
966*e5436536SAndroid Build Coastguard Worker
967*e5436536SAndroid Build Coastguard Worker UINT *iNode;
968*e5436536SAndroid Build Coastguard Worker UCHAR *pCntSign;
969*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
970*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
971*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
972*e5436536SAndroid Build Coastguard Worker
973*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
974*e5436536SAndroid Build Coastguard Worker UINT iQSC;
975*e5436536SAndroid Build Coastguard Worker UINT cntSign;
976*e5436536SAndroid Build Coastguard Worker UINT dimCntr;
977*e5436536SAndroid Build Coastguard Worker UINT treeNode;
978*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
979*e5436536SAndroid Build Coastguard Worker UINT branchNode;
980*e5436536SAndroid Build Coastguard Worker UINT branchValue;
981*e5436536SAndroid Build Coastguard Worker const UINT *pCurrentTree;
982*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantValBase;
983*e5436536SAndroid Build Coastguard Worker const SCHAR *pQuantVal;
984*e5436536SAndroid Build Coastguard Worker
985*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
986*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
987*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
988*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
989*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
990*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
991*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
992*e5436536SAndroid Build Coastguard Worker
993*e5436536SAndroid Build Coastguard Worker iNode = pHcr->nonPcwSideinfo.iNode;
994*e5436536SAndroid Build Coastguard Worker pCntSign = pHcr->nonPcwSideinfo.pCntSign;
995*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
996*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
997*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
998*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
999*e5436536SAndroid Build Coastguard Worker
1000*e5436536SAndroid Build Coastguard Worker treeNode = iNode[codewordOffset];
1001*e5436536SAndroid Build Coastguard Worker pCurrentTree = aHuffTable[ESCAPE_CODEBOOK];
1002*e5436536SAndroid Build Coastguard Worker
1003*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
1004*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
1005*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
1006*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
1007*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
1008*e5436536SAndroid Build Coastguard Worker
1009*e5436536SAndroid Build Coastguard Worker /* make a step in tree */
1010*e5436536SAndroid Build Coastguard Worker CarryBitToBranchValue(carryBit, treeNode, &branchValue, &branchNode);
1011*e5436536SAndroid Build Coastguard Worker
1012*e5436536SAndroid Build Coastguard Worker /* if end of branch reached write out lines and count bits needed for sign,
1013*e5436536SAndroid Build Coastguard Worker * otherwise store node in codeword sideinfo */
1014*e5436536SAndroid Build Coastguard Worker if ((branchNode & TEST_BIT_10) ==
1015*e5436536SAndroid Build Coastguard Worker TEST_BIT_10) { /* test bit 10 ; if set body complete */
1016*e5436536SAndroid Build Coastguard Worker
1017*e5436536SAndroid Build Coastguard Worker /* body completely decoded; branchValue is valid */
1018*e5436536SAndroid Build Coastguard Worker /* set pQuantVol to first (of two or four) quantized spectral coefficients
1019*e5436536SAndroid Build Coastguard Worker */
1020*e5436536SAndroid Build Coastguard Worker pQuantValBase = aQuantTable[ESCAPE_CODEBOOK]; /* get base address of
1021*e5436536SAndroid Build Coastguard Worker quantized values
1022*e5436536SAndroid Build Coastguard Worker belonging to current
1023*e5436536SAndroid Build Coastguard Worker codebook */
1024*e5436536SAndroid Build Coastguard Worker pQuantVal = pQuantValBase + branchValue; /* set pointer to first valid
1025*e5436536SAndroid Build Coastguard Worker line [of 2 or 4 quantized
1026*e5436536SAndroid Build Coastguard Worker values] */
1027*e5436536SAndroid Build Coastguard Worker
1028*e5436536SAndroid Build Coastguard Worker /* make backup from original resultPointer in node storage for state
1029*e5436536SAndroid Build Coastguard Worker * BODY_SIGN_ESC__SIGN */
1030*e5436536SAndroid Build Coastguard Worker iNode[codewordOffset] = iResultPointer[codewordOffset];
1031*e5436536SAndroid Build Coastguard Worker
1032*e5436536SAndroid Build Coastguard Worker /* get position of first line for writing result */
1033*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset];
1034*e5436536SAndroid Build Coastguard Worker
1035*e5436536SAndroid Build Coastguard Worker /* codeword decoding result is written out here: Write out 2 or 4
1036*e5436536SAndroid Build Coastguard Worker * quantized spectral values with probably */
1037*e5436536SAndroid Build Coastguard Worker /* wrong sign and count number of values which are different from zero for
1038*e5436536SAndroid Build Coastguard Worker * sign bit decoding [which happens in next state] */
1039*e5436536SAndroid Build Coastguard Worker cntSign = 0;
1040*e5436536SAndroid Build Coastguard Worker
1041*e5436536SAndroid Build Coastguard Worker for (dimCntr = DIMENSION_OF_ESCAPE_CODEBOOK; dimCntr != 0; dimCntr--) {
1042*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC++] =
1043*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)*pQuantVal; /* write quant. spec. coef. into spectrum */
1044*e5436536SAndroid Build Coastguard Worker if (*pQuantVal++ != 0) {
1045*e5436536SAndroid Build Coastguard Worker cntSign += 1;
1046*e5436536SAndroid Build Coastguard Worker }
1047*e5436536SAndroid Build Coastguard Worker }
1048*e5436536SAndroid Build Coastguard Worker
1049*e5436536SAndroid Build Coastguard Worker if (cntSign == 0) {
1050*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(
1051*e5436536SAndroid Build Coastguard Worker &(pHcr->nonPcwSideinfo.pState), segmentOffset,
1052*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and switch off
1053*e5436536SAndroid Build Coastguard Worker statemachine */
1054*e5436536SAndroid Build Coastguard Worker /* codeword decoded */
1055*e5436536SAndroid Build Coastguard Worker } else {
1056*e5436536SAndroid Build Coastguard Worker /* write sign count result into codewordsideinfo of current codeword */
1057*e5436536SAndroid Build Coastguard Worker pCntSign[codewordOffset] = cntSign;
1058*e5436536SAndroid Build Coastguard Worker pSta[codewordOffset] = BODY_SIGN_ESC__SIGN; /* change state */
1059*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
1060*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]]; /* get state from
1061*e5436536SAndroid Build Coastguard Worker separate array of
1062*e5436536SAndroid Build Coastguard Worker cw-sideinfo */
1063*e5436536SAndroid Build Coastguard Worker }
1064*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* the last reinitialzation
1065*e5436536SAndroid Build Coastguard Worker of for loop counter (see
1066*e5436536SAndroid Build Coastguard Worker above) is done here */
1067*e5436536SAndroid Build Coastguard Worker break; /* end of branch in tree reached i.e. a whole nonPCW-Body is
1068*e5436536SAndroid Build Coastguard Worker decoded */
1069*e5436536SAndroid Build Coastguard Worker } else { /* body is not decoded completely: */
1070*e5436536SAndroid Build Coastguard Worker /* update treeNode for further step in decoding tree and store updated
1071*e5436536SAndroid Build Coastguard Worker * treeNode because maybe no more bits left in segment */
1072*e5436536SAndroid Build Coastguard Worker treeNode = *(pCurrentTree + branchValue);
1073*e5436536SAndroid Build Coastguard Worker iNode[codewordOffset] = treeNode;
1074*e5436536SAndroid Build Coastguard Worker }
1075*e5436536SAndroid Build Coastguard Worker }
1076*e5436536SAndroid Build Coastguard Worker
1077*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
1078*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
1079*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
1080*e5436536SAndroid Build Coastguard Worker switch off statemachine */
1081*e5436536SAndroid Build Coastguard Worker
1082*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
1083*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__BODY;
1084*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__BODY;
1085*e5436536SAndroid Build Coastguard Worker }
1086*e5436536SAndroid Build Coastguard Worker }
1087*e5436536SAndroid Build Coastguard Worker
1088*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
1089*e5436536SAndroid Build Coastguard Worker }
1090*e5436536SAndroid Build Coastguard Worker
1091*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1092*e5436536SAndroid Build Coastguard Worker description: This state decodes the sign bits, if a codeword of codebook 11
1093*e5436536SAndroid Build Coastguard Worker needs some. A flag named 'flagB' in codeword sideinfo is set, if the second line
1094*e5436536SAndroid Build Coastguard Worker of quantized spectral values is 16. The 'flagB' is used in case of decoding of a
1095*e5436536SAndroid Build Coastguard Worker escape sequence is necessary as far as the second line is concerned.
1096*e5436536SAndroid Build Coastguard Worker
1097*e5436536SAndroid Build Coastguard Worker If only the first line needs an escape sequence, the flagB is
1098*e5436536SAndroid Build Coastguard Worker cleared. If only the second line needs an escape sequence, the flagB is not
1099*e5436536SAndroid Build Coastguard Worker used.
1100*e5436536SAndroid Build Coastguard Worker
1101*e5436536SAndroid Build Coastguard Worker For storing sideinfo in case of escape sequence decoding one
1102*e5436536SAndroid Build Coastguard Worker single word can be used for both escape sequences because they are decoded not
1103*e5436536SAndroid Build Coastguard Worker at the same time:
1104*e5436536SAndroid Build Coastguard Worker
1105*e5436536SAndroid Build Coastguard Worker
1106*e5436536SAndroid Build Coastguard Worker bit 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
1107*e5436536SAndroid Build Coastguard Worker 4 3 2 1 0
1108*e5436536SAndroid Build Coastguard Worker ===== == == =========== ===========
1109*e5436536SAndroid Build Coastguard Worker =================================== ^ ^ ^ ^ ^
1110*e5436536SAndroid Build Coastguard Worker ^ | | | | | | res. flagA flagB
1111*e5436536SAndroid Build Coastguard Worker escapePrefixUp escapePrefixDown escapeWord
1112*e5436536SAndroid Build Coastguard Worker
1113*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1114*e5436536SAndroid Build Coastguard Worker output: Two lines with correct sign. If one or two values is/are 16,
1115*e5436536SAndroid Build Coastguard Worker the lines are not valid, otherwise they are.
1116*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1117*e5436536SAndroid Build Coastguard Worker return: 0
1118*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1119*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs,void * ptr)1120*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN_ESC__SIGN(HANDLE_FDK_BITSTREAM bs, void *ptr) {
1121*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
1122*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
1123*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
1124*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
1125*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
1126*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
1127*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
1128*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
1129*e5436536SAndroid Build Coastguard Worker
1130*e5436536SAndroid Build Coastguard Worker UINT *iNode;
1131*e5436536SAndroid Build Coastguard Worker UCHAR *pCntSign;
1132*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
1133*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
1134*e5436536SAndroid Build Coastguard Worker UINT *pEscapeSequenceInfo;
1135*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
1136*e5436536SAndroid Build Coastguard Worker
1137*e5436536SAndroid Build Coastguard Worker UINT iQSC;
1138*e5436536SAndroid Build Coastguard Worker UCHAR cntSign;
1139*e5436536SAndroid Build Coastguard Worker UINT flagA;
1140*e5436536SAndroid Build Coastguard Worker UINT flagB;
1141*e5436536SAndroid Build Coastguard Worker UINT flags;
1142*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
1143*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
1144*e5436536SAndroid Build Coastguard Worker
1145*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1146*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
1147*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
1148*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
1149*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
1150*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
1151*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
1152*e5436536SAndroid Build Coastguard Worker
1153*e5436536SAndroid Build Coastguard Worker iNode = pHcr->nonPcwSideinfo.iNode;
1154*e5436536SAndroid Build Coastguard Worker pCntSign = pHcr->nonPcwSideinfo.pCntSign;
1155*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
1156*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
1157*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
1158*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
1159*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
1160*e5436536SAndroid Build Coastguard Worker
1161*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset];
1162*e5436536SAndroid Build Coastguard Worker cntSign = pCntSign[codewordOffset];
1163*e5436536SAndroid Build Coastguard Worker
1164*e5436536SAndroid Build Coastguard Worker /* loop for sign bit decoding */
1165*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
1166*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
1167*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
1168*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
1169*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
1170*e5436536SAndroid Build Coastguard Worker
1171*e5436536SAndroid Build Coastguard Worker /* decrement sign counter because one sign bit has been read */
1172*e5436536SAndroid Build Coastguard Worker cntSign -= 1;
1173*e5436536SAndroid Build Coastguard Worker pCntSign[codewordOffset] = cntSign;
1174*e5436536SAndroid Build Coastguard Worker
1175*e5436536SAndroid Build Coastguard Worker /* get a quantized spectral value (which was decoded in previous state)
1176*e5436536SAndroid Build Coastguard Worker * which is not zero. [This value will get a sign] */
1177*e5436536SAndroid Build Coastguard Worker while (pResultBase[iQSC] == (FIXP_DBL)0) {
1178*e5436536SAndroid Build Coastguard Worker if (++iQSC >= 1024) {
1179*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__SIGN;
1180*e5436536SAndroid Build Coastguard Worker }
1181*e5436536SAndroid Build Coastguard Worker }
1182*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iQSC;
1183*e5436536SAndroid Build Coastguard Worker
1184*e5436536SAndroid Build Coastguard Worker /* put negative sign together with quantized spectral value; if carryBit is
1185*e5436536SAndroid Build Coastguard Worker * zero, the sign is ok already; no write operation necessary in this case
1186*e5436536SAndroid Build Coastguard Worker */
1187*e5436536SAndroid Build Coastguard Worker if (carryBit != 0) {
1188*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC] = -pResultBase[iQSC]; /* carryBit = 1 --> minus */
1189*e5436536SAndroid Build Coastguard Worker }
1190*e5436536SAndroid Build Coastguard Worker iQSC++; /* update index to next (maybe valid) value */
1191*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iQSC;
1192*e5436536SAndroid Build Coastguard Worker
1193*e5436536SAndroid Build Coastguard Worker if (cntSign == 0) {
1194*e5436536SAndroid Build Coastguard Worker /* all sign bits are decoded now */
1195*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
1196*e5436536SAndroid Build Coastguard Worker for loop counter (see
1197*e5436536SAndroid Build Coastguard Worker above) is done here */
1198*e5436536SAndroid Build Coastguard Worker
1199*e5436536SAndroid Build Coastguard Worker /* check decoded values if codeword is decoded: Check if one or two escape
1200*e5436536SAndroid Build Coastguard Worker * sequences 16 follow */
1201*e5436536SAndroid Build Coastguard Worker
1202*e5436536SAndroid Build Coastguard Worker /* step 0 */
1203*e5436536SAndroid Build Coastguard Worker /* restore pointer to first decoded quantized value [ = original
1204*e5436536SAndroid Build Coastguard Worker * pResultPointr] from index iNode prepared in State_BODY_SIGN_ESC__BODY
1205*e5436536SAndroid Build Coastguard Worker */
1206*e5436536SAndroid Build Coastguard Worker iQSC = iNode[codewordOffset];
1207*e5436536SAndroid Build Coastguard Worker
1208*e5436536SAndroid Build Coastguard Worker /* step 1 */
1209*e5436536SAndroid Build Coastguard Worker /* test first value if escape sequence follows */
1210*e5436536SAndroid Build Coastguard Worker flagA = 0; /* for first possible escape sequence */
1211*e5436536SAndroid Build Coastguard Worker if (fixp_abs(pResultBase[iQSC++]) == (FIXP_DBL)ESCAPE_VALUE) {
1212*e5436536SAndroid Build Coastguard Worker flagA = 1;
1213*e5436536SAndroid Build Coastguard Worker }
1214*e5436536SAndroid Build Coastguard Worker
1215*e5436536SAndroid Build Coastguard Worker /* step 2 */
1216*e5436536SAndroid Build Coastguard Worker /* test second value if escape sequence follows */
1217*e5436536SAndroid Build Coastguard Worker flagB = 0; /* for second possible escape sequence */
1218*e5436536SAndroid Build Coastguard Worker if (fixp_abs(pResultBase[iQSC]) == (FIXP_DBL)ESCAPE_VALUE) {
1219*e5436536SAndroid Build Coastguard Worker flagB = 1;
1220*e5436536SAndroid Build Coastguard Worker }
1221*e5436536SAndroid Build Coastguard Worker
1222*e5436536SAndroid Build Coastguard Worker /* step 3 */
1223*e5436536SAndroid Build Coastguard Worker /* evaluate flag result and go on if necessary */
1224*e5436536SAndroid Build Coastguard Worker if (!flagA && !flagB) {
1225*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(
1226*e5436536SAndroid Build Coastguard Worker &(pHcr->nonPcwSideinfo.pState), segmentOffset,
1227*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and switch off
1228*e5436536SAndroid Build Coastguard Worker statemachine */
1229*e5436536SAndroid Build Coastguard Worker } else {
1230*e5436536SAndroid Build Coastguard Worker /* at least one of two lines is 16 */
1231*e5436536SAndroid Build Coastguard Worker /* store both flags at correct positions in non PCW codeword sideinfo
1232*e5436536SAndroid Build Coastguard Worker * pEscapeSequenceInfo[codewordOffset] */
1233*e5436536SAndroid Build Coastguard Worker flags = flagA << POSITION_OF_FLAG_A;
1234*e5436536SAndroid Build Coastguard Worker flags |= (flagB << POSITION_OF_FLAG_B);
1235*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] = flags;
1236*e5436536SAndroid Build Coastguard Worker
1237*e5436536SAndroid Build Coastguard Worker /* set next state */
1238*e5436536SAndroid Build Coastguard Worker pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
1239*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
1240*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]]; /* get state from
1241*e5436536SAndroid Build Coastguard Worker separate array of
1242*e5436536SAndroid Build Coastguard Worker cw-sideinfo */
1243*e5436536SAndroid Build Coastguard Worker
1244*e5436536SAndroid Build Coastguard Worker /* set result pointer to the first line of the two decoded lines */
1245*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iNode[codewordOffset];
1246*e5436536SAndroid Build Coastguard Worker
1247*e5436536SAndroid Build Coastguard Worker if (!flagA && flagB) {
1248*e5436536SAndroid Build Coastguard Worker /* update pResultPointr ==> state Stat_BODY_SIGN_ESC__ESC_WORD writes
1249*e5436536SAndroid Build Coastguard Worker * to correct position. Second value is the one and only escape value
1250*e5436536SAndroid Build Coastguard Worker */
1251*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset];
1252*e5436536SAndroid Build Coastguard Worker iQSC++;
1253*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iQSC;
1254*e5436536SAndroid Build Coastguard Worker }
1255*e5436536SAndroid Build Coastguard Worker
1256*e5436536SAndroid Build Coastguard Worker } /* at least one of two lines is 16 */
1257*e5436536SAndroid Build Coastguard Worker break; /* nonPCW-Body at cb 11 and according sign bits are decoded */
1258*e5436536SAndroid Build Coastguard Worker
1259*e5436536SAndroid Build Coastguard Worker } /* if ( cntSign == 0 ) */
1260*e5436536SAndroid Build Coastguard Worker } /* loop over remaining Bits in segment */
1261*e5436536SAndroid Build Coastguard Worker
1262*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
1263*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
1264*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
1265*e5436536SAndroid Build Coastguard Worker switch off statemachine */
1266*e5436536SAndroid Build Coastguard Worker
1267*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
1268*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__SIGN;
1269*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__SIGN;
1270*e5436536SAndroid Build Coastguard Worker }
1271*e5436536SAndroid Build Coastguard Worker }
1272*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
1273*e5436536SAndroid Build Coastguard Worker }
1274*e5436536SAndroid Build Coastguard Worker
1275*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1276*e5436536SAndroid Build Coastguard Worker description: Decode escape prefix of first or second escape sequence. The
1277*e5436536SAndroid Build Coastguard Worker escape prefix consists of ones. The following zero is also decoded here.
1278*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1279*e5436536SAndroid Build Coastguard Worker output: If the single separator-zero which follows the
1280*e5436536SAndroid Build Coastguard Worker escape-prefix-ones is not yet decoded: The value 'escapePrefixUp' in word
1281*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] is updated.
1282*e5436536SAndroid Build Coastguard Worker
1283*e5436536SAndroid Build Coastguard Worker If the single separator-zero which follows the
1284*e5436536SAndroid Build Coastguard Worker escape-prefix-ones is decoded: Two updated values 'escapePrefixUp' and
1285*e5436536SAndroid Build Coastguard Worker 'escapePrefixDown' in word pEscapeSequenceInfo[codewordOffset]. This State is
1286*e5436536SAndroid Build Coastguard Worker finished. Switch to next state.
1287*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1288*e5436536SAndroid Build Coastguard Worker return: 0
1289*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1290*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs,void * ptr)1291*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN_ESC__ESC_PREFIX(HANDLE_FDK_BITSTREAM bs, void *ptr) {
1292*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
1293*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
1294*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
1295*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
1296*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
1297*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
1298*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
1299*e5436536SAndroid Build Coastguard Worker UINT *pEscapeSequenceInfo;
1300*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
1301*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
1302*e5436536SAndroid Build Coastguard Worker UINT escapePrefixUp;
1303*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
1304*e5436536SAndroid Build Coastguard Worker
1305*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1306*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
1307*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
1308*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
1309*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
1310*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
1311*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
1312*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
1313*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
1314*e5436536SAndroid Build Coastguard Worker
1315*e5436536SAndroid Build Coastguard Worker escapePrefixUp =
1316*e5436536SAndroid Build Coastguard Worker (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
1317*e5436536SAndroid Build Coastguard Worker LSB_ESCAPE_PREFIX_UP;
1318*e5436536SAndroid Build Coastguard Worker
1319*e5436536SAndroid Build Coastguard Worker /* decode escape prefix */
1320*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
1321*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
1322*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
1323*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
1324*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
1325*e5436536SAndroid Build Coastguard Worker
1326*e5436536SAndroid Build Coastguard Worker /* count ones and store sum in escapePrefixUp */
1327*e5436536SAndroid Build Coastguard Worker if (carryBit == 1) {
1328*e5436536SAndroid Build Coastguard Worker escapePrefixUp += 1; /* update conter for ones */
1329*e5436536SAndroid Build Coastguard Worker if (escapePrefixUp > 8) {
1330*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
1331*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__ESC_PREFIX;
1332*e5436536SAndroid Build Coastguard Worker }
1333*e5436536SAndroid Build Coastguard Worker
1334*e5436536SAndroid Build Coastguard Worker /* store updated counter in sideinfo of current codeword */
1335*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &=
1336*e5436536SAndroid Build Coastguard Worker ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
1337*e5436536SAndroid Build Coastguard Worker escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
1338*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] |=
1339*e5436536SAndroid Build Coastguard Worker escapePrefixUp; /* insert new escapePrefixUp */
1340*e5436536SAndroid Build Coastguard Worker escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
1341*e5436536SAndroid Build Coastguard Worker } else { /* separator [zero] reached */
1342*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
1343*e5436536SAndroid Build Coastguard Worker for loop counter (see
1344*e5436536SAndroid Build Coastguard Worker above) is done here */
1345*e5436536SAndroid Build Coastguard Worker escapePrefixUp +=
1346*e5436536SAndroid Build Coastguard Worker 4; /* if escape_separator '0' appears, add 4 and ==> break */
1347*e5436536SAndroid Build Coastguard Worker
1348*e5436536SAndroid Build Coastguard Worker /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
1349*e5436536SAndroid Build Coastguard Worker * position escapePrefixUp */
1350*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &=
1351*e5436536SAndroid Build Coastguard Worker ~MASK_ESCAPE_PREFIX_UP; /* delete old escapePrefixUp */
1352*e5436536SAndroid Build Coastguard Worker escapePrefixUp <<= LSB_ESCAPE_PREFIX_UP; /* shift to correct position */
1353*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] |=
1354*e5436536SAndroid Build Coastguard Worker escapePrefixUp; /* insert new escapePrefixUp */
1355*e5436536SAndroid Build Coastguard Worker escapePrefixUp >>= LSB_ESCAPE_PREFIX_UP; /* shift back down */
1356*e5436536SAndroid Build Coastguard Worker
1357*e5436536SAndroid Build Coastguard Worker /* store escapePrefixUp in pEscapeSequenceInfo[codewordOffset] at bit
1358*e5436536SAndroid Build Coastguard Worker * position escapePrefixDown */
1359*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &=
1360*e5436536SAndroid Build Coastguard Worker ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
1361*e5436536SAndroid Build Coastguard Worker escapePrefixUp <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
1362*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] |=
1363*e5436536SAndroid Build Coastguard Worker escapePrefixUp; /* insert new escapePrefixDown */
1364*e5436536SAndroid Build Coastguard Worker
1365*e5436536SAndroid Build Coastguard Worker pSta[codewordOffset] = BODY_SIGN_ESC__ESC_WORD; /* set next state */
1366*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
1367*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]]; /* get state from separate
1368*e5436536SAndroid Build Coastguard Worker array of cw-sideinfo */
1369*e5436536SAndroid Build Coastguard Worker break;
1370*e5436536SAndroid Build Coastguard Worker }
1371*e5436536SAndroid Build Coastguard Worker }
1372*e5436536SAndroid Build Coastguard Worker
1373*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
1374*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
1375*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
1376*e5436536SAndroid Build Coastguard Worker switch off statemachine */
1377*e5436536SAndroid Build Coastguard Worker
1378*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
1379*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_PREFIX;
1380*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__ESC_PREFIX;
1381*e5436536SAndroid Build Coastguard Worker }
1382*e5436536SAndroid Build Coastguard Worker }
1383*e5436536SAndroid Build Coastguard Worker
1384*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
1385*e5436536SAndroid Build Coastguard Worker }
1386*e5436536SAndroid Build Coastguard Worker
1387*e5436536SAndroid Build Coastguard Worker /*---------------------------------------------------------------------------------------------
1388*e5436536SAndroid Build Coastguard Worker description: Decode escapeWord of escape sequence. If the escape sequence
1389*e5436536SAndroid Build Coastguard Worker is decoded completely, assemble quantized-spectral-escape-coefficient and
1390*e5436536SAndroid Build Coastguard Worker replace the previous decoded 16 by the new value. Test flagB. If flagB is set,
1391*e5436536SAndroid Build Coastguard Worker the second escape sequence must be decoded. If flagB is not set, the codeword is
1392*e5436536SAndroid Build Coastguard Worker decoded and the state machine is switched off.
1393*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1394*e5436536SAndroid Build Coastguard Worker output: Two lines with valid sign. At least one of both lines has got
1395*e5436536SAndroid Build Coastguard Worker the correct value.
1396*e5436536SAndroid Build Coastguard Worker -----------------------------------------------------------------------------------------------
1397*e5436536SAndroid Build Coastguard Worker return: 0
1398*e5436536SAndroid Build Coastguard Worker --------------------------------------------------------------------------------------------
1399*e5436536SAndroid Build Coastguard Worker */
Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs,void * ptr)1400*e5436536SAndroid Build Coastguard Worker UINT Hcr_State_BODY_SIGN_ESC__ESC_WORD(HANDLE_FDK_BITSTREAM bs, void *ptr) {
1401*e5436536SAndroid Build Coastguard Worker H_HCR_INFO pHcr = (H_HCR_INFO)ptr;
1402*e5436536SAndroid Build Coastguard Worker SCHAR *pRemainingBitsInSegment;
1403*e5436536SAndroid Build Coastguard Worker INT *pLeftStartOfSegment;
1404*e5436536SAndroid Build Coastguard Worker INT *pRightStartOfSegment;
1405*e5436536SAndroid Build Coastguard Worker UCHAR readDirection;
1406*e5436536SAndroid Build Coastguard Worker UINT *pSegmentBitfield;
1407*e5436536SAndroid Build Coastguard Worker UINT *pCodewordBitfield;
1408*e5436536SAndroid Build Coastguard Worker UINT segmentOffset;
1409*e5436536SAndroid Build Coastguard Worker
1410*e5436536SAndroid Build Coastguard Worker FIXP_DBL *pResultBase;
1411*e5436536SAndroid Build Coastguard Worker USHORT *iResultPointer;
1412*e5436536SAndroid Build Coastguard Worker UINT *pEscapeSequenceInfo;
1413*e5436536SAndroid Build Coastguard Worker UINT codewordOffset;
1414*e5436536SAndroid Build Coastguard Worker
1415*e5436536SAndroid Build Coastguard Worker UINT escapeWord;
1416*e5436536SAndroid Build Coastguard Worker UINT escapePrefixDown;
1417*e5436536SAndroid Build Coastguard Worker UINT escapePrefixUp;
1418*e5436536SAndroid Build Coastguard Worker UCHAR carryBit;
1419*e5436536SAndroid Build Coastguard Worker UINT iQSC;
1420*e5436536SAndroid Build Coastguard Worker INT sign;
1421*e5436536SAndroid Build Coastguard Worker UINT flagA;
1422*e5436536SAndroid Build Coastguard Worker UINT flagB;
1423*e5436536SAndroid Build Coastguard Worker SCHAR *pSta;
1424*e5436536SAndroid Build Coastguard Worker
1425*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment = pHcr->segmentInfo.pRemainingBitsInSegment;
1426*e5436536SAndroid Build Coastguard Worker pLeftStartOfSegment = pHcr->segmentInfo.pLeftStartOfSegment;
1427*e5436536SAndroid Build Coastguard Worker pRightStartOfSegment = pHcr->segmentInfo.pRightStartOfSegment;
1428*e5436536SAndroid Build Coastguard Worker readDirection = pHcr->segmentInfo.readDirection;
1429*e5436536SAndroid Build Coastguard Worker pSegmentBitfield = pHcr->segmentInfo.pSegmentBitfield;
1430*e5436536SAndroid Build Coastguard Worker pCodewordBitfield = pHcr->segmentInfo.pCodewordBitfield;
1431*e5436536SAndroid Build Coastguard Worker segmentOffset = pHcr->segmentInfo.segmentOffset;
1432*e5436536SAndroid Build Coastguard Worker
1433*e5436536SAndroid Build Coastguard Worker pResultBase = pHcr->nonPcwSideinfo.pResultBase;
1434*e5436536SAndroid Build Coastguard Worker iResultPointer = pHcr->nonPcwSideinfo.iResultPointer;
1435*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo = pHcr->nonPcwSideinfo.pEscapeSequenceInfo;
1436*e5436536SAndroid Build Coastguard Worker codewordOffset = pHcr->nonPcwSideinfo.codewordOffset;
1437*e5436536SAndroid Build Coastguard Worker pSta = pHcr->nonPcwSideinfo.pSta;
1438*e5436536SAndroid Build Coastguard Worker
1439*e5436536SAndroid Build Coastguard Worker escapeWord = pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_WORD;
1440*e5436536SAndroid Build Coastguard Worker escapePrefixDown =
1441*e5436536SAndroid Build Coastguard Worker (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_DOWN) >>
1442*e5436536SAndroid Build Coastguard Worker LSB_ESCAPE_PREFIX_DOWN;
1443*e5436536SAndroid Build Coastguard Worker
1444*e5436536SAndroid Build Coastguard Worker /* decode escape word */
1445*e5436536SAndroid Build Coastguard Worker for (; pRemainingBitsInSegment[segmentOffset] > 0;
1446*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1) {
1447*e5436536SAndroid Build Coastguard Worker carryBit = HcrGetABitFromBitstream(
1448*e5436536SAndroid Build Coastguard Worker bs, pHcr->decInOut.bitstreamAnchor, &pLeftStartOfSegment[segmentOffset],
1449*e5436536SAndroid Build Coastguard Worker &pRightStartOfSegment[segmentOffset], readDirection);
1450*e5436536SAndroid Build Coastguard Worker
1451*e5436536SAndroid Build Coastguard Worker /* build escape word */
1452*e5436536SAndroid Build Coastguard Worker escapeWord <<=
1453*e5436536SAndroid Build Coastguard Worker 1; /* left shift previous decoded part of escapeWord by on bit */
1454*e5436536SAndroid Build Coastguard Worker escapeWord = escapeWord | carryBit; /* assemble escape word by bitwise or */
1455*e5436536SAndroid Build Coastguard Worker
1456*e5436536SAndroid Build Coastguard Worker /* decrement counter for length of escape word because one more bit was
1457*e5436536SAndroid Build Coastguard Worker * decoded */
1458*e5436536SAndroid Build Coastguard Worker escapePrefixDown -= 1;
1459*e5436536SAndroid Build Coastguard Worker
1460*e5436536SAndroid Build Coastguard Worker /* store updated escapePrefixDown */
1461*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &=
1462*e5436536SAndroid Build Coastguard Worker ~MASK_ESCAPE_PREFIX_DOWN; /* delete old escapePrefixDown */
1463*e5436536SAndroid Build Coastguard Worker escapePrefixDown <<= LSB_ESCAPE_PREFIX_DOWN; /* shift to correct position */
1464*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] |=
1465*e5436536SAndroid Build Coastguard Worker escapePrefixDown; /* insert new escapePrefixDown */
1466*e5436536SAndroid Build Coastguard Worker escapePrefixDown >>= LSB_ESCAPE_PREFIX_DOWN; /* shift back */
1467*e5436536SAndroid Build Coastguard Worker
1468*e5436536SAndroid Build Coastguard Worker /* store updated escapeWord */
1469*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &=
1470*e5436536SAndroid Build Coastguard Worker ~MASK_ESCAPE_WORD; /* delete old escapeWord */
1471*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] |=
1472*e5436536SAndroid Build Coastguard Worker escapeWord; /* insert new escapeWord */
1473*e5436536SAndroid Build Coastguard Worker
1474*e5436536SAndroid Build Coastguard Worker if (escapePrefixDown == 0) {
1475*e5436536SAndroid Build Coastguard Worker pRemainingBitsInSegment[segmentOffset] -= 1; /* last reinitialzation of
1476*e5436536SAndroid Build Coastguard Worker for loop counter (see
1477*e5436536SAndroid Build Coastguard Worker above) is done here */
1478*e5436536SAndroid Build Coastguard Worker
1479*e5436536SAndroid Build Coastguard Worker /* escape sequence decoded. Assemble escape-line and replace original line
1480*e5436536SAndroid Build Coastguard Worker */
1481*e5436536SAndroid Build Coastguard Worker
1482*e5436536SAndroid Build Coastguard Worker /* step 0 */
1483*e5436536SAndroid Build Coastguard Worker /* derive sign */
1484*e5436536SAndroid Build Coastguard Worker iQSC = iResultPointer[codewordOffset];
1485*e5436536SAndroid Build Coastguard Worker sign = (pResultBase[iQSC] >= (FIXP_DBL)0)
1486*e5436536SAndroid Build Coastguard Worker ? 1
1487*e5436536SAndroid Build Coastguard Worker : -1; /* get sign of escape value 16 */
1488*e5436536SAndroid Build Coastguard Worker
1489*e5436536SAndroid Build Coastguard Worker /* step 1 */
1490*e5436536SAndroid Build Coastguard Worker /* get escapePrefixUp */
1491*e5436536SAndroid Build Coastguard Worker escapePrefixUp =
1492*e5436536SAndroid Build Coastguard Worker (pEscapeSequenceInfo[codewordOffset] & MASK_ESCAPE_PREFIX_UP) >>
1493*e5436536SAndroid Build Coastguard Worker LSB_ESCAPE_PREFIX_UP;
1494*e5436536SAndroid Build Coastguard Worker
1495*e5436536SAndroid Build Coastguard Worker /* step 2 */
1496*e5436536SAndroid Build Coastguard Worker /* calculate escape value */
1497*e5436536SAndroid Build Coastguard Worker pResultBase[iQSC] =
1498*e5436536SAndroid Build Coastguard Worker (FIXP_DBL)(sign * (((INT)1 << escapePrefixUp) + (INT)escapeWord));
1499*e5436536SAndroid Build Coastguard Worker
1500*e5436536SAndroid Build Coastguard Worker /* get both flags from sideinfo (flags are not shifted to the
1501*e5436536SAndroid Build Coastguard Worker * lsb-position) */
1502*e5436536SAndroid Build Coastguard Worker flagA = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_A;
1503*e5436536SAndroid Build Coastguard Worker flagB = pEscapeSequenceInfo[codewordOffset] & MASK_FLAG_B;
1504*e5436536SAndroid Build Coastguard Worker
1505*e5436536SAndroid Build Coastguard Worker /* step 3 */
1506*e5436536SAndroid Build Coastguard Worker /* clear the whole escape sideinfo word */
1507*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] = 0;
1508*e5436536SAndroid Build Coastguard Worker
1509*e5436536SAndroid Build Coastguard Worker /* change state in dependence of flag flagB */
1510*e5436536SAndroid Build Coastguard Worker if (flagA != 0) {
1511*e5436536SAndroid Build Coastguard Worker /* first escape sequence decoded; previous decoded 16 has been replaced
1512*e5436536SAndroid Build Coastguard Worker * by valid line */
1513*e5436536SAndroid Build Coastguard Worker
1514*e5436536SAndroid Build Coastguard Worker /* clear flagA in sideinfo word because this escape sequence has already
1515*e5436536SAndroid Build Coastguard Worker * beed decoded */
1516*e5436536SAndroid Build Coastguard Worker pEscapeSequenceInfo[codewordOffset] &= ~MASK_FLAG_A;
1517*e5436536SAndroid Build Coastguard Worker
1518*e5436536SAndroid Build Coastguard Worker if (flagB == 0) {
1519*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
1520*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield
1521*e5436536SAndroid Build Coastguard Worker and switch off
1522*e5436536SAndroid Build Coastguard Worker statemachine */
1523*e5436536SAndroid Build Coastguard Worker } else {
1524*e5436536SAndroid Build Coastguard Worker /* updated pointer to next and last 16 */
1525*e5436536SAndroid Build Coastguard Worker iQSC++;
1526*e5436536SAndroid Build Coastguard Worker iResultPointer[codewordOffset] = iQSC;
1527*e5436536SAndroid Build Coastguard Worker
1528*e5436536SAndroid Build Coastguard Worker /* change state */
1529*e5436536SAndroid Build Coastguard Worker pSta[codewordOffset] = BODY_SIGN_ESC__ESC_PREFIX;
1530*e5436536SAndroid Build Coastguard Worker pHcr->nonPcwSideinfo.pState =
1531*e5436536SAndroid Build Coastguard Worker aStateConstant2State[pSta[codewordOffset]]; /* get state from
1532*e5436536SAndroid Build Coastguard Worker separate array of
1533*e5436536SAndroid Build Coastguard Worker cw-sideinfo */
1534*e5436536SAndroid Build Coastguard Worker }
1535*e5436536SAndroid Build Coastguard Worker } else {
1536*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(
1537*e5436536SAndroid Build Coastguard Worker &(pHcr->nonPcwSideinfo.pState), segmentOffset,
1538*e5436536SAndroid Build Coastguard Worker pCodewordBitfield); /* clear a bit in bitfield and switch off
1539*e5436536SAndroid Build Coastguard Worker statemachine */
1540*e5436536SAndroid Build Coastguard Worker }
1541*e5436536SAndroid Build Coastguard Worker break;
1542*e5436536SAndroid Build Coastguard Worker }
1543*e5436536SAndroid Build Coastguard Worker }
1544*e5436536SAndroid Build Coastguard Worker
1545*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] <= 0) {
1546*e5436536SAndroid Build Coastguard Worker ClearBitFromBitfield(&(pHcr->nonPcwSideinfo.pState), segmentOffset,
1547*e5436536SAndroid Build Coastguard Worker pSegmentBitfield); /* clear a bit in bitfield and
1548*e5436536SAndroid Build Coastguard Worker switch off statemachine */
1549*e5436536SAndroid Build Coastguard Worker
1550*e5436536SAndroid Build Coastguard Worker if (pRemainingBitsInSegment[segmentOffset] < 0) {
1551*e5436536SAndroid Build Coastguard Worker pHcr->decInOut.errorLog |= STATE_ERROR_BODY_SIGN_ESC__ESC_WORD;
1552*e5436536SAndroid Build Coastguard Worker return BODY_SIGN_ESC__ESC_WORD;
1553*e5436536SAndroid Build Coastguard Worker }
1554*e5436536SAndroid Build Coastguard Worker }
1555*e5436536SAndroid Build Coastguard Worker
1556*e5436536SAndroid Build Coastguard Worker return STOP_THIS_STATE;
1557*e5436536SAndroid Build Coastguard Worker }
1558