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> 2003-09-10 Sven Neumann <sven@gimp.org>
* app/vectors/gimpvectors-import.c: started to add framework for * 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); base + prop_size - info->cp);
xcf_seek_pos (info, base + prop_size, NULL); xcf_seek_pos (info, base + prop_size, NULL);
} }
} else { }
else
{
/* skip silently since we don't understand the format and /* 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); xcf_seek_pos (info, base + prop_size, NULL);
} }
} }
@ -629,13 +632,13 @@ xcf_load_layer_props (XcfInfo *info,
} }
break; break;
default: default:
g_message ("unexpected/unknown layer property: %d (skipping)",
prop_type);
{ {
guint8 buf[16]; guint8 buf[16];
guint amount; guint amount;
g_message ("unexpected/unknown layer property: %d (skipping)",
prop_type);
while (prop_size > 0) while (prop_size > 0)
{ {
amount = MIN (16, prop_size); amount = MIN (16, prop_size);
@ -1506,9 +1509,9 @@ static gboolean
xcf_load_vectors (XcfInfo *info, xcf_load_vectors (XcfInfo *info,
GimpImage *gimage) GimpImage *gimage)
{ {
guint32 num_paths;
guint32 last_selected_row;
guint32 version; guint32 version;
guint32 active_index;
guint32 num_paths;
GimpVectors *active_vectors; GimpVectors *active_vectors;
guint32 base; guint32 base;
@ -1520,21 +1523,21 @@ xcf_load_vectors (XcfInfo *info,
if (version != 1) if (version != 1)
{ {
g_warning ("Unknown vectors type %d. Possibly corrupt XCF file", version); g_message ("Unknown vectors version: %d (skipping)", version);
return FALSE; return FALSE;
} }
info->cp += xcf_read_int32 (info->fp, &last_selected_row, 1); info->cp += xcf_read_int32 (info->fp, &active_index, 1);
info->cp += xcf_read_int32 (info->fp, &num_paths, 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) while (num_paths-- > 0)
xcf_load_vector (info, gimage); if (! xcf_load_vector (info, gimage))
return FALSE;
active_vectors = (GimpVectors *) 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) if (active_vectors)
gimp_image_set_active_vectors (gimage, active_vectors); gimp_image_set_active_vectors (gimage, active_vectors);
@ -1548,22 +1551,45 @@ xcf_load_vector (XcfInfo *info,
GimpImage *gimage) GimpImage *gimage)
{ {
gchar *name; gchar *name;
guint32 locked;
guint32 num_strokes;
GimpTattoo tattoo = 0; GimpTattoo tattoo = 0;
guint32 linked;
guint32 num_parasites;
guint32 num_strokes;
GimpVectors *vectors; GimpVectors *vectors;
gint i, j; gint i;
g_printerr ("xcf_load_vector\n"); g_printerr ("xcf_load_vector\n");
info->cp += xcf_read_string (info->fp, &name, 1); 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, &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); 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); 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); 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++) for (i = 0; i < num_strokes; i++)
{ {
gint stroke_type_id; gint stroke_type_id;
@ -1573,13 +1599,14 @@ xcf_load_vector (XcfInfo *info,
gint type; gint type;
gfloat coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 }; gfloat coords[6] = { 0.0, 0.0, 1.0, 0.5, 0.5, 0.5 };
GimpStroke *stroke; GimpStroke *stroke;
gint j;
GValueArray *control_points; GValueArray *control_points;
GValue value = { 0, }; GValue value = { 0, };
GimpAnchor anchor; GimpAnchor anchor;
GType stroke_type; 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, &stroke_type_id, 1);
info->cp += xcf_read_int32 (info->fp, &closed, 1); info->cp += xcf_read_int32 (info->fp, &closed, 1);
@ -1594,6 +1621,7 @@ xcf_load_vector (XcfInfo *info,
case XCF_STROKETYPE_BEZIER_STROKE: case XCF_STROKETYPE_BEZIER_STROKE:
stroke_type = gimp_bezier_stroke_get_type (); stroke_type = gimp_bezier_stroke_get_type ();
break; break;
default: default:
g_printerr ("skipping unknown stroke type\n"); g_printerr ("skipping unknown stroke type\n");
xcf_seek_pos (info, xcf_seek_pos (info,
@ -1606,7 +1634,7 @@ xcf_load_vector (XcfInfo *info,
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_int32 (info->fp, &type, 1);
info->cp += xcf_read_float (info->fp, coords, num_axes); 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, g_printerr ("Anchor: %d, (%f, %f, %f, %f, %f, %f)\n", type,
coords[0], coords[1], coords[2], coords[3], coords[0], coords[1], coords[2], coords[3],
coords[4], coords[5]); coords[4], coords[5]);
} }
g_value_unset (&value); g_value_unset (&value);
/* here the stroke has to be created */ stroke = g_object_new (stroke_type,
stroke = GIMP_STROKE (g_object_new (stroke_type,
"closed", closed, "closed", closed,
"control-points", control_points, "control-points", control_points,
NULL)); NULL);
gimp_vectors_stroke_add (vectors, stroke); 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_image_add_vectors (gimage, vectors,
gimp_container_num_children (gimage->vectors)); gimp_container_num_children (gimage->vectors));

