From b4e046778d8c002475350caee2a57dc08ba21699 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Mon, 18 Sep 2017 23:38:09 -0700 Subject: [PATCH] gif2webp: introduce -loop_compatibility option This patch fixes the compatibility for loop-count handling. This aims at addressing the change in Chrome handling of loop-count prior to M63. Before M63: loop-count interpretation was aligned to GIF's behaviour in Chrome, but incompatible with WebP's spec. In particular, you couldn't loop exactly once. Post-M63: loop-count in WebP is really the total number of loops. Gif2webp will convert correctly from a GIF source by adjusting the loop count. Note: The Chrome version can be retrieved from the User-Agent string (chrome://version). An M63 version will contain the pattern: Chrome/63.x.xxxx.xx for instance. Change-Id: Ie6dc13227e6498f4d7af2f09247913648997648a --- README | 2 ++ examples/gif2webp.c | 27 +++++++++++++++++++++++---- man/gif2webp.1 | 5 ++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/README b/README index 8f9028ec..05f2c16f 100644 --- a/README +++ b/README @@ -477,6 +477,8 @@ Options: -metadata ..... comma separated list of metadata to copy from the input to the output if present Valid values: all, none, icc, xmp (default) + -loop_compatibility .... use compatibility mode for Chrome + version prior to M62 (inclusive) -mt .................... use multi-threading if available -version ............... print version number and exit diff --git a/examples/gif2webp.c b/examples/gif2webp.c index 68e7350a..7287bea8 100644 --- a/examples/gif2webp.c +++ b/examples/gif2webp.c @@ -72,8 +72,10 @@ static void Help(void) { printf(" -metadata ..... comma separated list of metadata to\n"); printf(" "); printf("copy from the input to the output if present\n"); - printf(" " - "Valid values: all, none, icc, xmp (default)\n"); + printf(" "); + printf("Valid values: all, none, icc, xmp (default)\n"); + printf(" -loop_compatibility .... use compatibility mode for Chrome\n"); + printf(" version prior to M62 (inclusive)\n"); printf(" -mt .................... use multi-threading if available\n"); printf("\n"); printf(" -version ............... print version number and exit\n"); @@ -115,8 +117,9 @@ int main(int argc, const char *argv[]) { int stored_icc = 0; // Whether we have already stored an ICC profile. WebPData xmp_data; int stored_xmp = 0; // Whether we have already stored an XMP profile. - int loop_count = 0; + int loop_count = 0; // default: infinite int stored_loop_count = 0; // Whether we have found an explicit loop count. + int loop_compatibility = 0; WebPMux* mux = NULL; int default_kmin = 1; // Whether to use default kmin value. @@ -151,6 +154,8 @@ int main(int argc, const char *argv[]) { } else if (!strcmp(argv[c], "-mixed")) { enc_options.allow_mixed = 1; config.lossless = 0; + } else if (!strcmp(argv[c], "-loop_compatibility")) { + loop_compatibility = 1; } else if (!strcmp(argv[c], "-q") && c < argc - 1) { config.quality = ExUtilGetFloat(argv[++c], &parse_error); } else if (!strcmp(argv[c], "-m") && c < argc - 1) { @@ -386,7 +391,7 @@ int main(int argc, const char *argv[]) { if (verbose) { fprintf(stderr, "Loop count: %d\n", loop_count); } - stored_loop_count = (loop_count != 0); + stored_loop_count = loop_compatibility ? (loop_count != 0) : 1; } else { // An extension containing metadata. // We only store the first encountered chunk of each type, and // only if requested by the user. @@ -443,6 +448,20 @@ int main(int argc, const char *argv[]) { goto End; } + if (!loop_compatibility) { + if (!stored_loop_count) { + // if no loop-count element is seen, the default is '1' (loop-once) + // and we need to signal it explicitly in WebP. + stored_loop_count = 1; + loop_count = 1; + } else if (loop_count > 0) { + // adapt GIF's semantic to WebP's (except in the infinite-loop case) + loop_count += 1; + } + } + // loop_count of 0 is the default (infinite), so no need to signal it + if (loop_count == 0) stored_loop_count = 0; + if (stored_loop_count || stored_icc || stored_xmp) { // Re-mux to add loop count and/or metadata as needed. mux = WebPMuxCreate(&webp_data, 1); diff --git a/man/gif2webp.1 b/man/gif2webp.1 index 40ce96ac..8e86a110 100644 --- a/man/gif2webp.1 +++ b/man/gif2webp.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH GIF2WEBP 1 "January 25, 2017" +.TH GIF2WEBP 1 "September 20, 2017" .SH NAME gif2webp \- Convert a GIF image to WebP .SH SYNOPSIS @@ -109,6 +109,9 @@ the range of 20 to 50. .TP .B \-mt Use multi-threading for encoding, if possible. +.B \-loop_compatibility +If enabled, handle the loop information in a compatible fashion for Chrome +version prior to M62 (inclusive) and Firefox. .TP .B \-v Print extra information.