diff --git a/src/enc/picture_tools.c b/src/enc/picture_tools.c index 7c736463..bf97af84 100644 --- a/src/enc/picture_tools.c +++ b/src/enc/picture_tools.c @@ -11,6 +11,8 @@ // // Author: Skal (pascal.massimino@gmail.com) +#include + #include "./vp8enci.h" #include "../dsp/yuv.h" @@ -120,6 +122,24 @@ void WebPCleanupTransparentArea(WebPPicture* pic) { #undef SIZE #undef SIZE2 +void WebPCleanupTransparentAreaLossless(WebPPicture* const pic) { + int x, y, w, h; + uint32_t* argb; + assert(pic != NULL && pic->use_argb); + w = pic->width; + h = pic->height; + argb = pic->argb; + + for (y = 0; y < h; ++y) { + for (x = 0; x < w; ++x) { + if ((argb[x] & 0xff000000) == 0) { + argb[x] = 0x00000000; + } + } + argb += pic->argb_stride; + } +} + //------------------------------------------------------------------------------ // Blend color and remove transparency info diff --git a/src/enc/vp8enci.h b/src/enc/vp8enci.h index 1a7ebe57..08b26ef0 100644 --- a/src/enc/vp8enci.h +++ b/src/enc/vp8enci.h @@ -514,6 +514,10 @@ int WebPPictureAllocARGB(WebPPicture* const picture, int width, int height); // Returns false in case of error (invalid param, out-of-memory). int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height); +// Clean-up the RGB samples under fully transparent area, to help lossless +// compressibility (no guarantee, though). Assumes that pic->use_argb is true. +void WebPCleanupTransparentAreaLossless(WebPPicture* const pic); + // in near_lossless.c // Near lossless preprocessing in RGB color-space. int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality); diff --git a/src/enc/webpenc.c b/src/enc/webpenc.c index b5feb59b..fece7369 100644 --- a/src/enc/webpenc.c +++ b/src/enc/webpenc.c @@ -324,14 +324,15 @@ int WebPEncode(const WebPConfig* config, WebPPicture* pic) { if (pic->width > WEBP_MAX_DIMENSION || pic->height > WEBP_MAX_DIMENSION) return WebPEncodingSetError(pic, VP8_ENC_ERROR_BAD_DIMENSION); - if (!config->exact) { - WebPCleanupTransparentArea(pic); - } - if (pic->stats != NULL) memset(pic->stats, 0, sizeof(*pic->stats)); if (!config->lossless) { VP8Encoder* enc = NULL; + + if (!config->exact) { + WebPCleanupTransparentArea(pic); + } + if (pic->use_argb || pic->y == NULL || pic->u == NULL || pic->v == NULL) { // Make sure we have YUVA samples. if (config->preprocessing & 4) { @@ -379,6 +380,10 @@ int WebPEncode(const WebPConfig* config, WebPPicture* pic) { return 0; } + if (!config->exact) { + WebPCleanupTransparentAreaLossless(pic); + } + ok = VP8LEncodeImage(config, pic); // Sets pic->error in case of problem. }