/* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android

© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved.

 1.    INTRODUCTION
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
scheme for digital audio. This FDK AAC Codec software is intended to be used on
a wide variety of Android devices.

AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
general perceptual audio codecs. AAC-ELD is considered the best-performing
full-bandwidth communications codec by independent studies and is widely
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
specifications.

Patent licenses for necessary patent claims for the FDK AAC Codec (including
those of Fraunhofer) may be obtained through Via Licensing
(www.vialicensing.com) or through the respective patent owners individually for
the purpose of encoding or decoding bit streams in products that are compliant
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
Android devices already license these patent claims through Via Licensing or
directly from the patent owners, and therefore FDK AAC Codec software may
already be covered under those patent licenses when it is used for those
licensed purposes only.

Commercially-licensed AAC software libraries, including floating-point versions
with enhanced sound quality, are also available from Fraunhofer. Users are
encouraged to check the Fraunhofer website for additional applications
information and documentation.

2.    COPYRIGHT LICENSE

Redistribution and use in source and binary forms, with or without modification,
are permitted without payment of copyright license fees provided that you
satisfy the following conditions:

You must retain the complete text of this software license in redistributions of
the FDK AAC Codec or your modifications thereto in source code form.

You must retain the complete text of this software license in the documentation
and/or other materials provided with redistributions of the FDK AAC Codec or
your modifications thereto in binary form. You must make available free of
charge copies of the complete source code of the FDK AAC Codec and your
modifications thereto to recipients of copies in binary form.

The name of Fraunhofer may not be used to endorse or promote products derived
from this library without prior written permission.

You may not charge copyright license fees for anyone to use, copy or distribute
the FDK AAC Codec software or your modifications thereto.

Your modified versions of the FDK AAC Codec must carry prominent notices stating
that you changed the software and the date of any change. For modified versions
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
AAC Codec Library for Android."

3.    NO PATENT LICENSE

NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
Fraunhofer provides no warranty of patent non-infringement with respect to this
software.

You may use this FDK AAC Codec software or modifications thereto only for
purposes that are authorized by appropriate patent licenses.

4.    DISCLAIMER

This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
including but not limited to the implied warranties of merchantability and
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
or consequential damages, including but not limited to procurement of substitute
goods or services; loss of use, data, or profits, or business interruption,
however caused and on any theory of liability, whether in contract, strict
liability, or tort (including negligence), arising in any way out of the use of
this software, even if advised of the possibility of such damage.

5.    CONTACT INFORMATION

Fraunhofer Institute for Integrated Circuits IIS
Attention: Audio and Multimedia Departments - FDK AAC LL
Am Wolfsmantel 33
91058 Erlangen, Germany

www.iis.fraunhofer.de/amm
amm-info@iis.fraunhofer.de
----------------------------------------------------------------------------- */

/************************* MPEG-D DRC decoder library **************************

   Author(s):

   Description:

*******************************************************************************/

#include "fixpoint_math.h"
#include "drcDec_reader.h"
#include "drcDec_tools.h"
#include "drcDec_rom.h"
#include "drcDecoder.h"

/* MPEG-D DRC AMD 1 */

#define UNIDRCCONFEXT_PARAM_DRC 0x1
#define UNIDRCCONFEXT_V1 0x2
#define UNIDRCLOUDEXT_EQ 0x1

#define UNIDRCGAINEXT_TERM 0x0
#define UNIDRCLOUDEXT_TERM 0x0
#define UNIDRCCONFEXT_TERM 0x0

static int _getZ(const int nNodesMax) {
  /* Z is the minimum codeword length that is needed to encode all possible
   * timeDelta values */
  /* Z = ceil(log2(2*nNodesMax)) */
  int Z = 1;
  while ((1 << Z) < (2 * nNodesMax)) {
    Z++;
  }
  return Z;
}

static int _getTimeDeltaMin(const GAIN_SET* pGset, const int deltaTminDefault) {
  if (pGset->timeDeltaMinPresent) {
    return pGset->timeDeltaMin;
  } else {
    return deltaTminDefault;
  }
}

/* compare and assign */
static inline int _compAssign(UCHAR* dest, const UCHAR src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

static inline int _compAssign(ULONG* dest, const ULONG src) {
  int diff = 0;
  if (*dest != src) diff = 1;
  *dest = src;
  return diff;
}

typedef const SCHAR (*Huffman)[2];

int _decodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */
                     HANDLE_FDK_BITSTREAM hBs) /*!< Handle to bitbuffer */
{
  SCHAR index = 0;
  int value, bit;

  while (index >= 0) {
    bit = FDKreadBits(hBs, 1);
    index = h[index][bit];
  }

  value = index + 64; /* Add offset */

  return value;
}

/**********/
/* uniDrc */
/**********/

DRC_ERROR
drcDec_readUniDrc(HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
                  HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet,
                  const int frameSize, const int deltaTminDefault,
                  HANDLE_UNI_DRC_GAIN hUniDrcGain) {
  DRC_ERROR err = DE_OK;
  int loudnessInfoSetPresent, uniDrcConfigPresent;

  loudnessInfoSetPresent = FDKreadBits(hBs, 1);
  if (loudnessInfoSetPresent) {
    uniDrcConfigPresent = FDKreadBits(hBs, 1);
    if (uniDrcConfigPresent) {
      err = drcDec_readUniDrcConfig(hBs, hUniDrcConfig);
      if (err) return err;
    }
    err = drcDec_readLoudnessInfoSet(hBs, hLoudnessInfoSet);
    if (err) return err;
  }

  if (hUniDrcGain != NULL) {
    err = drcDec_readUniDrcGain(hBs, hUniDrcConfig, frameSize, deltaTminDefault,
                                hUniDrcGain);
    if (err) return err;
  }

  return err;
}

/**************/
/* uniDrcGain */
/**************/

