enabled error checking for GimpParasite saving and factored

2003-09-10  Michael Natterer  <mitch@gimp.org>

	* app/xcf/xcf-save.c: enabled error checking for GimpParasite
	saving and factored GimpParasiteList saving out to a new
	function. Cleaned up the (still disabled) PROP_VECTORS saving
	code and save the vector's parasites.

	* app/xcf/xcf-load.c: changed PROP_VECTORS loading accordingly.

	Note that the PROP_VECTORS changes are completely untested since
	Simon can judge its correctness much better than myself.
This commit is contained in:
Michael Natterer 2003-09-10 16:22:33 +00:00 committed by Michael Natterer
parent 9506c7570e
commit b724e662ff
3 changed files with 244 additions and 151 deletions

View File

@ -1,3 +1,15 @@
2003-09-10 Michael Natterer <mitch@gimp.org>
* app/xcf/xcf-save.c: enabled error checking for GimpParasite
saving and factored GimpParasiteList saving out to a new
function. Cleaned up the (still disabled) PROP_VECTORS saving
code and save the vector's parasites.
* app/xcf/xcf-load.c: changed PROP_VECTORS loading accordingly.
Note that the PROP_VECTORS changes are completely untested since
Simon can judge its correctness much better than myself.
2003-09-10 Sven Neumann <sven@gimp.org>
* app/vectors/gimpvectors-import.c: started to add framework for

View File

