From eba35640cc04fa90d55a9c6441f9a6bfe9077ea2 Mon Sep 17 00:00:00 2001 From: Essem Date: Thu, 3 Mar 2022 14:59:42 -0600 Subject: [PATCH 1/5] cgifsave: Added "noloop" option --- libvips/foreign/cgifsave.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index 0efec18d82..cd84a0d0a0 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -63,6 +63,7 @@ typedef struct _VipsForeignSaveCgif { int effort; int bitdepth; double maxerror; + gboolean noloop; VipsTarget *target; /* Derived write params. @@ -309,7 +310,7 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif ) */ if( !cgif->cgif_context ) { cgif->cgif_config.pGlobalPalette = cgif->palette_rgb; - cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED; + cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED | ( cgif->noloop ? CGIF_ATTR_NO_LOOP : 0 ); cgif->cgif_config.width = frame_rect->width; cgif->cgif_config.height = frame_rect->height; cgif->cgif_config.numGlobalPaletteEntries = cgif->lp->count; @@ -612,6 +613,13 @@ vips_foreign_save_cgif_class_init( VipsForeignSaveCgifClass *class ) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET( VipsForeignSaveCgif, maxerror ), 0, 32, 0.0 ); + + VIPS_ARG_BOOL( class, "noloop", 14, + _( "No loop" ), + _( "Disables looping" ), + VIPS_ARGUMENT_OPTIONAL_INPUT, + G_STRUCT_OFFSET( VipsForeignSaveCgif, noloop ), + FALSE ); } static void From e8b85fbfbb81c8db186ee3dd5f7592a4a9bbd1fa Mon Sep 17 00:00:00 2001 From: Essem Date: Fri, 4 Mar 2022 10:34:19 -0600 Subject: [PATCH 2/5] cgifsave: Change loop count logic --- libvips/foreign/cgifsave.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index b3c3fa0115..4e7b07eb50 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -63,7 +63,6 @@ typedef struct _VipsForeignSaveCgif { int effort; int bitdepth; double maxerror; - gboolean noloop; VipsTarget *target; /* Derived write params. @@ -311,11 +310,11 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif ) */ if( !cgif->cgif_context ) { cgif->cgif_config.pGlobalPalette = cgif->palette_rgb; - cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED | ( cgif->noloop ? CGIF_ATTR_NO_LOOP : 0 ); + cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED | ( cgif->loop == 1 ? CGIF_ATTR_NO_LOOP : 0 ); cgif->cgif_config.width = frame_rect->width; cgif->cgif_config.height = frame_rect->height; cgif->cgif_config.numGlobalPaletteEntries = cgif->lp->count; - cgif->cgif_config.numLoops = cgif->loop; + cgif->cgif_config.numLoops = cgif->loop > 1 ? cgif->loop - 1 : cgif->loop; cgif->cgif_config.pWriteFn = vips__cgif_write; cgif->cgif_config.pContext = (void *) cgif->target; @@ -614,13 +613,6 @@ vips_foreign_save_cgif_class_init( VipsForeignSaveCgifClass *class ) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET( VipsForeignSaveCgif, maxerror ), 0, 32, 0.0 ); - - VIPS_ARG_BOOL( class, "noloop", 14, - _( "No loop" ), - _( "Disables looping" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsForeignSaveCgif, noloop ), - FALSE ); } static void From 77550f097940944492d4178a783fc4e73c7a769f Mon Sep 17 00:00:00 2001 From: Essem Date: Mon, 7 Mar 2022 20:28:36 -0600 Subject: [PATCH 3/5] make sure nsgifload returns the correct loop count --- libvips/foreign/libnsgif/gif.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libvips/foreign/libnsgif/gif.c b/libvips/foreign/libnsgif/gif.c index 4fdaaac157..f511f30219 100644 --- a/libvips/foreign/libnsgif/gif.c +++ b/libvips/foreign/libnsgif/gif.c @@ -799,7 +799,8 @@ static nsgif_error nsgif__parse_extension_application( if ((data[1] == 0x0b) && (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0) && (data[13] == 0x03) && (data[14] == 0x01)) { - gif->info.loop_max = data[15] | (data[16] << 8); + int loop = data[15] | (data[16] << 8); + gif->info.loop_max = loop > 0 ? loop + 1 : loop; } return NSGIF_OK; From d0d2608cdeda4268c5947221a7253b775f341f98 Mon Sep 17 00:00:00 2001 From: Essem Date: Tue, 8 Mar 2022 23:42:30 -0600 Subject: [PATCH 4/5] Revert "make sure nsgifload returns the correct loop count" This reverts commit 77550f097940944492d4178a783fc4e73c7a769f. --- libvips/foreign/libnsgif/gif.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libvips/foreign/libnsgif/gif.c b/libvips/foreign/libnsgif/gif.c index f511f30219..4fdaaac157 100644 --- a/libvips/foreign/libnsgif/gif.c +++ b/libvips/foreign/libnsgif/gif.c @@ -799,8 +799,7 @@ static nsgif_error nsgif__parse_extension_application( if ((data[1] == 0x0b) && (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0) && (data[13] == 0x03) && (data[14] == 0x01)) { - int loop = data[15] | (data[16] << 8); - gif->info.loop_max = loop > 0 ? loop + 1 : loop; + gif->info.loop_max = data[15] | (data[16] << 8); } return NSGIF_OK; From b07e263030b2ef04cd2a133ae96f625041a8d9b7 Mon Sep 17 00:00:00 2001 From: Essem Date: Wed, 9 Mar 2022 15:06:32 -0600 Subject: [PATCH 5/5] Add fallback --- libvips/foreign/cgifsave.c | 8 ++++++++ meson.build | 3 +++ 2 files changed, 11 insertions(+) diff --git a/libvips/foreign/cgifsave.c b/libvips/foreign/cgifsave.c index 4e7b07eb50..f7983edaa4 100644 --- a/libvips/foreign/cgifsave.c +++ b/libvips/foreign/cgifsave.c @@ -310,11 +310,19 @@ vips_foreign_save_cgif_write_frame( VipsForeignSaveCgif *cgif ) */ if( !cgif->cgif_context ) { cgif->cgif_config.pGlobalPalette = cgif->palette_rgb; +#ifdef HAVE_CGIF_ATTR_NO_LOOP cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED | ( cgif->loop == 1 ? CGIF_ATTR_NO_LOOP : 0 ); +#else + cgif->cgif_config.attrFlags = CGIF_ATTR_IS_ANIMATED; +#endif/*HAVE_CGIF_ATTR_NO_LOOP*/ cgif->cgif_config.width = frame_rect->width; cgif->cgif_config.height = frame_rect->height; cgif->cgif_config.numGlobalPaletteEntries = cgif->lp->count; +#ifdef HAVE_CGIF_ATTR_NO_LOOP cgif->cgif_config.numLoops = cgif->loop > 1 ? cgif->loop - 1 : cgif->loop; +#else + cgif->cgif_config.numLoops = cgif->loop; +#endif/*HAVE_CGIF_ATTR_NO_LOOP*/ cgif->cgif_config.pWriteFn = vips__cgif_write; cgif->cgif_config.pContext = (void *) cgif->target; diff --git a/meson.build b/meson.build index 5cddf647c4..51a50c0e39 100644 --- a/meson.build +++ b/meson.build @@ -238,6 +238,9 @@ if quantisation_package.found() if cgif_dep.found() libvips_deps += cgif_dep cfg_var.set('HAVE_CGIF', '1') + if cc.compiles('#include \nint i = CGIF_ATTR_NO_LOOP;', name: 'Has CGIF_ATTR_NO_LOOP', dependencies: cgif_dep) + cfg_var.set('HAVE_CGIF_ATTR_NO_LOOP', '1') + endif endif endif