static FIXP_SGL _decodeGainInitial(
    HANDLE_FDK_BITSTREAM hBs, const GAIN_CODING_PROFILE gainCodingProfile) {
  int sign, magn;
  FIXP_SGL gainInitial = (FIXP_SGL)0;
  switch (gainCodingProfile) {
    case GCP_REGULAR:
      sign = FDKreadBits(hBs, 1);
      magn = FDKreadBits(hBs, 8);

      gainInitial =
          (FIXP_SGL)(magn << (FRACT_BITS - 1 - 3 - 7)); /* magn * 0.125; */
      if (sign) gainInitial = -gainInitial;
      break;
    case GCP_FADING:
      sign = FDKreadBits(hBs, 1);
      if (sign == 0)
        gainInitial = (FIXP_SGL)0;
      else {
        magn = FDKreadBits(hBs, 10);
        gainInitial = -(FIXP_SGL)(
            (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
      }
      break;
    case GCP_CLIPPING_DUCKING:
      sign = FDKreadBits(hBs, 1);
      if (sign == 0)
        gainInitial = (FIXP_SGL)0;
      else {
        magn = FDKreadBits(hBs, 8);
        gainInitial = -(FIXP_SGL)(
            (magn + 1) << (FRACT_BITS - 1 - 3 - 7)); /* - (magn + 1) * 0.125; */
      }
      break;
    case GCP_CONSTANT:
      break;
  }
  return gainInitial;
}

static int _decodeNNodes(HANDLE_FDK_BITSTREAM hBs) {
  int nNodes = 0, endMarker = 0;

  /* decode number of nodes */
  while (endMarker != 1) {
    nNodes++;
    if (nNodes >= 128) break;
    endMarker = FDKreadBits(hBs, 1);
  }
  return nNodes;
}

static void _decodeGains(HANDLE_FDK_BITSTREAM hBs,
                         const GAIN_CODING_PROFILE gainCodingProfile,
                         const int nNodes, GAIN_NODE* pNodes) {
  int k, deltaGain;
  Huffman deltaGainCodebook;

  pNodes[0].gainDb = _decodeGainInitial(hBs, gainCodingProfile);

  if (gainCodingProfile == GCP_CLIPPING_DUCKING) {
    deltaGainCodebook = (Huffman)&deltaGain_codingProfile_2_huffman;
  } else {
    deltaGainCodebook = (Huffman)&deltaGain_codingProfile_0_1_huffman;
  }

  for (k = 1; k < nNodes; k++) {
    deltaGain = _decodeHuffmanCW(deltaGainCodebook, hBs);
    if (k >= 16) continue;
    /* gain_dB_e = 7 */
    pNodes[k].gainDb =
        pNodes[k - 1].gainDb +
        (FIXP_SGL)(deltaGain << (FRACT_BITS - 1 - 7 -
                                 3)); /* pNodes[k-1].gainDb + 0.125*deltaGain */
  }
}

static void _decodeSlopes(HANDLE_FDK_BITSTREAM hBs,
                          const GAIN_INTERPOLATION_TYPE gainInterpolationType,
                          const int nNodes, GAIN_NODE* pNodes) {
  int k = 0;

  if (gainInterpolationType == GIT_SPLINE) {
    /* decode slope steepness */
    for (k = 0; k < nNodes; k++) {
      _decodeHuffmanCW((Huffman)&slopeSteepness_huffman, hBs);
    }
  }
}

static int _decodeTimeDelta(HANDLE_FDK_BITSTREAM hBs, const int Z) {
  int prefix, mu;

  prefix = FDKreadBits(hBs, 2);
  switch (prefix) {
    case 0x0:
      return 1;
    case 0x1:
      mu = FDKreadBits(hBs, 2);
      return mu + 2;
    case 0x2:
      mu = FDKreadBits(hBs, 3);
      return mu + 6;
    case 0x3:
      mu = FDKreadBits(hBs, Z);
      return mu + 14;
    default:
      return 0;
  }
}

static void _decodeTimes(HANDLE_FDK_BITSTREAM hBs, const int deltaTmin,
                         const int frameSize, const int fullFrame,
                         const int timeOffset, const int Z, const int nNodes,
                         GAIN_NODE* pNodes) {
  int timeDelta, k;
  int timeOffs = timeOffset;
  int frameEndFlag, nodeTimeTmp, nodeResFlag;

  if (fullFrame == 0) {
    frameEndFlag = FDKreadBits(hBs, 1);
  } else {
    frameEndFlag = 1;
  }

  if (frameEndFlag ==
      1) { /* frameEndFlag == 1 signals that the last node is at the end of the
              DRC frame */
    nodeResFlag = 0;
    for (k = 0; k < nNodes - 1; k++) {
      /* decode a delta time value */
      timeDelta = _decodeTimeDelta(hBs, Z);
      if (k >= (16 - 1)) continue;
      /* frameEndFlag == 1 needs special handling for last node with node
       * reservoir */
      nodeTimeTmp = timeOffs + timeDelta * deltaTmin;
      if (nodeTimeTmp > frameSize + timeOffset) {
        if (nodeResFlag == 0) {
          pNodes[k].time = frameSize + timeOffset;
          nodeResFlag = 1;
        }
        pNodes[k + 1].time = nodeTimeTmp;
      } else {
        pNodes[k].time = nodeTimeTmp;
      }
      timeOffs = nodeTimeTmp;
    }
    if (nodeResFlag == 0) {
      k = fMin(k, 16 - 1);
      pNodes[k].time = frameSize + timeOffset;
    }
  } else {
    for (k = 0; k < nNodes; k++) {
      /* decode a delta time value */
      timeDelta = _decodeTimeDelta(hBs, Z);
      if (k >= 16) continue;
      pNodes[k].time = timeOffs + timeDelta * deltaTmin;
      timeOffs = pNodes[k].time;
    }
  }
}

static void _readNodes(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
                       const int frameSize, const int timeDeltaMin,
                       UCHAR* pNNodes, GAIN_NODE* pNodes) {
  int timeOffset, drcGainCodingMode, nNodes;
  int Z = _getZ(frameSize / timeDeltaMin);
  if (gainSet->timeAlignment == 0) {
    timeOffset = -1;
  } else {
    timeOffset = -timeDeltaMin +
                 (timeDeltaMin - 1) /
                     2; /* timeOffset = - deltaTmin + floor((deltaTmin-1)/2); */
  }

  drcGainCodingMode = FDKreadBits(hBs, 1);
  if (drcGainCodingMode == 0) {
    /* "simple" mode: only one node at the end of the frame with slope = 0 */
    nNodes = 1;
    pNodes[0].gainDb = _decodeGainInitial(
        hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile);
    pNodes[0].time = frameSize + timeOffset;
  } else {
    nNodes = _decodeNNodes(hBs);

    _decodeSlopes(hBs, (GAIN_INTERPOLATION_TYPE)gainSet->gainInterpolationType,
                  nNodes, pNodes);

    _decodeTimes(hBs, timeDeltaMin, frameSize, gainSet->fullFrame, timeOffset,
                 Z, nNodes, pNodes);

    _decodeGains(hBs, (GAIN_CODING_PROFILE)gainSet->gainCodingProfile, nNodes,
                 pNodes);
  }
  *pNNodes = (UCHAR)nNodes;
}

static void _readDrcGainSequence(HANDLE_FDK_BITSTREAM hBs, GAIN_SET* gainSet,
                                 const int frameSize, const int timeDeltaMin,
                                 UCHAR* pNNodes, GAIN_NODE pNodes[16]) {
  SHORT timeBufPrevFrame[16], timeBufCurFrame[16];
  int nNodesNodeRes, nNodesCur, k, m;

  if (gainSet->gainCodingProfile == GCP_CONSTANT) {
    *pNNodes = 1;
    pNodes[0].time = frameSize - 1;
    pNodes[0].gainDb = (FIXP_SGL)0;
  } else {
    _readNodes(hBs, gainSet, frameSize, timeDeltaMin, pNNodes, pNodes);

    /* count number of nodes in node reservoir */
    nNodesNodeRes = 0;
    nNodesCur = 0;
    /* count and buffer nodes from node reservoir */
    for (k = 0; k < *pNNodes; k++) {
      if (k >= 16) continue;
      if (pNodes[k].time >= frameSize) {
        /* write node reservoir times into buffer */
        timeBufPrevFrame[nNodesNodeRes] = pNodes[k].time;
        nNodesNodeRes++;
      } else { /* times from current frame */
        timeBufCurFrame[nNodesCur] = pNodes[k].time;
        nNodesCur++;
      }
    }
    /* compose right time order (bit reservoir first) */
    for (k = 0; k < nNodesNodeRes; k++) {
      /* subtract two time frameSize: one to remove node reservoir offset and
       * one to get the negative index relative to the current frame
       */
      pNodes[k].time = timeBufPrevFrame[k] - 2 * frameSize;
    }
    /* ...and times from current frame */
    for (m = 0; m < nNodesCur; m++, k++) {
      pNodes[k].time = timeBufCurFrame[m];
    }
  }
}

static DRC_ERROR _readUniDrcGainExtension(HANDLE_FDK_BITSTREAM hBs,
                                          UNI_DRC_GAIN_EXTENSION* pExt) {
  DRC_ERROR err = DE_OK;
  int k, bitSizeLen, extSizeBits, bitSize;

  k = 0;
  pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
  while (pExt->uniDrcGainExtType[k] != UNIDRCGAINEXT_TERM) {
    if (k >= (8 - 1)) return DE_MEMORY_ERROR;
    bitSizeLen = FDKreadBits(hBs, 3);
    extSizeBits = bitSizeLen + 4;

    bitSize = FDKreadBits(hBs, extSizeBits);
    pExt->extBitSize[k] = bitSize + 1;

    switch (pExt->uniDrcGainExtType[k]) {
      /* add future extensions here */
      default:
        FDKpushFor(hBs, pExt->extBitSize[k]);
        break;
    }
    k++;
    pExt->uniDrcGainExtType[k] = FDKreadBits(hBs, 4);
  }

  return err;
}

DRC_ERROR
drcDec_readUniDrcGain(HANDLE_FDK_BITSTREAM hBs,
                      HANDLE_UNI_DRC_CONFIG hUniDrcConfig, const int frameSize,
                      const int deltaTminDefault,
                      HANDLE_UNI_DRC_GAIN hUniDrcGain) {
  DRC_ERROR err = DE_OK;
  int seq, gainSequenceCount;
  DRC_COEFFICIENTS_UNI_DRC* pCoef =
      selectDrcCoefficients(hUniDrcConfig, LOCATION_SELECTED);
  if (pCoef == NULL) return DE_OK;
  if (hUniDrcGain == NULL) return DE_OK; /* hUniDrcGain not initialized yet */

  gainSequenceCount = fMin(pCoef->gainSequenceCount, (UCHAR)12);

  for (seq = 0; seq < gainSequenceCount; seq++) {
    UCHAR index = pCoef->gainSetIndexForGainSequence[seq];
    GAIN_SET* gainSet;
    int timeDeltaMin;
    UCHAR tmpNNodes = 0;
    GAIN_NODE tmpNodes[16];

    if ((index >= pCoef->gainSetCount) || (index >= 12)) return DE_NOT_OK;
    gainSet = &(pCoef->gainSet[index]);

    timeDeltaMin = _getTimeDeltaMin(gainSet, deltaTminDefault);

    _readDrcGainSequence(hBs, gainSet, frameSize, timeDeltaMin, &tmpNNodes,
                         tmpNodes);

    hUniDrcGain->nNodes[seq] = tmpNNodes;
    FDKmemcpy(hUniDrcGain->gainNode[seq], tmpNodes,
              fMin(tmpNNodes, (UCHAR)16) * sizeof(GAIN_NODE));
  }

  hUniDrcGain->uniDrcGainExtPresent = FDKreadBits(hBs, 1);
  if (hUniDrcGain->uniDrcGainExtPresent == 1) {
    err = _readUniDrcGainExtension(hBs, &(hUniDrcGain->uniDrcGainExtension));
    if (err) return err;
  }

  return err;
}

/****************/
/* uniDrcConfig */
/****************/

static void _decodeDuckingModification(HANDLE_FDK_BITSTREAM hBs,
                                       DUCKING_MODIFICATION* pDMod, int isBox) {
  int bsDuckingScaling, sigma, mu;

  if (isBox) FDKpushFor(hBs, 7); /* reserved */
  pDMod->duckingScalingPresent = FDKreadBits(hBs, 1);

  if (pDMod->duckingScalingPresent) {
    if (isBox) FDKpushFor(hBs, 4); /* reserved */
    bsDuckingScaling = FDKreadBits(hBs, 4);
    sigma = bsDuckingScaling >> 3;
    mu = bsDuckingScaling & 0x7;

    if (sigma) {
      pDMod->duckingScaling = (FIXP_SGL)(
          (7 - mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 - 0.125 * (1 + mu); */
    } else {
      pDMod->duckingScaling = (FIXP_SGL)(
          (9 + mu) << (FRACT_BITS - 1 - 3 - 2)); /* 1.0 + 0.125 * (1 + mu); */
    }
  } else {
    pDMod->duckingScaling = (FIXP_SGL)(1 << (FRACT_BITS - 1 - 2)); /* 1.0 */
  }
}

static void _decodeGainModification(HANDLE_FDK_BITSTREAM hBs, const int version,
                                    int bandCount, GAIN_MODIFICATION* pGMod,
                                    int isBox) {
  int sign, bsGainOffset, bsAttenuationScaling, bsAmplificationScaling;

  if (version > 0) {
    int b, shapeFilterPresent;

    if (isBox) {
      FDKpushFor(hBs, 4); /* reserved */
      bandCount = FDKreadBits(hBs, 4);
    }

    for (b = 0; b < bandCount; b++) {
      if (isBox) {
        FDKpushFor(hBs, 4); /* reserved */
        pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
        pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
        pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
        pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
      }

      if (!isBox)
        pGMod[b].targetCharacteristicLeftPresent = FDKreadBits(hBs, 1);
      if (pGMod[b].targetCharacteristicLeftPresent) {
        if (isBox) FDKpushFor(hBs, 4); /* reserved */
        pGMod[b].targetCharacteristicLeftIndex = FDKreadBits(hBs, 4);
      }
      if (!isBox)
        pGMod[b].targetCharacteristicRightPresent = FDKreadBits(hBs, 1);
      if (pGMod[b].targetCharacteristicRightPresent) {
        if (isBox) FDKpushFor(hBs, 4); /* reserved */
        pGMod[b].targetCharacteristicRightIndex = FDKreadBits(hBs, 4);
      }
      if (!isBox) pGMod[b].gainScalingPresent = FDKreadBits(hBs, 1);
      if (pGMod[b].gainScalingPresent) {
        bsAttenuationScaling = FDKreadBits(hBs, 4);
        pGMod[b].attenuationScaling = (FIXP_SGL)(
            bsAttenuationScaling
            << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
        bsAmplificationScaling = FDKreadBits(hBs, 4);
        pGMod[b].amplificationScaling = (FIXP_SGL)(
            bsAmplificationScaling
            << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
      }
      if (!isBox) pGMod[b].gainOffsetPresent = FDKreadBits(hBs, 1);
      if (pGMod[b].gainOffsetPresent) {
        if (isBox) FDKpushFor(hBs, 2); /* reserved */
        sign = FDKreadBits(hBs, 1);
        bsGainOffset = FDKreadBits(hBs, 5);
        pGMod[b].gainOffset = (FIXP_SGL)(
            (1 + bsGainOffset)
            << (FRACT_BITS - 1 - 2 - 4)); /* (1+bsGainOffset) * 0.25; */
        if (sign) {
          pGMod[b].gainOffset = -pGMod[b].gainOffset;
        }
      }
    }
    if (bandCount == 1) {
      shapeFilterPresent = FDKreadBits(hBs, 1);
      if (shapeFilterPresent) {
        if (isBox) FDKpushFor(hBs, 3); /* reserved */
        FDKpushFor(hBs, 4);            /* pGMod->shapeFilterIndex */
      } else {
        if (isBox) FDKpushFor(hBs, 7); /* reserved */
      }
    }
  } else {
    int b, gainScalingPresent, gainOffsetPresent;
    FIXP_SGL attenuationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
             amplificationScaling = FL2FXCONST_SGL(1.0f / (float)(1 << 2)),
             gainOffset = (FIXP_SGL)0;
    if (isBox) FDKpushFor(hBs, 7); /* reserved */
    gainScalingPresent = FDKreadBits(hBs, 1);
    if (gainScalingPresent) {
      bsAttenuationScaling = FDKreadBits(hBs, 4);
      attenuationScaling = (FIXP_SGL)(
          bsAttenuationScaling
          << (FRACT_BITS - 1 - 3 - 2)); /* bsAttenuationScaling * 0.125; */
      bsAmplificationScaling = FDKreadBits(hBs, 4);
      amplificationScaling = (FIXP_SGL)(
          bsAmplificationScaling
          << (FRACT_BITS - 1 - 3 - 2)); /* bsAmplificationScaling * 0.125; */
    }
    if (isBox) FDKpushFor(hBs, 7); /* reserved */
    gainOffsetPresent = FDKreadBits(hBs, 1);
    if (gainOffsetPresent) {
      if (isBox) FDKpushFor(hBs, 2); /* reserved */
      sign = FDKreadBits(hBs, 1);
      bsGainOffset = FDKreadBits(hBs, 5);
      gainOffset =
          (FIXP_SGL)((1 + bsGainOffset) << (FRACT_BITS - 1 - 2 -
                                            4)); /* (1+bsGainOffset) * 0.25; */
      if (sign) {
        gainOffset = -gainOffset;
      }
    }
    for (b = 0; b < 4; b++) {
      pGMod[b].targetCharacteristicLeftPresent = 0;
      pGMod[b].targetCharacteristicRightPresent = 0;
      pGMod[b].gainScalingPresent = gainScalingPresent;
      pGMod[b].attenuationScaling = attenuationScaling;
      pGMod[b].amplificationScaling = amplificationScaling;
      pGMod[b].gainOffsetPresent = gainOffsetPresent;
      pGMod[b].gainOffset = gainOffset;
    }
  }
}

static void _readDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs, const int version,
                                   DRC_CHARACTERISTIC* pDChar, int isBox) {
  if (version == 0) {
    if (isBox) FDKpushFor(hBs, 1); /* reserved */
    pDChar->cicpIndex = FDKreadBits(hBs, 7);
    if (pDChar->cicpIndex > 0) {
      pDChar->present = 1;
      pDChar->isCICP = 1;
    } else {
      pDChar->present = 0;
    }
  } else {
    pDChar->present = FDKreadBits(hBs, 1);
    if (isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
    if (pDChar->present) {
      if (!isBox) pDChar->isCICP = FDKreadBits(hBs, 1);
      if (pDChar->isCICP) {
        if (isBox) FDKpushFor(hBs, 1); /* reserved */
        pDChar->cicpIndex = FDKreadBits(hBs, 7);
      } else {
        pDChar->custom.left = FDKreadBits(hBs, 4);
        pDChar->custom.right = FDKreadBits(hBs, 4);
      }
    }
  }
}

static void _readBandBorder(HANDLE_FDK_BITSTREAM hBs, BAND_BORDER* pBBord,
                            int drcBandType, int isBox) {
  if (drcBandType) {
    if (isBox) FDKpushFor(hBs, 4); /* reserved */
    pBBord->crossoverFreqIndex = FDKreadBits(hBs, 4);
  } else {
    if (isBox) FDKpushFor(hBs, 6); /* reserved */
    pBBord->startSubBandIndex = FDKreadBits(hBs, 10);
  }
}

static DRC_ERROR _readGainSet(HANDLE_FDK_BITSTREAM hBs, const int version,
                              int* gainSequenceIndex, GAIN_SET* pGSet,
                              int isBox) {
  if (isBox) FDKpushFor(hBs, 2); /* reserved */
  pGSet->gainCodingProfile = FDKreadBits(hBs, 2);
  pGSet->gainInterpolationType = FDKreadBits(hBs, 1);
  pGSet->fullFrame = FDKreadBits(hBs, 1);
  pGSet->timeAlignment = FDKreadBits(hBs, 1);
  pGSet->timeDeltaMinPresent = FDKreadBits(hBs, 1);

  if (pGSet->timeDeltaMinPresent) {
    int bsTimeDeltaMin;
    if (isBox) FDKpushFor(hBs, 5); /* reserved */
    bsTimeDeltaMin = FDKreadBits(hBs, 11);
    pGSet->timeDeltaMin = bsTimeDeltaMin + 1;
  }

  if (pGSet->gainCodingProfile != GCP_CONSTANT) {
    int i;
    if (isBox) FDKpushFor(hBs, 3); /* reserved */
    pGSet->bandCount = FDKreadBits(hBs, 4);
    if (pGSet->bandCount > 4) return DE_MEMORY_ERROR;

    if ((pGSet->bandCount > 1) || isBox) {
      pGSet->drcBandType = FDKreadBits(hBs, 1);
    }

    for (i = 0; i < pGSet->bandCount; i++) {
      if (version == 0) {
        *gainSequenceIndex = (*gainSequenceIndex) + 1;
      } else {
        int indexPresent;
        indexPresent = (isBox) ? 1 : FDKreadBits(hBs, 1);
        if (indexPresent) {
          int bsIndex;
          bsIndex = FDKreadBits(hBs, 6);
          *gainSequenceIndex = bsIndex;
        } else {
          *gainSequenceIndex = (*gainSequenceIndex) + 1;
        }
      }
      pGSet->gainSequenceIndex[i] = *gainSequenceIndex;
      _readDrcCharacteristic(hBs, version, &(pGSet->drcCharacteristic[i]),
                             isBox);
    }
    for (i = 1; i < pGSet->bandCount; i++) {
      _readBandBorder(hBs, &(pGSet->bandBorder[i]), pGSet->drcBandType, isBox);
    }
  } else {
    pGSet->bandCount = 1;
    *gainSequenceIndex = (*gainSequenceIndex) + 1;
    pGSet->gainSequenceIndex[0] = *gainSequenceIndex;
  }

  return DE_OK;
}

static DRC_ERROR _readCustomDrcCharacteristic(HANDLE_FDK_BITSTREAM hBs,
                                              const CHARACTERISTIC_SIDE side,
                                              UCHAR* pCharacteristicFormat,
                                              CUSTOM_DRC_CHAR* pCChar,
                                              int isBox) {
  if (isBox) FDKpushFor(hBs, 7); /* reserved */
  *pCharacteristicFormat = FDKreadBits(hBs, 1);
  if (*pCharacteristicFormat == CF_SIGMOID) {
    int bsGain, bsIoRatio, bsExp;
    if (isBox) FDKpushFor(hBs, 1); /* reserved */
    bsGain = FDKreadBits(hBs, 6);
    if (side == CS_LEFT) {
      pCChar->sigmoid.gain = (FIXP_SGL)(bsGain << (FRACT_BITS - 1 - 6));
    } else {
      pCChar->sigmoid.gain = (FIXP_SGL)(-bsGain << (FRACT_BITS - 1 - 6));
    }
    bsIoRatio = FDKreadBits(hBs, 4);
    /* pCChar->sigmoid.ioRatio = 0.05 + 0.15 * bsIoRatio; */
    pCChar->sigmoid.ioRatio =
        FL2FXCONST_SGL(0.05f / (float)(1 << 2)) +
        (FIXP_SGL)((((3 * bsIoRatio) << (FRACT_BITS - 1)) / 5) >> 4);
    bsExp = FDKreadBits(hBs, 4);
    if (bsExp < 15) {
      pCChar->sigmoid.exp = (FIXP_SGL)((1 + 2 * bsExp) << (FRACT_BITS - 1 - 5));
    } else {
      pCChar->sigmoid.exp = (FIXP_SGL)MAXVAL_SGL; /* represents infinity */
    }
    pCChar->sigmoid.flipSign = FDKreadBits(hBs, 1);
  } else { /* CF_NODES */
    int i, bsCharacteristicNodeCount, bsNodeLevelDelta, bsNodeGain;
    if (isBox) FDKpushFor(hBs, 6); /* reserved */
    bsCharacteristicNodeCount = FDKreadBits(hBs, 2);
    pCChar->nodes.characteristicNodeCount = bsCharacteristicNodeCount + 1;
    if (pCChar->nodes.characteristicNodeCount > 4) return DE_MEMORY_ERROR;
    pCChar->nodes.nodeLevel[0] = DRC_INPUT_LOUDNESS_TARGET_SGL;
    pCChar->nodes.nodeGain[0] = (FIXP_SGL)0;
    for (i = 0; i < pCChar->nodes.characteristicNodeCount; i++) {
      if (isBox) FDKpushFor(hBs, 3); /* reserved */
      bsNodeLevelDelta = FDKreadBits(hBs, 5);
      if (side == CS_LEFT) {
        pCChar->nodes.nodeLevel[i + 1] =
            pCChar->nodes.nodeLevel[i] -
            (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
      } else {
        pCChar->nodes.nodeLevel[i + 1] =
            pCChar->nodes.nodeLevel[i] +
            (FIXP_SGL)((1 + bsNodeLevelDelta) << (FRACT_BITS - 1 - 7));
      }
      bsNodeGain = FDKreadBits(hBs, 8);
      pCChar->nodes.nodeGain[i + 1] = (FIXP_SGL)(
          (bsNodeGain - 128)
          << (FRACT_BITS - 1 - 1 - 7)); /* 0.5f * bsNodeGain - 64.0f; */
    }
  }
  return DE_OK;
}

static void _skipLoudEqInstructions(HANDLE_FDK_BITSTREAM hBs) {
  int i;
  int downmixIdPresent, additionalDownmixIdPresent,
      additionalDownmixIdCount = 0;
  int drcSetIdPresent, additionalDrcSetIdPresent, additionalDrcSetIdCount = 0;
  int eqSetIdPresent, additionalEqSetIdPresent, additionalEqSetIdCount = 0;
  int loudEqGainSequenceCount, drcCharacteristicFormatIsCICP;

  FDKpushFor(hBs, 4); /* loudEqSetId */
  FDKpushFor(hBs, 4); /* drcLocation */
  downmixIdPresent = FDKreadBits(hBs, 1);
  if (downmixIdPresent) {
    FDKpushFor(hBs, 7); /* downmixId */
    additionalDownmixIdPresent = FDKreadBits(hBs, 1);
    if (additionalDownmixIdPresent) {
      additionalDownmixIdCount = FDKreadBits(hBs, 7);
      for (i = 0; i < additionalDownmixIdCount; i++) {
        FDKpushFor(hBs, 7); /* additionalDownmixId */
      }
    }
  }

  drcSetIdPresent = FDKreadBits(hBs, 1);
  if (drcSetIdPresent) {
    FDKpushFor(hBs, 6); /* drcSetId */
    additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
    if (additionalDrcSetIdPresent) {
      additionalDrcSetIdCount = FDKreadBits(hBs, 6);
      for (i = 0; i < additionalDrcSetIdCount; i++) {
        FDKpushFor(hBs, 6); /* additionalDrcSetId; */
      }
    }
  }

  eqSetIdPresent = FDKreadBits(hBs, 1);
  if (eqSetIdPresent) {
    FDKpushFor(hBs, 6); /* eqSetId */
    additionalEqSetIdPresent = FDKreadBits(hBs, 1);
    if (additionalEqSetIdPresent) {
      additionalEqSetIdCount = FDKreadBits(hBs, 6);
      for (i = 0; i < additionalEqSetIdCount; i++) {
        FDKpushFor(hBs, 6); /* additionalEqSetId; */
      }
    }
  }

  FDKpushFor(hBs, 1); /* loudnessAfterDrc */
  FDKpushFor(hBs, 1); /* loudnessAfterEq */
  loudEqGainSequenceCount = FDKreadBits(hBs, 6);
  for (i = 0; i < loudEqGainSequenceCount; i++) {
    FDKpushFor(hBs, 6); /* gainSequenceIndex */
    drcCharacteristicFormatIsCICP = FDKreadBits(hBs, 1);
    if (drcCharacteristicFormatIsCICP) {
      FDKpushFor(hBs, 7); /* drcCharacteristic */
    } else {
      FDKpushFor(hBs, 4); /* drcCharacteristicLeftIndex */
      FDKpushFor(hBs, 4); /* drcCharacteristicRightIndex */
    }
    FDKpushFor(hBs, 6); /* frequencyRangeIndex */
    FDKpushFor(hBs, 3); /* bsLoudEqScaling */
    FDKpushFor(hBs, 5); /* bsLoudEqOffset */
  }
}

static void _skipEqSubbandGainSpline(HANDLE_FDK_BITSTREAM hBs) {
  int nEqNodes, k, bits;
  nEqNodes = FDKreadBits(hBs, 5);
  nEqNodes += 2;
  for (k = 0; k < nEqNodes; k++) {
    bits = FDKreadBits(hBs, 1);
    if (!bits) {
      FDKpushFor(hBs, 4);
    }
  }
  FDKpushFor(hBs, 4 * (nEqNodes - 1));
  bits = FDKreadBits(hBs, 2);
  switch (bits) {
    case 0:
      FDKpushFor(hBs, 5);
      break;
    case 1:
    case 2:
      FDKpushFor(hBs, 4);
      break;
    case 3:
      FDKpushFor(hBs, 3);
      break;
  }
  FDKpushFor(hBs, 5 * (nEqNodes - 1));
}

static void _skipEqCoefficients(HANDLE_FDK_BITSTREAM hBs) {
  int j, k;
  int eqDelayMaxPresent;
  int uniqueFilterBlockCount, filterElementCount, filterElementGainPresent;
  int uniqueTdFilterElementCount, eqFilterFormat, bsRealZeroRadiusOneCount,
      realZeroCount, genericZeroCount, realPoleCount, complexPoleCount,
      firFilterOrder;
  int uniqueEqSubbandGainsCount, eqSubbandGainRepresentation,
      eqSubbandGainCount;
  EQ_SUBBAND_GAIN_FORMAT eqSubbandGainFormat;

  eqDelayMaxPresent = FDKreadBits(hBs, 1);
  if (eqDelayMaxPresent) {
    FDKpushFor(hBs, 8); /* bsEqDelayMax */
  }

  uniqueFilterBlockCount = FDKreadBits(hBs, 6);
  for (j = 0; j < uniqueFilterBlockCount; j++) {
    filterElementCount = FDKreadBits(hBs, 6);
    for (k = 0; k < filterElementCount; k++) {
      FDKpushFor(hBs, 6); /* filterElementIndex */
      filterElementGainPresent = FDKreadBits(hBs, 1);
      if (filterElementGainPresent) {
        FDKpushFor(hBs, 10); /* bsFilterElementGain */
      }
    }
  }
  uniqueTdFilterElementCount = FDKreadBits(hBs, 6);
  for (j = 0; j < uniqueTdFilterElementCount; j++) {
    eqFilterFormat = FDKreadBits(hBs, 1);
    if (eqFilterFormat == 0) { /* pole/zero */
      bsRealZeroRadiusOneCount = FDKreadBits(hBs, 3);
      realZeroCount = FDKreadBits(hBs, 6);
      genericZeroCount = FDKreadBits(hBs, 6);
      realPoleCount = FDKreadBits(hBs, 4);
      complexPoleCount = FDKreadBits(hBs, 4);
      FDKpushFor(hBs, 2 * bsRealZeroRadiusOneCount * 1);
      FDKpushFor(hBs, realZeroCount * 8);
      FDKpushFor(hBs, genericZeroCount * 14);
      FDKpushFor(hBs, realPoleCount * 8);
      FDKpushFor(hBs, complexPoleCount * 14);
    } else { /* FIR coefficients */
      firFilterOrder = FDKreadBits(hBs, 7);
      FDKpushFor(hBs, 1);
      FDKpushFor(hBs, (firFilterOrder / 2 + 1) * 11);
    }
  }
  uniqueEqSubbandGainsCount = FDKreadBits(hBs, 6);
  if (uniqueEqSubbandGainsCount > 0) {
    eqSubbandGainRepresentation = FDKreadBits(hBs, 1);
    eqSubbandGainFormat = (EQ_SUBBAND_GAIN_FORMAT)FDKreadBits(hBs, 4);
    switch (eqSubbandGainFormat) {
      case GF_QMF32:
        eqSubbandGainCount = 32;
        break;
      case GF_QMFHYBRID39:
        eqSubbandGainCount = 39;
        break;
      case GF_QMF64:
        eqSubbandGainCount = 64;
        break;
      case GF_QMFHYBRID71:
        eqSubbandGainCount = 71;
        break;
      case GF_QMF128:
        eqSubbandGainCount = 128;
        break;
      case GF_QMFHYBRID135:
        eqSubbandGainCount = 135;
        break;
      case GF_UNIFORM:
      default:
        eqSubbandGainCount = FDKreadBits(hBs, 8);
        eqSubbandGainCount++;
        break;
    }
    for (k = 0; k < uniqueEqSubbandGainsCount; k++) {
      if (eqSubbandGainRepresentation == 1) {
        _skipEqSubbandGainSpline(hBs);
      } else {
        FDKpushFor(hBs, eqSubbandGainCount * 9);
      }
    }
  }
}

static void _skipTdFilterCascade(HANDLE_FDK_BITSTREAM hBs,
                                 const int eqChannelGroupCount) {
  int i, eqCascadeGainPresent, filterBlockCount, eqPhaseAlignmentPresent;
  for (i = 0; i < eqChannelGroupCount; i++) {
    eqCascadeGainPresent = FDKreadBits(hBs, 1);
    if (eqCascadeGainPresent) {
      FDKpushFor(hBs, 10); /* bsEqCascadeGain */
    }
    filterBlockCount = FDKreadBits(hBs, 4);
    FDKpushFor(hBs, filterBlockCount * 7); /* filterBlockIndex */
  }
  eqPhaseAlignmentPresent = FDKreadBits(hBs, 1);
  {
    if (eqPhaseAlignmentPresent) {
      for (i = 0; i < eqChannelGroupCount; i++) {
        FDKpushFor(hBs, (eqChannelGroupCount - i - 1) * 1);
      }
    }
  }
}

static DRC_ERROR _skipEqInstructions(HANDLE_FDK_BITSTREAM hBs,
                                     HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  DRC_ERROR err = DE_OK;
  int c, i, k, channelCount;
  int downmixIdPresent, downmixId, eqApplyToDownmix, additionalDownmixIdPresent,
      additionalDownmixIdCount = 0;
  int additionalDrcSetIdPresent, additionalDrcSetIdCount;
  int dependsOnEqSetPresent, eqChannelGroupCount, tdFilterCascadePresent,
      subbandGainsPresent, eqTransitionDurationPresent;

  FDKpushFor(hBs, 6); /* eqSetId */
  FDKpushFor(hBs, 4); /* eqSetComplexityLevel */
  downmixIdPresent = FDKreadBits(hBs, 1);
  if (downmixIdPresent) {
    downmixId = FDKreadBits(hBs, 7);
    eqApplyToDownmix = FDKreadBits(hBs, 1);
    additionalDownmixIdPresent = FDKreadBits(hBs, 1);
    if (additionalDownmixIdPresent) {
      additionalDownmixIdCount = FDKreadBits(hBs, 7);
      FDKpushFor(hBs, additionalDownmixIdCount * 7); /* additionalDownmixId */
    }
  } else {
    downmixId = 0;
    eqApplyToDownmix = 0;
  }
  FDKpushFor(hBs, 6); /* drcSetId */
  additionalDrcSetIdPresent = FDKreadBits(hBs, 1);
  if (additionalDrcSetIdPresent) {
    additionalDrcSetIdCount = FDKreadBits(hBs, 6);
    for (i = 0; i < additionalDrcSetIdCount; i++) {
      FDKpushFor(hBs, 6); /* additionalDrcSetId */
    }
  }
  FDKpushFor(hBs, 16); /* eqSetPurpose */
  dependsOnEqSetPresent = FDKreadBits(hBs, 1);
  if (dependsOnEqSetPresent) {
    FDKpushFor(hBs, 6); /* dependsOnEqSet */
  } else {
    FDKpushFor(hBs, 1); /* noIndependentEqUse */
  }

  channelCount = hUniDrcConfig->channelLayout.baseChannelCount;
  if ((downmixIdPresent == 1) && (eqApplyToDownmix == 1) && (downmixId != 0) &&
      (downmixId != DOWNMIX_ID_ANY_DOWNMIX) &&
      (additionalDownmixIdCount == 0)) {
    DOWNMIX_INSTRUCTIONS* pDown =
        selectDownmixInstructions(hUniDrcConfig, downmixId);
    if (pDown == NULL) return DE_NOT_OK;

    channelCount =
        pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
  } else if ((downmixId == DOWNMIX_ID_ANY_DOWNMIX) ||
             (additionalDownmixIdCount > 1)) {
    channelCount = 1;
  }

  eqChannelGroupCount = 0;
  for (c = 0; c < channelCount; c++) {
    UCHAR eqChannelGroupForChannel[8];
    int newGroup = 1;
    if (c >= 8) return DE_MEMORY_ERROR;
    eqChannelGroupForChannel[c] = FDKreadBits(hBs, 7);
    for (k = 0; k < c; k++) {
      if (eqChannelGroupForChannel[c] == eqChannelGroupForChannel[k]) {
        newGroup = 0;
      }
    }
    if (newGroup == 1) {
      eqChannelGroupCount += 1;
    }
  }
  tdFilterCascadePresent = FDKreadBits(hBs, 1);
  if (tdFilterCascadePresent) {
    _skipTdFilterCascade(hBs, eqChannelGroupCount);
  }
  subbandGainsPresent = FDKreadBits(hBs, 1);
  if (subbandGainsPresent) {
    FDKpushFor(hBs, eqChannelGroupCount * 6); /* subbandGainsIndex */
  }
  eqTransitionDurationPresent = FDKreadBits(hBs, 1);
  if (eqTransitionDurationPresent) {
    FDKpushFor(hBs, 5); /* bsEqTransitionDuration */
  }
  return err;
}

static void _skipDrcCoefficientsBasic(HANDLE_FDK_BITSTREAM hBs) {
  FDKpushFor(hBs, 4); /* drcLocation */
  FDKpushFor(hBs, 7); /* drcCharacteristic */
}

static DRC_ERROR _readDrcCoefficientsUniDrc(HANDLE_FDK_BITSTREAM hBs,
                                            const int version,
                                            DRC_COEFFICIENTS_UNI_DRC* pCoef) {
  DRC_ERROR err = DE_OK;
  int i, bsDrcFrameSize;
  int gainSequenceIndex = -1;

  pCoef->drcLocation = FDKreadBits(hBs, 4);
  pCoef->drcFrameSizePresent = FDKreadBits(hBs, 1);

  if (pCoef->drcFrameSizePresent == 1) {
    bsDrcFrameSize = FDKreadBits(hBs, 15);
    pCoef->drcFrameSize = bsDrcFrameSize + 1;
  }
  if (version == 0) {
    int gainSequenceCount = 0, gainSetCount;
    pCoef->characteristicLeftCount = 0;
    pCoef->characteristicRightCount = 0;
    gainSetCount = FDKreadBits(hBs, 6);
    pCoef->gainSetCount = fMin(gainSetCount, 12);
    for (i = 0; i < gainSetCount; i++) {
      GAIN_SET tmpGset;
      FDKmemclear(&tmpGset, sizeof(GAIN_SET));
      err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
      if (err) return err;
      gainSequenceCount += tmpGset.bandCount;

      if (i >= 12) continue;
      pCoef->gainSet[i] = tmpGset;
    }
    pCoef->gainSequenceCount = gainSequenceCount;
  } else { /* (version == 1) */
    UCHAR drcCharacteristicLeftPresent, drcCharacteristicRightPresent;
    UCHAR shapeFiltersPresent, shapeFilterCount, tmpPresent;
    int gainSetCount;
    drcCharacteristicLeftPresent = FDKreadBits(hBs, 1);
    if (drcCharacteristicLeftPresent) {
      pCoef->characteristicLeftCount = FDKreadBits(hBs, 4);
      if ((pCoef->characteristicLeftCount + 1) > 8) return DE_MEMORY_ERROR;
      for (i = 0; i < pCoef->characteristicLeftCount; i++) {
        err = _readCustomDrcCharacteristic(
            hBs, CS_LEFT, &(pCoef->characteristicLeftFormat[i + 1]),
            &(pCoef->customCharacteristicLeft[i + 1]), 0);
        if (err) return err;
      }
    }
    drcCharacteristicRightPresent = FDKreadBits(hBs, 1);
    if (drcCharacteristicRightPresent) {
      pCoef->characteristicRightCount = FDKreadBits(hBs, 4);
      if ((pCoef->characteristicRightCount + 1) > 8) return DE_MEMORY_ERROR;
      for (i = 0; i < pCoef->characteristicRightCount; i++) {
        err = _readCustomDrcCharacteristic(
            hBs, CS_RIGHT, &(pCoef->characteristicRightFormat[i + 1]),
            &(pCoef->customCharacteristicRight[i + 1]), 0);
        if (err) return err;
      }
    }
    shapeFiltersPresent = FDKreadBits(hBs, 1);
    if (shapeFiltersPresent) {
      shapeFilterCount = FDKreadBits(hBs, 4);
      for (i = 0; i < shapeFilterCount; i++) {
        tmpPresent = FDKreadBits(hBs, 1);
        if (tmpPresent) /* lfCutParams */
          FDKpushFor(hBs, 5);

        tmpPresent = FDKreadBits(hBs, 1);
        if (tmpPresent) /* lfBoostParams */
          FDKpushFor(hBs, 5);

        tmpPresent = FDKreadBits(hBs, 1);
        if (tmpPresent) /* hfCutParams */
          FDKpushFor(hBs, 5);

        tmpPresent = FDKreadBits(hBs, 1);
        if (tmpPresent) /* hfBoostParams */
          FDKpushFor(hBs, 5);
      }
    }
    pCoef->gainSequenceCount = FDKreadBits(hBs, 6);
    gainSetCount = FDKreadBits(hBs, 6);
    pCoef->gainSetCount = fMin(gainSetCount, 12);
    for (i = 0; i < gainSetCount; i++) {
      GAIN_SET tmpGset;
      FDKmemclear(&tmpGset, sizeof(GAIN_SET));
      err = _readGainSet(hBs, version, &gainSequenceIndex, &tmpGset, 0);
      if (err) return err;

      if (i >= 12) continue;
      pCoef->gainSet[i] = tmpGset;
    }
  }
  for (i = 0; i < 12; i++) {
    pCoef->gainSetIndexForGainSequence[i] = 255;
  }
  for (i = 0; i < pCoef->gainSetCount; i++) {
    int b;
    for (b = 0; b < pCoef->gainSet[i].bandCount; b++) {
      if (pCoef->gainSet[i].gainSequenceIndex[b] >= 12) continue;
      pCoef->gainSetIndexForGainSequence[pCoef->gainSet[i]
                                             .gainSequenceIndex[b]] = i;
    }
  }

  return err;
}

static void _skipDrcInstructionsBasic(HANDLE_FDK_BITSTREAM hBs) {
  int drcSetEffect;
  int additionalDownmixIdPresent, additionalDownmixIdCount,
      limiterPeakTargetPresent;
  int drcSetTargetLoudnessPresent, drcSetTargetLoudnessValueLowerPresent;

  FDKpushFor(hBs, 6); /* drcSetId */
  FDKpushFor(hBs, 4); /* drcLocation */
  FDKpushFor(hBs, 7); /* downmixId */
  additionalDownmixIdPresent = FDKreadBits(hBs, 1);
  if (additionalDownmixIdPresent) {
    additionalDownmixIdCount = FDKreadBits(hBs, 3);
    FDKpushFor(hBs, 7 * additionalDownmixIdCount); /* additionalDownmixId */
  }

  drcSetEffect = FDKreadBits(hBs, 16);
  if (!(drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF))) {
    limiterPeakTargetPresent = FDKreadBits(hBs, 1);
    if (limiterPeakTargetPresent) {
      FDKpushFor(hBs, 8); /* bsLimiterPeakTarget */
    }
  }

  drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);
  if (drcSetTargetLoudnessPresent) {
    FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueUpper */
    drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
    if (drcSetTargetLoudnessValueLowerPresent) {
      FDKpushFor(hBs, 6); /* bsDrcSetTargetLoudnessValueLower */
    }
  }
}

static DRC_ERROR _readDrcInstructionsUniDrc(HANDLE_FDK_BITSTREAM hBs,
                                            const int version,
                                            HANDLE_UNI_DRC_CONFIG hUniDrcConfig,
                                            DRC_INSTRUCTIONS_UNI_DRC* pInst) {
  DRC_ERROR err = DE_OK;
  int i, g, c;
  int downmixIdPresent, additionalDownmixIdPresent, additionalDownmixIdCount;
  int bsLimiterPeakTarget, channelCount;
  DRC_COEFFICIENTS_UNI_DRC* pCoef = NULL;
  int repeatParameters, bsRepeatParametersCount;
  int repeatSequenceIndex, bsRepeatSequenceCount;
  SCHAR* gainSetIndex = pInst->gainSetIndex;
  SCHAR channelGroupForChannel[8];
  DUCKING_MODIFICATION duckingModificationForChannelGroup[8];

  pInst->drcSetId = FDKreadBits(hBs, 6);
  if (version == 0) {
    /* Assume all v0 DRC sets to be manageable in terms of complexity */
    pInst->drcSetComplexityLevel = 2;
  } else {
    pInst->drcSetComplexityLevel = FDKreadBits(hBs, 4);
  }
  pInst->drcLocation = FDKreadBits(hBs, 4);
  if (version == 0) {
    downmixIdPresent = 1;
  } else {
    downmixIdPresent = FDKreadBits(hBs, 1);
  }
  if (downmixIdPresent) {
    pInst->downmixId[0] = FDKreadBits(hBs, 7);
    if (version == 0) {
      if (pInst->downmixId[0] == 0)
        pInst->drcApplyToDownmix = 0;
      else
        pInst->drcApplyToDownmix = 1;
    } else {
      pInst->drcApplyToDownmix = FDKreadBits(hBs, 1);
    }

    additionalDownmixIdPresent = FDKreadBits(hBs, 1);
    if (additionalDownmixIdPresent) {
      additionalDownmixIdCount = FDKreadBits(hBs, 3);
      if ((1 + additionalDownmixIdCount) > 8) return DE_MEMORY_ERROR;
      for (i = 0; i < additionalDownmixIdCount; i++) {
        pInst->downmixId[i + 1] = FDKreadBits(hBs, 7);
      }
      pInst->downmixIdCount = 1 + additionalDownmixIdCount;
    } else {
      pInst->downmixIdCount = 1;
    }
  } else {
    pInst->downmixId[0] = 0;
    pInst->downmixIdCount = 1;
  }

  pInst->drcSetEffect = FDKreadBits(hBs, 16);

  if ((pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) == 0) {
    pInst->limiterPeakTargetPresent = FDKreadBits(hBs, 1);
    if (pInst->limiterPeakTargetPresent) {
      bsLimiterPeakTarget = FDKreadBits(hBs, 8);
      pInst->limiterPeakTarget = -(FIXP_SGL)(
          bsLimiterPeakTarget
          << (FRACT_BITS - 1 - 3 - 5)); /* - bsLimiterPeakTarget * 0.125; */
    }
  }

  pInst->drcSetTargetLoudnessPresent = FDKreadBits(hBs, 1);

  /* set default values */
  pInst->drcSetTargetLoudnessValueUpper = 0;
  pInst->drcSetTargetLoudnessValueLower = -63;

  if (pInst->drcSetTargetLoudnessPresent == 1) {
    int bsDrcSetTargetLoudnessValueUpper, bsDrcSetTargetLoudnessValueLower;
    int drcSetTargetLoudnessValueLowerPresent;
    bsDrcSetTargetLoudnessValueUpper = FDKreadBits(hBs, 6);
    pInst->drcSetTargetLoudnessValueUpper =
        bsDrcSetTargetLoudnessValueUpper - 63;
    drcSetTargetLoudnessValueLowerPresent = FDKreadBits(hBs, 1);
    if (drcSetTargetLoudnessValueLowerPresent == 1) {
      bsDrcSetTargetLoudnessValueLower = FDKreadBits(hBs, 6);
      pInst->drcSetTargetLoudnessValueLower =
          bsDrcSetTargetLoudnessValueLower - 63;
    }
  }

  pInst->dependsOnDrcSetPresent = FDKreadBits(hBs, 1);

  pInst->noIndependentUse = 0;
  if (pInst->dependsOnDrcSetPresent) {
    pInst->dependsOnDrcSet = FDKreadBits(hBs, 6);
  } else {
    pInst->noIndependentUse = FDKreadBits(hBs, 1);
  }

  if (version == 0) {
    pInst->requiresEq = 0;
  } else {
    pInst->requiresEq = FDKreadBits(hBs, 1);
  }

  pCoef = selectDrcCoefficients(hUniDrcConfig, pInst->drcLocation);

  pInst->drcChannelCount = channelCount =
      hUniDrcConfig->channelLayout.baseChannelCount;

  if (pInst->drcSetEffect & (EB_DUCK_OTHER | EB_DUCK_SELF)) {
    DUCKING_MODIFICATION* pDModForChannel =
        pInst->duckingModificationForChannel;
    c = 0;
    while (c < channelCount) {
      int bsGainSetIndex;
      bsGainSetIndex = FDKreadBits(hBs, 6);
      if (c >= 8) return DE_MEMORY_ERROR;
      gainSetIndex[c] = bsGainSetIndex - 1;
      _decodeDuckingModification(hBs, &(pDModForChannel[c]), 0);

      c++;
      repeatParameters = FDKreadBits(hBs, 1);
      if (repeatParameters == 1) {
        bsRepeatParametersCount = FDKreadBits(hBs, 5);
        bsRepeatParametersCount += 1;
        for (i = 0; i < bsRepeatParametersCount; i++) {
          if (c >= 8) return DE_MEMORY_ERROR;
          gainSetIndex[c] = gainSetIndex[c - 1];
          pDModForChannel[c] = pDModForChannel[c - 1];
          c++;
        }
      }
    }
    if (c > channelCount) {
      return DE_NOT_OK;
    }

    err = deriveDrcChannelGroups(
        pInst->drcSetEffect, pInst->drcChannelCount, gainSetIndex,
        pDModForChannel, &pInst->nDrcChannelGroups,
        pInst->gainSetIndexForChannelGroup, channelGroupForChannel,
        duckingModificationForChannelGroup);
    if (err) return (err);
  } else {
    int deriveChannelCount = 0;
    if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
        (pInst->downmixId[0] != DOWNMIX_ID_BASE_LAYOUT) &&
        (pInst->downmixId[0] != DOWNMIX_ID_ANY_DOWNMIX) &&
        (pInst->downmixIdCount == 1)) {
      if (hUniDrcConfig->downmixInstructionsCount != 0) {
        DOWNMIX_INSTRUCTIONS* pDown =
            selectDownmixInstructions(hUniDrcConfig, pInst->downmixId[0]);
        if (pDown == NULL) return DE_NOT_OK;
        pInst->drcChannelCount = channelCount =
            pDown->targetChannelCount; /* targetChannelCountFromDownmixId*/
      } else {
        deriveChannelCount = 1;
        channelCount = 1;
      }
    } else if (((version == 0) || (pInst->drcApplyToDownmix != 0)) &&
               ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
                (pInst->downmixIdCount > 1))) {
      /* Set maximum channel count as upper border. The effective channel count
       * is set at the process function. */
      pInst->drcChannelCount = 8;
      channelCount = 1;
    }

    c = 0;
    while (c < channelCount) {
      int bsGainSetIndex;
      bsGainSetIndex = FDKreadBits(hBs, 6);
      if (c >= 8) return DE_MEMORY_ERROR;
      gainSetIndex[c] = bsGainSetIndex - 1;
      c++;
      repeatSequenceIndex = FDKreadBits(hBs, 1);

      if (repeatSequenceIndex == 1) {
        bsRepeatSequenceCount = FDKreadBits(hBs, 5);
        bsRepeatSequenceCount += 1;
        if (deriveChannelCount) {
          channelCount = 1 + bsRepeatSequenceCount;
        }
        for (i = 0; i < bsRepeatSequenceCount; i++) {
          if (c >= 8) return DE_MEMORY_ERROR;
          gainSetIndex[c] = bsGainSetIndex - 1;
          c++;
        }
      }
    }
    if (c > channelCount) {
      return DE_NOT_OK;
    }
    if (deriveChannelCount) {
      pInst->drcChannelCount = channelCount;
    }

    /* DOWNMIX_ID_ANY_DOWNMIX: channelCount is 1. Distribute gainSetIndex to all
     * channels. */
    if ((pInst->downmixId[0] == DOWNMIX_ID_ANY_DOWNMIX) ||
        (pInst->downmixIdCount > 1)) {
      for (c = 1; c < pInst->drcChannelCount; c++) {
        gainSetIndex[c] = gainSetIndex[0];
      }
    }

    err = deriveDrcChannelGroups(pInst->drcSetEffect, pInst->drcChannelCount,
                                 gainSetIndex, NULL, &pInst->nDrcChannelGroups,
                                 pInst->gainSetIndexForChannelGroup,
                                 channelGroupForChannel, NULL);
    if (err) return (err);

    for (g = 0; g < pInst->nDrcChannelGroups; g++) {
      int set, bandCount;
      set = pInst->gainSetIndexForChannelGroup[g];

      /* get bandCount */
      if (pCoef != NULL && set < pCoef->gainSetCount) {
        bandCount = pCoef->gainSet[set].bandCount;
      } else {
        bandCount = 1;
      }

      _decodeGainModification(hBs, version, bandCount,
                              pInst->gainModificationForChannelGroup[g], 0);
    }
  }

  return err;
}

static DRC_ERROR _readChannelLayout(HANDLE_FDK_BITSTREAM hBs,
                                    CHANNEL_LAYOUT* pChan) {
  DRC_ERROR err = DE_OK;

  pChan->baseChannelCount = FDKreadBits(hBs, 7);

  if (pChan->baseChannelCount > 8) return DE_NOT_OK;

  pChan->layoutSignalingPresent = FDKreadBits(hBs, 1);

  if (pChan->layoutSignalingPresent) {
    pChan->definedLayout = FDKreadBits(hBs, 8);

    if (pChan->definedLayout == 0) {
      int i;
      for (i = 0; i < pChan->baseChannelCount; i++) {
        if (i < 8) {
          pChan->speakerPosition[i] = FDKreadBits(hBs, 7);
        } else {
          FDKpushFor(hBs, 7);
        }
      }
    }
  }
  return err;
}

static DRC_ERROR _readDownmixInstructions(HANDLE_FDK_BITSTREAM hBs,
                                          const int version,
                                          CHANNEL_LAYOUT* pChan,
                                          DOWNMIX_INSTRUCTIONS* pDown) {
  DRC_ERROR err = DE_OK;

  pDown->downmixId = FDKreadBits(hBs, 7);
  pDown->targetChannelCount = FDKreadBits(hBs, 7);
  pDown->targetLayout = FDKreadBits(hBs, 8);
  pDown->downmixCoefficientsPresent = FDKreadBits(hBs, 1);

  if (pDown->downmixCoefficientsPresent) {
    int nDownmixCoeffs = pDown->targetChannelCount * pChan->baseChannelCount;
    int i;
    if (nDownmixCoeffs > 8 * 8) return DE_NOT_OK;
    if (version == 0) {
      pDown->bsDownmixOffset = 0;
      for (i = 0; i < nDownmixCoeffs; i++) {
        /* LFE downmix coefficients are not supported. */
        pDown->downmixCoefficient[i] = downmixCoeff[FDKreadBits(hBs, 4)];
      }
    } else {
      pDown->bsDownmixOffset = FDKreadBits(hBs, 4);
      for (i = 0; i < nDownmixCoeffs; i++) {
        pDown->downmixCoefficient[i] = downmixCoeffV1[FDKreadBits(hBs, 5)];
      }
    }
  }
  return err;
}

static DRC_ERROR _readDrcExtensionV1(HANDLE_FDK_BITSTREAM hBs,
                                     HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  DRC_ERROR err = DE_OK;
  int downmixInstructionsV1Present;
  int drcCoeffsAndInstructionsUniDrcV1Present;
  int loudEqInstructionsPresent, loudEqInstructionsCount;
  int eqPresent, eqInstructionsCount;
  int i, offset;
  int diff = hUniDrcConfig->diff;

  downmixInstructionsV1Present = FDKreadBits(hBs, 1);
  if (downmixInstructionsV1Present == 1) {
    diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1,
                        FDKreadBits(hBs, 7));
    offset = hUniDrcConfig->downmixInstructionsCountV0;
    hUniDrcConfig->downmixInstructionsCount = fMin(
        (UCHAR)(offset + hUniDrcConfig->downmixInstructionsCountV1), (UCHAR)6);
    for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV1; i++) {
      DOWNMIX_INSTRUCTIONS tmpDown;
      FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
      err = _readDownmixInstructions(hBs, 1, &hUniDrcConfig->channelLayout,
                                     &tmpDown);
      if (err) return err;
      if ((offset + i) >= 6) continue;
      if (!diff)
        diff |= (FDKmemcmp(&tmpDown,
                           &(hUniDrcConfig->downmixInstructions[offset + i]),
                           sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
      hUniDrcConfig->downmixInstructions[offset + i] = tmpDown;
    }
  } else {
    diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV1, 0);
  }

  drcCoeffsAndInstructionsUniDrcV1Present = FDKreadBits(hBs, 1);
  if (drcCoeffsAndInstructionsUniDrcV1Present == 1) {
    diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1,
                        FDKreadBits(hBs, 3));
    offset = hUniDrcConfig->drcCoefficientsUniDrcCountV0;
    hUniDrcConfig->drcCoefficientsUniDrcCount =
        fMin((UCHAR)(offset + hUniDrcConfig->drcCoefficientsUniDrcCountV1),
             (UCHAR)2);
    for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV1; i++) {
      DRC_COEFFICIENTS_UNI_DRC tmpCoef;
      FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
      err = _readDrcCoefficientsUniDrc(hBs, 1, &tmpCoef);
      if (err) return err;
      if ((offset + i) >= 2) continue;
      if (!diff)
        diff |= (FDKmemcmp(&tmpCoef,
                           &(hUniDrcConfig->drcCoefficientsUniDrc[offset + i]),
                           sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
      hUniDrcConfig->drcCoefficientsUniDrc[offset + i] = tmpCoef;
    }

    diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1,
                        FDKreadBits(hBs, 6));
    offset = hUniDrcConfig->drcInstructionsUniDrcCount;
    hUniDrcConfig->drcInstructionsUniDrcCount =
        fMin((UCHAR)(offset + hUniDrcConfig->drcInstructionsUniDrcCountV1),
             (UCHAR)12);
    for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCount; i++) {
      DRC_INSTRUCTIONS_UNI_DRC tmpInst;
      FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
      err = _readDrcInstructionsUniDrc(hBs, 1, hUniDrcConfig, &tmpInst);
      if (err) return err;
      if ((offset + i) >= 12) continue;
      if (!diff)
        diff |= (FDKmemcmp(&tmpInst,
                           &(hUniDrcConfig->drcInstructionsUniDrc[offset + i]),
                           sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
      hUniDrcConfig->drcInstructionsUniDrc[offset + i] = tmpInst;
    }
  } else {
    diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV1, 0);
    diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV1, 0);
  }

  loudEqInstructionsPresent = FDKreadBits(hBs, 1);
  if (loudEqInstructionsPresent == 1) {
    loudEqInstructionsCount = FDKreadBits(hBs, 4);
    for (i = 0; i < loudEqInstructionsCount; i++) {
      _skipLoudEqInstructions(hBs);
    }
  }

  eqPresent = FDKreadBits(hBs, 1);
  if (eqPresent == 1) {
    _skipEqCoefficients(hBs);
    eqInstructionsCount = FDKreadBits(hBs, 4);
    for (i = 0; i < eqInstructionsCount; i++) {
      _skipEqInstructions(hBs, hUniDrcConfig);
    }
  }

  hUniDrcConfig->diff = diff;

  return err;
}

