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) |