diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2011-07-17 13:03:57 +0200 |
---|---|---|
committer | Carl Eugen Hoyos <cehoyos@ag.or.at> | 2011-08-04 11:42:33 +0200 |
commit | 7c772ccd276021fed1f6ea40d150d73337fc3c1b (patch) | |
tree | 1c5031b558991517c9bd211022bebc208d90176c | |
parent | cf82c5cd5b584ae9ee2b2d10fb1c9f0748446071 (diff) | |
download | ffmpeg-7c772ccd276021fed1f6ea40d150d73337fc3c1b.tar.gz |
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.c | 20 |
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; |