diff --git a/coding/arithmetic_codec.cpp b/coding/arithmetic_codec.cpp index c9efc65c57..7a3740d755 100644 --- a/coding/arithmetic_codec.cpp +++ b/coding/arithmetic_codec.cpp @@ -20,9 +20,9 @@ vector FreqsToDistrTable(vector const & origFreqs) while (1) { // Resulting distr table is initialized with first zero value. - vector result(1, 0); + vector result(1, 0); vector freqs; - u32 sum = 0; + u64 sum = 0; u64 minFreq = ~u64(0); for (u32 i = 0; i < origFreqs.size(); ++i) { @@ -39,16 +39,21 @@ vector FreqsToDistrTable(vector const & origFreqs) bool hasDegradedZeroInterval = false; for (u32 i = 1; i < result.size(); ++i) { - result[i] = (u64(result[i]) << DISTR_SHIFT) / u64(sum); + result[i] = (result[i] << DISTR_SHIFT) / sum; if (freqs[i - 1] > 0 && (result[i] - result[i - 1] == 0)) { hasDegradedZeroInterval = true; break; } } - if (!hasDegradedZeroInterval) return result; + if (!hasDegradedZeroInterval) { + // Convert distr_table to 32-bit vector, although currently only 17 bits are used. + vector distr_table; + for (u32 i = 0; i < result.size(); ++i) distr_table.push_back(result[i]); + return distr_table; + } ++freqLowerBound; - } + } } ArithmeticEncoder::ArithmeticEncoder(vector const & distrTable) @@ -121,15 +126,16 @@ ArithmeticDecoder::ArithmeticDecoder(Reader & reader, vector const & distrT u32 ArithmeticDecoder::Decode() { u32 l = 0, r = m_distrTable.size(), m = 0; + u32 shiftedSize = m_size >> DISTR_SHIFT; while (r - l > 1) { m = (l + r) / 2; - u32 intervalBegin = (m_size >> DISTR_SHIFT) * m_distrTable[m]; + u32 intervalBegin = shiftedSize * m_distrTable[m]; if (intervalBegin <= m_codeValue) l = m; else r = m; } u32 symbol = l; - m_codeValue -= (m_size >> DISTR_SHIFT) * m_distrTable[symbol]; - m_size = (m_size >> DISTR_SHIFT) * (m_distrTable[symbol + 1] - m_distrTable[symbol]); + m_codeValue -= shiftedSize * m_distrTable[symbol]; + m_size = shiftedSize * (m_distrTable[symbol + 1] - m_distrTable[symbol]); while (m_size < (u32(1) << 24)) { m_codeValue <<= 8;