diff --git a/ChangeLog b/ChangeLog index e14e222e1d..3f7679d31d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2003-09-10 Michael Natterer + + * 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 * app/vectors/gimpvectors-import.c: started to add framework for diff --git a/app/xcf/xcf-load.c b/app/xcf/xcf-load.c index 959fccbb53..110398c425 100644 --- a/app/xcf/xcf-load.c +++ b/app/xcf/xcf-load.c @@ -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)); diff --git a/app/xcf/xcf-save.c b/app/xcf/xcf-save.c index 818f3e45ca..86068c3e58 100644 --- a/app/xcf/xcf-save.c +++ b/app/xcf/xcf-save.c @@ -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, ¶site->name, 1); + xcf_write_int32_check_error (info->fp, ¶site->flags, 1); + xcf_write_int32_check_error (info->fp, ¶site->size, 1); + xcf_write_int8_check_error (info->fp, parasite->data, parasite->size); + } - info->cp += xcf_write_string (info->fp, ¶site->name, 1, NULL); - info->cp += xcf_write_int32 (info->fp, ¶site->flags, 1, NULL); - info->cp += xcf_write_int32 (info->fp, ¶site->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; } -