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:
parent
7efd6421ba
commit
ccd1231869
2 changed files with 61 additions and 3 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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, ¶site_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)))
|
||||
|
|
|
|||
Loading…
Reference in a new issue