summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYannis Guyon <yguyon@google.com>2018-09-25 13:02:30 +0200
committerYannis Guyon <yguyon@google.com>2018-10-01 10:14:51 +0200
commitb2a867c03812bfbb4dbe04bbe349788436e6d68c (patch)
tree9878855bfba0fc85429e1ffdbb1d4bb268e326b3
parent637141bc7cd0fa9eaea2d8b6b5e3bb69bf846ca9 (diff)
downloadlibwebp-b2a867c03812bfbb4dbe04bbe349788436e6d68c.tar.gz
cwebp: Don't premultiply during -resize if -exact
Fix issue where color data is discarded in fully transparent areas when -resize -exact. BUG=webp:397 Change-Id: I58ce8d5ae172d5d0f0138e07c7df3a3c6cbd0019
-rw-r--r--examples/cwebp.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/examples/cwebp.c b/examples/cwebp.c
index 3b1e1171..7b1836d3 100644
--- a/examples/cwebp.c
+++ b/examples/cwebp.c
@@ -1012,10 +1012,53 @@ int main(int argc, const char *argv[]) {
}
}
if ((resize_w | resize_h) > 0) {
+ WebPPicture picture_no_alpha;
+ if (config.exact) {
+ // If -exact, we can't premultiply RGB by A otherwise RGB is lost if A=0.
+ // We rescale an opaque copy and assemble scaled A and non-premultiplied
+ // RGB channels. This is slower but it's a very uncommon use case. Color
+ // leak at sharp alpha edges is possible.
+ if (!WebPPictureCopy(&picture, &picture_no_alpha)) {
+ fprintf(stderr, "Error! Cannot copy temporary picture\n");
+ goto Error;
+ }
+
+ // We enforced picture.use_argb = 1 above. Now, remove the alpha values.
+ {
+ int x, y;
+ uint32_t* argb_no_alpha = picture_no_alpha.argb;
+ for (y = 0; y < picture_no_alpha.height; ++y) {
+ for (x = 0; x < picture_no_alpha.width; ++x) {
+ argb_no_alpha[x] |= 0xff000000; // Opaque copy.
+ }
+ argb_no_alpha += picture_no_alpha.argb_stride;
+ }
+ }
+
+ if (!WebPPictureRescale(&picture_no_alpha, resize_w, resize_h)) {
+ fprintf(stderr, "Error! Cannot resize temporary picture\n");
+ goto Error;
+ }
+ }
+
if (!WebPPictureRescale(&picture, resize_w, resize_h)) {
fprintf(stderr, "Error! Cannot resize picture\n");
goto Error;
}
+
+ if (config.exact) { // Put back the alpha information.
+ int x, y;
+ uint32_t* argb_no_alpha = picture_no_alpha.argb;
+ uint32_t* argb = picture.argb;
+ for (y = 0; y < picture_no_alpha.height; ++y) {
+ for (x = 0; x < picture_no_alpha.width; ++x) {
+ argb[x] = (argb[x] & 0xff000000) | (argb_no_alpha[x] & 0x00ffffff);
+ }
+ argb_no_alpha += picture_no_alpha.argb_stride;
+ argb += picture.argb_stride;
+ }
+ WebPPictureFree(&picture_no_alpha);
+ }
}
if (verbose && (crop != 0 || (resize_w | resize_h) > 0)) {
const double preproc_time = StopwatchReadAndReset(&stop_watch);