Fix signed integer overflow in DuckerCalcEnergy().

Bug: 145668917
Test: atest DecoderTestXheAac ; atest DecoderTestAacDrc
Change-Id: I9f6458860901fa354a534e8fabe20dfa1a0cf7a9
This commit is contained in:
Fraunhofer IIS FDK 2019-10-29 13:08:53 +01:00 committed by Jean-Michel Trivi
parent 7bb841dfb1
commit c69e4584c3
1 changed files with 24 additions and 56 deletions

View File

@ -1,7 +1,7 @@
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
Software License for The Fraunhofer FDK AAC Codec Library for Android Software License for The Fraunhofer FDK AAC Codec Library for Android
© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten © Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten
Forschung e.V. All rights reserved. Forschung e.V. All rights reserved.
1. INTRODUCTION 1. INTRODUCTION
@ -227,7 +227,7 @@ static inline int SpatialDecGetQmfBand(int paramBand, const UCHAR *tab) {
} }
#define DUCKER_MAX_NRG_SCALE (24) #define DUCKER_MAX_NRG_SCALE (24)
#define DUCKER_HEADROOM_BITS (3) #define DUCKER_HEADROOM_BITS (2)
#define FILTER_SF (2) #define FILTER_SF (2)
@ -606,10 +606,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
dataImagIn += start; dataImagIn += start;
dataRealOut += start; dataRealOut += start;
dataImagOut += start; dataImagOut += start;
#ifdef FUNCTION_DecorrFilterApplyPASS_func1
DecorrFilterApplyPASS_func1(i, dataRealIn, dataImagIn, dataRealOut,
dataImagOut, pDelayBuffer, offset);
#else
do { do {
FIXP_DBL delay_re, delay_im, real, imag; FIXP_DBL delay_re, delay_im, real, imag;
@ -623,7 +619,6 @@ static INT DecorrFilterApplyPASS(DECORR_FILTER_INSTANCE const filter[],
*dataImagOut++ = delay_im; *dataImagOut++ = delay_im;
pDelayBuffer += offset; pDelayBuffer += offset;
} while (--i != 0); } while (--i != 0);
#endif
} }
} }
@ -1061,24 +1056,15 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f); FIXP_DBL maxVal = FL2FXCONST_DBL(-1.0f);
if (maxVal == FL2FXCONST_DBL(-1.0f)) { if (maxVal == FL2FXCONST_DBL(-1.0f)) {
#ifdef FUNCTION_DuckerCalcEnergy_func2 clz = fMin(getScalefactor(&inputReal[startHybBand],
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand, fMax(0, maxHybridBand - startHybBand + 1)),
maxHybBand, maxHybridBand); getScalefactor(&inputImag[startHybBand],
#else fMax(0, maxHybBand - startHybBand + 1)));
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f); } else {
for (qs = startHybBand; qs <= maxHybBand; qs++) { clz = CntLeadingZeros(maxVal) - 1;
localMaxVal |= fAbs(inputReal[qs]);
localMaxVal |= fAbs(inputImag[qs]);
}
for (; qs <= maxHybridBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
}
maxVal = localMaxVal;
#endif
} }
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS); clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1; *nrgScale = (SCHAR)clz << 1;
/* Initialize pb since it would stay uninitialized for the case startHybBand /* Initialize pb since it would stay uninitialized for the case startHybBand
@ -1086,9 +1072,10 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands); pb = SpatialDecGetProcessingBand(maxHybBand, self->mapHybBands2ProcBands);
for (qs = startHybBand; qs <= maxHybBand; qs++) { for (qs = startHybBand; qs <= maxHybBand; qs++) {
pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] = energy[pb] = SATURATE_LEFT_SHIFT(
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) + (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
fPow2Div2(inputImag[qs] << clz)); (fPow2Div2(inputImag[qs] << clz) >> 1),
1, DFRACT_BITS);
} }
pb++; pb++;
@ -1112,43 +1099,29 @@ static INT DuckerCalcEnergy(DUCKER_INSTANCE *const self,
maxVal = inputMaxVal; maxVal = inputMaxVal;
if (maxVal == FL2FXCONST_DBL(-1.0f)) { if (maxVal == FL2FXCONST_DBL(-1.0f)) {
#ifdef FUNCTION_DuckerCalcEnergy_func2 clz = fMin(getScalefactor(&inputReal[startHybBand],
maxVal = DuckerCalcEnergy_func2(inputReal, inputImag, startHybBand, fMax(0, maxHybridBand - startHybBand + 1)),
maxHybBand, maxHybridBand); getScalefactor(&inputImag[startHybBand],
#else fMax(0, maxHybBand - startHybBand + 1)));
FIXP_DBL localMaxVal = FL2FXCONST_DBL(0.0f); } else {
for (qs = startHybBand; qs <= maxHybBand; qs++) { clz = CntLeadingZeros(maxVal) - 1;
localMaxVal |= fAbs(inputReal[qs]);
localMaxVal |= fAbs(inputImag[qs]);
}
for (; qs <= maxHybridBand; qs++) {
localMaxVal |= fAbs(inputReal[qs]);
}
maxVal = localMaxVal;
#endif
} }
clz = fixMax(0, CntLeadingZeros(maxVal) - DUCKER_HEADROOM_BITS); clz = fMin(fMax(0, clz - DUCKER_HEADROOM_BITS), DUCKER_MAX_NRG_SCALE);
clz = fixMin(clz, DUCKER_MAX_NRG_SCALE);
*nrgScale = (SCHAR)clz << 1; *nrgScale = (SCHAR)clz << 1;
#ifdef FUNCTION_DuckerCalcEnergy_func4
DuckerCalcEnergy_func4(inputReal, inputImag, energy,
self->mapHybBands2ProcBands, clz, startHybBand,
maxHybBand, maxHybridBand);
#else
for (qs = startHybBand; qs <= maxHybBand; qs++) { for (qs = startHybBand; qs <= maxHybBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] = energy[pb] = SATURATE_LEFT_SHIFT(
fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz) + (energy[pb] >> 1) + (fPow2Div2(inputReal[qs] << clz) >> 1) +
fPow2Div2(inputImag[qs] << clz)); (fPow2Div2(inputImag[qs] << clz) >> 1),
1, DFRACT_BITS);
} }
for (; qs <= maxHybridBand; qs++) { for (; qs <= maxHybridBand; qs++) {
int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands); int pb = SpatialDecGetProcessingBand(qs, self->mapHybBands2ProcBands);
energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz)); energy[pb] = fAddSaturate(energy[pb], fPow2Div2(inputReal[qs] << clz));
} }
#endif /* FUNCTION_DuckerCalcEnergy_func4 */
} }
{ {
@ -1295,10 +1268,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
} }
} }
#ifdef FUNCTION_DuckerApply_func1
qs = DuckerApply_func1(qs, hybBands, qs_next, outputReal, outputImag,
duckGain);
#else
/* general gain*output section */ /* general gain*output section */
if (qs < hybBands) { /* true for about 39% */ if (qs < hybBands) { /* true for about 39% */
for (; qs < qs_next; qs++) { /* runs about 2 times */ for (; qs < qs_next; qs++) { /* runs about 2 times */
@ -1310,7 +1279,6 @@ static INT DuckerApply(DUCKER_INSTANCE *const self,
outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2; outputReal[qs] = fMultDiv2(outputReal[qs], duckGain) << 2;
} }
} }
#endif
} /* pb */ } /* pb */
self->headroomSmoothDirRevNrg = self->headroomSmoothDirRevNrg =