lossless: 0.13% compression density gain
over a 1000 image corpus Single photograph benchmark: Before: Q=20: 2.560 MP/s Q=40: 2.593 MP/s Q=60: 1.795 MP/s Q=80: 1.603 MP/s Q=99: 1.122 MP/s After: Q=20: 3.334 MP/s Q=40: 2.464 MP/s Q=60: 2.009 MP/s Q=80: 1.871 MP/s Q=99: 1.163 MP/s This CL allows for some further improvements that would not be possible otherwise. Change-Id: I61ba154beca2266cb96469281cf96e84a4412586
This commit is contained in:
parent
64960da9e1
commit
2beef2f245
@ -935,49 +935,55 @@ static float GetPredictionCostCrossColorBlue(
|
|||||||
return cur_diff;
|
return cur_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define kGreenRedToBlueNumAxis 8
|
||||||
|
#define kGreenRedToBlueMaxIters 7
|
||||||
static void GetBestGreenRedToBlue(
|
static void GetBestGreenRedToBlue(
|
||||||
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, int quality,
|
VP8LMultipliers prev_x, VP8LMultipliers prev_y, int quality,
|
||||||
const int accumulated_blue_histo[256],
|
const int accumulated_blue_histo[256],
|
||||||
VP8LMultipliers* const best_tx) {
|
VP8LMultipliers* const best_tx) {
|
||||||
float best_diff = MAX_DIFF_COST;
|
const int8_t offset[kGreenRedToBlueNumAxis][2] =
|
||||||
float cur_diff;
|
{{0, -1}, {0, 1}, {-1, 0}, {1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
|
||||||
const int step = (quality < 25) ? 32 : (quality > 50) ? 8 : 16;
|
const int8_t delta_lut[kGreenRedToBlueMaxIters] = { 16, 16, 8, 4, 2, 2, 2 };
|
||||||
const int min_green_to_blue = -32;
|
const int iters =
|
||||||
const int max_green_to_blue = 32;
|
(quality < 25) ? 1 : (quality > 50) ? kGreenRedToBlueMaxIters : 4;
|
||||||
const int min_red_to_blue = -32;
|
int green_to_blue_best = 0;
|
||||||
const int max_red_to_blue = 32;
|
int red_to_blue_best = 0;
|
||||||
const int num_iters =
|
int iter;
|
||||||
(1 + (max_green_to_blue - min_green_to_blue) / step) *
|
// Initial value at origin:
|
||||||
(1 + (max_red_to_blue - min_red_to_blue) / step);
|
float best_diff = GetPredictionCostCrossColorBlue(
|
||||||
// Number of tries to get optimal green_to_blue & red_to_blue color transforms
|
argb, stride, tile_width, tile_height, prev_x, prev_y,
|
||||||
// after finding a local minima.
|
green_to_blue_best, red_to_blue_best, accumulated_blue_histo);
|
||||||
const int max_tries_after_min = 4 + (num_iters >> 2);
|
for (iter = 0; iter < iters; ++iter) {
|
||||||
int num_tries_after_min = 0;
|
const int delta = delta_lut[iter];
|
||||||
int green_to_blue;
|
int axis;
|
||||||
for (green_to_blue = min_green_to_blue;
|
for (axis = 0; axis < kGreenRedToBlueNumAxis; ++axis) {
|
||||||
green_to_blue <= max_green_to_blue &&
|
const int green_to_blue_cur =
|
||||||
num_tries_after_min < max_tries_after_min;
|
offset[axis][0] * delta + green_to_blue_best;
|
||||||
green_to_blue += step) {
|
const int red_to_blue_cur = offset[axis][1] * delta + red_to_blue_best;
|
||||||
int red_to_blue;
|
const float cur_diff = GetPredictionCostCrossColorBlue(
|
||||||
for (red_to_blue = min_red_to_blue;
|
|
||||||
red_to_blue <= max_red_to_blue &&
|
|
||||||
num_tries_after_min < max_tries_after_min;
|
|
||||||
red_to_blue += step) {
|
|
||||||
cur_diff = GetPredictionCostCrossColorBlue(
|
|
||||||
argb, stride, tile_width, tile_height, prev_x, prev_y,
|
argb, stride, tile_width, tile_height, prev_x, prev_y,
|
||||||
green_to_blue, red_to_blue, accumulated_blue_histo);
|
green_to_blue_cur, red_to_blue_cur, accumulated_blue_histo);
|
||||||
if (cur_diff < best_diff) {
|
if (cur_diff < best_diff) {
|
||||||
best_diff = cur_diff;
|
best_diff = cur_diff;
|
||||||
best_tx->green_to_blue_ = green_to_blue;
|
green_to_blue_best = green_to_blue_cur;
|
||||||
best_tx->red_to_blue_ = red_to_blue;
|
red_to_blue_best = red_to_blue_cur;
|
||||||
num_tries_after_min = 0;
|
}
|
||||||
} else {
|
if (quality < 25 && iter == 4) {
|
||||||
++num_tries_after_min;
|
// Only axis aligned diffs for lower quality.
|
||||||
|
break; // next iter.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (delta == 2 && green_to_blue_best == 0 && red_to_blue_best == 0) {
|
||||||
|
// Further iterations would not help.
|
||||||
|
break; // out of iter-loop.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
best_tx->green_to_blue_ = green_to_blue_best;
|
||||||
|
best_tx->red_to_blue_ = red_to_blue_best;
|
||||||
}
|
}
|
||||||
|
#undef kGreenRedToBlueMaxIters
|
||||||
|
#undef kGreenRedToBlueNumAxis
|
||||||
|
|
||||||
static VP8LMultipliers GetBestColorTransformForTile(
|
static VP8LMultipliers GetBestColorTransformForTile(
|
||||||
int tile_x, int tile_y, int bits,
|
int tile_x, int tile_y, int bits,
|
||||||
|
Loading…
Reference in New Issue
Block a user