mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 06:24:27 +02:00
add a -dither dithering option to the decoder
Even at high quality setting, the U/V quantizer step is limited to 4 which can lead to banding on gradient. This option allows to selectively apply some randomness to potentially flattened-out U/V blocks and attenuate the banding. This option is off by default in 'dwebp', but set to -dither 50 by default in 'vwebp'. Note: depending on the number of blocks selectively dithered, we can have up to a 10% slow-down in decoding speed it seems. Change-Id: Icc2446007f33ddacb60b3a80a9e63f2d5ad162de
This commit is contained in:
@ -34,8 +34,10 @@ typedef struct {
|
||||
void VP8InitRandom(VP8Random* const rg, float dithering);
|
||||
|
||||
// Returns a centered pseudo-random number with 'num_bits' amplitude.
|
||||
// (uses D.Knuth's Difference-based random generator)
|
||||
static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) {
|
||||
// (uses D.Knuth's Difference-based random generator).
|
||||
// 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision.
|
||||
static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits,
|
||||
int amp) {
|
||||
int diff;
|
||||
assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31);
|
||||
diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_];
|
||||
@ -43,12 +45,16 @@ static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) {
|
||||
rg->tab_[rg->index1_] = diff;
|
||||
if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0;
|
||||
if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0;
|
||||
diff = (diff << 1) >> (32 - num_bits); // sign-extend, 0-center
|
||||
diff = (diff * rg->amp_) >> VP8_RANDOM_DITHER_FIX; // restrict range
|
||||
diff += 1 << (num_bits - 1); // shift back to 0.5-center
|
||||
diff = (diff << 1) >> (32 - num_bits); // sign-extend, 0-center
|
||||
diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range
|
||||
diff += 1 << (num_bits - 1); // shift back to 0.5-center
|
||||
return diff;
|
||||
}
|
||||
|
||||
static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) {
|
||||
return VP8RandomBits2(rg, num_bits, rg->amp_);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user