From 28f679e62ee06e1b383c657f53478fbb809cf936 Mon Sep 17 00:00:00 2001 From: "GMT 2000 Adam D. Moss" Date: Thu, 13 Jan 2000 20:47:30 +0000 Subject: [PATCH] Collapse timing of completely optimized-away frames onto previous Thu Jan 13 20:41:37 GMT 2000 Adam D. Moss * plug-ins/common/animoptimize.c: Collapse timing of completely optimized-away frames onto previous surviving frame. Also be looser with (XXXXX) tag parsing. * plug-ins/common/animationplay.c: Be looser with (XXXXX) tag parsing. --- ChangeLog | 9 + plug-ins/common/animationplay.c | 228 ++++++++++++++---- plug-ins/common/animoptimize.c | 394 +++++++++++++++++++++++++------- 3 files changed, 501 insertions(+), 130 deletions(-) diff --git a/ChangeLog b/ChangeLog index f56d1e1d12..0c38455d2f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Jan 13 20:41:37 GMT 2000 Adam D. Moss + + * plug-ins/common/animoptimize.c: Collapse timing of completely + optimized-away frames onto previous surviving frame. Also be + looser with (XXXXX) tag parsing. + + * plug-ins/common/animationplay.c: Be looser with (XXXXX) tag + parsing. + 2000-01-13 Yuri Syrota * configure.in: Added "uk" to ALL_LINGUAS diff --git a/plug-ins/common/animationplay.c b/plug-ins/common/animationplay.c index 002264a51e..0c569a22fd 100644 --- a/plug-ins/common/animationplay.c +++ b/plug-ins/common/animationplay.c @@ -1,7 +1,7 @@ /* - * Animation Playback plug-in version 0.98.5 + * Animation Playback plug-in version 0.98.6 * - * Adam D. Moss : 1997-98 : adam@gimp.org : adam@foxbox.org + * (c) Adam D. Moss : 1997-2000 : adam@gimp.org : adam@foxbox.org * * * This is part of the GIMP package and is released under the GNU @@ -11,6 +11,9 @@ /* * REVISION HISTORY: * + * 2000-01-13 : version 0.98.6 + * Looser parsing of (XXXXX) layer-name tags + * * 98.07.27 : version 0.98.5 * UI tweaks, fix for pseudocolor displays w/gdkrgb. * @@ -152,8 +155,6 @@ static void run (gchar *name, GParam **return_vals); static void do_playback (void); -static int parse_ms_tag (char *str); -static DisposeType parse_disposal_tag (char *str); static gint window_delete_callback (GtkWidget *widget, GdkEvent *event, @@ -173,13 +174,27 @@ static void repaint_da (GtkWidget *darea, gpointer data); #endif -static DisposeType get_frame_disposal (guint whichframe); static void render_frame (gint32 whichframe); static void show_frame (void); static void total_alpha_preview (guchar* ptr); static void init_preview_misc (void); +/* tag util functions*/ +static int parse_ms_tag (const char *str); +static DisposeType parse_disposal_tag (const char *str); +static DisposeType get_frame_disposal (const guint whichframe); +static guint32 get_frame_duration (const guint whichframe); +static int is_disposal_tag (const char *str, + DisposeType *disposal, + int *taglength); +static int is_ms_tag (const char *str, + int *duration, + int *taglength); + + + + GPlugInInfo PLUG_IN_INFO = { NULL, /* init_proc */ @@ -310,6 +325,7 @@ run (gchar *name, +/* static int parse_ms_tag (char *str) { @@ -365,8 +381,8 @@ parse_disposal_tag (char *str) offset++; } - return (DISPOSE_UNDEFINED); /* FIXME */ -} + return (DISPOSE_UNDEFINED); +}*/ static void @@ -1737,41 +1753,6 @@ do_step (void) render_frame(frame_number); } -static guint32 -get_frame_duration (guint whichframe) -{ - gchar* layer_name; - gint duration = 0; - - layer_name = gimp_layer_get_name(layers[total_frames-(whichframe+1)]); - if (layer_name != NULL) - { - duration = parse_ms_tag(layer_name); - g_free(layer_name); - } - - if (duration < 0) duration = 125; /* FIXME for default-if-not-said */ - if (duration == 0) duration = 125; /* FIXME - 0-wait is nasty */ - - return ((guint32) duration); -} - -static DisposeType -get_frame_disposal (guint whichframe) -{ - gchar* layer_name; - DisposeType disposal = DISPOSE_UNDEFINED; - - layer_name = gimp_layer_get_name(layers[total_frames-(whichframe+1)]); - if (layer_name != NULL) - { - disposal = parse_disposal_tag (layer_name); - g_free (layer_name); - } - - return (disposal); -} - /* Callbacks */ @@ -1867,3 +1848,166 @@ step_callback (GtkWidget *widget, show_frame(); } + + + + +/* tag util. */ + +static DisposeType +get_frame_disposal (const guint whichframe) +{ + gchar* layer_name; + DisposeType disposal; + + layer_name = gimp_layer_get_name(layers[total_frames-(whichframe+1)]); + disposal = parse_disposal_tag(layer_name); + g_free(layer_name); + + return(disposal); +} + + + +static guint32 +get_frame_duration (const guint whichframe) +{ + gchar* layer_name; + gint duration = 0; + + layer_name = gimp_layer_get_name(layers[total_frames-(whichframe+1)]); + if (layer_name != NULL) + { + duration = parse_ms_tag(layer_name); + g_free(layer_name); + } + + if (duration < 0) duration = 125; /* FIXME for default-if-not-said */ + if (duration == 0) duration = 125; /* FIXME - 0-wait is nasty */ + + return ((guint32) duration); +} + + +static int +is_ms_tag (const char *str, int *duration, int *taglength) +{ + gint sum = 0; + gint offset; + gint length; + + length = strlen(str); + + if (str[0] != '(') + return 0; + + offset = 1; + + /* eat any spaces between open-parenthesis and number */ + while ((offset=length) || (!isdigit(str[offset]))) + return 0; + + do + { + sum *= 10; + sum += str[offset] - '0'; + offset++; + } + while ((offset + * * 98.05.17 : version 1.0.0 * Finally preserves frame timings / layer names. Has * a progress bar now. No longer beta, I suppose. @@ -44,7 +53,6 @@ /* * TODO: * User interface - * PDB interface */ #include @@ -75,10 +83,21 @@ static void run(char *name, GParam ** return_vals); static gint32 do_optimizations (GRunModeType run_mode); -/*static int parse_ms_tag (char *str);*/ -static DisposeType parse_disposal_tag (char *str); -static DisposeType get_frame_disposal (guint whichframe); + +/* tag util functions*/ +static int parse_ms_tag (const char *str); +static DisposeType parse_disposal_tag (const char *str); +static DisposeType get_frame_disposal (const guint whichframe); +static guint32 get_frame_duration (const guint whichframe); +static void remove_disposal_tag (char* dest, char *src); +static void remove_ms_tag (char* dest, char *src); +static int is_disposal_tag (const char *str, + DisposeType *disposal, + int *taglength); +static int is_ms_tag (const char *str, + int *duration, + int *taglength); GPlugInInfo PLUG_IN_INFO = @@ -206,62 +225,6 @@ static void run(char *name, int n_params, GParam * param, int *nreturn_vals, -static DisposeType -parse_disposal_tag (gchar *str) -{ - gint offset = 0; - gint length; - - length = strlen(str); - - while ((offset+9)<=length) - { - if (strncmp(&str[offset],"(combine)",9)==0) - return(DISPOSE_COMBINE); - if (strncmp(&str[offset],"(replace)",9)==0) - return(DISPOSE_REPLACE); - offset++; - } - - return (DISPOSE_UNDEFINED); /* FIXME */ -} - - - -static gchar* -remove_disposal_tag (gchar* str) -{ - gchar* dest; - gint offset = 0; - gint destoffset = 0; - gint length; - - length = strlen(str); - dest = g_malloc(length+11); - memset(dest, 0, length+11); - - strcpy(dest, str); - - while ((offset+9)<=length) - { - if (strncmp(&str[offset],"(combine)",9)==0) - { - offset+=9; - } - if (strncmp(&str[offset],"(replace)",9)==0) - { - offset+=9; - } - dest[destoffset] = str[offset]; - destoffset++; - offset++; - } - - return dest; -} - - - /* Rendering Functions */ static void @@ -290,6 +253,11 @@ do_optimizations(GRunModeType run_mode) guchar* last_frame = NULL; guchar* opti_frame = NULL; + int this_delay; + int cumulated_delay = 0; + int last_true_frame = -1; + int buflen; + gchar* oldlayer_name; gchar* newlayer_name; @@ -354,7 +322,8 @@ do_optimizations(GRunModeType run_mode) gimp_quit(); } - dispose = get_frame_disposal(this_frame_num); + this_delay = get_frame_duration (this_frame_num); + dispose = get_frame_disposal (this_frame_num); if (dispose==DISPOSE_REPLACE) { @@ -621,7 +590,6 @@ do_optimizations(GRunModeType run_mode) gimp_drawable_detach(drawable); - can_combine = FALSE; bbox_left = 0; bbox_top = 0; @@ -804,35 +772,85 @@ do_optimizations(GRunModeType run_mode) oldlayer_name = gimp_layer_get_name(layers[total_frames-(this_frame_num+1)]); - newlayer_name = remove_disposal_tag(oldlayer_name); + + buflen = strlen(oldlayer_name) + 40; + + newlayer_name = g_malloc(buflen); + + remove_disposal_tag(newlayer_name, oldlayer_name); g_free(oldlayer_name); - if (this_frame_num > 0) - strcat(newlayer_name, can_combine?"(combine)":"(replace)"); - - new_layer_id = gimp_layer_new(new_image_id, - newlayer_name, - bbox_right-bbox_left, - bbox_bottom-bbox_top, - drawabletype_alpha, - 100.0, - NORMAL_MODE); - g_free(newlayer_name); + oldlayer_name = g_malloc(buflen); - gimp_image_add_layer (new_image_id, new_layer_id, 0); + remove_ms_tag(oldlayer_name, newlayer_name); - drawable = gimp_drawable_get (new_layer_id); + g_snprintf(newlayer_name, buflen, "%s(%dms)%s", + oldlayer_name, this_delay, + (this_frame_num == 0) ? "" : + can_combine ? "(combine)" : "(replace)"); - gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, - bbox_right-bbox_left, - bbox_bottom-bbox_top, - TRUE, FALSE); - gimp_pixel_rgn_set_rect (&pixel_rgn, opti_frame, 0, 0, + g_free(oldlayer_name); + + /* Empty frame! */ + if (bbox_right <= bbox_left || + bbox_bottom <= bbox_top) + { + cumulated_delay += this_delay; + + g_free (newlayer_name); + + oldlayer_name = + gimp_layer_get_name(last_true_frame); + + buflen = strlen(oldlayer_name) + 40; + + newlayer_name = g_malloc(buflen); + + remove_disposal_tag(newlayer_name, oldlayer_name); + g_free(oldlayer_name); + + oldlayer_name = g_malloc(buflen); + + remove_ms_tag(oldlayer_name, newlayer_name); + + g_snprintf(newlayer_name, buflen, "%s(%dms)%s", + oldlayer_name, cumulated_delay, + (this_frame_num == 0) ? "" : + can_combine ? "(combine)" : "(replace)"); + + gimp_layer_set_name(last_true_frame, newlayer_name); + + g_free (newlayer_name); + } + else + { + cumulated_delay = this_delay; + + last_true_frame = + new_layer_id = gimp_layer_new(new_image_id, + newlayer_name, + bbox_right-bbox_left, + bbox_bottom-bbox_top, + drawabletype_alpha, + 100.0, + NORMAL_MODE); + g_free(newlayer_name); + + gimp_image_add_layer (new_image_id, new_layer_id, 0); + + drawable = gimp_drawable_get (new_layer_id); + + gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, bbox_right-bbox_left, - bbox_bottom-bbox_top); - gimp_drawable_flush (drawable); - gimp_drawable_detach (drawable); - gimp_layer_translate (new_layer_id, (gint)bbox_left, (gint)bbox_top); + bbox_bottom-bbox_top, + TRUE, FALSE); + gimp_pixel_rgn_set_rect (&pixel_rgn, opti_frame, 0, 0, + bbox_right-bbox_left, + bbox_bottom-bbox_top); + gimp_drawable_flush (drawable); + gimp_drawable_detach (drawable); + gimp_layer_translate (new_layer_id, (gint)bbox_left, (gint)bbox_top); + } gimp_progress_update (((double)this_frame_num+1.0) / ((double)total_frames)); @@ -859,7 +877,7 @@ do_optimizations(GRunModeType run_mode) /* Util. */ static DisposeType -get_frame_disposal (guint whichframe) +get_frame_disposal (const guint whichframe) { gchar* layer_name; DisposeType disposal; @@ -872,3 +890,203 @@ get_frame_disposal (guint whichframe) } + +static guint32 +get_frame_duration (const guint whichframe) +{ + gchar* layer_name; + gint duration = 0; + + layer_name = gimp_layer_get_name(layers[total_frames-(whichframe+1)]); + if (layer_name != NULL) + { + duration = parse_ms_tag(layer_name); + g_free(layer_name); + } + + if (duration < 0) duration = 125; /* FIXME for default-if-not-said */ + if (duration == 0) duration = 125; /* FIXME - 0-wait is nasty */ + + return ((guint32) duration); +} + + +static int +is_ms_tag (const char *str, int *duration, int *taglength) +{ + gint sum = 0; + gint offset; + gint length; + + length = strlen(str); + + if (str[0] != '(') + return 0; + + offset = 1; + + /* eat any spaces between open-parenthesis and number */ + while ((offset=length) || (!isdigit(str[offset]))) + return 0; + + do + { + sum *= 10; + sum += str[offset] - '0'; + offset++; + } + while ((offset