| Index: third_party/libwebp/enc/alpha.c
|
| diff --git a/third_party/libwebp/enc/alpha.c b/third_party/libwebp/enc/alpha.c
|
| index 0e519b6c660a5a9f46f1485d492215d4e2093d3b..aadf88fef7ae5ff87df4924fd0a43a7e6e60e400 100644
|
| --- a/third_party/libwebp/enc/alpha.c
|
| +++ b/third_party/libwebp/enc/alpha.c
|
| @@ -79,18 +79,17 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
|
| WebPConfigInit(&config);
|
| config.lossless = 1;
|
| config.method = effort_level; // impact is very small
|
| - // Set moderate default quality setting for alpha. Higher qualities (80 and
|
| - // above) could be very slow.
|
| - config.quality = 10.f + 15.f * effort_level;
|
| - if (config.quality > 100.f) config.quality = 100.f;
|
| + // Set a moderate default quality setting for alpha.
|
| + config.quality = 5.f * effort_level;
|
| + assert(config.quality >= 0 && config.quality <= 100.f);
|
|
|
| ok = VP8LBitWriterInit(&tmp_bw, (width * height) >> 3);
|
| ok = ok && (VP8LEncodeStream(&config, &picture, &tmp_bw) == VP8_ENC_OK);
|
| WebPPictureFree(&picture);
|
| if (ok) {
|
| - const uint8_t* const data = VP8LBitWriterFinish(&tmp_bw);
|
| - const size_t data_size = VP8LBitWriterNumBytes(&tmp_bw);
|
| - VP8BitWriterAppend(bw, data, data_size);
|
| + const uint8_t* const buffer = VP8LBitWriterFinish(&tmp_bw);
|
| + const size_t buffer_size = VP8LBitWriterNumBytes(&tmp_bw);
|
| + VP8BitWriterAppend(bw, buffer, buffer_size);
|
| }
|
| VP8LBitWriterDestroy(&tmp_bw);
|
| return ok && !bw->error_;
|
| @@ -128,8 +127,8 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
| VP8BitWriterAppend(bw, &header, ALPHA_HEADER_LEN);
|
|
|
| filter_func = WebPFilters[filter];
|
| - if (filter_func) {
|
| - filter_func(data, width, height, 1, width, tmp_alpha);
|
| + if (filter_func != NULL) {
|
| + filter_func(data, width, height, width, tmp_alpha);
|
| alpha_src = tmp_alpha;
|
| } else {
|
| alpha_src = data;
|
| @@ -287,42 +286,80 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
| //------------------------------------------------------------------------------
|
| // Main calls
|
|
|
| +static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) {
|
| + const WebPConfig* config = enc->config_;
|
| + uint8_t* alpha_data = NULL;
|
| + size_t alpha_size = 0;
|
| + const int effort_level = config->method; // maps to [0..6]
|
| + const WEBP_FILTER_TYPE filter =
|
| + (config->alpha_filtering == 0) ? WEBP_FILTER_NONE :
|
| + (config->alpha_filtering == 1) ? WEBP_FILTER_FAST :
|
| + WEBP_FILTER_BEST;
|
| + if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression,
|
| + filter, effort_level, &alpha_data, &alpha_size)) {
|
| + return 0;
|
| + }
|
| + if (alpha_size != (uint32_t)alpha_size) { // Sanity check.
|
| + free(alpha_data);
|
| + return 0;
|
| + }
|
| + enc->alpha_data_size_ = (uint32_t)alpha_size;
|
| + enc->alpha_data_ = alpha_data;
|
| + (void)dummy;
|
| + return 1;
|
| +}
|
| +
|
| void VP8EncInitAlpha(VP8Encoder* const enc) {
|
| enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_);
|
| enc->alpha_data_ = NULL;
|
| enc->alpha_data_size_ = 0;
|
| + if (enc->thread_level_ > 0) {
|
| + WebPWorker* const worker = &enc->alpha_worker_;
|
| + WebPWorkerInit(worker);
|
| + worker->data1 = enc;
|
| + worker->data2 = NULL;
|
| + worker->hook = (WebPWorkerHook)CompressAlphaJob;
|
| + }
|
| }
|
|
|
| -int VP8EncFinishAlpha(VP8Encoder* const enc) {
|
| +int VP8EncStartAlpha(VP8Encoder* const enc) {
|
| if (enc->has_alpha_) {
|
| - const WebPConfig* config = enc->config_;
|
| - uint8_t* tmp_data = NULL;
|
| - size_t tmp_size = 0;
|
| - const int effort_level = config->method; // maps to [0..6]
|
| - const WEBP_FILTER_TYPE filter =
|
| - (config->alpha_filtering == 0) ? WEBP_FILTER_NONE :
|
| - (config->alpha_filtering == 1) ? WEBP_FILTER_FAST :
|
| - WEBP_FILTER_BEST;
|
| -
|
| - if (!EncodeAlpha(enc, config->alpha_quality, config->alpha_compression,
|
| - filter, effort_level, &tmp_data, &tmp_size)) {
|
| - return 0;
|
| + if (enc->thread_level_ > 0) {
|
| + WebPWorker* const worker = &enc->alpha_worker_;
|
| + if (!WebPWorkerReset(worker)) { // Makes sure worker is good to go.
|
| + return 0;
|
| + }
|
| + WebPWorkerLaunch(worker);
|
| + return 1;
|
| + } else {
|
| + return CompressAlphaJob(enc, NULL); // just do the job right away
|
| }
|
| - if (tmp_size != (uint32_t)tmp_size) { // Sanity check.
|
| - free(tmp_data);
|
| - return 0;
|
| + }
|
| + return 1;
|
| +}
|
| +
|
| +int VP8EncFinishAlpha(VP8Encoder* const enc) {
|
| + if (enc->has_alpha_) {
|
| + if (enc->thread_level_ > 0) {
|
| + WebPWorker* const worker = &enc->alpha_worker_;
|
| + if (!WebPWorkerSync(worker)) return 0; // error
|
| }
|
| - enc->alpha_data_size_ = (uint32_t)tmp_size;
|
| - enc->alpha_data_ = tmp_data;
|
| }
|
| return WebPReportProgress(enc->pic_, enc->percent_ + 20, &enc->percent_);
|
| }
|
|
|
| -void VP8EncDeleteAlpha(VP8Encoder* const enc) {
|
| +int VP8EncDeleteAlpha(VP8Encoder* const enc) {
|
| + int ok = 1;
|
| + if (enc->thread_level_ > 0) {
|
| + WebPWorker* const worker = &enc->alpha_worker_;
|
| + ok = WebPWorkerSync(worker); // finish anything left in flight
|
| + WebPWorkerEnd(worker); // still need to end the worker, even if !ok
|
| + }
|
| free(enc->alpha_data_);
|
| enc->alpha_data_ = NULL;
|
| enc->alpha_data_size_ = 0;
|
| enc->has_alpha_ = 0;
|
| + return ok;
|
| }
|
|
|
| #if defined(__cplusplus) || defined(c_plusplus)
|
|
|