diff options
Diffstat (limited to 'third_party/libwebp/enc/alpha.c')
-rw-r--r-- | third_party/libwebp/enc/alpha.c | 93 |
1 files changed, 65 insertions, 28 deletions
diff --git a/third_party/libwebp/enc/alpha.c b/third_party/libwebp/enc/alpha.c index 0e519b6..aadf88f 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) |