From 437999fb77db5e915da685bbc8b8d9f48d8e77ee Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Mon, 4 Jun 2012 15:50:05 -0700 Subject: [PATCH] introduce a generic WebPPictureHasTransparency() function VP8-lossy will now avoid writing an ALPH chunk if the alpha values are trivial. + changed DumpPicture() accordingly in cwebp + prevented the -d option to be active with lossless (DumpPicture wouldn't work). Change-Id: I34fdb108a2b6207e93fa6cd00b1d2509a8e1dc4b --- examples/cwebp.c | 9 +++++++-- src/enc/alpha.c | 2 +- src/enc/picture.c | 27 +++++++++++++++++++++++++++ src/enc/vp8l.c | 11 +---------- src/webp/encode.h | 5 +++++ 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/examples/cwebp.c b/examples/cwebp.c index 09c788de..53f6302e 100644 --- a/examples/cwebp.c +++ b/examples/cwebp.c @@ -650,7 +650,8 @@ static int DumpPicture(const WebPPicture* const picture, const char* PGM_name) { const int uv_width = (picture->width + 1) / 2; const int uv_height = (picture->height + 1) / 2; const int stride = (picture->width + 1) & ~1; - const int alpha_height = picture->a ? picture->height : 0; + const int alpha_height = + WebPPictureHasTransparency(picture) ? picture->height : 0; const int height = picture->height + uv_height + alpha_height; FILE* const f = fopen(PGM_name, "wb"); if (f == NULL) return 0; @@ -1035,7 +1036,11 @@ int main(int argc, const char *argv[]) { // Write info if (dump_file) { - DumpPicture(&picture, dump_file); + if (picture.use_argb_input) { + fprintf(stderr, "Warning: can't dump file (-d option) in lossless mode."); + } else if (!DumpPicture(&picture, dump_file)) { + fprintf(stderr, "Warning, couldn't dump picture %s\n", dump_file); + } } if (!quiet) { diff --git a/src/enc/alpha.c b/src/enc/alpha.c index ce5f3e8f..b7e4ce16 100644 --- a/src/enc/alpha.c +++ b/src/enc/alpha.c @@ -281,7 +281,7 @@ static int EncodeAlpha(const uint8_t* data, int width, int height, int stride, // Main calls void VP8EncInitAlpha(VP8Encoder* enc) { - enc->has_alpha_ = (enc->pic_->a != NULL); + enc->has_alpha_ = WebPPictureHasTransparency(enc->pic_); enc->alpha_data_ = NULL; enc->alpha_data_size_ = 0; } diff --git a/src/enc/picture.c b/src/enc/picture.c index 34d2758c..b177eef0 100644 --- a/src/enc/picture.c +++ b/src/enc/picture.c @@ -669,6 +669,33 @@ void WebPCleanupTransparentArea(WebPPicture* const pic) { #undef SIZE #undef SIZE2 +// Checking for the presence of non-opaque alpha. +int WebPPictureHasTransparency(const WebPPicture* const pic) { + if (pic == NULL) return 0; + if (!pic->use_argb_input) { + int x, y; + const uint8_t* alpha = pic->a; + if (alpha == NULL) return 0; + for (y = 0; y < pic->height; ++y) { + for (x = 0; x < pic->width; ++x) { + if (alpha[x] != 0xff) return 1; + } + alpha += pic->a_stride; + } + } else { + int x, y; + const uint32_t* argb = pic->argb; + if (argb == NULL) return 1; + for (y = 0; y < pic->height; ++y) { + for (x = 0; x < pic->width; ++x) { + if (argb[x] < 0xff000000) return 1; // test any alpha values != 0xff + } + argb += pic->argb_stride; + } + } + return 0; +} + //------------------------------------------------------------------------------ // Distortion diff --git a/src/enc/vp8l.c b/src/enc/vp8l.c index f8297a6d..ee113273 100644 --- a/src/enc/vp8l.c +++ b/src/enc/vp8l.c @@ -42,15 +42,6 @@ static int CompareColors(const void* p1, const void* p2) { return (a < b) ? -1 : (a > b) ? 1 : 0; } -static int HasRealAlpha(const uint32_t* const argb, int num_pix) { - int i; - for (i = 0; i < num_pix; ++i) { - // Checking for the presence of non-opaque alpha. - if (argb[i] < ARGB_BLACK) return 1; - } - return 0; -} - // If number of colors in the image is less than or equal to MAX_PALETTE_SIZE, // creates a palette and returns true, else returns false. static int AnalyzeAndCreatePalette(const uint32_t* const argb, int num_pix, @@ -983,7 +974,7 @@ int VP8LEncodeImage(const WebPConfig* const config, goto Error; } - has_alpha = HasRealAlpha(picture->argb, width * height); + has_alpha = WebPPictureHasTransparency(picture); // Write the non-trivial Alpha flag and lossless version. if (!WriteRealAlphaAndVersion(&bw, has_alpha)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; diff --git a/src/webp/encode.h b/src/webp/encode.h index 28a1d6bf..3b00bdc2 100644 --- a/src/webp/encode.h +++ b/src/webp/encode.h @@ -293,6 +293,11 @@ WEBP_EXTERN(int) WebPPictureImportBGRA( // area, to help compressibility (no guarantee, though). WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* const picture); +// Scan the picture 'pic' for the presence of non fully opaque alpha values. +// Returns true in such case. Otherwise returns false (indicating that the +// alpha plane can be ignored altogether e.g.). +WEBP_EXTERN(int) WebPPictureHasTransparency(const WebPPicture* const pic); + //------------------------------------------------------------------------------ // Main call