WebPAnimEncoder: Detect when canvas is modified, restore only when needed.

Change-Id: I6b45283e13c08c7d11c96500a65c75ce3637b06d
This commit is contained in:
Urvang Joshi 2016-05-23 11:17:23 -07:00
parent 0209d7e6d6
commit 08333b8551

View File

@ -703,21 +703,25 @@ static int GetColorCount(const WebPPicture* const pic) {
// For pixels in 'rect', replace those pixels in 'dst' that are same as 'src' by // For pixels in 'rect', replace those pixels in 'dst' that are same as 'src' by
// transparent pixels. // transparent pixels.
static void IncreaseTransparency(const WebPPicture* const src, // Returns true if at least one pixel gets modified.
const FrameRect* const rect, static int IncreaseTransparency(const WebPPicture* const src,
WebPPicture* const dst) { const FrameRect* const rect,
WebPPicture* const dst) {
int i, j; int i, j;
int modified = 0;
assert(src != NULL && dst != NULL && rect != NULL); assert(src != NULL && dst != NULL && rect != NULL);
assert(src->width == dst->width && src->height == dst->height); assert(src->width == dst->width && src->height == dst->height);
for (j = rect->y_offset_; j < rect->y_offset_ + rect->height_; ++j) { for (j = rect->y_offset_; j < rect->y_offset_ + rect->height_; ++j) {
const uint32_t* const psrc = src->argb + j * src->argb_stride; const uint32_t* const psrc = src->argb + j * src->argb_stride;
uint32_t* const pdst = dst->argb + j * dst->argb_stride; uint32_t* const pdst = dst->argb + j * dst->argb_stride;
for (i = rect->x_offset_; i < rect->x_offset_ + rect->width_; ++i) { for (i = rect->x_offset_; i < rect->x_offset_ + rect->width_; ++i) {
if (psrc[i] == pdst[i]) { if (psrc[i] == pdst[i] && pdst[i] != TRANSPARENT_COLOR) {
pdst[i] = TRANSPARENT_COLOR; pdst[i] = TRANSPARENT_COLOR;
modified = 1;
} }
} }
} }
return modified;
} }
#undef TRANSPARENT_COLOR #undef TRANSPARENT_COLOR
@ -725,12 +729,13 @@ static void IncreaseTransparency(const WebPPicture* const src,
// Replace similar blocks of pixels by a 'see-through' transparent block // Replace similar blocks of pixels by a 'see-through' transparent block
// with uniform average color. // with uniform average color.
// Assumes lossy compression is being used. // Assumes lossy compression is being used.
static void FlattenSimilarBlocks(const WebPPicture* const src, // Returns true if at least one pixel gets modified.
const FrameRect* const rect, static int FlattenSimilarBlocks(const WebPPicture* const src,
WebPPicture* const dst, const FrameRect* const rect,
float quality) { WebPPicture* const dst, float quality) {
const int max_allowed_diff_lossy = QualityToMaxDiff(quality); const int max_allowed_diff_lossy = QualityToMaxDiff(quality);
int i, j; int i, j;
int modified = 0;
const int block_size = 8; const int block_size = 8;
const int y_start = (rect->y_offset_ + block_size) & ~(block_size - 1); const int y_start = (rect->y_offset_ + block_size) & ~(block_size - 1);
const int y_end = (rect->y_offset_ + rect->height_) & ~(block_size - 1); const int y_end = (rect->y_offset_ + rect->height_) & ~(block_size - 1);
@ -773,9 +778,11 @@ static void FlattenSimilarBlocks(const WebPPicture* const src,
pdst[x + y * dst->argb_stride] = color; pdst[x + y * dst->argb_stride] = color;
} }
} }
modified = 1;
} }
} }
} }
return modified;
} }
static int EncodeFrame(const WebPConfig* const config, WebPPicture* const pic, static int EncodeFrame(const WebPConfig* const config, WebPPicture* const pic,
@ -900,8 +907,8 @@ static WebPEncodingError GenerateCandidates(
if (candidate_ll->evaluate_) { if (candidate_ll->evaluate_) {
CopyCurrentCanvas(enc); CopyCurrentCanvas(enc);
if (use_blending_ll) { if (use_blending_ll) {
IncreaseTransparency(prev_canvas, &params->rect_ll_, curr_canvas); enc->curr_canvas_copy_modified_ =
enc->curr_canvas_copy_modified_ = 1; IncreaseTransparency(prev_canvas, &params->rect_ll_, curr_canvas);
} }
error_code = EncodeCandidate(&params->sub_frame_ll_, &params->rect_ll_, error_code = EncodeCandidate(&params->sub_frame_ll_, &params->rect_ll_,
config_ll, use_blending_ll, candidate_ll); config_ll, use_blending_ll, candidate_ll);
@ -910,9 +917,9 @@ static WebPEncodingError GenerateCandidates(
if (candidate_lossy->evaluate_) { if (candidate_lossy->evaluate_) {
CopyCurrentCanvas(enc); CopyCurrentCanvas(enc);
if (use_blending_lossy) { if (use_blending_lossy) {
FlattenSimilarBlocks(prev_canvas, &params->rect_lossy_, curr_canvas, enc->curr_canvas_copy_modified_ =
config_lossy->quality); FlattenSimilarBlocks(prev_canvas, &params->rect_lossy_, curr_canvas,
enc->curr_canvas_copy_modified_ = 1; config_lossy->quality);
} }
error_code = error_code =
EncodeCandidate(&params->sub_frame_lossy_, &params->rect_lossy_, EncodeCandidate(&params->sub_frame_lossy_, &params->rect_lossy_,