diff options
Diffstat (limited to 'src/3rdparty/libwebp/src/enc/alpha.c')
-rw-r--r-- | src/3rdparty/libwebp/src/enc/alpha.c | 61 |
1 files changed, 29 insertions, 32 deletions
diff --git a/src/3rdparty/libwebp/src/enc/alpha.c b/src/3rdparty/libwebp/src/enc/alpha.c index 79cb94d..3c970b0 100644 --- a/src/3rdparty/libwebp/src/enc/alpha.c +++ b/src/3rdparty/libwebp/src/enc/alpha.c @@ -15,6 +15,7 @@ #include <stdlib.h> #include "./vp8enci.h" +#include "../dsp/dsp.h" #include "../utils/filters.h" #include "../utils/quant_levels.h" #include "../utils/utils.h" @@ -61,21 +62,16 @@ static int EncodeLossless(const uint8_t* const data, int width, int height, if (!WebPPictureAlloc(&picture)) return 0; // Transfer the alpha values to the green channel. - { - int i, j; - uint32_t* dst = picture.argb; - const uint8_t* src = data; - for (j = 0; j < picture.height; ++j) { - for (i = 0; i < picture.width; ++i) { - dst[i] = src[i] << 8; // we leave A/R/B channels zero'd. - } - src += width; - dst += picture.argb_stride; - } - } + WebPDispatchAlphaToGreen(data, width, picture.width, picture.height, + picture.argb, picture.argb_stride); WebPConfigInit(&config); config.lossless = 1; + // Enable exact, or it would alter RGB values of transparent alpha, which is + // normally OK but not here since we are not encoding the input image but an + // internal encoding-related image containing necessary exact information in + // RGB channels. + config.exact = 1; config.method = effort_level; // impact is very small // Set a low default quality for encoding alpha. Ensure that Alpha quality at // lower methods (3 and below) is less than the threshold for triggering @@ -87,11 +83,10 @@ static int EncodeLossless(const uint8_t* const data, int width, int height, WebPPictureFree(&picture); ok = ok && !bw->error_; if (!ok) { - VP8LBitWriterDestroy(bw); + VP8LBitWriterWipeOut(bw); return 0; } return 1; - } // ----------------------------------------------------------------------------- @@ -143,10 +138,10 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, if (output_size > data_size) { // compressed size is larger than source! Revert to uncompressed mode. method = ALPHA_NO_COMPRESSION; - VP8LBitWriterDestroy(&tmp_bw); + VP8LBitWriterWipeOut(&tmp_bw); } } else { - VP8LBitWriterDestroy(&tmp_bw); + VP8LBitWriterWipeOut(&tmp_bw); return 0; } } @@ -166,7 +161,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, ok = ok && VP8BitWriterAppend(&result->bw, output, output_size); if (method != ALPHA_NO_COMPRESSION) { - VP8LBitWriterDestroy(&tmp_bw); + VP8LBitWriterWipeOut(&tmp_bw); } ok = ok && !result->bw.error_; result->score = VP8BitWriterSize(&result->bw); @@ -175,16 +170,6 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height, // ----------------------------------------------------------------------------- -// TODO(skal): move to dsp/ ? -static void CopyPlane(const uint8_t* src, int src_stride, - uint8_t* dst, int dst_stride, int width, int height) { - while (height-- > 0) { - memcpy(dst, src, width); - src += src_stride; - dst += dst_stride; - } -} - static int GetNumColors(const uint8_t* data, int width, int height, int stride) { int j; @@ -218,8 +203,9 @@ static uint32_t GetFilterMap(const uint8_t* alpha, int width, int height, const int kMaxColorsForFilterNone = 192; const int num_colors = GetNumColors(alpha, width, height, width); // For low number of colors, NONE yields better compression. - filter = (num_colors <= kMinColorsForFilterNone) ? WEBP_FILTER_NONE : - EstimateBestFilter(alpha, width, height, width); + filter = (num_colors <= kMinColorsForFilterNone) + ? WEBP_FILTER_NONE + : WebPEstimateBestFilter(alpha, width, height, width); bit_map |= 1 << filter; // For large number of colors, try FILTER_NONE in addition to the best // filter as well. @@ -250,6 +236,7 @@ static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height, uint32_t try_map = GetFilterMap(alpha, width, height, filter, effort_level); InitFilterTrial(&best); + if (try_map != FILTER_TRY_NONE) { uint8_t* filtered_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size); if (filtered_alpha == NULL) return 0; @@ -274,7 +261,16 @@ static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height, reduce_levels, effort_level, NULL, &best); } if (ok) { - if (stats != NULL) *stats = best.stats; + if (stats != NULL) { + stats->lossless_features = best.stats.lossless_features; + stats->histogram_bits = best.stats.histogram_bits; + stats->transform_bits = best.stats.transform_bits; + stats->cache_bits = best.stats.cache_bits; + stats->palette_size = best.stats.palette_size; + stats->lossless_size = best.stats.lossless_size; + stats->lossless_hdr_size = best.stats.lossless_hdr_size; + stats->lossless_data_size = best.stats.lossless_data_size; + } *output_size = VP8BitWriterSize(&best.bw); *output = VP8BitWriterBuf(&best.bw); } else { @@ -324,7 +320,7 @@ static int EncodeAlpha(VP8Encoder* const enc, } // Extract alpha data (width x height) from raw_data (stride x height). - CopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height); + WebPCopyPlane(pic->a, pic->a_stride, quant_alpha, width, width, height); if (reduce_levels) { // No Quantization required for 'quality = 100'. // 16 alpha levels gives quite a low MSE w.r.t original alpha plane hence @@ -336,6 +332,7 @@ static int EncodeAlpha(VP8Encoder* const enc, } if (ok) { + VP8FiltersInit(); ok = ApplyFiltersAndEncode(quant_alpha, width, height, data_size, method, filter, reduce_levels, effort_level, output, output_size, pic->stats); @@ -376,6 +373,7 @@ static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) { } void VP8EncInitAlpha(VP8Encoder* const enc) { + WebPInitAlphaProcessing(); enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_); enc->alpha_data_ = NULL; enc->alpha_data_size_ = 0; @@ -430,4 +428,3 @@ int VP8EncDeleteAlpha(VP8Encoder* const enc) { enc->has_alpha_ = 0; return ok; } - |