extract random utils to their own file util/random.[ch]

they'll be used for decoding too, probably.

Change-Id: Id9cbb250c74fc0e876d4ea46b1b3dbf8356d6725
This commit is contained in:
Pascal Massimino 2013-10-30 02:00:33 -07:00
parent d3408720d8
commit 98aa33cf1e
7 changed files with 118 additions and 51 deletions

View File

@ -55,6 +55,7 @@ LOCAL_SRC_FILES := \
src/utils/huffman_encode.c \
src/utils/quant_levels.c \
src/utils/quant_levels_dec.c \
src/utils/random.c \
src/utils/rescaler.c \
src/utils/thread.c \
src/utils/utils.c \

View File

@ -224,6 +224,7 @@ UTILS_DEC_OBJS = \
$(DIROBJ)\utils\huffman.obj \
$(DIROBJ)\utils\quant_levels_dec.obj \
$(DIROBJ)\utils\rescaler.obj \
$(DIROBJ)\utils\random.obj \
$(DIROBJ)\utils\thread.obj \
$(DIROBJ)\utils\utils.obj \

View File

@ -156,6 +156,7 @@ UTILS_DEC_OBJS = \
src/utils/filters.o \
src/utils/huffman.o \
src/utils/quant_levels_dec.o \
src/utils/random.o \
src/utils/rescaler.o \
src/utils/thread.o \
src/utils/utils.o \
@ -199,6 +200,7 @@ HDRS = \
src/utils/huffman_encode.h \
src/utils/quant_levels.h \
src/utils/quant_levels_dec.h \
src/utils/random.h \
src/utils/rescaler.h \
src/utils/thread.h \
src/webp/format_constants.h \

View File

@ -17,6 +17,7 @@
#include "./vp8enci.h"
#include "../utils/alpha_processing.h"
#include "../utils/random.h"
#include "../utils/rescaler.h"
#include "../utils/utils.h"
#include "../dsp/dsp.h"
@ -593,62 +594,16 @@ int WebPPictureHasTransparency(const WebPPicture* picture) {
//------------------------------------------------------------------------------
// RGB -> YUV conversion
#define DITHER_FIX 8 // fixed-point precision for dithering
#define kRandomTableSize 55
static const uint32_t kRandomTable[kRandomTableSize] = { // 31b-range values
0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828,
0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da,
0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f,
0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2,
0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c,
0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd,
0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3,
0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b,
0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494,
0x27e5ed3c
};
typedef struct {
int index1_, index2_;
uint32_t tab_[kRandomTableSize];
int amp_;
} VP8Random;
static void InitRandom(VP8Random* const rg, float dithering) {
memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_));
rg->index1_ = 0;
rg->index2_ = 31;
rg->amp_ = (dithering < 0.0) ? 0
: (dithering > 1.0) ? (1 << DITHER_FIX)
: (uint32_t)((1 << DITHER_FIX) * dithering);
}
// D.Knuth's Difference-based random generator.
static WEBP_INLINE int Random(VP8Random* const rg, int num_bits) {
int diff;
assert(num_bits + DITHER_FIX <= 31);
diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_];
if (diff < 0) diff += (1u << 31);
rg->tab_[rg->index1_] = diff;
if (++rg->index1_ == kRandomTableSize) rg->index1_ = 0;
if (++rg->index2_ == kRandomTableSize) rg->index2_ = 0;
diff = (diff << 1) >> (32 - num_bits); // sign-extend, 0-center
diff = (diff * rg->amp_) >> DITHER_FIX; // restrict range
diff += 1 << (num_bits - 1); // shift back to 0.5-center
return diff;
}
static int RGBToY(int r, int g, int b, VP8Random* const rg) {
return VP8RGBToY(r, g, b, Random(rg, YUV_FIX));
return VP8RGBToY(r, g, b, VP8RandomBits(rg, YUV_FIX));
}
static int RGBToU(int r, int g, int b, VP8Random* const rg) {
return VP8RGBToU(r, g, b, Random(rg, YUV_FIX + 2));
return VP8RGBToU(r, g, b, VP8RandomBits(rg, YUV_FIX + 2));
}
static int RGBToV(int r, int g, int b, VP8Random* const rg) {
return VP8RGBToV(r, g, b, Random(rg, YUV_FIX + 2));
return VP8RGBToV(r, g, b, VP8RandomBits(rg, YUV_FIX + 2));
}
//------------------------------------------------------------------------------
@ -774,7 +729,7 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr,
}
if (!WebPPictureAlloc(picture)) return 0;
InitRandom(&rg, dithering);
VP8InitRandom(&rg, dithering);
InitGammaTables();
// Import luma plane
@ -1100,7 +1055,7 @@ void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) {
VP8Random rg;
int x, y;
if (pic == NULL) return;
InitRandom(&rg, 0.f);
VP8InitRandom(&rg, 0.f);
if (!pic->use_argb) {
const int uv_width = (pic->width >> 1); // omit last pixel during u/v loop
const int Y0 = RGBToY(red, green, blue, &rg);

View File

@ -23,6 +23,8 @@ COMMON_SOURCES += quant_levels_dec.c
COMMON_SOURCES += quant_levels_dec.h
COMMON_SOURCES += rescaler.c
COMMON_SOURCES += rescaler.h
COMMON_SOURCES += random.c
COMMON_SOURCES += random.h
COMMON_SOURCES += thread.c
COMMON_SOURCES += thread.h
COMMON_SOURCES += utils.c

50
src/utils/random.c Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Pseudo-random utilities
//
// Author: Skal (pascal.massimino@gmail.com)
#include <string.h>
#include "./random.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
//------------------------------------------------------------------------------
// 31b-range values
static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = {
0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828,
0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da,
0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f,
0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2,
0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c,
0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd,
0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3,
0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b,
0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494,
0x27e5ed3c
};
void VP8InitRandom(VP8Random* const rg, float dithering) {
memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_));
rg->index1_ = 0;
rg->index2_ = 31;
rg->amp_ = (dithering < 0.0) ? 0
: (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX)
: (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering);
}
//------------------------------------------------------------------------------
#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"
#endif

56
src/utils/random.h Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the COPYING file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
// -----------------------------------------------------------------------------
//
// Pseudo-random utilities
//
// Author: Skal (pascal.massimino@gmail.com)
#ifndef WEBP_UTILS_RANDOM_H_
#define WEBP_UTILS_RANDOM_H_
#include <assert.h>
#include "../webp/types.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering
#define VP8_RANDOM_TABLE_SIZE 55
typedef struct {
int index1_, index2_;
uint32_t tab_[VP8_RANDOM_TABLE_SIZE];
int amp_;
} VP8Random;
// Initializes random generator with an amplitude 'dithering' in range [0..1].
extern 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) {
int diff;
assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31);
diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_];
if (diff < 0) diff += (1u << 31);
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
return diff;
}
#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"
#endif
#endif /* WEBP_UTILS_RANDOM_H_ */