Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2011-07-17 15:03:57 +0400
committerCarl Eugen Hoyos <cehoyos@ag.or.at>2011-08-04 13:42:33 +0400
commit7c772ccd276021fed1f6ea40d150d73337fc3c1b (patch)
tree1c5031b558991517c9bd211022bebc208d90176c
parentcf82c5cd5b584ae9ee2b2d10fb1c9f0748446071 (diff)
Bink: clip AC coefficients during dequantization.
Fixes artefacts with Neverwinter Nights WOTCLogo.bik (http://drmccoy.de/zeugs/WOTCLogo.bik). Fixes trac ticket #352. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de> (cherry picked from commit 47b71eea099b3fe2c7e16644878ad9b7067974e3)
-rw-r--r--libavcodec/bink.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/libavcodec/bink.c b/libavcodec/bink.c
index ef07747dbc..4328a43525 100644
--- a/libavcodec/bink.c
+++ b/libavcodec/bink.c
@@ -571,6 +571,22 @@ static inline int binkb_get_value(BinkContext *c, int bundle_num)
return ret;
}
+static inline DCTELEM dequant(DCTELEM in, uint32_t quant, int dc)
+{
+ /* Note: multiplication is unsigned but we want signed shift
+ * otherwise clipping breaks.
+ * TODO: The official decoder does not use clipping at all
+ * but instead uses the full 32-bit result.
+ * However clipping at least gets rid of the case that a
+ * half-black half-white intra block gets black and white swapped
+ * and should cause at most minor differences (except for DC). */
+ int32_t res = in * quant;
+ res >>= 11;
+ if (!dc)
+ res = av_clip_int16(res);
+ return res;
+}
+
/**
* Read 8x8 block of DCT coefficients.
*
@@ -669,10 +685,10 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *
quant = quant_matrices[quant_idx];
- block[0] = (block[0] * quant[0]) >> 11;
+ block[0] = dequant(block[0], quant[0], 1);
for (i = 0; i < coef_count; i++) {
int idx = coef_idx[i];
- block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11;
+ block[scan[idx]] = dequant(block[scan[idx]], quant[idx], 0);
}
return 0;