static DRC_ERROR _readUniDrcConfigExtension(
    HANDLE_FDK_BITSTREAM hBs, HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  DRC_ERROR err = DE_OK;
  int k, bitSizeLen, extSizeBits, bitSize;
  INT nBitsRemaining;
  UNI_DRC_CONFIG_EXTENSION* pExt = &(hUniDrcConfig->uniDrcConfigExt);

  k = 0;
  pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
  while (pExt->uniDrcConfigExtType[k] != UNIDRCCONFEXT_TERM) {
    if (k >= (8 - 1)) return DE_MEMORY_ERROR;
    bitSizeLen = FDKreadBits(hBs, 4);
    extSizeBits = bitSizeLen + 4;

    bitSize = FDKreadBits(hBs, extSizeBits);
    pExt->extBitSize[k] = bitSize + 1;
    nBitsRemaining = (INT)FDKgetValidBits(hBs);

    switch (pExt->uniDrcConfigExtType[k]) {
      case UNIDRCCONFEXT_V1:
        err = _readDrcExtensionV1(hBs, hUniDrcConfig);
        if (err) return err;
        if (nBitsRemaining !=
            ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
          return DE_NOT_OK;
        break;
      case UNIDRCCONFEXT_PARAM_DRC:
      /* add future extensions here */
      default:
        FDKpushFor(hBs, pExt->extBitSize[k]);
        break;
    }
    k++;
    pExt->uniDrcConfigExtType[k] = FDKreadBits(hBs, 4);
  }

  return err;
}

DRC_ERROR
drcDec_readUniDrcConfig(HANDLE_FDK_BITSTREAM hBs,
                        HANDLE_UNI_DRC_CONFIG hUniDrcConfig) {
  DRC_ERROR err = DE_OK;
  int i, diff = 0;
  int drcDescriptionBasicPresent, drcCoefficientsBasicCount,
      drcInstructionsBasicCount;
  CHANNEL_LAYOUT tmpChan;
  FDKmemclear(&tmpChan, sizeof(CHANNEL_LAYOUT));
  if (hUniDrcConfig == NULL) return DE_NOT_OK;

  diff |= _compAssign(&hUniDrcConfig->sampleRatePresent, FDKreadBits(hBs, 1));

  if (hUniDrcConfig->sampleRatePresent == 1) {
    diff |=
        _compAssign(&hUniDrcConfig->sampleRate, FDKreadBits(hBs, 18) + 1000);
  }

  diff |= _compAssign(&hUniDrcConfig->downmixInstructionsCountV0,
                      FDKreadBits(hBs, 7));

  drcDescriptionBasicPresent = FDKreadBits(hBs, 1);
  if (drcDescriptionBasicPresent == 1) {
    drcCoefficientsBasicCount = FDKreadBits(hBs, 3);
    drcInstructionsBasicCount = FDKreadBits(hBs, 4);
  } else {
    drcCoefficientsBasicCount = 0;
    drcInstructionsBasicCount = 0;
  }

  diff |= _compAssign(&hUniDrcConfig->drcCoefficientsUniDrcCountV0,
                      FDKreadBits(hBs, 3));
  diff |= _compAssign(&hUniDrcConfig->drcInstructionsUniDrcCountV0,
                      FDKreadBits(hBs, 6));

  err = _readChannelLayout(hBs, &tmpChan);
  if (err) return err;

  if (!diff)
    diff |= (FDKmemcmp(&tmpChan, &hUniDrcConfig->channelLayout,
                       sizeof(CHANNEL_LAYOUT)) != 0);
  hUniDrcConfig->channelLayout = tmpChan;

  hUniDrcConfig->downmixInstructionsCount =
      fMin(hUniDrcConfig->downmixInstructionsCountV0, (UCHAR)6);
  for (i = 0; i < hUniDrcConfig->downmixInstructionsCountV0; i++) {
    DOWNMIX_INSTRUCTIONS tmpDown;
    FDKmemclear(&tmpDown, sizeof(DOWNMIX_INSTRUCTIONS));
    err = _readDownmixInstructions(hBs, 0, &hUniDrcConfig->channelLayout,
                                   &tmpDown);
    if (err) return err;
    if (i >= 6) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpDown, &(hUniDrcConfig->downmixInstructions[i]),
                         sizeof(DOWNMIX_INSTRUCTIONS)) != 0);
    hUniDrcConfig->downmixInstructions[i] = tmpDown;
  }

  for (i = 0; i < drcCoefficientsBasicCount; i++) {
    _skipDrcCoefficientsBasic(hBs);
  }
  for (i = 0; i < drcInstructionsBasicCount; i++) {
    _skipDrcInstructionsBasic(hBs);
  }

  hUniDrcConfig->drcCoefficientsUniDrcCount =
      fMin(hUniDrcConfig->drcCoefficientsUniDrcCountV0, (UCHAR)2);
  for (i = 0; i < hUniDrcConfig->drcCoefficientsUniDrcCountV0; i++) {
    DRC_COEFFICIENTS_UNI_DRC tmpCoef;
    FDKmemclear(&tmpCoef, sizeof(DRC_COEFFICIENTS_UNI_DRC));
    err = _readDrcCoefficientsUniDrc(hBs, 0, &tmpCoef);
    if (err) return err;
    if (i >= 2) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpCoef, &(hUniDrcConfig->drcCoefficientsUniDrc[i]),
                         sizeof(DRC_COEFFICIENTS_UNI_DRC)) != 0);
    hUniDrcConfig->drcCoefficientsUniDrc[i] = tmpCoef;
  }

  hUniDrcConfig->drcInstructionsUniDrcCount =
      fMin(hUniDrcConfig->drcInstructionsUniDrcCountV0, (UCHAR)12);
  for (i = 0; i < hUniDrcConfig->drcInstructionsUniDrcCountV0; i++) {
    DRC_INSTRUCTIONS_UNI_DRC tmpInst;
    FDKmemclear(&tmpInst, sizeof(DRC_INSTRUCTIONS_UNI_DRC));
    err = _readDrcInstructionsUniDrc(hBs, 0, hUniDrcConfig, &tmpInst);
    if (err) return err;
    if (i >= 12) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpInst, &(hUniDrcConfig->drcInstructionsUniDrc[i]),
                         sizeof(DRC_INSTRUCTIONS_UNI_DRC)) != 0);
    hUniDrcConfig->drcInstructionsUniDrc[i] = tmpInst;
  }

  diff |=
      _compAssign(&hUniDrcConfig->uniDrcConfigExtPresent, FDKreadBits(hBs, 1));
  hUniDrcConfig->diff = diff;

  if (hUniDrcConfig->uniDrcConfigExtPresent == 1) {
    err = _readUniDrcConfigExtension(hBs, hUniDrcConfig);
    if (err) return err;
  }

  return err;
}

