mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 06:24:27 +02:00
fix bad saturation order in QuantizeBlock
Saturation was done on input coeff, not quantized one. This saturation is not absolutely needed: output of FTransformWHT is in range [-16320, 16321]. At quality 100, max quantization steps is 8, so the maximal range used by QuantizeBlock() is [-2040, 2040]. But there's some extra bias (mtx->bias_[] and mtx->sharpen_[]) so it's better to leave this saturation check for now. addresses issue #145 Change-Id: I4b14f71cdc80c46f9eaadb2a4e8e03d396879d28
This commit is contained in:
@ -631,13 +631,13 @@ static int QuantizeBlock(int16_t in[16], int16_t out[16],
|
||||
for (; n < 16; ++n) {
|
||||
const int j = kZigzag[n];
|
||||
const int sign = (in[j] < 0);
|
||||
int coeff = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
|
||||
if (coeff > 2047) coeff = 2047;
|
||||
const int coeff = (sign ? -in[j] : in[j]) + mtx->sharpen_[j];
|
||||
if (coeff > mtx->zthresh_[j]) {
|
||||
const int Q = mtx->q_[j];
|
||||
const int iQ = mtx->iq_[j];
|
||||
const int B = mtx->bias_[j];
|
||||
out[n] = QUANTDIV(coeff, iQ, B);
|
||||
if (out[n] > MAX_LEVEL) out[n] = MAX_LEVEL;
|
||||
if (sign) out[n] = -out[n];
|
||||
in[j] = out[n] * Q;
|
||||
if (out[n]) last = n;
|
||||
|
@ -776,7 +776,7 @@ static int Disto16x16SSE2(const uint8_t* const a, const uint8_t* const b,
|
||||
// Simple quantization
|
||||
static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16],
|
||||
int n, const VP8Matrix* const mtx) {
|
||||
const __m128i max_coeff_2047 = _mm_set1_epi16(2047);
|
||||
const __m128i max_coeff_2047 = _mm_set1_epi16(MAX_LEVEL);
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
__m128i coeff0, coeff8;
|
||||
__m128i out0, out8;
|
||||
@ -812,10 +812,6 @@ static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16],
|
||||
coeff0 = _mm_add_epi16(coeff0, sharpen0);
|
||||
coeff8 = _mm_add_epi16(coeff8, sharpen8);
|
||||
|
||||
// if (coeff > 2047) coeff = 2047
|
||||
coeff0 = _mm_min_epi16(coeff0, max_coeff_2047);
|
||||
coeff8 = _mm_min_epi16(coeff8, max_coeff_2047);
|
||||
|
||||
// out = (coeff * iQ + B) >> QFIX;
|
||||
{
|
||||
// doing calculations with 32b precision (QFIX=17)
|
||||
@ -843,9 +839,14 @@ static int QuantizeBlockSSE2(int16_t in[16], int16_t out[16],
|
||||
out_04 = _mm_srai_epi32(out_04, QFIX);
|
||||
out_08 = _mm_srai_epi32(out_08, QFIX);
|
||||
out_12 = _mm_srai_epi32(out_12, QFIX);
|
||||
|
||||
// pack result as 16b
|
||||
out0 = _mm_packs_epi32(out_00, out_04);
|
||||
out8 = _mm_packs_epi32(out_08, out_12);
|
||||
|
||||
// if (coeff > 2047) coeff = 2047
|
||||
out0 = _mm_min_epi16(out0, max_coeff_2047);
|
||||
out8 = _mm_min_epi16(out8, max_coeff_2047);
|
||||
}
|
||||
|
||||
// get sign back (if (sign[j]) out_n = -out_n)
|
||||
|
Reference in New Issue
Block a user