plug-ins: Save GIF animation when overwriting

Overwriting a GIF animation results in loss of frames if a previous export turned off
animations.
This sets a parasite on import which we check for on overwrite. If it was an
animation originally, we overwrite as an animation as well.
This commit is contained in:
Alx Sa 2023-11-11 15:35:23 +00:00
parent 7efd6421ba
commit ccd1231869
2 changed files with 61 additions and 3 deletions

View file

@ -352,7 +352,8 @@ static struct
gint delayTime;
gint inputFlag;
gint disposal;
} Gif89 = { -1, -1, -1, 0 };
gint num_loops;
} Gif89 = { -1, -1, -1, 0, -1 };
static void read_error (const gchar *error_type,
GimpImage *image,
@ -399,9 +400,10 @@ load_image (GFile *file,
gint grayScale;
gboolean useGlobalColormap;
gint bitPixel;
gint imageCount = 0;
GimpImage *image = NULL;
gint imageCount = 0;
GimpImage *image = NULL;
gboolean status;
gboolean saved_parasite = FALSE;
gimp_progress_init_printf (_("Opening '%s'"),
gimp_file_get_utf8_name (file));
@ -590,6 +592,24 @@ load_image (GFile *file,
/* If we are loading a thumbnail, we stop after the first frame. */
if (thumbnail)
break;
/* If there is more than one frame, we add a parasite so that
* we know to export as an animation on overwrite */
if (Gif89.num_loops > -1 && ! saved_parasite)
{
GimpParasite *parasite;
gchar *str;
parasite = gimp_parasite_new ("gif/animated",
GIMP_PARASITE_PERSISTENT,
strlen (str) + 1,
(gpointer) str);
g_free (str);
gimp_image_attach_parasite (image, parasite);
gimp_parasite_free (parasite);
saved_parasite = TRUE;
}
}
fclose (fd);
@ -690,6 +710,15 @@ DoExtension (FILE *fd,
#ifdef GIFDEBUG
str = "Application Extension";
#endif
/* Animation block */
if (GetDataBlock (fd, (guchar *) buf))
{
if (strncmp ((const gchar *) buf, "NETSCAPE2.0", 8) == 0)
{
if (GetDataBlock (fd, (guchar *) buf))
Gif89.num_loops = (buf[0] << 8) | buf[1];
}
}
break;
case 0xfe: /* Comment Extension */
#ifdef GIFDEBUG

View file

@ -268,6 +268,7 @@ gif_save (GimpProcedure *procedure,
GimpExportReturn export = GIMP_EXPORT_CANCEL;
GimpImage *orig_image;
GimpImage *sanitized_image = NULL;
GimpParasite *parasite = NULL;
GError *error = NULL;
gegl_init (NULL, NULL);
@ -288,6 +289,34 @@ gif_save (GimpProcedure *procedure,
*/
sanitized_image = image;
/* If imported as an animation, set the animation configurations
* when overwriting the file */
parasite = gimp_image_get_parasite (image, "gif/animated");
if (parasite)
{
gint num_loops;
gchar *parasite_data;
guint32 parasite_size;
parasite_data = (gchar *) gimp_parasite_get_data (parasite, &parasite_size);
parasite_data = g_strndup (parasite_data, parasite_size);
if (sscanf (parasite_data, "%i", &num_loops) == 1)
{
gboolean loop = (num_loops == 0);
g_object_set (config,
"as-animation", TRUE,
"loop", loop,
"number-of-repeats", num_loops,
NULL);
}
gimp_image_detach_parasite (image, "gif/animated");
g_free (parasite);
g_free (parasite_data);
}
if (run_mode == GIMP_RUN_INTERACTIVE)
{
if (! save_dialog (image, procedure, G_OBJECT (config)))