/*******************/
/* loudnessInfoSet */
/*******************/

static DRC_ERROR _decodeMethodValue(HANDLE_FDK_BITSTREAM hBs,
                                    const UCHAR methodDefinition,
                                    FIXP_DBL* methodValue, INT isBox) {
  int tmp;
  FIXP_DBL val;
  switch (methodDefinition) {
    case MD_UNKNOWN_OTHER:
    case MD_PROGRAM_LOUDNESS:
    case MD_ANCHOR_LOUDNESS:
    case MD_MAX_OF_LOUDNESS_RANGE:
    case MD_MOMENTARY_LOUDNESS_MAX:
    case MD_SHORT_TERM_LOUDNESS_MAX:
      tmp = FDKreadBits(hBs, 8);
      val = FL2FXCONST_DBL(-57.75f / (float)(1 << 7)) +
            (FIXP_DBL)(
                tmp << (DFRACT_BITS - 1 - 2 - 7)); /* -57.75 + tmp * 0.25; */
      break;
    case MD_LOUDNESS_RANGE:
      tmp = FDKreadBits(hBs, 8);
      if (tmp == 0)
        val = (FIXP_DBL)0;
      else if (tmp <= 128)
        val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 2 - 7)); /* tmp * 0.25; */
      else if (tmp <= 204) {
        val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 1 - 7)) -
              FL2FXCONST_DBL(32.0f / (float)(1 << 7)); /* 0.5 * tmp - 32.0f; */
      } else {
        /* downscale by 1 more bit to prevent overflow at intermediate result */
        val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 8)) -
              FL2FXCONST_DBL(134.0f / (float)(1 << 8)); /* tmp - 134.0; */
        val <<= 1;
      }
      break;
    case MD_MIXING_LEVEL:
      tmp = FDKreadBits(hBs, isBox ? 8 : 5);
      val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)) +
            FL2FXCONST_DBL(80.0f / (float)(1 << 7)); /* tmp + 80.0; */
      break;
    case MD_ROOM_TYPE:
      tmp = FDKreadBits(hBs, isBox ? 8 : 2);
      val = (FIXP_DBL)(tmp << (DFRACT_BITS - 1 - 7)); /* tmp; */
      break;
    case MD_SHORT_TERM_LOUDNESS:
      tmp = FDKreadBits(hBs, 8);
      val = FL2FXCONST_DBL(-116.0f / (float)(1 << 7)) +
            (FIXP_DBL)(
                tmp << (DFRACT_BITS - 1 - 1 - 7)); /* -116.0 + tmp * 0.5; */
      break;
    default:
      return DE_NOT_OK; /* invalid methodDefinition value */
  }
  *methodValue = val;
  return DE_OK;
}

