app/xcf/xcf-load.c app/xcf/xcf-private.h app/xcf/xcf-save.c do progress

2006-07-11  Sven Neumann  <sven@gimp.org>

	* app/xcf/xcf-load.c
	* app/xcf/xcf-private.h
	* app/xcf/xcf-save.c
	* app/xcf/xcf.c: do progress updates when loading/saving XCF
files.
This commit is contained in:
Sven Neumann 2006-07-11 20:21:18 +00:00 committed by Sven Neumann
parent b2252db16c
commit 676c625c24
5 changed files with 121 additions and 31 deletions

View File

@ -1,3 +1,10 @@
2006-07-11 Sven Neumann <sven@gimp.org>
* app/xcf/xcf-load.c
* app/xcf/xcf-private.h
* app/xcf/xcf-save.c
* app/xcf/xcf.c: do progress updates when loading/saving XCF files.
2006-07-11 Sven Neumann <sven@gimp.org> 2006-07-11 Sven Neumann <sven@gimp.org>
* app/xcf/xcf.c: minor cleanup. * app/xcf/xcf.c: minor cleanup.

View File

@ -45,6 +45,7 @@
#include "core/gimplayer-floating-sel.h" #include "core/gimplayer-floating-sel.h"
#include "core/gimplayermask.h" #include "core/gimplayermask.h"
#include "core/gimpparasitelist.h" #include "core/gimpparasitelist.h"
#include "core/gimpprogress.h"
#include "core/gimpselection.h" #include "core/gimpselection.h"
#include "core/gimptemplate.h" #include "core/gimptemplate.h"
#include "core/gimpunit.h" #include "core/gimpunit.h"
@ -65,6 +66,7 @@
#include "gimp-intl.h" #include "gimp-intl.h"
/* #define GIMP_XCF_PATH_DEBUG */ /* #define GIMP_XCF_PATH_DEBUG */
static gboolean xcf_load_image_props (XcfInfo *info, static gboolean xcf_load_image_props (XcfInfo *info,
@ -115,6 +117,13 @@ static gboolean xcf_swap_func (gint fd,
#endif #endif
#define xcf_progress_update(info) G_STMT_START \
{ \
if (info->progress) \
gimp_progress_pulse (info->progress); \
} G_STMT_END
GimpImage * GimpImage *
xcf_load_image (Gimp *gimp, xcf_load_image (Gimp *gimp,
XcfInfo *info) XcfInfo *info)
@ -135,13 +144,12 @@ xcf_load_image (Gimp *gimp,
info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1); info->cp += xcf_read_int32 (info->fp, (guint32 *) &height, 1);
info->cp += xcf_read_int32 (info->fp, (guint32 *) &image_type, 1); info->cp += xcf_read_int32 (info->fp, (guint32 *) &image_type, 1);
image = gimp_create_image (gimp, image = gimp_create_image (gimp, width, height, image_type, FALSE);
width, height,
image_type,
FALSE);
gimp_image_undo_disable (image); gimp_image_undo_disable (image);
xcf_progress_update (info);
/* read the image properties */ /* read the image properties */
if (! xcf_load_image_props (info, image)) if (! xcf_load_image_props (info, image))
goto hard_error; goto hard_error;
@ -162,6 +170,8 @@ xcf_load_image (Gimp *gimp,
} }
} }
xcf_progress_update (info);
while (TRUE) while (TRUE)
{ {
/* read in the offset of the next layer */ /* read in the offset of the next layer */
@ -189,6 +199,8 @@ xcf_load_image (Gimp *gimp,
num_successful_elements++; num_successful_elements++;
xcf_progress_update (info);
/* add the layer to the image if its not the floating selection */ /* add the layer to the image if its not the floating selection */
if (layer != info->floating_sel) if (layer != info->floating_sel)
gimp_image_add_layer (image, layer, gimp_image_add_layer (image, layer,
@ -228,6 +240,8 @@ xcf_load_image (Gimp *gimp,
num_successful_elements++; num_successful_elements++;
xcf_progress_update (info);
/* add the channel to the image if its not the selection */ /* add the channel to the image if its not the selection */
if (channel != image->selection_mask) if (channel != image->selection_mask)
gimp_image_add_channel (image, channel, -1); gimp_image_add_channel (image, channel, -1);
@ -900,6 +914,8 @@ xcf_load_layer (XcfInfo *info,
&text_layer_flags)) &text_layer_flags))
goto error; goto error;
xcf_progress_update (info);
/* call the evil text layer hack that might change our layer pointer */ /* call the evil text layer hack that might change our layer pointer */
active = (info->active_layer == layer); active = (info->active_layer == layer);
floating = (info->floating_sel == layer); floating = (info->floating_sel == layer);
@ -926,6 +942,8 @@ xcf_load_layer (XcfInfo *info,
if (! xcf_load_hierarchy (info, GIMP_DRAWABLE (layer)->tiles)) if (! xcf_load_hierarchy (info, GIMP_DRAWABLE (layer)->tiles))
goto error; goto error;
xcf_progress_update (info);
/* read in the layer mask */ /* read in the layer mask */
if (layer_mask_offset != 0) if (layer_mask_offset != 0)
{ {
@ -936,6 +954,8 @@ xcf_load_layer (XcfInfo *info,
if (! layer_mask) if (! layer_mask)
goto error; goto error;
xcf_progress_update (info);
layer_mask->apply_mask = apply_mask; layer_mask->apply_mask = apply_mask;
layer_mask->edit_mask = edit_mask; layer_mask->edit_mask = edit_mask;
layer_mask->show_mask = show_mask; layer_mask->show_mask = show_mask;
@ -986,6 +1006,8 @@ xcf_load_channel (XcfInfo *info,
if (!xcf_load_channel_props (info, image, &channel)) if (!xcf_load_channel_props (info, image, &channel))
goto error; goto error;
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */ /* read the hierarchy and layer mask offsets */
info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1); info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
@ -996,6 +1018,8 @@ xcf_load_channel (XcfInfo *info,
if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (channel)->tiles)) if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (channel)->tiles))
goto error; goto error;
xcf_progress_update (info);
if (is_fs_drawable) if (is_fs_drawable)
info->floating_sel_drawable = GIMP_DRAWABLE (channel); info->floating_sel_drawable = GIMP_DRAWABLE (channel);
@ -1040,6 +1064,8 @@ xcf_load_layer_mask (XcfInfo *info,
if (!xcf_load_channel_props (info, image, &channel)) if (!xcf_load_channel_props (info, image, &channel))
goto error; goto error;
xcf_progress_update (info);
/* read the hierarchy and layer mask offsets */ /* read the hierarchy and layer mask offsets */
info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1); info->cp += xcf_read_int32 (info->fp, &hierarchy_offset, 1);
@ -1050,6 +1076,8 @@ xcf_load_layer_mask (XcfInfo *info,
if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (layer_mask)->tiles)) if (!xcf_load_hierarchy (info, GIMP_DRAWABLE (layer_mask)->tiles))
goto error; goto error;
xcf_progress_update (info);
/* attach the floating selection... */ /* attach the floating selection... */
if (is_fs_drawable) if (is_fs_drawable)
info->floating_sel_drawable = GIMP_DRAWABLE (layer_mask); info->floating_sel_drawable = GIMP_DRAWABLE (layer_mask);

View File

@ -88,6 +88,7 @@ struct _XcfInfo
gint *ref_count; gint *ref_count;
XcfCompressionType compression; XcfCompressionType compression;
gint file_version; gint file_version;
GimpProgress *progress;
}; };

View File

@ -44,6 +44,7 @@
#include "core/gimplayermask.h" #include "core/gimplayermask.h"
#include "core/gimplist.h" #include "core/gimplist.h"
#include "core/gimpparasitelist.h" #include "core/gimpparasitelist.h"
#include "core/gimpprogress.h"
#include "core/gimpunit.h" #include "core/gimpunit.h"
#include "text/gimptextlayer.h" #include "text/gimptextlayer.h"
@ -215,6 +216,14 @@ static gboolean xcf_save_vectors (XcfInfo *info,
} \ } \
} G_STMT_END } G_STMT_END
#define xcf_progress_update(info) G_STMT_START \
{ \
progress++; \
if (info->progress) \
gimp_progress_set_value (info->progress, \
(gdouble) progress / (gdouble) max_progress); \
} G_STMT_END
void void
xcf_save_choose_format (XcfInfo *info, xcf_save_choose_format (XcfInfo *info,
@ -263,10 +272,12 @@ xcf_save_image (XcfInfo *info,
guint32 offset; guint32 offset;
guint nlayers; guint nlayers;
guint nchannels; guint nchannels;
guint progress = 0;
guint max_progress;
GList *list; GList *list;
gboolean have_selection; gboolean have_selection;
gint t1, t2, t3, t4; gint t1, t2, t3, t4;
gchar version_tag[14]; gchar version_tag[16];
GError *error = NULL; GError *error = NULL;
floating_layer = gimp_image_floating_sel (image); floating_layer = gimp_image_floating_sel (image);
@ -282,6 +293,7 @@ xcf_save_image (XcfInfo *info,
{ {
strcpy (version_tag, "gimp xcf file"); strcpy (version_tag, "gimp xcf file");
} }
xcf_write_int8_print_error (info, (guint8 *) version_tag, 14); xcf_write_int8_print_error (info, (guint8 *) version_tag, 14);
/* write out the width, height and image type information for the image */ /* write out the width, height and image type information for the image */
@ -293,6 +305,8 @@ xcf_save_image (XcfInfo *info,
nlayers = (guint) gimp_container_num_children (image->layers); nlayers = (guint) gimp_container_num_children (image->layers);
nchannels = (guint) gimp_container_num_children (image->channels); nchannels = (guint) gimp_container_num_children (image->channels);
max_progress = 1 + nlayers + nchannels;
/* check and see if we have to save out the selection */ /* check and see if we have to save out the selection */
have_selection = gimp_channel_bounds (gimp_image_get_mask (image), have_selection = gimp_channel_bounds (gimp_image_get_mask (image),
&t1, &t2, &t3, &t4); &t1, &t2, &t3, &t4);
@ -304,6 +318,8 @@ xcf_save_image (XcfInfo *info,
xcf_print_error (xcf_save_image_props (info, image, &error)); xcf_print_error (xcf_save_image_props (info, image, &error));
xcf_progress_update (info);
/* save the current file position as it is the start of where /* save the current file position as it is the start of where
* we place the layer offset information. * we place the layer offset information.
*/ */
@ -318,7 +334,7 @@ xcf_save_image (XcfInfo *info,
list; list;
list = g_list_next (list)) list = g_list_next (list))
{ {
layer = (GimpLayer *) list->data; layer = list->data;
/* save the start offset of where we are writing /* save the start offset of where we are writing
* out the next layer. * out the next layer.
@ -328,6 +344,8 @@ xcf_save_image (XcfInfo *info,
/* write out the layer. */ /* write out the layer. */
xcf_print_error (xcf_save_layer (info, image, layer, &error)); xcf_print_error (xcf_save_layer (info, image, layer, &error));
xcf_progress_update (info);
/* seek back to where we are to write out the next /* seek back to where we are to write out the next
* layer offset and write it out. * layer offset and write it out.
*/ */
@ -360,7 +378,7 @@ xcf_save_image (XcfInfo *info,
{ {
if (list) if (list)
{ {
channel = (GimpChannel *) list->data; channel = list->data;
list = g_list_next (list); list = g_list_next (list);
} }
@ -378,6 +396,8 @@ xcf_save_image (XcfInfo *info,
/* write out the layer. */ /* write out the layer. */
xcf_print_error (xcf_save_channel (info, image, channel, &error)); xcf_print_error (xcf_save_channel (info, image, channel, &error));
xcf_progress_update (info);
/* seek back to where we are to write out the next /* seek back to where we are to write out the next
* channel offset and write it out. * channel offset and write it out.
*/ */
@ -628,7 +648,7 @@ xcf_save_prop (XcfInfo *info,
guchar *colors; guchar *colors;
ncolors = va_arg (args, guint32); ncolors = va_arg (args, guint32);
colors = va_arg (args, guchar*); colors = va_arg (args, guchar *);
size = 4 + ncolors * 3; size = 4 + ncolors * 3;
xcf_write_prop_type_check_error (info, prop_type); xcf_write_prop_type_check_error (info, prop_type);
@ -1392,17 +1412,10 @@ xcf_save_tile_rle (XcfInfo *info,
guchar *rlebuf, guchar *rlebuf,
GError **error) GError **error)
{ {
guchar *data, *t;
unsigned int last;
gint state;
gint length;
gint count;
gint size;
gint bpp;
gint i, j;
gint len = 0;
GError *tmp_error = NULL; GError *tmp_error = NULL;
gint len = 0;
gint bpp;
gint i, j;
tile_lock (tile); tile_lock (tile);
@ -1410,13 +1423,13 @@ xcf_save_tile_rle (XcfInfo *info,
for (i = 0; i < bpp; i++) for (i = 0; i < bpp; i++)
{ {
data = (guchar*) tile_data_pointer (tile, 0, 0) + i; const guchar *data = tile_data_pointer (tile, 0, 0) + i;
state = 0; gint state = 0;
length = 0; gint length = 0;
count = 0; gint count = 0;
size = tile_ewidth(tile) * tile_eheight(tile); gint size = tile_ewidth (tile) * tile_eheight (tile);
last = -1; guint last = -1;
while (size > 0) while (size > 0)
{ {
@ -1431,6 +1444,7 @@ xcf_save_tile_rle (XcfInfo *info,
((length > 1) && (last != *data))) ((length > 1) && (last != *data)))
{ {
count += length; count += length;
if (length >= 128) if (length >= 128)
{ {
rlebuf[len++] = 127; rlebuf[len++] = 127;
@ -1443,11 +1457,14 @@ xcf_save_tile_rle (XcfInfo *info,
rlebuf[len++] = length - 1; rlebuf[len++] = length - 1;
rlebuf[len++] = last; rlebuf[len++] = last;
} }
size -= length; size -= length;
length = 0; length = 0;
} }
else if ((length == 1) && (last != *data)) else if ((length == 1) && (last != *data))
state = 1; {
state = 1;
}
break; break;
case 1: case 1:
@ -1459,6 +1476,8 @@ xcf_save_tile_rle (XcfInfo *info,
((length > 0) && (last == *data) && ((length > 0) && (last == *data) &&
((size - length) == 1 || last == data[bpp]))) ((size - length) == 1 || last == data[bpp])))
{ {
const guchar *t;
count += length; count += length;
state = 0; state = 0;
@ -1474,6 +1493,7 @@ xcf_save_tile_rle (XcfInfo *info,
} }
t = data - length * bpp; t = data - length * bpp;
for (j = 0; j < length; j++) for (j = 0; j < length; j++)
{ {
rlebuf[len++] = *t; rlebuf[len++] = *t;
@ -1486,16 +1506,18 @@ xcf_save_tile_rle (XcfInfo *info,
break; break;
} }
if (size > 0) { if (size > 0)
length += 1; {
last = *data; length += 1;
data += bpp; last = *data;
} data += bpp;
}
} }
if (count != (tile_ewidth (tile) * tile_eheight (tile))) if (count != (tile_ewidth (tile) * tile_eheight (tile)))
g_message ("xcf: uh oh! xcf rle tile saving error: %d", count); g_message ("xcf: uh oh! xcf rle tile saving error: %d", count);
} }
xcf_write_int8_check_error (info, rlebuf, len); xcf_write_int8_check_error (info, rlebuf, len);
tile_release (tile, FALSE); tile_release (tile, FALSE);

View File

@ -32,6 +32,7 @@
#include "core/gimp.h" #include "core/gimp.h"
#include "core/gimpimage.h" #include "core/gimpimage.h"
#include "core/gimpparamspecs.h" #include "core/gimpparamspecs.h"
#include "core/gimpprogress.h"
#include "pdb/gimppluginprocedure.h" #include "pdb/gimppluginprocedure.h"
@ -254,6 +255,18 @@ xcf_load_invoker (GimpProcedure *procedure,
info.swap_num = 0; info.swap_num = 0;
info.ref_count = NULL; info.ref_count = NULL;
info.compression = COMPRESS_NONE; info.compression = COMPRESS_NONE;
info.progress = progress;
if (progress)
{
gchar *name = g_filename_display_name (filename);
gchar *msg = g_strdup_printf (_("Opening '%s'"), name);
gimp_progress_start (progress, msg, FALSE);
g_free (msg);
g_free (name);
}
success = TRUE; success = TRUE;
@ -278,7 +291,8 @@ xcf_load_invoker (GimpProcedure *procedure,
if (success) if (success)
{ {
if (info.file_version < G_N_ELEMENTS (xcf_loaders)) if (info.file_version >= 0 &&
info.file_version < G_N_ELEMENTS (xcf_loaders))
{ {
image = (*(xcf_loaders[info.file_version])) (gimp, &info); image = (*(xcf_loaders[info.file_version])) (gimp, &info);
@ -294,6 +308,9 @@ xcf_load_invoker (GimpProcedure *procedure,
} }
fclose (info.fp); fclose (info.fp);
if (progress)
gimp_progress_end (progress);
} }
else else
{ {
@ -343,6 +360,18 @@ xcf_save_invoker (GimpProcedure *procedure,
info.swap_num = 0; info.swap_num = 0;
info.ref_count = NULL; info.ref_count = NULL;
info.compression = COMPRESS_RLE; info.compression = COMPRESS_RLE;
info.progress = progress;
if (progress)
{
gchar *name = g_filename_display_name (filename);
gchar *msg = g_strdup_printf (_("Saving '%s'"), name);
gimp_progress_start (progress, msg, FALSE);
g_free (msg);
g_free (name);
}
xcf_save_choose_format (&info, image); xcf_save_choose_format (&info, image);
@ -354,6 +383,9 @@ xcf_save_invoker (GimpProcedure *procedure,
success = FALSE; success = FALSE;
} }
if (progress)
gimp_progress_end (progress);
} }
else else
{ {