Home | History | Annotate | Download | only in src
      1 /* -----------------------------------------------------------------------------
      2 Software License for The Fraunhofer FDK AAC Codec Library for Android
      3 
      4  Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Frderung der angewandten
      5 Forschung e.V. All rights reserved.
      6 
      7  1.    INTRODUCTION
      8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
      9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
     10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
     11 a wide variety of Android devices.
     12 
     13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
     14 general perceptual audio codecs. AAC-ELD is considered the best-performing
     15 full-bandwidth communications codec by independent studies and is widely
     16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
     17 specifications.
     18 
     19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
     20 those of Fraunhofer) may be obtained through Via Licensing
     21 (www.vialicensing.com) or through the respective patent owners individually for
     22 the purpose of encoding or decoding bit streams in products that are compliant
     23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
     24 Android devices already license these patent claims through Via Licensing or
     25 directly from the patent owners, and therefore FDK AAC Codec software may
     26 already be covered under those patent licenses when it is used for those
     27 licensed purposes only.
     28 
     29 Commercially-licensed AAC software libraries, including floating-point versions
     30 with enhanced sound quality, are also available from Fraunhofer. Users are
     31 encouraged to check the Fraunhofer website for additional applications
     32 information and documentation.
     33 
     34 2.    COPYRIGHT LICENSE
     35 
     36 Redistribution and use in source and binary forms, with or without modification,
     37 are permitted without payment of copyright license fees provided that you
     38 satisfy the following conditions:
     39 
     40 You must retain the complete text of this software license in redistributions of
     41 the FDK AAC Codec or your modifications thereto in source code form.
     42 
     43 You must retain the complete text of this software license in the documentation
     44 and/or other materials provided with redistributions of the FDK AAC Codec or
     45 your modifications thereto in binary form. You must make available free of
     46 charge copies of the complete source code of the FDK AAC Codec and your
     47 modifications thereto to recipients of copies in binary form.
     48 
     49 The name of Fraunhofer may not be used to endorse or promote products derived
     50 from this library without prior written permission.
     51 
     52 You may not charge copyright license fees for anyone to use, copy or distribute
     53 the FDK AAC Codec software or your modifications thereto.
     54 
     55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
     56 that you changed the software and the date of any change. For modified versions
     57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
     58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
     59 AAC Codec Library for Android."
     60 
     61 3.    NO PATENT LICENSE
     62 
     63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
     64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
     65 Fraunhofer provides no warranty of patent non-infringement with respect to this
     66 software.
     67 
     68 You may use this FDK AAC Codec software or modifications thereto only for
     69 purposes that are authorized by appropriate patent licenses.
     70 
     71 4.    DISCLAIMER
     72 
     73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
     74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
     75 including but not limited to the implied warranties of merchantability and
     76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
     77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
     78 or consequential damages, including but not limited to procurement of substitute
     79 goods or services; loss of use, data, or profits, or business interruption,
     80 however caused and on any theory of liability, whether in contract, strict
     81 liability, or tort (including negligence), arising in any way out of the use of
     82 this software, even if advised of the possibility of such damage.
     83 
     84 5.    CONTACT INFORMATION
     85 
     86 Fraunhofer Institute for Integrated Circuits IIS
     87 Attention: Audio and Multimedia Departments - FDK AAC LL
     88 Am Wolfsmantel 33
     89 91058 Erlangen, Germany
     90 
     91 www.iis.fraunhofer.de/amm
     92 amm-info (at) iis.fraunhofer.de
     93 ----------------------------------------------------------------------------- */
     94 
     95 /************************* MPEG-D DRC decoder library **************************
     96 
     97    Author(s):
     98 
     99    Description:
    100 
    101 *******************************************************************************/
    102 
    103 #include "fixpoint_math.h"
    104 #include "drcDec_reader.h"
    105 #include "drcDec_tools.h"
    106 #include "drcDec_rom.h"
    107 #include "drcDecoder.h"
    108 
    109 /* MPEG-D DRC AMD 1 */
    110 
    111 #define UNIDRCCONFEXT_PARAM_DRC 0x1
    112 #define UNIDRCCONFEXT_V1 0x2
    113 #define UNIDRCLOUDEXT_EQ 0x1
    114 
    115 #define UNIDRCGAINEXT_TERM 0x0
    116 #define UNIDRCLOUDEXT_TERM 0x0
    117 #define UNIDRCCONFEXT_TERM 0x0
    118 
    119 static int _getZ(const int nNodesMax) {
    120   /* Z is the minimum codeword length that is needed to encode all possible
    121    * timeDelta values */
    122   /* Z = ceil(log2(2*nNodesMax)) */
    123   int Z = 1;
    124   while ((1 << Z) < (2 * nNodesMax)) {
    125     Z++;
    126   }
    127   return Z;
    128 }
    129 
    130 static int _getTimeDeltaMin(const GAIN_SET* pGset, const int deltaTminDefault) {
    131   if (pGset->timeDeltaMinPresent) {
    132     return pGset->timeDeltaMin;
    133   } else {
    134     return deltaTminDefault;
    135   }
    136 }
    137 
    138 /* compare and assign */
    139 static inline int _compAssign(UCHAR* dest, const UCHAR src) {
    140   int diff = 0;
    141   if (*dest != src) diff = 1;
    142   *dest = src;
    143   return diff;
    144 }
    145 
    146 static inline int _compAssign(ULONG* dest, const ULONG src) {
    147   int diff = 0;
    148   if (*dest != src) diff = 1;
    149   *dest = src;
    150   return diff;
    151 }
    152 
    153 typedef const SCHAR (*Huffman)[2];
    154 
    155 int _decodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
    156                      HANDLE_FDK_BITSTREAM hBs) /*!< Handle to bitbuffer */
    157 {
    158   SCHAR index = 0;
    159   int value, bit;
    160 
    161   while (index >= 0) {
    162     bit = FDKreadBits(hBs, 1);
    163     index = h[index][bit];
    164   }
    165 
    166   value = index + 64; /* Add offset */
    167 
    168   return value;
    169 }
    170 
    171 /**********/
    172 /* uniDrc */
    173 /**********/
    174 
    175 DRC_ERROR
    176 drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
    177                   HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
    178                   const int frameSize, const int deltaTminDefault,
    179                   HANDLE_UNI_DRC_GAIN hUniDrcGain) {
    180   DRC_ERROR err = DE_OK;
    181   int loudnessInfoSetPresent, uniDrcConfigPresent;
    182 
    183   loudnessInfoSetPresent = FDKreadBits(hBs, 1);
    184   if (loudnessInfoSetPresent) {
    185     uniDrcConfigPresent = FDKreadBits(hBs, 1);
    186     if (uniDrcConfigPresent) {
    187       err = drcDec_readUniDrcConfig(hBs, hUniDrcConfig);
    188       if (err) return err;
    189     }
    190     err = drcDec_readLoudnessInfoSet(hBs, hLoudnessInfoSet);
    191     if (err) return err;
    192   }
    193 
    194   if (hUniDrcGain != NULL) {
    195     err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
    196                                 hUniDrcGain);
    197     if (err) return err;
    198   }
    199 
    200   return err;
    201 }
    202 
    203 /**************/
    204 /* uniDrcGain */
    205 /**************/
    206 
    207 static FIXP_SGL _decodeGainInitial(
    208     HANDLE_FDK_BITSTREAM hBs, const GAIN_CODING_PROFILE gainCodingProfile) {
    209   int sign, magn;
    210   FIXP_SGL gainInitial = (FIXP_SGL)0;
    211   switch (gainCodingProfile) {
    212     case GCP_REGULAR:
    213       sign = FDKreadBits(hBs, 1);
    214       magn = FDKreadBits(hBs, 8);
    215 
    216       gainInitial =
    217           (FIXP_SGL)(magn << (FRACT_BITS - 1 - 3 - 7)); /* magn * 0.125; */
    218       if (sign) gainInitial = -gainInitial;
    219       break;
    220     case GCP_FADING:
    221       sign = FDKreadBits(hBs, 1);
    222       if (sign == 0)
    223         gainInitial = (FIXP_SGL)0;
    224       else {
    225         magn = FDKreadBits(hBs, 10);
    226         gainInitial = -(FIXP_SGL)(
    227             (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
    228       }
    229       break;
    230     case GCP_CLIPPING_DUCKING:
    231       sign = FDKreadBits(hBs, 1);
    232       if (sign == 0)
    233         gainInitial = (FIXP_SGL)0;
    234       else {
    235         magn = FDKreadBits(hBs, 8);
    236         gainInitial = -(FIXP_SGL)(
    237             (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
    238       }
    239       break;
    240     case GCP_CONSTANT:
    241       break;
    242   }
    243   return gainInitial;
    244 }
    245 
    246 static int _decodeNNodes(HANDLE_FDK_BITSTREAM hBs) {
    247   int nNodes = 0, endMarker = 0;
    248 
    249   /* decode number of nodes */
    250   while (endMarker != 1) {
    251     nNodes++;
    252     if (nNodes >= 128) break;
    253     endMarker = FDKreadBits(hBs, 1);
    254   }
    255   return nNodes;
    256 }
    257 
    258 static void _decodeGains(HANDLE_FDK_BITSTREAM hBs,
    259                          const GAIN_CODING_PROFILE gainCodingProfile,
    260                          const int nNodes, GAIN_NODE* pNodes) {
    261   int k, deltaGain;
    262   Huffman deltaGainCodebook;
    263 
    264   pNodes[0].gainDb = _decodeGainInitial(hBs, gainCodingProfile);
    265 
    266   if (gainCodingProfile == GCP_CLIPPING_DUCKING) {
    267     deltaGainCodebook = (Huffman)&deltaGain_codingProfile_2_huffman;
    268   } else {
    269     deltaGainCodebook = (Huffman)&deltaGain_codingProfile_0_1_huffman;
    270   }
    271 
    272   for (k = 1; k < nNodes; k++) {
    273     deltaGain = _decodeHuffmanCW(deltaGainCodebook, hBs);
    274     if (k >= 16) continue;
    275     /* gain_dB_e = 7 */
    276     pNodes[k].gainDb =
    277         pNodes[k - 1].gainDb +
    278         (FIXP_SGL)(deltaGain << (FRACT_BITS - 1 - 7 -
    279                                  3)); /* pNodes[k-1].gainDb + 0.125*deltaGain */
    280   }
    281 }
    282 
    283 static void _decodeSlopes(HANDLE_FDK_BITSTREAM hBs,
    284                           const GAIN_INTERPOLATION_TYPE gainInterpolationType,
    285                           const int nNodes, GAIN_NODE* pNodes) {
    286   int k = 0;
    287 
    288   if (gainInterpolationType == GIT_SPLINE) {
    289     /* decode slope steepness */
    290     for (k = 0; k < nNodes; k++) {
    291       _decodeHuffmanCW((Huffman)&slopeSteepness_huffman, hBs);
    292     }
    293   }
    294 }
    295 
    296 static int _decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs, const int Z) {
    297   int prefix, mu;
    298 
    299   prefix = FDKreadBits(hBs, 2);
    300   switch (prefix) {
    301     case 0x0:
    302       return 1;
    303     case 0x1:
    304       mu = FDKreadBits(hBs, 2);
    305       return mu + 2;
    306     case 0x2:
    307       mu = FDKreadBits(hBs, 3);
    308       return mu + 6;
    309     case 0x3:
    310       mu = FDKreadBits(hBs, Z);
    311       return mu + 14;
    312     default:
    313       return 0;
    314   }
    315 }
    316 
    317 static void _decodeTimes(HANDLE_FDK_BITSTREAM hBs, const int deltaTmin,
    318                          const int frameSize, const int fullFrame,
    319                          const int timeOffset, const int Z, const int nNodes,
    320                          GAIN_NODE* pNodes) {
    321   int timeDelta, k;
    322   int timeOffs = timeOffset;
    323   int frameEndFlag, nodeTimeTmp, nodeResFlag;
    324 
    325   if (fullFrame == 0) {
    326     frameEndFlag = FDKreadBits(hBs, 1);
    327   } else {
    328     frameEndFlag = 1;
    329   }
    330 
    331   if (frameEndFlag ==
    332       1) { /* frameEndFlag == 1 signals that the last node is at the end of the
    333               DRC frame */
    334     nodeResFlag = 0;
    335     for (k = 0; k < nNodes - 1; k++) {
    336       /* decode a delta time value */
    337       timeDelta = _decodeTimeDelta(hBs, Z);
    338       if (k >= (16 - 1)) continue;
    339       /* frameEndFlag == 1 needs special handling for last node with node
    340        * reservoir */
    341       nodeTimeTmp = timeOffs + timeDelta * deltaTmin;
    342       if (nodeTimeTmp > frameSize + timeOffset) {
    343         if (nodeResFlag == 0) {
    344           pNodes[k].time = frameSize + timeOffset;
    345           nodeResFlag = 1;
    346         }
    347         pNodes[k + 1].time = nodeTimeTmp;
    348       } else {
    349         pNodes[k].time = nodeTimeTmp;
    350       }
    351       timeOffs = nodeTimeTmp;
    352     }
    353     if (nodeResFlag == 0) {
    354       k = fMin(k, 16 - 1);
    355       pNodes[k].time = frameSize + timeOffset;
    356     }
    357   } else {
    358     for (k = 0; k < nNodes; k++) {
    359       /* decode a delta time value */
    360       timeDelta = _decodeTimeDelta(hBs, Z);
    361       if (k >= 16) continue;
    362       pNodes[k].time = timeOffs + timeDelta * deltaTmin;
    363       timeOffs = pNodes[k].time;
    364     }
    365   }
    366 }
    367 
    368 static void _readNodes(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
    369                        const int frameSize, const int timeDeltaMin,
    370                        UCHAR* pNNodes, GAIN_NODE* pNodes) {
    371   int timeOffset, drcGainCodingMode, nNodes;
    372   int Z = _getZ(frameSize / timeDeltaMin);
    373   if (gainSet->timeAlignment == 0) {
    374     timeOffset = -1;
    375   } else {
    376     timeOffset = -timeDeltaMin +
    377                  (timeDeltaMin - 1) /
    378                      2; /* timeOffset = - deltaTmin + floor((deltaTmin-1)/2); */
    379   }
    380 
    381   drcGainCodingMode = FDKreadBits(hBs, 1);
    382   if (drcGainCodingMode == 0) {
    383     /* "simple" mode: only one node at the end of the frame with slope = 0 */
    384     nNodes = 1;
    385     pNodes[0].gainDb = _decodeGainInitial(
    386         hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile);
    387     pNodes[0].time = frameSize + timeOffset;
    388   } else {
    389     nNodes = _decodeNNodes(hBs);
    390 
    391     _decodeSlopes(hBs, (GAIN_INTERPOLATION_TYPE)gainSet->gainInterpolationType,
    392                   nNodes, pNodes);
    393 
    394     _decodeTimes(hBs, timeDeltaMin, frameSize, gainSet->fullFrame, timeOffset,
    395                  Z, nNodes, pNodes);
    396 
    397     _decodeGains(hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile, nNodes,
    398                  pNodes);
    399   }
    400   *pNNodes = (UCHAR)nNodes;
    401 }
    402 
    403 static void _readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
    404                                  const int frameSize, const int timeDeltaMin,
    405                                  UCHAR* pNNodes, GAIN_NODE pNodes[16]) {
    406   SHORT timeBufPrevFrame[16], timeBufCurFrame[16];
    407   int nNodesNodeRes, nNodesCur, k, m;
    408 
    409   if (gainSet->gainCodingProfile == GCP_CONSTANT) {
    410     *pNNodes = 1;
    411     pNodes[0].time = frameSize - 1;
    412     pNodes[0].gainDb = (FIXP_SGL)0;
    413   } else {
    414     _readNodes(hBs, gainSet, frameSize, timeDeltaMin, pNNodes, pNodes);
    415 
    416     /* count number of nodes in node reservoir */
    417     nNodesNodeRes = 0;
    418     nNodesCur = 0;
    419     /* count and buffer nodes from node reservoir */
    420     for (k = 0; k < *pNNodes; k++) {
    421       if (k >= 16) continue;
    422       if (pNodes[k].time >= frameSize) {
    423         /* write node reservoir times into buffer */
    424         timeBufPrevFrame[nNodesNodeRes] = pNodes[k].time;
    425         nNodesNodeRes++;
    426       } else { /* times from current frame */
    427         timeBufCurFrame[nNodesCur] = pNodes[k].time;
    428         nNodesCur++;
    429       }
    430     }
    431     /* compose right time order (bit reservoir first) */
    432     for (k = 0; k < nNodesNodeRes; k++) {
    433       /* subtract two time frameSize: one to remove node reservoir offset and
    434        * one to get the negative index relative to the current frame
    435        */
    436       pNodes[k].time = timeBufPrevFrame[k] - 2 * frameSize;
    437     }
    438     /* ...and times from current frame */
    439     for (m = 0; m < nNodesCur; m++, k++) {
    440       pNodes[k].time = timeBufCurFrame[m];
    441     }
    442   }
    443 }
    444 
    445 static DRC_ERROR _readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,
    446                                           UNI_DRC_GAIN_EXTENSION* pExt) {
    447   DRC_ERROR err = DE_OK;
    448   int k, bitSizeLen, extSizeBits, bitSize;
    449 
    450   k = 0;
    451   pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
    452   while (pExt->uniDrcGainExtType[k] != UNIDRCGAINEXT_TERM) {
    453     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
    454     bitSizeLen = FDKreadBits(hBs, 3);
    455     extSizeBits = bitSizeLen + 4;
    456 
    457     bitSize = FDKreadBits(hBs, extSizeBits);
    458     pExt->extBitSize[k] = bitSize + 1;
    459 
    460     switch (pExt->uniDrcGainExtType[k]) {
    461       /* add future extensions here */
    462       default:
    463         FDKpushFor(hBs, pExt->extBitSize[k]);
    464         break;
    465     }
    466     k++;
    467     pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
    468   }
    469 
    470   return err;
    471 }
    472 
    473 DRC_ERROR
    474 drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
    475                       HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
    476                       const int deltaTminDefault,
    477                       HANDLE_UNI_DRC_GAIN hUniDrcGain) {
    478   DRC_ERROR err = DE_OK;
    479   int seq, gainSequenceCount;
    480   DRC_COEFFICIENTS_UNI_DRC* pCoef =
    481       selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
    482   if (pCoef == NULL) return DE_OK;
    483   if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */
    484 
    485   gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);
    486 
    487   for (seq = 0; seq < gainSequenceCount; seq++) {
    488     UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
    489     GAIN_SET* gainSet;
    490     int timeDeltaMin;
    491     UCHAR tmpNNodes = 0;
    492     GAIN_NODE tmpNodes[16];
    493 
    494     if ((index >= pCoef->gainSetCount) || (index >= 12)) return DE_NOT_OK;
    495     gainSet = &(pCoef->gainSet[index]);
    496 
    497     timeDeltaMin = _getTimeDeltaMin(gainSet, deltaTminDefault);
    498 
    499     _readDrcGainSequence(hBs, gainSet, frameSize, timeDeltaMin, &tmpNNodes,
    500                          tmpNodes);
    501 
    502     hUniDrcGain->nNodes[seq] = tmpNNodes;
    503     FDKmemcpy(hUniDrcGain->gainNode[seq], tmpNodes,
    504               fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
    505   }
    506 
    507   hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
    508   if (hUniDrcGain->uniDrcGainExtPresent == 1) {
    509     err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
    510     if (err) return err;
    511   }
    512 
    513   return err;
    514 }
    515 
    516 /****************/
    517 /* uniDrcConfig */
    518 /****************/
    519 
    520 static void _decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,
    521                                        DUCKING_MODIFICATION* pDMod, int isBox) {
    522   int bsDuckingScaling, sigma, mu;
    523 
    524   if (isBox) FDKpushFor(hBs, 7); /* reserved */
    525   pDMod->duckingScalingPresent = FDKreadBits(hBs, 1);
    526 
    527   if (pDMod->duckingScalingPresent) {
    528     if (isBox) FDKpushFor(hBs, 4); /* reserved */
    529     bsDuckingScaling = FDKreadBits(hBs, 4);
    530     sigma = bsDuckingScaling >> 3;
    531     mu = bsDuckingScaling & 0x7;
    532 
    533     if (sigma) {
    534       pDMod->duckingScaling = (FIXP_SGL)(
    535           (7 - mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 - 0.125 * (1 + mu); */
    536     } else {
    537       pDMod->duckingScaling = (FIXP_SGL)(
    538           (9 + mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 + 0.125 * (1 + mu); */
    539     }
    540   } else {
    541     pDMod->duckingScaling = (FIXP_SGL)(1 << (FRACT_BITS - 1 - 2)); /* 1.0 */
    542   }
    543 }
    544 
    545 static void _decodeGainModification(HANDLE_FDK_BITSTREAM hBs, const int version,
    546                                     int bandCount, GAIN_MODIFICATION* pGMod,
    547                                     int isBox) {
    548   int sign, bsGainOffset, bsAttenuationScaling, bsAmplificationScaling;
    549 
    550   if (version > 0) {
    551     int b, shapeFilterPresent;
    552 
    553     if (isBox) {
    554       FDKpushFor(hBs, 4); /* reserved */
    555       bandCount = FDKreadBits(hBs, 4);
    556     }
    557 
    558     for (b = 0; b < bandCount; b++) {
    559       if (isBox) {
    560         FDKpushFor(hBs, 4); /* reserved */
    561         pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
    562         pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
    563         pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
    564         pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
    565       }
    566 
    567       if (!isBox)
    568         pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
    569       if (pGMod[b].targetCharacteristicLeftPresent) {
    570         if (isBox) FDKpushFor(hBs, 4); /* reserved */
    571         pGMod[b].targetCharacteristicLeftIndex = FDKreadBits(hBs, 4);
    572       }
    573       if (!isBox)
    574         pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
    575       if (pGMod[b].targetCharacteristicRightPresent) {
    576         if (isBox) FDKpushFor(hBs, 4); /* reserved */
    577         pGMod[b].targetCharacteristicRightIndex = FDKreadBits(hBs, 4);
    578       }
    579       if (!isBox) pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
    580       if (pGMod[b].gainScalingPresent) {
    581         bsAttenuationScaling = FDKreadBits(hBs, 4);
    582         pGMod[b].attenuationScaling = (FIXP_SGL)(
    583             bsAttenuationScaling
    584             << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
    585         bsAmplificationScaling = FDKreadBits(hBs, 4);
    586         pGMod[b].amplificationScaling = (FIXP_SGL)(
    587             bsAmplificationScaling
    588             << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
    589       }
    590       if (!isBox) pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
    591       if (pGMod[b].gainOffsetPresent) {
    592         if (isBox) FDKpushFor(hBs, 2); /* reserved */
    593         sign = FDKreadBits(hBs, 1);
    594         bsGainOffset = FDKreadBits(hBs, 5);
    595         pGMod[b].gainOffset = (FIXP_SGL)(
    596             (1 + bsGainOffset)
    597             << (FRACT_BITS - 1 - 2 - 4)); /* (1+bsGainOffset) * 0.25; */
    598         if (sign) {
    599           pGMod[b].gainOffset = -pGMod[b].gainOffset;
    600         }
    601       }
    602     }
    603     if (bandCount == 1) {
    604       shapeFilterPresent = FDKreadBits(hBs, 1);
    605       if (shapeFilterPresent) {
    606         if (isBox) FDKpushFor(hBs, 3); /* reserved */
    607         FDKpushFor(hBs, 4);            /* pGMod->shapeFilterIndex */
    608       } else {
    609         if (isBox) FDKpushFor(hBs, 7); /* reserved */
    610       }
    611     }
    612   } else {
    613     int b, gainScalingPresent, gainOffsetPresent;
    614     FIXP_SGL attenuationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
    615              amplificationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
    616              gainOffset = (FIXP_SGL)0;
    617     if (isBox) FDKpushFor(hBs, 7); /* reserved */
    618     gainScalingPresent = FDKreadBits(hBs, 1);
    619     if (gainScalingPresent) {
    620       bsAttenuationScaling = FDKreadBits(hBs, 4);
    621       attenuationScaling = (FIXP_SGL)(
    622           bsAttenuationScaling
    623           << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
    624       bsAmplificationScaling = FDKreadBits(hBs, 4);
    625       amplificationScaling = (FIXP_SGL)(
    626           bsAmplificationScaling
    627           << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
    628     }
    629     if (isBox) FDKpushFor(hBs, 7); /* reserved */
    630     gainOffsetPresent = FDKreadBits(hBs, 1);
    631     if (gainOffsetPresent) {
    632       if (isBox) FDKpushFor(hBs, 2); /* reserved */
    633       sign = FDKreadBits(hBs, 1);
    634       bsGainOffset = FDKreadBits(hBs, 5);
    635       gainOffset =
    636           (FIXP_SGL)((1 + bsGainOffset) << (FRACT_BITS - 1 - 2 -
    637                                             4)); /* (1+bsGainOffset) * 0.25; */
    638       if (sign) {
    639         gainOffset = -gainOffset;
    640       }
    641     }
    642     for (b = 0; b < 4; b++) {
    643       pGMod[b].targetCharacteristicLeftPresent = 0;
    644       pGMod[b].targetCharacteristicRightPresent = 0;
    645       pGMod[b].gainScalingPresent = gainScalingPresent;
    646       pGMod[b].attenuationScaling = attenuationScaling;
    647       pGMod[b].amplificationScaling = amplificationScaling;
    648       pGMod[b].gainOffsetPresent = gainOffsetPresent;
    649       pGMod[b].gainOffset = gainOffset;
    650     }
    651   }
    652 }
    653 
    654 static void _readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs, const int version,
    655                                    DRC_CHARACTERISTIC* pDChar, int isBox) {
    656   if (version == 0) {
    657     if (isBox) FDKpushFor(hBs, 1); /* reserved */
    658     pDChar->cicpIndex = FDKreadBits(hBs, 7);
    659     if (pDChar->cicpIndex > 0) {
    660       pDChar->present = 1;
    661       pDChar->isCICP = 1;
    662     } else {
    663       pDChar->present = 0;
    664     }
    665   } else {
    666     pDChar->present = FDKreadBits(hBs, 1);
    667     if (isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
    668     if (pDChar->present) {
    669       if (!isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
    670       if (pDChar->isCICP) {
    671         if (isBox) FDKpushFor(hBs, 1); /* reserved */
    672         pDChar->cicpIndex = FDKreadBits(hBs, 7);
    673       } else {
    674         pDChar->custom.left = FDKreadBits(hBs, 4);
    675         pDChar->custom.right = FDKreadBits(hBs, 4);
    676       }
    677     }
    678   }
    679 }
    680 
    681 static void _readBandBorder(HANDLE_FDK_BITSTREAM hBs, BAND_BORDER* pBBord,
    682                             int drcBandType, int isBox) {
    683   if (drcBandType) {
    684     if (isBox) FDKpushFor(hBs, 4); /* reserved */
    685     pBBord->crossoverFreqIndex = FDKreadBits(hBs, 4);
    686   } else {
    687     if (isBox) FDKpushFor(hBs, 6); /* reserved */
    688     pBBord->startSubBandIndex = FDKreadBits(hBs, 10);
    689   }
    690 }
    691 
    692 static DRC_ERROR _readGainSet(HANDLE_FDK_BITSTREAM hBs, const int version,
    693                               int* gainSequenceIndex, GAIN_SET* pGSet,
    694                               int isBox) {
    695   if (isBox) FDKpushFor(hBs, 2); /* reserved */
    696   pGSet->gainCodingProfile = FDKreadBits(hBs, 2);
    697   pGSet->gainInterpolationType = FDKreadBits(hBs, 1);
    698   pGSet->fullFrame = FDKreadBits(hBs, 1);
    699   pGSet->timeAlignment = FDKreadBits(hBs, 1);
    700   pGSet->timeDeltaMinPresent = FDKreadBits(hBs, 1);
    701 
    702   if (pGSet->timeDeltaMinPresent) {
    703     int bsTimeDeltaMin;
    704     if (isBox) FDKpushFor(hBs, 5); /* reserved */
    705     bsTimeDeltaMin = FDKreadBits(hBs, 11);
    706     pGSet->timeDeltaMin = bsTimeDeltaMin + 1;
    707   }
    708 
    709   if (pGSet->gainCodingProfile != GCP_CONSTANT) {
    710     int i;
    711     if (isBox) FDKpushFor(hBs, 3); /* reserved */
    712     pGSet->bandCount = FDKreadBits(hBs, 4);
    713     if (pGSet->bandCount > 4) return DE_MEMORY_ERROR;
    714 
    715     if ((pGSet->bandCount > 1) || isBox) {
    716       pGSet->drcBandType = FDKreadBits(hBs, 1);
    717     }
    718 
    719     for (i = 0; i < pGSet->bandCount; i++) {
    720       if (version == 0) {
    721         *gainSequenceIndex = (*gainSequenceIndex) + 1;
    722       } else {
    723         int indexPresent;
    724         indexPresent = (isBox) ? 1 : FDKreadBits(hBs, 1);
    725         if (indexPresent) {
    726           int bsIndex;
    727           bsIndex = FDKreadBits(hBs, 6);
    728           *gainSequenceIndex = bsIndex;
    729         } else {
    730           *gainSequenceIndex = (*gainSequenceIndex) + 1;
    731         }
    732       }
    733       pGSet->gainSequenceIndex[i] = *gainSequenceIndex;
    734       _readDrcCharacteristic(hBs, version, &(pGSet->drcCharacteristic[i]),
    735                              isBox);
    736     }
    737     for (i = 1; i < pGSet->bandCount; i++) {
    738       _readBandBorder(hBs, &(pGSet->bandBorder[i]), pGSet->drcBandType, isBox);
    739     }
    740   } else {
    741     pGSet->bandCount = 1;
    742     *gainSequenceIndex = (*gainSequenceIndex) + 1;
    743     pGSet->gainSequenceIndex[0] = *gainSequenceIndex;
    744   }
    745 
    746   return DE_OK;
    747 }
    748 
    749 static DRC_ERROR _readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,
    750                                               const CHARACTERISTIC_SIDE side,
    751                                               UCHAR* pCharacteristicFormat,
    752                                               CUSTOM_DRC_CHAR* pCChar,
    753                                               int isBox) {
    754   if (isBox) FDKpushFor(hBs, 7); /* reserved */
    755   *pCharacteristicFormat = FDKreadBits(hBs, 1);
    756   if (*pCharacteristicFormat == CF_SIGMOID) {
    757     int bsGain, bsIoRatio, bsExp;
    758     if (isBox) FDKpushFor(hBs, 1); /* reserved */
    759     bsGain = FDKreadBits(hBs, 6);
    760     if (side == CS_LEFT) {
    761       pCChar->sigmoid.gain = (FIXP_SGL)(bsGain << (FRACT_BITS - 1 - 6));
    762     } else {
    763       pCChar->sigmoid.gain = (FIXP_SGL)(-bsGain << (FRACT_BITS - 1 - 6));
    764     }
    765     bsIoRatio = FDKreadBits(hBs, 4);
    766     /* pCChar->sigmoid.ioRatio = 0.05 + 0.15 * bsIoRatio; */
    767     pCChar->sigmoid.ioRatio =
    768         FL2FXCONST_SGL(0.05f / (float)(1 << 2)) +
    769         (FIXP_SGL)((((3 * bsIoRatio) << (FRACT_BITS - 1)) / 5) >> 4);
    770     bsExp = FDKreadBits(hBs, 4);
    771     if (bsExp < 15) {
    772       pCChar->sigmoid.exp = (FIXP_SGL)((1 + 2 * bsExp) << (FRACT_BITS - 1 - 5));
    773     } else {
    774       pCChar->sigmoid.exp = (FIXP_SGL)MAXVAL_SGL; /* represents infinity */
    775     }
    776     pCChar->sigmoid.flipSign = FDKreadBits(hBs, 1);
    777   } else { /* CF_NODES */
    778     int i, bsCharacteristicNodeCount, bsNodeLevelDelta, bsNodeGain;
    779     if (isBox) FDKpushFor(hBs, 6); /* reserved */
    780     bsCharacteristicNodeCount = FDKreadBits(hBs, 2);
    781     pCChar->nodes.characteristicNodeCount = bsCharacteristicNodeCount + 1;
    782     if (pCChar->nodes.characteristicNodeCount > 4) return DE_MEMORY_ERROR;
    783     pCChar->nodes.nodeLevel[0] = DRC_INPUT_LOUDNESS_TARGET_SGL;
    784     pCChar->nodes.nodeGain[0] = (FIXP_SGL)0;
    785     for (i = 0; i < pCChar->nodes.characteristicNodeCount; i++) {
    786       if (isBox) FDKpushFor(hBs, 3); /* reserved */
    787       bsNodeLevelDelta = FDKreadBits(hBs, 5);
    788       if (side == CS_LEFT) {
    789         pCChar->nodes.nodeLevel[i + 1] =
    790             pCChar->nodes.nodeLevel[i] -
    791             (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
    792       } else {
    793         pCChar->nodes.nodeLevel[i + 1] =
    794             pCChar->nodes.nodeLevel[i] +
    795             (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
    796       }
    797       bsNodeGain = FDKreadBits(hBs, 8);
    798       pCChar->nodes.nodeGain[i + 1] = (FIXP_SGL)(
    799           (bsNodeGain - 128)
    800           << (FRACT_BITS - 1 - 1 - 7)); /* 0.5f * bsNodeGain - 64.0f; */
    801     }
    802   }
    803   return DE_OK;
    804 }
    805 
    806 static void _skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs) {
    807   int i;
    808   int downmixIdPresent, additionalDownmixIdPresent,
    809       additionalDownmixIdCount = 0;
    810   int drcSetIdPresent, additionalDrcSetIdPresent, additionalDrcSetIdCount = 0;
    811   int eqSetIdPresent, additionalEqSetIdPresent, additionalEqSetIdCount = 0;
    812   int loudEqGainSequenceCount, drcCharacteristicFormatIsCICP;
    813 
    814   FDKpushFor(hBs, 4); /* loudEqSetId */
    815   FDKpushFor(hBs, 4); /* drcLocation */
    816   downmixIdPresent = FDKreadBits(hBs, 1);
    817   if (downmixIdPresent) {
    818     FDKpushFor(hBs, 7); /* downmixId */
    819     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
    820     if (additionalDownmixIdPresent) {
    821       additionalDownmixIdCount = FDKreadBits(hBs, 7);
    822       for (i = 0; i < additionalDownmixIdCount; i++) {
    823         FDKpushFor(hBs, 7); /* additionalDownmixId */
    824       }
    825     }
    826   }
    827 
    828   drcSetIdPresent = FDKreadBits(hBs, 1);
    829   if (drcSetIdPresent) {
    830     FDKpushFor(hBs, 6); /* drcSetId */
    831     additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
    832     if (additionalDrcSetIdPresent) {
    833       additionalDrcSetIdCount = FDKreadBits(hBs, 6);
    834       for (i = 0; i < additionalDrcSetIdCount; i++) {
    835         FDKpushFor(hBs, 6); /* additionalDrcSetId; */
    836       }
    837     }
    838   }
    839 
    840   eqSetIdPresent = FDKreadBits(hBs, 1);
    841   if (eqSetIdPresent) {
    842     FDKpushFor(hBs, 6); /* eqSetId */
    843     additionalEqSetIdPresent = FDKreadBits(hBs, 1);
    844     if (additionalEqSetIdPresent) {
    845       additionalEqSetIdCount = FDKreadBits(hBs, 6);
    846       for (i = 0; i < additionalEqSetIdCount; i++) {
    847         FDKpushFor(hBs, 6); /* additionalEqSetId; */
    848       }
    849     }
    850   }
    851 
    852   FDKpushFor(hBs, 1); /* loudnessAfterDrc */
    853   FDKpushFor(hBs, 1); /* loudnessAfterEq */
    854   loudEqGainSequenceCount = FDKreadBits(hBs, 6);
    855   for (i = 0; i < loudEqGainSequenceCount; i++) {
    856     FDKpushFor(hBs, 6); /* gainSequenceIndex */
    857     drcCharacteristicFormatIsCICP = FDKreadBits(hBs, 1);
    858     if (drcCharacteristicFormatIsCICP) {
    859       FDKpushFor(hBs, 7); /* drcCharacteristic */
    860     } else {
    861       FDKpushFor(hBs, 4); /* drcCharacteristicLeftIndex */
    862       FDKpushFor(hBs, 4); /* drcCharacteristicRightIndex */
    863     }
    864     FDKpushFor(hBs, 6); /* frequencyRangeIndex */
    865     FDKpushFor(hBs, 3); /* bsLoudEqScaling */
    866     FDKpushFor(hBs, 5); /* bsLoudEqOffset */
    867   }
    868 }
    869 
    870 static void _skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs) {
    871   int nEqNodes, k, bits;
    872   nEqNodes = FDKreadBits(hBs, 5);
    873   nEqNodes += 2;
    874   for (k = 0; k < nEqNodes; k++) {
    875     bits = FDKreadBits(hBs, 1);
    876     if (!bits) {
    877       FDKpushFor(hBs, 4);
    878     }
    879   }
    880   FDKpushFor(hBs, 4 * (nEqNodes - 1));
    881   bits = FDKreadBits(hBs, 2);
    882   switch (bits) {
    883     case 0:
    884       FDKpushFor(hBs, 5);
    885       break;
    886     case 1:
    887     case 2:
    888       FDKpushFor(hBs, 4);
    889       break;
    890     case 3:
    891       FDKpushFor(hBs, 3);
    892       break;
    893   }
    894   FDKpushFor(hBs, 5 * (nEqNodes - 1));
    895 }
    896 
    897 static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
    898   int j, k;
    899   int eqDelayMaxPresent;
    900   int uniqueFilterBlockCount, filterElementCount, filterElementGainPresent;
    901   int uniqueTdFilterElementCount, eqFilterFormat, bsRealZeroRadiusOneCount,
    902       realZeroCount, genericZeroCount, realPoleCount, complexPoleCount,
    903       firFilterOrder;
    904   int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
    905       eqSubbandGainCount;
    906   EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat;
    907 
    908   eqDelayMaxPresent = FDKreadBits(hBs, 1);
    909   if (eqDelayMaxPresent) {
    910     FDKpushFor(hBs, 8); /* bsEqDelayMax */
    911   }
    912 
    913   uniqueFilterBlockCount = FDKreadBits(hBs, 6);
    914   for (j = 0; j < uniqueFilterBlockCount; j++) {
    915     filterElementCount = FDKreadBits(hBs, 6);
    916     for (k = 0; k < filterElementCount; k++) {
    917       FDKpushFor(hBs, 6); /* filterElementIndex */
    918       filterElementGainPresent = FDKreadBits(hBs, 1);
    919       if (filterElementGainPresent) {
    920         FDKpushFor(hBs, 10); /* bsFilterElementGain */
    921       }
    922     }
    923   }
    924   uniqueTdFilterElementCount = FDKreadBits(hBs, 6);
    925   for (j = 0; j < uniqueTdFilterElementCount; j++) {
    926     eqFilterFormat = FDKreadBits(hBs, 1);
    927     if (eqFilterFormat == 0) { /* pole/zero */
    928       bsRealZeroRadiusOneCount = FDKreadBits(hBs, 3);
    929       realZeroCount = FDKreadBits(hBs, 6);
    930       genericZeroCount = FDKreadBits(hBs, 6);
    931       realPoleCount = FDKreadBits(hBs, 4);
    932       complexPoleCount = FDKreadBits(hBs, 4);
    933       FDKpushFor(hBs, 2 * bsRealZeroRadiusOneCount * 1);
    934       FDKpushFor(hBs, realZeroCount * 8);
    935       FDKpushFor(hBs, genericZeroCount * 14);
    936       FDKpushFor(hBs, realPoleCount * 8);
    937       FDKpushFor(hBs, complexPoleCount * 14);
    938     } else { /* FIR coefficients */
    939       firFilterOrder = FDKreadBits(hBs, 7);
    940       FDKpushFor(hBs, 1);
    941       FDKpushFor(hBs, (firFilterOrder / 2 + 1) * 11);
    942     }
    943   }
    944   uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
    945   if (uniqueEqSubbandGainsCount > 0) {
    946     eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
    947     eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4);
    948     switch (eqSubbandGainFormat) {
    949       case GF_QMF32:
    950         eqSubbandGainCount = 32;
    951         break;
    952       case GF_QMFHYBRID39:
    953         eqSubbandGainCount = 39;
    954         break;
    955       case GF_QMF64:
    956         eqSubbandGainCount = 64;
    957         break;
    958       case GF_QMFHYBRID71:
    959         eqSubbandGainCount = 71;
    960         break;
    961       case GF_QMF128:
    962         eqSubbandGainCount = 128;
    963         break;
    964       case GF_QMFHYBRID135:
    965         eqSubbandGainCount = 135;
    966         break;
    967       case GF_UNIFORM:
    968       default:
    969         eqSubbandGainCount = FDKreadBits(hBs, 8);
    970         eqSubbandGainCount++;
    971         break;
    972     }
    973     for (k = 0; k < uniqueEqSubbandGainsCount; k++) {
    974       if (eqSubbandGainRepresentation == 1) {
    975         _skipEqSubbandGainSpline(hBs);
    976       } else {
    977         FDKpushFor(hBs, eqSubbandGainCount * 9);
    978       }
    979     }
    980   }
    981 }
    982 
    983 static void _skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,
    984                                  const int eqChannelGroupCount) {
    985   int i, eqCascadeGainPresent, filterBlockCount, eqPhaseAlignmentPresent;
    986   for (i = 0; i < eqChannelGroupCount; i++) {
    987     eqCascadeGainPresent = FDKreadBits(hBs, 1);
    988     if (eqCascadeGainPresent) {
    989       FDKpushFor(hBs, 10); /* bsEqCascadeGain */
    990     }
    991     filterBlockCount = FDKreadBits(hBs, 4);
    992     FDKpushFor(hBs, filterBlockCount * 7); /* filterBlockIndex */
    993   }
    994   eqPhaseAlignmentPresent = FDKreadBits(hBs, 1);
    995   {
    996     if (eqPhaseAlignmentPresent) {
    997       for (i = 0; i < eqChannelGroupCount; i++) {
    998         FDKpushFor(hBs, (eqChannelGroupCount - i - 1) * 1);
    999       }
   1000     }
   1001   }
   1002 }
   1003 
   1004 static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
   1005                                      HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1006   DRC_ERROR err = DE_OK;
   1007   int c, i, k, channelCount;
   1008   int downmixIdPresent, downmixId, eqApplyToDownmix, additionalDownmixIdPresent,
   1009       additionalDownmixIdCount = 0;
   1010   int additionalDrcSetIdPresent, additionalDrcSetIdCount;
   1011   int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
   1012       subbandGainsPresent, eqTransitionDurationPresent;
   1013 
   1014   FDKpushFor(hBs, 6); /* eqSetId */
   1015   FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
   1016   downmixIdPresent = FDKreadBits(hBs, 1);
   1017   if (downmixIdPresent) {
   1018     downmixId = FDKreadBits(hBs, 7);
   1019     eqApplyToDownmix = FDKreadBits(hBs, 1);
   1020     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1021     if (additionalDownmixIdPresent) {
   1022       additionalDownmixIdCount = FDKreadBits(hBs, 7);
   1023       FDKpushFor(hBs, additionalDownmixIdCount * 7); /* additionalDownmixId */
   1024     }
   1025   } else {
   1026     downmixId = 0;
   1027     eqApplyToDownmix = 0;
   1028   }
   1029   FDKpushFor(hBs, 6); /* drcSetId */
   1030   additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
   1031   if (additionalDrcSetIdPresent) {
   1032     additionalDrcSetIdCount = FDKreadBits(hBs, 6);
   1033     for (i = 0; i < additionalDrcSetIdCount; i++) {
   1034       FDKpushFor(hBs, 6); /* additionalDrcSetId */
   1035     }
   1036   }
   1037   FDKpushFor(hBs, 16); /* eqSetPurpose */
   1038   dependsOnEqSetPresent = FDKreadBits(hBs, 1);
   1039   if (dependsOnEqSetPresent) {
   1040     FDKpushFor(hBs, 6); /* dependsOnEqSet */
   1041   } else {
   1042     FDKpushFor(hBs, 1); /* noIndependentEqUse */
   1043   }
   1044 
   1045   channelCount = hUniDrcConfig->channelLayout.baseChannelCount;
   1046   if ((downmixIdPresent == 1) && (eqApplyToDownmix == 1) && (downmixId != 0) &&
   1047       (downmixId != DOWNMIX_ID_ANY_DOWNMIX) &&
   1048       (additionalDownmixIdCount == 0)) {
   1049     DOWNMIX_INSTRUCTIONS* pDown =
   1050         selectDownmixInstructions(hUniDrcConfig, downmixId);
   1051     if (pDown == NULL) return DE_NOT_OK;
   1052 
   1053     channelCount =
   1054         pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
   1055   } else if ((downmixId == DOWNMIX_ID_ANY_DOWNMIX) ||
   1056              (additionalDownmixIdCount > 1)) {
   1057     channelCount = 1;
   1058   }
   1059 
   1060   eqChannelGroupCount = 0;
   1061   for (c = 0; c < channelCount; c++) {
   1062     UCHAR eqChannelGroupForChannel[8];
   1063     int newGroup = 1;
   1064     if (c >= 8) return DE_MEMORY_ERROR;
   1065     eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
   1066     for (k = 0; k < c; k++) {
   1067       if (eqChannelGroupForChannel[c] == eqChannelGroupForChannel[k]) {
   1068         newGroup = 0;
   1069       }
   1070     }
   1071     if (newGroup == 1) {
   1072       eqChannelGroupCount += 1;
   1073     }
   1074   }
   1075   tdFilterCascadePresent = FDKreadBits(hBs, 1);
   1076   if (tdFilterCascadePresent) {
   1077     _skipTdFilterCascade(hBs, eqChannelGroupCount);
   1078   }
   1079   subbandGainsPresent = FDKreadBits(hBs, 1);
   1080   if (subbandGainsPresent) {
   1081     FDKpushFor(hBs, eqChannelGroupCount * 6); /* subbandGainsIndex */
   1082   }
   1083   eqTransitionDurationPresent = FDKreadBits(hBs, 1);
   1084   if (eqTransitionDurationPresent) {
   1085     FDKpushFor(hBs, 5); /* bsEqTransitionDuration */
   1086   }
   1087   return err;
   1088 }
   1089 
   1090 static void _skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs) {
   1091   FDKpushFor(hBs, 4); /* drcLocation */
   1092   FDKpushFor(hBs, 7); /* drcCharacteristic */
   1093 }
   1094 
   1095 static DRC_ERROR _readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,
   1096                                             const int version,
   1097                                             DRC_COEFFICIENTS_UNI_DRC* pCoef) {
   1098   DRC_ERROR err = DE_OK;
   1099   int i, bsDrcFrameSize;
   1100   int gainSequenceIndex = -1;
   1101 
   1102   pCoef->drcLocation = FDKreadBits(hBs, 4);
   1103   pCoef->drcFrameSizePresent = FDKreadBits(hBs, 1);
   1104 
   1105   if (pCoef->drcFrameSizePresent == 1) {
   1106     bsDrcFrameSize = FDKreadBits(hBs, 15);
   1107     pCoef->drcFrameSize = bsDrcFrameSize + 1;
   1108   }
   1109   if (version == 0) {
   1110     int gainSequenceCount = 0, gainSetCount;
   1111     pCoef->characteristicLeftCount = 0;
   1112     pCoef->characteristicRightCount = 0;
   1113     gainSetCount = FDKreadBits(hBs, 6);
   1114     pCoef->gainSetCount = fMin(gainSetCount, 12);
   1115     for (i = 0; i < gainSetCount; i++) {
   1116       GAIN_SET tmpGset;
   1117       FDKmemclear(&tmpGset, sizeof(GAIN_SET));
   1118       err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
   1119       if (err) return err;
   1120       gainSequenceCount += tmpGset.bandCount;
   1121 
   1122       if (i >= 12) continue;
   1123       pCoef->gainSet[i] = tmpGset;
   1124     }
   1125     pCoef->gainSequenceCount = gainSequenceCount;
   1126   } else { /* (version == 1) */
   1127     UCHAR drcCharacteristicLeftPresent, drcCharacteristicRightPresent;
   1128     UCHAR shapeFiltersPresent, shapeFilterCount, tmpPresent;
   1129     int gainSetCount;
   1130     drcCharacteristicLeftPresent = FDKreadBits(hBs, 1);
   1131     if (drcCharacteristicLeftPresent) {
   1132       pCoef->characteristicLeftCount = FDKreadBits(hBs, 4);
   1133       if ((pCoef->characteristicLeftCount + 1) > 8) return DE_MEMORY_ERROR;
   1134       for (i = 0; i < pCoef->characteristicLeftCount; i++) {
   1135         err = _readCustomDrcCharacteristic(
   1136             hBs, CS_LEFT, &(pCoef->characteristicLeftFormat[i + 1]),
   1137             &(pCoef->customCharacteristicLeft[i + 1]), 0);
   1138         if (err) return err;
   1139       }
   1140     }
   1141     drcCharacteristicRightPresent = FDKreadBits(hBs, 1);
   1142     if (drcCharacteristicRightPresent) {
   1143       pCoef->characteristicRightCount = FDKreadBits(hBs, 4);
   1144       if ((pCoef->characteristicRightCount + 1) > 8) return DE_MEMORY_ERROR;
   1145       for (i = 0; i < pCoef->characteristicRightCount; i++) {
   1146         err = _readCustomDrcCharacteristic(
   1147             hBs, CS_RIGHT, &(pCoef->characteristicRightFormat[i + 1]),
   1148             &(pCoef->customCharacteristicRight[i + 1]), 0);
   1149         if (err) return err;
   1150       }
   1151     }
   1152     shapeFiltersPresent = FDKreadBits(hBs, 1);
   1153     if (shapeFiltersPresent) {
   1154       shapeFilterCount = FDKreadBits(hBs, 4);
   1155       for (i = 0; i < shapeFilterCount; i++) {
   1156         tmpPresent = FDKreadBits(hBs, 1);
   1157         if (tmpPresent) /* lfCutParams */
   1158           FDKpushFor(hBs, 5);
   1159 
   1160         tmpPresent = FDKreadBits(hBs, 1);
   1161         if (tmpPresent) /* lfBoostParams */
   1162           FDKpushFor(hBs, 5);
   1163 
   1164         tmpPresent = FDKreadBits(hBs, 1);
   1165         if (tmpPresent) /* hfCutParams */
   1166           FDKpushFor(hBs, 5);
   1167 
   1168         tmpPresent = FDKreadBits(hBs, 1);
   1169         if (tmpPresent) /* hfBoostParams */
   1170           FDKpushFor(hBs, 5);
   1171       }
   1172     }
   1173     pCoef->gainSequenceCount = FDKreadBits(hBs, 6);
   1174     gainSetCount = FDKreadBits(hBs, 6);
   1175     pCoef->gainSetCount = fMin(gainSetCount, 12);
   1176     for (i = 0; i < gainSetCount; i++) {
   1177       GAIN_SET tmpGset;
   1178       FDKmemclear(&tmpGset, sizeof(GAIN_SET));
   1179       err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
   1180       if (err) return err;
   1181 
   1182       if (i >= 12) continue;
   1183       pCoef->gainSet[i] = tmpGset;
   1184     }
   1185   }
   1186   for (i = 0; i < 12; i++) {
   1187     pCoef->gainSetIndexForGainSequence[i] = 255;
   1188   }
   1189   for (i = 0; i < pCoef->gainSetCount; i++) {
   1190     int b;
   1191     for (b = 0; b < pCoef->gainSet[i].bandCount; b++) {
   1192       if (pCoef->gainSet[i].gainSequenceIndex[b] >= 12) continue;
   1193       pCoef->gainSetIndexForGainSequence[pCoef->gainSet[i]
   1194                                              .gainSequenceIndex[b]] = i;
   1195     }
   1196   }
   1197 
   1198   return err;
   1199 }
   1200 
   1201 static void _skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs) {
   1202   int drcSetEffect;
   1203   int additionalDownmixIdPresent, additionalDownmixIdCount,
   1204       limiterPeakTargetPresent;
   1205   int drcSetTargetLoudnessPresent, drcSetTargetLoudnessValueLowerPresent;
   1206 
   1207   FDKpushFor(hBs, 6); /* drcSetId */
   1208   FDKpushFor(hBs, 4); /* drcLocation */
   1209   FDKpushFor(hBs, 7); /* downmixId */
   1210   additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1211   if (additionalDownmixIdPresent) {
   1212     additionalDownmixIdCount = FDKreadBits(hBs, 3);
   1213     FDKpushFor(hBs, 7 * additionalDownmixIdCount); /* additionalDownmixId */
   1214   }
   1215 
   1216   drcSetEffect = FDKreadBits(hBs, 16);
   1217   if (!(drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF))) {
   1218     limiterPeakTargetPresent = FDKreadBits(hBs, 1);
   1219     if (limiterPeakTargetPresent) {
   1220       FDKpushFor(hBs, 8); /* bsLimiterPeakTarget */
   1221     }
   1222   }
   1223 
   1224   drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
   1225   if (drcSetTargetLoudnessPresent) {
   1226     FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueUpper */
   1227     drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
   1228     if (drcSetTargetLoudnessValueLowerPresent) {
   1229       FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueLower */
   1230     }
   1231   }
   1232 }
   1233 
   1234 static DRC_ERROR _readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,
   1235                                             const int version,
   1236                                             HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
   1237                                             DRC_INSTRUCTIONS_UNI_DRC* pInst) {
   1238   DRC_ERROR err = DE_OK;
   1239   int i, g, c;
   1240   int downmixIdPresent, additionalDownmixIdPresent, additionalDownmixIdCount;
   1241   int bsLimiterPeakTarget, channelCount;
   1242   DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
   1243   int repeatParameters, bsRepeatParametersCount;
   1244   int repeatSequenceIndex, bsRepeatSequenceCount;
   1245   SCHAR* gainSetIndex = pInst->gainSetIndex;
   1246   SCHAR channelGroupForChannel[8];
   1247   DUCKING_MODIFICATION duckingModificationForChannelGroup[8];
   1248 
   1249   pInst->drcSetId = FDKreadBits(hBs, 6);
   1250   if (version == 0) {
   1251     /* Assume all v0 DRC sets to be manageable in terms of complexity */
   1252     pInst->drcSetComplexityLevel = 2;
   1253   } else {
   1254     pInst->drcSetComplexityLevel = FDKreadBits(hBs, 4);
   1255   }
   1256   pInst->drcLocation = FDKreadBits(hBs, 4);
   1257   if (version == 0) {
   1258     downmixIdPresent = 1;
   1259   } else {
   1260     downmixIdPresent = FDKreadBits(hBs, 1);
   1261   }
   1262   if (downmixIdPresent) {
   1263     pInst->downmixId[0] = FDKreadBits(hBs, 7);
   1264     if (version == 0) {
   1265       if (pInst->downmixId[0] == 0)
   1266         pInst->drcApplyToDownmix = 0;
   1267       else
   1268         pInst->drcApplyToDownmix = 1;
   1269     } else {
   1270       pInst->drcApplyToDownmix = FDKreadBits(hBs, 1);
   1271     }
   1272 
   1273     additionalDownmixIdPresent = FDKreadBits(hBs, 1);
   1274     if (additionalDownmixIdPresent) {
   1275       additionalDownmixIdCount = FDKreadBits(hBs, 3);
   1276       if ((1 + additionalDownmixIdCount) > 8) return DE_MEMORY_ERROR;
   1277       for (i = 0; i < additionalDownmixIdCount; i++) {
   1278         pInst->downmixId[i + 1] = FDKreadBits(hBs, 7);
   1279       }
   1280       pInst->downmixIdCount = 1 + additionalDownmixIdCount;
   1281     } else {
   1282       pInst->downmixIdCount = 1;
   1283     }
   1284   } else {
   1285     pInst->downmixId[0] = 0;
   1286     pInst->downmixIdCount = 1;
   1287   }
   1288 
   1289   pInst->drcSetEffect = FDKreadBits(hBs, 16);
   1290 
   1291   if ((pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) {
   1292     pInst->limiterPeakTargetPresent = FDKreadBits(hBs, 1);
   1293     if (pInst->limiterPeakTargetPresent) {
   1294       bsLimiterPeakTarget = FDKreadBits(hBs, 8);
   1295       pInst->limiterPeakTarget = -(FIXP_SGL)(
   1296           bsLimiterPeakTarget
   1297           << (FRACT_BITS - 1 - 3 - 5)); /* - bsLimiterPeakTarget * 0.125; */
   1298     }
   1299   }
   1300 
   1301   pInst->drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
   1302 
   1303   /* set default values */
   1304   pInst->drcSetTargetLoudnessValueUpper = 0;
   1305   pInst->drcSetTargetLoudnessValueLower = -63;
   1306 
   1307   if (pInst->drcSetTargetLoudnessPresent == 1) {
   1308     int bsDrcSetTargetLoudnessValueUpper, bsDrcSetTargetLoudnessValueLower;
   1309     int drcSetTargetLoudnessValueLowerPresent;
   1310     bsDrcSetTargetLoudnessValueUpper = FDKreadBits(hBs, 6);
   1311     pInst->drcSetTargetLoudnessValueUpper =
   1312         bsDrcSetTargetLoudnessValueUpper - 63;
   1313     drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
   1314     if (drcSetTargetLoudnessValueLowerPresent == 1) {
   1315       bsDrcSetTargetLoudnessValueLower = FDKreadBits(hBs, 6);
   1316       pInst->drcSetTargetLoudnessValueLower =
   1317           bsDrcSetTargetLoudnessValueLower - 63;
   1318     }
   1319   }
   1320 
   1321   pInst->dependsOnDrcSetPresent = FDKreadBits(hBs, 1);
   1322 
   1323   pInst->noIndependentUse = 0;
   1324   if (pInst->dependsOnDrcSetPresent) {
   1325     pInst->dependsOnDrcSet = FDKreadBits(hBs, 6);
   1326   } else {
   1327     pInst->noIndependentUse = FDKreadBits(hBs, 1);
   1328   }
   1329 
   1330   if (version == 0) {
   1331     pInst->requiresEq = 0;
   1332   } else {
   1333     pInst->requiresEq = FDKreadBits(hBs, 1);
   1334   }
   1335 
   1336   pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);
   1337 
   1338   pInst->drcChannelCount = channelCount =
   1339       hUniDrcConfig->channelLayout.baseChannelCount;
   1340 
   1341   if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
   1342     DUCKING_MODIFICATION* pDModForChannel =
   1343         pInst->duckingModificationForChannel;
   1344     c = 0;
   1345     while (c < channelCount) {
   1346       int bsGainSetIndex;
   1347       bsGainSetIndex = FDKreadBits(hBs, 6);
   1348       if (c >= 8) return DE_MEMORY_ERROR;
   1349       gainSetIndex[c] = bsGainSetIndex - 1;
   1350       _decodeDuckingModification(hBs, &(pDModForChannel[c]), 0);
   1351 
   1352       c++;
   1353       repeatParameters = FDKreadBits(hBs, 1);
   1354       if (repeatParameters == 1) {
   1355         bsRepeatParametersCount = FDKreadBits(hBs, 5);
   1356         bsRepeatParametersCount += 1;
   1357         for (i = 0; i < bsRepeatParametersCount; i++) {
   1358           if (c >= 8) return DE_MEMORY_ERROR;
   1359           gainSetIndex[c] = gainSetIndex[c - 1];
   1360           pDModForChannel[c] = pDModForChannel[c - 1];
   1361           c++;
   1362         }
   1363       }
   1364     }
   1365     if (c > channelCount) {
   1366       return DE_NOT_OK;
   1367     }
   1368 
   1369     err = deriveDrcChannelGroups(
   1370         pInst->drcSetEffect, pInst->drcChannelCount, gainSetIndex,
   1371         pDModForChannel, &pInst->nDrcChannelGroups,
   1372         pInst->gainSetIndexForChannelGroup, channelGroupForChannel,
   1373         duckingModificationForChannelGroup);
   1374     if (err) return (err);
   1375   } else {
   1376     int deriveChannelCount = 0;
   1377     if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
   1378         (pInst->downmixId[0] != DOWNMIX_ID_BASE_LAYOUT) &&
   1379         (pInst->downmixId[0] != DOWNMIX_ID_ANY_DOWNMIX) &&
   1380         (pInst->downmixIdCount == 1)) {
   1381       if (hUniDrcConfig->downmixInstructionsCount != 0) {
   1382         DOWNMIX_INSTRUCTIONS* pDown =
   1383             selectDownmixInstructions(hUniDrcConfig, pInst->downmixId[0]);
   1384         if (pDown == NULL) return DE_NOT_OK;
   1385         pInst->drcChannelCount = channelCount =
   1386             pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
   1387       } else {
   1388         deriveChannelCount = 1;
   1389         channelCount = 1;
   1390       }
   1391     } else if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
   1392                ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
   1393                 (pInst->downmixIdCount > 1))) {
   1394       /* Set maximum channel count as upper border. The effective channel count
   1395        * is set at the process function. */
   1396       pInst->drcChannelCount = 8;
   1397       channelCount = 1;
   1398     }
   1399 
   1400     c = 0;
   1401     while (c < channelCount) {
   1402       int bsGainSetIndex;
   1403       bsGainSetIndex = FDKreadBits(hBs, 6);
   1404       if (c >= 8) return DE_MEMORY_ERROR;
   1405       gainSetIndex[c] = bsGainSetIndex - 1;
   1406       c++;
   1407       repeatSequenceIndex = FDKreadBits(hBs, 1);
   1408 
   1409       if (repeatSequenceIndex == 1) {
   1410         bsRepeatSequenceCount = FDKreadBits(hBs, 5);
   1411         bsRepeatSequenceCount += 1;
   1412         if (deriveChannelCount) {
   1413           channelCount = 1 + bsRepeatSequenceCount;
   1414         }
   1415         for (i = 0; i < bsRepeatSequenceCount; i++) {
   1416           if (c >= 8) return DE_MEMORY_ERROR;
   1417           gainSetIndex[c] = bsGainSetIndex - 1;
   1418           c++;
   1419         }
   1420       }
   1421     }
   1422     if (c > channelCount) {
   1423       return DE_NOT_OK;
   1424     }
   1425     if (deriveChannelCount) {
   1426       pInst->drcChannelCount = channelCount;
   1427     }
   1428 
   1429     /* DOWNMIX_ID_ANY_DOWNMIX: channelCount is 1. Distribute gainSetIndex to all
   1430      * channels. */
   1431     if ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
   1432         (pInst->downmixIdCount > 1)) {
   1433       for (c = 1; c < pInst->drcChannelCount; c++) {
   1434         gainSetIndex[c] = gainSetIndex[0];
   1435       }
   1436     }
   1437 
   1438     err = deriveDrcChannelGroups(pInst->drcSetEffect, pInst->drcChannelCount,
   1439                                  gainSetIndex, NULL, &pInst->nDrcChannelGroups,
   1440                                  pInst->gainSetIndexForChannelGroup,
   1441                                  channelGroupForChannel, NULL);
   1442     if (err) return (err);
   1443 
   1444     for (g = 0; g < pInst->nDrcChannelGroups; g++) {
   1445       int set, bandCount;
   1446       set = pInst->gainSetIndexForChannelGroup[g];
   1447 
   1448       /* get bandCount */
   1449       if (pCoef != NULL && set < pCoef->gainSetCount) {
   1450         bandCount = pCoef->gainSet[set].bandCount;
   1451       } else {
   1452         bandCount = 1;
   1453       }
   1454 
   1455       _decodeGainModification(hBs, version, bandCount,
   1456                               pInst->gainModificationForChannelGroup[g], 0);
   1457     }
   1458   }
   1459 
   1460   return err;
   1461 }
   1462 
   1463 static DRC_ERROR _readChannelLayout(HANDLE_FDK_BITSTREAM hBs,
   1464                                     CHANNEL_LAYOUT* pChan) {
   1465   DRC_ERROR err = DE_OK;
   1466 
   1467   pChan->baseChannelCount = FDKreadBits(hBs, 7);
   1468 
   1469   if (pChan->baseChannelCount > 8) return DE_NOT_OK;
   1470 
   1471   pChan->layoutSignalingPresent = FDKreadBits(hBs, 1);
   1472 
   1473   if (pChan->layoutSignalingPresent) {
   1474     pChan->definedLayout = FDKreadBits(hBs, 8);
   1475 
   1476     if (pChan->definedLayout == 0) {
   1477       int i;
   1478       for (i = 0; i < pChan->baseChannelCount; i++) {
   1479         if (i < 8) {
   1480           pChan->speakerPosition[i] = FDKreadBits(hBs, 7);
   1481         } else {
   1482           FDKpushFor(hBs, 7);
   1483         }
   1484       }
   1485     }
   1486   }
   1487   return err;
   1488 }
   1489 
   1490 static DRC_ERROR _readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,
   1491                                           const int version,
   1492                                           CHANNEL_LAYOUT* pChan,
   1493                                           DOWNMIX_INSTRUCTIONS* pDown) {
   1494   DRC_ERROR err = DE_OK;
   1495 
   1496   pDown->downmixId = FDKreadBits(hBs, 7);
   1497   pDown->targetChannelCount = FDKreadBits(hBs, 7);
   1498   pDown->targetLayout = FDKreadBits(hBs, 8);
   1499   pDown->downmixCoefficientsPresent = FDKreadBits(hBs, 1);
   1500 
   1501   if (pDown->downmixCoefficientsPresent) {
   1502     int nDownmixCoeffs = pDown->targetChannelCount * pChan->baseChannelCount;
   1503     int i;
   1504     if (nDownmixCoeffs > 8 * 8) return DE_NOT_OK;
   1505     if (version == 0) {
   1506       pDown->bsDownmixOffset = 0;
   1507       for (i = 0; i < nDownmixCoeffs; i++) {
   1508         /* LFE downmix coefficients are not supported. */
   1509         pDown->downmixCoefficient[i] = downmixCoeff[FDKreadBits(hBs, 4)];
   1510       }
   1511     } else {
   1512       pDown->bsDownmixOffset = FDKreadBits(hBs, 4);
   1513       for (i = 0; i < nDownmixCoeffs; i++) {
   1514         pDown->downmixCoefficient[i] = downmixCoeffV1[FDKreadBits(hBs, 5)];
   1515       }
   1516     }
   1517   }
   1518   return err;
   1519 }
   1520 
   1521 static DRC_ERROR _readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,
   1522                                      HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1523   DRC_ERROR err = DE_OK;
   1524   int downmixInstructionsV1Present;
   1525   int drcCoeffsAndInstructionsUniDrcV1Present;
   1526   int loudEqInstructionsPresent, loudEqInstructionsCount;
   1527   int eqPresent, eqInstructionsCount;
   1528   int i, offset;
   1529   int diff = hUniDrcConfig->diff;
   1530 
   1531   downmixInstructionsV1Present = FDKreadBits(hBs, 1);
   1532   if (downmixInstructionsV1Present == 1) {
   1533     diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1,
   1534                         FDKreadBits(hBs, 7));
   1535     offset = hUniDrcConfig->downmixInstructionsCountV0;
   1536     hUniDrcConfig->downmixInstructionsCount = fMin(
   1537         (UCHAR)(offset + hUniDrcConfig->downmixInstructionsCountV1), (UCHAR)6);
   1538     for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV1; i++) {
   1539       DOWNMIX_INSTRUCTIONS tmpDown;
   1540       FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
   1541       err = _readDownmixInstructions(hBs, 1, &hUniDrcConfig->channelLayout,
   1542                                      &tmpDown);
   1543       if (err) return err;
   1544       if ((offset + i) >= 6) continue;
   1545       if (!diff)
   1546         diff |= (FDKmemcmp(&tmpDown,
   1547                            &(hUniDrcConfig->downmixInstructions[offset + i]),
   1548                            sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
   1549       hUniDrcConfig->downmixInstructions[offset + i] = tmpDown;
   1550     }
   1551   } else {
   1552     diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1, 0);
   1553   }
   1554 
   1555   drcCoeffsAndInstructionsUniDrcV1Present = FDKreadBits(hBs, 1);
   1556   if (drcCoeffsAndInstructionsUniDrcV1Present == 1) {
   1557     diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1,
   1558                         FDKreadBits(hBs, 3));
   1559     offset = hUniDrcConfig->drcCoefficientsUniDrcCountV0;
   1560     hUniDrcConfig->drcCoefficientsUniDrcCount =
   1561         fMin((UCHAR)(offset + hUniDrcConfig->drcCoefficientsUniDrcCountV1),
   1562              (UCHAR)2);
   1563     for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV1; i++) {
   1564       DRC_COEFFICIENTS_UNI_DRC tmpCoef;
   1565       FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
   1566       err = _readDrcCoefficientsUniDrc(hBs, 1, &tmpCoef);
   1567       if (err) return err;
   1568       if ((offset + i) >= 2) continue;
   1569       if (!diff)
   1570         diff |= (FDKmemcmp(&tmpCoef,
   1571                            &(hUniDrcConfig->drcCoefficientsUniDrc[offset + i]),
   1572                            sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
   1573       hUniDrcConfig->drcCoefficientsUniDrc[offset + i] = tmpCoef;
   1574     }
   1575 
   1576     diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1,
   1577                         FDKreadBits(hBs, 6));
   1578     offset = hUniDrcConfig->drcInstructionsUniDrcCount;
   1579     hUniDrcConfig->drcInstructionsUniDrcCount =
   1580         fMin((UCHAR)(offset + hUniDrcConfig->drcInstructionsUniDrcCountV1),
   1581              (UCHAR)12);
   1582     for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
   1583       DRC_INSTRUCTIONS_UNI_DRC tmpInst;
   1584       FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
   1585       err = _readDrcInstructionsUniDrc(hBs, 1, hUniDrcConfig, &tmpInst);
   1586       if (err) return err;
   1587       if ((offset + i) >= 12) continue;
   1588       if (!diff)
   1589         diff |= (FDKmemcmp(&tmpInst,
   1590                            &(hUniDrcConfig->drcInstructionsUniDrc[offset + i]),
   1591                            sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
   1592       hUniDrcConfig->drcInstructionsUniDrc[offset + i] = tmpInst;
   1593     }
   1594   } else {
   1595     diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1, 0);
   1596     diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1, 0);
   1597   }
   1598 
   1599   loudEqInstructionsPresent = FDKreadBits(hBs, 1);
   1600   if (loudEqInstructionsPresent == 1) {
   1601     loudEqInstructionsCount = FDKreadBits(hBs, 4);
   1602     for (i = 0; i < loudEqInstructionsCount; i++) {
   1603       _skipLoudEqInstructions(hBs);
   1604     }
   1605   }
   1606 
   1607   eqPresent = FDKreadBits(hBs, 1);
   1608   if (eqPresent == 1) {
   1609     _skipEqCoefficients(hBs);
   1610     eqInstructionsCount = FDKreadBits(hBs, 4);
   1611     for (i = 0; i < eqInstructionsCount; i++) {
   1612       _skipEqInstructions(hBs, hUniDrcConfig);
   1613     }
   1614   }
   1615 
   1616   hUniDrcConfig->diff = diff;
   1617 
   1618   return err;
   1619 }
   1620 
   1621 static DRC_ERROR _readUniDrcConfigExtension(
   1622     HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1623   DRC_ERROR err = DE_OK;
   1624   int k, bitSizeLen, extSizeBits, bitSize;
   1625   INT nBitsRemaining;
   1626   UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt);
   1627 
   1628   k = 0;
   1629   pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
   1630   while (pExt->uniDrcConfigExtType[k] != UNIDRCCONFEXT_TERM) {
   1631     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
   1632     bitSizeLen = FDKreadBits(hBs, 4);
   1633     extSizeBits = bitSizeLen + 4;
   1634 
   1635     bitSize = FDKreadBits(hBs, extSizeBits);
   1636     pExt->extBitSize[k] = bitSize + 1;
   1637     nBitsRemaining = (INT)FDKgetValidBits(hBs);
   1638 
   1639     switch (pExt->uniDrcConfigExtType[k]) {
   1640       case UNIDRCCONFEXT_V1:
   1641         err = _readDrcExtensionV1(hBs, hUniDrcConfig);
   1642         if (err) return err;
   1643         if (nBitsRemaining !=
   1644             ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
   1645           return DE_NOT_OK;
   1646         break;
   1647       case UNIDRCCONFEXT_PARAM_DRC:
   1648       /* add future extensions here */
   1649       default:
   1650         FDKpushFor(hBs, pExt->extBitSize[k]);
   1651         break;
   1652     }
   1653     k++;
   1654     pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
   1655   }
   1656 
   1657   return err;
   1658 }
   1659 
   1660 DRC_ERROR
   1661 drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
   1662                         HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
   1663   DRC_ERROR err = DE_OK;
   1664   int i, diff = 0;
   1665   int drcDescriptionBasicPresent, drcCoefficientsBasicCount,
   1666       drcInstructionsBasicCount;
   1667   CHANNEL_LAYOUT tmpChan;
   1668   FDKmemclear(&tmpChan, sizeof(CHANNEL_LAYOUT));
   1669   if (hUniDrcConfig == NULL) return DE_NOT_OK;
   1670 
   1671   diff |= _compAssign(&hUniDrcConfig->sampleRatePresent, FDKreadBits(hBs, 1));
   1672 
   1673   if (hUniDrcConfig->sampleRatePresent == 1) {
   1674     diff |=
   1675         _compAssign(&hUniDrcConfig->sampleRate, FDKreadBits(hBs, 18) + 1000);
   1676   }
   1677 
   1678   diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV0,
   1679                       FDKreadBits(hBs, 7));
   1680 
   1681   drcDescriptionBasicPresent = FDKreadBits(hBs, 1);
   1682   if (drcDescriptionBasicPresent == 1) {
   1683     drcCoefficientsBasicCount = FDKreadBits(hBs, 3);
   1684     drcInstructionsBasicCount = FDKreadBits(hBs, 4);
   1685   } else {
   1686     drcCoefficientsBasicCount = 0;
   1687     drcInstructionsBasicCount = 0;
   1688   }
   1689 
   1690   diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV0,
   1691                       FDKreadBits(hBs, 3));
   1692   diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV0,
   1693                       FDKreadBits(hBs, 6));
   1694 
   1695   err = _readChannelLayout(hBs, &tmpChan);
   1696   if (err) return err;
   1697 
   1698   if (!diff)
   1699     diff |= (FDKmemcmp(&tmpChan, &hUniDrcConfig->channelLayout,
   1700                        sizeof(CHANNEL_LAYOUT)) != 0);
   1701   hUniDrcConfig->channelLayout = tmpChan;
   1702 
   1703   hUniDrcConfig->downmixInstructionsCount =
   1704       fMin(hUniDrcConfig->downmixInstructionsCountV0, (UCHAR)6);
   1705   for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV0; i++) {
   1706     DOWNMIX_INSTRUCTIONS tmpDown;
   1707     FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
   1708     err = _readDownmixInstructions(hBs, 0, &hUniDrcConfig->channelLayout,
   1709                                    &tmpDown);
   1710     if (err) return err;
   1711     if (i >= 6) continue;
   1712     if (!diff)
   1713       diff |= (FDKmemcmp(&tmpDown, &(hUniDrcConfig->downmixInstructions[i]),
   1714                          sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
   1715     hUniDrcConfig->downmixInstructions[i] = tmpDown;
   1716   }
   1717 
   1718   for (i = 0; i < drcCoefficientsBasicCount; i++) {
   1719     _skipDrcCoefficientsBasic(hBs);
   1720   }
   1721   for (i = 0; i < drcInstructionsBasicCount; i++) {
   1722     _skipDrcInstructionsBasic(hBs);
   1723   }
   1724 
   1725   hUniDrcConfig->drcCoefficientsUniDrcCount =
   1726       fMin(hUniDrcConfig->drcCoefficientsUniDrcCountV0, (UCHAR)2);
   1727   for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV0; i++) {
   1728     DRC_COEFFICIENTS_UNI_DRC tmpCoef;
   1729     FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
   1730     err = _readDrcCoefficientsUniDrc(hBs, 0, &tmpCoef);
   1731     if (err) return err;
   1732     if (i >= 2) continue;
   1733     if (!diff)
   1734       diff |= (FDKmemcmp(&tmpCoef, &(hUniDrcConfig->drcCoefficientsUniDrc[i]),
   1735                          sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
   1736     hUniDrcConfig->drcCoefficientsUniDrc[i] = tmpCoef;
   1737   }
   1738 
   1739   hUniDrcConfig->drcInstructionsUniDrcCount =
   1740       fMin(hUniDrcConfig->drcInstructionsUniDrcCountV0, (UCHAR)12);
   1741   for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCountV0; i++) {
   1742     DRC_INSTRUCTIONS_UNI_DRC tmpInst;
   1743     FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
   1744     err = _readDrcInstructionsUniDrc(hBs, 0, hUniDrcConfig, &tmpInst);
   1745     if (err) return err;
   1746     if (i >= 12) continue;
   1747     if (!diff)
   1748       diff |= (FDKmemcmp(&tmpInst, &(hUniDrcConfig->drcInstructionsUniDrc[i]),
   1749                          sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
   1750     hUniDrcConfig->drcInstructionsUniDrc[i] = tmpInst;
   1751   }
   1752 
   1753   diff |=
   1754       _compAssign(&hUniDrcConfig->uniDrcConfigExtPresent, FDKreadBits(hBs, 1));
   1755   hUniDrcConfig->diff = diff;
   1756 
   1757   if (hUniDrcConfig->uniDrcConfigExtPresent == 1) {
   1758     err = _readUniDrcConfigExtension(hBs, hUniDrcConfig);
   1759     if (err) return err;
   1760   }
   1761 
   1762   return err;
   1763 }
   1764 
   1765 /*******************/
   1766 /* loudnessInfoSet */
   1767 /*******************/
   1768 
   1769 static DRC_ERROR _decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,
   1770                                     const UCHAR methodDefinition,
   1771                                     FIXP_DBL* methodValue, INT isBox) {
   1772   int tmp;
   1773   FIXP_DBL val;
   1774   switch (methodDefinition) {
   1775     case MD_UNKNOWN_OTHER:
   1776     case MD_PROGRAM_LOUDNESS:
   1777     case MD_ANCHOR_LOUDNESS:
   1778     case MD_MAX_OF_LOUDNESS_RANGE:
   1779     case MD_MOMENTARY_LOUDNESS_MAX:
   1780     case MD_SHORT_TERM_LOUDNESS_MAX:
   1781       tmp = FDKreadBits(hBs, 8);
   1782       val = FL2FXCONST_DBL(-57.75f / (float)(1 << 7)) +
   1783             (FIXP_DBL)(
   1784                 tmp << (DFRACT_BITS - 1 - 2 - 7)); /* -57.75 + tmp * 0.25; */
   1785       break;
   1786     case MD_LOUDNESS_RANGE:
   1787       tmp = FDKreadBits(hBs, 8);
   1788       if (tmp == 0)
   1789         val = (FIXP_DBL)0;
   1790       else if (tmp <= 128)
   1791         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 2 - 7)); /* tmp * 0.25; */
   1792       else if (tmp <= 204) {
   1793         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 1 - 7)) -
   1794               FL2FXCONST_DBL(32.0f / (float)(1 << 7)); /* 0.5 * tmp - 32.0f; */
   1795       } else {
   1796         /* downscale by 1 more bit to prevent overflow at intermediate result */
   1797         val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 8)) -
   1798               FL2FXCONST_DBL(134.0f / (float)(1 << 8)); /* tmp - 134.0; */
   1799         val <<= 1;
   1800       }
   1801       break;
   1802     case MD_MIXING_LEVEL:
   1803       tmp = FDKreadBits(hBs, isBox ? 8 : 5);
   1804       val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)) +
   1805             FL2FXCONST_DBL(80.0f / (float)(1 << 7)); /* tmp + 80.0; */
   1806       break;
   1807     case MD_ROOM_TYPE:
   1808       tmp = FDKreadBits(hBs, isBox ? 8 : 2);
   1809       val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)); /* tmp; */
   1810       break;
   1811     case MD_SHORT_TERM_LOUDNESS:
   1812       tmp = FDKreadBits(hBs, 8);
   1813       val = FL2FXCONST_DBL(-116.0f / (float)(1 << 7)) +
   1814             (FIXP_DBL)(
   1815                 tmp << (DFRACT_BITS - 1 - 1 - 7)); /* -116.0 + tmp * 0.5; */
   1816       break;
   1817     default:
   1818       return DE_NOT_OK; /* invalid methodDefinition value */
   1819   }
   1820   *methodValue = val;
   1821   return DE_OK;
   1822 }
   1823 
   1824 static DRC_ERROR _readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,
   1825                                           LOUDNESS_MEASUREMENT* pMeas) {
   1826   DRC_ERROR err = DE_OK;
   1827 
   1828   pMeas->methodDefinition = FDKreadBits(hBs, 4);
   1829   err =
   1830       _decodeMethodValue(hBs, pMeas->methodDefinition, &pMeas->methodValue, 0);
   1831   if (err) return err;
   1832   pMeas->measurementSystem = FDKreadBits(hBs, 4);
   1833   pMeas->reliability = FDKreadBits(hBs, 2);
   1834 
   1835   return err;
   1836 }
   1837 
   1838 static DRC_ERROR _readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs, const int version,
   1839                                    LOUDNESS_INFO* loudnessInfo) {
   1840   DRC_ERROR err = DE_OK;
   1841   int bsSamplePeakLevel, bsTruePeakLevel, i;
   1842   int measurementCount;
   1843 
   1844   loudnessInfo->drcSetId = FDKreadBits(hBs, 6);
   1845   if (version >= 1) {
   1846     loudnessInfo->eqSetId = FDKreadBits(hBs, 6);
   1847   } else {
   1848     loudnessInfo->eqSetId = 0;
   1849   }
   1850   loudnessInfo->downmixId = FDKreadBits(hBs, 7);
   1851 
   1852   loudnessInfo->samplePeakLevelPresent = FDKreadBits(hBs, 1);
   1853   if (loudnessInfo->samplePeakLevelPresent) {
   1854     bsSamplePeakLevel = FDKreadBits(hBs, 12);
   1855     if (bsSamplePeakLevel == 0) {
   1856       loudnessInfo->samplePeakLevelPresent = 0;
   1857       loudnessInfo->samplePeakLevel = (FIXP_DBL)0;
   1858     } else { /* 20.0 - bsSamplePeakLevel * 0.03125; */
   1859       loudnessInfo->samplePeakLevel =
   1860           FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
   1861           (FIXP_DBL)(bsSamplePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
   1862     }
   1863   }
   1864 
   1865   loudnessInfo->truePeakLevelPresent = FDKreadBits(hBs, 1);
   1866   if (loudnessInfo->truePeakLevelPresent) {
   1867     bsTruePeakLevel = FDKreadBits(hBs, 12);
   1868     if (bsTruePeakLevel == 0) {
   1869       loudnessInfo->truePeakLevelPresent = 0;
   1870       loudnessInfo->truePeakLevel = (FIXP_DBL)0;
   1871     } else {
   1872       loudnessInfo->truePeakLevel =
   1873           FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
   1874           (FIXP_DBL)(bsTruePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
   1875     }
   1876     loudnessInfo->truePeakLevelMeasurementSystem = FDKreadBits(hBs, 4);
   1877     loudnessInfo->truePeakLevelReliability = FDKreadBits(hBs, 2);
   1878   }
   1879 
   1880   measurementCount = FDKreadBits(hBs, 4);
   1881   loudnessInfo->measurementCount = fMin(measurementCount, 8);
   1882   for (i = 0; i < measurementCount; i++) {
   1883     LOUDNESS_MEASUREMENT tmpMeas;
   1884     FDKmemclear(&tmpMeas, sizeof(LOUDNESS_MEASUREMENT));
   1885     err = _readLoudnessMeasurement(hBs, &tmpMeas);
   1886     if (err) return err;
   1887     if (i >= 8) continue;
   1888     loudnessInfo->loudnessMeasurement[i] = tmpMeas;
   1889   }
   1890 
   1891   return err;
   1892 }
   1893 
   1894 static DRC_ERROR _readLoudnessInfoSetExtEq(
   1895     HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1896   DRC_ERROR err = DE_OK;
   1897   int i, offset;
   1898   int diff = hLoudnessInfoSet->diff;
   1899 
   1900   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV1,
   1901                       FDKreadBits(hBs, 6));
   1902   diff |=
   1903       _compAssign(&hLoudnessInfoSet->loudnessInfoCountV1, FDKreadBits(hBs, 6));
   1904 
   1905   offset = hLoudnessInfoSet->loudnessInfoAlbumCountV0;
   1906   hLoudnessInfoSet->loudnessInfoAlbumCount = fMin(
   1907       (UCHAR)(offset + hLoudnessInfoSet->loudnessInfoAlbumCountV1), (UCHAR)12);
   1908   for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV1; i++) {
   1909     LOUDNESS_INFO tmpLoud;
   1910     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   1911     err = _readLoudnessInfo(hBs, 1, &tmpLoud);
   1912     if (err) return err;
   1913     if ((offset + i) >= 12) continue;
   1914     if (!diff)
   1915       diff |= (FDKmemcmp(&tmpLoud,
   1916                          &(hLoudnessInfoSet->loudnessInfoAlbum[offset + i]),
   1917                          sizeof(LOUDNESS_INFO)) != 0);
   1918     hLoudnessInfoSet->loudnessInfoAlbum[offset + i] = tmpLoud;
   1919   }
   1920 
   1921   offset = hLoudnessInfoSet->loudnessInfoCountV0;
   1922   hLoudnessInfoSet->loudnessInfoCount =
   1923       fMin((UCHAR)(offset + hLoudnessInfoSet->loudnessInfoCountV1), (UCHAR)12);
   1924   for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV1; i++) {
   1925     LOUDNESS_INFO tmpLoud;
   1926     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   1927     err = _readLoudnessInfo(hBs, 1, &tmpLoud);
   1928     if (err) return err;
   1929     if ((offset + i) >= 12) continue;
   1930     if (!diff)
   1931       diff |=
   1932           (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[offset + i]),
   1933                      sizeof(LOUDNESS_INFO)) != 0);
   1934     hLoudnessInfoSet->loudnessInfo[offset + i] = tmpLoud;
   1935   }
   1936   hLoudnessInfoSet->diff = diff;
   1937   return err;
   1938 }
   1939 
   1940 static DRC_ERROR _readLoudnessInfoSetExtension(
   1941     HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1942   DRC_ERROR err = DE_OK;
   1943   int k, bitSizeLen, extSizeBits, bitSize;
   1944   INT nBitsRemaining;
   1945   LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt);
   1946 
   1947   k = 0;
   1948   pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
   1949   while (pExt->loudnessInfoSetExtType[k] != UNIDRCLOUDEXT_TERM) {
   1950     if (k >= (8 - 1)) return DE_MEMORY_ERROR;
   1951     bitSizeLen = FDKreadBits(hBs, 4);
   1952     extSizeBits = bitSizeLen + 4;
   1953 
   1954     bitSize = FDKreadBits(hBs, extSizeBits);
   1955     pExt->extBitSize[k] = bitSize + 1;
   1956     nBitsRemaining = (INT)FDKgetValidBits(hBs);
   1957 
   1958     switch (pExt->loudnessInfoSetExtType[k]) {
   1959       case UNIDRCLOUDEXT_EQ:
   1960         err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet);
   1961         if (err) return err;
   1962         if (nBitsRemaining !=
   1963             ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
   1964           return DE_NOT_OK;
   1965         break;
   1966       /* add future extensions here */
   1967       default:
   1968         FDKpushFor(hBs, pExt->extBitSize[k]);
   1969         break;
   1970     }
   1971     k++;
   1972     pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
   1973   }
   1974 
   1975   return err;
   1976 }
   1977 
   1978 /* Parser for loundessInfoSet() */
   1979 DRC_ERROR
   1980 drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
   1981                            HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
   1982   DRC_ERROR err = DE_OK;
   1983   int i, diff = 0;
   1984   if (hLoudnessInfoSet == NULL) return DE_NOT_OK;
   1985 
   1986   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV0,
   1987                       FDKreadBits(hBs, 6));
   1988   diff |=
   1989       _compAssign(&hLoudnessInfoSet->loudnessInfoCountV0, FDKreadBits(hBs, 6));
   1990 
   1991   hLoudnessInfoSet->loudnessInfoAlbumCount =
   1992       fMin(hLoudnessInfoSet->loudnessInfoAlbumCountV0, (UCHAR)12);
   1993   for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV0; i++) {
   1994     LOUDNESS_INFO tmpLoud;
   1995     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   1996     err = _readLoudnessInfo(hBs, 0, &tmpLoud);
   1997     if (err) return err;
   1998     if (i >= 12) continue;
   1999     if (!diff)
   2000       diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfoAlbum[i]),
   2001                          sizeof(LOUDNESS_INFO)) != 0);
   2002     hLoudnessInfoSet->loudnessInfoAlbum[i] = tmpLoud;
   2003   }
   2004 
   2005   hLoudnessInfoSet->loudnessInfoCount =
   2006       fMin(hLoudnessInfoSet->loudnessInfoCountV0, (UCHAR)12);
   2007   for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV0; i++) {
   2008     LOUDNESS_INFO tmpLoud;
   2009     FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
   2010     err = _readLoudnessInfo(hBs, 0, &tmpLoud);
   2011     if (err) return err;
   2012     if (i >= 12) continue;
   2013     if (!diff)
   2014       diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[i]),
   2015                          sizeof(LOUDNESS_INFO)) != 0);
   2016     hLoudnessInfoSet->loudnessInfo[i] = tmpLoud;
   2017   }
   2018 
   2019   diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoSetExtPresent,
   2020                       FDKreadBits(hBs, 1));
   2021   hLoudnessInfoSet->diff = diff;
   2022 
   2023   if (hLoudnessInfoSet->loudnessInfoSetExtPresent) {
   2024     err = _readLoudnessInfoSetExtension(hBs, hLoudnessInfoSet);
   2025     if (err) return err;
   2026   }
   2027 
   2028   return err;
   2029 }
   2030