static DRC_ERROR _readLoudnessMeasurement(HANDLE_FDK_BITSTREAM hBs,
                                          LOUDNESS_MEASUREMENT* pMeas) {
  DRC_ERROR err = DE_OK;

  pMeas->methodDefinition = FDKreadBits(hBs, 4);
  err =
      _decodeMethodValue(hBs, pMeas->methodDefinition, &pMeas->methodValue, 0);
  if (err) return err;
  pMeas->measurementSystem = FDKreadBits(hBs, 4);
  pMeas->reliability = FDKreadBits(hBs, 2);

  return err;
}

static DRC_ERROR _readLoudnessInfo(HANDLE_FDK_BITSTREAM hBs, const int version,
                                   LOUDNESS_INFO* loudnessInfo) {
  DRC_ERROR err = DE_OK;
  int bsSamplePeakLevel, bsTruePeakLevel, i;
  int measurementCount;

  loudnessInfo->drcSetId = FDKreadBits(hBs, 6);
  if (version >= 1) {
    loudnessInfo->eqSetId = FDKreadBits(hBs, 6);
  } else {
    loudnessInfo->eqSetId = 0;
  }
  loudnessInfo->downmixId = FDKreadBits(hBs, 7);

  loudnessInfo->samplePeakLevelPresent = FDKreadBits(hBs, 1);
  if (loudnessInfo->samplePeakLevelPresent) {
    bsSamplePeakLevel = FDKreadBits(hBs, 12);
    if (bsSamplePeakLevel == 0) {
      loudnessInfo->samplePeakLevelPresent = 0;
      loudnessInfo->samplePeakLevel = (FIXP_DBL)0;
    } else { /* 20.0 - bsSamplePeakLevel * 0.03125; */
      loudnessInfo->samplePeakLevel =
          FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
          (FIXP_DBL)(bsSamplePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
    }
  }

  loudnessInfo->truePeakLevelPresent = FDKreadBits(hBs, 1);
  if (loudnessInfo->truePeakLevelPresent) {
    bsTruePeakLevel = FDKreadBits(hBs, 12);
    if (bsTruePeakLevel == 0) {
      loudnessInfo->truePeakLevelPresent = 0;
      loudnessInfo->truePeakLevel = (FIXP_DBL)0;
    } else {
      loudnessInfo->truePeakLevel =
          FL2FXCONST_DBL(20.0f / (float)(1 << 7)) -
          (FIXP_DBL)(bsTruePeakLevel << (DFRACT_BITS - 1 - 5 - 7));
    }
    loudnessInfo->truePeakLevelMeasurementSystem = FDKreadBits(hBs, 4);
    loudnessInfo->truePeakLevelReliability = FDKreadBits(hBs, 2);
  }

  measurementCount = FDKreadBits(hBs, 4);
  loudnessInfo->measurementCount = fMin(measurementCount, 8);
  for (i = 0; i < measurementCount; i++) {
    LOUDNESS_MEASUREMENT tmpMeas;
    FDKmemclear(&tmpMeas, sizeof(LOUDNESS_MEASUREMENT));
    err = _readLoudnessMeasurement(hBs, &tmpMeas);
    if (err) return err;
    if (i >= 8) continue;
    loudnessInfo->loudnessMeasurement[i] = tmpMeas;
  }

  return err;
}

static DRC_ERROR _readLoudnessInfoSetExtEq(
    HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
  DRC_ERROR err = DE_OK;
  int i, offset;
  int diff = hLoudnessInfoSet->diff;

  diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV1,
                      FDKreadBits(hBs, 6));
  diff |=
      _compAssign(&hLoudnessInfoSet->loudnessInfoCountV1, FDKreadBits(hBs, 6));

  offset = hLoudnessInfoSet->loudnessInfoAlbumCountV0;
  hLoudnessInfoSet->loudnessInfoAlbumCount = fMin(
      (UCHAR)(offset + hLoudnessInfoSet->loudnessInfoAlbumCountV1), (UCHAR)12);
  for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV1; i++) {
    LOUDNESS_INFO tmpLoud;
    FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
    err = _readLoudnessInfo(hBs, 1, &tmpLoud);
    if (err) return err;
    if ((offset + i) >= 12) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpLoud,
                         &(hLoudnessInfoSet->loudnessInfoAlbum[offset + i]),
                         sizeof(LOUDNESS_INFO)) != 0);
    hLoudnessInfoSet->loudnessInfoAlbum[offset + i] = tmpLoud;
  }

  offset = hLoudnessInfoSet->loudnessInfoCountV0;
  hLoudnessInfoSet->loudnessInfoCount =
      fMin((UCHAR)(offset + hLoudnessInfoSet->loudnessInfoCountV1), (UCHAR)12);
  for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV1; i++) {
    LOUDNESS_INFO tmpLoud;
    FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
    err = _readLoudnessInfo(hBs, 1, &tmpLoud);
    if (err) return err;
    if ((offset + i) >= 12) continue;
    if (!diff)
      diff |=
          (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[offset + i]),
                     sizeof(LOUDNESS_INFO)) != 0);
    hLoudnessInfoSet->loudnessInfo[offset + i] = tmpLoud;
  }
  hLoudnessInfoSet->diff = diff;
  return err;
}

