mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-28 14:38:21 +01:00
lossless: 0.06 % compression density improvement
Change-Id: Ib662e6aec53b40d6bc736d3ecfd6475bb005c790
This commit is contained in:
parent
64960da9e1
commit
3033f24c26
@ -854,40 +854,32 @@ static float GetPredictionCostCrossColorRed(
|
|||||||
|
|
||||||
static void GetBestGreenToRed(
|
static void GetBestGreenToRed(
|
||||||
const uint32_t* argb, int stride, int tile_width, int tile_height,
|
const uint32_t* argb, int stride, int tile_width, int tile_height,
|
||||||
VP8LMultipliers prev_x, VP8LMultipliers prev_y,
|
VP8LMultipliers prev_x, VP8LMultipliers prev_y, int quality,
|
||||||
const int accumulated_red_histo[256], VP8LMultipliers* const best_tx) {
|
const int accumulated_red_histo[256], VP8LMultipliers* const best_tx) {
|
||||||
int min_green_to_red = -64;
|
const int kMaxIters = 4 + ((7 * quality) >> 8); // in range [4..6]
|
||||||
int max_green_to_red = 64;
|
int green_to_red_best = 0;
|
||||||
int green_to_red = 0;
|
int iter, offset;
|
||||||
int eval_min = 1;
|
float best_diff = GetPredictionCostCrossColorRed(
|
||||||
int eval_max = 1;
|
argb, stride, tile_width, tile_height, prev_x, prev_y,
|
||||||
float cur_diff_min = MAX_DIFF_COST;
|
green_to_red_best, accumulated_red_histo);
|
||||||
float cur_diff_max = MAX_DIFF_COST;
|
for (iter = 0; iter < kMaxIters; ++iter) {
|
||||||
// Do a binary search to find the optimal green_to_red color transform.
|
// ColorTransformDelta is a 3.5 bit fixed point, so 32 is equal to
|
||||||
while (max_green_to_red - min_green_to_red > 2) {
|
// one in color computation. Having initial delta here as 1 is sufficient
|
||||||
if (eval_min) {
|
// to explore the range of (-2, 2).
|
||||||
cur_diff_min = GetPredictionCostCrossColorRed(
|
const int delta = 32 >> iter;
|
||||||
argb, stride, tile_width, tile_height,
|
// Try a negative and a positive delta from the best known value.
|
||||||
prev_x, prev_y, min_green_to_red, accumulated_red_histo);
|
for (offset = -delta; offset <= delta; offset += 2 * delta) {
|
||||||
eval_min = 0;
|
const int green_to_red_cur = offset + green_to_red_best;
|
||||||
}
|
const float cur_diff = GetPredictionCostCrossColorRed(
|
||||||
if (eval_max) {
|
argb, stride, tile_width, tile_height, prev_x, prev_y,
|
||||||
cur_diff_max = GetPredictionCostCrossColorRed(
|
green_to_red_cur, accumulated_red_histo);
|
||||||
argb, stride, tile_width, tile_height,
|
if (cur_diff < best_diff) {
|
||||||
prev_x, prev_y, max_green_to_red, accumulated_red_histo);
|
best_diff = cur_diff;
|
||||||
eval_max = 0;
|
green_to_red_best = green_to_red_cur;
|
||||||
}
|
|
||||||
if (cur_diff_min < cur_diff_max) {
|
|
||||||
green_to_red = min_green_to_red;
|
|
||||||
max_green_to_red = (max_green_to_red + min_green_to_red) / 2;
|
|
||||||
eval_max = 1;
|
|
||||||
} else {
|
|
||||||
green_to_red = max_green_to_red;
|
|
||||||
min_green_to_red = (max_green_to_red + min_green_to_red) / 2;
|
|
||||||
eval_min = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
best_tx->green_to_red_ = green_to_red;
|
}
|
||||||
|
best_tx->green_to_red_ = green_to_red_best;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CollectColorBlueTransforms(const uint32_t* argb, int stride,
|
static void CollectColorBlueTransforms(const uint32_t* argb, int stride,
|
||||||
@ -1000,7 +992,7 @@ static VP8LMultipliers GetBestColorTransformForTile(
|
|||||||
MultipliersClear(&best_tx);
|
MultipliersClear(&best_tx);
|
||||||
|
|
||||||
GetBestGreenToRed(tile_argb, xsize, tile_width, tile_height,
|
GetBestGreenToRed(tile_argb, xsize, tile_width, tile_height,
|
||||||
prev_x, prev_y, accumulated_red_histo, &best_tx);
|
prev_x, prev_y, quality, accumulated_red_histo, &best_tx);
|
||||||
GetBestGreenRedToBlue(tile_argb, xsize, tile_width, tile_height,
|
GetBestGreenRedToBlue(tile_argb, xsize, tile_width, tile_height,
|
||||||
prev_x, prev_y, quality, accumulated_blue_histo,
|
prev_x, prev_y, quality, accumulated_blue_histo,
|
||||||
&best_tx);
|
&best_tx);
|
||||||
|
Loading…
Reference in New Issue
Block a user