remove use of log2(). Use VP8LFastLog2() instead.

Order-by-cost mostly unchanged (up to a scaling constant 1/log(2))
(except for few minor diff in < 2% of cases)

+ remove unused field cost_mode->cache_bits_

Change-Id: I714f8ab12f49a23f5d499a64c741382c9b489a3e
This commit is contained in:
Pascal Massimino
2012-08-01 18:22:06 -07:00
parent 8c515d54ea
commit 323dc4d9b9
5 changed files with 214 additions and 192 deletions

View File

@ -14,6 +14,7 @@
#include "./backward_references.h"
#include "./histogram.h"
#include "../dsp/lossless.h"
#include "../utils/color_cache.h"
#include "../utils/utils.h"
@ -357,46 +358,65 @@ typedef struct {
double literal_[PIX_OR_COPY_CODES_MAX];
double blue_[VALUES_IN_BYTE];
double distance_[NUM_DISTANCE_CODES];
int cache_bits_;
} CostModel;
static int BackwardReferencesTraceBackwards(
int xsize, int ysize, int recursive_cost_model,
const uint32_t* const argb, int cache_bits, VP8LBackwardRefs* const refs);
static int CostModelBuild(CostModel* const p, int xsize, int ysize,
static void ConvertPopulationCountTableToBitEstimates(
int num_symbols, const int population_counts[], double output[]) {
int sum = 0;
int nonzeros = 0;
int i;
for (i = 0; i < num_symbols; ++i) {
sum += population_counts[i];
if (population_counts[i] > 0) {
++nonzeros;
}
}
if (nonzeros <= 1) {
memset(output, 0, num_symbols * sizeof(*output));
} else {
const double logsum = VP8LFastLog2(sum);
for (i = 0; i < num_symbols; ++i) {
output[i] = logsum - VP8LFastLog2(population_counts[i]);
}
}
}
static int CostModelBuild(CostModel* const m, int xsize, int ysize,
int recursion_level, const uint32_t* const argb,
int cache_bits) {
int ok = 0;
VP8LHistogram histo;
VP8LBackwardRefs refs;
const int quality = 100;
if (!VP8LBackwardRefsAlloc(&refs, xsize * ysize)) goto Error;
p->cache_bits_ = cache_bits;
if (recursion_level > 0) {
if (!BackwardReferencesTraceBackwards(xsize, ysize, recursion_level - 1,
argb, cache_bits, &refs)) {
goto Error;
}
} else {
const int quality = 100;
if (!BackwardReferencesHashChain(xsize, ysize, argb, cache_bits, quality,
&refs)) {
goto Error;
}
}
VP8LHistogramCreate(&histo, &refs, cache_bits);
VP8LConvertPopulationCountTableToBitEstimates(
VP8LHistogramNumCodes(&histo), histo.literal_, p->literal_);
VP8LConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.red_, p->red_);
VP8LConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.blue_, p->blue_);
VP8LConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.alpha_, p->alpha_);
VP8LConvertPopulationCountTableToBitEstimates(
NUM_DISTANCE_CODES, histo.distance_, p->distance_);
ConvertPopulationCountTableToBitEstimates(
VP8LHistogramNumCodes(&histo), histo.literal_, m->literal_);
ConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.red_, m->red_);
ConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.blue_, m->blue_);
ConvertPopulationCountTableToBitEstimates(
VALUES_IN_BYTE, histo.alpha_, m->alpha_);
ConvertPopulationCountTableToBitEstimates(
NUM_DISTANCE_CODES, histo.distance_, m->distance_);
ok = 1;
Error:
@ -404,30 +424,30 @@ static int CostModelBuild(CostModel* const p, int xsize, int ysize,
return ok;
}
static WEBP_INLINE double GetLiteralCost(const CostModel* const p, uint32_t v) {
return p->alpha_[v >> 24] +
p->red_[(v >> 16) & 0xff] +
p->literal_[(v >> 8) & 0xff] +
p->blue_[v & 0xff];
static WEBP_INLINE double GetLiteralCost(const CostModel* const m, uint32_t v) {
return m->alpha_[v >> 24] +
m->red_[(v >> 16) & 0xff] +
m->literal_[(v >> 8) & 0xff] +
m->blue_[v & 0xff];
}
static WEBP_INLINE double GetCacheCost(const CostModel* const p, uint32_t idx) {
static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) {
const int literal_idx = VALUES_IN_BYTE + NUM_LENGTH_CODES + idx;
return p->literal_[literal_idx];
return m->literal_[literal_idx];
}
static WEBP_INLINE double GetLengthCost(const CostModel* const p,
static WEBP_INLINE double GetLengthCost(const CostModel* const m,
uint32_t length) {
int code, extra_bits_count, extra_bits_value;
PrefixEncode(length, &code, &extra_bits_count, &extra_bits_value);
return p->literal_[VALUES_IN_BYTE + code] + extra_bits_count;
return m->literal_[VALUES_IN_BYTE + code] + extra_bits_count;
}
static WEBP_INLINE double GetDistanceCost(const CostModel* const p,
static WEBP_INLINE double GetDistanceCost(const CostModel* const m,
uint32_t distance) {
int code, extra_bits_count, extra_bits_value;
PrefixEncode(distance, &code, &extra_bits_count, &extra_bits_value);
return p->distance_[code] + extra_bits_count;
return m->distance_[code] + extra_bits_count;
}
static int BackwardReferencesHashChainDistanceOnly(

View File

@ -19,17 +19,6 @@
#include "../dsp/lossless.h"
#include "../utils/utils.h"
#if defined(_MSC_VER) && !defined(NOT_HAVE_LOG2)
# define NOT_HAVE_LOG2 1
#endif
#ifdef NOT_HAVE_LOG2
static WEBP_INLINE double log2(double d) {
const double kLog2Reciprocal = 1.442695040888963;
return log(d) * kLog2Reciprocal;
}
#endif
static void HistogramClear(VP8LHistogram* const p) {
memset(p->literal_, 0, sizeof(p->literal_));
memset(p->red_, 0, sizeof(p->red_));
@ -88,33 +77,6 @@ VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
// -----------------------------------------------------------------------------
void VP8LConvertPopulationCountTableToBitEstimates(
int num_symbols, const int population_counts[], double output[]) {
int sum = 0;
int nonzeros = 0;
int i;
for (i = 0; i < num_symbols; ++i) {
sum += population_counts[i];
if (population_counts[i] > 0) {
++nonzeros;
}
}
if (nonzeros <= 1) {
memset(output, 0, num_symbols * sizeof(*output));
return;
}
{
const double log2sum = log2(sum);
for (i = 0; i < num_symbols; ++i) {
if (population_counts[i] == 0) {
output[i] = log2sum;
} else {
output[i] = log2sum - log2(population_counts[i]);
}
}
}
}
void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
const PixOrCopy* const v) {
if (PixOrCopyIsLiteral(v)) {
@ -139,7 +101,7 @@ void VP8LHistogramAddSinglePixOrCopy(VP8LHistogram* const histo,
static double BitsEntropy(const int* const array, int n) {
double retval = 0;
double retval = 0.;
int sum = 0;
int nonzeros = 0;
int max_val = 0;
@ -149,15 +111,14 @@ static double BitsEntropy(const int* const array, int n) {
if (array[i] != 0) {
sum += array[i];
++nonzeros;
retval += array[i] * VP8LFastLog(array[i]);
retval -= VP8LFastSLog2(array[i]);
if (max_val < array[i]) {
max_val = array[i];
}
}
}
retval -= sum * VP8LFastLog(sum);
retval *= -1.4426950408889634; // 1.0 / -Log(2);
mix = 0.627;
retval += VP8LFastSLog2(sum);
if (nonzeros < 5) {
if (nonzeros <= 1) {
return 0;
@ -177,15 +138,15 @@ static double BitsEntropy(const int* const array, int n) {
} else {
mix = 0.7; // nonzeros == 4.
}
} else {
mix = 0.627;
}
{
double min_limit = 2 * sum - max_val;
min_limit = mix * min_limit + (1.0 - mix) * retval;
if (retval < min_limit) {
return min_limit;
}
return (retval < min_limit) ? min_limit : retval;
}
return retval;
}
double VP8LHistogramEstimateBitsBulk(const VP8LHistogram* const p) {

View File

@ -101,9 +101,6 @@ static WEBP_INLINE int VP8LHistogramNumCodes(const VP8LHistogram* const p) {
((p->palette_code_bits_ > 0) ? (1 << p->palette_code_bits_) : 0);
}
void VP8LConvertPopulationCountTableToBitEstimates(
int num_symbols, const int population_counts[], double output[]);
// Builds the histogram image.
int VP8LGetHistoImageSymbols(int xsize, int ysize,
const VP8LBackwardRefs* const refs,