static DRC_ERROR _readLoudnessInfoSetExtension(
    HANDLE_FDK_BITSTREAM hBs, HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
  DRC_ERROR err = DE_OK;
  int k, bitSizeLen, extSizeBits, bitSize;
  INT nBitsRemaining;
  LOUDNESS_INFO_SET_EXTENSION* pExt = &(hLoudnessInfoSet->loudnessInfoSetExt);

  k = 0;
  pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
  while (pExt->loudnessInfoSetExtType[k] != UNIDRCLOUDEXT_TERM) {
    if (k >= (8 - 1)) return DE_MEMORY_ERROR;
    bitSizeLen = FDKreadBits(hBs, 4);
    extSizeBits = bitSizeLen + 4;

    bitSize = FDKreadBits(hBs, extSizeBits);
    pExt->extBitSize[k] = bitSize + 1;
    nBitsRemaining = (INT)FDKgetValidBits(hBs);

    switch (pExt->loudnessInfoSetExtType[k]) {
      case UNIDRCLOUDEXT_EQ:
        err = _readLoudnessInfoSetExtEq(hBs, hLoudnessInfoSet);
        if (err) return err;
        if (nBitsRemaining !=
            ((INT)pExt->extBitSize[k] + (INT)FDKgetValidBits(hBs)))
          return DE_NOT_OK;
        break;
      /* add future extensions here */
      default:
        FDKpushFor(hBs, pExt->extBitSize[k]);
        break;
    }
    k++;
    pExt->loudnessInfoSetExtType[k] = FDKreadBits(hBs, 4);
  }

  return err;
}

