mirror of https://github.com/GNOME/gimp.git
added new API gimp_drawable_estimate_memsize() and virtual function
2007-12-04 Michael Natterer <mitch@gimp.org> * app/core/gimpdrawable.[ch]: added new API gimp_drawable_estimate_memsize() and virtual function GimpDrawable::estimate_memsize() which estimate the memsize of a drawable after scaling/resizing. * app/core/gimplayer.c: implement the virtual function and take the layer mask into account. * app/core/gimpimage-item-list.[ch] (gimp_image_item_list_get_list): added const qualifiers. * app/core/gimpimage-scale.c (gimp_image_scale_check): use the new function to correctly estimate the new size instead of scaling the drawables' memsizes including all constant parts. Fixes bug #329468. * app/gimp-log.[ch]: added IMAGE_SCALE log domain. * app/core/gimpimage-scale.c: use it here for debugging output. svn path=/trunk/; revision=24260
This commit is contained in:
parent
4fe0a3a613
commit
dd80b4c263
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2007-12-04 Michael Natterer <mitch@gimp.org>
|
||||||
|
|
||||||
|
* app/core/gimpdrawable.[ch]: added new API
|
||||||
|
gimp_drawable_estimate_memsize() and virtual function
|
||||||
|
GimpDrawable::estimate_memsize() which estimate the memsize of a
|
||||||
|
drawable after scaling/resizing.
|
||||||
|
|
||||||
|
* app/core/gimplayer.c: implement the virtual function and take
|
||||||
|
the layer mask into account.
|
||||||
|
|
||||||
|
* app/core/gimpimage-item-list.[ch] (gimp_image_item_list_get_list):
|
||||||
|
added const qualifiers.
|
||||||
|
|
||||||
|
* app/core/gimpimage-scale.c (gimp_image_scale_check): use the new
|
||||||
|
function to correctly estimate the new size instead of scaling the
|
||||||
|
drawables' memsizes including all constant parts. Fixes bug #329468.
|
||||||
|
|
||||||
|
* app/gimp-log.[ch]: added IMAGE_SCALE log domain.
|
||||||
|
|
||||||
|
* app/core/gimpimage-scale.c: use it here for debugging output.
|
||||||
|
|
||||||
2007-12-04 Sven Neumann <sven@gimp.org>
|
2007-12-04 Sven Neumann <sven@gimp.org>
|
||||||
|
|
||||||
* modules/Makefile.am
|
* modules/Makefile.am
|
||||||
|
|
|
@ -124,6 +124,10 @@ static void gimp_drawable_real_update (GimpDrawable *drawable,
|
||||||
gint width,
|
gint width,
|
||||||
gint height);
|
gint height);
|
||||||
|
|
||||||
|
static gint64 gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
|
|
||||||
static void gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
static void gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
||||||
gboolean push_undo,
|
gboolean push_undo,
|
||||||
const gchar *undo_desc,
|
const gchar *undo_desc,
|
||||||
|
@ -206,6 +210,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
|
||||||
|
|
||||||
klass->update = gimp_drawable_real_update;
|
klass->update = gimp_drawable_real_update;
|
||||||
klass->alpha_changed = NULL;
|
klass->alpha_changed = NULL;
|
||||||
|
klass->estimate_memsize = gimp_drawable_real_estimate_memsize;
|
||||||
klass->invalidate_boundary = NULL;
|
klass->invalidate_boundary = NULL;
|
||||||
klass->get_active_components = NULL;
|
klass->get_active_components = NULL;
|
||||||
klass->apply_region = gimp_drawable_real_apply_region;
|
klass->apply_region = gimp_drawable_real_apply_region;
|
||||||
|
@ -612,6 +617,14 @@ gimp_drawable_real_update (GimpDrawable *drawable,
|
||||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (drawable));
|
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint64
|
||||||
|
gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
return (gint64) gimp_drawable_bytes (drawable) * width * height;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
||||||
gboolean push_undo,
|
gboolean push_undo,
|
||||||
|
@ -758,6 +771,17 @@ gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
|
|
||||||
|
gint64
|
||||||
|
gimp_drawable_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), 0);
|
||||||
|
|
||||||
|
return GIMP_DRAWABLE_GET_CLASS (drawable)->estimate_memsize (drawable,
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gimp_drawable_configure (GimpDrawable *drawable,
|
gimp_drawable_configure (GimpDrawable *drawable,
|
||||||
GimpImage *image,
|
GimpImage *image,
|
||||||
|
|
|
@ -61,6 +61,9 @@ struct _GimpDrawableClass
|
||||||
void (* alpha_changed) (GimpDrawable *drawable);
|
void (* alpha_changed) (GimpDrawable *drawable);
|
||||||
|
|
||||||
/* virtual functions */
|
/* virtual functions */
|
||||||
|
gint64 (* estimate_memsize) (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
void (* invalidate_boundary) (GimpDrawable *drawable);
|
void (* invalidate_boundary) (GimpDrawable *drawable);
|
||||||
void (* get_active_components) (const GimpDrawable *drawable,
|
void (* get_active_components) (const GimpDrawable *drawable,
|
||||||
gboolean *active);
|
gboolean *active);
|
||||||
|
@ -109,6 +112,10 @@ struct _GimpDrawableClass
|
||||||
|
|
||||||
GType gimp_drawable_get_type (void) G_GNUC_CONST;
|
GType gimp_drawable_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
gint64 gimp_drawable_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
|
|
||||||
void gimp_drawable_configure (GimpDrawable *drawable,
|
void gimp_drawable_configure (GimpDrawable *drawable,
|
||||||
GimpImage *image,
|
GimpImage *image,
|
||||||
gint offset_x,
|
gint offset_x,
|
||||||
|
|
|
@ -159,8 +159,8 @@ gimp_image_item_list_transform (GimpImage *image,
|
||||||
* Return value: The list of items, excluding @exclude.
|
* Return value: The list of items, excluding @exclude.
|
||||||
**/
|
**/
|
||||||
GList *
|
GList *
|
||||||
gimp_image_item_list_get_list (GimpImage *image,
|
gimp_image_item_list_get_list (const GimpImage *image,
|
||||||
GimpItem *exclude,
|
const GimpItem *exclude,
|
||||||
GimpItemTypeMask type,
|
GimpItemTypeMask type,
|
||||||
GimpItemSet set)
|
GimpItemSet set)
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,8 +48,8 @@ void gimp_image_item_list_transform (GimpImage *image,
|
||||||
GimpTransformResize clip_result,
|
GimpTransformResize clip_result,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
|
|
||||||
GList * gimp_image_item_list_get_list (GimpImage *image,
|
GList * gimp_image_item_list_get_list (const GimpImage *image,
|
||||||
GimpItem *exclude,
|
const GimpItem *exclude,
|
||||||
GimpItemTypeMask type,
|
GimpItemTypeMask type,
|
||||||
GimpItemSet set);
|
GimpItemSet set);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "gimpguide.h"
|
#include "gimpguide.h"
|
||||||
#include "gimpimage.h"
|
#include "gimpimage.h"
|
||||||
#include "gimpimage-guides.h"
|
#include "gimpimage-guides.h"
|
||||||
|
#include "gimpimage-item-list.h"
|
||||||
#include "gimpimage-sample-points.h"
|
#include "gimpimage-sample-points.h"
|
||||||
#include "gimpimage-scale.h"
|
#include "gimpimage-scale.h"
|
||||||
#include "gimpimage-undo.h"
|
#include "gimpimage-undo.h"
|
||||||
|
@ -35,9 +36,11 @@
|
||||||
#include "gimplayer.h"
|
#include "gimplayer.h"
|
||||||
#include "gimplist.h"
|
#include "gimplist.h"
|
||||||
#include "gimpprogress.h"
|
#include "gimpprogress.h"
|
||||||
|
#include "gimpprojection.h"
|
||||||
#include "gimpsamplepoint.h"
|
#include "gimpsamplepoint.h"
|
||||||
#include "gimpsubprogress.h"
|
#include "gimpsubprogress.h"
|
||||||
|
|
||||||
|
#include "gimp-log.h"
|
||||||
#include "gimp-intl.h"
|
#include "gimp-intl.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,9 +237,11 @@ gimp_image_scale_check (const GimpImage *image,
|
||||||
gint64 max_memsize,
|
gint64 max_memsize,
|
||||||
gint64 *new_memsize)
|
gint64 *new_memsize)
|
||||||
{
|
{
|
||||||
|
GList *drawables;
|
||||||
GList *list;
|
GList *list;
|
||||||
gint64 current_size;
|
gint64 current_size;
|
||||||
gint64 scalable_size;
|
gint64 scalable_size;
|
||||||
|
gint64 scaled_size;
|
||||||
gint64 undo_size;
|
gint64 undo_size;
|
||||||
gint64 redo_size;
|
gint64 redo_size;
|
||||||
gint64 fixed_size;
|
gint64 fixed_size;
|
||||||
|
@ -248,11 +253,47 @@ gimp_image_scale_check (const GimpImage *image,
|
||||||
current_size = gimp_object_get_memsize (GIMP_OBJECT (image), NULL);
|
current_size = gimp_object_get_memsize (GIMP_OBJECT (image), NULL);
|
||||||
|
|
||||||
/* the part of the image's memsize that scales linearly with the image */
|
/* the part of the image's memsize that scales linearly with the image */
|
||||||
scalable_size =
|
drawables = gimp_image_item_list_get_list (image, NULL,
|
||||||
gimp_object_get_memsize (GIMP_OBJECT (image->layers), NULL) +
|
GIMP_ITEM_TYPE_LAYERS |
|
||||||
gimp_object_get_memsize (GIMP_OBJECT (image->channels), NULL) +
|
GIMP_ITEM_TYPE_CHANNELS,
|
||||||
gimp_object_get_memsize (GIMP_OBJECT (image->selection_mask), NULL) +
|
GIMP_ITEM_SET_ALL);
|
||||||
gimp_object_get_memsize (GIMP_OBJECT (image->projection), NULL);
|
drawables = g_list_prepend (drawables, image->selection_mask);
|
||||||
|
|
||||||
|
scalable_size = 0;
|
||||||
|
scaled_size = 0;
|
||||||
|
|
||||||
|
for (list = drawables; list; list = g_list_next (list))
|
||||||
|
{
|
||||||
|
GimpDrawable *drawable = list->data;
|
||||||
|
gdouble width = gimp_item_width (GIMP_ITEM (drawable));
|
||||||
|
gdouble height = gimp_item_height (GIMP_ITEM (drawable));
|
||||||
|
|
||||||
|
scalable_size +=
|
||||||
|
gimp_drawable_estimate_memsize (drawable,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
scaled_size +=
|
||||||
|
gimp_drawable_estimate_memsize (drawable,
|
||||||
|
width * new_width /
|
||||||
|
gimp_image_get_width (image),
|
||||||
|
height * new_height /
|
||||||
|
gimp_image_get_height (image));
|
||||||
|
}
|
||||||
|
|
||||||
|
g_list_free (drawables);
|
||||||
|
|
||||||
|
scalable_size +=
|
||||||
|
gimp_projection_estimate_memsize (gimp_image_base_type (image),
|
||||||
|
gimp_image_get_width (image),
|
||||||
|
gimp_image_get_height (image));
|
||||||
|
|
||||||
|
scaled_size +=
|
||||||
|
gimp_projection_estimate_memsize (gimp_image_base_type (image),
|
||||||
|
new_width, new_height);
|
||||||
|
|
||||||
|
GIMP_LOG (IMAGE_SCALE,
|
||||||
|
"scalable_size = %"G_GINT64_FORMAT" scaled_size = %"G_GINT64_FORMAT,
|
||||||
|
scalable_size, scaled_size);
|
||||||
|
|
||||||
undo_size = gimp_object_get_memsize (GIMP_OBJECT (image->undo_stack), NULL);
|
undo_size = gimp_object_get_memsize (GIMP_OBJECT (image->undo_stack), NULL);
|
||||||
redo_size = gimp_object_get_memsize (GIMP_OBJECT (image->redo_stack), NULL);
|
redo_size = gimp_object_get_memsize (GIMP_OBJECT (image->redo_stack), NULL);
|
||||||
|
@ -262,9 +303,11 @@ gimp_image_scale_check (const GimpImage *image,
|
||||||
|
|
||||||
/* calculate the new size, which is: */
|
/* calculate the new size, which is: */
|
||||||
new_size = (fixed_size + /* the fixed part */
|
new_size = (fixed_size + /* the fixed part */
|
||||||
scalable_size * /* plus the part that scales... */
|
scaled_size); /* plus the part that scales... */
|
||||||
((gdouble) new_width / gimp_image_get_width (image)) *
|
|
||||||
((gdouble) new_height / gimp_image_get_height (image)));
|
GIMP_LOG (IMAGE_SCALE,
|
||||||
|
"old_size = %"G_GINT64_FORMAT" new_size = %"G_GINT64_FORMAT,
|
||||||
|
current_size - undo_size - redo_size, new_size);
|
||||||
|
|
||||||
*new_memsize = new_size;
|
*new_memsize = new_size;
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,10 @@ static void gimp_layer_transform (GimpItem *item,
|
||||||
gint recursion_level,
|
gint recursion_level,
|
||||||
GimpTransformResize clip_result,
|
GimpTransformResize clip_result,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
|
|
||||||
|
static gint64 gimp_layer_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height);
|
||||||
static void gimp_layer_invalidate_boundary (GimpDrawable *drawable);
|
static void gimp_layer_invalidate_boundary (GimpDrawable *drawable);
|
||||||
static void gimp_layer_get_active_components (const GimpDrawable *drawable,
|
static void gimp_layer_get_active_components (const GimpDrawable *drawable,
|
||||||
gboolean *active);
|
gboolean *active);
|
||||||
|
@ -250,6 +254,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
|
||||||
item_class->rotate_desc = _("Rotate Layer");
|
item_class->rotate_desc = _("Rotate Layer");
|
||||||
item_class->transform_desc = _("Transform Layer");
|
item_class->transform_desc = _("Transform Layer");
|
||||||
|
|
||||||
|
drawable_class->estimate_memsize = gimp_layer_estimate_memsize;
|
||||||
drawable_class->invalidate_boundary = gimp_layer_invalidate_boundary;
|
drawable_class->invalidate_boundary = gimp_layer_invalidate_boundary;
|
||||||
drawable_class->get_active_components = gimp_layer_get_active_components;
|
drawable_class->get_active_components = gimp_layer_get_active_components;
|
||||||
drawable_class->set_tiles = gimp_layer_set_tiles;
|
drawable_class->set_tiles = gimp_layer_set_tiles;
|
||||||
|
@ -798,6 +803,23 @@ gimp_layer_transform (GimpItem *item,
|
||||||
clip_result, progress);
|
clip_result, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint64
|
||||||
|
gimp_layer_estimate_memsize (const GimpDrawable *drawable,
|
||||||
|
gint width,
|
||||||
|
gint height)
|
||||||
|
{
|
||||||
|
GimpLayer *layer = GIMP_LAYER (drawable);
|
||||||
|
gint64 memsize = 0;
|
||||||
|
|
||||||
|
if (layer->mask)
|
||||||
|
memsize += gimp_drawable_estimate_memsize (GIMP_DRAWABLE (layer->mask),
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
return memsize + GIMP_DRAWABLE_CLASS (parent_class)->estimate_memsize (drawable,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_layer_invalidate_boundary (GimpDrawable *drawable)
|
gimp_layer_invalidate_boundary (GimpDrawable *drawable)
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,8 @@ gimp_log_init (void)
|
||||||
{ "dnd", GIMP_LOG_DND },
|
{ "dnd", GIMP_LOG_DND },
|
||||||
{ "help", GIMP_LOG_HELP },
|
{ "help", GIMP_LOG_HELP },
|
||||||
{ "dialog-factory", GIMP_LOG_DIALOG_FACTORY },
|
{ "dialog-factory", GIMP_LOG_DIALOG_FACTORY },
|
||||||
{ "save-dialog", GIMP_LOG_SAVE_DIALOG }
|
{ "save-dialog", GIMP_LOG_SAVE_DIALOG },
|
||||||
|
{ "image-scale", GIMP_LOG_IMAGE_SCALE }
|
||||||
};
|
};
|
||||||
|
|
||||||
gimp_log_flags = g_parse_debug_string (env_log_val,
|
gimp_log_flags = g_parse_debug_string (env_log_val,
|
||||||
|
|
|
@ -26,7 +26,8 @@ typedef enum
|
||||||
GIMP_LOG_DND = 1 << 1,
|
GIMP_LOG_DND = 1 << 1,
|
||||||
GIMP_LOG_HELP = 1 << 2,
|
GIMP_LOG_HELP = 1 << 2,
|
||||||
GIMP_LOG_DIALOG_FACTORY = 1 << 3,
|
GIMP_LOG_DIALOG_FACTORY = 1 << 3,
|
||||||
GIMP_LOG_SAVE_DIALOG = 1 << 4
|
GIMP_LOG_SAVE_DIALOG = 1 << 4,
|
||||||
|
GIMP_LOG_IMAGE_SCALE = 1 << 5
|
||||||
} GimpLogFlags;
|
} GimpLogFlags;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue