1
2/* -----------------------------------------------------------------------------------------------------------
3Software License for The Fraunhofer FDK AAC Codec Library for Android
4
5© Copyright  1995 - 2012 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 const INT psBands[] =
265{
266  PS_BANDS_COARSE,
267  PS_BANDS_MID
268};
269
270static INT getNoBands(PS_RESOLUTION mode)
271{
272  if(mode>=6)
273    return 0;
274
275  if(mode>=3)
276    mode = (PS_RESOLUTION)(mode-3);
277
278  return psBands[mode];
279}
280
281static INT getIIDRes(INT iidMode)
282{
283  if(iidMode<3)
284    return PS_IID_RES_COARSE;
285  else
286    return PS_IID_RES_FINE;
287}
288
289static INT
290encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf,
291                const INT          *val,
292                const INT           nBands,
293                const UINT *codeTable,
294                const UINT *lengthTable,
295                const INT           tableOffset,
296                const INT           maxVal,
297                INT                *error)
298{
299  INT bitCnt = 0;
300  INT lastVal = 0;
301  INT band;
302
303  for(band=0;band<nBands;band++) {
304    INT delta = (val[band] - lastVal) + tableOffset;
305    lastVal = val[band];
306    if( (delta>maxVal) || (delta<0) ) {
307      *error = 1;
308      delta = delta>0?maxVal:0;
309    }
310    bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
311  }
312
313  return bitCnt;
314}
315
316static INT
317encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf,
318                const INT          *val,
319                const INT          *valLast,
320                const INT           nBands,
321                const UINT *codeTable,
322                const UINT *lengthTable,
323                const INT           tableOffset,
324                const INT           maxVal,
325                INT                *error)
326{
327  INT bitCnt = 0;
328  INT band;
329
330  for(band=0;band<nBands;band++) {
331    INT delta = (val[band] - valLast[band]) + tableOffset;
332    if( (delta>maxVal) || (delta<0) ) {
333      *error = 1;
334      delta = delta>0?maxVal:0;
335    }
336    bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]);
337  }
338
339  return bitCnt;
340}
341
342INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM     hBitBuf,
343              const INT               *iidVal,
344              const INT               *iidValLast,
345              const INT                nBands,
346              const PS_IID_RESOLUTION  res,
347              const PS_DELTA           mode,
348              INT                     *error)
349{
350  const UINT *codeTable;
351  const UINT *lengthTable;
352  INT bitCnt = 0;
353
354  bitCnt = 0;
355
356  switch(mode) {
357  case PS_DELTA_FREQ:
358    switch(res) {
359    case PS_IID_RES_COARSE:
360      codeTable   = iidDeltaFreqCoarse_Code;
361      lengthTable = iidDeltaFreqCoarse_Length;
362      bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
363                                lengthTable, iidDeltaCoarse_Offset,
364                                iidDeltaCoarse_MaxVal, error);
365    break;
366    case PS_IID_RES_FINE:
367      codeTable   = iidDeltaFreqFine_Code;
368      lengthTable = iidDeltaFreqFine_Length;
369      bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable,
370                                lengthTable, iidDeltaFine_Offset,
371                                iidDeltaFine_MaxVal, error);
372    break;
373    default:
374      *error = 1;
375    }
376    break;
377
378  case PS_DELTA_TIME:
379    switch(res) {
380    case PS_IID_RES_COARSE:
381      codeTable   = iidDeltaTimeCoarse_Code;
382      lengthTable = iidDeltaTimeCoarse_Length;
383      bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, codeTable,
384                                lengthTable, iidDeltaCoarse_Offset,
385                                iidDeltaCoarse_MaxVal, error);
386    break;
387    case PS_IID_RES_FINE:
388      codeTable   = iidDeltaTimeFine_Code;
389      lengthTable = iidDeltaTimeFine_Length;
390      bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, codeTable,
391                                lengthTable, iidDeltaFine_Offset,
392                                iidDeltaFine_MaxVal, error);
393    break;
394    default:
395      *error = 1;
396    }
397    break;
398
399  default:
400    *error = 1;
401  }
402
403  return bitCnt;
404}
405
406
407INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf,
408              const INT      *iccVal,
409              const INT      *iccValLast,
410              const INT       nBands,
411              const PS_DELTA  mode,
412              INT            *error)
413{
414  const UINT *codeTable;
415  const UINT *lengthTable;
416  INT bitCnt = 0;
417
418  switch(mode) {
419  case PS_DELTA_FREQ:
420    codeTable   = iccDeltaFreq_Code;
421    lengthTable = iccDeltaFreq_Length;
422    bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable,
423                              lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
424    break;
425
426  case PS_DELTA_TIME:
427    codeTable   = iccDeltaTime_Code;
428    lengthTable = iccDeltaTime_Length;
429
430    bitCnt += encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable,
431                              lengthTable, iccDelta_Offset, iccDelta_MaxVal, error);
432    break;
433
434  default:
435    *error = 1;
436  }
437
438  return bitCnt;
439}
440
441INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf,
442              const INT      *ipdVal,
443              const INT      *ipdValLast,
444              const INT       nBands,
445              const PS_DELTA  mode,
446              INT            *error)
447{
448  const UINT *codeTable;
449  const UINT *lengthTable;
450  INT bitCnt = 0;
451
452  switch(mode) {
453  case PS_DELTA_FREQ:
454    codeTable   = ipdDeltaFreq_Code;
455    lengthTable = ipdDeltaFreq_Length;
456    bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable,
457                              lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
458    break;
459
460  case PS_DELTA_TIME:
461    codeTable   = ipdDeltaTime_Code;
462    lengthTable = ipdDeltaTime_Length;
463
464    bitCnt += encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable,
465                              lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error);
466    break;
467
468  default:
469    *error = 1;
470  }
471
472  return bitCnt;
473}
474
475INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf,
476              const INT      *opdVal,
477              const INT      *opdValLast,
478              const INT       nBands,
479              const PS_DELTA  mode,
480              INT            *error)
481{
482  const UINT *codeTable;
483  const UINT *lengthTable;
484  INT bitCnt = 0;
485
486  switch(mode) {
487  case PS_DELTA_FREQ:
488    codeTable   = opdDeltaFreq_Code;
489    lengthTable = opdDeltaFreq_Length;
490    bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable,
491                              lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
492    break;
493
494  case PS_DELTA_TIME:
495    codeTable   = opdDeltaTime_Code;
496    lengthTable = opdDeltaTime_Length;
497
498    bitCnt += encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable,
499                              lengthTable, opdDelta_Offset, opdDelta_MaxVal, error);
500    break;
501
502  default:
503    *error = 1;
504  }
505
506  return bitCnt;
507}
508
509static INT encodeIpdOpd(HANDLE_PS_OUT        psOut,
510                        HANDLE_FDK_BITSTREAM hBitBuf )
511{
512  INT bitCnt = 0;
513  INT error  = 0;
514  INT env;
515
516  FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1);
517
518  if(psOut->enableIpdOpd==1) {
519    INT *ipdLast = psOut->ipdLast;
520    INT *opdLast = psOut->opdLast;
521
522    for(env=0; env<psOut->nEnvelopes; env++) {
523      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaIPD[env], 1);
524      bitCnt += FDKsbrEnc_EncodeIpd( hBitBuf,
525                           psOut->ipd[env],
526                           ipdLast,
527                           getNoBands((PS_RESOLUTION)psOut->iidMode),
528                           psOut->deltaIPD[env],
529                           &error);
530
531      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaOPD[env], 1);
532      bitCnt += FDKsbrEnc_EncodeOpd( hBitBuf,
533                           psOut->opd[env],
534                           opdLast,
535                           getNoBands((PS_RESOLUTION)psOut->iidMode),
536                           psOut->deltaOPD[env],
537                           &error );
538    }
539    /* reserved bit */
540    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, 0, 1);
541  }
542
543
544  return bitCnt;
545}
546
547static INT getEnvIdx(const INT nEnvelopes, const INT frameClass)
548{
549  INT envIdx = 0;
550
551  switch(nEnvelopes) {
552  case 0:
553    envIdx = 0;
554    break;
555
556  case 1:
557    if (frameClass==0)
558      envIdx = 1;
559    else
560      envIdx = 0;
561    break;
562
563  case 2:
564    if (frameClass==0)
565      envIdx = 2;
566    else
567      envIdx = 1;
568    break;
569
570  case 3:
571    envIdx = 2;
572    break;
573
574  case 4:
575    envIdx = 3;
576    break;
577
578  default:
579    /* unsupported number of envelopes */
580    envIdx = 0;
581  }
582
583  return envIdx;
584}
585
586
587static INT encodePSExtension(const HANDLE_PS_OUT   psOut,
588                             HANDLE_FDK_BITSTREAM  hBitBuf )
589{
590  INT bitCnt = 0;
591
592  if(psOut->enableIpdOpd==1) {
593    INT ipdOpdBits = 0;
594    INT extSize = (2 + encodeIpdOpd(psOut,NULL)+7)>>3;
595
596    if(extSize<15) {
597      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf,  extSize, 4);
598    }
599    else {
600      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf,          15 , 4);
601      bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize-15), 8);
602    }
603
604    /* write ipd opd data */
605    ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2);
606    ipdOpdBits += encodeIpdOpd(psOut, hBitBuf );
607
608    /* byte align the ipd opd data  */
609    if(ipdOpdBits%8)
610      ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8-(ipdOpdBits%8)) );
611
612    bitCnt += ipdOpdBits;
613  }
614
615  return (bitCnt);
616}
617
618INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT   psOut,
619                               HANDLE_FDK_BITSTREAM  hBitBuf )
620{
621  INT psExtEnable = 0;
622  INT bitCnt = 0;
623  INT error = 0;
624  INT env;
625
626  if(psOut != NULL){
627
628    /* PS HEADER */
629    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enablePSHeader, 1);
630
631    if(psOut->enablePSHeader) {
632
633      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enableIID, 1);
634      if(psOut->enableIID) {
635        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->iidMode, 3);
636      }
637      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->enableICC, 1);
638      if(psOut->enableICC) {
639        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->iccMode, 3);
640      }
641      if(psOut->enableIpdOpd) {
642        psExtEnable = 1;
643      }
644      bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psExtEnable, 1);
645    }
646
647    /* Frame class, number of envelopes */
648    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->frameClass, 1);
649    bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2);
650
651    if(psOut->frameClass==1) {
652      for(env=0; env<psOut->nEnvelopes; env++) {
653        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->frameBorder[env], 5);
654      }
655    }
656
657    if(psOut->enableIID==1) {
658      INT *iidLast = psOut->iidLast;
659      for(env=0; env<psOut->nEnvelopes; env++) {
660        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaIID[env], 1);
661        bitCnt += FDKsbrEnc_EncodeIid( hBitBuf,
662                             psOut->iid[env],
663                             iidLast,
664                             getNoBands((PS_RESOLUTION)psOut->iidMode),
665                             (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode),
666                             psOut->deltaIID[env],
667                             &error );
668
669        iidLast = psOut->iid[env];
670      }
671    }
672
673    if(psOut->enableICC==1) {
674      INT *iccLast = psOut->iccLast;
675      for(env=0; env<psOut->nEnvelopes; env++) {
676        bitCnt += FDKsbrEnc_WriteBits_ps( hBitBuf, psOut->deltaICC[env], 1);
677        bitCnt += FDKsbrEnc_EncodeIcc( hBitBuf,
678                             psOut->icc[env],
679                             iccLast,
680                             getNoBands((PS_RESOLUTION)psOut->iccMode),
681                             psOut->deltaICC[env],
682                             &error);
683
684        iccLast = psOut->icc[env];
685      }
686    }
687
688    if(psExtEnable!=0) {
689      bitCnt += encodePSExtension(psOut, hBitBuf);
690    }
691
692  } /* if(psOut != NULL) */
693
694  return bitCnt;
695}
696
697