mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 13:48:21 +01:00
add a WebPCleanupTransparentArea() method
to 'clean up' the fully-transparent area and make it more compressible new cwebp flags: -alpha_cleanup (off by default, since gain is not 100% guaranteed) Change-Id: I74d77e1915eee146584cd61c9c1132a41db922eb
This commit is contained in:
parent
552c121715
commit
2e3e8b2ef5
15
README
15
README
@ -121,19 +121,21 @@ A longer list of options is available using the -longhelp command line flag:
|
|||||||
Usage:
|
Usage:
|
||||||
cwebp [-preset <...>] [options] in_file [-o out_file]
|
cwebp [-preset <...>] [options] in_file [-o out_file]
|
||||||
|
|
||||||
If input size (-s) for an image is not specified, it is assumed to be a either
|
If input size (-s) for an image is not specified, it is assumed to be a
|
||||||
PNG or JPEG format file.
|
PNG or JPEG file.
|
||||||
options:
|
options:
|
||||||
-h / -help ............ short help
|
-h / -help ............ short help
|
||||||
-H / -longhelp ........ long help
|
-H / -longhelp ........ long help
|
||||||
-q <float> ............. quality factor (0:small..100:big)
|
-q <float> ............. quality factor (0:small..100:big)
|
||||||
-alpha_q <int> ......... Transparency-compression quality (0..100)
|
-alpha_q <int> ......... Transparency-compression quality (0..100).
|
||||||
-preset <string> ....... Preset setting, one of:
|
-preset <string> ....... Preset setting, one of:
|
||||||
default, photo, picture,
|
default, photo, picture,
|
||||||
drawing, icon, text
|
drawing, icon, text
|
||||||
-preset must come first, as it overwrites other parameters.
|
-preset must come first, as it overwrites other parameters.
|
||||||
-m <int> ............... compression method (0=fast, 6=slowest)
|
-m <int> ............... compression method (0=fast, 6=slowest)
|
||||||
-segments <int> ........ number of segments to use (1..4)
|
-segments <int> ........ number of segments to use (1..4)
|
||||||
|
-size <int> ............ Target size (in bytes)
|
||||||
|
-psnr <float> .......... Target PSNR (in dB. typically: 42)
|
||||||
|
|
||||||
-s <int> <int> ......... Input size (width x height) for YUV
|
-s <int> <int> ......... Input size (width x height) for YUV
|
||||||
-sns <int> ............. Spatial Noise Shaping (0:off, 100:max)
|
-sns <int> ............. Spatial Noise Shaping (0:off, 100:max)
|
||||||
@ -143,7 +145,6 @@ options:
|
|||||||
-partition_limit <int> . limit quality to fit the 512k limit on
|
-partition_limit <int> . limit quality to fit the 512k limit on
|
||||||
the first partition (0=no degradation ... 100=full)
|
the first partition (0=no degradation ... 100=full)
|
||||||
-pass <int> ............ analysis pass number (1..10)
|
-pass <int> ............ analysis pass number (1..10)
|
||||||
-partitions <int> ...... number of partitions to use (0..3)
|
|
||||||
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
|
-crop <x> <y> <w> <h> .. crop picture with the given rectangle
|
||||||
-resize <w> <h> ........ resize picture (after any cropping)
|
-resize <w> <h> ........ resize picture (after any cropping)
|
||||||
-map <int> ............. print map of extra info.
|
-map <int> ............. print map of extra info.
|
||||||
@ -151,6 +152,7 @@ options:
|
|||||||
-alpha_method <int> .... Transparency-compression method (0..1)
|
-alpha_method <int> .... Transparency-compression method (0..1)
|
||||||
-alpha_filter <string> . predictive filtering for alpha plane.
|
-alpha_filter <string> . predictive filtering for alpha plane.
|
||||||
One of: none, fast (default) or best.
|
One of: none, fast (default) or best.
|
||||||
|
-alpha_cleanup ......... Clean RGB values in transparent area.
|
||||||
-noalpha ............... discard any transparency information.
|
-noalpha ............... discard any transparency information.
|
||||||
|
|
||||||
-short ................. condense printed message
|
-short ................. condense printed message
|
||||||
@ -160,11 +162,8 @@ options:
|
|||||||
-v ..................... verbose, e.g. print encoding/decoding times
|
-v ..................... verbose, e.g. print encoding/decoding times
|
||||||
-progress .............. report encoding progress
|
-progress .............. report encoding progress
|
||||||
|
|
||||||
|
|
||||||
Experimental Options:
|
Experimental Options:
|
||||||
-size <int> ............ Target size (in bytes)
|
-af .................... auto-adjust filter strength.
|
||||||
-psnr <float> .......... Target PSNR (in dB. typically: 42)
|
|
||||||
-af <int> .............. adjust filter strength (0=off, 1=on)
|
|
||||||
-pre <int> ............. pre-processing filter
|
-pre <int> ............. pre-processing filter
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,6 +206,11 @@ static HRESULT ReadPictureWithWIC(const char* filename,
|
|||||||
if (!ok)
|
if (!ok)
|
||||||
hr = E_FAIL;
|
hr = E_FAIL;
|
||||||
}
|
}
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
if (has_alpha && keep_alpha == 2) {
|
||||||
|
WebPCleanupTransparentArea(pic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Cleanup.
|
// Cleanup.
|
||||||
if (pConverter != NULL) IUnknown_Release(pConverter);
|
if (pConverter != NULL) IUnknown_Release(pConverter);
|
||||||
@ -416,6 +421,10 @@ static int ReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
|
|||||||
: WebPPictureImportRGB(pic, rgb, stride);
|
: WebPPictureImportRGB(pic, rgb, stride);
|
||||||
free(rgb);
|
free(rgb);
|
||||||
|
|
||||||
|
if (ok && has_alpha && keep_alpha == 2) {
|
||||||
|
WebPCleanupTransparentArea(pic);
|
||||||
|
}
|
||||||
|
|
||||||
End:
|
End:
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@ -702,6 +711,7 @@ static void HelpLong(void) {
|
|||||||
printf(" -alpha_method <int> .... Transparency-compression method (0..1)\n");
|
printf(" -alpha_method <int> .... Transparency-compression method (0..1)\n");
|
||||||
printf(" -alpha_filter <string> . predictive filtering for alpha plane.\n");
|
printf(" -alpha_filter <string> . predictive filtering for alpha plane.\n");
|
||||||
printf(" One of: none, fast (default) or best.\n");
|
printf(" One of: none, fast (default) or best.\n");
|
||||||
|
printf(" -alpha_cleanup ......... Clean RGB values in transparent area.\n");
|
||||||
printf(" -noalpha ............... discard any transparency information.\n");
|
printf(" -noalpha ............... discard any transparency information.\n");
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -795,6 +805,8 @@ int main(int argc, const char *argv[]) {
|
|||||||
config.alpha_quality = strtol(argv[++c], NULL, 0);
|
config.alpha_quality = strtol(argv[++c], NULL, 0);
|
||||||
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
|
||||||
config.alpha_compression = strtol(argv[++c], NULL, 0);
|
config.alpha_compression = strtol(argv[++c], NULL, 0);
|
||||||
|
} else if (!strcmp(argv[c], "-alpha_cleanup")) {
|
||||||
|
keep_alpha = keep_alpha ? 2 : 0;
|
||||||
} else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
|
} else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
|
||||||
++c;
|
++c;
|
||||||
if (!strcmp(argv[c], "none")) {
|
if (!strcmp(argv[c], "none")) {
|
||||||
|
@ -155,6 +155,10 @@ Specify the algorithm used for alpha compression: 0 or 1. Algorithm 0 denotes
|
|||||||
no compression, 1 uses uses backward reference counts encoded with arithmetic
|
no compression, 1 uses uses backward reference counts encoded with arithmetic
|
||||||
encoder. The default is 1.
|
encoder. The default is 1.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-alpha_cleanup
|
||||||
|
Modify unseen RGB values under fully transparent area, to help compressibility.
|
||||||
|
The default is off.
|
||||||
|
.TP
|
||||||
.B \-noalpha
|
.B \-noalpha
|
||||||
Using this option will discard the alpha channel.
|
Using this option will discard the alpha channel.
|
||||||
.TP
|
.TP
|
||||||
|
@ -593,6 +593,71 @@ int WebPPictureImportBGRA(WebPPicture* const picture,
|
|||||||
return Import(picture, rgba, rgba_stride, 4, 1, 1);
|
return Import(picture, rgba, rgba_stride, 4, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// Helper: clean up fully transparent area to help compressibility.
|
||||||
|
|
||||||
|
#define SIZE 8
|
||||||
|
#define SIZE2 (SIZE / 2)
|
||||||
|
static int is_transparent_area(const uint8_t* ptr, int stride, int size) {
|
||||||
|
int y, x;
|
||||||
|
for (y = 0; y < size; ++y) {
|
||||||
|
for (x = 0; x < size; ++x) {
|
||||||
|
if (ptr[x]) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptr += stride;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WEBP_INLINE void flatten(uint8_t* ptr, int v, int stride, int size) {
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < size; ++y) {
|
||||||
|
memset(ptr, v, size);
|
||||||
|
ptr += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WebPCleanupTransparentArea(WebPPicture* const pic) {
|
||||||
|
int x, y, w, h;
|
||||||
|
const uint8_t* a_ptr;
|
||||||
|
int values[3] = { 0 };
|
||||||
|
|
||||||
|
if (pic == NULL) return;
|
||||||
|
|
||||||
|
a_ptr = pic->a;
|
||||||
|
if (a_ptr == NULL) return; // nothing to do
|
||||||
|
|
||||||
|
w = pic->width / SIZE;
|
||||||
|
h = pic->height / SIZE;
|
||||||
|
for (y = 0; y < h; ++y) {
|
||||||
|
int need_reset = 1;
|
||||||
|
for (x = 0; x < w; ++x) {
|
||||||
|
const int off_a = (y * pic->a_stride + x) * SIZE;
|
||||||
|
const int off_y = (y * pic->y_stride + x) * SIZE;
|
||||||
|
const int off_uv = (y * pic->uv_stride + x) * SIZE2;
|
||||||
|
if (is_transparent_area(a_ptr + off_a, pic->a_stride, SIZE)) {
|
||||||
|
if (need_reset) {
|
||||||
|
values[0] = pic->y[off_y];
|
||||||
|
values[1] = pic->u[off_uv];
|
||||||
|
values[2] = pic->v[off_uv];
|
||||||
|
need_reset = 0;
|
||||||
|
}
|
||||||
|
flatten(pic->y + off_y, values[0], pic->y_stride, SIZE);
|
||||||
|
flatten(pic->u + off_uv, values[1], pic->uv_stride, SIZE2);
|
||||||
|
flatten(pic->v + off_uv, values[2], pic->uv_stride, SIZE2);
|
||||||
|
} else {
|
||||||
|
need_reset = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ignore the left-overs on right/bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef SIZE
|
||||||
|
#undef SIZE2
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Simplest call:
|
// Simplest call:
|
||||||
|
|
||||||
|
@ -276,6 +276,11 @@ WEBP_EXTERN(int) WebPPictureImportBGR(
|
|||||||
WEBP_EXTERN(int) WebPPictureImportBGRA(
|
WEBP_EXTERN(int) WebPPictureImportBGRA(
|
||||||
WebPPicture* const picture, const uint8_t* const bgra, int bgra_stride);
|
WebPPicture* const picture, const uint8_t* const bgra, int bgra_stride);
|
||||||
|
|
||||||
|
// Helper function: given a width x height plane of YUV(A) samples
|
||||||
|
// (with stride 'stride'), clean-up the YUV samples under fully transparent
|
||||||
|
// area, to help compressibility (no guarantee, though).
|
||||||
|
WEBP_EXTERN(void) WebPCleanupTransparentArea(WebPPicture* const picture);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main call
|
// Main call
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user