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>
|
||||
|
||||
* modules/Makefile.am
|
||||
|
|
|
@ -124,6 +124,10 @@ static void gimp_drawable_real_update (GimpDrawable *drawable,
|
|||
gint width,
|
||||
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,
|
||||
gboolean push_undo,
|
||||
const gchar *undo_desc,
|
||||
|
@ -206,6 +210,7 @@ gimp_drawable_class_init (GimpDrawableClass *klass)
|
|||
|
||||
klass->update = gimp_drawable_real_update;
|
||||
klass->alpha_changed = NULL;
|
||||
klass->estimate_memsize = gimp_drawable_real_estimate_memsize;
|
||||
klass->invalidate_boundary = NULL;
|
||||
klass->get_active_components = NULL;
|
||||
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));
|
||||
}
|
||||
|
||||
static gint64
|
||||
gimp_drawable_real_estimate_memsize (const GimpDrawable *drawable,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
return (gint64) gimp_drawable_bytes (drawable) * width * height;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_drawable_real_set_tiles (GimpDrawable *drawable,
|
||||
gboolean push_undo,
|
||||
|
@ -758,6 +771,17 @@ gimp_drawable_real_swap_pixels (GimpDrawable *drawable,
|
|||
|
||||
/* 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
|
||||
gimp_drawable_configure (GimpDrawable *drawable,
|
||||
GimpImage *image,
|
||||
|
|
|
@ -61,6 +61,9 @@ struct _GimpDrawableClass
|
|||
void (* alpha_changed) (GimpDrawable *drawable);
|
||||
|
||||
/* virtual functions */
|
||||
gint64 (* estimate_memsize) (const GimpDrawable *drawable,
|
||||
gint width,
|
||||
gint height);
|
||||
void (* invalidate_boundary) (GimpDrawable *drawable);
|
||||
void (* get_active_components) (const GimpDrawable *drawable,
|
||||
gboolean *active);
|
||||
|
@ -109,6 +112,10 @@ struct _GimpDrawableClass
|
|||
|
||||
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,
|
||||
GimpImage *image,
|
||||
gint offset_x,
|
||||
|
|
|
@ -159,8 +159,8 @@ gimp_image_item_list_transform (GimpImage *image,
|
|||
* Return value: The list of items, excluding @exclude.
|
||||
**/
|
||||
GList *
|
||||
gimp_image_item_list_get_list (GimpImage *image,
|
||||
GimpItem *exclude,
|
||||
gimp_image_item_list_get_list (const GimpImage *image,
|
||||
const GimpItem *exclude,
|
||||
GimpItemTypeMask type,
|
||||
GimpItemSet set)
|
||||
{
|
||||
|
|
|
@ -48,8 +48,8 @@ void gimp_image_item_list_transform (GimpImage *image,
|
|||
GimpTransformResize clip_result,
|
||||
GimpProgress *progress);
|
||||
|
||||
GList * gimp_image_item_list_get_list (GimpImage *image,
|
||||
GimpItem *exclude,
|
||||
GList * gimp_image_item_list_get_list (const GimpImage *image,
|
||||
const GimpItem *exclude,
|
||||
GimpItemTypeMask type,
|
||||
GimpItemSet set);
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "gimpguide.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-guides.h"
|
||||
#include "gimpimage-item-list.h"
|
||||
#include "gimpimage-sample-points.h"
|
||||
#include "gimpimage-scale.h"
|
||||
#include "gimpimage-undo.h"
|
||||
|
@ -35,9 +36,11 @@
|
|||
#include "gimplayer.h"
|
||||
#include "gimplist.h"
|
||||
#include "gimpprogress.h"
|
||||
#include "gimpprojection.h"
|
||||
#include "gimpsamplepoint.h"
|
||||
#include "gimpsubprogress.h"
|
||||
|
||||
#include "gimp-log.h"
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
|
@ -234,9 +237,11 @@ gimp_image_scale_check (const GimpImage *image,
|
|||
gint64 max_memsize,
|
||||
gint64 *new_memsize)
|
||||
{
|
||||
GList *drawables;
|
||||
GList *list;
|
||||
gint64 current_size;
|
||||
gint64 scalable_size;
|
||||
gint64 scaled_size;
|
||||
gint64 undo_size;
|
||||
gint64 redo_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);
|
||||
|
||||
/* the part of the image's memsize that scales linearly with the image */
|
||||
scalable_size =
|
||||
gimp_object_get_memsize (GIMP_OBJECT (image->layers), NULL) +
|
||||
gimp_object_get_memsize (GIMP_OBJECT (image->channels), NULL) +
|
||||
gimp_object_get_memsize (GIMP_OBJECT (image->selection_mask), NULL) +
|
||||
gimp_object_get_memsize (GIMP_OBJECT (image->projection), NULL);
|
||||
drawables = gimp_image_item_list_get_list (image, NULL,
|
||||
GIMP_ITEM_TYPE_LAYERS |
|
||||
GIMP_ITEM_TYPE_CHANNELS,
|
||||
GIMP_ITEM_SET_ALL);
|
||||
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);
|
||||
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: */
|
||||
new_size = (fixed_size + /* the fixed part */
|
||||
scalable_size * /* plus the part that scales... */
|
||||
((gdouble) new_width / gimp_image_get_width (image)) *
|
||||
((gdouble) new_height / gimp_image_get_height (image)));
|
||||
scaled_size); /* plus the part that scales... */
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -136,6 +136,10 @@ static void gimp_layer_transform (GimpItem *item,
|
|||
gint recursion_level,
|
||||
GimpTransformResize clip_result,
|
||||
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_get_active_components (const GimpDrawable *drawable,
|
||||
gboolean *active);
|
||||
|
@ -250,6 +254,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
|
|||
item_class->rotate_desc = _("Rotate 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->get_active_components = gimp_layer_get_active_components;
|
||||
drawable_class->set_tiles = gimp_layer_set_tiles;
|
||||
|
@ -798,6 +803,23 @@ gimp_layer_transform (GimpItem *item,
|
|||
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
|
||||
gimp_layer_invalidate_boundary (GimpDrawable *drawable)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,8 @@ gimp_log_init (void)
|
|||
{ "dnd", GIMP_LOG_DND },
|
||||
{ "help", GIMP_LOG_HELP },
|
||||
{ "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,
|
||||
|
|
|
@ -26,7 +26,8 @@ typedef enum
|
|||
GIMP_LOG_DND = 1 << 1,
|
||||
GIMP_LOG_HELP = 1 << 2,
|
||||
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;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue