WebPAnimEncoder: Restore original canvas between multiple encodes.

tl;dr
We do the following:
- Start with transparent value of 0x00000000 instead of 0x00ffffff, so that
WebPCleanupTransparentAreaLossless() is a no-op.
- Restore the original canvas after lossy encoding, to discard changes made by
WebPCleanupTransparentArea() before the next encode.

Explanation of why:
In the mixed mode, anim_encoder tries to encode using both lossless and lossy
compression. In fact, when "min_size" option is enabled, there are at most 4
encodes that can happen in this order:
- lossless with dispose none
- lossy with dispose none
- lossless with dispose background
- lossy with dispose background

But both lossless and lossy both potentially modify the canvas during encode
(for better compression):
- Lossless: WebPCleanupTransparentAreaLossless() turns all transparent pixels
to 0x00000000
- Lossy: WebPCleanupTransparentArea() flattens some transparent pixels

So, the result is that, sometimes we feed the modified canvas to the encoder
instead of the original one, which isn't the right thing to do.

This also applies to just lossless or just lossy encoding, as multiple encodes
happen (with the two dispose methods) in those cases too.

Change-Id: Idfa8ce831a1627014785ba7d0316c42f72594455
This commit is contained in:
Urvang Joshi 2016-05-20 15:07:50 -07:00
parent 169004b1d5
commit f25c4406e6

View File

@ -190,7 +190,8 @@ int WebPAnimEncoderOptionsInitInternal(WebPAnimEncoderOptions* enc_options,
return 1; return 1;
} }
#define TRANSPARENT_COLOR 0x00ffffff // This starting value is more fit to WebPCleanupTransparentAreaLossless().
#define TRANSPARENT_COLOR 0x00000000
static void ClearRectangle(WebPPicture* const picture, static void ClearRectangle(WebPPicture* const picture,
int left, int top, int width, int height) { int left, int top, int width, int height) {
@ -865,6 +866,7 @@ static WebPEncodingError GenerateCandidates(
EncodeCandidate(&params->sub_frame_lossy_, &params->rect_lossy_, EncodeCandidate(&params->sub_frame_lossy_, &params->rect_lossy_,
config_lossy, use_blending_lossy, candidate_lossy); config_lossy, use_blending_lossy, candidate_lossy);
if (error_code != VP8_ENC_OK) return error_code; if (error_code != VP8_ENC_OK) return error_code;
enc->curr_canvas_copy_modified_ = 1;
} }
return error_code; return error_code;
} }