Improved near-lossless mode.

Compared to previous mode it gives another 10-30% improvement in compression keeping comparable PSNR on corresponding quality settings.

Still protected by the WEBP_EXPERIMENTAL_FEATURES flag.

Change-Id: I4821815b9a508f4f38c98821acaddb74c73c60ac
This commit is contained in:
Pascal Massimino
2014-10-15 14:28:19 +02:00
committed by Gerrit Code Review
parent 0ce27e715e
commit 6c6736816c
4 changed files with 184 additions and 24 deletions

View File

@ -1214,6 +1214,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
const int height = picture->height;
VP8LEncoder* const enc = VP8LEncoderNew(config, picture);
const size_t byte_position = VP8LBitWriterNumBytes(bw);
const int use_near_lossless = !enc->use_palette_ && config->near_lossless;
int hdr_size = 0;
int data_size = 0;
@ -1230,6 +1231,13 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
goto Error;
}
// If no prediction transform just apply near-lossless preprocessing.
if (!enc->use_predict_ && use_near_lossless &&
!VP8ApplyNearLossless(width, height, picture->argb,
config->near_lossless)) {
goto Error;
}
if (enc->use_palette_) {
err = EncodePalette(bw, enc);
if (err != VP8_ENC_OK) goto Error;
@ -1256,8 +1264,39 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config,
}
if (enc->use_predict_) {
uint32_t* copy_buffer = NULL;
#ifdef WEBP_EXPERIMENTAL_FEATURES
if (use_near_lossless) {
// Copy image to temporary buffer.
int y;
copy_buffer = WebPSafeMalloc(height * enc->current_width_,
sizeof(*copy_buffer));
if (copy_buffer == NULL) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;
}
for (y = 0; y < height; ++y) {
memcpy(copy_buffer + y * enc->current_width_,
enc->argb_ + y * enc->current_width_,
enc->current_width_ * sizeof(*enc->argb_));
}
}
#endif // WEBP_EXPERIMENTAL_FEATURES
err = ApplyPredictFilter(enc, enc->current_width_, height, quality, bw);
if (err != VP8_ENC_OK) goto Error;
if (err != VP8_ENC_OK) {
WebPSafeFree(copy_buffer);
goto Error;
}
#ifdef WEBP_EXPERIMENTAL_FEATURES
if (use_near_lossless) {
VP8ApplyNearLosslessPredict(enc->current_width_, height,
enc->transform_bits_, copy_buffer, enc->argb_,
enc->argb_scratch_, enc->transform_data_,
config->near_lossless,
enc->use_subtract_green_);
WebPSafeFree(copy_buffer);
}
#endif // WEBP_EXPERIMENTAL_FEATURES
}
if (enc->use_cross_color_) {