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

This commit is contained in:
Pascal Massimino 2013-10-30 02:07:28 -07:00 committed by Gerrit Code Review
commit c8d48c6e0d
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/huffman_encode.c \
src/utils/quant_levels.c \ src/utils/quant_levels.c \
src/utils/quant_levels_dec.c \ src/utils/quant_levels_dec.c \
src/utils/random.c \
src/utils/rescaler.c \ src/utils/rescaler.c \
src/utils/thread.c \ src/utils/thread.c \
src/utils/utils.c \ src/utils/utils.c \

View File

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

View File

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

View File

@ -17,6 +17,7 @@
#include "./vp8enci.h" #include "./vp8enci.h"
#include "../utils/alpha_processing.h" #include "../utils/alpha_processing.h"
#include "../utils/random.h"
#include "../utils/rescaler.h" #include "../utils/rescaler.h"
#include "../utils/utils.h" #include "../utils/utils.h"
#include "../dsp/dsp.h" #include "../dsp/dsp.h"
@ -593,62 +594,16 @@ int WebPPictureHasTransparency(const WebPPicture* picture) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// RGB -> YUV conversion // 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) { 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) { 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) { 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; if (!WebPPictureAlloc(picture)) return 0;
InitRandom(&rg, dithering); VP8InitRandom(&rg, dithering);
InitGammaTables(); InitGammaTables();
// Import luma plane // Import luma plane
@ -1100,7 +1055,7 @@ void WebPBlendAlpha(WebPPicture* pic, uint32_t background_rgb) {
VP8Random rg; VP8Random rg;
int x, y; int x, y;
if (pic == NULL) return; if (pic == NULL) return;
InitRandom(&rg, 0.f); VP8InitRandom(&rg, 0.f);
if (!pic->use_argb) { if (!pic->use_argb) {
const int uv_width = (pic->width >> 1); // omit last pixel during u/v loop const int uv_width = (pic->width >> 1); // omit last pixel during u/v loop
const int Y0 = RGBToY(red, green, blue, &rg); 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 += quant_levels_dec.h
COMMON_SOURCES += rescaler.c COMMON_SOURCES += rescaler.c
COMMON_SOURCES += rescaler.h COMMON_SOURCES += rescaler.h
COMMON_SOURCES += random.c
COMMON_SOURCES += random.h
COMMON_SOURCES += thread.c COMMON_SOURCES += thread.c
COMMON_SOURCES += thread.h COMMON_SOURCES += thread.h
COMMON_SOURCES += utils.c 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_ */