gif2webp: Add '-min-size' option to get best compression.

This disables key-frame insertion and tries both dispose methods for
each frame.

Change-Id: Ib167747198fd1d98cb93321f76826e91228f24d8
This commit is contained in:
Urvang Joshi 2014-10-30 15:17:09 -07:00
parent 77bdddf016
commit 7489b0e72b
4 changed files with 30 additions and 4 deletions

View File

@ -231,6 +231,10 @@ static void Help(void) {
" or lossless compression heuristically\n");
printf(" -q <float> ............. quality factor (0:small..100:big)\n");
printf(" -m <int> ............... compression method (0=fast, 6=slowest)\n");
printf(" -min_size .............. minimize output size (default:off)\n"
" lossless compression by default; can be\n"
" combined with -q, -m, -lossy or -mixed\n"
" options\n");
printf(" -kmin <int> ............ min distance between key frames\n");
printf(" -kmax <int> ............ max distance between key frames\n");
printf(" -f <int> ............... filter strength (0=off..100)\n");
@ -274,6 +278,7 @@ int main(int argc, const char *argv[]) {
int stored_icc = 0; // Whether we have already stored an ICC profile.
int stored_xmp = 0;
int minimize_size = 0;
int default_kmin = 1; // Whether to use default kmin value.
int default_kmax = 1;
size_t kmin = 0;
@ -307,6 +312,8 @@ int main(int argc, const char *argv[]) {
config.quality = ExUtilGetFloat(argv[++c], &parse_error);
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
config.method = ExUtilGetInt(argv[++c], 0, &parse_error);
} else if (!strcmp(argv[c], "-min_size")) {
minimize_size = 1;
} else if (!strcmp(argv[c], "-kmax") && c < argc - 1) {
kmax = ExUtilGetUInt(argv[++c], 0, &parse_error);
default_kmax = 0;
@ -466,7 +473,7 @@ int main(int argc, const char *argv[]) {
WebPUtilClearPic(&frame, NULL);
// Initialize cache.
cache = WebPFrameCacheNew(frame.width, frame.height,
cache = WebPFrameCacheNew(frame.width, frame.height, minimize_size,
kmin, kmax, allow_mixed);
if (cache == NULL) goto End;

View File

@ -287,6 +287,9 @@ struct WebPFrameCache {
// transparent pixels in a frame.
int keyframe; // Index of selected keyframe relative to 'start'.
// TODO(urvang): Create a struct WebPAnimationEncodingConfig for these
// encoding parameters.
int min_size; // If true, produce the smallest output.
size_t kmin; // Min distance between key frames.
size_t kmax; // Max distance between key frames.
size_t count_since_key_frame; // Frames seen since the last key frame.
@ -319,7 +322,7 @@ static void CacheReset(WebPFrameCache* const cache) {
cache->keyframe = KEYFRAME_NONE;
}
WebPFrameCache* WebPFrameCacheNew(int width, int height,
WebPFrameCache* WebPFrameCacheNew(int width, int height, int minimize_size,
size_t kmin, size_t kmax, int allow_mixed) {
WebPFrameCache* cache = (WebPFrameCache*)WebPSafeCalloc(1, sizeof(*cache));
if (cache == NULL) return NULL;
@ -354,7 +357,12 @@ WebPFrameCache* WebPFrameCacheNew(int width, int height,
WebPUtilClearPic(&cache->prev_to_prev_canvas_disposed, NULL);
// Cache data.
cache->min_size = minimize_size;
cache->allow_mixed = allow_mixed;
if (cache->min_size) { // Disable keyframe insertion.
kmax = ~0;
kmin = kmax - 1;
}
cache->kmin = kmin;
cache->kmax = kmax;
cache->count_since_key_frame = 0;
@ -790,7 +798,10 @@ static WebPEncodingError SetFrame(WebPFrameCache* const cache,
GetSubRect(prev_canvas_disposed, curr_canvas, orig_rect, is_key_frame,
&rect_bg, &sub_frame_bg);
if (RectArea(&rect_bg) < RectArea(&rect_none)) {
if (cache->min_size) { // Try both dispose methods.
try_dispose_bg = 1;
try_dispose_none = 1;
} else if (RectArea(&rect_bg) < RectArea(&rect_none)) {
try_dispose_bg = 1; // Pick DISPOSE_BACKGROUND.
try_dispose_none = 0;
}

View File

@ -51,10 +51,12 @@ typedef struct WebPFrameCache WebPFrameCache;
// Given the minimum distance between key frames 'kmin' and maximum distance
// between key frames 'kmax', returns an appropriately allocated cache object.
// If 'minimize_size' is true, optimizes for file size. This also implies that
// keyframe addition is off.
// If 'allow_mixed' is true, the subsequent calls to WebPFrameCacheAddFrame()
// will heuristically pick lossy or lossless compression for each frame.
// Use WebPFrameCacheDelete() to deallocate the 'cache'.
WebPFrameCache* WebPFrameCacheNew(int width, int height,
WebPFrameCache* WebPFrameCacheNew(int width, int height, int minimize_size,
size_t kmin, size_t kmax, int allow_mixed);
// Release all the frame data from 'cache' and free 'cache'.

View File

@ -54,6 +54,12 @@ additional encoding possibilities and decide on the quality gain.
Lower value can result is faster processing time at the expense of
larger file size and lower compression quality.
.TP
.BI \-min_size
Encode image to achieve smallest size. This disables key frame insertion and
picks the dispose method resulting in smallest output for each frame. It uses
lossless compression by default, but can be combined with \-q, \-m, \-lossy or
\-mixed options.
.TP
.BI \-kmin " int
.TP
.BI \-kmax " int