View File

@ -101,9 +101,12 @@ static gboolean xcf_save_tile_rle (XcfInfo *info,
Tile *tile, Tile *tile,
guchar *rlebuf, guchar *rlebuf,
GError **error); GError **error);
static void xcf_save_parasite (gchar *key, static gboolean xcf_save_parasite (XcfInfo *info,
GimpParasite *parasite, GimpParasite *parasite,
XcfInfo *info); GError **error);
static gboolean xcf_save_parasite_list (XcfInfo *info,
GimpParasiteList *parasite,
GError **error);
static gboolean xcf_save_old_paths (XcfInfo *info, static gboolean xcf_save_old_paths (XcfInfo *info,
GimpImage *gimage, GimpImage *gimage,
GError **error); GError **error);
@ -894,8 +897,9 @@ xcf_save_prop (XcfInfo *info,
pos = info->cp; pos = info->cp;
xcf_write_int32_check_error (info->fp, &length, 1); xcf_write_int32_check_error (info->fp, &length, 1);
base = info->cp; 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; length = info->cp - base;
/* go back to the saved position and write the length */ /* go back to the saved position and write the length */
xcf_check_error (xcf_seek_pos (info, pos, error)); xcf_check_error (xcf_seek_pos (info, pos, error));
@ -1466,20 +1470,58 @@ xcf_save_tile_rle (XcfInfo *info,
return TRUE; return TRUE;
} }
static void static gboolean
xcf_save_parasite (gchar *key, xcf_save_parasite (XcfInfo *info,
GimpParasite *parasite, GimpParasite *parasite,
XcfInfo *info) 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)) xcf_write_string_check_error (info->fp, &parasite->name, 1);
return; 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); return TRUE;
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); 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 static gboolean
@ -1594,76 +1636,92 @@ xcf_save_vectors (XcfInfo *info,
GError **error) GError **error)
{ {
GimpVectors *active_vectors; GimpVectors *active_vectors;
guint32 num_paths;
guint32 active_index = 0;
guint32 version = 1; guint32 version = 1;
guint32 active_index = 0;
guint32 num_paths;
GList *list; GList *list;
GList *stroke_list; GList *stroke_list;
GError *tmp_error = NULL; GError *tmp_error = NULL;
/* Write out the following:- /* Write out the following:-
* *
* last_selected_row (gint) * version (gint)
* number_of_paths (gint) * active_index (gint)
* num_paths (gint)
* *
* then each path:- * then each path:-
*/ */
num_paths = gimp_container_num_children (gimage->vectors);
active_vectors = gimp_image_get_active_vectors (gimage); active_vectors = gimp_image_get_active_vectors (gimage);
if (active_vectors) if (active_vectors)
active_index = gimp_container_get_child_index (gimage->vectors, active_index = gimp_container_get_child_index (gimage->vectors,
GIMP_OBJECT (active_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, &version, 1);
xcf_write_int32_check_error (info->fp, &active_index, 1); xcf_write_int32_check_error (info->fp, &active_index, 1);
xcf_write_int32_check_error (info->fp, &num_paths, 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; for (list = GIMP_LIST (gimage->vectors)->list;
list; list;
list = g_list_next (list)) list = g_list_next (list))
{ {
GimpVectors *vectors = list->data; GimpVectors *vectors = list->data;
GimpParasiteList *parasites;
gchar *name; gchar *name;
guint32 locked;
guint32 num_strokes;
guint32 tattoo; guint32 tattoo;
guint32 linked;
guint32 num_parasites;
guint32 num_strokes;
/* /*
* name (string) * name (string)
* locked (gint)
* tattoo (gint) * tattoo (gint)
* number strokes (gint) * linked (gint)
* num_parasites (gint)
* num_strokes (gint)
* *
* then each stroke. * then each parasite
* then each stroke
*/ */
parasites = GIMP_ITEM (vectors)->parasites;
name = (gchar *) gimp_object_get_name (GIMP_OBJECT (vectors)); name = (gchar *) gimp_object_get_name (GIMP_OBJECT (vectors));
locked = gimp_item_get_linked (GIMP_ITEM (vectors)); linked = gimp_item_get_linked (GIMP_ITEM (vectors));
tattoo = gimp_item_get_tattoo (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); num_strokes = g_list_length (vectors->strokes);
xcf_write_string_check_error (info->fp, &name, 1); 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, &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); xcf_write_int32_check_error (info->fp, &num_strokes, 1);
g_printerr ("name: %s, version: %d, locked: %d, tattoo: %d, num_strokes %d\n", name, version, locked, tattoo, num_strokes); 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); for (stroke_list = g_list_first (vectors->strokes);
stroke_list; stroke_list;
stroke_list = g_list_next (stroke_list)) stroke_list = g_list_next (stroke_list))
{ {
GimpStroke *stroke; GimpStroke *stroke;
gint stroke_type, closed, num_axes; guint32 stroke_type;
guint32 closed;
guint32 num_axes;
GArray *control_points; GArray *control_points;
gint i; gint i;
gint type; guint32 type;
gfloat coords[6]; gfloat coords[6];
/* /*
@ -1693,7 +1751,7 @@ xcf_save_vectors (XcfInfo *info,
xcf_write_int32_check_error (info->fp, &stroke_type, 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, &closed, 1);
xcf_write_int32_check_error (info->fp, &num_axes, 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, &control_points->len, 1);
g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n", g_printerr ("stroke_type: %d, closed: %d, num_axes %d, len %d\n",
stroke_type, closed, num_axes, control_points->len); stroke_type, closed, num_axes, control_points->len);
@ -1714,11 +1772,14 @@ xcf_save_vectors (XcfInfo *info,
/* /*
* type (gint) * type (gint)
* x (gfloat) *
* y (gfloat) * the first num_axis elements of:
* .... * [0] x (gfloat)
* wheel (gfloat) * [1] y (gfloat)
* (but only the first num_axis elements) * [2] pressure (gfloat)
* [3] xtilt (gfloat)
* [4] ytilt (gfloat)
* [5] wheel (gfloat)
*/ */
xcf_write_int32_check_error (info->fp, &type, 1); xcf_write_int32_check_error (info->fp, &type, 1);
@ -1735,4 +1796,3 @@ xcf_save_vectors (XcfInfo *info,
return TRUE; return TRUE;
} }