/* Parser for loundessInfoSet() */
DRC_ERROR
drcDec_readLoudnessInfoSet(HANDLE_FDK_BITSTREAM hBs,
                           HANDLE_LOUDNESS_INFO_SET hLoudnessInfoSet) {
  DRC_ERROR err = DE_OK;
  int i, diff = 0;
  if (hLoudnessInfoSet == NULL) return DE_NOT_OK;

  diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoAlbumCountV0,
                      FDKreadBits(hBs, 6));
  diff |=
      _compAssign(&hLoudnessInfoSet->loudnessInfoCountV0, FDKreadBits(hBs, 6));

  hLoudnessInfoSet->loudnessInfoAlbumCount =
      fMin(hLoudnessInfoSet->loudnessInfoAlbumCountV0, (UCHAR)12);
  for (i = 0; i < hLoudnessInfoSet->loudnessInfoAlbumCountV0; i++) {
    LOUDNESS_INFO tmpLoud;
    FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
    err = _readLoudnessInfo(hBs, 0, &tmpLoud);
    if (err) return err;
    if (i >= 12) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfoAlbum[i]),
                         sizeof(LOUDNESS_INFO)) != 0);
    hLoudnessInfoSet->loudnessInfoAlbum[i] = tmpLoud;
  }

  hLoudnessInfoSet->loudnessInfoCount =
      fMin(hLoudnessInfoSet->loudnessInfoCountV0, (UCHAR)12);
  for (i = 0; i < hLoudnessInfoSet->loudnessInfoCountV0; i++) {
    LOUDNESS_INFO tmpLoud;
    FDKmemclear(&tmpLoud, sizeof(LOUDNESS_INFO));
    err = _readLoudnessInfo(hBs, 0, &tmpLoud);
    if (err) return err;
    if (i >= 12) continue;
    if (!diff)
      diff |= (FDKmemcmp(&tmpLoud, &(hLoudnessInfoSet->loudnessInfo[i]),
                         sizeof(LOUDNESS_INFO)) != 0);
    hLoudnessInfoSet->loudnessInfo[i] = tmpLoud;
  }

  diff |= _compAssign(&hLoudnessInfoSet->loudnessInfoSetExtPresent,
                      FDKreadBits(hBs, 1));
  hLoudnessInfoSet->diff = diff;

  if (hLoudnessInfoSet->loudnessInfoSetExtPresent) {
    err = _readLoudnessInfoSetExtension(hBs, hLoudnessInfoSet);
    if (err) return err;
  }

  return err;
}
