From 04c7a2ecf08000cab3d9d841a584e1f087c56777 Mon Sep 17 00:00:00 2001 From: James Zern Date: Sat, 23 Mar 2013 12:45:11 -0700 Subject: [PATCH] vwebp/animation: fix background dispose buffer the last frame's details to perform DISPOSE_BACKGROUND on the image's area, rather than the entire canvas. also fixes transparent backgrounds with animated images Change-Id: I53e4d70c441e1eeb136f1d01e7c88de4f9ecff53 --- examples/vwebp.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/examples/vwebp.c b/examples/vwebp.c index 312649b9..8fe49acd 100644 --- a/examples/vwebp.c +++ b/examples/vwebp.c @@ -62,6 +62,11 @@ static struct { const WebPDecBuffer* pic; WebPDemuxer* dmux; WebPIterator frameiter; + struct { + int width, height; + int x_offset, y_offset; + enum WebPMuxAnimDispose dispose_method; + } prev_frame; WebPChunkIterator iccp; } kParams; @@ -287,9 +292,31 @@ static void HandleDisplay(void) { glRasterPos2f(-1.f + xoff, 1.f - yoff); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, pic->u.RGBA.stride / 4); - if (iter->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { + + if (kParams.prev_frame.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND) { + // TODO(later): these offsets and those above should factor in window size. + // they will be incorrect if the window is resized. + // glScissor() takes window coordinates (0,0 at bottom left). + const int window_x = kParams.prev_frame.x_offset; + const int window_y = kParams.canvas_height - + kParams.prev_frame.y_offset - + kParams.prev_frame.height; + glEnable(GL_SCISSOR_TEST); + // Only updated the requested area, not the whole canvas. + glScissor(window_x, window_y, + kParams.prev_frame.width, kParams.prev_frame.height); + glClear(GL_COLOR_BUFFER_BIT); // use clear color + DrawCheckerBoard(); + + glDisable(GL_SCISSOR_TEST); } + kParams.prev_frame.width = iter->width; + kParams.prev_frame.height = iter->height; + kParams.prev_frame.x_offset = iter->x_offset; + kParams.prev_frame.y_offset = iter->y_offset; + kParams.prev_frame.dispose_method = iter->dispose_method; + glDrawPixels(pic->width, pic->height, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pic->u.RGBA.rgba); @@ -426,6 +453,11 @@ int main(int argc, char *argv[]) { printf("Canvas: %d x %d\n", kParams.canvas_width, kParams.canvas_height); } + kParams.prev_frame.width = kParams.canvas_width; + kParams.prev_frame.height = kParams.canvas_height; + kParams.prev_frame.x_offset = kParams.prev_frame.y_offset = 0; + kParams.prev_frame.dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; + memset(&kParams.iccp, 0, sizeof(kParams.iccp)); kParams.has_color_profile = !!(WebPDemuxGetI(kParams.dmux, WEBP_FF_FORMAT_FLAGS) & ICCP_FLAG);