mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-28 14:38:21 +01:00
lossless: Remove about 25 % of the speed degradation
introduced in: "lossless: 0.37 % compression density improvement" Uses the statistics of red and blue histograms to decide if to run cross color correction at all. Improves compression density by 0.02 % or so. Change-Id: I47429557e9cdbd9fa90c584696f241b17427d73f
This commit is contained in:
parent
2cce031704
commit
d92453f381
@ -210,7 +210,9 @@ typedef enum {
|
|||||||
|
|
||||||
static int AnalyzeEntropy(const uint32_t* argb,
|
static int AnalyzeEntropy(const uint32_t* argb,
|
||||||
int width, int height, int argb_stride,
|
int width, int height, int argb_stride,
|
||||||
double entropy[kNumEntropyIx]) {
|
int use_palette,
|
||||||
|
EntropyIx* const min_entropy_ix,
|
||||||
|
int* const red_and_blue_always_zero) {
|
||||||
// Allocate histogram set with cache_bits = 0.
|
// Allocate histogram set with cache_bits = 0.
|
||||||
VP8LHistogramSet* const histo_set = VP8LAllocateHistogramSet(5, 0);
|
VP8LHistogramSet* const histo_set = VP8LAllocateHistogramSet(5, 0);
|
||||||
if (histo_set != NULL) {
|
if (histo_set != NULL) {
|
||||||
@ -242,8 +244,29 @@ static int AnalyzeEntropy(const uint32_t* argb,
|
|||||||
prev_row = curr_row;
|
prev_row = curr_row;
|
||||||
curr_row += argb_stride;
|
curr_row += argb_stride;
|
||||||
}
|
}
|
||||||
for (i = 0; i < kNumEntropyIx; ++i) {
|
{
|
||||||
entropy[i] = VP8LHistogramEstimateBitsBulk(histo[i]);
|
double entropy[kNumEntropyIx];
|
||||||
|
EntropyIx k;
|
||||||
|
EntropyIx last_mode_to_analyze =
|
||||||
|
use_palette ? kPalette : kSpatialSubGreen;
|
||||||
|
*min_entropy_ix = kDirect;
|
||||||
|
for (k = kDirect; k <= last_mode_to_analyze; ++k) {
|
||||||
|
entropy[k] = VP8LHistogramEstimateBitsBulk(histo[k]);
|
||||||
|
if (k == kDirect || entropy[*min_entropy_ix] >= entropy[k]) {
|
||||||
|
*min_entropy_ix = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*red_and_blue_always_zero = 1;
|
||||||
|
// Let's check if the histogram of the chosen entropy mode has
|
||||||
|
// non-zero red and blue values. If all are zero, we can later skip
|
||||||
|
// the cross color optimization.
|
||||||
|
for (i = 1; i < 256; ++i) {
|
||||||
|
if ((histo[*min_entropy_ix]->red_[i] |
|
||||||
|
histo[*min_entropy_ix]->blue_[i]) != 0) {
|
||||||
|
*red_and_blue_always_zero = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
VP8LFreeHistogramSet(histo_set);
|
VP8LFreeHistogramSet(histo_set);
|
||||||
return 1;
|
return 1;
|
||||||
@ -301,26 +324,19 @@ static int AnalyzeAndInit(VP8LEncoder* const enc) {
|
|||||||
enc->use_subtract_green_ = !enc->use_palette_;
|
enc->use_subtract_green_ = !enc->use_palette_;
|
||||||
enc->use_cross_color_ = 0;
|
enc->use_cross_color_ = 0;
|
||||||
} else {
|
} else {
|
||||||
double entropy[kNumEntropyIx];
|
int red_and_blue_always_zero;
|
||||||
EntropyIx min_entropy_ix = kDirect;
|
EntropyIx min_entropy_ix;
|
||||||
EntropyIx i = kDirect;
|
|
||||||
EntropyIx last_mode_to_analyze;
|
|
||||||
if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride,
|
if (!AnalyzeEntropy(pic->argb, width, height, pic->argb_stride,
|
||||||
&entropy[0])) {
|
enc->use_palette_, &min_entropy_ix,
|
||||||
|
&red_and_blue_always_zero)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
entropy[kPalette] -= 10.; // Small bias in favor of using the palette.
|
|
||||||
last_mode_to_analyze = enc->use_palette_ ? kPalette : kSpatialSubGreen;
|
|
||||||
for (i = 1; i <= last_mode_to_analyze; ++i) {
|
|
||||||
if (entropy[min_entropy_ix] > entropy[i]) {
|
|
||||||
min_entropy_ix = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
enc->use_palette_ = (min_entropy_ix == kPalette);
|
enc->use_palette_ = (min_entropy_ix == kPalette);
|
||||||
enc->use_subtract_green_ =
|
enc->use_subtract_green_ =
|
||||||
(min_entropy_ix == kSubGreen) || (min_entropy_ix == kSpatialSubGreen);
|
(min_entropy_ix == kSubGreen) || (min_entropy_ix == kSpatialSubGreen);
|
||||||
enc->use_cross_color_ = enc->use_predict_ =
|
enc->use_predict_ =
|
||||||
(min_entropy_ix == kSpatial) || (min_entropy_ix == kSpatialSubGreen);
|
(min_entropy_ix == kSpatial) || (min_entropy_ix == kSpatialSubGreen);
|
||||||
|
enc->use_cross_color_ = red_and_blue_always_zero ? 0 : enc->use_predict_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!VP8LHashChainInit(&enc->hash_chain_, pix_cnt)) return 0;
|
if (!VP8LHashChainInit(&enc->hash_chain_, pix_cnt)) return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user