From fe3fa4e2e5834f08a56ecd2e2215ed1bfbf350a3 Mon Sep 17 00:00:00 2001 From: jaycox Date: Wed, 16 Dec 1998 11:23:30 +0000 Subject: [PATCH] libgimp/gserialize.c Changed the enum values to allow for simpler future * libgimp/gserialize.c * libgimp/gserialize.h: Changed the enum values to allow for simpler future expansion. * libgimp/parasite.c * libgimp/parasite.h: s/persistant/persistent/. new accessor functions for parasites. #defines for new flags. * app/paintbrush.c: added timeing code for brush strokes. It is #ifed out, and is only valid for shift clicks. * app/parasite_cmds.h: fixed a warning * app/parasitelist.h * app/parasitelist.c: added _for_each and _length functions * app/gimpdrawable.c: set the dirty flag when adding or removing a persistent parasite * app/gimpimage.c: set the dirty flag when adding or removing a persistent parasite. Fixed bug and removed debug statements in merge_down. * app/xcf.c: save and load resolution, parasites, and tattoos. * app/main.c: updated the deserialize test. * plug-ins/tiff/tiff.c * plug-ins/gif/gif.c: use PARASITE_PERSISTENT define instead of 1 * plug-ins/bmp/bmp.c * plug-ins/bmp/bmp.h: declare some struct variable as extern. * app/paint_funcs.c: Lots of optimizations aimed at speeding up painting. Should see a 2-4X speed up on most painting (depending on paint modes, brush size etc.) * app/drawable.c: check for NULL drawable in drawable_ID. this stops us from being crashed by ill-behaved plug-ins --- ChangeLog | 42 ++++++ app/core/gimpdrawable.c | 23 ++- app/core/gimpimage-guides.c | 17 ++- app/core/gimpimage-merge.c | 17 ++- app/core/gimpimage-projection.c | 17 ++- app/core/gimpimage-resize.c | 17 ++- app/core/gimpimage-scale.c | 17 ++- app/core/gimpimage.c | 17 ++- app/core/gimpparasitelist.c | 43 ++++++ app/core/gimpparasitelist.h | 6 + app/core/gimpprojection-construct.c | 17 ++- app/drawable.c | 6 +- app/gimpdrawable.c | 23 ++- app/gimpimage.c | 17 ++- app/main.c | 2 +- app/paint-funcs/paint-funcs.c | 219 +++++++++++++++++++--------- app/paint_funcs.c | 219 +++++++++++++++++++--------- app/paintbrush.c | 26 ++++ app/parasite_cmds.h | 2 +- app/parasitelist.c | 43 ++++++ app/parasitelist.h | 6 + app/tools/paintbrush.c | 26 ++++ app/xcf.c | 181 ++++++++++++++++++++++- app/xcf/xcf.c | 181 ++++++++++++++++++++++- libgimp/gimpparasite.c | 28 +++- libgimp/gimpparasite.h | 17 ++- libgimp/gserialize.c | 11 +- libgimp/gserialize.h | 28 ++-- libgimp/parasite.c | 28 +++- libgimp/parasite.h | 17 ++- libgimpbase/gimpparasite.c | 28 +++- libgimpbase/gimpparasite.h | 17 ++- plug-ins/bmp/bmp.c | 3 + plug-ins/bmp/bmp.h | 6 +- plug-ins/common/gif.c | 2 +- plug-ins/common/tiff.c | 3 +- plug-ins/gif/gif.c | 2 +- plug-ins/tiff/tiff.c | 3 +- 38 files changed, 1162 insertions(+), 215 deletions(-) diff --git a/ChangeLog b/ChangeLog index e5a80e289d..1d50e3fa2a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +1998-12-16 Jay Cox + + * libgimp/gserialize.c + * libgimp/gserialize.h: Changed the enum values to allow for + simpler future expansion. + + * libgimp/parasite.c + * libgimp/parasite.h: s/persistant/persistent/. + new accessor functions for parasites. #defines for new flags. + + * app/paintbrush.c: added timeing code for brush strokes. + It is #ifed out, and is only valid for shift clicks. + + * app/parasite_cmds.h: fixed a warning + + * app/parasitelist.h + * app/parasitelist.c: added _for_each and _length functions + + * app/gimpdrawable.c: set the dirty flag when adding or removing a + persistent parasite + + * app/gimpimage.c: set the dirty flag when adding or removing a + persistent parasite. Fixed bug and removed debug statements in + merge_down. + + * app/xcf.c: save and load resolution, parasites, and tattoos. + + * app/main.c: updated the deserialize test. + + * plug-ins/tiff/tiff.c + * plug-ins/gif/gif.c: use PARASITE_PERSISTENT define instead of 1 + + * plug-ins/bmp/bmp.c + * plug-ins/bmp/bmp.h: declare some struct variable as extern. + + * app/paint_funcs.c: Lots of optimizations aimed at speeding up + painting. Should see a 2-4X speed up on most painting + (depending on paint modes, brush size etc.) + + * app/drawable.c: check for NULL drawable in drawable_ID. + this stops us from being crashed by ill-behaved plug-ins + Tue Dec 15 16:18:40 PST 1998 Manish Singh * app/*: stuff from patches/i18n by Daniel Egger diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c index eb8293a77b..efbb952313 100644 --- a/app/core/gimpdrawable.c +++ b/app/core/gimpdrawable.c @@ -26,6 +26,7 @@ #include "gimage_mask.h" #include "parasitelist.h" +#include "libgimp/parasite.h" #include "libgimp/gimpintl.h" enum { @@ -260,11 +261,11 @@ void gimp_drawable_set_gimage (GimpDrawable *drawable, GimpImage *gimage) { g_assert(GIMP_IS_DRAWABLE(drawable)); - drawable->gimage = gimage; if (gimage == NULL) drawable->tattoo = 0; - else + else if (drawable->tattoo == 0 || drawable->gimage != gimage ) drawable->tattoo = gimp_image_get_new_tattoo(gimage); + drawable->gimage = gimage; } @@ -383,11 +384,29 @@ void gimp_drawable_attach_parasite (GimpDrawable *drawable, Parasite *parasite) { parasite_list_add(drawable->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(drawable->gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_image_attach_parasite(drawable->gimage, parasite); + } + else if (parasite_has_flag(parasite, PARASITE_ATTACH_GRANDPARENT)) + { + parasite_shift_parent(parasite); + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_drawable_detach_parasite (GimpDrawable *drawable, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(drawable->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(drawable->gimage); parasite_list_remove(drawable->parasites, parasite); } diff --git a/app/core/gimpimage-guides.c b/app/core/gimpimage-guides.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage-guides.c +++ b/app/core/gimpimage-guides.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpimage-merge.c b/app/core/gimpimage-merge.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage-merge.c +++ b/app/core/gimpimage-merge.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpimage-projection.c b/app/core/gimpimage-projection.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage-projection.c +++ b/app/core/gimpimage-projection.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpimage-resize.c b/app/core/gimpimage-resize.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage-resize.c +++ b/app/core/gimpimage-resize.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpimage-scale.c b/app/core/gimpimage-scale.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage-scale.c +++ b/app/core/gimpimage-scale.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/core/gimpparasitelist.c b/app/core/gimpparasitelist.c index 48e955af3e..95d9678ce9 100644 --- a/app/core/gimpparasitelist.c +++ b/app/core/gimpparasitelist.c @@ -144,6 +144,7 @@ parasite_list_add(ParasiteList *list, Parasite *p) list->table = g_hash_table_new(g_str_hash, parasite_compare_func); g_return_if_fail(p != NULL); g_return_if_fail(p->name != NULL); + parasite_list_remove(list, p->name); p = parasite_copy(p); g_hash_table_insert(list->table, p->name, p); gtk_signal_emit (GTK_OBJECT(list), parasite_list_signals[ADD], p); @@ -166,6 +167,41 @@ parasite_list_remove(ParasiteList *list, const char *name) } } +gint +parasite_list_length(ParasiteList *list) +{ + g_return_val_if_fail(list != NULL, 0); + if (!list->table) + return 0; + return g_hash_table_size(list->table); +} + +static void ppcount_func(char *key, Parasite *p, int *count) +{ + if (parasite_is_persistent(p)) + *count = *count + 1; +} + +gint +parasite_list_persistent_length(ParasiteList *list) +{ + int ppcount = 0; + g_return_val_if_fail(list != NULL, 0); + if (!list->table) + return 0; + parasite_list_foreach(list, (GHFunc)ppcount_func, &ppcount); + return ppcount; +} + +void +parasite_list_foreach(ParasiteList *list, GHFunc function, gpointer user_data) +{ + g_return_if_fail(list != NULL); + if (!list->table) + return; + g_hash_table_foreach(list->table, function, user_data); +} + Parasite * parasite_list_find(ParasiteList *list, const char *name) { @@ -177,3 +213,10 @@ parasite_list_find(ParasiteList *list, const char *name) } +void +parasite_shift_parent(Parasite *p) +{ + if (p == NULL) + return; + p->flags = (p->flags >> 8); +} diff --git a/app/core/gimpparasitelist.h b/app/core/gimpparasitelist.h index 256c4da9c9..a4d086b6af 100644 --- a/app/core/gimpparasitelist.h +++ b/app/core/gimpparasitelist.h @@ -40,6 +40,12 @@ ParasiteList *parasite_list_new (void); ParasiteList *parasite_list_copy (const ParasiteList *list); void parasite_list_add (ParasiteList *list, Parasite *p); void parasite_list_remove (ParasiteList *list, const char *name); +gint parasite_list_length (ParasiteList *list); +gint parasite_list_persistent_length (ParasiteList *list); +void parasite_list_foreach (ParasiteList *list, GHFunc function, + gpointer user_data); Parasite *parasite_list_find (ParasiteList *list, const char *name); +void parasite_shift_parent (Parasite *p); + #endif /* __GIMP_PARASITE_H__ */ diff --git a/app/core/gimpprojection-construct.c b/app/core/gimpprojection-construct.c index 30fc44dce7..addfe621ee 100644 --- a/app/core/gimpprojection-construct.c +++ b/app/core/gimpprojection-construct.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/drawable.c b/app/drawable.c index 99d0d28e17..9621b49891 100644 --- a/app/drawable.c +++ b/app/drawable.c @@ -29,7 +29,11 @@ int drawable_ID (GimpDrawable *drawable) { - return drawable->ID; + if (drawable) + return drawable->ID; + else + g_warning("drawable_ID called on a NULL pointer"); + return 0; } void diff --git a/app/gimpdrawable.c b/app/gimpdrawable.c index eb8293a77b..efbb952313 100644 --- a/app/gimpdrawable.c +++ b/app/gimpdrawable.c @@ -26,6 +26,7 @@ #include "gimage_mask.h" #include "parasitelist.h" +#include "libgimp/parasite.h" #include "libgimp/gimpintl.h" enum { @@ -260,11 +261,11 @@ void gimp_drawable_set_gimage (GimpDrawable *drawable, GimpImage *gimage) { g_assert(GIMP_IS_DRAWABLE(drawable)); - drawable->gimage = gimage; if (gimage == NULL) drawable->tattoo = 0; - else + else if (drawable->tattoo == 0 || drawable->gimage != gimage ) drawable->tattoo = gimp_image_get_new_tattoo(gimage); + drawable->gimage = gimage; } @@ -383,11 +384,29 @@ void gimp_drawable_attach_parasite (GimpDrawable *drawable, Parasite *parasite) { parasite_list_add(drawable->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(drawable->gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_image_attach_parasite(drawable->gimage, parasite); + } + else if (parasite_has_flag(parasite, PARASITE_ATTACH_GRANDPARENT)) + { + parasite_shift_parent(parasite); + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_drawable_detach_parasite (GimpDrawable *drawable, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(drawable->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(drawable->gimage); parasite_list_remove(drawable->parasites, parasite); } diff --git a/app/gimpimage.c b/app/gimpimage.c index 30fc44dce7..addfe621ee 100644 --- a/app/gimpimage.c +++ b/app/gimpimage.c @@ -893,11 +893,23 @@ void gimp_image_attach_parasite (GimpImage *gimage, Parasite *parasite) { parasite_list_add(gimage->parasites, parasite); + if (parasite_is_persistent(parasite)) /* make sure we can be saved */ + gimp_image_dirty(gimage); + if (parasite_has_flag(parasite, PARASITE_ATTACH_PARENT)) + { + parasite_shift_parent(parasite); + gimp_attach_parasite(parasite); + } } void gimp_image_detach_parasite (GimpImage *gimage, const char *parasite) { + Parasite *p; + if (!(p = parasite_list_find(gimage->parasites, parasite))) + return; + if (parasite_is_persistent(p)) + gimp_image_dirty(gimage); parasite_list_remove(gimage->parasites, parasite); } @@ -2025,8 +2037,6 @@ gimp_image_merge_down (GimpImage *gimage, layer = (Layer *) layer_list->data; if (layer == current_layer) { - printf ("found it\n"); - layer_list = g_slist_next (layer_list); while (layer_list) { @@ -2034,7 +2044,6 @@ gimp_image_merge_down (GimpImage *gimage, if (drawable_visible (GIMP_DRAWABLE(layer))) { merge_list = g_slist_append (merge_list, layer); - printf ("found the next\n"); layer_list = NULL; } else @@ -2042,6 +2051,8 @@ gimp_image_merge_down (GimpImage *gimage, } merge_list = g_slist_prepend (merge_list, current_layer); } + else + layer_list = g_slist_next (layer_list); } if (merge_list && merge_list->next) diff --git a/app/main.c b/app/main.c index c063c2356e..9c5d830570 100644 --- a/app/main.c +++ b/app/main.c @@ -402,7 +402,7 @@ static void test_gserialize() { GSerialDescription *test_struct_descript; test_struct *ts, *to; - char ser_1[] = {3, 1, 2, 3, 4, 4, 64, 83, 51, 51, 6, 0, 0, 0, 4, 102, 111, 111, 0, 8, 0, 0, 0, 2, 5, 6, 7, 8 }; + char ser_1[] = {3, 1, 2, 3, 4, 4, 64, 83, 51, 51, 101, 0, 0, 0, 4, 102, 111, 111, 0, 103, 0, 0, 0, 2, 5, 6, 7, 8 }; ts = g_malloc(sizeof(test_struct)); to = g_malloc(sizeof(test_struct)); test_struct_descript diff --git a/app/paint-funcs/paint-funcs.c b/app/paint-funcs/paint-funcs.c index dd2f3a8e00..23b47c66f9 100644 --- a/app/paint-funcs/paint-funcs.c +++ b/app/paint-funcs/paint-funcs.c @@ -40,6 +40,9 @@ #define EPSILON 0.0001 #define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8)) +#define INT_MULT3(a,b,c,t) ((t) = (a) * (b) * (c)+ 0x100, \ + ((((t) >> 16) + (t)) >> 16)) +#define INT_BLEND(a,b,alpha,tmp) (INT_MULT(a-b, alpha,tmp) + b) typedef enum { @@ -718,18 +721,38 @@ multiply_pixels (const unsigned char *src1, int has_alpha2) { int alpha, b; - + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; - while (length --) + if (has_alpha1 && has_alpha2) + while (length --) { for (b = 0; b < alpha; b++) - dest[b] = (src1[b] * src2[b]) / 255; + dest[b] = INT_MULT(src1[b], src2[b], tmp); - if (has_alpha1 && has_alpha2) - dest[alpha] = MIN (src1[alpha], src2[alpha]); - else if (has_alpha2) - dest[alpha] = src2[alpha]; + dest[alpha] = MIN (src1[alpha], src2[alpha]); + + src1 += bytes1; + src2 += bytes2; + dest += bytes2; + } + else if (has_alpha2) + while (length --) + { + for (b = 0; b < alpha; b++) + dest[b] = INT_MULT(src1[b], src2[b], tmp); + + dest[alpha] = src2[alpha]; + + src1 += bytes1; + src2 += bytes2; + dest += bytes2; + } + else + while (length --) + { + for (b = 0; b < alpha; b++) + dest[b] = INT_MULT(src1[b], src2[b], tmp); src1 += bytes1; src2 += bytes2; @@ -782,13 +805,14 @@ screen_pixels (const unsigned char *src1, int has_alpha2) { int alpha, b; + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; while (length --) { for (b = 0; b < alpha; b++) - dest[b] = 255 - ((255 - src1[b]) * (255 - src2[b])) / 255; + dest[b] = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp); if (has_alpha1 && has_alpha2) dest[alpha] = MIN (src1[alpha], src2[alpha]); @@ -814,6 +838,7 @@ overlay_pixels (const unsigned char *src1, { int alpha, b; int screen, mult; + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; @@ -821,9 +846,9 @@ overlay_pixels (const unsigned char *src1, { for (b = 0; b < alpha; b++) { - screen = 255 - ((255 - src1[b]) * (255 - src2[b])) / 255; - mult = (src1[b] * src2[b]) / 255; - dest[b] = (screen * src1[b] + mult * (255 - src1[b])) / 255; + screen = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp); + mult = INT_MULT(src1[b] ,src2[b], tmp); + dest[b] = INT_BLEND(screen , mult, src1[b], tmp); } if (has_alpha1 && has_alpha2) @@ -1062,8 +1087,12 @@ scale_pixels (const unsigned char *src, int length, int scale) { + int tmp; while (length --) - *dest++ = (unsigned char) ((*src++ * scale) / 255); + { + *dest++ = (unsigned char) INT_MULT(*src,scale,tmp); + src++; + } } @@ -1145,12 +1174,20 @@ apply_mask_to_alpha_channel (unsigned char *src, int length, int bytes) { - int alpha; - - alpha = bytes - 1; - while (length --) + long tmp; + src += bytes - 1; + if (opacity == 255) + while (length --) { - src[alpha] = (src[alpha] * *mask++ * opacity) / 65025; + *src = INT_MULT(*src, *mask, tmp); + mask++; + src += bytes; + } + else + while (length --) + { + *src = INT_MULT3(*src, *mask, opacity, tmp); + mask++; src += bytes; } } @@ -1163,16 +1200,27 @@ combine_mask_and_alpha_channel (unsigned char *src, int length, int bytes) { - unsigned char mask_val; + int mask_val; int alpha; - + int tmp; alpha = bytes - 1; - while (length --) + src += alpha; + + if (opacity != 255) + while (length --) { - mask_val = (*mask++ * opacity) / 255; - src[alpha] = src[alpha] + ((255 - src[alpha]) * mask_val) / 255; + mask_val = INT_MULT(*mask, opacity, tmp); + mask++; + *src = *src + INT_MULT((255 - *src) , mask_val, tmp); src += bytes; } + else + while (length --) + { + *src = *src + INT_MULT((255 - *src) , *mask, tmp); + src += bytes; + mask++; + } } @@ -1287,6 +1335,10 @@ initial_inten_pixels (const unsigned char *src, { int b, dest_bytes; const unsigned char * m; + int tmp; + int l; + unsigned char *destp; + const unsigned char *srcp; if (mask) m = mask; @@ -1298,34 +1350,41 @@ initial_inten_pixels (const unsigned char *src, */ dest_bytes = bytes + 1; - if (mask) + for (b =0; b < bytes; b++) + { + destp = dest + b; + srcp = src + b; + l = length; + if (affect[b]) + while(l--) + { + *destp = *srcp; + srcp += bytes; + destp += dest_bytes; + } + else + while(l--) + { + *destp = 0; + destp += dest_bytes; + } + } +/* fill the alpha channel */ + if (!affect[bytes]) + opacity = 0; + destp = dest + bytes; + if (mask && opacity != 0) + while (length--) { - while (length --) - { - for (b = 0; b < bytes; b++) - dest [b] = affect [b] ? src [b] : 0; - - /* Set the alpha channel */ - dest[b] = affect [b] ? (opacity * *m) / 255 : 0; - - m++; - dest += dest_bytes; - src += bytes; - } + *destp = INT_MULT(opacity , *m, tmp); + destp += dest_bytes; + m++; } else + while (length--) { - while (length --) - { - for (b = 0; b < bytes; b++) - dest [b] = affect [b] ? src [b] : 0; - - /* Set the alpha channel */ - dest[b] = affect [b] ? opacity : 0; - - dest += dest_bytes; - src += bytes; - } + *destp = opacity; + destp += dest_bytes; } } @@ -1341,6 +1400,7 @@ initial_inten_a_pixels (const unsigned char *src, { int alpha, b; const unsigned char * m; + int tmp; alpha = bytes - 1; if (mask) @@ -1368,7 +1428,7 @@ initial_inten_a_pixels (const unsigned char *src, dest[b] = src[b] * affect[b]; /* Set the alpha channel */ - dest[alpha] = affect [alpha] ? (opacity * src[alpha]) / 255 : 0; + dest[alpha] = affect [alpha] ? INT_MULT(opacity , src[alpha], tmp) : 0; dest += bytes; src += bytes; @@ -1390,13 +1450,13 @@ combine_indexed_and_indexed_pixels (const unsigned char *src1, int b; unsigned char new_alpha; const unsigned char * m; - + int tmp; if (mask) { m = mask; while (length --) { - new_alpha = (*m * opacity) / 255; + new_alpha = INT_MULT(*m , opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1439,7 +1499,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, unsigned char new_alpha; const unsigned char * m; int src2_bytes; - + long tmp; alpha = 1; src2_bytes = 2; @@ -1448,7 +1508,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1464,7 +1524,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1490,6 +1550,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, int b, alpha; unsigned char new_alpha; const unsigned char * m; + long tmp; alpha = 1; @@ -1498,7 +1559,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); for (b = 0; b < alpha; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1516,7 +1577,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); for (b = 0; b < alpha; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1545,6 +1606,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, unsigned char new_alpha; int src2_bytes; int index; + long tmp; alpha = 1; src2_bytes = 2; @@ -1554,7 +1616,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, const unsigned char *m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); index = src2[0] * 3; @@ -1574,7 +1636,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); index = src2[0] * 3; @@ -1606,17 +1668,17 @@ combine_inten_and_inten_pixels (const unsigned char *src1, int b; unsigned char new_alpha; const unsigned char * m; - + int tmp; if (mask) { m = mask; while (length --) { - new_alpha = (*m * opacity) / 255; + new_alpha = INT_MULT(*m, opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b], src1[b], new_alpha, tmp) : src1[b]; m++; @@ -1630,11 +1692,10 @@ combine_inten_and_inten_pixels (const unsigned char *src1, { while (length --) { - new_alpha = opacity; for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b], src1[b], opacity, tmp) : src1[b]; src1 += bytes; @@ -1659,7 +1720,7 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, int src2_bytes; unsigned char new_alpha; const unsigned char * m; - + register int t1; alpha = bytes; src2_bytes = bytes + 1; @@ -1672,8 +1733,8 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : - src1[b]; + INT_BLEND(src2[b], src1[b], new_alpha, t1) : + src1[b]; m++; src1 += bytes; @@ -1683,13 +1744,23 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, } else { + if (bytes == 3 && affect[0] && affect[1] && affect[2]) + while (length --) + { + new_alpha = INT_MULT(src2[alpha],opacity,t1); + dest[0] = INT_BLEND(src2[0] , src1[0] , new_alpha, t1); + dest[1] = INT_BLEND(src2[1] , src1[1] , new_alpha, t1); + dest[2] = INT_BLEND(src2[2] , src1[2] , new_alpha, t1); + src1 += bytes; + src2 += src2_bytes; + dest += bytes; + } while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; - + new_alpha = INT_MULT(src2[alpha],opacity,t1); for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b] , src1[b] , new_alpha, t1) : src1[b]; src1 += bytes; @@ -2540,7 +2611,6 @@ map_rgb_to_indexed (const unsigned char *cmap, /* REGION FUNCTIONS */ /**************************************************/ - void color_region (PixelRegion *dest, const unsigned char *col) @@ -2554,11 +2624,21 @@ color_region (PixelRegion *dest, h = dest->h; s = dest->data; - while (h--) + if (dest->w*dest->bytes == dest->rowstride) + { + /* do it all in one function call if we can */ + /* this hasn't been tested to see if it is a + signifigant speed gain yet */ + color_pixels (s, col, dest->w*h, dest->bytes); + } + else + { + while (h--) { color_pixels (s, col, dest->w, dest->bytes); s += dest->rowstride; } + } } } @@ -4492,7 +4572,6 @@ combine_regions (PixelRegion *src1, unsigned char * d, * m; unsigned char * buf; void * pr; - combine = 0; /* Determine which sources have alpha channels */ diff --git a/app/paint_funcs.c b/app/paint_funcs.c index dd2f3a8e00..23b47c66f9 100644 --- a/app/paint_funcs.c +++ b/app/paint_funcs.c @@ -40,6 +40,9 @@ #define EPSILON 0.0001 #define INT_MULT(a,b,t) ((t) = (a) * (b) + 0x80, ((((t) >> 8) + (t)) >> 8)) +#define INT_MULT3(a,b,c,t) ((t) = (a) * (b) * (c)+ 0x100, \ + ((((t) >> 16) + (t)) >> 16)) +#define INT_BLEND(a,b,alpha,tmp) (INT_MULT(a-b, alpha,tmp) + b) typedef enum { @@ -718,18 +721,38 @@ multiply_pixels (const unsigned char *src1, int has_alpha2) { int alpha, b; - + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; - while (length --) + if (has_alpha1 && has_alpha2) + while (length --) { for (b = 0; b < alpha; b++) - dest[b] = (src1[b] * src2[b]) / 255; + dest[b] = INT_MULT(src1[b], src2[b], tmp); - if (has_alpha1 && has_alpha2) - dest[alpha] = MIN (src1[alpha], src2[alpha]); - else if (has_alpha2) - dest[alpha] = src2[alpha]; + dest[alpha] = MIN (src1[alpha], src2[alpha]); + + src1 += bytes1; + src2 += bytes2; + dest += bytes2; + } + else if (has_alpha2) + while (length --) + { + for (b = 0; b < alpha; b++) + dest[b] = INT_MULT(src1[b], src2[b], tmp); + + dest[alpha] = src2[alpha]; + + src1 += bytes1; + src2 += bytes2; + dest += bytes2; + } + else + while (length --) + { + for (b = 0; b < alpha; b++) + dest[b] = INT_MULT(src1[b], src2[b], tmp); src1 += bytes1; src2 += bytes2; @@ -782,13 +805,14 @@ screen_pixels (const unsigned char *src1, int has_alpha2) { int alpha, b; + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; while (length --) { for (b = 0; b < alpha; b++) - dest[b] = 255 - ((255 - src1[b]) * (255 - src2[b])) / 255; + dest[b] = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp); if (has_alpha1 && has_alpha2) dest[alpha] = MIN (src1[alpha], src2[alpha]); @@ -814,6 +838,7 @@ overlay_pixels (const unsigned char *src1, { int alpha, b; int screen, mult; + int tmp; alpha = (has_alpha1 || has_alpha2) ? MAXIMUM (bytes1, bytes2) - 1 : bytes1; @@ -821,9 +846,9 @@ overlay_pixels (const unsigned char *src1, { for (b = 0; b < alpha; b++) { - screen = 255 - ((255 - src1[b]) * (255 - src2[b])) / 255; - mult = (src1[b] * src2[b]) / 255; - dest[b] = (screen * src1[b] + mult * (255 - src1[b])) / 255; + screen = 255 - INT_MULT((255 - src1[b]), (255 - src2[b]), tmp); + mult = INT_MULT(src1[b] ,src2[b], tmp); + dest[b] = INT_BLEND(screen , mult, src1[b], tmp); } if (has_alpha1 && has_alpha2) @@ -1062,8 +1087,12 @@ scale_pixels (const unsigned char *src, int length, int scale) { + int tmp; while (length --) - *dest++ = (unsigned char) ((*src++ * scale) / 255); + { + *dest++ = (unsigned char) INT_MULT(*src,scale,tmp); + src++; + } } @@ -1145,12 +1174,20 @@ apply_mask_to_alpha_channel (unsigned char *src, int length, int bytes) { - int alpha; - - alpha = bytes - 1; - while (length --) + long tmp; + src += bytes - 1; + if (opacity == 255) + while (length --) { - src[alpha] = (src[alpha] * *mask++ * opacity) / 65025; + *src = INT_MULT(*src, *mask, tmp); + mask++; + src += bytes; + } + else + while (length --) + { + *src = INT_MULT3(*src, *mask, opacity, tmp); + mask++; src += bytes; } } @@ -1163,16 +1200,27 @@ combine_mask_and_alpha_channel (unsigned char *src, int length, int bytes) { - unsigned char mask_val; + int mask_val; int alpha; - + int tmp; alpha = bytes - 1; - while (length --) + src += alpha; + + if (opacity != 255) + while (length --) { - mask_val = (*mask++ * opacity) / 255; - src[alpha] = src[alpha] + ((255 - src[alpha]) * mask_val) / 255; + mask_val = INT_MULT(*mask, opacity, tmp); + mask++; + *src = *src + INT_MULT((255 - *src) , mask_val, tmp); src += bytes; } + else + while (length --) + { + *src = *src + INT_MULT((255 - *src) , *mask, tmp); + src += bytes; + mask++; + } } @@ -1287,6 +1335,10 @@ initial_inten_pixels (const unsigned char *src, { int b, dest_bytes; const unsigned char * m; + int tmp; + int l; + unsigned char *destp; + const unsigned char *srcp; if (mask) m = mask; @@ -1298,34 +1350,41 @@ initial_inten_pixels (const unsigned char *src, */ dest_bytes = bytes + 1; - if (mask) + for (b =0; b < bytes; b++) + { + destp = dest + b; + srcp = src + b; + l = length; + if (affect[b]) + while(l--) + { + *destp = *srcp; + srcp += bytes; + destp += dest_bytes; + } + else + while(l--) + { + *destp = 0; + destp += dest_bytes; + } + } +/* fill the alpha channel */ + if (!affect[bytes]) + opacity = 0; + destp = dest + bytes; + if (mask && opacity != 0) + while (length--) { - while (length --) - { - for (b = 0; b < bytes; b++) - dest [b] = affect [b] ? src [b] : 0; - - /* Set the alpha channel */ - dest[b] = affect [b] ? (opacity * *m) / 255 : 0; - - m++; - dest += dest_bytes; - src += bytes; - } + *destp = INT_MULT(opacity , *m, tmp); + destp += dest_bytes; + m++; } else + while (length--) { - while (length --) - { - for (b = 0; b < bytes; b++) - dest [b] = affect [b] ? src [b] : 0; - - /* Set the alpha channel */ - dest[b] = affect [b] ? opacity : 0; - - dest += dest_bytes; - src += bytes; - } + *destp = opacity; + destp += dest_bytes; } } @@ -1341,6 +1400,7 @@ initial_inten_a_pixels (const unsigned char *src, { int alpha, b; const unsigned char * m; + int tmp; alpha = bytes - 1; if (mask) @@ -1368,7 +1428,7 @@ initial_inten_a_pixels (const unsigned char *src, dest[b] = src[b] * affect[b]; /* Set the alpha channel */ - dest[alpha] = affect [alpha] ? (opacity * src[alpha]) / 255 : 0; + dest[alpha] = affect [alpha] ? INT_MULT(opacity , src[alpha], tmp) : 0; dest += bytes; src += bytes; @@ -1390,13 +1450,13 @@ combine_indexed_and_indexed_pixels (const unsigned char *src1, int b; unsigned char new_alpha; const unsigned char * m; - + int tmp; if (mask) { m = mask; while (length --) { - new_alpha = (*m * opacity) / 255; + new_alpha = INT_MULT(*m , opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1439,7 +1499,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, unsigned char new_alpha; const unsigned char * m; int src2_bytes; - + long tmp; alpha = 1; src2_bytes = 2; @@ -1448,7 +1508,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1464,7 +1524,7 @@ combine_indexed_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1490,6 +1550,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, int b, alpha; unsigned char new_alpha; const unsigned char * m; + long tmp; alpha = 1; @@ -1498,7 +1559,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); for (b = 0; b < alpha; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1516,7 +1577,7 @@ combine_indexed_a_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); for (b = 0; b < alpha; b++) dest[b] = (affect[b] && new_alpha > 127) ? src2[b] : src1[b]; @@ -1545,6 +1606,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, unsigned char new_alpha; int src2_bytes; int index; + long tmp; alpha = 1; src2_bytes = 2; @@ -1554,7 +1616,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, const unsigned char *m = mask; while (length --) { - new_alpha = (src2[alpha] * *m * opacity) / 65025; + new_alpha = INT_MULT3(src2[alpha], *m, opacity, tmp); index = src2[0] * 3; @@ -1574,7 +1636,7 @@ combine_inten_a_and_indexed_a_pixels (const unsigned char *src1, { while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; + new_alpha = INT_MULT(src2[alpha], opacity, tmp); index = src2[0] * 3; @@ -1606,17 +1668,17 @@ combine_inten_and_inten_pixels (const unsigned char *src1, int b; unsigned char new_alpha; const unsigned char * m; - + int tmp; if (mask) { m = mask; while (length --) { - new_alpha = (*m * opacity) / 255; + new_alpha = INT_MULT(*m, opacity, tmp); for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b], src1[b], new_alpha, tmp) : src1[b]; m++; @@ -1630,11 +1692,10 @@ combine_inten_and_inten_pixels (const unsigned char *src1, { while (length --) { - new_alpha = opacity; for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b], src1[b], opacity, tmp) : src1[b]; src1 += bytes; @@ -1659,7 +1720,7 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, int src2_bytes; unsigned char new_alpha; const unsigned char * m; - + register int t1; alpha = bytes; src2_bytes = bytes + 1; @@ -1672,8 +1733,8 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : - src1[b]; + INT_BLEND(src2[b], src1[b], new_alpha, t1) : + src1[b]; m++; src1 += bytes; @@ -1683,13 +1744,23 @@ combine_inten_and_inten_a_pixels (const unsigned char *src1, } else { + if (bytes == 3 && affect[0] && affect[1] && affect[2]) + while (length --) + { + new_alpha = INT_MULT(src2[alpha],opacity,t1); + dest[0] = INT_BLEND(src2[0] , src1[0] , new_alpha, t1); + dest[1] = INT_BLEND(src2[1] , src1[1] , new_alpha, t1); + dest[2] = INT_BLEND(src2[2] , src1[2] , new_alpha, t1); + src1 += bytes; + src2 += src2_bytes; + dest += bytes; + } while (length --) { - new_alpha = (src2[alpha] * opacity) / 255; - + new_alpha = INT_MULT(src2[alpha],opacity,t1); for (b = 0; b < bytes; b++) dest[b] = (affect[b]) ? - (src2[b] * new_alpha + src1[b] * (255 - new_alpha)) / 255 : + INT_BLEND(src2[b] , src1[b] , new_alpha, t1) : src1[b]; src1 += bytes; @@ -2540,7 +2611,6 @@ map_rgb_to_indexed (const unsigned char *cmap, /* REGION FUNCTIONS */ /**************************************************/ - void color_region (PixelRegion *dest, const unsigned char *col) @@ -2554,11 +2624,21 @@ color_region (PixelRegion *dest, h = dest->h; s = dest->data; - while (h--) + if (dest->w*dest->bytes == dest->rowstride) + { + /* do it all in one function call if we can */ + /* this hasn't been tested to see if it is a + signifigant speed gain yet */ + color_pixels (s, col, dest->w*h, dest->bytes); + } + else + { + while (h--) { color_pixels (s, col, dest->w, dest->bytes); s += dest->rowstride; } + } } } @@ -4492,7 +4572,6 @@ combine_regions (PixelRegion *src1, unsigned char * d, * m; unsigned char * buf; void * pr; - combine = 0; /* Determine which sources have alpha channels */ diff --git a/app/paintbrush.c b/app/paintbrush.c index 8c79419968..d3645b066e 100644 --- a/app/paintbrush.c +++ b/app/paintbrush.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include "appenv.h" #include "gimpbrushlist.h" @@ -133,14 +134,31 @@ create_paint_options (void) return options; } +#define USE_SPEEDSHOP_CALIPERS 0 +#define TIMED_BRUSH 0 + +#if USE_SPEEDSHOP_CALIPERS +#include +#endif + void * paintbrush_paint_func (PaintCore *paint_core, GimpDrawable *drawable, int state) { +#if TIMED_BRUSH + static GTimer *timer; +#endif switch (state) { case INIT_PAINT : +#if TIMED_BRUSH + timer = g_timer_new(); + g_timer_start(timer); +#if USE_SPEEDSHOP_CALIPERS + ssrt_caliper_point(0, "Painting"); +#endif /* USE_SPEEDSHOP_CALIPERS */ +#endif /* TIMED_BRUSH */ break; case MOTION_PAINT : @@ -148,6 +166,14 @@ paintbrush_paint_func (PaintCore *paint_core, break; case FINISH_PAINT : +#if TIMED_BRUSH +#if USE_SPEEDSHOP_CALIPERS + ssrt_caliper_point(0, "Not Painting Anymore"); +#endif /* USE_SPEEDSHOP_CALIPERS */ + g_timer_stop(timer); + printf("painting took %f:\n", g_timer_elapsed(timer, NULL)); + g_timer_destroy(timer); +#endif /* TIMED_BRUSH */ break; default : diff --git a/app/parasite_cmds.h b/app/parasite_cmds.h index d22b0d1dc4..e37322c996 100644 --- a/app/parasite_cmds.h +++ b/app/parasite_cmds.h @@ -25,4 +25,4 @@ extern ProcRecord gimp_find_parasite_proc; extern ProcRecord gimp_attach_parasite_proc; extern ProcRecord gimp_detach_parasite_proc; -#endif __PARASITE_CMDS_H__ +#endif /* __PARASITE_CMDS_H__ */ diff --git a/app/parasitelist.c b/app/parasitelist.c index 48e955af3e..95d9678ce9 100644 --- a/app/parasitelist.c +++ b/app/parasitelist.c @@ -144,6 +144,7 @@ parasite_list_add(ParasiteList *list, Parasite *p) list->table = g_hash_table_new(g_str_hash, parasite_compare_func); g_return_if_fail(p != NULL); g_return_if_fail(p->name != NULL); + parasite_list_remove(list, p->name); p = parasite_copy(p); g_hash_table_insert(list->table, p->name, p); gtk_signal_emit (GTK_OBJECT(list), parasite_list_signals[ADD], p); @@ -166,6 +167,41 @@ parasite_list_remove(ParasiteList *list, const char *name) } } +gint +parasite_list_length(ParasiteList *list) +{ + g_return_val_if_fail(list != NULL, 0); + if (!list->table) + return 0; + return g_hash_table_size(list->table); +} + +static void ppcount_func(char *key, Parasite *p, int *count) +{ + if (parasite_is_persistent(p)) + *count = *count + 1; +} + +gint +parasite_list_persistent_length(ParasiteList *list) +{ + int ppcount = 0; + g_return_val_if_fail(list != NULL, 0); + if (!list->table) + return 0; + parasite_list_foreach(list, (GHFunc)ppcount_func, &ppcount); + return ppcount; +} + +void +parasite_list_foreach(ParasiteList *list, GHFunc function, gpointer user_data) +{ + g_return_if_fail(list != NULL); + if (!list->table) + return; + g_hash_table_foreach(list->table, function, user_data); +} + Parasite * parasite_list_find(ParasiteList *list, const char *name) { @@ -177,3 +213,10 @@ parasite_list_find(ParasiteList *list, const char *name) } +void +parasite_shift_parent(Parasite *p) +{ + if (p == NULL) + return; + p->flags = (p->flags >> 8); +} diff --git a/app/parasitelist.h b/app/parasitelist.h index 256c4da9c9..a4d086b6af 100644 --- a/app/parasitelist.h +++ b/app/parasitelist.h @@ -40,6 +40,12 @@ ParasiteList *parasite_list_new (void); ParasiteList *parasite_list_copy (const ParasiteList *list); void parasite_list_add (ParasiteList *list, Parasite *p); void parasite_list_remove (ParasiteList *list, const char *name); +gint parasite_list_length (ParasiteList *list); +gint parasite_list_persistent_length (ParasiteList *list); +void parasite_list_foreach (ParasiteList *list, GHFunc function, + gpointer user_data); Parasite *parasite_list_find (ParasiteList *list, const char *name); +void parasite_shift_parent (Parasite *p); + #endif /* __GIMP_PARASITE_H__ */ diff --git a/app/tools/paintbrush.c b/app/tools/paintbrush.c index 8c79419968..d3645b066e 100644 --- a/app/tools/paintbrush.c +++ b/app/tools/paintbrush.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include +#include #include #include "appenv.h" #include "gimpbrushlist.h" @@ -133,14 +134,31 @@ create_paint_options (void) return options; } +#define USE_SPEEDSHOP_CALIPERS 0 +#define TIMED_BRUSH 0 + +#if USE_SPEEDSHOP_CALIPERS +#include +#endif + void * paintbrush_paint_func (PaintCore *paint_core, GimpDrawable *drawable, int state) { +#if TIMED_BRUSH + static GTimer *timer; +#endif switch (state) { case INIT_PAINT : +#if TIMED_BRUSH + timer = g_timer_new(); + g_timer_start(timer); +#if USE_SPEEDSHOP_CALIPERS + ssrt_caliper_point(0, "Painting"); +#endif /* USE_SPEEDSHOP_CALIPERS */ +#endif /* TIMED_BRUSH */ break; case MOTION_PAINT : @@ -148,6 +166,14 @@ paintbrush_paint_func (PaintCore *paint_core, break; case FINISH_PAINT : +#if TIMED_BRUSH +#if USE_SPEEDSHOP_CALIPERS + ssrt_caliper_point(0, "Not Painting Anymore"); +#endif /* USE_SPEEDSHOP_CALIPERS */ + g_timer_stop(timer); + printf("painting took %f:\n", g_timer_elapsed(timer, NULL)); + g_timer_destroy(timer); +#endif /* TIMED_BRUSH */ break; default : diff --git a/app/xcf.c b/app/xcf.c index 548d71d325..a8926e7016 100644 --- a/app/xcf.c +++ b/app/xcf.c @@ -28,6 +28,9 @@ #include "channel_pvt.h" #include "tile_manager_pvt.h" #include "tile.h" /* ick. */ +#include +#include +#include "parasitelist.h" /* #define SWAP_FROM_FILE */ @@ -52,7 +55,10 @@ typedef enum PROP_OFFSETS = 15, PROP_COLOR = 16, PROP_COMPRESSION = 17, - PROP_GUIDES = 18 + PROP_GUIDES = 18, + PROP_RESOLUTION = 19, + PROP_TATTOO = 20, + PROP_PARASITES = 21 } PropType; typedef enum @@ -140,6 +146,9 @@ static void xcf_seek_end (XcfInfo *info); static guint xcf_read_int32 (FILE *fp, guint32 *data, gint count); +static guint xcf_read_float (FILE *fp, + gfloat *data, + gint count); static guint xcf_read_int8 (FILE *fp, guint8 *data, gint count); @@ -149,6 +158,9 @@ static guint xcf_read_string (FILE *fp, static guint xcf_write_int32 (FILE *fp, guint32 *data, gint count); +static guint xcf_write_float (FILE *fp, + gfloat *data, + gint count); static guint xcf_write_int8 (FILE *fp, guint8 *data, gint count); @@ -573,6 +585,14 @@ xcf_save_image_props (XcfInfo *info, if (gimage->guides) xcf_save_prop (info, PROP_GUIDES, gimage->guides); + xcf_save_prop (info, PROP_RESOLUTION, + gimage->xresolution, gimage->yresolution); + + xcf_save_prop (info, PROP_TATTOO, gimage->tattoo_state); + + if (parasite_list_length(gimage->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, gimage->parasites); + xcf_save_prop (info, PROP_END); } @@ -599,6 +619,9 @@ xcf_save_layer_props (XcfInfo *info, xcf_save_prop (info, PROP_SHOW_MASK, layer->show_mask); xcf_save_prop (info, PROP_OFFSETS, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y); xcf_save_prop (info, PROP_MODE, layer->mode); + xcf_save_prop (info, PROP_TATTOO, GIMP_DRAWABLE(layer)->tattoo); + if (parasite_list_length(GIMP_DRAWABLE(layer)->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, GIMP_DRAWABLE(layer)->parasites); xcf_save_prop (info, PROP_END); } @@ -618,10 +641,36 @@ xcf_save_channel_props (XcfInfo *info, xcf_save_prop (info, PROP_VISIBLE, GIMP_DRAWABLE(channel)->visible); xcf_save_prop (info, PROP_SHOW_MASKED, channel->show_masked); xcf_save_prop (info, PROP_COLOR, channel->col); + xcf_save_prop (info, PROP_TATTOO, GIMP_DRAWABLE(channel)->tattoo); + if (parasite_list_length(GIMP_DRAWABLE(channel)->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, GIMP_DRAWABLE(channel)->parasites); xcf_save_prop (info, PROP_END); } +static void write_a_parasite(char *key, Parasite *p, XcfInfo *info) +{ + if ((p->flags & PARASITE_PERSISTENT)) + { + info->cp += xcf_write_string(info->fp, &p->name, 1); + info->cp += xcf_write_int32(info->fp, &p->flags, 1); + info->cp += xcf_write_int32(info->fp, &p->size, 1); + info->cp += xcf_write_int8(info->fp, p->data, p->size); + } +} + +static Parasite *read_a_parasite(XcfInfo *info) +{ + Parasite *p; + p = g_new(Parasite, 1); + info->cp += xcf_read_string(info->fp, &p->name, 1); + info->cp += xcf_read_int32(info->fp, &p->flags, 1); + info->cp += xcf_read_int32(info->fp, &p->size, 1); + p->data = g_new (char, p->size); + info->cp += xcf_read_int8(info->fp, p->data, p->size); + return p; +} + static void xcf_save_prop (XcfInfo *info, PropType prop_type, @@ -851,6 +900,58 @@ xcf_save_prop (XcfInfo *info, } } break; + case PROP_RESOLUTION: + { + float xresolution, yresolution; + + xresolution = va_arg (args, gfloat); + yresolution = va_arg (args, gfloat); + + size = 4*2; + + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + info->cp += xcf_write_int32 (info->fp, &size, 1); + + info->cp += xcf_write_float (info->fp, &xresolution, 1); + info->cp += xcf_write_float (info->fp, &yresolution, 1); + + } + break; + case PROP_TATTOO: + { + guint32 tattoo; + + tattoo = va_arg (args, guint32); + size = 4; + + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + info->cp += xcf_write_int32 (info->fp, &size, 1); + info->cp += xcf_write_int32 (info->fp, &tattoo, 1); + } + break; + case PROP_PARASITES: + { + ParasiteList *list; + guint32 base, length; + long pos; + list = va_arg (args, ParasiteList*); + if (parasite_list_persistent_length(list) > 0) + { + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + /* because we don't know how much room the parasite list will take + we save the file position and write the length later */ + pos = ftell(info->fp); + info->cp += xcf_write_int32 (info->fp, &length, 1); + base = info->cp; + parasite_list_foreach(list, (GHFunc) write_a_parasite, info); + length = info->cp - base; + /* go back to the saved position and write the length */ + fseek(info->fp, pos, SEEK_SET); + xcf_write_int32 (info->fp, &length, 1); + fseek(info->fp, 0, SEEK_END); + } + } + break; } va_end (args); @@ -1447,6 +1548,31 @@ xcf_load_image_props (XcfInfo *info, gimage->guides = g_list_reverse (gimage->guides); } break; + case PROP_RESOLUTION: + { + info->cp += xcf_read_float (info->fp, &gimage->xresolution, 1); + info->cp += xcf_read_float (info->fp, &gimage->yresolution, 1); + } + break; + case PROP_TATTOO: + { + info->cp += xcf_read_int32 (info->fp, &gimage->tattoo_state, 1); + } + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while (info->cp - base < prop_size) + { + p = read_a_parasite(info); + gimp_image_attach_parasite(gimage, p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading an image's parasites"); + } + break; default: g_message (_("unexpected/unknown image property: %d (skipping)"), prop_type); @@ -1520,6 +1646,25 @@ xcf_load_layer_props (XcfInfo *info, case PROP_MODE: info->cp += xcf_read_int32 (info->fp, (guint32*) &layer->mode, 1); break; + case PROP_TATTOO: + info->cp += xcf_read_int32 (info->fp, + (guint32*) &GIMP_DRAWABLE(layer)->tattoo, + 1); + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while (info->cp - base < prop_size) + { + p = read_a_parasite(info); + gimp_drawable_attach_parasite(GIMP_DRAWABLE(layer), p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading a layer's parasites"); + } + break; default: g_message (_("unexpected/unknown layer property: %d (skipping)"), prop_type); @@ -1579,6 +1724,24 @@ xcf_load_channel_props (XcfInfo *info, case PROP_COLOR: info->cp += xcf_read_int8 (info->fp, (guint8*) channel->col, 3); break; + case PROP_TATTOO: + info->cp += xcf_read_int32 (info->fp, &GIMP_DRAWABLE(channel)->tattoo, + 1); + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while ((info->cp - base) < prop_size) + { + p = read_a_parasite(info); + gimp_drawable_attach_parasite(GIMP_DRAWABLE(channel), p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading a channel's parasites"); + } + break; default: g_message (_("unexpected/unknown channel property: %d (skipping)"), prop_type); @@ -2210,6 +2373,14 @@ xcf_read_int32 (FILE *fp, return total * 4; } +static guint +xcf_read_float (FILE *fp, + gfloat *data, + gint count) +{ + return (xcf_read_int32(fp, (guint32 *)((void *)data), count)); +} + static guint xcf_read_int8 (FILE *fp, guint8 *data, @@ -2278,6 +2449,14 @@ xcf_write_int32 (FILE *fp, return count * 4; } +static guint +xcf_write_float (FILE *fp, + gfloat *data, + gint count) +{ + return (xcf_write_int32(fp, (guint32 *)((void *)data), count)); +} + static guint xcf_write_int8 (FILE *fp, guint8 *data, diff --git a/app/xcf/xcf.c b/app/xcf/xcf.c index 548d71d325..a8926e7016 100644 --- a/app/xcf/xcf.c +++ b/app/xcf/xcf.c @@ -28,6 +28,9 @@ #include "channel_pvt.h" #include "tile_manager_pvt.h" #include "tile.h" /* ick. */ +#include +#include +#include "parasitelist.h" /* #define SWAP_FROM_FILE */ @@ -52,7 +55,10 @@ typedef enum PROP_OFFSETS = 15, PROP_COLOR = 16, PROP_COMPRESSION = 17, - PROP_GUIDES = 18 + PROP_GUIDES = 18, + PROP_RESOLUTION = 19, + PROP_TATTOO = 20, + PROP_PARASITES = 21 } PropType; typedef enum @@ -140,6 +146,9 @@ static void xcf_seek_end (XcfInfo *info); static guint xcf_read_int32 (FILE *fp, guint32 *data, gint count); +static guint xcf_read_float (FILE *fp, + gfloat *data, + gint count); static guint xcf_read_int8 (FILE *fp, guint8 *data, gint count); @@ -149,6 +158,9 @@ static guint xcf_read_string (FILE *fp, static guint xcf_write_int32 (FILE *fp, guint32 *data, gint count); +static guint xcf_write_float (FILE *fp, + gfloat *data, + gint count); static guint xcf_write_int8 (FILE *fp, guint8 *data, gint count); @@ -573,6 +585,14 @@ xcf_save_image_props (XcfInfo *info, if (gimage->guides) xcf_save_prop (info, PROP_GUIDES, gimage->guides); + xcf_save_prop (info, PROP_RESOLUTION, + gimage->xresolution, gimage->yresolution); + + xcf_save_prop (info, PROP_TATTOO, gimage->tattoo_state); + + if (parasite_list_length(gimage->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, gimage->parasites); + xcf_save_prop (info, PROP_END); } @@ -599,6 +619,9 @@ xcf_save_layer_props (XcfInfo *info, xcf_save_prop (info, PROP_SHOW_MASK, layer->show_mask); xcf_save_prop (info, PROP_OFFSETS, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y); xcf_save_prop (info, PROP_MODE, layer->mode); + xcf_save_prop (info, PROP_TATTOO, GIMP_DRAWABLE(layer)->tattoo); + if (parasite_list_length(GIMP_DRAWABLE(layer)->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, GIMP_DRAWABLE(layer)->parasites); xcf_save_prop (info, PROP_END); } @@ -618,10 +641,36 @@ xcf_save_channel_props (XcfInfo *info, xcf_save_prop (info, PROP_VISIBLE, GIMP_DRAWABLE(channel)->visible); xcf_save_prop (info, PROP_SHOW_MASKED, channel->show_masked); xcf_save_prop (info, PROP_COLOR, channel->col); + xcf_save_prop (info, PROP_TATTOO, GIMP_DRAWABLE(channel)->tattoo); + if (parasite_list_length(GIMP_DRAWABLE(channel)->parasites) > 0) + xcf_save_prop (info, PROP_PARASITES, GIMP_DRAWABLE(channel)->parasites); xcf_save_prop (info, PROP_END); } +static void write_a_parasite(char *key, Parasite *p, XcfInfo *info) +{ + if ((p->flags & PARASITE_PERSISTENT)) + { + info->cp += xcf_write_string(info->fp, &p->name, 1); + info->cp += xcf_write_int32(info->fp, &p->flags, 1); + info->cp += xcf_write_int32(info->fp, &p->size, 1); + info->cp += xcf_write_int8(info->fp, p->data, p->size); + } +} + +static Parasite *read_a_parasite(XcfInfo *info) +{ + Parasite *p; + p = g_new(Parasite, 1); + info->cp += xcf_read_string(info->fp, &p->name, 1); + info->cp += xcf_read_int32(info->fp, &p->flags, 1); + info->cp += xcf_read_int32(info->fp, &p->size, 1); + p->data = g_new (char, p->size); + info->cp += xcf_read_int8(info->fp, p->data, p->size); + return p; +} + static void xcf_save_prop (XcfInfo *info, PropType prop_type, @@ -851,6 +900,58 @@ xcf_save_prop (XcfInfo *info, } } break; + case PROP_RESOLUTION: + { + float xresolution, yresolution; + + xresolution = va_arg (args, gfloat); + yresolution = va_arg (args, gfloat); + + size = 4*2; + + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + info->cp += xcf_write_int32 (info->fp, &size, 1); + + info->cp += xcf_write_float (info->fp, &xresolution, 1); + info->cp += xcf_write_float (info->fp, &yresolution, 1); + + } + break; + case PROP_TATTOO: + { + guint32 tattoo; + + tattoo = va_arg (args, guint32); + size = 4; + + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + info->cp += xcf_write_int32 (info->fp, &size, 1); + info->cp += xcf_write_int32 (info->fp, &tattoo, 1); + } + break; + case PROP_PARASITES: + { + ParasiteList *list; + guint32 base, length; + long pos; + list = va_arg (args, ParasiteList*); + if (parasite_list_persistent_length(list) > 0) + { + info->cp += xcf_write_int32 (info->fp, (guint32*) &prop_type, 1); + /* because we don't know how much room the parasite list will take + we save the file position and write the length later */ + pos = ftell(info->fp); + info->cp += xcf_write_int32 (info->fp, &length, 1); + base = info->cp; + parasite_list_foreach(list, (GHFunc) write_a_parasite, info); + length = info->cp - base; + /* go back to the saved position and write the length */ + fseek(info->fp, pos, SEEK_SET); + xcf_write_int32 (info->fp, &length, 1); + fseek(info->fp, 0, SEEK_END); + } + } + break; } va_end (args); @@ -1447,6 +1548,31 @@ xcf_load_image_props (XcfInfo *info, gimage->guides = g_list_reverse (gimage->guides); } break; + case PROP_RESOLUTION: + { + info->cp += xcf_read_float (info->fp, &gimage->xresolution, 1); + info->cp += xcf_read_float (info->fp, &gimage->yresolution, 1); + } + break; + case PROP_TATTOO: + { + info->cp += xcf_read_int32 (info->fp, &gimage->tattoo_state, 1); + } + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while (info->cp - base < prop_size) + { + p = read_a_parasite(info); + gimp_image_attach_parasite(gimage, p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading an image's parasites"); + } + break; default: g_message (_("unexpected/unknown image property: %d (skipping)"), prop_type); @@ -1520,6 +1646,25 @@ xcf_load_layer_props (XcfInfo *info, case PROP_MODE: info->cp += xcf_read_int32 (info->fp, (guint32*) &layer->mode, 1); break; + case PROP_TATTOO: + info->cp += xcf_read_int32 (info->fp, + (guint32*) &GIMP_DRAWABLE(layer)->tattoo, + 1); + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while (info->cp - base < prop_size) + { + p = read_a_parasite(info); + gimp_drawable_attach_parasite(GIMP_DRAWABLE(layer), p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading a layer's parasites"); + } + break; default: g_message (_("unexpected/unknown layer property: %d (skipping)"), prop_type); @@ -1579,6 +1724,24 @@ xcf_load_channel_props (XcfInfo *info, case PROP_COLOR: info->cp += xcf_read_int8 (info->fp, (guint8*) channel->col, 3); break; + case PROP_TATTOO: + info->cp += xcf_read_int32 (info->fp, &GIMP_DRAWABLE(channel)->tattoo, + 1); + break; + case PROP_PARASITES: + { + long base = info->cp; + Parasite *p; + while ((info->cp - base) < prop_size) + { + p = read_a_parasite(info); + gimp_drawable_attach_parasite(GIMP_DRAWABLE(channel), p); + parasite_free(p); + } + if (info->cp - base != prop_size) + g_message("Error detected while loading a channel's parasites"); + } + break; default: g_message (_("unexpected/unknown channel property: %d (skipping)"), prop_type); @@ -2210,6 +2373,14 @@ xcf_read_int32 (FILE *fp, return total * 4; } +static guint +xcf_read_float (FILE *fp, + gfloat *data, + gint count) +{ + return (xcf_read_int32(fp, (guint32 *)((void *)data), count)); +} + static guint xcf_read_int8 (FILE *fp, guint8 *data, @@ -2278,6 +2449,14 @@ xcf_write_int32 (FILE *fp, return count * 4; } +static guint +xcf_write_float (FILE *fp, + gfloat *data, + gint count) +{ + return (xcf_write_int32(fp, (guint32 *)((void *)data), count)); +} + static guint xcf_write_int8 (FILE *fp, guint8 *data, diff --git a/libgimp/gimpparasite.c b/libgimp/gimpparasite.c index 69472cc893..703211c231 100644 --- a/libgimp/gimpparasite.c +++ b/libgimp/gimpparasite.c @@ -56,7 +56,7 @@ parasite_new (const char *name, guint32 flags, g_free (p); return NULL; } - p->flags = flags; + p->flags = (flags & 0xFF); p->size = size; if (size) p->data = g_memdup(data, size); @@ -95,9 +95,31 @@ parasite_copy (const Parasite *parasite) } int -parasite_is_persistant(const Parasite *p) +parasite_is_persistent(const Parasite *p) { if (p == NULL) return FALSE; - return (p->flags & PARASITE_PERSISTANT); + return (p->flags & PARASITE_PERSISTENT); +} + +int +parasite_has_flag(const Parasite *p, gulong flag) +{ + if (p == NULL) + return FALSE; + return (p->flags & flag); +} + +void *parasite_data(const Parasite *p) +{ + if (p) + return p->data; + return NULL; +} + +long parasite_data_size(const Parasite *p) +{ + if (p) + return p->size; + return 0; } diff --git a/libgimp/gimpparasite.h b/libgimp/gimpparasite.h index 98820b3014..49cd5e1f92 100644 --- a/libgimp/gimpparasite.h +++ b/libgimp/gimpparasite.h @@ -27,16 +27,27 @@ extern "C" { #endif /* __cplusplus */ -#define PARASITE_PERSISTANT 1 +#define PARASITE_PERSISTENT 1 + +#define PARASITE_ATTACH_PARENT (0x80 << 8) +#define PARASITE_PARENT_PERSISTENT (PARASITE_PERSISTENT << 8) + +#define PARASITE_ATTACH_GRANDPARENT (0x80 << 16) +#define PARASITE_GRANDPARENT_PERSISTENT (PARASITE_PERSISTENT << 16) Parasite *parasite_new (const char *name, guint32 flags, guint32 size, const void *data); void parasite_free (Parasite *parasite); -int parasite_is_type (const Parasite *parasite, const char *name); Parasite *parasite_copy (const Parasite *parasite); -int parasite_is_persistant (const Parasite *p); +int parasite_is_type (const Parasite *parasite, const char *name); +int parasite_is_persistent (const Parasite *p); +int parasite_has_flag (const Parasite *p, gulong flag); +void *parasite_data (const Parasite *p); +long parasite_data_size (const Parasite *p); + + #ifdef __cplusplus } diff --git a/libgimp/gserialize.c b/libgimp/gserialize.c index ba34f7c311..62630fbb66 100644 --- a/libgimp/gserialize.c +++ b/libgimp/gserialize.c @@ -37,7 +37,8 @@ struct _GSerialItem #define g_serial_copy_from_n g_serial_copy_to_n -long g_serial_copy_to_n(char *dest, char *source, long data_size, long n_items) +static long g_serial_copy_to_n(char *dest, char *source, long data_size, + long n_items) { int i; int length = n_items*data_size; @@ -128,6 +129,8 @@ static int g_serial_item_is_array(GSerialItem *item) static long g_serial_item_data_size(GSerialItem *item) { static long sizes[] = {0, 1, 2, 4, 4, 8, 1, 1, 2, 4, 4, 8}; + if (item->type >= GSERIAL_STRING) + return sizes[item->type - 95]; return sizes[item->type]; } @@ -169,7 +172,8 @@ static long g_serial_item_serialize(GSerialItem *item, char *buffer, { char *buf = buffer; gint32 tmp; - if (item->type >= GSERIAL_LAST_TYPE) + if (item->type >= GSERIAL_LAST_TYPE || + (item->type > GSERIAL_DOUBLE && item->type < GSERIAL_STRING)) { g_warning("Error serializing: Unknown serial item type.\n"); return 0; @@ -250,7 +254,7 @@ long g_serialize(GSerialDescription *d, void **output, void *struct_data) return length; } -void g_deserialize(GSerialDescription *d, void *struct_data, void *serial) +long g_deserialize(GSerialDescription *d, void *struct_data, void *serial) { GSList *list; char *in_buf = serial; @@ -262,4 +266,5 @@ void g_deserialize(GSerialDescription *d, void *struct_data, void *serial) out_buf, in_buf); list = list->next; } + return (in_buf - (char *)serial); } diff --git a/libgimp/gserialize.h b/libgimp/gserialize.h index 8152b64909..e93811ae8a 100644 --- a/libgimp/gserialize.h +++ b/libgimp/gserialize.h @@ -28,19 +28,19 @@ extern "C" { #include typedef enum { - GSERIAL_END, /* for internal use only */ - GSERIAL_INT8, - GSERIAL_INT16, - GSERIAL_INT32, - GSERIAL_FLOAT, /* 32 bit IEEE fp value */ - GSERIAL_DOUBLE, /* 64 bit IEEE fp value */ - GSERIAL_STRING, - GSERIAL_INT8ARRAY, - GSERIAL_INT16ARRAY, - GSERIAL_INT32ARRAY, - GSERIAL_FLOATARRAY, - GSERIAL_DOUBLEARRAY, - GSERIAL_LAST_TYPE + GSERIAL_END = 0, /* for internal use only */ + GSERIAL_INT8 = 1, + GSERIAL_INT16 = 2, + GSERIAL_INT32 = 3, + GSERIAL_FLOAT = 4, /* 32 bit IEEE fp value */ + GSERIAL_DOUBLE = 5, /* 64 bit IEEE fp value */ + GSERIAL_STRING = 101, + GSERIAL_INT8ARRAY = 102, + GSERIAL_INT16ARRAY = 103, + GSERIAL_INT32ARRAY = 104, + GSERIAL_FLOATARRAY = 105, + GSERIAL_DOUBLEARRAY = 106, + GSERIAL_LAST_TYPE = 107 } GSerialType; typedef struct _GSerialItem GSerialItem; @@ -68,7 +68,7 @@ long g_serialize(GSerialDescription *d, void **output, void *struct_data); /* returns the length of the serialized data. g_mallocs space for the data and stores a pointer to it in output */ -void g_deserialize(GSerialDescription *d, void *output, void *serial); +long g_deserialize(GSerialDescription *d, void *output, void *serial); /* output must be a preallocated area large enough to hold the deserialized struct. */ diff --git a/libgimp/parasite.c b/libgimp/parasite.c index 69472cc893..703211c231 100644 --- a/libgimp/parasite.c +++ b/libgimp/parasite.c @@ -56,7 +56,7 @@ parasite_new (const char *name, guint32 flags, g_free (p); return NULL; } - p->flags = flags; + p->flags = (flags & 0xFF); p->size = size; if (size) p->data = g_memdup(data, size); @@ -95,9 +95,31 @@ parasite_copy (const Parasite *parasite) } int -parasite_is_persistant(const Parasite *p) +parasite_is_persistent(const Parasite *p) { if (p == NULL) return FALSE; - return (p->flags & PARASITE_PERSISTANT); + return (p->flags & PARASITE_PERSISTENT); +} + +int +parasite_has_flag(const Parasite *p, gulong flag) +{ + if (p == NULL) + return FALSE; + return (p->flags & flag); +} + +void *parasite_data(const Parasite *p) +{ + if (p) + return p->data; + return NULL; +} + +long parasite_data_size(const Parasite *p) +{ + if (p) + return p->size; + return 0; } diff --git a/libgimp/parasite.h b/libgimp/parasite.h index 98820b3014..49cd5e1f92 100644 --- a/libgimp/parasite.h +++ b/libgimp/parasite.h @@ -27,16 +27,27 @@ extern "C" { #endif /* __cplusplus */ -#define PARASITE_PERSISTANT 1 +#define PARASITE_PERSISTENT 1 + +#define PARASITE_ATTACH_PARENT (0x80 << 8) +#define PARASITE_PARENT_PERSISTENT (PARASITE_PERSISTENT << 8) + +#define PARASITE_ATTACH_GRANDPARENT (0x80 << 16) +#define PARASITE_GRANDPARENT_PERSISTENT (PARASITE_PERSISTENT << 16) Parasite *parasite_new (const char *name, guint32 flags, guint32 size, const void *data); void parasite_free (Parasite *parasite); -int parasite_is_type (const Parasite *parasite, const char *name); Parasite *parasite_copy (const Parasite *parasite); -int parasite_is_persistant (const Parasite *p); +int parasite_is_type (const Parasite *parasite, const char *name); +int parasite_is_persistent (const Parasite *p); +int parasite_has_flag (const Parasite *p, gulong flag); +void *parasite_data (const Parasite *p); +long parasite_data_size (const Parasite *p); + + #ifdef __cplusplus } diff --git a/libgimpbase/gimpparasite.c b/libgimpbase/gimpparasite.c index 69472cc893..703211c231 100644 --- a/libgimpbase/gimpparasite.c +++ b/libgimpbase/gimpparasite.c @@ -56,7 +56,7 @@ parasite_new (const char *name, guint32 flags, g_free (p); return NULL; } - p->flags = flags; + p->flags = (flags & 0xFF); p->size = size; if (size) p->data = g_memdup(data, size); @@ -95,9 +95,31 @@ parasite_copy (const Parasite *parasite) } int -parasite_is_persistant(const Parasite *p) +parasite_is_persistent(const Parasite *p) { if (p == NULL) return FALSE; - return (p->flags & PARASITE_PERSISTANT); + return (p->flags & PARASITE_PERSISTENT); +} + +int +parasite_has_flag(const Parasite *p, gulong flag) +{ + if (p == NULL) + return FALSE; + return (p->flags & flag); +} + +void *parasite_data(const Parasite *p) +{ + if (p) + return p->data; + return NULL; +} + +long parasite_data_size(const Parasite *p) +{ + if (p) + return p->size; + return 0; } diff --git a/libgimpbase/gimpparasite.h b/libgimpbase/gimpparasite.h index 98820b3014..49cd5e1f92 100644 --- a/libgimpbase/gimpparasite.h +++ b/libgimpbase/gimpparasite.h @@ -27,16 +27,27 @@ extern "C" { #endif /* __cplusplus */ -#define PARASITE_PERSISTANT 1 +#define PARASITE_PERSISTENT 1 + +#define PARASITE_ATTACH_PARENT (0x80 << 8) +#define PARASITE_PARENT_PERSISTENT (PARASITE_PERSISTENT << 8) + +#define PARASITE_ATTACH_GRANDPARENT (0x80 << 16) +#define PARASITE_GRANDPARENT_PERSISTENT (PARASITE_PERSISTENT << 16) Parasite *parasite_new (const char *name, guint32 flags, guint32 size, const void *data); void parasite_free (Parasite *parasite); -int parasite_is_type (const Parasite *parasite, const char *name); Parasite *parasite_copy (const Parasite *parasite); -int parasite_is_persistant (const Parasite *p); +int parasite_is_type (const Parasite *parasite, const char *name); +int parasite_is_persistent (const Parasite *p); +int parasite_has_flag (const Parasite *p, gulong flag); +void *parasite_data (const Parasite *p); +long parasite_data_size (const Parasite *p); + + #ifdef __cplusplus } diff --git a/plug-ins/bmp/bmp.c b/plug-ins/bmp/bmp.c index 22b0986b1e..fc5630b388 100644 --- a/plug-ins/bmp/bmp.c +++ b/plug-ins/bmp/bmp.c @@ -50,6 +50,9 @@ FILE *errorfile; char *prog_name="bmp"; char *filename; int interactive_bmp; +struct Bitmap_File_Head_Struct Bitmap_File_Head; +struct Bitmap_Head_Struct Bitmap_Head; +struct Bitmap_OS2_Head_Struct Bitmap_OS2_Head; /* Declare some local functions. */ diff --git a/plug-ins/bmp/bmp.h b/plug-ins/bmp/bmp.h index dcc2007b51..a2b725f145 100644 --- a/plug-ins/bmp/bmp.h +++ b/plug-ins/bmp/bmp.h @@ -25,7 +25,7 @@ extern char *prog_name; extern char *filename; extern FILE *errorfile; -struct +extern struct Bitmap_File_Head_Struct { unsigned long bfSize; /* 02 */ unsigned long reserverd; /* 06 */ @@ -33,7 +33,7 @@ struct unsigned long biSize; /* 0E */ }Bitmap_File_Head; -struct +extern struct Bitmap_Head_Struct { unsigned long biWidth; /* 12 */ unsigned long biHeight; /* 16 */ @@ -48,7 +48,7 @@ struct /* 36 */ }Bitmap_Head; -struct +extern struct Bitmap_OS2_Head_Struct { unsigned short bcWidth; /* 12 */ unsigned short bcHeight; /* 14 */ diff --git a/plug-ins/common/gif.c b/plug-ins/common/gif.c index fa816084d3..ced83d40f3 100644 --- a/plug-ins/common/gif.c +++ b/plug-ins/common/gif.c @@ -888,7 +888,7 @@ DoExtension (FILE *fd, parasite_free (comment_parasite); } - comment_parasite = parasite_new ("gimp-comment",TRUE, + comment_parasite = parasite_new ("gimp-comment",PARASITE_PERSISTENT, strlen(buf)+1, (void*)buf); #else if (showComment) diff --git a/plug-ins/common/tiff.c b/plug-ins/common/tiff.c index 5744543111..f963286bd6 100644 --- a/plug-ins/common/tiff.c +++ b/plug-ins/common/tiff.c @@ -456,7 +456,8 @@ static gint32 load_image (char *filename) { len = MIN(len, 241); img_desc[len-1] = '\000'; - parasite = parasite_new("gimp-comment", 1, len, img_desc); + parasite = parasite_new("gimp-comment", PARASITE_PERSISTENT, + len, img_desc); gimp_image_attach_parasite(image, parasite); parasite_free(parasite); } diff --git a/plug-ins/gif/gif.c b/plug-ins/gif/gif.c index fa816084d3..ced83d40f3 100644 --- a/plug-ins/gif/gif.c +++ b/plug-ins/gif/gif.c @@ -888,7 +888,7 @@ DoExtension (FILE *fd, parasite_free (comment_parasite); } - comment_parasite = parasite_new ("gimp-comment",TRUE, + comment_parasite = parasite_new ("gimp-comment",PARASITE_PERSISTENT, strlen(buf)+1, (void*)buf); #else if (showComment) diff --git a/plug-ins/tiff/tiff.c b/plug-ins/tiff/tiff.c index 5744543111..f963286bd6 100644 --- a/plug-ins/tiff/tiff.c +++ b/plug-ins/tiff/tiff.c @@ -456,7 +456,8 @@ static gint32 load_image (char *filename) { len = MIN(len, 241); img_desc[len-1] = '\000'; - parasite = parasite_new("gimp-comment", 1, len, img_desc); + parasite = parasite_new("gimp-comment", PARASITE_PERSISTENT, + len, img_desc); gimp_image_attach_parasite(image, parasite); parasite_free(parasite); }