@ -497,9 +497,12 @@ xcf_load_image_props (XcfInfo *info,
base + prop_size - info->cp);
xcf_seek_pos (info, base + prop_size, NULL);
}
} else {
}
else
{
/* skip silently since we don't understand the format and
* xcf_load_vectors already explained what was wrong */
* xcf_load_vectors already explained what was wrong
*/
xcf_seek_pos (info, base + prop_size, NULL);
}
}
@ -629,13 +632,13 @@ xcf_load_layer_props (XcfInfo *info,
}
break;
default:
g_message ("unexpected/unknown layer property: %d (skipping)",
prop_type);
{
guint8 buf[16];
guint amount;
g_message ("unexpected/unknown layer property: %d (skipping)",
prop_type);
while (prop_size > 0)
{
amount = MIN (16, prop_size);
@ -1506,9 +1509,9 @@ static gboolean
xcf_load_vectors (XcfInfo *info,
GimpImage *gimage)
{
guint32 num_paths;
guint32 last_selected_row;
guint32 version;
guint32 active_index;
guint32 num_paths;
GimpVectors *active_vectors;
guint32 base;
@ -1520,21 +1523,21 @@ xcf_load_vectors (XcfInfo *info,
if (version != 1)
{
g_warning ("Unknown vectors type %d. Possibly corrupt XCF file", version);
g_message ("Unknown vectors version: %d (skipping)", version);
return FALSE;
}
info->cp += xcf_read_int32 (info->fp, &last_selected_row, 1);
info->cp += xcf_read_int32 (info->fp, &num_paths, 1);
info->cp += xcf_read_int32 (info->fp, &active_index, 1);
info->cp += xcf_read_int32 (info->fp, &num_paths, 1);
g_printerr ("%d paths (active: %d)\n", num_paths, last_selected_row);
g_printerr ("%d paths (active: %d)\n", num_paths, active_index);
while (num_paths-- > 0)
xcf_load_vector (info, gimage);
if (! xcf_load_vector (info, gimage))
return FALSE;
active_vectors = (GimpVectors *)
gimp_container_get_child_by_index (gimage->vectors, last_selected_row);
gimp_container_get_child_by_index (gimage->vectors, active_index);
if (active_vectors)
gimp_image_set_active_vectors (gimage, active_vectors);
@ -1547,44 +1550,68 @@ static gboolean
xcf_load_vector (XcfInfo *info,
GimpImage *gimage)
{
gchar *name;
guint32 locked;
guint32 num_strokes;
GimpTattoo tattoo = 0;
GimpVectors *vectors;
gint i, j;
gchar *name;
GimpTattoo tattoo = 0;
guint32 linked;
guint32 num_parasites;
guint32 num_strokes;
GimpVectors *vectors;
gint i;
g_printerr ("xcf_load_vector\n");
info->cp += xcf_read_string (info->fp, &name, 1);
info->cp += xcf_read_int32 (info->fp, &locked, 1);
info->cp += xcf_read_int32 (info->fp, &tattoo, 1);
info->cp += xcf_read_int32 (info->fp, &num_strokes, 1);
g_printerr ("name: %s, locked: %d, tattoo: %d, num_strokes %d\n", name, locked, tattoo, num_strokes);
info->cp += xcf_read_string (info->fp, &name, 1);
info->cp += xcf_read_int32 (info->fp, &tattoo, 1);
info->cp += xcf_read_int32 (info->fp, &linked, 1);
info->cp += xcf_read_int32 (info->fp, &num_parasites, 1);
info->cp += xcf_read_int32 (info->fp, &num_strokes, 1);
g_printerr ("name: %s, tattoo: %d, linked: %d, num_parasites %d, "
"num_strokes %d\n",
name, tattoo, linked, num_parasites, num_strokes);
vectors = gimp_vectors_new (gimage, name);
GIMP_ITEM (vectors)->linked = linked;
if (tattoo)
GIMP_ITEM (vectors)->tattoo = tattoo;
for (i = 0; i < num_parasites; i++)
{
GimpParasite *parasite;
parasite = xcf_load_parasite (info);
if (! parasite)
return FALSE;
gimp_item_parasite_attach (GIMP_ITEM (vectors), parasite);
gimp_parasite_free (parasite);
}
for (i = 0; i < num_strokes; i++)
{
gint stroke_type_id;
gint closed;
gint num_axes;
gint num_control_points;
gint type;
gfloat coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
GimpStroke *stroke;
gint stroke_type_id;
gint closed;
gint num_axes;
gint num_control_points;
gint type;
gfloat coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
GimpStroke *stroke;
gint j;
GValueArray *control_points;
GValue value = { 0, };
GimpAnchor anchor;
GType stroke_type;
GValue value = { 0, };
GimpAnchor anchor;
GType stroke_type;
g_value_init (&value, gimp_anchor_get_type ());
g_value_init (&value, GIMP_TYPE_ANCHOR);
info->cp += xcf_read_int32 (info->fp, &stroke_type_id, 1);
info->cp += xcf_read_int32 (info->fp, &closed, 1);
info->cp += xcf_read_int32 (info->fp, &num_axes, 1);
info->cp += xcf_read_int32 (info->fp, &num_control_points, 1);
info->cp += xcf_read_int32 (info->fp, &stroke_type_id, 1);
info->cp += xcf_read_int32 (info->fp, &closed, 1);
info->cp += xcf_read_int32 (info->fp, &num_axes, 1);
info->cp += xcf_read_int32 (info->fp, &num_control_points, 1);
g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n",
stroke_type_id, closed, num_axes, num_control_points);
@ -1594,6 +1621,7 @@ xcf_load_vector (XcfInfo *info,
case XCF_STROKETYPE_BEZIER_STROKE:
stroke_type = gimp_bezier_stroke_get_type ();
break;
default:
g_printerr ("skipping unknown stroke type\n");
xcf_seek_pos (info,
@ -1604,9 +1632,9 @@ xcf_load_vector (XcfInfo *info,
control_points = g_value_array_new (num_control_points);
anchor.selected = FALSE;
anchor.selected = FALSE;
for (j=0; j < num_control_points; j++)
for (j = 0; j < num_control_points; j++)
{
info->cp += xcf_read_int32 (info->fp, &type, 1);
info->cp += xcf_read_float (info->fp, coords, num_axes);
@ -1625,25 +1653,18 @@ xcf_load_vector (XcfInfo *info,
g_printerr ("Anchor: %d, (%f, %f, %f, %f, %f, %f)\n", type,
coords[0], coords[1], coords[2], coords[3],
coords[4], coords[5]);
}
g_value_unset (&value);
/* here the stroke has to be created */
stroke = GIMP_STROKE (g_object_new (stroke_type,
"closed", closed,
"control-points", control_points,
NULL));
stroke = g_object_new (stroke_type,
"closed", closed,
"control-points", control_points,
NULL);
gimp_vectors_stroke_add (vectors, stroke);
}
GIMP_ITEM (vectors)->linked = locked;
if (tattoo)
GIMP_ITEM (vectors)->tattoo = tattoo;
gimp_image_add_vectors (gimage, vectors,
gimp_container_num_children (gimage->vectors));

View File

@ -64,52 +64,55 @@
#undef NEW_SAVE_CODE
static gboolean xcf_save_image_props (XcfInfo *info,
GimpImage *gimage,
GError **error);
static gboolean xcf_save_layer_props (XcfInfo *info,
GimpImage *gimage,
GimpLayer *layer,
GError **error);
static gboolean xcf_save_channel_props (XcfInfo *info,
GimpImage *gimage,
GimpChannel *channel,
GError **error);
static gboolean xcf_save_prop (XcfInfo *info,
GimpImage *gimage,
PropType prop_type,
GError **error,
static gboolean xcf_save_image_props (XcfInfo *info,
GimpImage *gimage,
GError **error);
static gboolean xcf_save_layer_props (XcfInfo *info,
GimpImage *gimage,
GimpLayer *layer,
GError **error);
static gboolean xcf_save_channel_props (XcfInfo *info,
GimpImage *gimage,
GimpChannel *channel,
GError **error);
static gboolean xcf_save_prop (XcfInfo *info,
GimpImage *gimage,
PropType prop_type,
GError **error,
...);
static gboolean xcf_save_layer (XcfInfo *info,
GimpImage *gimage,
GimpLayer *layer,
GError **error);
static gboolean xcf_save_channel (XcfInfo *info,
GimpImage *gimage,
GimpChannel *channel,
GError **error);
static gboolean xcf_save_hierarchy (XcfInfo *info,
TileManager *tiles,
GError **error);
static gboolean xcf_save_level (XcfInfo *info,
TileManager *tiles,
GError **error);
static gboolean xcf_save_tile (XcfInfo *info,
Tile *tile,
GError **error);
static gboolean xcf_save_tile_rle (XcfInfo *info,
Tile *tile,
guchar *rlebuf,
GError **error);
static void xcf_save_parasite (gchar *key,
GimpParasite *parasite,
XcfInfo *info);
static gboolean xcf_save_old_paths (XcfInfo *info,
GimpImage *gimage,
GError **error);
static gboolean xcf_save_vectors (XcfInfo *info,
GimpImage *gimage,
GError **error);
static gboolean xcf_save_layer (XcfInfo *info,
GimpImage *gimage,
GimpLayer *layer,
GError **error);
static gboolean xcf_save_channel (XcfInfo *info,
GimpImage *gimage,
GimpChannel *channel,
GError **error);
static gboolean xcf_save_hierarchy (XcfInfo *info,
TileManager *tiles,
GError **error);
static gboolean xcf_save_level (XcfInfo *info,
TileManager *tiles,
GError **error);
static gboolean xcf_save_tile (XcfInfo *info,
Tile *tile,
GError **error);
static gboolean xcf_save_tile_rle (XcfInfo *info,
Tile *tile,
guchar *rlebuf,
GError **error);
static gboolean xcf_save_parasite (XcfInfo *info,
GimpParasite *parasite,
GError **error);
static gboolean xcf_save_parasite_list (XcfInfo *info,
GimpParasiteList *parasite,
GError **error);
static gboolean xcf_save_old_paths (XcfInfo *info,
GimpImage *gimage,
GError **error);
static gboolean xcf_save_vectors (XcfInfo *info,
GimpImage *gimage,
GError **error);
/* private convieniece macros */
@ -894,8 +897,9 @@ xcf_save_prop (XcfInfo *info,
pos = info->cp;
xcf_write_int32_check_error (info->fp, &length, 1);
base = info->cp;
gimp_parasite_list_foreach (list,
(GHFunc) xcf_save_parasite, info);
xcf_check_error (xcf_save_parasite_list (info, list, error));
length = info->cp - base;
/* go back to the saved position and write the length */
xcf_check_error (xcf_seek_pos (info, pos, error));
@ -1466,20 +1470,58 @@ xcf_save_tile_rle (XcfInfo *info,
return TRUE;
}
static void
xcf_save_parasite (gchar *key,
GimpParasite *parasite,
XcfInfo *info)
static gboolean
xcf_save_parasite (XcfInfo *info,
GimpParasite *parasite,
GError **error)
{
/* can't fail fast because there is no way to exit g_slist_foreach */
if (gimp_parasite_is_persistent (parasite))
{
GError *tmp_error = NULL;
if (! gimp_parasite_is_persistent (parasite))
return;
xcf_write_string_check_error (info->fp, &parasite->name, 1);
xcf_write_int32_check_error (info->fp, &parasite->flags, 1);
xcf_write_int32_check_error (info->fp, &parasite->size, 1);
xcf_write_int8_check_error (info->fp, parasite->data, parasite->size);
}
info->cp += xcf_write_string (info->fp, &parasite->name, 1, NULL);
info->cp += xcf_write_int32 (info->fp, &parasite->flags, 1, NULL);
info->cp += xcf_write_int32 (info->fp, &parasite->size, 1, NULL);
info->cp += xcf_write_int8 (info->fp, parasite->data, parasite->size, NULL);
return TRUE;
}
typedef struct
{
XcfInfo *info;
GError *error;
} XcfParasiteData;
static void
xcf_save_parasite_func (gchar *key,
GimpParasite *parasite,
XcfParasiteData *data)
{
if (! data->error)
xcf_save_parasite (data->info, parasite, &data->error);
}
static gboolean
xcf_save_parasite_list (XcfInfo *info,
GimpParasiteList *list,
GError **error)
{
XcfParasiteData data;
data.info = info;
data.error = NULL;
gimp_parasite_list_foreach (list, (GHFunc) xcf_save_parasite_func, &data);
if (data.error)
{
g_propagate_error (error, data.error);
return FALSE;
}
return TRUE;
}
static gboolean
@ -1594,77 +1636,93 @@ xcf_save_vectors (XcfInfo *info,
GError **error)
{
GimpVectors *active_vectors;
guint32 num_paths;
guint32 version = 1;
guint32 active_index = 0;
guint32 version = 1;
guint32 num_paths;
GList *list;
GList *stroke_list;
GError *tmp_error = NULL;
/* Write out the following:-
*
* last_selected_row (gint)
* number_of_paths (gint)
* version (gint)
* active_index (gint)
* num_paths (gint)
*
* then each path:-
*/
num_paths = gimp_container_num_children (gimage->vectors);
active_vectors = gimp_image_get_active_vectors (gimage);
if (active_vectors)
active_index = gimp_container_get_child_index (gimage->vectors,
GIMP_OBJECT (active_vectors));
num_paths = gimp_container_num_children (gimage->vectors);
xcf_write_int32_check_error (info->fp, &version, 1);
xcf_write_int32_check_error (info->fp, &active_index, 1);
xcf_write_int32_check_error (info->fp, &num_paths, 1);
g_printerr ("%d paths (active: %d)\n", num_paths, active_index);
g_printerr ("%d paths (active: %d, version: %d)\n",
num_paths, active_index, version);
for (list = GIMP_LIST (gimage->vectors)->list;
list;
list = g_list_next (list))
{
GimpVectors *vectors = list->data;
gchar *name;
guint32 locked;
guint32 num_strokes;
guint32 tattoo;
GimpVectors *vectors = list->data;
GimpParasiteList *parasites;
gchar *name;
guint32 tattoo;
guint32 linked;
guint32 num_parasites;
guint32 num_strokes;
/*
* name (string)
* locked (gint)
* tattoo (gint)
* number strokes (gint)
* linked (gint)
* num_parasites (gint)
* num_strokes (gint)
*
* then each stroke.
* then each parasite
* then each stroke
*/
name = (gchar *) gimp_object_get_name (GIMP_OBJECT (vectors));
locked = gimp_item_get_linked (GIMP_ITEM (vectors));
tattoo = gimp_item_get_tattoo (GIMP_ITEM (vectors));
num_strokes = g_list_length (vectors->strokes);
parasites = GIMP_ITEM (vectors)->parasites;
xcf_write_string_check_error (info->fp, &name, 1);
xcf_write_int32_check_error (info->fp, &locked, 1);
xcf_write_int32_check_error (info->fp, &tattoo, 1);
xcf_write_int32_check_error (info->fp, &num_strokes, 1);
name = (gchar *) gimp_object_get_name (GIMP_OBJECT (vectors));
linked = gimp_item_get_linked (GIMP_ITEM (vectors));
tattoo = gimp_item_get_tattoo (GIMP_ITEM (vectors));
num_parasites = gimp_parasite_list_persistent_length (parasites);
num_strokes = g_list_length (vectors->strokes);
g_printerr ("name: %s, version: %d, locked: %d, tattoo: %d, num_strokes %d\n", name, version, locked, tattoo, num_strokes);
xcf_write_string_check_error (info->fp, &name, 1);
xcf_write_int32_check_error (info->fp, &tattoo, 1);
xcf_write_int32_check_error (info->fp, &linked, 1);
xcf_write_int32_check_error (info->fp, &num_parasites, 1);
xcf_write_int32_check_error (info->fp, &num_strokes, 1);
g_printerr ("name: %s, tattoo: %d, linked: %d, num_parasites %d, "
"num_strokes %d\n",
name, tattoo, linked, num_parasites, num_strokes);
xcf_check_error (xcf_save_parasite_list (info, parasites, error));
for (stroke_list = g_list_first (vectors->strokes);
stroke_list;
stroke_list = g_list_next (stroke_list))
{
GimpStroke *stroke;
gint stroke_type, closed, num_axes;
GArray *control_points;
gint i;
guint32 stroke_type;
guint32 closed;
guint32 num_axes;
GArray *control_points;
gint i;
gint type;
gfloat coords[6];
guint32 type;
gfloat coords[6];
/*
* stroke_type (gint)
@ -1690,10 +1748,10 @@ xcf_save_vectors (XcfInfo *info,
control_points = gimp_stroke_control_points_get (stroke, &closed);
xcf_write_int32_check_error (info->fp, &stroke_type, 1);
xcf_write_int32_check_error (info->fp, &closed, 1);
xcf_write_int32_check_error (info->fp, &num_axes, 1);
xcf_write_int32_check_error (info->fp, &(control_points->len), 1);
xcf_write_int32_check_error (info->fp, &stroke_type, 1);
xcf_write_int32_check_error (info->fp, &closed, 1);
xcf_write_int32_check_error (info->fp, &num_axes, 1);
xcf_write_int32_check_error (info->fp, &control_points->len, 1);
g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n",
stroke_type, closed, num_axes, control_points->len);
@ -1704,7 +1762,7 @@ xcf_save_vectors (XcfInfo *info,
anchor = & (g_array_index (control_points, GimpAnchor, i));
type = anchor->type;
type = anchor->type;
coords[0] = anchor->position.x;
coords[1] = anchor->position.y;
coords[2] = anchor->position.pressure;
@ -1714,11 +1772,14 @@ xcf_save_vectors (XcfInfo *info,
/*
* type (gint)
* x (gfloat)
* y (gfloat)
* ....
* wheel (gfloat)
* (but only the first num_axis elements)
*
* the first num_axis elements of:
* [0] x (gfloat)
* [1] y (gfloat)
* [2] pressure (gfloat)
* [3] xtilt (gfloat)
* [4] ytilt (gfloat)
* [5] wheel (gfloat)
*/
xcf_write_int32_check_error (info->fp, &type, 1);
@ -1735,4 +1796,3 @@ xcf_save_vectors (XcfInfo *info,
return TRUE;
}