1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5� Copyright  1995 - 2015 Fraunhofer-Gesellschaft zur F�rderung der angewandten Forschung e.V.
6  All rights reserved.
7
8 1.    INTRODUCTION
9The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements
10the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio.
11This FDK AAC Codec software is intended to be used on a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual
14audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by
15independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part
16of the MPEG specifications.
17
18Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer)
19may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners
20individually for the purpose of encoding or decoding bit streams in products that are compliant with
21the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license
22these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec
23software may already be covered under those patent licenses when it is used for those licensed purposes only.
24
25Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality,
26are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional
27applications information and documentation.
28
292.    COPYRIGHT LICENSE
30
31Redistribution and use in source and binary forms, with or without modification, are permitted without
32payment of copyright license fees provided that you satisfy the following conditions:
33
34You must retain the complete text of this software license in redistributions of the FDK AAC Codec or
35your modifications thereto in source code form.
36
37You must retain the complete text of this software license in the documentation and/or other materials
38provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form.
39You must make available free of charge copies of the complete source code of the FDK AAC Codec and your
40modifications thereto to recipients of copies in binary form.
41
42The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43prior written permission.
44
45You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec
46software or your modifications thereto.
47
48Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software
49and the date of any change. For modified versions of the FDK AAC Codec, the term
50"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term
51"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android."
52
533.    NO PATENT LICENSE
54
55NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer,
56ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with
57respect to this software.
58
59You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60by appropriate patent licenses.
61
624.    DISCLAIMER
63
64This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors
65"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties
66of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
67CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages,
68including but not limited to procurement of substitute goods or services; loss of use, data, or profits,
69or business interruption, however caused and on any theory of liability, whether in contract, strict
70liability, or tort (including negligence), arising in any way out of the use of this software, even if
71advised of the possibility of such damage.
72
735.    CONTACT INFORMATION
74
75Fraunhofer Institute for Integrated Circuits IIS
76Attention: Audio and Multimedia Departments - FDK AAC LL
77Am Wolfsmantel 33
7891058 Erlangen, Germany
79
80www.iis.fraunhofer.de/amm
81amm-info@iis.fraunhofer.de
82----------------------------------------------------------------------------------------------------------- */
83
84/*****************************  MPEG Audio Encoder  ***************************
85
86   Initial author:       N. Rettelbach
87   contents/description: Parametric Stereo bitstream encoder
88
89******************************************************************************/
90
91#include "ps_main.h"
92
93
94#include "ps_const.h"
95#include "ps_bitenc.h"
96
97static
98inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream, UINT value,
99                                    const UINT numberOfBits)
100{
101  /* hBitStream == NULL happens here intentionally */
102  if(hBitStream!=NULL){
103    FDKwriteBits(hBitStream, value, numberOfBits);
104  }
105  return numberOfBits;
106}
107
108#define SI_SBR_EXTENSION_SIZE_BITS              4
109#define SI_SBR_EXTENSION_ESC_COUNT_BITS         8
110#define SI_SBR_EXTENSION_ID_BITS                2
111#define EXTENSION_ID_PS_CODING                  2
112#define PS_EXT_ID_V0                            0
113
114static const INT iidDeltaCoarse_Offset = 14;
115static const INT iidDeltaCoarse_MaxVal = 28;
116static const INT iidDeltaFine_Offset = 30;
117static const INT iidDeltaFine_MaxVal = 60;
118
119/* PS Stereo Huffmantable: iidDeltaFreqCoarse */
120static const UINT iidDeltaFreqCoarse_Length[] =
121{
122  17,    17,    17,    17,    16,  15,    13,    10,     9,     7,
123   6,     5,     4,     3,     1,   3,     4,     5,     6,     6,
124   8,    11,    13,    14,    14,  15,    17,    18,    18
125};
126static const UINT iidDeltaFreqCoarse_Code[]  =
127{
128  0x0001fffb,  0x0001fffc,  0x0001fffd,  0x0001fffa,  0x0000fffc,  0x00007ffc,  0x00001ffd,  0x000003fe,  0x000001fe,  0x0000007e,
129  0x0000003c,  0x0000001d,  0x0000000d,  0x00000005,  0000000000,  0x00000004,  0x0000000c,  0x0000001c,  0x0000003d,  0x0000003e,
130  0x000000fe,  0x000007fe,  0x00001ffc,  0x00003ffc,  0x00003ffd,  0x00007ffd,  0x0001fffe,  0x0003fffe,  0x0003ffff
131};
132
133/* PS Stereo Huffmantable: iidDeltaFreqFine */
134static const UINT iidDeltaFreqFine_Length[] =
135{
136  18,    18,    18,    18,    18,  18,    18,    18,    18,    17,
137  18,    17,    17,    16,    16,  15,    14,    14,    13,    12,
138  12,    11,    10,    10,     8,   7,     6,     5,     4,     3,
139   1,     3,     4,     5,     6,   7,     8,     9,    10,    11,
140  11,    12,    13,    14,    14,  15,    16,    16,    17,    17,
141  18,    17,    18,    18,    18,  18,    18,    18,    18,    18,
142  18
143};
144static const UINT iidDeltaFreqFine_Code[] =
145{
146  0x0001feb4,  0x0001feb5,  0x0001fd76,  0x0001fd77,  0x0001fd74,  0x0001fd75,  0x0001fe8a,  0x0001fe8b,  0x0001fe88,  0x0000fe80,
147  0x0001feb6,  0x0000fe82,  0x0000feb8,  0x00007f42,  0x00007fae,  0x00003faf,  0x00001fd1,  0x00001fe9,  0x00000fe9,  0x000007ea,
148  0x000007fb,  0x000003fb,  0x000001fb,  0x000001ff,  0x0000007c,  0x0000003c,  0x0000001c,  0x0000000c,  0000000000,  0x00000001,
149  0x00000001,  0x00000002,  0x00000001,  0x0000000d,  0x0000001d,  0x0000003d,  0x0000007d,  0x000000fc,  0x000001fc,  0x000003fc,
150  0x000003f4,  0x000007eb,  0x00000fea,  0x00001fea,  0x00001fd6,  0x00003fd0,  0x00007faf,  0x00007f43,  0x0000feb9,  0x0000fe83,
151  0x0001feb7,  0x0000fe81,  0x0001fe89,  0x0001fe8e,  0x0001fe8f,  0x0001fe8c,  0x0001fe8d,  0x0001feb2,  0x0001feb3,  0x0001feb0,
152  0x0001feb1
153};
154
155/* PS Stereo Huffmantable: iidDeltaTimeCoarse */
156static const UINT iidDeltaTimeCoarse_Length[] =
157{
158  19,    19,    19,    20,    20,  20,    17,    15,    12,    10,
159   8,     6,     4,     2,     1,   3,     5,     7,     9,    11,
160  13,    14,    17,    19,    20,  20,    20,    20,    20
161};
162static const UINT iidDeltaTimeCoarse_Code[] =
163{
164  0x0007fff9,  0x0007fffa,  0x0007fffb,  0x000ffff8,  0x000ffff9,  0x000ffffa,  0x0001fffd,  0x00007ffe,  0x00000ffe,  0x000003fe,
165  0x000000fe,  0x0000003e,  0x0000000e,  0x00000002,  0000000000,  0x00000006,  0x0000001e,  0x0000007e,  0x000001fe,  0x000007fe,
166  0x00001ffe,  0x00003ffe,  0x0001fffc,  0x0007fff8,  0x000ffffb,  0x000ffffc,  0x000ffffd,  0x000ffffe,  0x000fffff
167};
168
169/* PS Stereo Huffmantable: iidDeltaTimeFine */
170static const UINT iidDeltaTimeFine_Length[] =
171{
172  16,    16,    16,    16,    16,  16,    16,    16,    16,    15,
173  15,    15,    15,    15,    15,  14,    14,    13,    13,    13,
174  12,    12,    11,    10,     9,   9,     7,     6,     5,     3,
175   1,     2,     5,     6,     7,   8,     9,    10,    11,    11,
176  12,    12,    13,    13,    14,  14,    15,    15,    15,    15,
177  16,    16,    16,    16,    16,  16,    16,    16,    16,    16,
178  16
179};
180static const UINT iidDeltaTimeFine_Code[] =
181{
182  0x00004ed4,  0x00004ed5,  0x00004ece,  0x00004ecf,  0x00004ecc,  0x00004ed6,  0x00004ed8,  0x00004f46,  0x00004f60,  0x00002718,
183  0x00002719,  0x00002764,  0x00002765,  0x0000276d,  0x000027b1,  0x000013b7,  0x000013d6,  0x000009c7,  0x000009e9,  0x000009ed,
184  0x000004ee,  0x000004f7,  0x00000278,  0x00000139,  0x0000009a,  0x0000009f,  0x00000020,  0x00000011,  0x0000000a,  0x00000003,
185  0x00000001,  0000000000,  0x0000000b,  0x00000012,  0x00000021,  0x0000004c,  0x0000009b,  0x0000013a,  0x00000279,  0x00000270,
186  0x000004ef,  0x000004e2,  0x000009ea,  0x000009d8,  0x000013d7,  0x000013d0,  0x000027b2,  0x000027a2,  0x0000271a,  0x0000271b,
187  0x00004f66,  0x00004f67,  0x00004f61,  0x00004f47,  0x00004ed9,  0x00004ed7,  0x00004ecd,  0x00004ed2,  0x00004ed3,  0x00004ed0,
188  0x00004ed1
189};
190
191static const INT iccDelta_Offset =  7;
192static const INT iccDelta_MaxVal = 14;
193/* PS Stereo Huffmantable: iccDeltaFreq */
194static const UINT iccDeltaFreq_Length[] =
195{
196  14,    14,    12,    10,     7,   5,     3,     1,     2,     4,
197   6,     8,     9,    11,    13
198};
199static const UINT iccDeltaFreq_Code[] =
200{
201  0x00003fff,  0x00003ffe,  0x00000ffe,  0x000003fe,  0x0000007e,  0x0000001e,  0x00000006,  0000000000,  0x00000002,  0x0000000e,
202  0x0000003e,  0x000000fe,  0x000001fe,  0x000007fe,  0x00001ffe
203};
204
205/* PS Stereo Huffmantable: iccDeltaTime */
206static const UINT iccDeltaTime_Length[] =
207{
208  14,    13,    11,     9,     7,   5,     3,     1,     2,     4,
209   6,     8,    10,    12,    14
210};
211static const UINT iccDeltaTime_Code[] =
212{
213  0x00003ffe,  0x00001ffe,  0x000007fe,  0x000001fe,  0x0000007e,  0x0000001e,  0x00000006,  0000000000,  0x00000002,  0x0000000e,
214  0x0000003e,  0x000000fe,  0x000003fe,  0x00000ffe,  0x00003fff
215};
216
217
218
219static const INT ipdDelta_Offset = 0;
220static const INT ipdDelta_MaxVal = 7;
221/* PS Stereo Huffmantable: ipdDeltaFreq */
222static const UINT ipdDeltaFreq_Length[] =
223{
224   1,     3,     4,     4,     4,   4,     4,     4
225};
226static const UINT ipdDeltaFreq_Code[] =
227{
228  0x00000001,  0000000000,  0x00000006,  0x00000004,  0x00000002,  0x00000003,  0x00000005,  0x00000007
229};
230
231/* PS Stereo Huffmantable: ipdDeltaTime */
232static const UINT ipdDeltaTime_Length[] =
233{
234   1,     3,     4,     5,     5,   4,     4,     3
235};
236static const UINT ipdDeltaTime_Code[] =
237{
238  0x00000001,  0x00000002,  0x00000002,  0x00000003,  0x00000002,  0000000000,  0x00000003,  0x00000003
239};
240
241
242static const INT opdDelta_Offset = 0;
243static const INT opdDelta_MaxVal = 7;
244/* PS Stereo Huffmantable: opdDeltaFreq */
245static const UINT opdDeltaFreq_Length[] =
246{
247   1,     3,     4,     4,     5,   5,     4,     3
248};
249static const UINT opdDeltaFreq_Code[] =
250{
251  0x00000001,  0x00000001,  0x00000006,  0x00000004,  0x0000000f,  0x0000000e,  0x00000005,  0000000000,
252};
253
254/* PS Stereo Huffmantable: opdDeltaTime */
255static const UINT opdDeltaTime_Length[] =
256{
257   1,     3,     4,     5,     5,   4,     4,     3
258};
259static const UINT opdDeltaTime_Code[] =
260{
261  0x00000001,  0x00000002,  0x00000001,  0x00000007,  0x00000006,  0000000000,  0x00000002,  0x00000003
262};
263
264static INT getNoBands(const INT mode)
265{
266  INT noBands = 0;
267
268  switch (mode) {
269    case 0: case 3: /* coarse */
270      noBands = PS_BANDS_COARSE;
271      break;
272    case 1: case 4: /* mid */
273      noBands = PS_BANDS_MID;
274      break;
275    case 2: case 5: /* fine not supported */
276    default:        /* coarse as default */
277      noBands = PS_BANDS_COARSE;
278  }
279
280  return noBands;
281}
282
283static INT getIIDRes(INT iidMode)
284{
285  if(iidMode<3)
286    return PS_IID_RES_COARSE;
287  else
288    return PS_IID_RES_FINE;
289}
290
291static INT
292encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf,
293                const INT          *val,
294                const INT           nBands,
295                const UINT *codeTable,
296                const UINT *lengthTable,
297                const INT           tableOffset,
298                const INT           maxVal,
299                INT                *error)
300{
301  INT bitCnt = 0;
302  INT lastVal = 0;
303  INT band;
304
305  for(band=0;band<nBands;band++) {
306    INT delta = (val[band] - lastVal) + tableOffset;
307    lastVal = val[band];
308    if( (delta>maxVal) || (delta<0) ) {
309      *error = 1;
310      delta = delta>0?maxVal:0;
311    }
312    bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
313  }
314
315  return bitCnt;
316}
317
318static INT
319encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf,
320                const INT          *val,
321                const INT          *valLast,
322                const INT           nBands,
323                const UINT *codeTable,
324                const UINT *lengthTable,
325                const INT           tableOffset,
326                const INT           maxVal,
327                INT                *error)
328{
329  INT bitCnt = 0;
330  INT band;
331
332  for(band=0;band<nBands;band++) {
333    INT delta = (val[band] - valLast[band]) + tableOffset;
334    if( (delta>maxVal) || (delta<0) ) {
335      *error = 1;
336      delta = delta>0?maxVal:0;
337    }
338    bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
339  }
340
341  return bitCnt;
342}
343
344INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM     hBitBuf,
345              const INT               *iidVal,
346              const INT               *iidValLast,
347              const INT                nBands,
348              const PS_IID_RESOLUTION  res,
349              const PS_DELTA           mode,
350              INT                     *error)
351{
352  const UINT *codeTable;
353  const UINT *lengthTable;
354  INT bitCnt = 0;
355
356  bitCnt = 0;
357
358  switch(mode) {
359  case PS_DELTA_FREQ:
360    switch(res) {
361    case PS_IID_RES_COARSE:
362      codeTable   = iidDeltaFreqCoarse_Code;
363      lengthTable = iidDeltaFreqCoarse_Length;
364      bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
365                                lengthTable, iidDeltaCoarse_Offset,
366                                iidDeltaCoarse_MaxVal, error);
367    break;
368    case PS_IID_RES_FINE:
369      codeTable   = iidDeltaFreqFine_Code;
370      lengthTable = iidDeltaFreqFine_Length;
371      bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
372                                lengthTable, iidDeltaFine_Offset,
373                                iidDeltaFine_MaxVal, error);
374    break;
375    default:
376      *error = 1;
377    }
378    break;
379
380  case PS_DELTA_TIME:
381    switch(res) {
382    case PS_IID_RES_COARSE:
383      codeTable   = iidDeltaTimeCoarse_Code;
384      lengthTable = iidDeltaTimeCoarse_Length;
385      bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, codeTable,
386                                lengthTable, iidDeltaCoarse_Offset,
387                                iidDeltaCoarse_MaxVal, error);
388    break;
389    case PS_IID_RES_FINE:
390      codeTable   = iidDeltaTimeFine_Code;
391      lengthTable = iidDeltaTimeFine_Length;
392      bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, codeTable,
393                                lengthTable, iidDeltaFine_Offset,
394                                iidDeltaFine_MaxVal, error);
395    break;
396    default:
397      *error = 1;
398    }
399    break;
400
401  default:
402    *error = 1;
403  }
404
405  return bitCnt;
406}
407
408
409INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf,
410              const INT      *iccVal,
411              const INT      *iccValLast,
412              const INT       nBands,
413              const PS_DELTA  mode,
414              INT            *error)
415{
416  const UINT *codeTable;
417  const UINT *lengthTable;
418  INT bitCnt = 0;
419
420  switch(mode) {
421  case PS_DELTA_FREQ:
422    codeTable   = iccDeltaFreq_Code;
423    lengthTable = iccDeltaFreq_Length;
424    bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable,
425                              lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
426    break;
427
428  case PS_DELTA_TIME:
429    codeTable   = iccDeltaTime_Code;
430    lengthTable = iccDeltaTime_Length;
431
432    bitCnt += encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable,
433                              lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
434    break;
435
436  default:
437    *error = 1;
438  }
439
440  return bitCnt;
441}
442
443INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf,
444              const INT      *ipdVal,
445              const INT      *ipdValLast,
446              const INT       nBands,
447              const PS_DELTA  mode,
448              INT            *error)
449{
450  const UINT *codeTable;
451  const UINT *lengthTable;
452  INT bitCnt = 0;
453
454  switch(mode) {
455  case PS_DELTA_FREQ:
456    codeTable   = ipdDeltaFreq_Code;
457    lengthTable = ipdDeltaFreq_Length;
458    bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable,
459                              lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
460    break;
461
462  case PS_DELTA_TIME:
463    codeTable   = ipdDeltaTime_Code;
464    lengthTable = ipdDeltaTime_Length;
465
466    bitCnt += encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable,
467                              lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
468    break;
469
470  default:
471    *error = 1;
472  }
473
474  return bitCnt;
475}
476
477INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf,
478              const INT      *opdVal,
479              const INT      *opdValLast,
480              const INT       nBands,
481              const PS_DELTA  mode,
482              INT            *error)
483{
484  const UINT *codeTable;
485  const UINT *lengthTable;
486  INT bitCnt = 0;
487
488  switch(mode) {
489  case PS_DELTA_FREQ:
490    codeTable   = opdDeltaFreq_Code;
491    lengthTable = opdDeltaFreq_Length;
492    bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable,
493                              lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
494    break;
495
496  case PS_DELTA_TIME:
497    codeTable   = opdDeltaTime_Code;
498    lengthTable = opdDeltaTime_Length;
499
500    bitCnt += encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable,
501                              lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
502    break;
503
504  default:
505    *error = 1;
506  }
507
508  return bitCnt;
509}
510
511static INT encodeIpdOpd(HANDLE_PS_OUT        psOut,
512                        HANDLE_FDK_BITSTREAM hBitBuf )
513{
514  INT bitCnt = 0;
515  INT error  = 0;
516  INT env;
517
518  FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1);
519
520  if(psOut->enableIpdOpd==1) {
521    INT *ipdLast = psOut->ipdLast;
522    INT *opdLast = psOut->opdLast;
523
524    for(env=0; env<psOut->nEnvelopes; env++) {
525      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaIPD[env], 1);
526      bitCnt += FDKsbrEnc_EncodeIpd( hBitBuf,
527                           psOut->ipd[env],
528                           ipdLast,
529                           getNoBands(psOut->iidMode),
530                           psOut->deltaIPD[env],
531                           &error);
532
533      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaOPD[env], 1);
534      bitCnt += FDKsbrEnc_EncodeOpd( hBitBuf,
535                           psOut->opd[env],
536                           opdLast,
537                           getNoBands(psOut->iidMode),
538                           psOut->deltaOPD[env],
539                           &error );
540    }
541    /* reserved bit */
542    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, 0, 1);
543  }
544
545
546  return bitCnt;
547}
548
549static INT getEnvIdx(const INT nEnvelopes, const INT frameClass)
550{
551  INT envIdx = 0;
552
553  switch(nEnvelopes) {
554  case 0:
555    envIdx = 0;
556    break;
557
558  case 1:
559    if (frameClass==0)
560      envIdx = 1;
561    else
562      envIdx = 0;
563    break;
564
565  case 2:
566    if (frameClass==0)
567      envIdx = 2;
568    else
569      envIdx = 1;
570    break;
571
572  case 3:
573    envIdx = 2;
574    break;
575
576  case 4:
577    envIdx = 3;
578    break;
579
580  default:
581    /* unsupported number of envelopes */
582    envIdx = 0;
583  }
584
585  return envIdx;
586}
587
588
589static INT encodePSExtension(const HANDLE_PS_OUT   psOut,
590                             HANDLE_FDK_BITSTREAM  hBitBuf )
591{
592  INT bitCnt = 0;
593
594  if(psOut->enableIpdOpd==1) {
595    INT ipdOpdBits = 0;
596    INT extSize = (2 + encodeIpdOpd(psOut,NULL)+7)>>3;
597
598    if(extSize<15) {
599      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf,  extSize, 4);
600    }
601    else {
602      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf,          15 , 4);
603      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize-15), 8);
604    }
605
606    /* write ipd opd data */
607    ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2);
608    ipdOpdBits += encodeIpdOpd(psOut, hBitBuf );
609
610    /* byte align the ipd opd data  */
611    if(ipdOpdBits%8)
612      ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8-(ipdOpdBits%8)) );
613
614    bitCnt += ipdOpdBits;
615  }
616
617  return (bitCnt);
618}
619
620INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT   psOut,
621                               HANDLE_FDK_BITSTREAM  hBitBuf )
622{
623  INT psExtEnable = 0;
624  INT bitCnt = 0;
625  INT error = 0;
626  INT env;
627
628  if(psOut != NULL){
629
630    /* PS HEADER */
631    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enablePSHeader, 1);
632
633    if(psOut->enablePSHeader) {
634
635      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enableIID, 1);
636      if(psOut->enableIID) {
637        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->iidMode, 3);
638      }
639      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enableICC, 1);
640      if(psOut->enableICC) {
641        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->iccMode, 3);
642      }
643      if(psOut->enableIpdOpd) {
644        psExtEnable = 1;
645      }
646      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psExtEnable, 1);
647    }
648
649    /* Frame class, number of envelopes */
650    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->frameClass, 1);
651    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2);
652
653    if(psOut->frameClass==1) {
654      for(env=0; env<psOut->nEnvelopes; env++) {
655        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->frameBorder[env], 5);
656      }
657    }
658
659    if(psOut->enableIID==1) {
660      INT *iidLast = psOut->iidLast;
661      for(env=0; env<psOut->nEnvelopes; env++) {
662        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaIID[env], 1);
663        bitCnt += FDKsbrEnc_EncodeIid( hBitBuf,
664                             psOut->iid[env],
665                             iidLast,
666                             getNoBands(psOut->iidMode),
667                             (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode),
668                             psOut->deltaIID[env],
669                             &error );
670
671        iidLast = psOut->iid[env];
672      }
673    }
674
675    if(psOut->enableICC==1) {
676      INT *iccLast = psOut->iccLast;
677      for(env=0; env<psOut->nEnvelopes; env++) {
678        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaICC[env], 1);
679        bitCnt += FDKsbrEnc_EncodeIcc( hBitBuf,
680                             psOut->icc[env],
681                             iccLast,
682                             getNoBands(psOut->iccMode),
683                             psOut->deltaICC[env],
684                             &error);
685
686        iccLast = psOut->icc[env];
687      }
688    }
689
690    if(psExtEnable!=0) {
691      bitCnt += encodePSExtension(psOut, hBitBuf);
692    }
693
694  } /* if(psOut != NULL) */
695
696  return bitCnt;
697}
698
699