1159b3361Sopenharmony_ci/*
2159b3361Sopenharmony_ci * layer3.c: Mpeg Layer-3 audio decoder
3159b3361Sopenharmony_ci *
4159b3361Sopenharmony_ci * Copyright (C) 1999-2010 The L.A.M.E. project
5159b3361Sopenharmony_ci *
6159b3361Sopenharmony_ci * Initially written by Michael Hipp, see also AUTHORS and README.
7159b3361Sopenharmony_ci *
8159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or
9159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public
10159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either
11159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version.
12159b3361Sopenharmony_ci *
13159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful,
14159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16159b3361Sopenharmony_ci * Library General Public License for more details.
17159b3361Sopenharmony_ci *
18159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public
19159b3361Sopenharmony_ci * License along with this library; if not, write to the
20159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA.
22159b3361Sopenharmony_ci */
23159b3361Sopenharmony_ci/* $Id$ */
24159b3361Sopenharmony_ci
25159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H
26159b3361Sopenharmony_ci# include <config.h>
27159b3361Sopenharmony_ci#endif
28159b3361Sopenharmony_ci
29159b3361Sopenharmony_ci#include <stdlib.h>
30159b3361Sopenharmony_ci#include "common.h"
31159b3361Sopenharmony_ci#include "huffman.h"
32159b3361Sopenharmony_ci#include "lame.h"
33159b3361Sopenharmony_ci#include "machine.h"
34159b3361Sopenharmony_ci#include "encoder.h"
35159b3361Sopenharmony_ci#include "lame-analysis.h"
36159b3361Sopenharmony_ci#include "decode_i386.h"
37159b3361Sopenharmony_ci#include "layer3.h"
38159b3361Sopenharmony_ci
39159b3361Sopenharmony_ci#ifdef WITH_DMALLOC
40159b3361Sopenharmony_ci#include <dmalloc.h>
41159b3361Sopenharmony_ci#endif
42159b3361Sopenharmony_ci
43159b3361Sopenharmony_ci
44159b3361Sopenharmony_cistatic int gd_are_hip_tables_layer3_initialized = 0;
45159b3361Sopenharmony_ci
46159b3361Sopenharmony_cistatic real ispow[8207];
47159b3361Sopenharmony_cistatic real aa_ca[8], aa_cs[8];
48159b3361Sopenharmony_cistatic real COS1[12][6];
49159b3361Sopenharmony_cistatic real win[4][36];
50159b3361Sopenharmony_cistatic real win1[4][36];
51159b3361Sopenharmony_cistatic real gainpow2[256 + 118 + 4];
52159b3361Sopenharmony_cistatic real COS9[9];
53159b3361Sopenharmony_cistatic real COS6_1, COS6_2;
54159b3361Sopenharmony_cistatic real tfcos36[9];
55159b3361Sopenharmony_cistatic real tfcos12[3];
56159b3361Sopenharmony_ci
57159b3361Sopenharmony_cistruct bandInfoStruct {
58159b3361Sopenharmony_ci    short   longIdx[23];
59159b3361Sopenharmony_ci    short   longDiff[22];
60159b3361Sopenharmony_ci    short   shortIdx[14];
61159b3361Sopenharmony_ci    short   shortDiff[13];
62159b3361Sopenharmony_ci};
63159b3361Sopenharmony_ci
64159b3361Sopenharmony_cistatic int longLimit[9][23];
65159b3361Sopenharmony_cistatic int shortLimit[9][14];
66159b3361Sopenharmony_ci
67159b3361Sopenharmony_ci/* *INDENT-OFF* */
68159b3361Sopenharmony_ci
69159b3361Sopenharmony_cistatic const struct bandInfoStruct bandInfo[9] = {
70159b3361Sopenharmony_ci
71159b3361Sopenharmony_ci/* MPEG 1.0 */
72159b3361Sopenharmony_ci { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
73159b3361Sopenharmony_ci   {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
74159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
75159b3361Sopenharmony_ci   {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
76159b3361Sopenharmony_ci
77159b3361Sopenharmony_ci { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
78159b3361Sopenharmony_ci   {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
79159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
80159b3361Sopenharmony_ci   {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
81159b3361Sopenharmony_ci
82159b3361Sopenharmony_ci { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
83159b3361Sopenharmony_ci   {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
84159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
85159b3361Sopenharmony_ci   {4,4,4,4,6,8,12,16,20,26,34,42,12} }  ,
86159b3361Sopenharmony_ci
87159b3361Sopenharmony_ci/* MPEG 2.0 */
88159b3361Sopenharmony_ci { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
89159b3361Sopenharmony_ci   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
90159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
91159b3361Sopenharmony_ci   {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
92159b3361Sopenharmony_ci                                             /* docs: 332. mpg123: 330 */
93159b3361Sopenharmony_ci { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,332,394,464,540,576},
94159b3361Sopenharmony_ci   {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36 } ,
95159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
96159b3361Sopenharmony_ci   {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
97159b3361Sopenharmony_ci
98159b3361Sopenharmony_ci { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
99159b3361Sopenharmony_ci   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
100159b3361Sopenharmony_ci   {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
101159b3361Sopenharmony_ci   {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
102159b3361Sopenharmony_ci/* MPEG 2.5 */
103159b3361Sopenharmony_ci { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
104159b3361Sopenharmony_ci   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
105159b3361Sopenharmony_ci   {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
106159b3361Sopenharmony_ci   {4,4,4,6,8,10,12,14,18,24,30,40,18} },
107159b3361Sopenharmony_ci { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
108159b3361Sopenharmony_ci   {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
109159b3361Sopenharmony_ci   {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
110159b3361Sopenharmony_ci   {4,4,4,6,8,10,12,14,18,24,30,40,18} },
111159b3361Sopenharmony_ci { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
112159b3361Sopenharmony_ci   {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
113159b3361Sopenharmony_ci   {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
114159b3361Sopenharmony_ci   {8,8,8,12,16,20,24,28,36,2,2,2,26} } ,
115159b3361Sopenharmony_ci};
116159b3361Sopenharmony_ci/* *INDENT-ON* */
117159b3361Sopenharmony_ci
118159b3361Sopenharmony_cistatic int mapbuf0[9][152];
119159b3361Sopenharmony_cistatic int mapbuf1[9][156];
120159b3361Sopenharmony_cistatic int mapbuf2[9][44];
121159b3361Sopenharmony_cistatic int *map[9][3];
122159b3361Sopenharmony_cistatic int *mapend[9][3];
123159b3361Sopenharmony_ci
124159b3361Sopenharmony_cistatic unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
125159b3361Sopenharmony_cistatic unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
126159b3361Sopenharmony_ci
127159b3361Sopenharmony_cistatic real tan1_1[16], tan2_1[16], tan1_2[16], tan2_2[16];
128159b3361Sopenharmony_cistatic real pow1_1[2][16], pow2_1[2][16], pow1_2[2][16], pow2_2[2][16];
129159b3361Sopenharmony_ci
130159b3361Sopenharmony_cistatic unsigned int
131159b3361Sopenharmony_ciget1bit(PMPSTR mp)
132159b3361Sopenharmony_ci{
133159b3361Sopenharmony_ci    unsigned char rval;
134159b3361Sopenharmony_ci    rval = *mp->wordpointer << mp->bitindex;
135159b3361Sopenharmony_ci
136159b3361Sopenharmony_ci    mp->bitindex++;
137159b3361Sopenharmony_ci    mp->wordpointer += (mp->bitindex >> 3);
138159b3361Sopenharmony_ci    mp->bitindex &= 7;
139159b3361Sopenharmony_ci
140159b3361Sopenharmony_ci    return rval >> 7;
141159b3361Sopenharmony_ci}
142159b3361Sopenharmony_ci
143159b3361Sopenharmony_cistatic real
144159b3361Sopenharmony_ciget_gain(real const* gain_ptr, int idx, int* overflow)
145159b3361Sopenharmony_ci{
146159b3361Sopenharmony_ci    static const real* const gainpow2_end_ptr = gainpow2 + (sizeof(gainpow2)/sizeof(gainpow2[0])) -1;
147159b3361Sopenharmony_ci    real const * ptr = &gain_ptr[idx];
148159b3361Sopenharmony_ci    if (&gain_ptr[idx] > gainpow2_end_ptr) {
149159b3361Sopenharmony_ci        ptr = gainpow2_end_ptr;
150159b3361Sopenharmony_ci        if (overflow) *overflow = 1;
151159b3361Sopenharmony_ci    }
152159b3361Sopenharmony_ci    return *ptr;
153159b3361Sopenharmony_ci}
154159b3361Sopenharmony_ci
155159b3361Sopenharmony_ci
156159b3361Sopenharmony_ci/*
157159b3361Sopenharmony_ci * init tables for layer-3
158159b3361Sopenharmony_ci */
159159b3361Sopenharmony_civoid
160159b3361Sopenharmony_cihip_init_tables_layer3(void)
161159b3361Sopenharmony_ci{
162159b3361Sopenharmony_ci    int     i, j, k;
163159b3361Sopenharmony_ci
164159b3361Sopenharmony_ci    if (gd_are_hip_tables_layer3_initialized) {
165159b3361Sopenharmony_ci        return;
166159b3361Sopenharmony_ci    }
167159b3361Sopenharmony_ci    gd_are_hip_tables_layer3_initialized = 1;
168159b3361Sopenharmony_ci
169159b3361Sopenharmony_ci    for (i = -256; i < 118 + 4; i++)
170159b3361Sopenharmony_ci        gainpow2[i + 256] = pow((double) 2.0, -0.25 * (double) (i + 210));
171159b3361Sopenharmony_ci
172159b3361Sopenharmony_ci    for (i = 0; i < 8207; i++)
173159b3361Sopenharmony_ci        ispow[i] = pow((double) i, (double) 4.0 / 3.0);
174159b3361Sopenharmony_ci
175159b3361Sopenharmony_ci    for (i = 0; i < 8; i++) {
176159b3361Sopenharmony_ci        static const double Ci[8] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 };
177159b3361Sopenharmony_ci        double  sq = sqrt(1.0 + Ci[i] * Ci[i]);
178159b3361Sopenharmony_ci        aa_cs[i] = 1.0 / sq;
179159b3361Sopenharmony_ci        aa_ca[i] = Ci[i] / sq;
180159b3361Sopenharmony_ci    }
181159b3361Sopenharmony_ci
182159b3361Sopenharmony_ci    for (i = 0; i < 18; i++) {
183159b3361Sopenharmony_ci        win[0][i] = win[1][i] =
184159b3361Sopenharmony_ci            0.5 * sin(M_PI / 72.0 * (double) (2 * (i + 0) + 1)) / cos(M_PI *
185159b3361Sopenharmony_ci                                                                      (double) (2 * (i + 0) +
186159b3361Sopenharmony_ci                                                                                19) / 72.0);
187159b3361Sopenharmony_ci        win[0][i + 18] = win[3][i + 18] =
188159b3361Sopenharmony_ci            0.5 * sin(M_PI / 72.0 * (double) (2 * (i + 18) + 1)) / cos(M_PI *
189159b3361Sopenharmony_ci                                                                       (double) (2 * (i + 18) +
190159b3361Sopenharmony_ci                                                                                 19) / 72.0);
191159b3361Sopenharmony_ci    }
192159b3361Sopenharmony_ci    for (i = 0; i < 6; i++) {
193159b3361Sopenharmony_ci        win[1][i + 18] = 0.5 / cos(M_PI * (double) (2 * (i + 18) + 19) / 72.0);
194159b3361Sopenharmony_ci        win[3][i + 12] = 0.5 / cos(M_PI * (double) (2 * (i + 12) + 19) / 72.0);
195159b3361Sopenharmony_ci        win[1][i + 24] =
196159b3361Sopenharmony_ci            0.5 * sin(M_PI / 24.0 * (double) (2 * i + 13)) / cos(M_PI *
197159b3361Sopenharmony_ci                                                                 (double) (2 * (i + 24) +
198159b3361Sopenharmony_ci                                                                           19) / 72.0);
199159b3361Sopenharmony_ci        win[1][i + 30] = win[3][i] = 0.0;
200159b3361Sopenharmony_ci        win[3][i + 6] =
201159b3361Sopenharmony_ci            0.5 * sin(M_PI / 24.0 * (double) (2 * i + 1)) / cos(M_PI * (double) (2 * (i + 6) + 19) /
202159b3361Sopenharmony_ci                                                                72.0);
203159b3361Sopenharmony_ci    }
204159b3361Sopenharmony_ci
205159b3361Sopenharmony_ci    for (i = 0; i < 9; i++)
206159b3361Sopenharmony_ci        COS9[i] = cos(M_PI / 18.0 * (double) i);
207159b3361Sopenharmony_ci
208159b3361Sopenharmony_ci    for (i = 0; i < 9; i++)
209159b3361Sopenharmony_ci        tfcos36[i] = 0.5 / cos(M_PI * (double) (i * 2 + 1) / 36.0);
210159b3361Sopenharmony_ci    for (i = 0; i < 3; i++)
211159b3361Sopenharmony_ci        tfcos12[i] = 0.5 / cos(M_PI * (double) (i * 2 + 1) / 12.0);
212159b3361Sopenharmony_ci
213159b3361Sopenharmony_ci    COS6_1 = cos(M_PI / 6.0 * (double) 1);
214159b3361Sopenharmony_ci    COS6_2 = cos(M_PI / 6.0 * (double) 2);
215159b3361Sopenharmony_ci
216159b3361Sopenharmony_ci    for (i = 0; i < 12; i++) {
217159b3361Sopenharmony_ci        win[2][i] =
218159b3361Sopenharmony_ci            0.5 * sin(M_PI / 24.0 * (double) (2 * i + 1)) / cos(M_PI * (double) (2 * i + 7) / 24.0);
219159b3361Sopenharmony_ci        for (j = 0; j < 6; j++)
220159b3361Sopenharmony_ci            COS1[i][j] = cos(M_PI / 24.0 * (double) ((2 * i + 7) * (2 * j + 1)));
221159b3361Sopenharmony_ci    }
222159b3361Sopenharmony_ci
223159b3361Sopenharmony_ci    for (j = 0; j < 4; j++) {
224159b3361Sopenharmony_ci        static int const len[4] = { 36, 36, 12, 36 };
225159b3361Sopenharmony_ci        for (i = 0; i < len[j]; i += 2)
226159b3361Sopenharmony_ci            win1[j][i] = +win[j][i];
227159b3361Sopenharmony_ci        for (i = 1; i < len[j]; i += 2)
228159b3361Sopenharmony_ci            win1[j][i] = -win[j][i];
229159b3361Sopenharmony_ci    }
230159b3361Sopenharmony_ci
231159b3361Sopenharmony_ci    for (i = 0; i < 16; i++) {
232159b3361Sopenharmony_ci        double  t = tan((double) i * M_PI / 12.0);
233159b3361Sopenharmony_ci        tan1_1[i] = t / (1.0 + t);
234159b3361Sopenharmony_ci        tan2_1[i] = 1.0 / (1.0 + t);
235159b3361Sopenharmony_ci        tan1_2[i] = M_SQRT2 * t / (1.0 + t);
236159b3361Sopenharmony_ci        tan2_2[i] = M_SQRT2 / (1.0 + t);
237159b3361Sopenharmony_ci
238159b3361Sopenharmony_ci        for (j = 0; j < 2; j++) {
239159b3361Sopenharmony_ci            double  base = pow(2.0, -0.25 * (j + 1.0));
240159b3361Sopenharmony_ci            double  p1 = 1.0, p2 = 1.0;
241159b3361Sopenharmony_ci            if (i > 0) {
242159b3361Sopenharmony_ci                if (i & 1)
243159b3361Sopenharmony_ci                    p1 = pow(base, (i + 1.0) * 0.5);
244159b3361Sopenharmony_ci                else
245159b3361Sopenharmony_ci                    p2 = pow(base, i * 0.5);
246159b3361Sopenharmony_ci            }
247159b3361Sopenharmony_ci            pow1_1[j][i] = p1;
248159b3361Sopenharmony_ci            pow2_1[j][i] = p2;
249159b3361Sopenharmony_ci            pow1_2[j][i] = M_SQRT2 * p1;
250159b3361Sopenharmony_ci            pow2_2[j][i] = M_SQRT2 * p2;
251159b3361Sopenharmony_ci        }
252159b3361Sopenharmony_ci    }
253159b3361Sopenharmony_ci
254159b3361Sopenharmony_ci    for (j = 0; j < 9; j++) {
255159b3361Sopenharmony_ci        struct bandInfoStruct const *bi = (struct bandInfoStruct const *) &bandInfo[j];
256159b3361Sopenharmony_ci        int    *mp;
257159b3361Sopenharmony_ci        int     cb, lwin;
258159b3361Sopenharmony_ci        short const *bdf;
259159b3361Sopenharmony_ci        int switch_idx = (j < 3) ? 8 : 6;
260159b3361Sopenharmony_ci
261159b3361Sopenharmony_ci        mp = map[j][0] = mapbuf0[j];
262159b3361Sopenharmony_ci        bdf = bi->longDiff;
263159b3361Sopenharmony_ci        for (i = 0, cb = 0; cb < switch_idx; cb++, i += *bdf++) {
264159b3361Sopenharmony_ci            *mp++ = (*bdf) >> 1;
265159b3361Sopenharmony_ci            *mp++ = i;
266159b3361Sopenharmony_ci            *mp++ = 3;
267159b3361Sopenharmony_ci            *mp++ = cb;
268159b3361Sopenharmony_ci        }
269159b3361Sopenharmony_ci        bdf = bi->shortDiff + 3;
270159b3361Sopenharmony_ci        for (cb = 3; cb < 13; cb++) {
271159b3361Sopenharmony_ci            int     l = (*bdf++) >> 1;
272159b3361Sopenharmony_ci            for (lwin = 0; lwin < 3; lwin++) {
273159b3361Sopenharmony_ci                *mp++ = l;
274159b3361Sopenharmony_ci                *mp++ = i + lwin;
275159b3361Sopenharmony_ci                *mp++ = lwin;
276159b3361Sopenharmony_ci                *mp++ = cb;
277159b3361Sopenharmony_ci            }
278159b3361Sopenharmony_ci            i += 6 * l;
279159b3361Sopenharmony_ci        }
280159b3361Sopenharmony_ci        mapend[j][0] = mp;
281159b3361Sopenharmony_ci
282159b3361Sopenharmony_ci        mp = map[j][1] = mapbuf1[j];
283159b3361Sopenharmony_ci        bdf = bi->shortDiff + 0;
284159b3361Sopenharmony_ci        for (i = 0, cb = 0; cb < 13; cb++) {
285159b3361Sopenharmony_ci            int     l = (*bdf++) >> 1;
286159b3361Sopenharmony_ci            for (lwin = 0; lwin < 3; lwin++) {
287159b3361Sopenharmony_ci                *mp++ = l;
288159b3361Sopenharmony_ci                *mp++ = i + lwin;
289159b3361Sopenharmony_ci                *mp++ = lwin;
290159b3361Sopenharmony_ci                *mp++ = cb;
291159b3361Sopenharmony_ci            }
292159b3361Sopenharmony_ci            i += 6 * l;
293159b3361Sopenharmony_ci        }
294159b3361Sopenharmony_ci        mapend[j][1] = mp;
295159b3361Sopenharmony_ci
296159b3361Sopenharmony_ci        mp = map[j][2] = mapbuf2[j];
297159b3361Sopenharmony_ci        bdf = bi->longDiff;
298159b3361Sopenharmony_ci        for (cb = 0; cb < 22; cb++) {
299159b3361Sopenharmony_ci            *mp++ = (*bdf++) >> 1;
300159b3361Sopenharmony_ci            *mp++ = cb;
301159b3361Sopenharmony_ci        }
302159b3361Sopenharmony_ci        mapend[j][2] = mp;
303159b3361Sopenharmony_ci
304159b3361Sopenharmony_ci    }
305159b3361Sopenharmony_ci
306159b3361Sopenharmony_ci    for (j = 0; j < 9; j++) {
307159b3361Sopenharmony_ci        for (i = 0; i < 23; i++) {
308159b3361Sopenharmony_ci            longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
309159b3361Sopenharmony_ci            if (longLimit[j][i] > SBLIMIT)
310159b3361Sopenharmony_ci                longLimit[j][i] = SBLIMIT;
311159b3361Sopenharmony_ci        }
312159b3361Sopenharmony_ci        for (i = 0; i < 14; i++) {
313159b3361Sopenharmony_ci            shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
314159b3361Sopenharmony_ci            if (shortLimit[j][i] > SBLIMIT)
315159b3361Sopenharmony_ci                shortLimit[j][i] = SBLIMIT;
316159b3361Sopenharmony_ci        }
317159b3361Sopenharmony_ci    }
318159b3361Sopenharmony_ci
319159b3361Sopenharmony_ci    for (i = 0; i < 5; i++) {
320159b3361Sopenharmony_ci        for (j = 0; j < 6; j++) {
321159b3361Sopenharmony_ci            for (k = 0; k < 6; k++) {
322159b3361Sopenharmony_ci                int     n = k + j * 6 + i * 36;
323159b3361Sopenharmony_ci                i_slen2[n] = i | (j << 3) | (k << 6) | (3 << 12);
324159b3361Sopenharmony_ci            }
325159b3361Sopenharmony_ci        }
326159b3361Sopenharmony_ci    }
327159b3361Sopenharmony_ci    for (i = 0; i < 4; i++) {
328159b3361Sopenharmony_ci        for (j = 0; j < 4; j++) {
329159b3361Sopenharmony_ci            for (k = 0; k < 4; k++) {
330159b3361Sopenharmony_ci                int     n = k + j * 4 + i * 16;
331159b3361Sopenharmony_ci                i_slen2[n + 180] = i | (j << 3) | (k << 6) | (4 << 12);
332159b3361Sopenharmony_ci            }
333159b3361Sopenharmony_ci        }
334159b3361Sopenharmony_ci    }
335159b3361Sopenharmony_ci    for (i = 0; i < 4; i++) {
336159b3361Sopenharmony_ci        for (j = 0; j < 3; j++) {
337159b3361Sopenharmony_ci            int     n = j + i * 3;
338159b3361Sopenharmony_ci            i_slen2[n + 244] = i | (j << 3) | (5 << 12);
339159b3361Sopenharmony_ci            n_slen2[n + 500] = i | (j << 3) | (2 << 12) | (1 << 15);
340159b3361Sopenharmony_ci        }
341159b3361Sopenharmony_ci    }
342159b3361Sopenharmony_ci
343159b3361Sopenharmony_ci    for (i = 0; i < 5; i++) {
344159b3361Sopenharmony_ci        for (j = 0; j < 5; j++) {
345159b3361Sopenharmony_ci            for (k = 0; k < 4; k++) {
346159b3361Sopenharmony_ci                int     l;
347159b3361Sopenharmony_ci                for (l = 0; l < 4; l++) {
348159b3361Sopenharmony_ci                    int     n = l + k * 4 + j * 16 + i * 80;
349159b3361Sopenharmony_ci                    n_slen2[n] = i | (j << 3) | (k << 6) | (l << 9) | (0 << 12);
350159b3361Sopenharmony_ci                }
351159b3361Sopenharmony_ci            }
352159b3361Sopenharmony_ci        }
353159b3361Sopenharmony_ci    }
354159b3361Sopenharmony_ci    for (i = 0; i < 5; i++) {
355159b3361Sopenharmony_ci        for (j = 0; j < 5; j++) {
356159b3361Sopenharmony_ci            for (k = 0; k < 4; k++) {
357159b3361Sopenharmony_ci                int     n = k + j * 4 + i * 20;
358159b3361Sopenharmony_ci                n_slen2[n + 400] = i | (j << 3) | (k << 6) | (1 << 12);
359159b3361Sopenharmony_ci            }
360159b3361Sopenharmony_ci        }
361159b3361Sopenharmony_ci    }
362159b3361Sopenharmony_ci}
363159b3361Sopenharmony_ci
364159b3361Sopenharmony_ci/*
365159b3361Sopenharmony_ci * read additional side information
366159b3361Sopenharmony_ci */
367159b3361Sopenharmony_ci
368159b3361Sopenharmony_cistatic void
369159b3361Sopenharmony_ciIII_get_side_info_1(PMPSTR mp, int stereo,
370159b3361Sopenharmony_ci                    int ms_stereo, long sfreq, int single)
371159b3361Sopenharmony_ci{
372159b3361Sopenharmony_ci    int     ch, gr;
373159b3361Sopenharmony_ci    int     powdiff = (single == 3) ? 4 : 0;
374159b3361Sopenharmony_ci
375159b3361Sopenharmony_ci    mp->sideinfo.main_data_begin = getbits(mp, 9);
376159b3361Sopenharmony_ci    if (stereo == 1)
377159b3361Sopenharmony_ci        mp->sideinfo.private_bits = getbits_fast(mp, 5);
378159b3361Sopenharmony_ci    else
379159b3361Sopenharmony_ci        mp->sideinfo.private_bits = getbits_fast(mp, 3);
380159b3361Sopenharmony_ci
381159b3361Sopenharmony_ci    for (ch = 0; ch < stereo; ch++) {
382159b3361Sopenharmony_ci        mp->sideinfo.ch[ch].gr[0].scfsi = -1;
383159b3361Sopenharmony_ci        mp->sideinfo.ch[ch].gr[1].scfsi = getbits_fast(mp, 4);
384159b3361Sopenharmony_ci    }
385159b3361Sopenharmony_ci
386159b3361Sopenharmony_ci    for (gr = 0; gr < 2; gr++) {
387159b3361Sopenharmony_ci        for (ch = 0; ch < stereo; ch++) {
388159b3361Sopenharmony_ci            struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[gr]);
389159b3361Sopenharmony_ci
390159b3361Sopenharmony_ci            gr_infos->part2_3_length = getbits(mp, 12);
391159b3361Sopenharmony_ci            gr_infos->big_values = getbits_fast(mp, 9);
392159b3361Sopenharmony_ci            if (gr_infos->big_values > 288) {
393159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "big_values too large! %i\n", gr_infos->big_values);
394159b3361Sopenharmony_ci                gr_infos->big_values = 288;
395159b3361Sopenharmony_ci            }
396159b3361Sopenharmony_ci            {
397159b3361Sopenharmony_ci                unsigned int qss = getbits_fast(mp, 8);
398159b3361Sopenharmony_ci                gr_infos->pow2gain = gainpow2 + 256 - qss + powdiff;
399159b3361Sopenharmony_ci                if (mp->pinfo != NULL) {
400159b3361Sopenharmony_ci                    mp->pinfo->qss[gr][ch] = qss;
401159b3361Sopenharmony_ci                }
402159b3361Sopenharmony_ci            }
403159b3361Sopenharmony_ci            if (ms_stereo)
404159b3361Sopenharmony_ci                gr_infos->pow2gain += 2;
405159b3361Sopenharmony_ci            gr_infos->scalefac_compress = getbits_fast(mp, 4);
406159b3361Sopenharmony_ci/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
407159b3361Sopenharmony_ci            if (get1bit(mp)) {
408159b3361Sopenharmony_ci                int     i;
409159b3361Sopenharmony_ci                gr_infos->block_type = getbits_fast(mp, 2);
410159b3361Sopenharmony_ci                gr_infos->mixed_block_flag = get1bit(mp);
411159b3361Sopenharmony_ci                gr_infos->table_select[0] = getbits_fast(mp, 5);
412159b3361Sopenharmony_ci                gr_infos->table_select[1] = getbits_fast(mp, 5);
413159b3361Sopenharmony_ci
414159b3361Sopenharmony_ci
415159b3361Sopenharmony_ci                /*
416159b3361Sopenharmony_ci                 * table_select[2] not needed, because there is no region2,
417159b3361Sopenharmony_ci                 * but to satisfy some verifications tools we set it either.
418159b3361Sopenharmony_ci                 */
419159b3361Sopenharmony_ci                gr_infos->table_select[2] = 0;
420159b3361Sopenharmony_ci                for (i = 0; i < 3; i++) {
421159b3361Sopenharmony_ci                    unsigned int sbg = (getbits_fast(mp, 3) << 3);
422159b3361Sopenharmony_ci                    gr_infos->full_gain[i] = gr_infos->pow2gain + sbg;
423159b3361Sopenharmony_ci                    if (mp->pinfo != NULL)
424159b3361Sopenharmony_ci                        mp->pinfo->sub_gain[gr][ch][i] = sbg / 8;
425159b3361Sopenharmony_ci                }
426159b3361Sopenharmony_ci
427159b3361Sopenharmony_ci                if (gr_infos->block_type == 0) {
428159b3361Sopenharmony_ci                    lame_report_fnc(mp->report_err, "Blocktype == 0 and window-switching == 1 not allowed.\n");
429159b3361Sopenharmony_ci                    /* error seems to be very good recoverable, so don't exit */
430159b3361Sopenharmony_ci                    /* exit(1); */
431159b3361Sopenharmony_ci                }
432159b3361Sopenharmony_ci                /* region_count/start parameters are implicit in this case. */
433159b3361Sopenharmony_ci                gr_infos->region1start = 36 >> 1;
434159b3361Sopenharmony_ci                gr_infos->region2start = 576 >> 1;
435159b3361Sopenharmony_ci            }
436159b3361Sopenharmony_ci            else {
437159b3361Sopenharmony_ci                unsigned int i, r0c, r1c, region0index, region1index;
438159b3361Sopenharmony_ci                for (i = 0; i < 3; i++)
439159b3361Sopenharmony_ci                    gr_infos->table_select[i] = getbits_fast(mp, 5);
440159b3361Sopenharmony_ci                r0c = getbits_fast(mp, 4);
441159b3361Sopenharmony_ci                r1c = getbits_fast(mp, 3);
442159b3361Sopenharmony_ci                region0index = r0c+1;
443159b3361Sopenharmony_ci                if (region0index > 22) {
444159b3361Sopenharmony_ci                    lame_report_fnc(mp->report_err, "region0index=%d > 22\n", region0index);
445159b3361Sopenharmony_ci                    region0index = 22;
446159b3361Sopenharmony_ci                }
447159b3361Sopenharmony_ci                region1index = r0c+1 + r1c+1;
448159b3361Sopenharmony_ci                if (region1index > 22) {
449159b3361Sopenharmony_ci                    lame_report_fnc(mp->report_err, "region1index=%d > 22\n", region1index);
450159b3361Sopenharmony_ci                    region1index = 22;
451159b3361Sopenharmony_ci                }
452159b3361Sopenharmony_ci                gr_infos->region1start = bandInfo[sfreq].longIdx[region0index] >> 1;
453159b3361Sopenharmony_ci                gr_infos->region2start = bandInfo[sfreq].longIdx[region1index] >> 1;
454159b3361Sopenharmony_ci                gr_infos->block_type = 0;
455159b3361Sopenharmony_ci                gr_infos->mixed_block_flag = 0;
456159b3361Sopenharmony_ci            }
457159b3361Sopenharmony_ci            gr_infos->preflag = get1bit(mp);
458159b3361Sopenharmony_ci            gr_infos->scalefac_scale = get1bit(mp);
459159b3361Sopenharmony_ci            gr_infos->count1table_select = get1bit(mp);
460159b3361Sopenharmony_ci        }
461159b3361Sopenharmony_ci    }
462159b3361Sopenharmony_ci}
463159b3361Sopenharmony_ci
464159b3361Sopenharmony_ci/*
465159b3361Sopenharmony_ci * Side Info for MPEG 2.0 / LSF
466159b3361Sopenharmony_ci */
467159b3361Sopenharmony_cistatic void
468159b3361Sopenharmony_ciIII_get_side_info_2(PMPSTR mp, int stereo, int ms_stereo, long sfreq, int single)
469159b3361Sopenharmony_ci{
470159b3361Sopenharmony_ci    int     ch;
471159b3361Sopenharmony_ci    int     powdiff = (single == 3) ? 4 : 0;
472159b3361Sopenharmony_ci
473159b3361Sopenharmony_ci    mp->sideinfo.main_data_begin = getbits(mp, 8);
474159b3361Sopenharmony_ci
475159b3361Sopenharmony_ci    if (stereo == 1)
476159b3361Sopenharmony_ci        mp->sideinfo.private_bits = get1bit(mp);
477159b3361Sopenharmony_ci    else
478159b3361Sopenharmony_ci        mp->sideinfo.private_bits = getbits_fast(mp, 2);
479159b3361Sopenharmony_ci
480159b3361Sopenharmony_ci    for (ch = 0; ch < stereo; ch++) {
481159b3361Sopenharmony_ci        struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[0]);
482159b3361Sopenharmony_ci        unsigned int qss;
483159b3361Sopenharmony_ci
484159b3361Sopenharmony_ci        gr_infos->part2_3_length = getbits(mp, 12);
485159b3361Sopenharmony_ci        gr_infos->big_values = getbits_fast(mp, 9);
486159b3361Sopenharmony_ci        if (gr_infos->big_values > 288) {
487159b3361Sopenharmony_ci            lame_report_fnc(mp->report_err, "big_values too large! %i\n", gr_infos->big_values);
488159b3361Sopenharmony_ci            gr_infos->big_values = 288;
489159b3361Sopenharmony_ci        }
490159b3361Sopenharmony_ci        qss = getbits_fast(mp, 8);
491159b3361Sopenharmony_ci        gr_infos->pow2gain = gainpow2 + 256 - qss + powdiff;
492159b3361Sopenharmony_ci        if (mp->pinfo != NULL) {
493159b3361Sopenharmony_ci            mp->pinfo->qss[0][ch] = qss;
494159b3361Sopenharmony_ci        }
495159b3361Sopenharmony_ci
496159b3361Sopenharmony_ci
497159b3361Sopenharmony_ci        if (ms_stereo)
498159b3361Sopenharmony_ci            gr_infos->pow2gain += 2;
499159b3361Sopenharmony_ci        gr_infos->scalefac_compress = getbits(mp, 9);
500159b3361Sopenharmony_ci/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
501159b3361Sopenharmony_ci        if (get1bit(mp)) {
502159b3361Sopenharmony_ci            int     i;
503159b3361Sopenharmony_ci            gr_infos->block_type = getbits_fast(mp, 2);
504159b3361Sopenharmony_ci            gr_infos->mixed_block_flag = get1bit(mp);
505159b3361Sopenharmony_ci            gr_infos->table_select[0] = getbits_fast(mp, 5);
506159b3361Sopenharmony_ci            gr_infos->table_select[1] = getbits_fast(mp, 5);
507159b3361Sopenharmony_ci            /*
508159b3361Sopenharmony_ci             * table_select[2] not needed, because there is no region2,
509159b3361Sopenharmony_ci             * but to satisfy some verifications tools we set it either.
510159b3361Sopenharmony_ci             */
511159b3361Sopenharmony_ci            gr_infos->table_select[2] = 0;
512159b3361Sopenharmony_ci            for (i = 0; i < 3; i++) {
513159b3361Sopenharmony_ci                unsigned int sbg = (getbits_fast(mp, 3) << 3);
514159b3361Sopenharmony_ci                gr_infos->full_gain[i] = gr_infos->pow2gain + sbg;
515159b3361Sopenharmony_ci                if (mp->pinfo != NULL)
516159b3361Sopenharmony_ci                    mp->pinfo->sub_gain[0][ch][i] = sbg / 8;
517159b3361Sopenharmony_ci
518159b3361Sopenharmony_ci            }
519159b3361Sopenharmony_ci
520159b3361Sopenharmony_ci            if (gr_infos->block_type == 0) {
521159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "Blocktype == 0 and window-switching == 1 not allowed.\n");
522159b3361Sopenharmony_ci                /* error seems to be very good recoverable, so don't exit */
523159b3361Sopenharmony_ci                /* exit(1); */
524159b3361Sopenharmony_ci            }
525159b3361Sopenharmony_ci            /* region_count/start parameters are implicit in this case. */
526159b3361Sopenharmony_ci            if (gr_infos->block_type == 2) {
527159b3361Sopenharmony_ci                if (gr_infos->mixed_block_flag == 0)
528159b3361Sopenharmony_ci                    gr_infos->region1start = 36 >> 1;
529159b3361Sopenharmony_ci                else
530159b3361Sopenharmony_ci                    gr_infos->region1start = 48 >> 1;
531159b3361Sopenharmony_ci            }
532159b3361Sopenharmony_ci            else
533159b3361Sopenharmony_ci                gr_infos->region1start = 54 >> 1;
534159b3361Sopenharmony_ci            if (sfreq == 8)
535159b3361Sopenharmony_ci                gr_infos->region1start *= 2;
536159b3361Sopenharmony_ci            gr_infos->region2start = 576 >> 1;
537159b3361Sopenharmony_ci        }
538159b3361Sopenharmony_ci        else {
539159b3361Sopenharmony_ci            unsigned int i, r0c, r1c, region0index, region1index;
540159b3361Sopenharmony_ci            for (i = 0; i < 3; i++)
541159b3361Sopenharmony_ci                gr_infos->table_select[i] = getbits_fast(mp, 5);
542159b3361Sopenharmony_ci            r0c = getbits_fast(mp, 4);
543159b3361Sopenharmony_ci            r1c = getbits_fast(mp, 3);
544159b3361Sopenharmony_ci            region0index = r0c+1;
545159b3361Sopenharmony_ci            if (region0index > 22) {
546159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "region0index=%d > 22\n", region0index);
547159b3361Sopenharmony_ci                region0index = 22;
548159b3361Sopenharmony_ci            }
549159b3361Sopenharmony_ci            region1index = r0c+1 + r1c+1;
550159b3361Sopenharmony_ci            if (region1index > 22) {
551159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "region1index=%d > 22\n", region1index);
552159b3361Sopenharmony_ci                region1index = 22;
553159b3361Sopenharmony_ci            }
554159b3361Sopenharmony_ci            gr_infos->region1start = bandInfo[sfreq].longIdx[region0index] >> 1;
555159b3361Sopenharmony_ci            gr_infos->region2start = bandInfo[sfreq].longIdx[region1index] >> 1;
556159b3361Sopenharmony_ci            gr_infos->block_type = 0;
557159b3361Sopenharmony_ci            gr_infos->mixed_block_flag = 0;
558159b3361Sopenharmony_ci        }
559159b3361Sopenharmony_ci        gr_infos->scalefac_scale = get1bit(mp);
560159b3361Sopenharmony_ci        gr_infos->count1table_select = get1bit(mp);
561159b3361Sopenharmony_ci    }
562159b3361Sopenharmony_ci}
563159b3361Sopenharmony_ci
564159b3361Sopenharmony_ci/*
565159b3361Sopenharmony_ci * read scalefactors
566159b3361Sopenharmony_ci */
567159b3361Sopenharmony_ci
568159b3361Sopenharmony_cistatic int
569159b3361Sopenharmony_ciIII_get_scale_factors_1(PMPSTR mp, int *scf, struct gr_info_s *gr_infos)
570159b3361Sopenharmony_ci{
571159b3361Sopenharmony_ci    static const unsigned char slen[2][16] = {
572159b3361Sopenharmony_ci        {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
573159b3361Sopenharmony_ci        {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
574159b3361Sopenharmony_ci    };
575159b3361Sopenharmony_ci    int     numbits;
576159b3361Sopenharmony_ci    int     num0 = slen[0][gr_infos->scalefac_compress];
577159b3361Sopenharmony_ci    int     num1 = slen[1][gr_infos->scalefac_compress];
578159b3361Sopenharmony_ci
579159b3361Sopenharmony_ci    if (gr_infos->block_type == 2) {
580159b3361Sopenharmony_ci        int     i = 18;
581159b3361Sopenharmony_ci        numbits = (num0 + num1) * 18;
582159b3361Sopenharmony_ci
583159b3361Sopenharmony_ci        if (gr_infos->mixed_block_flag) {
584159b3361Sopenharmony_ci            for (i = 8; i; i--)
585159b3361Sopenharmony_ci                *scf++ = getbits_fast(mp, num0);
586159b3361Sopenharmony_ci            i = 9;
587159b3361Sopenharmony_ci            numbits -= num0; /* num0 * 17 + num1 * 18 */
588159b3361Sopenharmony_ci        }
589159b3361Sopenharmony_ci
590159b3361Sopenharmony_ci        for (; i; i--)
591159b3361Sopenharmony_ci            *scf++ = getbits_fast(mp, num0);
592159b3361Sopenharmony_ci        for (i = 18; i; i--)
593159b3361Sopenharmony_ci            *scf++ = getbits_fast(mp, num1);
594159b3361Sopenharmony_ci        *scf++ = 0;
595159b3361Sopenharmony_ci        *scf++ = 0;
596159b3361Sopenharmony_ci        *scf++ = 0;     /* short[13][0..2] = 0 */
597159b3361Sopenharmony_ci    }
598159b3361Sopenharmony_ci    else {
599159b3361Sopenharmony_ci        int     i;
600159b3361Sopenharmony_ci        int     scfsi = gr_infos->scfsi;
601159b3361Sopenharmony_ci
602159b3361Sopenharmony_ci        if (scfsi < 0) { /* scfsi < 0 => granule == 0 */
603159b3361Sopenharmony_ci            for (i = 11; i; i--)
604159b3361Sopenharmony_ci                *scf++ = getbits_fast(mp, num0);
605159b3361Sopenharmony_ci            for (i = 10; i; i--)
606159b3361Sopenharmony_ci                *scf++ = getbits_fast(mp, num1);
607159b3361Sopenharmony_ci            numbits = (num0 + num1) * 10 + num0;
608159b3361Sopenharmony_ci        }
609159b3361Sopenharmony_ci        else {
610159b3361Sopenharmony_ci            numbits = 0;
611159b3361Sopenharmony_ci            if (!(scfsi & 0x8)) {
612159b3361Sopenharmony_ci                for (i = 6; i; i--)
613159b3361Sopenharmony_ci                    *scf++ = getbits_fast(mp, num0);
614159b3361Sopenharmony_ci                numbits += num0 * 6;
615159b3361Sopenharmony_ci            }
616159b3361Sopenharmony_ci            else {
617159b3361Sopenharmony_ci                scf += 6;
618159b3361Sopenharmony_ci            }
619159b3361Sopenharmony_ci
620159b3361Sopenharmony_ci            if (!(scfsi & 0x4)) {
621159b3361Sopenharmony_ci                for (i = 5; i; i--)
622159b3361Sopenharmony_ci                    *scf++ = getbits_fast(mp, num0);
623159b3361Sopenharmony_ci                numbits += num0 * 5;
624159b3361Sopenharmony_ci            }
625159b3361Sopenharmony_ci            else {
626159b3361Sopenharmony_ci                scf += 5;
627159b3361Sopenharmony_ci            }
628159b3361Sopenharmony_ci
629159b3361Sopenharmony_ci            if (!(scfsi & 0x2)) {
630159b3361Sopenharmony_ci                for (i = 5; i; i--)
631159b3361Sopenharmony_ci                    *scf++ = getbits_fast(mp, num1);
632159b3361Sopenharmony_ci                numbits += num1 * 5;
633159b3361Sopenharmony_ci            }
634159b3361Sopenharmony_ci            else {
635159b3361Sopenharmony_ci                scf += 5;
636159b3361Sopenharmony_ci            }
637159b3361Sopenharmony_ci
638159b3361Sopenharmony_ci            if (!(scfsi & 0x1)) {
639159b3361Sopenharmony_ci                for (i = 5; i; i--)
640159b3361Sopenharmony_ci                    *scf++ = getbits_fast(mp, num1);
641159b3361Sopenharmony_ci                numbits += num1 * 5;
642159b3361Sopenharmony_ci            }
643159b3361Sopenharmony_ci            else {
644159b3361Sopenharmony_ci                scf += 5;
645159b3361Sopenharmony_ci            }
646159b3361Sopenharmony_ci        }
647159b3361Sopenharmony_ci
648159b3361Sopenharmony_ci        *scf++ = 0;     /* no l[21] in original sources */
649159b3361Sopenharmony_ci    }
650159b3361Sopenharmony_ci    return numbits;
651159b3361Sopenharmony_ci}
652159b3361Sopenharmony_ci
653159b3361Sopenharmony_ci
654159b3361Sopenharmony_cistatic int
655159b3361Sopenharmony_ciIII_get_scale_factors_2(PMPSTR mp, int *scf, struct gr_info_s *gr_infos, int i_stereo)
656159b3361Sopenharmony_ci{
657159b3361Sopenharmony_ci    unsigned char const *pnt;
658159b3361Sopenharmony_ci    int     i, j;
659159b3361Sopenharmony_ci    unsigned int slen;
660159b3361Sopenharmony_ci    int     n = 0;
661159b3361Sopenharmony_ci    int     numbits = 0;
662159b3361Sopenharmony_ci
663159b3361Sopenharmony_ci  /* *INDENT-OFF* */
664159b3361Sopenharmony_ci  static const unsigned char stab[3][6][4] = {
665159b3361Sopenharmony_ci   { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
666159b3361Sopenharmony_ci     { 7, 7, 7,0 } , { 6, 6, 6,3 } , {  8, 8,5,0} } ,
667159b3361Sopenharmony_ci   { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
668159b3361Sopenharmony_ci     {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
669159b3361Sopenharmony_ci   { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
670159b3361Sopenharmony_ci     { 6,15,12,0 } , { 6,12, 9,6 } , {  6,18,9,0} } };
671159b3361Sopenharmony_ci  /* *INDENT-ON* */
672159b3361Sopenharmony_ci
673159b3361Sopenharmony_ci    if (i_stereo)       /* i_stereo AND second channel -> do_layer3() checks this */
674159b3361Sopenharmony_ci        slen = i_slen2[gr_infos->scalefac_compress >> 1];
675159b3361Sopenharmony_ci    else
676159b3361Sopenharmony_ci        slen = n_slen2[gr_infos->scalefac_compress];
677159b3361Sopenharmony_ci
678159b3361Sopenharmony_ci    gr_infos->preflag = (slen >> 15) & 0x1;
679159b3361Sopenharmony_ci
680159b3361Sopenharmony_ci    n = 0;
681159b3361Sopenharmony_ci    if (gr_infos->block_type == 2) {
682159b3361Sopenharmony_ci        n++;
683159b3361Sopenharmony_ci        if (gr_infos->mixed_block_flag)
684159b3361Sopenharmony_ci            n++;
685159b3361Sopenharmony_ci    }
686159b3361Sopenharmony_ci
687159b3361Sopenharmony_ci    pnt = (unsigned char const *) stab[n][(slen >> 12) & 0x7];
688159b3361Sopenharmony_ci
689159b3361Sopenharmony_ci    for (i = 0; i < 4; i++) {
690159b3361Sopenharmony_ci        int     num = slen & 0x7;
691159b3361Sopenharmony_ci        slen >>= 3;
692159b3361Sopenharmony_ci        if (num) {
693159b3361Sopenharmony_ci            for (j = 0; j < (int) (pnt[i]); j++)
694159b3361Sopenharmony_ci                *scf++ = getbits_fast(mp, num);
695159b3361Sopenharmony_ci            numbits += pnt[i] * num;
696159b3361Sopenharmony_ci        }
697159b3361Sopenharmony_ci        else {
698159b3361Sopenharmony_ci            for (j = 0; j < (int) (pnt[i]); j++)
699159b3361Sopenharmony_ci                *scf++ = 0;
700159b3361Sopenharmony_ci        }
701159b3361Sopenharmony_ci    }
702159b3361Sopenharmony_ci
703159b3361Sopenharmony_ci    n = (n << 1) + 1;
704159b3361Sopenharmony_ci    for (i = 0; i < n; i++)
705159b3361Sopenharmony_ci        *scf++ = 0;
706159b3361Sopenharmony_ci
707159b3361Sopenharmony_ci    return numbits;
708159b3361Sopenharmony_ci}
709159b3361Sopenharmony_ci
710159b3361Sopenharmony_ci/* *INDENT-OFF* */
711159b3361Sopenharmony_cistatic const int pretab1 [22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; /* char enough ? */
712159b3361Sopenharmony_cistatic const int pretab2 [22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
713159b3361Sopenharmony_ci/* *INDENT-ON* */
714159b3361Sopenharmony_ci
715159b3361Sopenharmony_ci/*
716159b3361Sopenharmony_ci * don't forget to apply the same changes to III_dequantize_sample_ms() !!!
717159b3361Sopenharmony_ci */
718159b3361Sopenharmony_cistatic int
719159b3361Sopenharmony_ciIII_dequantize_sample(PMPSTR mp, real xr[SBLIMIT][SSLIMIT], int *scf,
720159b3361Sopenharmony_ci                      struct gr_info_s *gr_infos, int sfreq, int part2bits)
721159b3361Sopenharmony_ci{
722159b3361Sopenharmony_ci    int     shift = 1 + gr_infos->scalefac_scale;
723159b3361Sopenharmony_ci    real   *xrpnt = (real *) xr, xr_value=0;
724159b3361Sopenharmony_ci    int     l[3], l3;
725159b3361Sopenharmony_ci    int     part2remain = gr_infos->part2_3_length - part2bits;
726159b3361Sopenharmony_ci    int    *me;
727159b3361Sopenharmony_ci    real const * const xr_endptr = &xr[SBLIMIT-1][SSLIMIT-1];
728159b3361Sopenharmony_ci
729159b3361Sopenharmony_ci    int isbug = 0;
730159b3361Sopenharmony_ci    int bobug = 0;
731159b3361Sopenharmony_ci    int bobug_sb = 0, bobug_l3=0;
732159b3361Sopenharmony_ci#define BUFFER_OVERFLOW_BUG() if(!bobug){bobug=1;bobug_sb=cb;bobug_l3=l3;}else
733159b3361Sopenharmony_ci
734159b3361Sopenharmony_ci    /* lame_report_fnc(mp->report_dbg,"part2remain = %d, gr_infos->part2_3_length = %d, part2bits = %d\n",
735159b3361Sopenharmony_ci       part2remain, gr_infos->part2_3_length, part2bits); */
736159b3361Sopenharmony_ci
737159b3361Sopenharmony_ci    {
738159b3361Sopenharmony_ci        int     i;
739159b3361Sopenharmony_ci
740159b3361Sopenharmony_ci        for (i = (&xr[SBLIMIT][0] - xrpnt) >> 1; i > 0; i--) {
741159b3361Sopenharmony_ci            *xrpnt++ = 0.0;
742159b3361Sopenharmony_ci            *xrpnt++ = 0.0;
743159b3361Sopenharmony_ci        }
744159b3361Sopenharmony_ci
745159b3361Sopenharmony_ci        xrpnt = (real *) xr;
746159b3361Sopenharmony_ci    }
747159b3361Sopenharmony_ci
748159b3361Sopenharmony_ci    {
749159b3361Sopenharmony_ci        int     bv = gr_infos->big_values;
750159b3361Sopenharmony_ci        int     region1 = gr_infos->region1start;
751159b3361Sopenharmony_ci        int     region2 = gr_infos->region2start;
752159b3361Sopenharmony_ci
753159b3361Sopenharmony_ci        l3 = ((576 >> 1) - bv) >> 1;
754159b3361Sopenharmony_ci/*
755159b3361Sopenharmony_ci * we may lose the 'odd' bit here !!
756159b3361Sopenharmony_ci * check this later again
757159b3361Sopenharmony_ci */
758159b3361Sopenharmony_ci        if (bv <= region1) {
759159b3361Sopenharmony_ci            l[0] = bv;
760159b3361Sopenharmony_ci            l[1] = 0;
761159b3361Sopenharmony_ci            l[2] = 0;
762159b3361Sopenharmony_ci        }
763159b3361Sopenharmony_ci        else {
764159b3361Sopenharmony_ci            l[0] = region1;
765159b3361Sopenharmony_ci            if (bv <= region2) {
766159b3361Sopenharmony_ci                l[1] = bv - l[0];
767159b3361Sopenharmony_ci                l[2] = 0;
768159b3361Sopenharmony_ci            }
769159b3361Sopenharmony_ci            else {
770159b3361Sopenharmony_ci                l[1] = region2 - l[0];
771159b3361Sopenharmony_ci                l[2] = bv - region2;
772159b3361Sopenharmony_ci            }
773159b3361Sopenharmony_ci        }
774159b3361Sopenharmony_ci    }
775159b3361Sopenharmony_ci    /* MDH crash fix */
776159b3361Sopenharmony_ci    {
777159b3361Sopenharmony_ci        int     i;
778159b3361Sopenharmony_ci        for (i = 0; i < 3; i++) {
779159b3361Sopenharmony_ci            if (l[i] < 0) {
780159b3361Sopenharmony_ci                lame_report_fnc(mp->report_err, "hip: Bogus region length (%d)\n", l[i]);
781159b3361Sopenharmony_ci                l[i] = 0;
782159b3361Sopenharmony_ci            }
783159b3361Sopenharmony_ci        }
784159b3361Sopenharmony_ci    }
785159b3361Sopenharmony_ci    /* end MDH crash fix */
786159b3361Sopenharmony_ci
787159b3361Sopenharmony_ci    if (gr_infos->block_type == 2) {
788159b3361Sopenharmony_ci        /*
789159b3361Sopenharmony_ci         * decoding with short or mixed mode BandIndex table
790159b3361Sopenharmony_ci         */
791159b3361Sopenharmony_ci        int     i, max[4];
792159b3361Sopenharmony_ci        int     step = 0, lwin = 0, cb = 0;
793159b3361Sopenharmony_ci        real    v = 0.0;
794159b3361Sopenharmony_ci        int    *m, mc;
795159b3361Sopenharmony_ci
796159b3361Sopenharmony_ci        if (gr_infos->mixed_block_flag) {
797159b3361Sopenharmony_ci            max[3] = -1;
798159b3361Sopenharmony_ci            max[0] = max[1] = max[2] = 2;
799159b3361Sopenharmony_ci            m = map[sfreq][0];
800159b3361Sopenharmony_ci            me = mapend[sfreq][0];
801159b3361Sopenharmony_ci        }
802159b3361Sopenharmony_ci        else {
803159b3361Sopenharmony_ci            max[0] = max[1] = max[2] = max[3] = -1;
804159b3361Sopenharmony_ci            /* max[3] not really needed in this case */
805159b3361Sopenharmony_ci            m = map[sfreq][1];
806159b3361Sopenharmony_ci            me = mapend[sfreq][1];
807159b3361Sopenharmony_ci        }
808159b3361Sopenharmony_ci
809159b3361Sopenharmony_ci        mc = 0;
810159b3361Sopenharmony_ci        for (i = 0; i < 2; i++) {
811159b3361Sopenharmony_ci            int     lp = l[i];
812159b3361Sopenharmony_ci            struct newhuff const *h = (struct newhuff const *) (ht + gr_infos->table_select[i]);
813159b3361Sopenharmony_ci            for (; lp; lp--, mc--) {
814159b3361Sopenharmony_ci                int     x, y;
815159b3361Sopenharmony_ci                if ((!mc)) {
816159b3361Sopenharmony_ci                    mc = *m++;
817159b3361Sopenharmony_ci                    xrpnt = ((real *) xr) + (*m++);
818159b3361Sopenharmony_ci                    lwin = *m++;
819159b3361Sopenharmony_ci                    cb = *m++;
820159b3361Sopenharmony_ci                    if (lwin == 3) {
821159b3361Sopenharmony_ci                        v = get_gain(gr_infos->pow2gain, (*scf++) << shift, &isbug);
822159b3361Sopenharmony_ci                        step = 1;
823159b3361Sopenharmony_ci                    }
824159b3361Sopenharmony_ci                    else {
825159b3361Sopenharmony_ci                        v = get_gain(gr_infos->full_gain[lwin], (*scf++) << shift, &isbug);
826159b3361Sopenharmony_ci                        step = 3;
827159b3361Sopenharmony_ci                    }
828159b3361Sopenharmony_ci                }
829159b3361Sopenharmony_ci                {
830159b3361Sopenharmony_ci                    short const *val = (short const *) h->table;
831159b3361Sopenharmony_ci                    while ((y = *val++) < 0) {
832159b3361Sopenharmony_ci                        if (get1bit(mp))
833159b3361Sopenharmony_ci                            val -= y;
834159b3361Sopenharmony_ci                        part2remain--;
835159b3361Sopenharmony_ci                    }
836159b3361Sopenharmony_ci                    x = y >> 4;
837159b3361Sopenharmony_ci                    y &= 0xf;
838159b3361Sopenharmony_ci                }
839159b3361Sopenharmony_ci                if (x == 15) {
840159b3361Sopenharmony_ci                    max[lwin] = cb;
841159b3361Sopenharmony_ci                    part2remain -= h->linbits + 1;
842159b3361Sopenharmony_ci                    x += getbits(mp, (int) h->linbits);
843159b3361Sopenharmony_ci                    if (get1bit(mp))
844159b3361Sopenharmony_ci                        xr_value = -ispow[x] * v;
845159b3361Sopenharmony_ci                    else
846159b3361Sopenharmony_ci                        xr_value = ispow[x] * v;
847159b3361Sopenharmony_ci                }
848159b3361Sopenharmony_ci                else if (x) {
849159b3361Sopenharmony_ci                    max[lwin] = cb;
850159b3361Sopenharmony_ci                    if (get1bit(mp))
851159b3361Sopenharmony_ci                        xr_value = -ispow[x] * v;
852159b3361Sopenharmony_ci                    else
853159b3361Sopenharmony_ci                        xr_value = ispow[x] * v;
854159b3361Sopenharmony_ci                    part2remain--;
855159b3361Sopenharmony_ci                }
856159b3361Sopenharmony_ci                else
857159b3361Sopenharmony_ci                    xr_value = 0.0;
858159b3361Sopenharmony_ci
859159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
860159b3361Sopenharmony_ci                    *xrpnt = xr_value;
861159b3361Sopenharmony_ci                else
862159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
863159b3361Sopenharmony_ci                xrpnt += step;
864159b3361Sopenharmony_ci                if (y == 15) {
865159b3361Sopenharmony_ci                    max[lwin] = cb;
866159b3361Sopenharmony_ci                    part2remain -= h->linbits + 1;
867159b3361Sopenharmony_ci                    y += getbits(mp, (int) h->linbits);
868159b3361Sopenharmony_ci                    if (get1bit(mp))
869159b3361Sopenharmony_ci                        xr_value = -ispow[y] * v;
870159b3361Sopenharmony_ci                    else
871159b3361Sopenharmony_ci                        xr_value = ispow[y] * v;
872159b3361Sopenharmony_ci                }
873159b3361Sopenharmony_ci                else if (y) {
874159b3361Sopenharmony_ci                    max[lwin] = cb;
875159b3361Sopenharmony_ci                    if (get1bit(mp))
876159b3361Sopenharmony_ci                        xr_value = -ispow[y] * v;
877159b3361Sopenharmony_ci                    else
878159b3361Sopenharmony_ci                        xr_value = ispow[y] * v;
879159b3361Sopenharmony_ci                    part2remain--;
880159b3361Sopenharmony_ci                }
881159b3361Sopenharmony_ci                else
882159b3361Sopenharmony_ci                    xr_value = 0.0;
883159b3361Sopenharmony_ci
884159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
885159b3361Sopenharmony_ci                    *xrpnt = xr_value;
886159b3361Sopenharmony_ci                else
887159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
888159b3361Sopenharmony_ci                xrpnt += step;
889159b3361Sopenharmony_ci            }
890159b3361Sopenharmony_ci        }
891159b3361Sopenharmony_ci        for (; (l3 > 0) && (part2remain > 0); l3--) {
892159b3361Sopenharmony_ci            struct newhuff const *h = (struct newhuff const *) (htc + gr_infos->count1table_select);
893159b3361Sopenharmony_ci            short const *val = (short const *) h->table;
894159b3361Sopenharmony_ci            short   a;
895159b3361Sopenharmony_ci
896159b3361Sopenharmony_ci            while ((a = *val++) < 0) {
897159b3361Sopenharmony_ci                part2remain--;
898159b3361Sopenharmony_ci                if (part2remain < 0) {
899159b3361Sopenharmony_ci                    part2remain++;
900159b3361Sopenharmony_ci                    a = 0;
901159b3361Sopenharmony_ci                    break;
902159b3361Sopenharmony_ci                }
903159b3361Sopenharmony_ci                if (get1bit(mp))
904159b3361Sopenharmony_ci                    val -= a;
905159b3361Sopenharmony_ci            }
906159b3361Sopenharmony_ci            for (i = 0; i < 4; i++) {
907159b3361Sopenharmony_ci                if (!(i & 1)) {
908159b3361Sopenharmony_ci                    if (!mc) {
909159b3361Sopenharmony_ci                        mc = *m++;
910159b3361Sopenharmony_ci                        xrpnt = ((real *) xr) + (*m++);
911159b3361Sopenharmony_ci                        lwin = *m++;
912159b3361Sopenharmony_ci                        cb = *m++;
913159b3361Sopenharmony_ci                        if (lwin == 3) {
914159b3361Sopenharmony_ci                            v = get_gain(gr_infos->pow2gain, (*scf++) << shift, &isbug);
915159b3361Sopenharmony_ci                            step = 1;
916159b3361Sopenharmony_ci                        }
917159b3361Sopenharmony_ci                        else {
918159b3361Sopenharmony_ci                            v = get_gain(gr_infos->full_gain[lwin], (*scf++) << shift, &isbug);
919159b3361Sopenharmony_ci                            step = 3;
920159b3361Sopenharmony_ci                        }
921159b3361Sopenharmony_ci                    }
922159b3361Sopenharmony_ci                    mc--;
923159b3361Sopenharmony_ci                }
924159b3361Sopenharmony_ci                if ((a & (0x8 >> i))) {
925159b3361Sopenharmony_ci                    max[lwin] = cb;
926159b3361Sopenharmony_ci                    part2remain--;
927159b3361Sopenharmony_ci                    if (part2remain < 0) {
928159b3361Sopenharmony_ci                        part2remain++;
929159b3361Sopenharmony_ci                        break;
930159b3361Sopenharmony_ci                    }
931159b3361Sopenharmony_ci                    if (get1bit(mp))
932159b3361Sopenharmony_ci                        xr_value = -v;
933159b3361Sopenharmony_ci                    else
934159b3361Sopenharmony_ci                        xr_value = v;
935159b3361Sopenharmony_ci                }
936159b3361Sopenharmony_ci                else
937159b3361Sopenharmony_ci                    xr_value = 0.0;
938159b3361Sopenharmony_ci
939159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
940159b3361Sopenharmony_ci                    *xrpnt = xr_value;
941159b3361Sopenharmony_ci                else
942159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
943159b3361Sopenharmony_ci                xrpnt += step;
944159b3361Sopenharmony_ci            }
945159b3361Sopenharmony_ci        }
946159b3361Sopenharmony_ci        while (m < me) {
947159b3361Sopenharmony_ci            if (!mc) {
948159b3361Sopenharmony_ci                mc = *m++;
949159b3361Sopenharmony_ci                xrpnt = ((real *) xr) + *m++;
950159b3361Sopenharmony_ci                if ((*m++) == 3)
951159b3361Sopenharmony_ci                    step = 1;
952159b3361Sopenharmony_ci                else
953159b3361Sopenharmony_ci                    step = 3;
954159b3361Sopenharmony_ci                m++;    /* cb */
955159b3361Sopenharmony_ci            }
956159b3361Sopenharmony_ci            mc--;
957159b3361Sopenharmony_ci            if (xrpnt <= xr_endptr)
958159b3361Sopenharmony_ci                *xrpnt = 0.0;
959159b3361Sopenharmony_ci            else
960159b3361Sopenharmony_ci                BUFFER_OVERFLOW_BUG();
961159b3361Sopenharmony_ci            xrpnt += step;
962159b3361Sopenharmony_ci            if (xrpnt <= xr_endptr)
963159b3361Sopenharmony_ci                *xrpnt = 0.0;
964159b3361Sopenharmony_ci            else
965159b3361Sopenharmony_ci                BUFFER_OVERFLOW_BUG();
966159b3361Sopenharmony_ci            xrpnt += step;
967159b3361Sopenharmony_ci/* we could add a little opt. here:
968159b3361Sopenharmony_ci * if we finished a band for window 3 or a long band
969159b3361Sopenharmony_ci * further bands could copied in a simple loop without a
970159b3361Sopenharmony_ci * special 'map' decoding
971159b3361Sopenharmony_ci */
972159b3361Sopenharmony_ci        }
973159b3361Sopenharmony_ci
974159b3361Sopenharmony_ci        gr_infos->maxband[0] = max[0] + 1;
975159b3361Sopenharmony_ci        gr_infos->maxband[1] = max[1] + 1;
976159b3361Sopenharmony_ci        gr_infos->maxband[2] = max[2] + 1;
977159b3361Sopenharmony_ci        gr_infos->maxbandl = max[3] + 1;
978159b3361Sopenharmony_ci
979159b3361Sopenharmony_ci        {
980159b3361Sopenharmony_ci            int     rmax = max[0] > max[1] ? max[0] : max[1];
981159b3361Sopenharmony_ci            rmax = (rmax > max[2] ? rmax : max[2]) + 1;
982159b3361Sopenharmony_ci            gr_infos->maxb = rmax ? shortLimit[sfreq][rmax] : longLimit[sfreq][max[3] + 1];
983159b3361Sopenharmony_ci        }
984159b3361Sopenharmony_ci
985159b3361Sopenharmony_ci    }
986159b3361Sopenharmony_ci    else {
987159b3361Sopenharmony_ci        /*
988159b3361Sopenharmony_ci         * decoding with 'long' BandIndex table (block_type != 2)
989159b3361Sopenharmony_ci         */
990159b3361Sopenharmony_ci        int const *pretab = (int const *) (gr_infos->preflag ? pretab1 : pretab2);
991159b3361Sopenharmony_ci        int     i, max = -1;
992159b3361Sopenharmony_ci        int     cb = 0;
993159b3361Sopenharmony_ci        int    *m = map[sfreq][2];
994159b3361Sopenharmony_ci        real    v = 0.0;
995159b3361Sopenharmony_ci        int     mc = 0;
996159b3361Sopenharmony_ci
997159b3361Sopenharmony_ci        /*
998159b3361Sopenharmony_ci         * long hash table values
999159b3361Sopenharmony_ci         */
1000159b3361Sopenharmony_ci        for (i = 0; i < 3; i++) {
1001159b3361Sopenharmony_ci            int     lp = l[i];
1002159b3361Sopenharmony_ci            struct newhuff const *h = (struct newhuff const *) (ht + gr_infos->table_select[i]);
1003159b3361Sopenharmony_ci
1004159b3361Sopenharmony_ci            for (; lp; lp--, mc--) {
1005159b3361Sopenharmony_ci                int     x, y;
1006159b3361Sopenharmony_ci
1007159b3361Sopenharmony_ci                if (!mc) {
1008159b3361Sopenharmony_ci                    mc = *m++;
1009159b3361Sopenharmony_ci                    v = get_gain(gr_infos->pow2gain, ((*scf++) + (*pretab++)) << shift, &isbug);
1010159b3361Sopenharmony_ci                    cb = *m++;
1011159b3361Sopenharmony_ci                }
1012159b3361Sopenharmony_ci                {
1013159b3361Sopenharmony_ci                    short const *val = (short const *) h->table;
1014159b3361Sopenharmony_ci                    while ((y = *val++) < 0) {
1015159b3361Sopenharmony_ci                        if (get1bit(mp))
1016159b3361Sopenharmony_ci                            val -= y;
1017159b3361Sopenharmony_ci                        part2remain--;
1018159b3361Sopenharmony_ci                    }
1019159b3361Sopenharmony_ci                    x = y >> 4;
1020159b3361Sopenharmony_ci                    y &= 0xf;
1021159b3361Sopenharmony_ci                }
1022159b3361Sopenharmony_ci                if (x == 15) {
1023159b3361Sopenharmony_ci                    max = cb;
1024159b3361Sopenharmony_ci                    part2remain -= h->linbits + 1;
1025159b3361Sopenharmony_ci                    x += getbits(mp, (int) h->linbits);
1026159b3361Sopenharmony_ci                    if (get1bit(mp))
1027159b3361Sopenharmony_ci                        xr_value = -ispow[x] * v;
1028159b3361Sopenharmony_ci                    else
1029159b3361Sopenharmony_ci                        xr_value = ispow[x] * v;
1030159b3361Sopenharmony_ci                }
1031159b3361Sopenharmony_ci                else if (x) {
1032159b3361Sopenharmony_ci                    max = cb;
1033159b3361Sopenharmony_ci                    if (get1bit(mp))
1034159b3361Sopenharmony_ci                        xr_value = -ispow[x] * v;
1035159b3361Sopenharmony_ci                    else
1036159b3361Sopenharmony_ci                        xr_value = ispow[x] * v;
1037159b3361Sopenharmony_ci                    part2remain--;
1038159b3361Sopenharmony_ci                }
1039159b3361Sopenharmony_ci                else
1040159b3361Sopenharmony_ci                    xr_value = 0.0;
1041159b3361Sopenharmony_ci
1042159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
1043159b3361Sopenharmony_ci                    *xrpnt++ = xr_value;
1044159b3361Sopenharmony_ci                else
1045159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
1046159b3361Sopenharmony_ci
1047159b3361Sopenharmony_ci                if (y == 15) {
1048159b3361Sopenharmony_ci                    max = cb;
1049159b3361Sopenharmony_ci                    part2remain -= h->linbits + 1;
1050159b3361Sopenharmony_ci                    y += getbits(mp, (int) h->linbits);
1051159b3361Sopenharmony_ci                    if (get1bit(mp))
1052159b3361Sopenharmony_ci                        xr_value = -ispow[y] * v;
1053159b3361Sopenharmony_ci                    else
1054159b3361Sopenharmony_ci                        xr_value = ispow[y] * v;
1055159b3361Sopenharmony_ci                }
1056159b3361Sopenharmony_ci                else if (y) {
1057159b3361Sopenharmony_ci                    max = cb;
1058159b3361Sopenharmony_ci                    if (get1bit(mp))
1059159b3361Sopenharmony_ci                        xr_value = -ispow[y] * v;
1060159b3361Sopenharmony_ci                    else
1061159b3361Sopenharmony_ci                        xr_value = ispow[y] * v;
1062159b3361Sopenharmony_ci                    part2remain--;
1063159b3361Sopenharmony_ci                }
1064159b3361Sopenharmony_ci                else
1065159b3361Sopenharmony_ci                    xr_value = 0.0;
1066159b3361Sopenharmony_ci
1067159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
1068159b3361Sopenharmony_ci                    *xrpnt++ = xr_value;
1069159b3361Sopenharmony_ci                else
1070159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
1071159b3361Sopenharmony_ci            }
1072159b3361Sopenharmony_ci        }
1073159b3361Sopenharmony_ci
1074159b3361Sopenharmony_ci        /*
1075159b3361Sopenharmony_ci         * short (count1table) values
1076159b3361Sopenharmony_ci         */
1077159b3361Sopenharmony_ci        for (; l3 && (part2remain > 0); l3--) {
1078159b3361Sopenharmony_ci            struct newhuff const *h = (struct newhuff const *) (htc + gr_infos->count1table_select);
1079159b3361Sopenharmony_ci            short const *val = (short const *) h->table;
1080159b3361Sopenharmony_ci            short   a;
1081159b3361Sopenharmony_ci
1082159b3361Sopenharmony_ci            while ((a = *val++) < 0) {
1083159b3361Sopenharmony_ci                part2remain--;
1084159b3361Sopenharmony_ci                if (part2remain < 0) {
1085159b3361Sopenharmony_ci                    part2remain++;
1086159b3361Sopenharmony_ci                    a = 0;
1087159b3361Sopenharmony_ci                    break;
1088159b3361Sopenharmony_ci                }
1089159b3361Sopenharmony_ci                if (get1bit(mp))
1090159b3361Sopenharmony_ci                    val -= a;
1091159b3361Sopenharmony_ci            }
1092159b3361Sopenharmony_ci            for (i = 0; i < 4; i++) {
1093159b3361Sopenharmony_ci                if (!(i & 1)) {
1094159b3361Sopenharmony_ci                    if (!mc) {
1095159b3361Sopenharmony_ci                        mc = *m++;
1096159b3361Sopenharmony_ci                        cb = *m++;
1097159b3361Sopenharmony_ci                        v = get_gain(gr_infos->pow2gain, ((*scf++) + (*pretab++)) << shift, &isbug);
1098159b3361Sopenharmony_ci                    }
1099159b3361Sopenharmony_ci                    mc--;
1100159b3361Sopenharmony_ci                }
1101159b3361Sopenharmony_ci                if ((a & (0x8 >> i))) {
1102159b3361Sopenharmony_ci                    max = cb;
1103159b3361Sopenharmony_ci                    part2remain--;
1104159b3361Sopenharmony_ci                    if (part2remain < 0) {
1105159b3361Sopenharmony_ci                        part2remain++;
1106159b3361Sopenharmony_ci                        break;
1107159b3361Sopenharmony_ci                    }
1108159b3361Sopenharmony_ci                    if (get1bit(mp))
1109159b3361Sopenharmony_ci                        xr_value = -v;
1110159b3361Sopenharmony_ci                    else
1111159b3361Sopenharmony_ci                        xr_value = v;
1112159b3361Sopenharmony_ci                }
1113159b3361Sopenharmony_ci                else
1114159b3361Sopenharmony_ci                    xr_value = 0.0;
1115159b3361Sopenharmony_ci
1116159b3361Sopenharmony_ci                if (xrpnt <= xr_endptr)
1117159b3361Sopenharmony_ci                    *xrpnt++ = xr_value;
1118159b3361Sopenharmony_ci                else
1119159b3361Sopenharmony_ci                    BUFFER_OVERFLOW_BUG();
1120159b3361Sopenharmony_ci            }
1121159b3361Sopenharmony_ci        }
1122159b3361Sopenharmony_ci
1123159b3361Sopenharmony_ci        /*
1124159b3361Sopenharmony_ci         * zero part
1125159b3361Sopenharmony_ci         */
1126159b3361Sopenharmony_ci        while (xrpnt <= xr_endptr)
1127159b3361Sopenharmony_ci            *xrpnt++ = 0.0;
1128159b3361Sopenharmony_ci
1129159b3361Sopenharmony_ci        gr_infos->maxbandl = max + 1;
1130159b3361Sopenharmony_ci        gr_infos->maxb = longLimit[sfreq][gr_infos->maxbandl];
1131159b3361Sopenharmony_ci    }
1132159b3361Sopenharmony_ci#undef BUFFER_OVERFLOW_BUG
1133159b3361Sopenharmony_ci    if (bobug) {
1134159b3361Sopenharmony_ci        /* well, there was a bug report, where this happened!
1135159b3361Sopenharmony_ci           The problem was, that mixed blocks summed up to over 576,
1136159b3361Sopenharmony_ci           because of a wrong long/short switching index.
1137159b3361Sopenharmony_ci           It's likely, that the buffer overflow is fixed now, after correcting mixed block map.
1138159b3361Sopenharmony_ci        */
1139159b3361Sopenharmony_ci        lame_report_fnc
1140159b3361Sopenharmony_ci          (mp->report_err
1141159b3361Sopenharmony_ci          ,"hip: OOPS, part2remain=%d l3=%d cb=%d bv=%d region1=%d region2=%d b-type=%d mixed=%d\n"
1142159b3361Sopenharmony_ci          ,part2remain
1143159b3361Sopenharmony_ci          ,bobug_l3
1144159b3361Sopenharmony_ci          ,bobug_sb
1145159b3361Sopenharmony_ci          ,gr_infos->big_values
1146159b3361Sopenharmony_ci          ,gr_infos->region1start
1147159b3361Sopenharmony_ci          ,gr_infos->region2start
1148159b3361Sopenharmony_ci          ,gr_infos->block_type
1149159b3361Sopenharmony_ci          ,gr_infos->mixed_block_flag
1150159b3361Sopenharmony_ci          );
1151159b3361Sopenharmony_ci    }
1152159b3361Sopenharmony_ci    if (isbug) {
1153159b3361Sopenharmony_ci        /* there is a bug report, where there is trouble with IS coded short block gain.
1154159b3361Sopenharmony_ci           Is intensity stereo coding implementation correct? Likely not.
1155159b3361Sopenharmony_ci        */
1156159b3361Sopenharmony_ci        int i_stereo = 0;
1157159b3361Sopenharmony_ci        if (mp->fr.mode == MPG_MD_JOINT_STEREO) {
1158159b3361Sopenharmony_ci            i_stereo = mp->fr.mode_ext & 0x1;
1159159b3361Sopenharmony_ci        }
1160159b3361Sopenharmony_ci        lame_report_fnc
1161159b3361Sopenharmony_ci          (mp->report_err
1162159b3361Sopenharmony_ci          ,"hip: OOPS, 'gainpow2' buffer overflow  lsf=%d i-stereo=%d b-type=%d mixed=%d\n"
1163159b3361Sopenharmony_ci          ,mp->fr.lsf
1164159b3361Sopenharmony_ci          ,i_stereo
1165159b3361Sopenharmony_ci          ,gr_infos->block_type
1166159b3361Sopenharmony_ci          ,gr_infos->mixed_block_flag
1167159b3361Sopenharmony_ci          );
1168159b3361Sopenharmony_ci    }
1169159b3361Sopenharmony_ci
1170159b3361Sopenharmony_ci    while (part2remain > 16) {
1171159b3361Sopenharmony_ci        getbits(mp, 16); /* Dismiss stuffing Bits */
1172159b3361Sopenharmony_ci        part2remain -= 16;
1173159b3361Sopenharmony_ci    }
1174159b3361Sopenharmony_ci    if (part2remain > 0)
1175159b3361Sopenharmony_ci        getbits(mp, part2remain);
1176159b3361Sopenharmony_ci    else if (part2remain < 0) {
1177159b3361Sopenharmony_ci        lame_report_fnc(mp->report_err, "hip: Can't rewind stream by %d bits!\n", -part2remain);
1178159b3361Sopenharmony_ci        return 1;       /* -> error */
1179159b3361Sopenharmony_ci    }
1180159b3361Sopenharmony_ci    return 0;
1181159b3361Sopenharmony_ci}
1182159b3361Sopenharmony_ci
1183159b3361Sopenharmony_ci/* intensity position, transmitted via a scalefactor value, allowed range is 0 - 15 */
1184159b3361Sopenharmony_cistatic
1185159b3361Sopenharmony_ciint scalefac_to_is_pos(int sf)
1186159b3361Sopenharmony_ci{
1187159b3361Sopenharmony_ci    if (0 <= sf && sf <= 15)
1188159b3361Sopenharmony_ci        return sf;
1189159b3361Sopenharmony_ci    return (sf < 0 ? 0 : 15);
1190159b3361Sopenharmony_ci}
1191159b3361Sopenharmony_ci
1192159b3361Sopenharmony_ci/*
1193159b3361Sopenharmony_ci * III_stereo: calculate real channel values for Joint-I-Stereo-mode
1194159b3361Sopenharmony_ci */
1195159b3361Sopenharmony_cistatic void
1196159b3361Sopenharmony_ciIII_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT], int *scalefac,
1197159b3361Sopenharmony_ci             struct gr_info_s *gr_infos, int sfreq, int ms_stereo, int lsf)
1198159b3361Sopenharmony_ci{
1199159b3361Sopenharmony_ci    real(*xr)[SBLIMIT * SSLIMIT] = (real(*)[SBLIMIT * SSLIMIT]) xr_buf;
1200159b3361Sopenharmony_ci    struct bandInfoStruct const *bi = (struct bandInfoStruct const *) &bandInfo[sfreq];
1201159b3361Sopenharmony_ci    real   *tabl1, *tabl2;
1202159b3361Sopenharmony_ci
1203159b3361Sopenharmony_ci    if (lsf) {
1204159b3361Sopenharmony_ci        int     p = gr_infos->scalefac_compress & 0x1;
1205159b3361Sopenharmony_ci        if (ms_stereo) {
1206159b3361Sopenharmony_ci            tabl1 = pow1_2[p];
1207159b3361Sopenharmony_ci            tabl2 = pow2_2[p];
1208159b3361Sopenharmony_ci        }
1209159b3361Sopenharmony_ci        else {
1210159b3361Sopenharmony_ci            tabl1 = pow1_1[p];
1211159b3361Sopenharmony_ci            tabl2 = pow2_1[p];
1212159b3361Sopenharmony_ci        }
1213159b3361Sopenharmony_ci    }
1214159b3361Sopenharmony_ci    else {
1215159b3361Sopenharmony_ci        if (ms_stereo) {
1216159b3361Sopenharmony_ci            tabl1 = tan1_2;
1217159b3361Sopenharmony_ci            tabl2 = tan2_2;
1218159b3361Sopenharmony_ci        }
1219159b3361Sopenharmony_ci        else {
1220159b3361Sopenharmony_ci            tabl1 = tan1_1;
1221159b3361Sopenharmony_ci            tabl2 = tan2_1;
1222159b3361Sopenharmony_ci        }
1223159b3361Sopenharmony_ci    }
1224159b3361Sopenharmony_ci
1225159b3361Sopenharmony_ci    if (gr_infos->block_type == 2) {
1226159b3361Sopenharmony_ci        int     lwin, do_l = 0;
1227159b3361Sopenharmony_ci        if (gr_infos->mixed_block_flag)
1228159b3361Sopenharmony_ci            do_l = 1;
1229159b3361Sopenharmony_ci
1230159b3361Sopenharmony_ci        for (lwin = 0; lwin < 3; lwin++) { /* process each window */
1231159b3361Sopenharmony_ci            /* get first band with zero values */
1232159b3361Sopenharmony_ci            int     is_p, sb, idx, sfb = gr_infos->maxband[lwin]; /* sfb is minimal 3 for mixed mode */
1233159b3361Sopenharmony_ci            if (sfb > 3)
1234159b3361Sopenharmony_ci                do_l = 0;
1235159b3361Sopenharmony_ci
1236159b3361Sopenharmony_ci            for (; sfb < 12; sfb++) {
1237159b3361Sopenharmony_ci                is_p = scalefac[sfb * 3 + lwin - gr_infos->mixed_block_flag]; /* scale: 0-15 */
1238159b3361Sopenharmony_ci                is_p = scalefac_to_is_pos(is_p);
1239159b3361Sopenharmony_ci                if (is_p != 7) {
1240159b3361Sopenharmony_ci                    real    t1, t2;
1241159b3361Sopenharmony_ci                    sb = bi->shortDiff[sfb];
1242159b3361Sopenharmony_ci                    idx = bi->shortIdx[sfb] + lwin;
1243159b3361Sopenharmony_ci                    t1 = tabl1[is_p];
1244159b3361Sopenharmony_ci                    t2 = tabl2[is_p];
1245159b3361Sopenharmony_ci                    for (; sb > 0; sb--, idx += 3) {
1246159b3361Sopenharmony_ci                        real    v = xr[0][idx];
1247159b3361Sopenharmony_ci                        xr[0][idx] = v * t1;
1248159b3361Sopenharmony_ci                        xr[1][idx] = v * t2;
1249159b3361Sopenharmony_ci                    }
1250159b3361Sopenharmony_ci                }
1251159b3361Sopenharmony_ci            }
1252159b3361Sopenharmony_ci
1253159b3361Sopenharmony_ci#if 1
1254159b3361Sopenharmony_ci/* in the original: copy 10 to 11 , here: copy 11 to 12
1255159b3361Sopenharmony_cimaybe still wrong??? (copy 12 to 13?) */
1256159b3361Sopenharmony_ci            is_p = scalefac[11 * 3 + lwin - gr_infos->mixed_block_flag]; /* scale: 0-15 */
1257159b3361Sopenharmony_ci            sb = bi->shortDiff[12];
1258159b3361Sopenharmony_ci            idx = bi->shortIdx[12] + lwin;
1259159b3361Sopenharmony_ci#else
1260159b3361Sopenharmony_ci            is_p = scalefac[10 * 3 + lwin - gr_infos->mixed_block_flag]; /* scale: 0-15 */
1261159b3361Sopenharmony_ci            sb = bi->shortDiff[11];
1262159b3361Sopenharmony_ci            idx = bi->shortIdx[11] + lwin;
1263159b3361Sopenharmony_ci#endif
1264159b3361Sopenharmony_ci            is_p = scalefac_to_is_pos(is_p);
1265159b3361Sopenharmony_ci            if (is_p != 7) {
1266159b3361Sopenharmony_ci                real    t1, t2;
1267159b3361Sopenharmony_ci                t1 = tabl1[is_p];
1268159b3361Sopenharmony_ci                t2 = tabl2[is_p];
1269159b3361Sopenharmony_ci                for (; sb > 0; sb--, idx += 3) {
1270159b3361Sopenharmony_ci                    real    v = xr[0][idx];
1271159b3361Sopenharmony_ci                    xr[0][idx] = v * t1;
1272159b3361Sopenharmony_ci                    xr[1][idx] = v * t2;
1273159b3361Sopenharmony_ci                }
1274159b3361Sopenharmony_ci            }
1275159b3361Sopenharmony_ci        }               /* end for(lwin; .. ; . ) */
1276159b3361Sopenharmony_ci
1277159b3361Sopenharmony_ci        if (do_l) {
1278159b3361Sopenharmony_ci/* also check l-part, if ALL bands in the three windows are 'empty'
1279159b3361Sopenharmony_ci * and mode = mixed_mode
1280159b3361Sopenharmony_ci */
1281159b3361Sopenharmony_ci            int     sfb = gr_infos->maxbandl;
1282159b3361Sopenharmony_ci            int     idx = bi->longIdx[sfb];
1283159b3361Sopenharmony_ci
1284159b3361Sopenharmony_ci            for (; sfb < 8; sfb++) {
1285159b3361Sopenharmony_ci                int     sb = bi->longDiff[sfb];
1286159b3361Sopenharmony_ci                int     is_p = scalefac[sfb]; /* scale: 0-15 */
1287159b3361Sopenharmony_ci                is_p = scalefac_to_is_pos(is_p);
1288159b3361Sopenharmony_ci                if (is_p != 7) {
1289159b3361Sopenharmony_ci                    real    t1, t2;
1290159b3361Sopenharmony_ci                    t1 = tabl1[is_p];
1291159b3361Sopenharmony_ci                    t2 = tabl2[is_p];
1292159b3361Sopenharmony_ci                    for (; sb > 0; sb--, idx++) {
1293159b3361Sopenharmony_ci                        real    v = xr[0][idx];
1294159b3361Sopenharmony_ci                        xr[0][idx] = v * t1;
1295159b3361Sopenharmony_ci                        xr[1][idx] = v * t2;
1296159b3361Sopenharmony_ci                    }
1297159b3361Sopenharmony_ci                }
1298159b3361Sopenharmony_ci                else
1299159b3361Sopenharmony_ci                    idx += sb;
1300159b3361Sopenharmony_ci            }
1301159b3361Sopenharmony_ci        }
1302159b3361Sopenharmony_ci    }
1303159b3361Sopenharmony_ci    else {              /* ((gr_infos->block_type != 2)) */
1304159b3361Sopenharmony_ci
1305159b3361Sopenharmony_ci        int     sfb = gr_infos->maxbandl;
1306159b3361Sopenharmony_ci        int     is_p, idx = bi->longIdx[sfb];
1307159b3361Sopenharmony_ci        for (; sfb < 21; sfb++) {
1308159b3361Sopenharmony_ci            int     sb = bi->longDiff[sfb];
1309159b3361Sopenharmony_ci            is_p = scalefac[sfb]; /* scale: 0-15 */
1310159b3361Sopenharmony_ci            is_p = scalefac_to_is_pos(is_p);
1311159b3361Sopenharmony_ci            if (is_p != 7) {
1312159b3361Sopenharmony_ci                real    t1, t2;
1313159b3361Sopenharmony_ci                t1 = tabl1[is_p];
1314159b3361Sopenharmony_ci                t2 = tabl2[is_p];
1315159b3361Sopenharmony_ci                for (; sb > 0; sb--, idx++) {
1316159b3361Sopenharmony_ci                    real    v = xr[0][idx];
1317159b3361Sopenharmony_ci                    xr[0][idx] = v * t1;
1318159b3361Sopenharmony_ci                    xr[1][idx] = v * t2;
1319159b3361Sopenharmony_ci                }
1320159b3361Sopenharmony_ci            }
1321159b3361Sopenharmony_ci            else
1322159b3361Sopenharmony_ci                idx += sb;
1323159b3361Sopenharmony_ci        }
1324159b3361Sopenharmony_ci
1325159b3361Sopenharmony_ci        is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */
1326159b3361Sopenharmony_ci        is_p = scalefac_to_is_pos(is_p);
1327159b3361Sopenharmony_ci        idx = bi->longIdx[21];
1328159b3361Sopenharmony_ci        if (is_p != 7) {
1329159b3361Sopenharmony_ci            int     sb;
1330159b3361Sopenharmony_ci            real    t1 = tabl1[is_p], t2 = tabl2[is_p];
1331159b3361Sopenharmony_ci
1332159b3361Sopenharmony_ci            for (sb = bi->longDiff[21]; sb > 0; sb--, idx++) {
1333159b3361Sopenharmony_ci                real    v = xr[0][idx];
1334159b3361Sopenharmony_ci                xr[0][idx] = v * t1;
1335159b3361Sopenharmony_ci                xr[1][idx] = v * t2;
1336159b3361Sopenharmony_ci            }
1337159b3361Sopenharmony_ci        }
1338159b3361Sopenharmony_ci    }                   /* ... */
1339159b3361Sopenharmony_ci}
1340159b3361Sopenharmony_ci
1341159b3361Sopenharmony_cistatic void
1342159b3361Sopenharmony_ciIII_antialias(real xr[SBLIMIT][SSLIMIT], struct gr_info_s *gr_infos)
1343159b3361Sopenharmony_ci{
1344159b3361Sopenharmony_ci    int     sblim;
1345159b3361Sopenharmony_ci
1346159b3361Sopenharmony_ci    if (gr_infos->block_type == 2) {
1347159b3361Sopenharmony_ci        if (!gr_infos->mixed_block_flag)
1348159b3361Sopenharmony_ci            return;
1349159b3361Sopenharmony_ci        sblim = 1;
1350159b3361Sopenharmony_ci    }
1351159b3361Sopenharmony_ci    else {
1352159b3361Sopenharmony_ci        sblim = gr_infos->maxb - 1;
1353159b3361Sopenharmony_ci    }
1354159b3361Sopenharmony_ci
1355159b3361Sopenharmony_ci    /* 31 alias-reduction operations between each pair of sub-bands */
1356159b3361Sopenharmony_ci    /* with 8 butterflies between each pair                         */
1357159b3361Sopenharmony_ci
1358159b3361Sopenharmony_ci    {
1359159b3361Sopenharmony_ci        int     sb;
1360159b3361Sopenharmony_ci        real   *xr1 = (real *) xr[1];
1361159b3361Sopenharmony_ci
1362159b3361Sopenharmony_ci        for (sb = sblim; sb; sb--, xr1 += 10) {
1363159b3361Sopenharmony_ci            int     ss;
1364159b3361Sopenharmony_ci            real   *cs = aa_cs, *ca = aa_ca;
1365159b3361Sopenharmony_ci            real   *xr2 = xr1;
1366159b3361Sopenharmony_ci
1367159b3361Sopenharmony_ci            for (ss = 7; ss >= 0; ss--) { /* upper and lower butterfly inputs */
1368159b3361Sopenharmony_ci                real    bu = *--xr2, bd = *xr1;
1369159b3361Sopenharmony_ci                *xr2 = (bu * (*cs)) - (bd * (*ca));
1370159b3361Sopenharmony_ci                *xr1++ = (bd * (*cs++)) + (bu * (*ca++));
1371159b3361Sopenharmony_ci            }
1372159b3361Sopenharmony_ci        }
1373159b3361Sopenharmony_ci    }
1374159b3361Sopenharmony_ci}
1375159b3361Sopenharmony_ci
1376159b3361Sopenharmony_ci
1377159b3361Sopenharmony_ci/* *INDENT-OFF* */
1378159b3361Sopenharmony_ci
1379159b3361Sopenharmony_ci/*
1380159b3361Sopenharmony_ci DCT insipired by Jeff Tsay's DCT from the maplay package
1381159b3361Sopenharmony_ci this is an optimized version with manual unroll.
1382159b3361Sopenharmony_ci
1383159b3361Sopenharmony_ci References:
1384159b3361Sopenharmony_ci [1] S. Winograd: "On Computing the Discrete Fourier Transform",
1385159b3361Sopenharmony_ci     Mathematics of Computation, Volume 32, Number 141, January 1978,
1386159b3361Sopenharmony_ci     Pages 175-199
1387159b3361Sopenharmony_ci*/
1388159b3361Sopenharmony_ci
1389159b3361Sopenharmony_cistatic void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf)
1390159b3361Sopenharmony_ci{
1391159b3361Sopenharmony_ci  {
1392159b3361Sopenharmony_ci    real *in = inbuf;
1393159b3361Sopenharmony_ci
1394159b3361Sopenharmony_ci    in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
1395159b3361Sopenharmony_ci    in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
1396159b3361Sopenharmony_ci    in[11]+=in[10]; in[10]+=in[9];  in[9] +=in[8];
1397159b3361Sopenharmony_ci    in[8] +=in[7];  in[7] +=in[6];  in[6] +=in[5];
1398159b3361Sopenharmony_ci    in[5] +=in[4];  in[4] +=in[3];  in[3] +=in[2];
1399159b3361Sopenharmony_ci    in[2] +=in[1];  in[1] +=in[0];
1400159b3361Sopenharmony_ci
1401159b3361Sopenharmony_ci    in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
1402159b3361Sopenharmony_ci    in[9] +=in[7];  in[7] +=in[5];  in[5] +=in[3];  in[3] +=in[1];
1403159b3361Sopenharmony_ci
1404159b3361Sopenharmony_ci  {
1405159b3361Sopenharmony_ci
1406159b3361Sopenharmony_ci#define MACRO0(v) { \
1407159b3361Sopenharmony_ci    real tmp; \
1408159b3361Sopenharmony_ci    out2[9+(v)] = (tmp = sum0 + sum1) * w[27+(v)]; \
1409159b3361Sopenharmony_ci    out2[8-(v)] = tmp * w[26-(v)];  } \
1410159b3361Sopenharmony_ci    sum0 -= sum1; \
1411159b3361Sopenharmony_ci    ts[SBLIMIT*(8-(v))] = out1[8-(v)] + sum0 * w[8-(v)]; \
1412159b3361Sopenharmony_ci    ts[SBLIMIT*(9+(v))] = out1[9+(v)] + sum0 * w[9+(v)];
1413159b3361Sopenharmony_ci#define MACRO1(v) { \
1414159b3361Sopenharmony_ci    real sum0,sum1; \
1415159b3361Sopenharmony_ci    sum0 = tmp1a + tmp2a; \
1416159b3361Sopenharmony_ci    sum1 = (tmp1b + tmp2b) * tfcos36[(v)]; \
1417159b3361Sopenharmony_ci    MACRO0(v); }
1418159b3361Sopenharmony_ci#define MACRO2(v) { \
1419159b3361Sopenharmony_ci    real sum0,sum1; \
1420159b3361Sopenharmony_ci    sum0 = tmp2a - tmp1a; \
1421159b3361Sopenharmony_ci    sum1 = (tmp2b - tmp1b) * tfcos36[(v)]; \
1422159b3361Sopenharmony_ci    MACRO0(v); }
1423159b3361Sopenharmony_ci
1424159b3361Sopenharmony_ci    const real *c = COS9;
1425159b3361Sopenharmony_ci    real *out2 = o2;
1426159b3361Sopenharmony_ci    real *w = wintab;
1427159b3361Sopenharmony_ci    real *out1 = o1;
1428159b3361Sopenharmony_ci    real *ts = tsbuf;
1429159b3361Sopenharmony_ci
1430159b3361Sopenharmony_ci    real ta33,ta66,tb33,tb66;
1431159b3361Sopenharmony_ci
1432159b3361Sopenharmony_ci    ta33 = in[2*3+0] * c[3];
1433159b3361Sopenharmony_ci    ta66 = in[2*6+0] * c[6];
1434159b3361Sopenharmony_ci    tb33 = in[2*3+1] * c[3];
1435159b3361Sopenharmony_ci    tb66 = in[2*6+1] * c[6];
1436159b3361Sopenharmony_ci
1437159b3361Sopenharmony_ci    {
1438159b3361Sopenharmony_ci      real tmp1a,tmp2a,tmp1b,tmp2b;
1439159b3361Sopenharmony_ci      tmp1a =             in[2*1+0] * c[1] + ta33 + in[2*5+0] * c[5] + in[2*7+0] * c[7];
1440159b3361Sopenharmony_ci      tmp1b =             in[2*1+1] * c[1] + tb33 + in[2*5+1] * c[5] + in[2*7+1] * c[7];
1441159b3361Sopenharmony_ci      tmp2a = in[2*0+0] + in[2*2+0] * c[2] + in[2*4+0] * c[4] + ta66 + in[2*8+0] * c[8];
1442159b3361Sopenharmony_ci      tmp2b = in[2*0+1] + in[2*2+1] * c[2] + in[2*4+1] * c[4] + tb66 + in[2*8+1] * c[8];
1443159b3361Sopenharmony_ci
1444159b3361Sopenharmony_ci      MACRO1(0);
1445159b3361Sopenharmony_ci      MACRO2(8);
1446159b3361Sopenharmony_ci    }
1447159b3361Sopenharmony_ci
1448159b3361Sopenharmony_ci    {
1449159b3361Sopenharmony_ci      real tmp1a,tmp2a,tmp1b,tmp2b;
1450159b3361Sopenharmony_ci      tmp1a = ( in[2*1+0] - in[2*5+0] - in[2*7+0] ) * c[3];
1451159b3361Sopenharmony_ci      tmp1b = ( in[2*1+1] - in[2*5+1] - in[2*7+1] ) * c[3];
1452159b3361Sopenharmony_ci      tmp2a = ( in[2*2+0] - in[2*4+0] - in[2*8+0] ) * c[6] - in[2*6+0] + in[2*0+0];
1453159b3361Sopenharmony_ci      tmp2b = ( in[2*2+1] - in[2*4+1] - in[2*8+1] ) * c[6] - in[2*6+1] + in[2*0+1];
1454159b3361Sopenharmony_ci
1455159b3361Sopenharmony_ci      MACRO1(1);
1456159b3361Sopenharmony_ci      MACRO2(7);
1457159b3361Sopenharmony_ci    }
1458159b3361Sopenharmony_ci
1459159b3361Sopenharmony_ci    {
1460159b3361Sopenharmony_ci      real tmp1a,tmp2a,tmp1b,tmp2b;
1461159b3361Sopenharmony_ci      tmp1a =             in[2*1+0] * c[5] - ta33 - in[2*5+0] * c[7] + in[2*7+0] * c[1];
1462159b3361Sopenharmony_ci      tmp1b =             in[2*1+1] * c[5] - tb33 - in[2*5+1] * c[7] + in[2*7+1] * c[1];
1463159b3361Sopenharmony_ci      tmp2a = in[2*0+0] - in[2*2+0] * c[8] - in[2*4+0] * c[2] + ta66 + in[2*8+0] * c[4];
1464159b3361Sopenharmony_ci      tmp2b = in[2*0+1] - in[2*2+1] * c[8] - in[2*4+1] * c[2] + tb66 + in[2*8+1] * c[4];
1465159b3361Sopenharmony_ci
1466159b3361Sopenharmony_ci      MACRO1(2);
1467159b3361Sopenharmony_ci      MACRO2(6);
1468159b3361Sopenharmony_ci    }
1469159b3361Sopenharmony_ci
1470159b3361Sopenharmony_ci    {
1471159b3361Sopenharmony_ci      real tmp1a,tmp2a,tmp1b,tmp2b;
1472159b3361Sopenharmony_ci      tmp1a =             in[2*1+0] * c[7] - ta33 + in[2*5+0] * c[1] - in[2*7+0] * c[5];
1473159b3361Sopenharmony_ci      tmp1b =             in[2*1+1] * c[7] - tb33 + in[2*5+1] * c[1] - in[2*7+1] * c[5];
1474159b3361Sopenharmony_ci      tmp2a = in[2*0+0] - in[2*2+0] * c[4] + in[2*4+0] * c[8] + ta66 - in[2*8+0] * c[2];
1475159b3361Sopenharmony_ci      tmp2b = in[2*0+1] - in[2*2+1] * c[4] + in[2*4+1] * c[8] + tb66 - in[2*8+1] * c[2];
1476159b3361Sopenharmony_ci
1477159b3361Sopenharmony_ci      MACRO1(3);
1478159b3361Sopenharmony_ci      MACRO2(5);
1479159b3361Sopenharmony_ci    }
1480159b3361Sopenharmony_ci
1481159b3361Sopenharmony_ci    {
1482159b3361Sopenharmony_ci      real sum0,sum1;
1483159b3361Sopenharmony_ci      sum0 =  in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0];
1484159b3361Sopenharmony_ci      sum1 = (in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ) * tfcos36[4];
1485159b3361Sopenharmony_ci      MACRO0(4);
1486159b3361Sopenharmony_ci    }
1487159b3361Sopenharmony_ci  }
1488159b3361Sopenharmony_ci
1489159b3361Sopenharmony_ci  }
1490159b3361Sopenharmony_ci}
1491159b3361Sopenharmony_ci
1492159b3361Sopenharmony_ci
1493159b3361Sopenharmony_ci/*
1494159b3361Sopenharmony_ci * new DCT12
1495159b3361Sopenharmony_ci */
1496159b3361Sopenharmony_cistatic void dct12(real *in,real *rawout1,real *rawout2,real *wi,real *ts)
1497159b3361Sopenharmony_ci{
1498159b3361Sopenharmony_ci#define DCT12_PART1 \
1499159b3361Sopenharmony_ci             in5 = in[5*3];  \
1500159b3361Sopenharmony_ci     in5 += (in4 = in[4*3]); \
1501159b3361Sopenharmony_ci     in4 += (in3 = in[3*3]); \
1502159b3361Sopenharmony_ci     in3 += (in2 = in[2*3]); \
1503159b3361Sopenharmony_ci     in2 += (in1 = in[1*3]); \
1504159b3361Sopenharmony_ci     in1 += (in0 = in[0*3]); \
1505159b3361Sopenharmony_ci                             \
1506159b3361Sopenharmony_ci     in5 += in3; in3 += in1; \
1507159b3361Sopenharmony_ci                             \
1508159b3361Sopenharmony_ci     in2 *= COS6_1; \
1509159b3361Sopenharmony_ci     in3 *= COS6_1; \
1510159b3361Sopenharmony_ci
1511159b3361Sopenharmony_ci#define DCT12_PART2 \
1512159b3361Sopenharmony_ci     in0 += in4 * COS6_2; \
1513159b3361Sopenharmony_ci                          \
1514159b3361Sopenharmony_ci     in4 = in0 + in2;     \
1515159b3361Sopenharmony_ci     in0 -= in2;          \
1516159b3361Sopenharmony_ci                          \
1517159b3361Sopenharmony_ci     in1 += in5 * COS6_2; \
1518159b3361Sopenharmony_ci                          \
1519159b3361Sopenharmony_ci     in5 = (in1 + in3) * tfcos12[0]; \
1520159b3361Sopenharmony_ci     in1 = (in1 - in3) * tfcos12[2]; \
1521159b3361Sopenharmony_ci                         \
1522159b3361Sopenharmony_ci     in3 = in4 + in5;    \
1523159b3361Sopenharmony_ci     in4 -= in5;         \
1524159b3361Sopenharmony_ci                         \
1525159b3361Sopenharmony_ci     in2 = in0 + in1;    \
1526159b3361Sopenharmony_ci     in0 -= in1;
1527159b3361Sopenharmony_ci
1528159b3361Sopenharmony_ci
1529159b3361Sopenharmony_ci   {
1530159b3361Sopenharmony_ci     real in0,in1,in2,in3,in4,in5;
1531159b3361Sopenharmony_ci     real *out1 = rawout1;
1532159b3361Sopenharmony_ci     ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
1533159b3361Sopenharmony_ci     ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
1534159b3361Sopenharmony_ci
1535159b3361Sopenharmony_ci     DCT12_PART1
1536159b3361Sopenharmony_ci
1537159b3361Sopenharmony_ci     {
1538159b3361Sopenharmony_ci       real tmp0,tmp1 = (in0 - in4);
1539159b3361Sopenharmony_ci       {
1540159b3361Sopenharmony_ci         real tmp2 = (in1 - in5) * tfcos12[1];
1541159b3361Sopenharmony_ci         tmp0 = tmp1 + tmp2;
1542159b3361Sopenharmony_ci         tmp1 -= tmp2;
1543159b3361Sopenharmony_ci       }
1544159b3361Sopenharmony_ci       ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1];
1545159b3361Sopenharmony_ci       ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1];
1546159b3361Sopenharmony_ci       ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1];
1547159b3361Sopenharmony_ci       ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1];
1548159b3361Sopenharmony_ci     }
1549159b3361Sopenharmony_ci
1550159b3361Sopenharmony_ci     DCT12_PART2
1551159b3361Sopenharmony_ci
1552159b3361Sopenharmony_ci     ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0];
1553159b3361Sopenharmony_ci     ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0];
1554159b3361Sopenharmony_ci     ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2];
1555159b3361Sopenharmony_ci     ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2];
1556159b3361Sopenharmony_ci
1557159b3361Sopenharmony_ci     ts[(6+0)*SBLIMIT]  = out1[6+0] + in0 * wi[0];
1558159b3361Sopenharmony_ci     ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0];
1559159b3361Sopenharmony_ci     ts[(6+2)*SBLIMIT]  = out1[6+2] + in4 * wi[2];
1560159b3361Sopenharmony_ci     ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2];
1561159b3361Sopenharmony_ci  }
1562159b3361Sopenharmony_ci
1563159b3361Sopenharmony_ci  in++;
1564159b3361Sopenharmony_ci
1565159b3361Sopenharmony_ci  {
1566159b3361Sopenharmony_ci     real in0,in1,in2,in3,in4,in5;
1567159b3361Sopenharmony_ci     real *out2 = rawout2;
1568159b3361Sopenharmony_ci
1569159b3361Sopenharmony_ci     DCT12_PART1
1570159b3361Sopenharmony_ci
1571159b3361Sopenharmony_ci     {
1572159b3361Sopenharmony_ci       real tmp0,tmp1 = (in0 - in4);
1573159b3361Sopenharmony_ci       {
1574159b3361Sopenharmony_ci         real tmp2 = (in1 - in5) * tfcos12[1];
1575159b3361Sopenharmony_ci         tmp0 = tmp1 + tmp2;
1576159b3361Sopenharmony_ci         tmp1 -= tmp2;
1577159b3361Sopenharmony_ci       }
1578159b3361Sopenharmony_ci       out2[5-1] = tmp0 * wi[11-1];
1579159b3361Sopenharmony_ci       out2[0+1] = tmp0 * wi[6+1];
1580159b3361Sopenharmony_ci       ts[(12+1)*SBLIMIT] += tmp1 * wi[1];
1581159b3361Sopenharmony_ci       ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1];
1582159b3361Sopenharmony_ci     }
1583159b3361Sopenharmony_ci
1584159b3361Sopenharmony_ci     DCT12_PART2
1585159b3361Sopenharmony_ci
1586159b3361Sopenharmony_ci     out2[5-0] = in2 * wi[11-0];
1587159b3361Sopenharmony_ci     out2[0+0] = in2 * wi[6+0];
1588159b3361Sopenharmony_ci     out2[0+2] = in3 * wi[6+2];
1589159b3361Sopenharmony_ci     out2[5-2] = in3 * wi[11-2];
1590159b3361Sopenharmony_ci
1591159b3361Sopenharmony_ci     ts[(12+0)*SBLIMIT] += in0 * wi[0];
1592159b3361Sopenharmony_ci     ts[(17-0)*SBLIMIT] += in0 * wi[5-0];
1593159b3361Sopenharmony_ci     ts[(12+2)*SBLIMIT] += in4 * wi[2];
1594159b3361Sopenharmony_ci     ts[(17-2)*SBLIMIT] += in4 * wi[5-2];
1595159b3361Sopenharmony_ci  }
1596159b3361Sopenharmony_ci
1597159b3361Sopenharmony_ci  in++;
1598159b3361Sopenharmony_ci
1599159b3361Sopenharmony_ci  {
1600159b3361Sopenharmony_ci     real in0,in1,in2,in3,in4,in5;
1601159b3361Sopenharmony_ci     real *out2 = rawout2;
1602159b3361Sopenharmony_ci     out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
1603159b3361Sopenharmony_ci
1604159b3361Sopenharmony_ci     DCT12_PART1
1605159b3361Sopenharmony_ci
1606159b3361Sopenharmony_ci     {
1607159b3361Sopenharmony_ci       real tmp0,tmp1 = (in0 - in4);
1608159b3361Sopenharmony_ci       {
1609159b3361Sopenharmony_ci         real tmp2 = (in1 - in5) * tfcos12[1];
1610159b3361Sopenharmony_ci         tmp0 = tmp1 + tmp2;
1611159b3361Sopenharmony_ci         tmp1 -= tmp2;
1612159b3361Sopenharmony_ci       }
1613159b3361Sopenharmony_ci       out2[11-1] = tmp0 * wi[11-1];
1614159b3361Sopenharmony_ci       out2[6 +1] = tmp0 * wi[6+1];
1615159b3361Sopenharmony_ci       out2[0+1] += tmp1 * wi[1];
1616159b3361Sopenharmony_ci       out2[5-1] += tmp1 * wi[5-1];
1617159b3361Sopenharmony_ci     }
1618159b3361Sopenharmony_ci
1619159b3361Sopenharmony_ci     DCT12_PART2
1620159b3361Sopenharmony_ci
1621159b3361Sopenharmony_ci     out2[11-0] = in2 * wi[11-0];
1622159b3361Sopenharmony_ci     out2[6 +0] = in2 * wi[6+0];
1623159b3361Sopenharmony_ci     out2[6 +2] = in3 * wi[6+2];
1624159b3361Sopenharmony_ci     out2[11-2] = in3 * wi[11-2];
1625159b3361Sopenharmony_ci
1626159b3361Sopenharmony_ci     out2[0+0] += in0 * wi[0];
1627159b3361Sopenharmony_ci     out2[5-0] += in0 * wi[5-0];
1628159b3361Sopenharmony_ci     out2[0+2] += in4 * wi[2];
1629159b3361Sopenharmony_ci     out2[5-2] += in4 * wi[5-2];
1630159b3361Sopenharmony_ci  }
1631159b3361Sopenharmony_ci}
1632159b3361Sopenharmony_ci/* *INDENT-ON* */
1633159b3361Sopenharmony_ci
1634159b3361Sopenharmony_ci/*
1635159b3361Sopenharmony_ci * III_hybrid
1636159b3361Sopenharmony_ci */
1637159b3361Sopenharmony_cistatic void
1638159b3361Sopenharmony_ciIII_hybrid(PMPSTR mp, real fsIn[SBLIMIT][SSLIMIT], real tsOut[SSLIMIT][SBLIMIT],
1639159b3361Sopenharmony_ci           int ch, struct gr_info_s *gr_infos)
1640159b3361Sopenharmony_ci{
1641159b3361Sopenharmony_ci    real   *tspnt = (real *) tsOut;
1642159b3361Sopenharmony_ci    real(*block)[2][SBLIMIT * SSLIMIT] = mp->hybrid_block;
1643159b3361Sopenharmony_ci    int    *blc = mp->hybrid_blc;
1644159b3361Sopenharmony_ci    real   *rawout1, *rawout2;
1645159b3361Sopenharmony_ci    int     bt;
1646159b3361Sopenharmony_ci    int     sb = 0;
1647159b3361Sopenharmony_ci
1648159b3361Sopenharmony_ci    {
1649159b3361Sopenharmony_ci        int     b = blc[ch];
1650159b3361Sopenharmony_ci        rawout1 = block[b][ch];
1651159b3361Sopenharmony_ci        b = -b + 1;
1652159b3361Sopenharmony_ci        rawout2 = block[b][ch];
1653159b3361Sopenharmony_ci        blc[ch] = b;
1654159b3361Sopenharmony_ci    }
1655159b3361Sopenharmony_ci
1656159b3361Sopenharmony_ci
1657159b3361Sopenharmony_ci    if (gr_infos->mixed_block_flag) {
1658159b3361Sopenharmony_ci        sb = 2;
1659159b3361Sopenharmony_ci        dct36(fsIn[0], rawout1, rawout2, win[0], tspnt);
1660159b3361Sopenharmony_ci        dct36(fsIn[1], rawout1 + 18, rawout2 + 18, win1[0], tspnt + 1);
1661159b3361Sopenharmony_ci        rawout1 += 36;
1662159b3361Sopenharmony_ci        rawout2 += 36;
1663159b3361Sopenharmony_ci        tspnt += 2;
1664159b3361Sopenharmony_ci    }
1665159b3361Sopenharmony_ci
1666159b3361Sopenharmony_ci    bt = gr_infos->block_type;
1667159b3361Sopenharmony_ci    if (bt == 2) {
1668159b3361Sopenharmony_ci        for (; sb < (int) gr_infos->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36) {
1669159b3361Sopenharmony_ci            dct12(fsIn[sb], rawout1, rawout2, win[2], tspnt);
1670159b3361Sopenharmony_ci            dct12(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, win1[2], tspnt + 1);
1671159b3361Sopenharmony_ci        }
1672159b3361Sopenharmony_ci    }
1673159b3361Sopenharmony_ci    else {
1674159b3361Sopenharmony_ci        for (; sb < (int) gr_infos->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36) {
1675159b3361Sopenharmony_ci            dct36(fsIn[sb], rawout1, rawout2, win[bt], tspnt);
1676159b3361Sopenharmony_ci            dct36(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, win1[bt], tspnt + 1);
1677159b3361Sopenharmony_ci        }
1678159b3361Sopenharmony_ci    }
1679159b3361Sopenharmony_ci
1680159b3361Sopenharmony_ci    for (; sb < SBLIMIT; sb++, tspnt++) {
1681159b3361Sopenharmony_ci        int     i;
1682159b3361Sopenharmony_ci        for (i = 0; i < SSLIMIT; i++) {
1683159b3361Sopenharmony_ci            tspnt[i * SBLIMIT] = *rawout1++;
1684159b3361Sopenharmony_ci            *rawout2++ = 0.0;
1685159b3361Sopenharmony_ci        }
1686159b3361Sopenharmony_ci    }
1687159b3361Sopenharmony_ci}
1688159b3361Sopenharmony_ci
1689159b3361Sopenharmony_ci/*
1690159b3361Sopenharmony_ci * main layer3 handler
1691159b3361Sopenharmony_ci */
1692159b3361Sopenharmony_ci
1693159b3361Sopenharmony_ciint
1694159b3361Sopenharmony_cilayer3_audiodata_precedesframes(PMPSTR mp)
1695159b3361Sopenharmony_ci{
1696159b3361Sopenharmony_ci    int     audioDataInFrame;
1697159b3361Sopenharmony_ci    int     framesToBacktrack;
1698159b3361Sopenharmony_ci
1699159b3361Sopenharmony_ci    /* specific to Layer 3, since Layer 1 & 2 the audio data starts at the frame that describes it. */
1700159b3361Sopenharmony_ci    /* determine how many bytes and therefore bitstream frames the audio data precedes it's matching frame */
1701159b3361Sopenharmony_ci    /* lame_report_fnc(mp->report_err, "hip: main_data_begin = %d, mp->bsize %d, mp->fsizeold %d, mp->ssize %d\n",
1702159b3361Sopenharmony_ci       sideinfo.main_data_begin, mp->bsize, mp->fsizeold, mp->ssize); */
1703159b3361Sopenharmony_ci    /* compute the number of frames to backtrack, 4 for the header, ssize already holds the CRC */
1704159b3361Sopenharmony_ci    /* TODO Erroneously assumes current frame is same as previous frame. */
1705159b3361Sopenharmony_ci    audioDataInFrame = mp->bsize - 4 - mp->ssize;
1706159b3361Sopenharmony_ci    framesToBacktrack = (mp->sideinfo.main_data_begin + audioDataInFrame - 1) / audioDataInFrame;
1707159b3361Sopenharmony_ci    /* lame_report_fnc(mp->report_err, "hip: audioDataInFrame %d framesToBacktrack %d\n", audioDataInFrame, framesToBacktrack); */
1708159b3361Sopenharmony_ci    return framesToBacktrack;
1709159b3361Sopenharmony_ci}
1710159b3361Sopenharmony_ci
1711159b3361Sopenharmony_ciint
1712159b3361Sopenharmony_cidecode_layer3_sideinfo(PMPSTR mp)
1713159b3361Sopenharmony_ci{
1714159b3361Sopenharmony_ci    struct frame *fr = &mp->fr;
1715159b3361Sopenharmony_ci    int     stereo = fr->stereo;
1716159b3361Sopenharmony_ci    int     single = fr->single;
1717159b3361Sopenharmony_ci    int     ms_stereo;
1718159b3361Sopenharmony_ci    int     sfreq = fr->sampling_frequency;
1719159b3361Sopenharmony_ci    int     granules;
1720159b3361Sopenharmony_ci    int     ch, gr, databits;
1721159b3361Sopenharmony_ci
1722159b3361Sopenharmony_ci    if (stereo == 1) {  /* stream is mono */
1723159b3361Sopenharmony_ci        single = 0;
1724159b3361Sopenharmony_ci    }
1725159b3361Sopenharmony_ci
1726159b3361Sopenharmony_ci    if (fr->mode == MPG_MD_JOINT_STEREO) {
1727159b3361Sopenharmony_ci        ms_stereo = fr->mode_ext & 0x2;
1728159b3361Sopenharmony_ci    }
1729159b3361Sopenharmony_ci    else
1730159b3361Sopenharmony_ci        ms_stereo = 0;
1731159b3361Sopenharmony_ci
1732159b3361Sopenharmony_ci
1733159b3361Sopenharmony_ci    if (fr->lsf) {
1734159b3361Sopenharmony_ci        granules = 1;
1735159b3361Sopenharmony_ci        III_get_side_info_2(mp, stereo, ms_stereo, sfreq, single);
1736159b3361Sopenharmony_ci    }
1737159b3361Sopenharmony_ci    else {
1738159b3361Sopenharmony_ci        granules = 2;
1739159b3361Sopenharmony_ci        III_get_side_info_1(mp, stereo, ms_stereo, sfreq, single);
1740159b3361Sopenharmony_ci    }
1741159b3361Sopenharmony_ci
1742159b3361Sopenharmony_ci    databits = 0;
1743159b3361Sopenharmony_ci    for (gr = 0; gr < granules; ++gr) {
1744159b3361Sopenharmony_ci        for (ch = 0; ch < stereo; ++ch) {
1745159b3361Sopenharmony_ci            struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[gr]);
1746159b3361Sopenharmony_ci            databits += gr_infos->part2_3_length;
1747159b3361Sopenharmony_ci        }
1748159b3361Sopenharmony_ci    }
1749159b3361Sopenharmony_ci    return databits - 8 * mp->sideinfo.main_data_begin;
1750159b3361Sopenharmony_ci}
1751159b3361Sopenharmony_ci
1752159b3361Sopenharmony_ci
1753159b3361Sopenharmony_ci
1754159b3361Sopenharmony_ciint
1755159b3361Sopenharmony_cidecode_layer3_frame(PMPSTR mp, unsigned char *pcm_sample, int *pcm_point,
1756159b3361Sopenharmony_ci          int (*synth_1to1_mono_ptr) (PMPSTR, real *, unsigned char *, int *),
1757159b3361Sopenharmony_ci          int (*synth_1to1_ptr) (PMPSTR, real *, int, unsigned char *, int *))
1758159b3361Sopenharmony_ci{
1759159b3361Sopenharmony_ci    int     gr, ch, ss, clip = 0;
1760159b3361Sopenharmony_ci    int     scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
1761159b3361Sopenharmony_ci    /*  struct III_sideinfo sideinfo; */
1762159b3361Sopenharmony_ci    struct frame *fr = &(mp->fr);
1763159b3361Sopenharmony_ci    int     stereo = fr->stereo;
1764159b3361Sopenharmony_ci    int     single = fr->single;
1765159b3361Sopenharmony_ci    int     ms_stereo, i_stereo;
1766159b3361Sopenharmony_ci    int     sfreq = fr->sampling_frequency;
1767159b3361Sopenharmony_ci    int     stereo1, granules;
1768159b3361Sopenharmony_ci    real    hybridIn[2][SBLIMIT][SSLIMIT];
1769159b3361Sopenharmony_ci    real    hybridOut[2][SSLIMIT][SBLIMIT];
1770159b3361Sopenharmony_ci
1771159b3361Sopenharmony_ci    if (set_pointer(mp, (int) mp->sideinfo.main_data_begin) == MP3_ERR)
1772159b3361Sopenharmony_ci        return 0;
1773159b3361Sopenharmony_ci
1774159b3361Sopenharmony_ci    if (stereo == 1) {  /* stream is mono */
1775159b3361Sopenharmony_ci        stereo1 = 1;
1776159b3361Sopenharmony_ci        single = 0;
1777159b3361Sopenharmony_ci    }
1778159b3361Sopenharmony_ci    else if (single >= 0) /* stream is stereo, but force to mono */
1779159b3361Sopenharmony_ci        stereo1 = 1;
1780159b3361Sopenharmony_ci    else
1781159b3361Sopenharmony_ci        stereo1 = 2;
1782159b3361Sopenharmony_ci
1783159b3361Sopenharmony_ci    if (fr->mode == MPG_MD_JOINT_STEREO) {
1784159b3361Sopenharmony_ci        ms_stereo = fr->mode_ext & 0x2;
1785159b3361Sopenharmony_ci        i_stereo = fr->mode_ext & 0x1;
1786159b3361Sopenharmony_ci    }
1787159b3361Sopenharmony_ci    else
1788159b3361Sopenharmony_ci        ms_stereo = i_stereo = 0;
1789159b3361Sopenharmony_ci
1790159b3361Sopenharmony_ci
1791159b3361Sopenharmony_ci    if (fr->lsf) {
1792159b3361Sopenharmony_ci        granules = 1;
1793159b3361Sopenharmony_ci    }
1794159b3361Sopenharmony_ci    else {
1795159b3361Sopenharmony_ci        granules = 2;
1796159b3361Sopenharmony_ci    }
1797159b3361Sopenharmony_ci
1798159b3361Sopenharmony_ci    for (gr = 0; gr < granules; gr++) {
1799159b3361Sopenharmony_ci
1800159b3361Sopenharmony_ci        {
1801159b3361Sopenharmony_ci            struct gr_info_s *gr_infos = &(mp->sideinfo.ch[0].gr[gr]);
1802159b3361Sopenharmony_ci            long    part2bits;
1803159b3361Sopenharmony_ci
1804159b3361Sopenharmony_ci            if (fr->lsf)
1805159b3361Sopenharmony_ci                part2bits = III_get_scale_factors_2(mp, scalefacs[0], gr_infos, 0);
1806159b3361Sopenharmony_ci            else {
1807159b3361Sopenharmony_ci                part2bits = III_get_scale_factors_1(mp, scalefacs[0], gr_infos);
1808159b3361Sopenharmony_ci            }
1809159b3361Sopenharmony_ci            if (mp->pinfo != NULL) {
1810159b3361Sopenharmony_ci                int     i;
1811159b3361Sopenharmony_ci                mp->pinfo->sfbits[gr][0] = part2bits;
1812159b3361Sopenharmony_ci                for (i = 0; i < 39; i++)
1813159b3361Sopenharmony_ci                    mp->pinfo->sfb_s[gr][0][i] = scalefacs[0][i];
1814159b3361Sopenharmony_ci            }
1815159b3361Sopenharmony_ci
1816159b3361Sopenharmony_ci            /* lame_report_fnc(mp->report_err, "calling III dequantize sample 1 gr_infos->part2_3_length %d\n", gr_infos->part2_3_length); */
1817159b3361Sopenharmony_ci            if (III_dequantize_sample(mp, hybridIn[0], scalefacs[0], gr_infos, sfreq, part2bits))
1818159b3361Sopenharmony_ci                return clip;
1819159b3361Sopenharmony_ci        }
1820159b3361Sopenharmony_ci        if (stereo == 2) {
1821159b3361Sopenharmony_ci            struct gr_info_s *gr_infos = &(mp->sideinfo.ch[1].gr[gr]);
1822159b3361Sopenharmony_ci            long    part2bits;
1823159b3361Sopenharmony_ci            if (fr->lsf)
1824159b3361Sopenharmony_ci                part2bits = III_get_scale_factors_2(mp, scalefacs[1], gr_infos, i_stereo);
1825159b3361Sopenharmony_ci            else {
1826159b3361Sopenharmony_ci                part2bits = III_get_scale_factors_1(mp, scalefacs[1], gr_infos);
1827159b3361Sopenharmony_ci            }
1828159b3361Sopenharmony_ci            if (mp->pinfo != NULL) {
1829159b3361Sopenharmony_ci                int     i;
1830159b3361Sopenharmony_ci                mp->pinfo->sfbits[gr][1] = part2bits;
1831159b3361Sopenharmony_ci                for (i = 0; i < 39; i++)
1832159b3361Sopenharmony_ci                    mp->pinfo->sfb_s[gr][1][i] = scalefacs[1][i];
1833159b3361Sopenharmony_ci            }
1834159b3361Sopenharmony_ci
1835159b3361Sopenharmony_ci            /* lame_report_fnc(mp->report_err, "calling III dequantize sample 2  gr_infos->part2_3_length %d\n", gr_infos->part2_3_length); */
1836159b3361Sopenharmony_ci            if (III_dequantize_sample(mp, hybridIn[1], scalefacs[1], gr_infos, sfreq, part2bits))
1837159b3361Sopenharmony_ci                return clip;
1838159b3361Sopenharmony_ci
1839159b3361Sopenharmony_ci            if (ms_stereo) {
1840159b3361Sopenharmony_ci                int     i;
1841159b3361Sopenharmony_ci                for (i = 0; i < SBLIMIT * SSLIMIT; i++) {
1842159b3361Sopenharmony_ci                    real    tmp0, tmp1;
1843159b3361Sopenharmony_ci                    tmp0 = ((real *) hybridIn[0])[i];
1844159b3361Sopenharmony_ci                    tmp1 = ((real *) hybridIn[1])[i];
1845159b3361Sopenharmony_ci                    ((real *) hybridIn[1])[i] = tmp0 - tmp1;
1846159b3361Sopenharmony_ci                    ((real *) hybridIn[0])[i] = tmp0 + tmp1;
1847159b3361Sopenharmony_ci                }
1848159b3361Sopenharmony_ci            }
1849159b3361Sopenharmony_ci
1850159b3361Sopenharmony_ci            if (i_stereo)
1851159b3361Sopenharmony_ci                III_i_stereo(hybridIn, scalefacs[1], gr_infos, sfreq, ms_stereo, fr->lsf);
1852159b3361Sopenharmony_ci
1853159b3361Sopenharmony_ci            if (ms_stereo || i_stereo || (single == 3)) {
1854159b3361Sopenharmony_ci                if (gr_infos->maxb > mp->sideinfo.ch[0].gr[gr].maxb)
1855159b3361Sopenharmony_ci                    mp->sideinfo.ch[0].gr[gr].maxb = gr_infos->maxb;
1856159b3361Sopenharmony_ci                else
1857159b3361Sopenharmony_ci                    gr_infos->maxb = mp->sideinfo.ch[0].gr[gr].maxb;
1858159b3361Sopenharmony_ci            }
1859159b3361Sopenharmony_ci
1860159b3361Sopenharmony_ci            switch (single) {
1861159b3361Sopenharmony_ci            case 3:
1862159b3361Sopenharmony_ci                {
1863159b3361Sopenharmony_ci                    int     i;
1864159b3361Sopenharmony_ci                    real   *in0 = (real *) hybridIn[0], *in1 = (real *) hybridIn[1];
1865159b3361Sopenharmony_ci                    for (i = 0; i < (int) (SSLIMIT * gr_infos->maxb); i++, in0++)
1866159b3361Sopenharmony_ci                        *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */
1867159b3361Sopenharmony_ci                }
1868159b3361Sopenharmony_ci                break;
1869159b3361Sopenharmony_ci            case 1:
1870159b3361Sopenharmony_ci                {
1871159b3361Sopenharmony_ci                    int     i;
1872159b3361Sopenharmony_ci                    real   *in0 = (real *) hybridIn[0], *in1 = (real *) hybridIn[1];
1873159b3361Sopenharmony_ci                    for (i = 0; i < (int) (SSLIMIT * gr_infos->maxb); i++)
1874159b3361Sopenharmony_ci                        *in0++ = *in1++;
1875159b3361Sopenharmony_ci                }
1876159b3361Sopenharmony_ci                break;
1877159b3361Sopenharmony_ci            }
1878159b3361Sopenharmony_ci        }
1879159b3361Sopenharmony_ci
1880159b3361Sopenharmony_ci        if (mp->pinfo != NULL) {
1881159b3361Sopenharmony_ci            int     i, sb;
1882159b3361Sopenharmony_ci            float   ifqstep;
1883159b3361Sopenharmony_ci
1884159b3361Sopenharmony_ci            mp->pinfo->bitrate = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index];
1885159b3361Sopenharmony_ci            mp->pinfo->sampfreq = freqs[sfreq];
1886159b3361Sopenharmony_ci            mp->pinfo->emph = fr->emphasis;
1887159b3361Sopenharmony_ci            mp->pinfo->crc = fr->error_protection;
1888159b3361Sopenharmony_ci            mp->pinfo->padding = fr->padding;
1889159b3361Sopenharmony_ci            mp->pinfo->stereo = fr->stereo;
1890159b3361Sopenharmony_ci            mp->pinfo->js = (fr->mode == MPG_MD_JOINT_STEREO);
1891159b3361Sopenharmony_ci            mp->pinfo->ms_stereo = ms_stereo;
1892159b3361Sopenharmony_ci            mp->pinfo->i_stereo = i_stereo;
1893159b3361Sopenharmony_ci            mp->pinfo->maindata = mp->sideinfo.main_data_begin;
1894159b3361Sopenharmony_ci
1895159b3361Sopenharmony_ci            for (ch = 0; ch < stereo1; ch++) {
1896159b3361Sopenharmony_ci                struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[gr]);
1897159b3361Sopenharmony_ci                mp->pinfo->big_values[gr][ch] = gr_infos->big_values;
1898159b3361Sopenharmony_ci                mp->pinfo->scalefac_scale[gr][ch] = gr_infos->scalefac_scale;
1899159b3361Sopenharmony_ci                mp->pinfo->mixed[gr][ch] = gr_infos->mixed_block_flag;
1900159b3361Sopenharmony_ci                mp->pinfo->mpg123blocktype[gr][ch] = gr_infos->block_type;
1901159b3361Sopenharmony_ci                mp->pinfo->mainbits[gr][ch] = gr_infos->part2_3_length;
1902159b3361Sopenharmony_ci                mp->pinfo->preflag[gr][ch] = gr_infos->preflag;
1903159b3361Sopenharmony_ci                if (gr == 1)
1904159b3361Sopenharmony_ci                    mp->pinfo->scfsi[ch] = gr_infos->scfsi;
1905159b3361Sopenharmony_ci            }
1906159b3361Sopenharmony_ci
1907159b3361Sopenharmony_ci
1908159b3361Sopenharmony_ci            for (ch = 0; ch < stereo1; ch++) {
1909159b3361Sopenharmony_ci                struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[gr]);
1910159b3361Sopenharmony_ci                ifqstep = (mp->pinfo->scalefac_scale[gr][ch] == 0) ? .5 : 1.0;
1911159b3361Sopenharmony_ci                if (2 == gr_infos->block_type) {
1912159b3361Sopenharmony_ci                    for (i = 0; i < 3; i++) {
1913159b3361Sopenharmony_ci                        for (sb = 0; sb < 12; sb++) {
1914159b3361Sopenharmony_ci                            int     j = 3 * sb + i;
1915159b3361Sopenharmony_ci                            /*
1916159b3361Sopenharmony_ci                               is_p = scalefac[sfb*3+lwin-gr_infos->mixed_block_flag];
1917159b3361Sopenharmony_ci                             */
1918159b3361Sopenharmony_ci                            /* scalefac was copied into pinfo->sfb_s[] above */
1919159b3361Sopenharmony_ci                            mp->pinfo->sfb_s[gr][ch][j] =
1920159b3361Sopenharmony_ci                                -ifqstep * mp->pinfo->sfb_s[gr][ch][j - gr_infos->mixed_block_flag];
1921159b3361Sopenharmony_ci                            mp->pinfo->sfb_s[gr][ch][j] -= 2 * (mp->pinfo->sub_gain[gr][ch][i]);
1922159b3361Sopenharmony_ci                        }
1923159b3361Sopenharmony_ci                        mp->pinfo->sfb_s[gr][ch][3 * sb + i] =
1924159b3361Sopenharmony_ci                            -2 * (mp->pinfo->sub_gain[gr][ch][i]);
1925159b3361Sopenharmony_ci                    }
1926159b3361Sopenharmony_ci                }
1927159b3361Sopenharmony_ci                else {
1928159b3361Sopenharmony_ci                    for (sb = 0; sb < 21; sb++) {
1929159b3361Sopenharmony_ci                        /* scalefac was copied into pinfo->sfb[] above */
1930159b3361Sopenharmony_ci                        mp->pinfo->sfb[gr][ch][sb] = mp->pinfo->sfb_s[gr][ch][sb];
1931159b3361Sopenharmony_ci                        if (gr_infos->preflag)
1932159b3361Sopenharmony_ci                            mp->pinfo->sfb[gr][ch][sb] += pretab1[sb];
1933159b3361Sopenharmony_ci                        mp->pinfo->sfb[gr][ch][sb] *= -ifqstep;
1934159b3361Sopenharmony_ci                    }
1935159b3361Sopenharmony_ci                    mp->pinfo->sfb[gr][ch][21] = 0;
1936159b3361Sopenharmony_ci                }
1937159b3361Sopenharmony_ci            }
1938159b3361Sopenharmony_ci
1939159b3361Sopenharmony_ci
1940159b3361Sopenharmony_ci
1941159b3361Sopenharmony_ci            for (ch = 0; ch < stereo1; ch++) {
1942159b3361Sopenharmony_ci                int     j = 0;
1943159b3361Sopenharmony_ci                for (sb = 0; sb < SBLIMIT; sb++)
1944159b3361Sopenharmony_ci                    for (ss = 0; ss < SSLIMIT; ss++, j++)
1945159b3361Sopenharmony_ci                        mp->pinfo->mpg123xr[gr][ch][j] = hybridIn[ch][sb][ss];
1946159b3361Sopenharmony_ci            }
1947159b3361Sopenharmony_ci        }
1948159b3361Sopenharmony_ci
1949159b3361Sopenharmony_ci
1950159b3361Sopenharmony_ci        for (ch = 0; ch < stereo1; ch++) {
1951159b3361Sopenharmony_ci            struct gr_info_s *gr_infos = &(mp->sideinfo.ch[ch].gr[gr]);
1952159b3361Sopenharmony_ci            III_antialias(hybridIn[ch], gr_infos);
1953159b3361Sopenharmony_ci            III_hybrid(mp, hybridIn[ch], hybridOut[ch], ch, gr_infos);
1954159b3361Sopenharmony_ci        }
1955159b3361Sopenharmony_ci
1956159b3361Sopenharmony_ci        for (ss = 0; ss < SSLIMIT; ss++) {
1957159b3361Sopenharmony_ci            if (single >= 0) {
1958159b3361Sopenharmony_ci                clip += (*synth_1to1_mono_ptr) (mp, hybridOut[0][ss], pcm_sample, pcm_point);
1959159b3361Sopenharmony_ci            }
1960159b3361Sopenharmony_ci            else {
1961159b3361Sopenharmony_ci                int     p1 = *pcm_point;
1962159b3361Sopenharmony_ci                clip += (*synth_1to1_ptr) (mp, hybridOut[0][ss], 0, pcm_sample, &p1);
1963159b3361Sopenharmony_ci                clip += (*synth_1to1_ptr) (mp, hybridOut[1][ss], 1, pcm_sample, pcm_point);
1964159b3361Sopenharmony_ci            }
1965159b3361Sopenharmony_ci        }
1966159b3361Sopenharmony_ci    }
1967159b3361Sopenharmony_ci
1968159b3361Sopenharmony_ci    return clip;
1969159b3361Sopenharmony_ci}
1970