lossless: simpler alpha cleanup preprocessing

setting all transparent pixels to black rather than the "flatten" method.

0.3% smaller filesize on the 1000 PNGs if alpha cleanup is used (before: 18685774, after: 18622472)

Change-Id: Ib0db9e7ccde55b36e82de07855f2dbb630fe62b1
This commit is contained in:
Lode Vandevenne 2015-12-17 15:03:26 +01:00 committed by Pascal Massimino
parent ba7f4b68c9
commit fb4c7832f1
3 changed files with 33 additions and 4 deletions

View File

@ -11,6 +11,8 @@
//
// Author: Skal (pascal.massimino@gmail.com)
#include <assert.h>
#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

View File

@ -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);

View File

@ -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.
}