summaryrefslogtreecommitdiffstats
path: root/third_party/libwebp/enc/alpha.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebp/enc/alpha.c')
-rw-r--r--third_party/libwebp/enc/alpha.c93
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)