xref: /aosp_15_r20/external/aac/libFDK/src/nlc_dec.cpp (revision e54365361535b070c2db7374cec45c159c7d0e7a)
1*e5436536SAndroid Build Coastguard Worker /* -----------------------------------------------------------------------------
2*e5436536SAndroid Build Coastguard Worker Software License for The Fraunhofer FDK AAC Codec Library for Android
3*e5436536SAndroid Build Coastguard Worker 
4*e5436536SAndroid Build Coastguard Worker © Copyright  1995 - 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 /******************* Library for basic calculation routines ********************
96*e5436536SAndroid Build Coastguard Worker 
97*e5436536SAndroid Build Coastguard Worker    Author(s):   Omer Osman
98*e5436536SAndroid Build Coastguard Worker 
99*e5436536SAndroid Build Coastguard Worker    Description: SAC/SAOC Dec Noiseless Coding
100*e5436536SAndroid Build Coastguard Worker 
101*e5436536SAndroid Build Coastguard Worker *******************************************************************************/
102*e5436536SAndroid Build Coastguard Worker 
103*e5436536SAndroid Build Coastguard Worker #include "nlc_dec.h"
104*e5436536SAndroid Build Coastguard Worker #include "FDK_tools_rom.h"
105*e5436536SAndroid Build Coastguard Worker 
106*e5436536SAndroid Build Coastguard Worker /* MAX_PARAMETER_BANDS defines array length in huffdec */
107*e5436536SAndroid Build Coastguard Worker 
108*e5436536SAndroid Build Coastguard Worker #ifndef min
109*e5436536SAndroid Build Coastguard Worker #define min(a, b) (((a) < (b)) ? (a) : (b))
110*e5436536SAndroid Build Coastguard Worker #endif
111*e5436536SAndroid Build Coastguard Worker 
sym_restoreIPD(HANDLE_FDK_BITSTREAM strm,int lav,SCHAR data[2])112*e5436536SAndroid Build Coastguard Worker ERROR_t sym_restoreIPD(HANDLE_FDK_BITSTREAM strm, int lav, SCHAR data[2]) {
113*e5436536SAndroid Build Coastguard Worker   int sum_val = data[0] + data[1];
114*e5436536SAndroid Build Coastguard Worker   int diff_val = data[0] - data[1];
115*e5436536SAndroid Build Coastguard Worker 
116*e5436536SAndroid Build Coastguard Worker   if (sum_val > lav) {
117*e5436536SAndroid Build Coastguard Worker     data[0] = -sum_val + (2 * lav + 1);
118*e5436536SAndroid Build Coastguard Worker     data[1] = -diff_val;
119*e5436536SAndroid Build Coastguard Worker   } else {
120*e5436536SAndroid Build Coastguard Worker     data[0] = sum_val;
121*e5436536SAndroid Build Coastguard Worker     data[1] = diff_val;
122*e5436536SAndroid Build Coastguard Worker   }
123*e5436536SAndroid Build Coastguard Worker 
124*e5436536SAndroid Build Coastguard Worker   if (data[0] - data[1] != 0) {
125*e5436536SAndroid Build Coastguard Worker     ULONG sym_bit;
126*e5436536SAndroid Build Coastguard Worker     sym_bit = FDKreadBits(strm, 1);
127*e5436536SAndroid Build Coastguard Worker     if (sym_bit) {
128*e5436536SAndroid Build Coastguard Worker       int tmp;
129*e5436536SAndroid Build Coastguard Worker       tmp = data[0];
130*e5436536SAndroid Build Coastguard Worker       data[0] = data[1];
131*e5436536SAndroid Build Coastguard Worker       data[1] = tmp;
132*e5436536SAndroid Build Coastguard Worker     }
133*e5436536SAndroid Build Coastguard Worker   }
134*e5436536SAndroid Build Coastguard Worker 
135*e5436536SAndroid Build Coastguard Worker   return HUFFDEC_OK;
136*e5436536SAndroid Build Coastguard Worker }
137*e5436536SAndroid Build Coastguard Worker 
ilog2(unsigned int i)138*e5436536SAndroid Build Coastguard Worker static int ilog2(unsigned int i) {
139*e5436536SAndroid Build Coastguard Worker   int l = 0;
140*e5436536SAndroid Build Coastguard Worker 
141*e5436536SAndroid Build Coastguard Worker   if (i) i--;
142*e5436536SAndroid Build Coastguard Worker   while (i > 0) {
143*e5436536SAndroid Build Coastguard Worker     i >>= 1;
144*e5436536SAndroid Build Coastguard Worker     l++;
145*e5436536SAndroid Build Coastguard Worker   }
146*e5436536SAndroid Build Coastguard Worker 
147*e5436536SAndroid Build Coastguard Worker   return l;
148*e5436536SAndroid Build Coastguard Worker }
149*e5436536SAndroid Build Coastguard Worker 
pcm_decode(HANDLE_FDK_BITSTREAM strm,SCHAR * out_data_1,SCHAR * out_data_2,int offset,int num_val,int num_levels)150*e5436536SAndroid Build Coastguard Worker static ERROR_t pcm_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
151*e5436536SAndroid Build Coastguard Worker                           SCHAR* out_data_2, int offset, int num_val,
152*e5436536SAndroid Build Coastguard Worker                           int num_levels) {
153*e5436536SAndroid Build Coastguard Worker   int i = 0, j = 0, idx = 0;
154*e5436536SAndroid Build Coastguard Worker   int max_grp_len = 0, next_val = 0;
155*e5436536SAndroid Build Coastguard Worker   ULONG tmp;
156*e5436536SAndroid Build Coastguard Worker 
157*e5436536SAndroid Build Coastguard Worker   int pcm_chunk_size[7] = {0};
158*e5436536SAndroid Build Coastguard Worker 
159*e5436536SAndroid Build Coastguard Worker   switch (num_levels) {
160*e5436536SAndroid Build Coastguard Worker     case 3:
161*e5436536SAndroid Build Coastguard Worker       max_grp_len = 5;
162*e5436536SAndroid Build Coastguard Worker       break;
163*e5436536SAndroid Build Coastguard Worker     case 7:
164*e5436536SAndroid Build Coastguard Worker       max_grp_len = 6;
165*e5436536SAndroid Build Coastguard Worker       break;
166*e5436536SAndroid Build Coastguard Worker     case 11:
167*e5436536SAndroid Build Coastguard Worker       max_grp_len = 2;
168*e5436536SAndroid Build Coastguard Worker       break;
169*e5436536SAndroid Build Coastguard Worker     case 13:
170*e5436536SAndroid Build Coastguard Worker       max_grp_len = 4;
171*e5436536SAndroid Build Coastguard Worker       break;
172*e5436536SAndroid Build Coastguard Worker     case 19:
173*e5436536SAndroid Build Coastguard Worker       max_grp_len = 4;
174*e5436536SAndroid Build Coastguard Worker       break;
175*e5436536SAndroid Build Coastguard Worker     case 25:
176*e5436536SAndroid Build Coastguard Worker       max_grp_len = 3;
177*e5436536SAndroid Build Coastguard Worker       break;
178*e5436536SAndroid Build Coastguard Worker     case 51:
179*e5436536SAndroid Build Coastguard Worker       max_grp_len = 4;
180*e5436536SAndroid Build Coastguard Worker       break;
181*e5436536SAndroid Build Coastguard Worker     case 4:
182*e5436536SAndroid Build Coastguard Worker     case 8:
183*e5436536SAndroid Build Coastguard Worker     case 15:
184*e5436536SAndroid Build Coastguard Worker     case 16:
185*e5436536SAndroid Build Coastguard Worker     case 26:
186*e5436536SAndroid Build Coastguard Worker     case 31:
187*e5436536SAndroid Build Coastguard Worker       max_grp_len = 1;
188*e5436536SAndroid Build Coastguard Worker       break;
189*e5436536SAndroid Build Coastguard Worker     default:
190*e5436536SAndroid Build Coastguard Worker       return HUFFDEC_NOTOK;
191*e5436536SAndroid Build Coastguard Worker   }
192*e5436536SAndroid Build Coastguard Worker 
193*e5436536SAndroid Build Coastguard Worker   tmp = 1;
194*e5436536SAndroid Build Coastguard Worker   for (i = 1; i <= max_grp_len; i++) {
195*e5436536SAndroid Build Coastguard Worker     tmp *= num_levels;
196*e5436536SAndroid Build Coastguard Worker     pcm_chunk_size[i] = ilog2(tmp);
197*e5436536SAndroid Build Coastguard Worker   }
198*e5436536SAndroid Build Coastguard Worker 
199*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < num_val; i += max_grp_len) {
200*e5436536SAndroid Build Coastguard Worker     int grp_len, grp_val, data;
201*e5436536SAndroid Build Coastguard Worker     grp_len = min(max_grp_len, num_val - i);
202*e5436536SAndroid Build Coastguard Worker     data = FDKreadBits(strm, pcm_chunk_size[grp_len]);
203*e5436536SAndroid Build Coastguard Worker 
204*e5436536SAndroid Build Coastguard Worker     grp_val = data;
205*e5436536SAndroid Build Coastguard Worker 
206*e5436536SAndroid Build Coastguard Worker     for (j = 0; j < grp_len; j++) {
207*e5436536SAndroid Build Coastguard Worker       idx = i + (grp_len - j - 1);
208*e5436536SAndroid Build Coastguard Worker       next_val = grp_val % num_levels;
209*e5436536SAndroid Build Coastguard Worker 
210*e5436536SAndroid Build Coastguard Worker       if (out_data_2 == NULL) {
211*e5436536SAndroid Build Coastguard Worker         out_data_1[idx] = next_val - offset;
212*e5436536SAndroid Build Coastguard Worker       } else if (out_data_1 == NULL) {
213*e5436536SAndroid Build Coastguard Worker         out_data_2[idx] = next_val - offset;
214*e5436536SAndroid Build Coastguard Worker       } else {
215*e5436536SAndroid Build Coastguard Worker         if (idx % 2) {
216*e5436536SAndroid Build Coastguard Worker           out_data_2[idx / 2] = next_val - offset;
217*e5436536SAndroid Build Coastguard Worker         } else {
218*e5436536SAndroid Build Coastguard Worker           out_data_1[idx / 2] = next_val - offset;
219*e5436536SAndroid Build Coastguard Worker         }
220*e5436536SAndroid Build Coastguard Worker       }
221*e5436536SAndroid Build Coastguard Worker 
222*e5436536SAndroid Build Coastguard Worker       grp_val = (grp_val - next_val) / num_levels;
223*e5436536SAndroid Build Coastguard Worker     }
224*e5436536SAndroid Build Coastguard Worker   }
225*e5436536SAndroid Build Coastguard Worker 
226*e5436536SAndroid Build Coastguard Worker   return HUFFDEC_OK;
227*e5436536SAndroid Build Coastguard Worker }
228*e5436536SAndroid Build Coastguard Worker 
huff_read(HANDLE_FDK_BITSTREAM strm,const SHORT (* nodeTab)[MAX_ENTRIES][2],int * out_data)229*e5436536SAndroid Build Coastguard Worker static ERROR_t huff_read(HANDLE_FDK_BITSTREAM strm,
230*e5436536SAndroid Build Coastguard Worker                          const SHORT (*nodeTab)[MAX_ENTRIES][2],
231*e5436536SAndroid Build Coastguard Worker                          int* out_data) {
232*e5436536SAndroid Build Coastguard Worker   int node = 0;
233*e5436536SAndroid Build Coastguard Worker   int len = 0;
234*e5436536SAndroid Build Coastguard Worker 
235*e5436536SAndroid Build Coastguard Worker   do {
236*e5436536SAndroid Build Coastguard Worker     ULONG next_bit;
237*e5436536SAndroid Build Coastguard Worker     next_bit = FDKreadBits(strm, 1);
238*e5436536SAndroid Build Coastguard Worker     len++;
239*e5436536SAndroid Build Coastguard Worker     node = (*nodeTab)[node][next_bit];
240*e5436536SAndroid Build Coastguard Worker   } while (node > 0);
241*e5436536SAndroid Build Coastguard Worker 
242*e5436536SAndroid Build Coastguard Worker   *out_data = node;
243*e5436536SAndroid Build Coastguard Worker 
244*e5436536SAndroid Build Coastguard Worker   return HUFFDEC_OK;
245*e5436536SAndroid Build Coastguard Worker }
246*e5436536SAndroid Build Coastguard Worker 
huff_read_2D(HANDLE_FDK_BITSTREAM strm,const SHORT (* nodeTab)[MAX_ENTRIES][2],SCHAR out_data[2],int * escape)247*e5436536SAndroid Build Coastguard Worker static ERROR_t huff_read_2D(HANDLE_FDK_BITSTREAM strm,
248*e5436536SAndroid Build Coastguard Worker                             const SHORT (*nodeTab)[MAX_ENTRIES][2],
249*e5436536SAndroid Build Coastguard Worker                             SCHAR out_data[2], int* escape) {
250*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
251*e5436536SAndroid Build Coastguard Worker 
252*e5436536SAndroid Build Coastguard Worker   int huff_2D_8bit = 0;
253*e5436536SAndroid Build Coastguard Worker   int node = 0;
254*e5436536SAndroid Build Coastguard Worker 
255*e5436536SAndroid Build Coastguard Worker   if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
256*e5436536SAndroid Build Coastguard Worker     goto bail;
257*e5436536SAndroid Build Coastguard Worker   }
258*e5436536SAndroid Build Coastguard Worker   *escape = (node == 0);
259*e5436536SAndroid Build Coastguard Worker 
260*e5436536SAndroid Build Coastguard Worker   if (*escape) {
261*e5436536SAndroid Build Coastguard Worker     out_data[0] = 0;
262*e5436536SAndroid Build Coastguard Worker     out_data[1] = 1;
263*e5436536SAndroid Build Coastguard Worker   } else {
264*e5436536SAndroid Build Coastguard Worker     huff_2D_8bit = -(node + 1);
265*e5436536SAndroid Build Coastguard Worker     out_data[0] = huff_2D_8bit >> 4;
266*e5436536SAndroid Build Coastguard Worker     out_data[1] = huff_2D_8bit & 0xf;
267*e5436536SAndroid Build Coastguard Worker   }
268*e5436536SAndroid Build Coastguard Worker 
269*e5436536SAndroid Build Coastguard Worker bail:
270*e5436536SAndroid Build Coastguard Worker   return err;
271*e5436536SAndroid Build Coastguard Worker }
272*e5436536SAndroid Build Coastguard Worker 
sym_restore(HANDLE_FDK_BITSTREAM strm,int lav,SCHAR data[2])273*e5436536SAndroid Build Coastguard Worker static ERROR_t sym_restore(HANDLE_FDK_BITSTREAM strm, int lav, SCHAR data[2]) {
274*e5436536SAndroid Build Coastguard Worker   ULONG sym_bit = 0;
275*e5436536SAndroid Build Coastguard Worker 
276*e5436536SAndroid Build Coastguard Worker   int sum_val = data[0] + data[1];
277*e5436536SAndroid Build Coastguard Worker   int diff_val = data[0] - data[1];
278*e5436536SAndroid Build Coastguard Worker 
279*e5436536SAndroid Build Coastguard Worker   if (sum_val > lav) {
280*e5436536SAndroid Build Coastguard Worker     data[0] = -sum_val + (2 * lav + 1);
281*e5436536SAndroid Build Coastguard Worker     data[1] = -diff_val;
282*e5436536SAndroid Build Coastguard Worker   } else {
283*e5436536SAndroid Build Coastguard Worker     data[0] = sum_val;
284*e5436536SAndroid Build Coastguard Worker     data[1] = diff_val;
285*e5436536SAndroid Build Coastguard Worker   }
286*e5436536SAndroid Build Coastguard Worker 
287*e5436536SAndroid Build Coastguard Worker   if (data[0] + data[1] != 0) {
288*e5436536SAndroid Build Coastguard Worker     sym_bit = FDKreadBits(strm, 1);
289*e5436536SAndroid Build Coastguard Worker     if (sym_bit) {
290*e5436536SAndroid Build Coastguard Worker       data[0] = -data[0];
291*e5436536SAndroid Build Coastguard Worker       data[1] = -data[1];
292*e5436536SAndroid Build Coastguard Worker     }
293*e5436536SAndroid Build Coastguard Worker   }
294*e5436536SAndroid Build Coastguard Worker 
295*e5436536SAndroid Build Coastguard Worker   if (data[0] - data[1] != 0) {
296*e5436536SAndroid Build Coastguard Worker     sym_bit = FDKreadBits(strm, 1);
297*e5436536SAndroid Build Coastguard Worker     if (sym_bit) {
298*e5436536SAndroid Build Coastguard Worker       int tmp;
299*e5436536SAndroid Build Coastguard Worker       tmp = data[0];
300*e5436536SAndroid Build Coastguard Worker       data[0] = data[1];
301*e5436536SAndroid Build Coastguard Worker       data[1] = tmp;
302*e5436536SAndroid Build Coastguard Worker     }
303*e5436536SAndroid Build Coastguard Worker   }
304*e5436536SAndroid Build Coastguard Worker 
305*e5436536SAndroid Build Coastguard Worker   return HUFFDEC_OK;
306*e5436536SAndroid Build Coastguard Worker }
307*e5436536SAndroid Build Coastguard Worker 
huff_dec_1D(HANDLE_FDK_BITSTREAM strm,const DATA_TYPE data_type,const INT dim1,SCHAR * out_data,const INT num_val,const INT p0_flag)308*e5436536SAndroid Build Coastguard Worker static ERROR_t huff_dec_1D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
309*e5436536SAndroid Build Coastguard Worker                            const INT dim1, SCHAR* out_data, const INT num_val,
310*e5436536SAndroid Build Coastguard Worker                            const INT p0_flag)
311*e5436536SAndroid Build Coastguard Worker 
312*e5436536SAndroid Build Coastguard Worker {
313*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
314*e5436536SAndroid Build Coastguard Worker   int i = 0, node = 0, offset = 0;
315*e5436536SAndroid Build Coastguard Worker   int od = 0, od_sign = 0;
316*e5436536SAndroid Build Coastguard Worker   ULONG data = 0;
317*e5436536SAndroid Build Coastguard Worker   int bitsAvail = 0;
318*e5436536SAndroid Build Coastguard Worker 
319*e5436536SAndroid Build Coastguard Worker   const SHORT(*partTab)[MAX_ENTRIES][2] = NULL;
320*e5436536SAndroid Build Coastguard Worker   const SHORT(*nodeTab)[MAX_ENTRIES][2] = NULL;
321*e5436536SAndroid Build Coastguard Worker 
322*e5436536SAndroid Build Coastguard Worker   switch (data_type) {
323*e5436536SAndroid Build Coastguard Worker     case t_CLD:
324*e5436536SAndroid Build Coastguard Worker       partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.cld[0][0];
325*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h1D[dim1]->nodeTab[0][0];
326*e5436536SAndroid Build Coastguard Worker       break;
327*e5436536SAndroid Build Coastguard Worker     case t_ICC:
328*e5436536SAndroid Build Coastguard Worker       partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.icc[0][0];
329*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h1D[dim1]->nodeTab[0][0];
330*e5436536SAndroid Build Coastguard Worker       break;
331*e5436536SAndroid Build Coastguard Worker     case t_OLD:
332*e5436536SAndroid Build Coastguard Worker       partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.old[0][0];
333*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h1D[dim1]->nodeTab[0][0];
334*e5436536SAndroid Build Coastguard Worker       break;
335*e5436536SAndroid Build Coastguard Worker     case t_IPD:
336*e5436536SAndroid Build Coastguard Worker       partTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.ipd[0][0];
337*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h1D[dim1].nodeTab[0][0];
338*e5436536SAndroid Build Coastguard Worker       break;
339*e5436536SAndroid Build Coastguard Worker     default:
340*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(0);
341*e5436536SAndroid Build Coastguard Worker       err = HUFFDEC_NOTOK;
342*e5436536SAndroid Build Coastguard Worker       goto bail;
343*e5436536SAndroid Build Coastguard Worker   }
344*e5436536SAndroid Build Coastguard Worker 
345*e5436536SAndroid Build Coastguard Worker   if (p0_flag) {
346*e5436536SAndroid Build Coastguard Worker     if ((err = huff_read(strm, partTab, &node)) != HUFFDEC_OK) {
347*e5436536SAndroid Build Coastguard Worker       goto bail;
348*e5436536SAndroid Build Coastguard Worker     }
349*e5436536SAndroid Build Coastguard Worker 
350*e5436536SAndroid Build Coastguard Worker     out_data[0] = -(node + 1);
351*e5436536SAndroid Build Coastguard Worker     offset = 1;
352*e5436536SAndroid Build Coastguard Worker   }
353*e5436536SAndroid Build Coastguard Worker 
354*e5436536SAndroid Build Coastguard Worker   for (i = offset; i < num_val; i++) {
355*e5436536SAndroid Build Coastguard Worker     bitsAvail = FDKgetValidBits(strm);
356*e5436536SAndroid Build Coastguard Worker     if (bitsAvail < 1) {
357*e5436536SAndroid Build Coastguard Worker       err = HUFFDEC_NOTOK;
358*e5436536SAndroid Build Coastguard Worker       goto bail;
359*e5436536SAndroid Build Coastguard Worker     }
360*e5436536SAndroid Build Coastguard Worker 
361*e5436536SAndroid Build Coastguard Worker     if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
362*e5436536SAndroid Build Coastguard Worker       goto bail;
363*e5436536SAndroid Build Coastguard Worker     }
364*e5436536SAndroid Build Coastguard Worker     od = -(node + 1);
365*e5436536SAndroid Build Coastguard Worker 
366*e5436536SAndroid Build Coastguard Worker     if (data_type != t_IPD) {
367*e5436536SAndroid Build Coastguard Worker       if (od != 0) {
368*e5436536SAndroid Build Coastguard Worker         bitsAvail = FDKgetValidBits(strm);
369*e5436536SAndroid Build Coastguard Worker         if (bitsAvail < 1) {
370*e5436536SAndroid Build Coastguard Worker           err = HUFFDEC_NOTOK;
371*e5436536SAndroid Build Coastguard Worker           goto bail;
372*e5436536SAndroid Build Coastguard Worker         }
373*e5436536SAndroid Build Coastguard Worker 
374*e5436536SAndroid Build Coastguard Worker         data = FDKreadBits(strm, 1);
375*e5436536SAndroid Build Coastguard Worker         od_sign = data;
376*e5436536SAndroid Build Coastguard Worker 
377*e5436536SAndroid Build Coastguard Worker         if (od_sign) od = -od;
378*e5436536SAndroid Build Coastguard Worker       }
379*e5436536SAndroid Build Coastguard Worker     }
380*e5436536SAndroid Build Coastguard Worker 
381*e5436536SAndroid Build Coastguard Worker     out_data[i] = od;
382*e5436536SAndroid Build Coastguard Worker   }
383*e5436536SAndroid Build Coastguard Worker 
384*e5436536SAndroid Build Coastguard Worker bail:
385*e5436536SAndroid Build Coastguard Worker   return err;
386*e5436536SAndroid Build Coastguard Worker }
387*e5436536SAndroid Build Coastguard Worker 
huff_dec_2D(HANDLE_FDK_BITSTREAM strm,const DATA_TYPE data_type,const INT dim1,const INT dim2,SCHAR out_data[][2],const INT num_val,const INT stride,SCHAR * p0_data[2])388*e5436536SAndroid Build Coastguard Worker static ERROR_t huff_dec_2D(HANDLE_FDK_BITSTREAM strm, const DATA_TYPE data_type,
389*e5436536SAndroid Build Coastguard Worker                            const INT dim1, const INT dim2, SCHAR out_data[][2],
390*e5436536SAndroid Build Coastguard Worker                            const INT num_val, const INT stride,
391*e5436536SAndroid Build Coastguard Worker                            SCHAR* p0_data[2]) {
392*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
393*e5436536SAndroid Build Coastguard Worker   int i = 0, lav = 0, escape = 0, escCntr = 0;
394*e5436536SAndroid Build Coastguard Worker   int node = 0;
395*e5436536SAndroid Build Coastguard Worker   unsigned long data = 0;
396*e5436536SAndroid Build Coastguard Worker 
397*e5436536SAndroid Build Coastguard Worker   SCHAR esc_data[2][28] = {{0}};
398*e5436536SAndroid Build Coastguard Worker   int escIdx[28] = {0};
399*e5436536SAndroid Build Coastguard Worker   const SHORT(*nodeTab)[MAX_ENTRIES][2] = NULL;
400*e5436536SAndroid Build Coastguard Worker 
401*e5436536SAndroid Build Coastguard Worker   /* LAV */
402*e5436536SAndroid Build Coastguard Worker   if ((err =
403*e5436536SAndroid Build Coastguard Worker            huff_read(strm, (HANDLE_HUFF_NODE)&FDK_huffLavIdxNodes.nodeTab[0][0],
404*e5436536SAndroid Build Coastguard Worker                      &node)) != HUFFDEC_OK) {
405*e5436536SAndroid Build Coastguard Worker     goto bail;
406*e5436536SAndroid Build Coastguard Worker   }
407*e5436536SAndroid Build Coastguard Worker   data = -(node + 1);
408*e5436536SAndroid Build Coastguard Worker 
409*e5436536SAndroid Build Coastguard Worker   switch (data_type) {
410*e5436536SAndroid Build Coastguard Worker     case t_CLD:
411*e5436536SAndroid Build Coastguard Worker       lav = 2 * data + 3; /* 3, 5, 7, 9 */
412*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.cld[0][0];
413*e5436536SAndroid Build Coastguard Worker       break;
414*e5436536SAndroid Build Coastguard Worker     case t_ICC:
415*e5436536SAndroid Build Coastguard Worker       lav = 2 * data + 1; /* 1, 3, 5, 7 */
416*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.icc[0][0];
417*e5436536SAndroid Build Coastguard Worker       break;
418*e5436536SAndroid Build Coastguard Worker     case t_OLD:
419*e5436536SAndroid Build Coastguard Worker       lav = 3 * data + 3;
420*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.old[0][0];
421*e5436536SAndroid Build Coastguard Worker       break;
422*e5436536SAndroid Build Coastguard Worker     case t_IPD:
423*e5436536SAndroid Build Coastguard Worker       if (data == 0)
424*e5436536SAndroid Build Coastguard Worker         data = 3;
425*e5436536SAndroid Build Coastguard Worker       else
426*e5436536SAndroid Build Coastguard Worker         data--;
427*e5436536SAndroid Build Coastguard Worker       lav = 2 * data + 1; /* 1, 3, 5, 7 */
428*e5436536SAndroid Build Coastguard Worker       nodeTab = (HANDLE_HUFF_NODE)&FDK_huffPart0Nodes.ipd[0][0];
429*e5436536SAndroid Build Coastguard Worker       break;
430*e5436536SAndroid Build Coastguard Worker     default:
431*e5436536SAndroid Build Coastguard Worker       FDK_ASSERT(0);
432*e5436536SAndroid Build Coastguard Worker       err = HUFFDEC_NOTOK;
433*e5436536SAndroid Build Coastguard Worker       goto bail;
434*e5436536SAndroid Build Coastguard Worker   }
435*e5436536SAndroid Build Coastguard Worker 
436*e5436536SAndroid Build Coastguard Worker   /* Partition 0 */
437*e5436536SAndroid Build Coastguard Worker   if (p0_data[0] != NULL) {
438*e5436536SAndroid Build Coastguard Worker     if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
439*e5436536SAndroid Build Coastguard Worker       goto bail;
440*e5436536SAndroid Build Coastguard Worker     }
441*e5436536SAndroid Build Coastguard Worker     *p0_data[0] = -(node + 1);
442*e5436536SAndroid Build Coastguard Worker   }
443*e5436536SAndroid Build Coastguard Worker   if (p0_data[1] != NULL) {
444*e5436536SAndroid Build Coastguard Worker     if ((err = huff_read(strm, nodeTab, &node)) != HUFFDEC_OK) {
445*e5436536SAndroid Build Coastguard Worker       goto bail;
446*e5436536SAndroid Build Coastguard Worker     }
447*e5436536SAndroid Build Coastguard Worker     *p0_data[1] = -(node + 1);
448*e5436536SAndroid Build Coastguard Worker   }
449*e5436536SAndroid Build Coastguard Worker 
450*e5436536SAndroid Build Coastguard Worker   switch (data_type) {
451*e5436536SAndroid Build Coastguard Worker     case t_CLD:
452*e5436536SAndroid Build Coastguard Worker       switch (lav) {
453*e5436536SAndroid Build Coastguard Worker         case 3:
454*e5436536SAndroid Build Coastguard Worker           nodeTab =
455*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav3[0][0];
456*e5436536SAndroid Build Coastguard Worker           break;
457*e5436536SAndroid Build Coastguard Worker         case 5:
458*e5436536SAndroid Build Coastguard Worker           nodeTab =
459*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav5[0][0];
460*e5436536SAndroid Build Coastguard Worker           break;
461*e5436536SAndroid Build Coastguard Worker         case 7:
462*e5436536SAndroid Build Coastguard Worker           nodeTab =
463*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav7[0][0];
464*e5436536SAndroid Build Coastguard Worker           break;
465*e5436536SAndroid Build Coastguard Worker         case 9:
466*e5436536SAndroid Build Coastguard Worker           nodeTab =
467*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffCLDNodes.h2D[dim1][dim2]->lav9[0][0];
468*e5436536SAndroid Build Coastguard Worker           break;
469*e5436536SAndroid Build Coastguard Worker       }
470*e5436536SAndroid Build Coastguard Worker       break;
471*e5436536SAndroid Build Coastguard Worker     case t_ICC:
472*e5436536SAndroid Build Coastguard Worker       switch (lav) {
473*e5436536SAndroid Build Coastguard Worker         case 1:
474*e5436536SAndroid Build Coastguard Worker           nodeTab =
475*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav1[0][0];
476*e5436536SAndroid Build Coastguard Worker           break;
477*e5436536SAndroid Build Coastguard Worker         case 3:
478*e5436536SAndroid Build Coastguard Worker           nodeTab =
479*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav3[0][0];
480*e5436536SAndroid Build Coastguard Worker           break;
481*e5436536SAndroid Build Coastguard Worker         case 5:
482*e5436536SAndroid Build Coastguard Worker           nodeTab =
483*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav5[0][0];
484*e5436536SAndroid Build Coastguard Worker           break;
485*e5436536SAndroid Build Coastguard Worker         case 7:
486*e5436536SAndroid Build Coastguard Worker           nodeTab =
487*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffICCNodes.h2D[dim1][dim2]->lav7[0][0];
488*e5436536SAndroid Build Coastguard Worker           break;
489*e5436536SAndroid Build Coastguard Worker       }
490*e5436536SAndroid Build Coastguard Worker       break;
491*e5436536SAndroid Build Coastguard Worker     case t_OLD:
492*e5436536SAndroid Build Coastguard Worker       switch (lav) {
493*e5436536SAndroid Build Coastguard Worker         case 3:
494*e5436536SAndroid Build Coastguard Worker           nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav3[0][0];
495*e5436536SAndroid Build Coastguard Worker           break;
496*e5436536SAndroid Build Coastguard Worker         case 6:
497*e5436536SAndroid Build Coastguard Worker           nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav6[0][0];
498*e5436536SAndroid Build Coastguard Worker           break;
499*e5436536SAndroid Build Coastguard Worker         case 9:
500*e5436536SAndroid Build Coastguard Worker           nodeTab = (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav9[0][0];
501*e5436536SAndroid Build Coastguard Worker           break;
502*e5436536SAndroid Build Coastguard Worker         case 12:
503*e5436536SAndroid Build Coastguard Worker           nodeTab =
504*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&huffOLDNodes.h2D[dim1][dim2]->lav12[0][0];
505*e5436536SAndroid Build Coastguard Worker           break;
506*e5436536SAndroid Build Coastguard Worker       }
507*e5436536SAndroid Build Coastguard Worker       break;
508*e5436536SAndroid Build Coastguard Worker     case t_IPD:
509*e5436536SAndroid Build Coastguard Worker       switch (lav) {
510*e5436536SAndroid Build Coastguard Worker         case 1:
511*e5436536SAndroid Build Coastguard Worker           nodeTab =
512*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav1[0][0];
513*e5436536SAndroid Build Coastguard Worker           break;
514*e5436536SAndroid Build Coastguard Worker         case 3:
515*e5436536SAndroid Build Coastguard Worker           nodeTab =
516*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav3[0][0];
517*e5436536SAndroid Build Coastguard Worker           break;
518*e5436536SAndroid Build Coastguard Worker         case 5:
519*e5436536SAndroid Build Coastguard Worker           nodeTab =
520*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav5[0][0];
521*e5436536SAndroid Build Coastguard Worker           break;
522*e5436536SAndroid Build Coastguard Worker         case 7:
523*e5436536SAndroid Build Coastguard Worker           nodeTab =
524*e5436536SAndroid Build Coastguard Worker               (HANDLE_HUFF_NODE)&FDK_huffIPDNodes.h2D[dim1][dim2].lav7[0][0];
525*e5436536SAndroid Build Coastguard Worker           break;
526*e5436536SAndroid Build Coastguard Worker       }
527*e5436536SAndroid Build Coastguard Worker       break;
528*e5436536SAndroid Build Coastguard Worker     default:
529*e5436536SAndroid Build Coastguard Worker       break;
530*e5436536SAndroid Build Coastguard Worker   }
531*e5436536SAndroid Build Coastguard Worker 
532*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < num_val; i += stride) {
533*e5436536SAndroid Build Coastguard Worker     if ((err = huff_read_2D(strm, nodeTab, out_data[i], &escape)) !=
534*e5436536SAndroid Build Coastguard Worker         HUFFDEC_OK) {
535*e5436536SAndroid Build Coastguard Worker       goto bail;
536*e5436536SAndroid Build Coastguard Worker     }
537*e5436536SAndroid Build Coastguard Worker 
538*e5436536SAndroid Build Coastguard Worker     if (escape) {
539*e5436536SAndroid Build Coastguard Worker       escIdx[escCntr++] = i;
540*e5436536SAndroid Build Coastguard Worker     } else {
541*e5436536SAndroid Build Coastguard Worker       if (data_type == t_IPD) {
542*e5436536SAndroid Build Coastguard Worker         if ((err = sym_restoreIPD(strm, lav, out_data[i])) != HUFFDEC_OK) {
543*e5436536SAndroid Build Coastguard Worker           goto bail;
544*e5436536SAndroid Build Coastguard Worker         }
545*e5436536SAndroid Build Coastguard Worker       } else {
546*e5436536SAndroid Build Coastguard Worker         if ((err = sym_restore(strm, lav, out_data[i])) != HUFFDEC_OK) {
547*e5436536SAndroid Build Coastguard Worker           goto bail;
548*e5436536SAndroid Build Coastguard Worker         }
549*e5436536SAndroid Build Coastguard Worker       }
550*e5436536SAndroid Build Coastguard Worker     }
551*e5436536SAndroid Build Coastguard Worker   } /* i */
552*e5436536SAndroid Build Coastguard Worker 
553*e5436536SAndroid Build Coastguard Worker   if (escCntr > 0) {
554*e5436536SAndroid Build Coastguard Worker     if ((err = pcm_decode(strm, esc_data[0], esc_data[1], 0, 2 * escCntr,
555*e5436536SAndroid Build Coastguard Worker                           (2 * lav + 1))) != HUFFDEC_OK) {
556*e5436536SAndroid Build Coastguard Worker       goto bail;
557*e5436536SAndroid Build Coastguard Worker     }
558*e5436536SAndroid Build Coastguard Worker 
559*e5436536SAndroid Build Coastguard Worker     for (i = 0; i < escCntr; i++) {
560*e5436536SAndroid Build Coastguard Worker       out_data[escIdx[i]][0] = esc_data[0][i] - lav;
561*e5436536SAndroid Build Coastguard Worker       out_data[escIdx[i]][1] = esc_data[1][i] - lav;
562*e5436536SAndroid Build Coastguard Worker     }
563*e5436536SAndroid Build Coastguard Worker   }
564*e5436536SAndroid Build Coastguard Worker bail:
565*e5436536SAndroid Build Coastguard Worker   return err;
566*e5436536SAndroid Build Coastguard Worker }
567*e5436536SAndroid Build Coastguard Worker 
huff_decode(HANDLE_FDK_BITSTREAM strm,SCHAR * out_data_1,SCHAR * out_data_2,DATA_TYPE data_type,DIFF_TYPE diff_type_1,DIFF_TYPE diff_type_2,int num_val,PAIRING * pairing_scheme,int ldMode)568*e5436536SAndroid Build Coastguard Worker static ERROR_t huff_decode(HANDLE_FDK_BITSTREAM strm, SCHAR* out_data_1,
569*e5436536SAndroid Build Coastguard Worker                            SCHAR* out_data_2, DATA_TYPE data_type,
570*e5436536SAndroid Build Coastguard Worker                            DIFF_TYPE diff_type_1, DIFF_TYPE diff_type_2,
571*e5436536SAndroid Build Coastguard Worker                            int num_val, PAIRING* pairing_scheme, int ldMode) {
572*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
573*e5436536SAndroid Build Coastguard Worker   CODING_SCHEME coding_scheme = HUFF_1D;
574*e5436536SAndroid Build Coastguard Worker   DIFF_TYPE diff_type;
575*e5436536SAndroid Build Coastguard Worker 
576*e5436536SAndroid Build Coastguard Worker   int i = 0;
577*e5436536SAndroid Build Coastguard Worker 
578*e5436536SAndroid Build Coastguard Worker   SCHAR pair_vec[28][2];
579*e5436536SAndroid Build Coastguard Worker 
580*e5436536SAndroid Build Coastguard Worker   SCHAR* p0_data_1[2] = {NULL, NULL};
581*e5436536SAndroid Build Coastguard Worker   SCHAR* p0_data_2[2] = {NULL, NULL};
582*e5436536SAndroid Build Coastguard Worker 
583*e5436536SAndroid Build Coastguard Worker   int p0_flag[2];
584*e5436536SAndroid Build Coastguard Worker 
585*e5436536SAndroid Build Coastguard Worker   int num_val_1_int = num_val;
586*e5436536SAndroid Build Coastguard Worker   int num_val_2_int = num_val;
587*e5436536SAndroid Build Coastguard Worker 
588*e5436536SAndroid Build Coastguard Worker   SCHAR* out_data_1_int = out_data_1;
589*e5436536SAndroid Build Coastguard Worker   SCHAR* out_data_2_int = out_data_2;
590*e5436536SAndroid Build Coastguard Worker 
591*e5436536SAndroid Build Coastguard Worker   int df_rest_flag_1 = 0;
592*e5436536SAndroid Build Coastguard Worker   int df_rest_flag_2 = 0;
593*e5436536SAndroid Build Coastguard Worker 
594*e5436536SAndroid Build Coastguard Worker   int hufYY1;
595*e5436536SAndroid Build Coastguard Worker   int hufYY2;
596*e5436536SAndroid Build Coastguard Worker   int hufYY;
597*e5436536SAndroid Build Coastguard Worker 
598*e5436536SAndroid Build Coastguard Worker   /* Coding scheme */
599*e5436536SAndroid Build Coastguard Worker   coding_scheme = (CODING_SCHEME)FDKreadBits(strm, 1);
600*e5436536SAndroid Build Coastguard Worker 
601*e5436536SAndroid Build Coastguard Worker   if (coding_scheme == HUFF_2D) {
602*e5436536SAndroid Build Coastguard Worker     if ((out_data_1 != NULL) && (out_data_2 != NULL) && (ldMode == 0)) {
603*e5436536SAndroid Build Coastguard Worker       *pairing_scheme = (PAIRING)FDKreadBits(strm, 1);
604*e5436536SAndroid Build Coastguard Worker     } else {
605*e5436536SAndroid Build Coastguard Worker       *pairing_scheme = FREQ_PAIR;
606*e5436536SAndroid Build Coastguard Worker     }
607*e5436536SAndroid Build Coastguard Worker   }
608*e5436536SAndroid Build Coastguard Worker 
609*e5436536SAndroid Build Coastguard Worker   {
610*e5436536SAndroid Build Coastguard Worker     hufYY1 = diff_type_1;
611*e5436536SAndroid Build Coastguard Worker     hufYY2 = diff_type_2;
612*e5436536SAndroid Build Coastguard Worker   }
613*e5436536SAndroid Build Coastguard Worker 
614*e5436536SAndroid Build Coastguard Worker   switch (coding_scheme) {
615*e5436536SAndroid Build Coastguard Worker     case HUFF_1D:
616*e5436536SAndroid Build Coastguard Worker       p0_flag[0] = (diff_type_1 == DIFF_FREQ);
617*e5436536SAndroid Build Coastguard Worker       p0_flag[1] = (diff_type_2 == DIFF_FREQ);
618*e5436536SAndroid Build Coastguard Worker       if (out_data_1 != NULL) {
619*e5436536SAndroid Build Coastguard Worker         if ((err = huff_dec_1D(strm, data_type, hufYY1, out_data_1,
620*e5436536SAndroid Build Coastguard Worker                                num_val_1_int, p0_flag[0])) != HUFFDEC_OK) {
621*e5436536SAndroid Build Coastguard Worker           goto bail;
622*e5436536SAndroid Build Coastguard Worker         }
623*e5436536SAndroid Build Coastguard Worker       }
624*e5436536SAndroid Build Coastguard Worker       if (out_data_2 != NULL) {
625*e5436536SAndroid Build Coastguard Worker         if ((err = huff_dec_1D(strm, data_type, hufYY2, out_data_2,
626*e5436536SAndroid Build Coastguard Worker                                num_val_2_int, p0_flag[1])) != HUFFDEC_OK) {
627*e5436536SAndroid Build Coastguard Worker           goto bail;
628*e5436536SAndroid Build Coastguard Worker         }
629*e5436536SAndroid Build Coastguard Worker       }
630*e5436536SAndroid Build Coastguard Worker 
631*e5436536SAndroid Build Coastguard Worker       break; /* HUFF_1D */
632*e5436536SAndroid Build Coastguard Worker 
633*e5436536SAndroid Build Coastguard Worker     case HUFF_2D:
634*e5436536SAndroid Build Coastguard Worker 
635*e5436536SAndroid Build Coastguard Worker       switch (*pairing_scheme) {
636*e5436536SAndroid Build Coastguard Worker         case FREQ_PAIR:
637*e5436536SAndroid Build Coastguard Worker 
638*e5436536SAndroid Build Coastguard Worker           if (out_data_1 != NULL) {
639*e5436536SAndroid Build Coastguard Worker             if (diff_type_1 == DIFF_FREQ) {
640*e5436536SAndroid Build Coastguard Worker               p0_data_1[0] = &out_data_1[0];
641*e5436536SAndroid Build Coastguard Worker               p0_data_1[1] = NULL;
642*e5436536SAndroid Build Coastguard Worker 
643*e5436536SAndroid Build Coastguard Worker               num_val_1_int -= 1;
644*e5436536SAndroid Build Coastguard Worker               out_data_1_int += 1;
645*e5436536SAndroid Build Coastguard Worker             }
646*e5436536SAndroid Build Coastguard Worker             df_rest_flag_1 = num_val_1_int % 2;
647*e5436536SAndroid Build Coastguard Worker             if (df_rest_flag_1) num_val_1_int -= 1;
648*e5436536SAndroid Build Coastguard Worker             if (num_val_1_int < 0) {
649*e5436536SAndroid Build Coastguard Worker               err = HUFFDEC_NOTOK;
650*e5436536SAndroid Build Coastguard Worker               goto bail;
651*e5436536SAndroid Build Coastguard Worker             }
652*e5436536SAndroid Build Coastguard Worker           }
653*e5436536SAndroid Build Coastguard Worker           if (out_data_2 != NULL) {
654*e5436536SAndroid Build Coastguard Worker             if (diff_type_2 == DIFF_FREQ) {
655*e5436536SAndroid Build Coastguard Worker               p0_data_2[0] = NULL;
656*e5436536SAndroid Build Coastguard Worker               p0_data_2[1] = &out_data_2[0];
657*e5436536SAndroid Build Coastguard Worker 
658*e5436536SAndroid Build Coastguard Worker               num_val_2_int -= 1;
659*e5436536SAndroid Build Coastguard Worker               out_data_2_int += 1;
660*e5436536SAndroid Build Coastguard Worker             }
661*e5436536SAndroid Build Coastguard Worker             df_rest_flag_2 = num_val_2_int % 2;
662*e5436536SAndroid Build Coastguard Worker             if (df_rest_flag_2) num_val_2_int -= 1;
663*e5436536SAndroid Build Coastguard Worker             if (num_val_2_int < 0) {
664*e5436536SAndroid Build Coastguard Worker               err = HUFFDEC_NOTOK;
665*e5436536SAndroid Build Coastguard Worker               goto bail;
666*e5436536SAndroid Build Coastguard Worker             }
667*e5436536SAndroid Build Coastguard Worker           }
668*e5436536SAndroid Build Coastguard Worker 
669*e5436536SAndroid Build Coastguard Worker           if (out_data_1 != NULL) {
670*e5436536SAndroid Build Coastguard Worker             if ((err = huff_dec_2D(strm, data_type, hufYY1, FREQ_PAIR, pair_vec,
671*e5436536SAndroid Build Coastguard Worker                                    num_val_1_int, 2, p0_data_1)) !=
672*e5436536SAndroid Build Coastguard Worker                 HUFFDEC_OK) {
673*e5436536SAndroid Build Coastguard Worker               goto bail;
674*e5436536SAndroid Build Coastguard Worker             }
675*e5436536SAndroid Build Coastguard Worker             if (df_rest_flag_1) {
676*e5436536SAndroid Build Coastguard Worker               if ((err = huff_dec_1D(strm, data_type, hufYY1,
677*e5436536SAndroid Build Coastguard Worker                                      out_data_1_int + num_val_1_int, 1, 0)) !=
678*e5436536SAndroid Build Coastguard Worker                   HUFFDEC_OK) {
679*e5436536SAndroid Build Coastguard Worker                 goto bail;
680*e5436536SAndroid Build Coastguard Worker               }
681*e5436536SAndroid Build Coastguard Worker             }
682*e5436536SAndroid Build Coastguard Worker           }
683*e5436536SAndroid Build Coastguard Worker           if (out_data_2 != NULL) {
684*e5436536SAndroid Build Coastguard Worker             if ((err = huff_dec_2D(strm, data_type, hufYY2, FREQ_PAIR,
685*e5436536SAndroid Build Coastguard Worker                                    pair_vec + 1, num_val_2_int, 2,
686*e5436536SAndroid Build Coastguard Worker                                    p0_data_2)) != HUFFDEC_OK) {
687*e5436536SAndroid Build Coastguard Worker               goto bail;
688*e5436536SAndroid Build Coastguard Worker             }
689*e5436536SAndroid Build Coastguard Worker             if (df_rest_flag_2) {
690*e5436536SAndroid Build Coastguard Worker               if ((err = huff_dec_1D(strm, data_type, hufYY2,
691*e5436536SAndroid Build Coastguard Worker                                      out_data_2_int + num_val_2_int, 1, 0)) !=
692*e5436536SAndroid Build Coastguard Worker                   HUFFDEC_OK) {
693*e5436536SAndroid Build Coastguard Worker                 goto bail;
694*e5436536SAndroid Build Coastguard Worker               }
695*e5436536SAndroid Build Coastguard Worker             }
696*e5436536SAndroid Build Coastguard Worker           }
697*e5436536SAndroid Build Coastguard Worker 
698*e5436536SAndroid Build Coastguard Worker           if (out_data_1 != NULL) {
699*e5436536SAndroid Build Coastguard Worker             for (i = 0; i < num_val_1_int - 1; i += 2) {
700*e5436536SAndroid Build Coastguard Worker               out_data_1_int[i] = pair_vec[i][0];
701*e5436536SAndroid Build Coastguard Worker               out_data_1_int[i + 1] = pair_vec[i][1];
702*e5436536SAndroid Build Coastguard Worker             }
703*e5436536SAndroid Build Coastguard Worker           }
704*e5436536SAndroid Build Coastguard Worker           if (out_data_2 != NULL) {
705*e5436536SAndroid Build Coastguard Worker             for (i = 0; i < num_val_2_int - 1; i += 2) {
706*e5436536SAndroid Build Coastguard Worker               out_data_2_int[i] = pair_vec[i + 1][0];
707*e5436536SAndroid Build Coastguard Worker               out_data_2_int[i + 1] = pair_vec[i + 1][1];
708*e5436536SAndroid Build Coastguard Worker             }
709*e5436536SAndroid Build Coastguard Worker           }
710*e5436536SAndroid Build Coastguard Worker           break; /* FREQ_PAIR */
711*e5436536SAndroid Build Coastguard Worker 
712*e5436536SAndroid Build Coastguard Worker         case TIME_PAIR:
713*e5436536SAndroid Build Coastguard Worker           if (((diff_type_1 == DIFF_FREQ) || (diff_type_2 == DIFF_FREQ))) {
714*e5436536SAndroid Build Coastguard Worker             p0_data_1[0] = &out_data_1[0];
715*e5436536SAndroid Build Coastguard Worker             p0_data_1[1] = &out_data_2[0];
716*e5436536SAndroid Build Coastguard Worker 
717*e5436536SAndroid Build Coastguard Worker             out_data_1_int += 1;
718*e5436536SAndroid Build Coastguard Worker             out_data_2_int += 1;
719*e5436536SAndroid Build Coastguard Worker 
720*e5436536SAndroid Build Coastguard Worker             num_val_1_int -= 1;
721*e5436536SAndroid Build Coastguard Worker           }
722*e5436536SAndroid Build Coastguard Worker 
723*e5436536SAndroid Build Coastguard Worker           if ((diff_type_1 == DIFF_TIME) || (diff_type_2 == DIFF_TIME)) {
724*e5436536SAndroid Build Coastguard Worker             diff_type = DIFF_TIME;
725*e5436536SAndroid Build Coastguard Worker           } else {
726*e5436536SAndroid Build Coastguard Worker             diff_type = DIFF_FREQ;
727*e5436536SAndroid Build Coastguard Worker           }
728*e5436536SAndroid Build Coastguard Worker           { hufYY = diff_type; }
729*e5436536SAndroid Build Coastguard Worker 
730*e5436536SAndroid Build Coastguard Worker           if ((err = huff_dec_2D(strm, data_type, hufYY, TIME_PAIR, pair_vec,
731*e5436536SAndroid Build Coastguard Worker                                  num_val_1_int, 1, p0_data_1)) != HUFFDEC_OK) {
732*e5436536SAndroid Build Coastguard Worker             goto bail;
733*e5436536SAndroid Build Coastguard Worker           }
734*e5436536SAndroid Build Coastguard Worker 
735*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < num_val_1_int; i++) {
736*e5436536SAndroid Build Coastguard Worker             out_data_1_int[i] = pair_vec[i][0];
737*e5436536SAndroid Build Coastguard Worker             out_data_2_int[i] = pair_vec[i][1];
738*e5436536SAndroid Build Coastguard Worker           }
739*e5436536SAndroid Build Coastguard Worker 
740*e5436536SAndroid Build Coastguard Worker           break; /* TIME_PAIR */
741*e5436536SAndroid Build Coastguard Worker 
742*e5436536SAndroid Build Coastguard Worker         default:
743*e5436536SAndroid Build Coastguard Worker           break;
744*e5436536SAndroid Build Coastguard Worker       }
745*e5436536SAndroid Build Coastguard Worker 
746*e5436536SAndroid Build Coastguard Worker       break; /* HUFF_2D */
747*e5436536SAndroid Build Coastguard Worker 
748*e5436536SAndroid Build Coastguard Worker     default:
749*e5436536SAndroid Build Coastguard Worker       break;
750*e5436536SAndroid Build Coastguard Worker   }
751*e5436536SAndroid Build Coastguard Worker bail:
752*e5436536SAndroid Build Coastguard Worker   return err;
753*e5436536SAndroid Build Coastguard Worker }
754*e5436536SAndroid Build Coastguard Worker 
diff_freq_decode(const SCHAR * const diff_data,SCHAR * const out_data,const int num_val)755*e5436536SAndroid Build Coastguard Worker static void diff_freq_decode(const SCHAR* const diff_data,
756*e5436536SAndroid Build Coastguard Worker                              SCHAR* const out_data, const int num_val) {
757*e5436536SAndroid Build Coastguard Worker   int i = 0;
758*e5436536SAndroid Build Coastguard Worker   out_data[0] = diff_data[0];
759*e5436536SAndroid Build Coastguard Worker 
760*e5436536SAndroid Build Coastguard Worker   for (i = 1; i < num_val; i++) {
761*e5436536SAndroid Build Coastguard Worker     out_data[i] = out_data[i - 1] + diff_data[i];
762*e5436536SAndroid Build Coastguard Worker   }
763*e5436536SAndroid Build Coastguard Worker }
764*e5436536SAndroid Build Coastguard Worker 
diff_time_decode_backwards(const SCHAR * const prev_data,const SCHAR * const diff_data,SCHAR * const out_data,const int mixed_diff_type,const int num_val)765*e5436536SAndroid Build Coastguard Worker static void diff_time_decode_backwards(const SCHAR* const prev_data,
766*e5436536SAndroid Build Coastguard Worker                                        const SCHAR* const diff_data,
767*e5436536SAndroid Build Coastguard Worker                                        SCHAR* const out_data,
768*e5436536SAndroid Build Coastguard Worker                                        const int mixed_diff_type,
769*e5436536SAndroid Build Coastguard Worker                                        const int num_val) {
770*e5436536SAndroid Build Coastguard Worker   int i = 0; /* default start value*/
771*e5436536SAndroid Build Coastguard Worker 
772*e5436536SAndroid Build Coastguard Worker   if (mixed_diff_type) {
773*e5436536SAndroid Build Coastguard Worker     out_data[0] = diff_data[0];
774*e5436536SAndroid Build Coastguard Worker     i = 1; /* new start value */
775*e5436536SAndroid Build Coastguard Worker   }
776*e5436536SAndroid Build Coastguard Worker   for (; i < num_val; i++) {
777*e5436536SAndroid Build Coastguard Worker     out_data[i] = prev_data[i] + diff_data[i];
778*e5436536SAndroid Build Coastguard Worker   }
779*e5436536SAndroid Build Coastguard Worker }
780*e5436536SAndroid Build Coastguard Worker 
diff_time_decode_forwards(const SCHAR * const prev_data,const SCHAR * const diff_data,SCHAR * const out_data,const int mixed_diff_type,const int num_val)781*e5436536SAndroid Build Coastguard Worker static void diff_time_decode_forwards(const SCHAR* const prev_data,
782*e5436536SAndroid Build Coastguard Worker                                       const SCHAR* const diff_data,
783*e5436536SAndroid Build Coastguard Worker                                       SCHAR* const out_data,
784*e5436536SAndroid Build Coastguard Worker                                       const int mixed_diff_type,
785*e5436536SAndroid Build Coastguard Worker                                       const int num_val) {
786*e5436536SAndroid Build Coastguard Worker   int i = 0; /* default start value*/
787*e5436536SAndroid Build Coastguard Worker 
788*e5436536SAndroid Build Coastguard Worker   if (mixed_diff_type) {
789*e5436536SAndroid Build Coastguard Worker     out_data[0] = diff_data[0];
790*e5436536SAndroid Build Coastguard Worker     i = 1; /* new start value */
791*e5436536SAndroid Build Coastguard Worker   }
792*e5436536SAndroid Build Coastguard Worker   for (; i < num_val; i++) {
793*e5436536SAndroid Build Coastguard Worker     out_data[i] = prev_data[i] - diff_data[i];
794*e5436536SAndroid Build Coastguard Worker   }
795*e5436536SAndroid Build Coastguard Worker }
796*e5436536SAndroid Build Coastguard Worker 
attach_lsb(HANDLE_FDK_BITSTREAM strm,SCHAR * in_data_msb,int offset,int num_lsb,int num_val,SCHAR * out_data)797*e5436536SAndroid Build Coastguard Worker static ERROR_t attach_lsb(HANDLE_FDK_BITSTREAM strm, SCHAR* in_data_msb,
798*e5436536SAndroid Build Coastguard Worker                           int offset, int num_lsb, int num_val,
799*e5436536SAndroid Build Coastguard Worker                           SCHAR* out_data) {
800*e5436536SAndroid Build Coastguard Worker   int i = 0, lsb = 0;
801*e5436536SAndroid Build Coastguard Worker   ULONG data = 0;
802*e5436536SAndroid Build Coastguard Worker 
803*e5436536SAndroid Build Coastguard Worker   for (i = 0; i < num_val; i++) {
804*e5436536SAndroid Build Coastguard Worker     int msb;
805*e5436536SAndroid Build Coastguard Worker     msb = in_data_msb[i];
806*e5436536SAndroid Build Coastguard Worker 
807*e5436536SAndroid Build Coastguard Worker     if (num_lsb > 0) {
808*e5436536SAndroid Build Coastguard Worker       data = FDKreadBits(strm, num_lsb);
809*e5436536SAndroid Build Coastguard Worker       lsb = data;
810*e5436536SAndroid Build Coastguard Worker 
811*e5436536SAndroid Build Coastguard Worker       out_data[i] = ((msb << num_lsb) | lsb) - offset;
812*e5436536SAndroid Build Coastguard Worker     } else
813*e5436536SAndroid Build Coastguard Worker       out_data[i] = msb - offset;
814*e5436536SAndroid Build Coastguard Worker   }
815*e5436536SAndroid Build Coastguard Worker 
816*e5436536SAndroid Build Coastguard Worker   return HUFFDEC_OK; /* dummy */
817*e5436536SAndroid Build Coastguard Worker }
818*e5436536SAndroid Build Coastguard Worker 
EcDataPairDec(DECODER_TYPE DECODER,HANDLE_FDK_BITSTREAM strm,SCHAR * aaOutData1,SCHAR * aaOutData2,SCHAR * aHistory,DATA_TYPE data_type,int startBand,int dataBands,int pair_flag,int coarse_flag,int allowDiffTimeBack_flag)819*e5436536SAndroid Build Coastguard Worker ERROR_t EcDataPairDec(DECODER_TYPE DECODER, HANDLE_FDK_BITSTREAM strm,
820*e5436536SAndroid Build Coastguard Worker                       SCHAR* aaOutData1, SCHAR* aaOutData2, SCHAR* aHistory,
821*e5436536SAndroid Build Coastguard Worker                       DATA_TYPE data_type, int startBand, int dataBands,
822*e5436536SAndroid Build Coastguard Worker                       int pair_flag, int coarse_flag,
823*e5436536SAndroid Build Coastguard Worker                       int allowDiffTimeBack_flag)
824*e5436536SAndroid Build Coastguard Worker 
825*e5436536SAndroid Build Coastguard Worker {
826*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
827*e5436536SAndroid Build Coastguard Worker 
828*e5436536SAndroid Build Coastguard Worker   // int allowDiffTimeBack_flag = !independency_flag || (setIdx > 0);
829*e5436536SAndroid Build Coastguard Worker   int attachLsb_flag = 0;
830*e5436536SAndroid Build Coastguard Worker   int pcmCoding_flag = 0;
831*e5436536SAndroid Build Coastguard Worker 
832*e5436536SAndroid Build Coastguard Worker   int mixed_time_pair = 0, numValPcm = 0;
833*e5436536SAndroid Build Coastguard Worker   int quant_levels = 0, quant_offset = 0;
834*e5436536SAndroid Build Coastguard Worker   ULONG data = 0;
835*e5436536SAndroid Build Coastguard Worker 
836*e5436536SAndroid Build Coastguard Worker   SCHAR aaDataPair[2][28] = {{0}};
837*e5436536SAndroid Build Coastguard Worker   SCHAR aaDataDiff[2][28] = {{0}};
838*e5436536SAndroid Build Coastguard Worker 
839*e5436536SAndroid Build Coastguard Worker   SCHAR aHistoryMsb[28] = {0};
840*e5436536SAndroid Build Coastguard Worker 
841*e5436536SAndroid Build Coastguard Worker   SCHAR* pDataVec[2] = {NULL, NULL};
842*e5436536SAndroid Build Coastguard Worker 
843*e5436536SAndroid Build Coastguard Worker   DIFF_TYPE diff_type[2] = {DIFF_FREQ, DIFF_FREQ};
844*e5436536SAndroid Build Coastguard Worker   PAIRING pairing = FREQ_PAIR;
845*e5436536SAndroid Build Coastguard Worker   DIRECTION direction = BACKWARDS;
846*e5436536SAndroid Build Coastguard Worker 
847*e5436536SAndroid Build Coastguard Worker   switch (data_type) {
848*e5436536SAndroid Build Coastguard Worker     case t_CLD:
849*e5436536SAndroid Build Coastguard Worker       if (coarse_flag) {
850*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
851*e5436536SAndroid Build Coastguard Worker         quant_levels = 15;
852*e5436536SAndroid Build Coastguard Worker         quant_offset = 7;
853*e5436536SAndroid Build Coastguard Worker       } else {
854*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
855*e5436536SAndroid Build Coastguard Worker         quant_levels = 31;
856*e5436536SAndroid Build Coastguard Worker         quant_offset = 15;
857*e5436536SAndroid Build Coastguard Worker       }
858*e5436536SAndroid Build Coastguard Worker 
859*e5436536SAndroid Build Coastguard Worker       break;
860*e5436536SAndroid Build Coastguard Worker 
861*e5436536SAndroid Build Coastguard Worker     case t_ICC:
862*e5436536SAndroid Build Coastguard Worker       if (coarse_flag) {
863*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
864*e5436536SAndroid Build Coastguard Worker         quant_levels = 4;
865*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
866*e5436536SAndroid Build Coastguard Worker       } else {
867*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
868*e5436536SAndroid Build Coastguard Worker         quant_levels = 8;
869*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
870*e5436536SAndroid Build Coastguard Worker       }
871*e5436536SAndroid Build Coastguard Worker 
872*e5436536SAndroid Build Coastguard Worker       break;
873*e5436536SAndroid Build Coastguard Worker 
874*e5436536SAndroid Build Coastguard Worker     case t_OLD:
875*e5436536SAndroid Build Coastguard Worker       if (coarse_flag) {
876*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
877*e5436536SAndroid Build Coastguard Worker         quant_levels = 8;
878*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
879*e5436536SAndroid Build Coastguard Worker       } else {
880*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
881*e5436536SAndroid Build Coastguard Worker         quant_levels = 16;
882*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
883*e5436536SAndroid Build Coastguard Worker       }
884*e5436536SAndroid Build Coastguard Worker       break;
885*e5436536SAndroid Build Coastguard Worker 
886*e5436536SAndroid Build Coastguard Worker     case t_NRG:
887*e5436536SAndroid Build Coastguard Worker       if (coarse_flag) {
888*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
889*e5436536SAndroid Build Coastguard Worker         quant_levels = 32;
890*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
891*e5436536SAndroid Build Coastguard Worker       } else {
892*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
893*e5436536SAndroid Build Coastguard Worker         quant_levels = 64;
894*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
895*e5436536SAndroid Build Coastguard Worker       }
896*e5436536SAndroid Build Coastguard Worker       break;
897*e5436536SAndroid Build Coastguard Worker 
898*e5436536SAndroid Build Coastguard Worker     case t_IPD:
899*e5436536SAndroid Build Coastguard Worker       if (!coarse_flag) {
900*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 1;
901*e5436536SAndroid Build Coastguard Worker         quant_levels = 16;
902*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
903*e5436536SAndroid Build Coastguard Worker       } else {
904*e5436536SAndroid Build Coastguard Worker         attachLsb_flag = 0;
905*e5436536SAndroid Build Coastguard Worker         quant_levels = 8;
906*e5436536SAndroid Build Coastguard Worker         quant_offset = 0;
907*e5436536SAndroid Build Coastguard Worker       }
908*e5436536SAndroid Build Coastguard Worker       break;
909*e5436536SAndroid Build Coastguard Worker 
910*e5436536SAndroid Build Coastguard Worker     default:
911*e5436536SAndroid Build Coastguard Worker       return HUFFDEC_NOTOK;
912*e5436536SAndroid Build Coastguard Worker   }
913*e5436536SAndroid Build Coastguard Worker 
914*e5436536SAndroid Build Coastguard Worker   data = FDKreadBits(strm, 1);
915*e5436536SAndroid Build Coastguard Worker   pcmCoding_flag = data;
916*e5436536SAndroid Build Coastguard Worker 
917*e5436536SAndroid Build Coastguard Worker   if (pcmCoding_flag) {
918*e5436536SAndroid Build Coastguard Worker     if (pair_flag) {
919*e5436536SAndroid Build Coastguard Worker       pDataVec[0] = aaDataPair[0];
920*e5436536SAndroid Build Coastguard Worker       pDataVec[1] = aaDataPair[1];
921*e5436536SAndroid Build Coastguard Worker       numValPcm = 2 * dataBands;
922*e5436536SAndroid Build Coastguard Worker     } else {
923*e5436536SAndroid Build Coastguard Worker       pDataVec[0] = aaDataPair[0];
924*e5436536SAndroid Build Coastguard Worker       pDataVec[1] = NULL;
925*e5436536SAndroid Build Coastguard Worker       numValPcm = dataBands;
926*e5436536SAndroid Build Coastguard Worker     }
927*e5436536SAndroid Build Coastguard Worker 
928*e5436536SAndroid Build Coastguard Worker     err = pcm_decode(strm, pDataVec[0], pDataVec[1], quant_offset, numValPcm,
929*e5436536SAndroid Build Coastguard Worker                      quant_levels);
930*e5436536SAndroid Build Coastguard Worker     if (err != HUFFDEC_OK) return HUFFDEC_NOTOK;
931*e5436536SAndroid Build Coastguard Worker 
932*e5436536SAndroid Build Coastguard Worker   } else { /* Differential/Huffman/LSB Coding */
933*e5436536SAndroid Build Coastguard Worker 
934*e5436536SAndroid Build Coastguard Worker     if (pair_flag) {
935*e5436536SAndroid Build Coastguard Worker       pDataVec[0] = aaDataDiff[0];
936*e5436536SAndroid Build Coastguard Worker       pDataVec[1] = aaDataDiff[1];
937*e5436536SAndroid Build Coastguard Worker     } else {
938*e5436536SAndroid Build Coastguard Worker       pDataVec[0] = aaDataDiff[0];
939*e5436536SAndroid Build Coastguard Worker       pDataVec[1] = NULL;
940*e5436536SAndroid Build Coastguard Worker     }
941*e5436536SAndroid Build Coastguard Worker 
942*e5436536SAndroid Build Coastguard Worker     diff_type[0] = DIFF_FREQ;
943*e5436536SAndroid Build Coastguard Worker     diff_type[1] = DIFF_FREQ;
944*e5436536SAndroid Build Coastguard Worker 
945*e5436536SAndroid Build Coastguard Worker     direction = BACKWARDS;
946*e5436536SAndroid Build Coastguard Worker     {
947*e5436536SAndroid Build Coastguard Worker       if (pair_flag || allowDiffTimeBack_flag) {
948*e5436536SAndroid Build Coastguard Worker         data = FDKreadBits(strm, 1);
949*e5436536SAndroid Build Coastguard Worker         diff_type[0] = (DIFF_TYPE)data;
950*e5436536SAndroid Build Coastguard Worker       }
951*e5436536SAndroid Build Coastguard Worker 
952*e5436536SAndroid Build Coastguard Worker       if (pair_flag &&
953*e5436536SAndroid Build Coastguard Worker           ((diff_type[0] == DIFF_FREQ) || allowDiffTimeBack_flag)) {
954*e5436536SAndroid Build Coastguard Worker         data = FDKreadBits(strm, 1);
955*e5436536SAndroid Build Coastguard Worker         diff_type[1] = (DIFF_TYPE)data;
956*e5436536SAndroid Build Coastguard Worker       }
957*e5436536SAndroid Build Coastguard Worker     }
958*e5436536SAndroid Build Coastguard Worker     /* Huffman decoding */
959*e5436536SAndroid Build Coastguard Worker     err = huff_decode(strm, pDataVec[0], pDataVec[1], data_type, diff_type[0],
960*e5436536SAndroid Build Coastguard Worker                       diff_type[1], dataBands, &pairing,
961*e5436536SAndroid Build Coastguard Worker                       (DECODER == SAOC_DECODER));
962*e5436536SAndroid Build Coastguard Worker     if (err != HUFFDEC_OK) {
963*e5436536SAndroid Build Coastguard Worker       return HUFFDEC_NOTOK;
964*e5436536SAndroid Build Coastguard Worker     }
965*e5436536SAndroid Build Coastguard Worker 
966*e5436536SAndroid Build Coastguard Worker     {
967*e5436536SAndroid Build Coastguard Worker       /* Differential decoding */
968*e5436536SAndroid Build Coastguard Worker       if ((diff_type[0] == DIFF_TIME) || (diff_type[1] == DIFF_TIME)) {
969*e5436536SAndroid Build Coastguard Worker         if (DECODER == SAOC_DECODER) {
970*e5436536SAndroid Build Coastguard Worker           direction = BACKWARDS;
971*e5436536SAndroid Build Coastguard Worker         } else {
972*e5436536SAndroid Build Coastguard Worker           if (pair_flag) {
973*e5436536SAndroid Build Coastguard Worker             if ((diff_type[0] == DIFF_TIME) && !allowDiffTimeBack_flag) {
974*e5436536SAndroid Build Coastguard Worker               direction = FORWARDS;
975*e5436536SAndroid Build Coastguard Worker             } else if (diff_type[1] == DIFF_TIME) {
976*e5436536SAndroid Build Coastguard Worker               direction = BACKWARDS;
977*e5436536SAndroid Build Coastguard Worker             } else {
978*e5436536SAndroid Build Coastguard Worker               data = FDKreadBits(strm, 1);
979*e5436536SAndroid Build Coastguard Worker               direction = (DIRECTION)data;
980*e5436536SAndroid Build Coastguard Worker             }
981*e5436536SAndroid Build Coastguard Worker           } else {
982*e5436536SAndroid Build Coastguard Worker             direction = BACKWARDS;
983*e5436536SAndroid Build Coastguard Worker           }
984*e5436536SAndroid Build Coastguard Worker         }
985*e5436536SAndroid Build Coastguard Worker       }
986*e5436536SAndroid Build Coastguard Worker 
987*e5436536SAndroid Build Coastguard Worker       mixed_time_pair =
988*e5436536SAndroid Build Coastguard Worker           (diff_type[0] != diff_type[1]) && (pairing == TIME_PAIR);
989*e5436536SAndroid Build Coastguard Worker 
990*e5436536SAndroid Build Coastguard Worker       if (direction == BACKWARDS) {
991*e5436536SAndroid Build Coastguard Worker         if (diff_type[0] == DIFF_FREQ) {
992*e5436536SAndroid Build Coastguard Worker           diff_freq_decode(aaDataDiff[0], aaDataPair[0], dataBands);
993*e5436536SAndroid Build Coastguard Worker         } else {
994*e5436536SAndroid Build Coastguard Worker           int i;
995*e5436536SAndroid Build Coastguard Worker           for (i = 0; i < dataBands; i++) {
996*e5436536SAndroid Build Coastguard Worker             aHistoryMsb[i] = aHistory[i + startBand] + quant_offset;
997*e5436536SAndroid Build Coastguard Worker             if (attachLsb_flag) {
998*e5436536SAndroid Build Coastguard Worker               aHistoryMsb[i] >>= 1;
999*e5436536SAndroid Build Coastguard Worker             }
1000*e5436536SAndroid Build Coastguard Worker           }
1001*e5436536SAndroid Build Coastguard Worker           diff_time_decode_backwards(aHistoryMsb, aaDataDiff[0], aaDataPair[0],
1002*e5436536SAndroid Build Coastguard Worker                                      mixed_time_pair, dataBands);
1003*e5436536SAndroid Build Coastguard Worker         }
1004*e5436536SAndroid Build Coastguard Worker         if (diff_type[1] == DIFF_FREQ) {
1005*e5436536SAndroid Build Coastguard Worker           diff_freq_decode(aaDataDiff[1], aaDataPair[1], dataBands);
1006*e5436536SAndroid Build Coastguard Worker         } else {
1007*e5436536SAndroid Build Coastguard Worker           diff_time_decode_backwards(aaDataPair[0], aaDataDiff[1],
1008*e5436536SAndroid Build Coastguard Worker                                      aaDataPair[1], mixed_time_pair, dataBands);
1009*e5436536SAndroid Build Coastguard Worker         }
1010*e5436536SAndroid Build Coastguard Worker       } else {
1011*e5436536SAndroid Build Coastguard Worker         /* diff_type[1] MUST BE DIFF_FREQ */
1012*e5436536SAndroid Build Coastguard Worker         diff_freq_decode(aaDataDiff[1], aaDataPair[1], dataBands);
1013*e5436536SAndroid Build Coastguard Worker 
1014*e5436536SAndroid Build Coastguard Worker         if (diff_type[0] == DIFF_FREQ) {
1015*e5436536SAndroid Build Coastguard Worker           diff_freq_decode(aaDataDiff[0], aaDataPair[0], dataBands);
1016*e5436536SAndroid Build Coastguard Worker         } else {
1017*e5436536SAndroid Build Coastguard Worker           diff_time_decode_forwards(aaDataPair[1], aaDataDiff[0], aaDataPair[0],
1018*e5436536SAndroid Build Coastguard Worker                                     mixed_time_pair, dataBands);
1019*e5436536SAndroid Build Coastguard Worker         }
1020*e5436536SAndroid Build Coastguard Worker       }
1021*e5436536SAndroid Build Coastguard Worker     }
1022*e5436536SAndroid Build Coastguard Worker 
1023*e5436536SAndroid Build Coastguard Worker     /* LSB decoding */
1024*e5436536SAndroid Build Coastguard Worker     err = attach_lsb(strm, aaDataPair[0], quant_offset, attachLsb_flag ? 1 : 0,
1025*e5436536SAndroid Build Coastguard Worker                      dataBands, aaDataPair[0]);
1026*e5436536SAndroid Build Coastguard Worker     if (err != HUFFDEC_OK) goto bail;
1027*e5436536SAndroid Build Coastguard Worker 
1028*e5436536SAndroid Build Coastguard Worker     if (pair_flag) {
1029*e5436536SAndroid Build Coastguard Worker       err = attach_lsb(strm, aaDataPair[1], quant_offset,
1030*e5436536SAndroid Build Coastguard Worker                        attachLsb_flag ? 1 : 0, dataBands, aaDataPair[1]);
1031*e5436536SAndroid Build Coastguard Worker       if (err != HUFFDEC_OK) goto bail;
1032*e5436536SAndroid Build Coastguard Worker     }
1033*e5436536SAndroid Build Coastguard Worker   } /* End: Differential/Huffman/LSB Coding */
1034*e5436536SAndroid Build Coastguard Worker 
1035*e5436536SAndroid Build Coastguard Worker   /* Copy data to output arrays */
1036*e5436536SAndroid Build Coastguard Worker   FDKmemcpy(aaOutData1 + startBand, aaDataPair[0], sizeof(SCHAR) * dataBands);
1037*e5436536SAndroid Build Coastguard Worker   if (pair_flag) {
1038*e5436536SAndroid Build Coastguard Worker     FDKmemcpy(aaOutData2 + startBand, aaDataPair[1], sizeof(SCHAR) * dataBands);
1039*e5436536SAndroid Build Coastguard Worker   }
1040*e5436536SAndroid Build Coastguard Worker 
1041*e5436536SAndroid Build Coastguard Worker bail:
1042*e5436536SAndroid Build Coastguard Worker   return err;
1043*e5436536SAndroid Build Coastguard Worker }
1044*e5436536SAndroid Build Coastguard Worker 
huff_dec_reshape(HANDLE_FDK_BITSTREAM strm,int * out_data,int num_val)1045*e5436536SAndroid Build Coastguard Worker ERROR_t huff_dec_reshape(HANDLE_FDK_BITSTREAM strm, int* out_data,
1046*e5436536SAndroid Build Coastguard Worker                          int num_val) {
1047*e5436536SAndroid Build Coastguard Worker   ERROR_t err = HUFFDEC_OK;
1048*e5436536SAndroid Build Coastguard Worker   int val_rcvd = 0, dummy = 0, i = 0, val = 0, len = 0;
1049*e5436536SAndroid Build Coastguard Worker   SCHAR rl_data[2] = {0};
1050*e5436536SAndroid Build Coastguard Worker 
1051*e5436536SAndroid Build Coastguard Worker   while (val_rcvd < num_val) {
1052*e5436536SAndroid Build Coastguard Worker     err = huff_read_2D(strm,
1053*e5436536SAndroid Build Coastguard Worker                        (HANDLE_HUFF_NODE)&FDK_huffReshapeNodes.nodeTab[0][0],
1054*e5436536SAndroid Build Coastguard Worker                        rl_data, &dummy);
1055*e5436536SAndroid Build Coastguard Worker     if (err != HUFFDEC_OK) goto bail;
1056*e5436536SAndroid Build Coastguard Worker     val = rl_data[0];
1057*e5436536SAndroid Build Coastguard Worker     len = rl_data[1] + 1;
1058*e5436536SAndroid Build Coastguard Worker     if (val_rcvd + len > num_val) {
1059*e5436536SAndroid Build Coastguard Worker       err = HUFFDEC_NOTOK;
1060*e5436536SAndroid Build Coastguard Worker       goto bail;
1061*e5436536SAndroid Build Coastguard Worker     }
1062*e5436536SAndroid Build Coastguard Worker     for (i = val_rcvd; i < val_rcvd + len; i++) {
1063*e5436536SAndroid Build Coastguard Worker       out_data[i] = val;
1064*e5436536SAndroid Build Coastguard Worker     }
1065*e5436536SAndroid Build Coastguard Worker     val_rcvd += len;
1066*e5436536SAndroid Build Coastguard Worker   }
1067*e5436536SAndroid Build Coastguard Worker bail:
1068*e5436536SAndroid Build Coastguard Worker   return err;
1069*e5436536SAndroid Build Coastguard Worker }
1070