| Index: third_party/libwebp/enc/alpha.c
|
| diff --git a/third_party/libwebp/enc/alpha.c b/third_party/libwebp/enc/alpha.c
|
| index 4eb1cdc8cb2980ba3ba8319bd1337e93830a1a9d..79cb94dbdcc54149c09597a042dd23c99c8dc481 100644
|
| --- a/third_party/libwebp/enc/alpha.c
|
| +++ b/third_party/libwebp/enc/alpha.c
|
| @@ -47,12 +47,11 @@
|
|
|
| static int EncodeLossless(const uint8_t* const data, int width, int height,
|
| int effort_level, // in [0..6] range
|
| - VP8BitWriter* const bw,
|
| + VP8LBitWriter* const bw,
|
| WebPAuxStats* const stats) {
|
| int ok = 0;
|
| WebPConfig config;
|
| WebPPicture picture;
|
| - VP8LBitWriter tmp_bw;
|
|
|
| WebPPictureInit(&picture);
|
| picture.width = width;
|
| @@ -84,16 +83,15 @@ static int EncodeLossless(const uint8_t* const data, int width, int height,
|
| config.quality = 8.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);
|
| + ok = (VP8LEncodeStream(&config, &picture, bw) == VP8_ENC_OK);
|
| WebPPictureFree(&picture);
|
| - if (ok) {
|
| - const uint8_t* const buffer = VP8LBitWriterFinish(&tmp_bw);
|
| - const size_t buffer_size = VP8LBitWriterNumBytes(&tmp_bw);
|
| - VP8BitWriterAppend(bw, buffer, buffer_size);
|
| + ok = ok && !bw->error_;
|
| + if (!ok) {
|
| + VP8LBitWriterDestroy(bw);
|
| + return 0;
|
| }
|
| - VP8LBitWriterDestroy(&tmp_bw);
|
| - return ok && !bw->error_;
|
| + return 1;
|
| +
|
| }
|
|
|
| // -----------------------------------------------------------------------------
|
| @@ -115,8 +113,10 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
| const uint8_t* alpha_src;
|
| WebPFilterFunc filter_func;
|
| uint8_t header;
|
| - size_t expected_size;
|
| const size_t data_size = width * height;
|
| + const uint8_t* output = NULL;
|
| + size_t output_size = 0;
|
| + VP8LBitWriter tmp_bw;
|
|
|
| assert((uint64_t)data_size == (uint64_t)width * height); // as per spec
|
| assert(filter >= 0 && filter < WEBP_FILTER_LAST);
|
| @@ -125,15 +125,6 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
| assert(sizeof(header) == ALPHA_HEADER_LEN);
|
| // TODO(skal): have a common function and #define's to validate alpha params.
|
|
|
| - expected_size =
|
| - (method == ALPHA_NO_COMPRESSION) ? (ALPHA_HEADER_LEN + data_size)
|
| - : (data_size >> 5);
|
| - header = method | (filter << 2);
|
| - if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
|
| -
|
| - VP8BitWriterInit(&result->bw, expected_size);
|
| - VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN);
|
| -
|
| filter_func = WebPFilters[filter];
|
| if (filter_func != NULL) {
|
| filter_func(data, width, height, width, tmp_alpha);
|
| @@ -142,14 +133,42 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
|
| alpha_src = data;
|
| }
|
|
|
| + if (method != ALPHA_NO_COMPRESSION) {
|
| + ok = VP8LBitWriterInit(&tmp_bw, data_size >> 3);
|
| + ok = ok && EncodeLossless(alpha_src, width, height, effort_level,
|
| + &tmp_bw, &result->stats);
|
| + if (ok) {
|
| + output = VP8LBitWriterFinish(&tmp_bw);
|
| + output_size = VP8LBitWriterNumBytes(&tmp_bw);
|
| + if (output_size > data_size) {
|
| + // compressed size is larger than source! Revert to uncompressed mode.
|
| + method = ALPHA_NO_COMPRESSION;
|
| + VP8LBitWriterDestroy(&tmp_bw);
|
| + }
|
| + } else {
|
| + VP8LBitWriterDestroy(&tmp_bw);
|
| + return 0;
|
| + }
|
| + }
|
| +
|
| if (method == ALPHA_NO_COMPRESSION) {
|
| - ok = VP8BitWriterAppend(&result->bw, alpha_src, width * height);
|
| - ok = ok && !result->bw.error_;
|
| - } else {
|
| - ok = EncodeLossless(alpha_src, width, height, effort_level,
|
| - &result->bw, &result->stats);
|
| - VP8BitWriterFinish(&result->bw);
|
| + output = alpha_src;
|
| + output_size = data_size;
|
| + ok = 1;
|
| + }
|
| +
|
| + // Emit final result.
|
| + header = method | (filter << 2);
|
| + if (reduce_levels) header |= ALPHA_PREPROCESSED_LEVELS << 4;
|
| +
|
| + VP8BitWriterInit(&result->bw, ALPHA_HEADER_LEN + output_size);
|
| + ok = ok && VP8BitWriterAppend(&result->bw, &header, ALPHA_HEADER_LEN);
|
| + ok = ok && VP8BitWriterAppend(&result->bw, output, output_size);
|
| +
|
| + if (method != ALPHA_NO_COMPRESSION) {
|
| + VP8LBitWriterDestroy(&tmp_bw);
|
| }
|
| + ok = ok && !result->bw.error_;
|
| result->score = VP8BitWriterSize(&result->bw);
|
| return ok;
|
| }
|
|
|