15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 Google Inc. All Rights Reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// that can be found in the COPYING file in the root of the source 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// tree. An additional intellectual property rights grant can be found 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// in the file PATENTS. All contributing project authors may 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// be found in the AUTHORS file in the root of the source tree. 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// ----------------------------------------------------------------------------- 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Pseudo-random utilities 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Author: Skal (pascal.massimino@gmail.com) 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef WEBP_UTILS_RANDOM_H_ 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define WEBP_UTILS_RANDOM_H_ 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <assert.h> 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "../webp/types.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)extern "C" { 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define VP8_RANDOM_TABLE_SIZE 55 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)typedef struct { 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int index1_, index2_; 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t tab_[VP8_RANDOM_TABLE_SIZE]; 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int amp_; 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} VP8Random; 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Initializes random generator with an amplitude 'dithering' in range [0..1]. 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void VP8InitRandom(VP8Random* const rg, float dithering); 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns a centered pseudo-random number with 'num_bits' amplitude. 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (uses D.Knuth's Difference-based random generator). 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision. 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static WEBP_INLINE int VP8RandomBits2(VP8Random* const rg, int num_bits, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int amp) { 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int diff; 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31); 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_]; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (diff < 0) diff += (1u << 31); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rg->tab_[rg->index1_] = diff; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0; 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // sign-extend, 0-center 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) diff = (int)((uint32_t)diff << 1) >> (32 - num_bits); 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diff += 1 << (num_bits - 1); // shift back to 0.5-center 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return diff; 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static WEBP_INLINE int VP8RandomBits(VP8Random* const rg, int num_bits) { 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return VP8RandomBits2(rg, num_bits, rg->amp_); 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __cplusplus 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // extern "C" 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif /* WEBP_UTILS_RANDOM_H_ */ 64