app/core/gimpimage-crop.c (gimp_image_crop) app/core/gimpimage-resize.c

2003-05-09  Michael Natterer  <mitch@gimp.org>

	* app/core/gimpimage-crop.c (gimp_image_crop)
	* app/core/gimpimage-resize.c (gimp_image_resize)
	* app/core/gimpimage-scale.c (gimp_image_scale):
	don't #include "gimpchannel.h". Moved code around so they all do
	their stuff in the same order (improves readability when comparing
	the functions). Use GimpItem variables instead of GimpChannel or
	GimpLayer ones. Lots of cleanup.
This commit is contained in:
Michael Natterer
2003-05-09 11:27:21 +00:00
committed by Michael Natterer
parent 2de90bdb41
commit 3a8ef85b8c
4 changed files with 237 additions and 272 deletions

View File

@ -1,3 +1,13 @@
2003-05-09 Michael Natterer <mitch@gimp.org>
* app/core/gimpimage-crop.c (gimp_image_crop)
* app/core/gimpimage-resize.c (gimp_image_resize)
* app/core/gimpimage-scale.c (gimp_image_scale):
don't #include "gimpchannel.h". Moved code around so they all do
their stuff in the same order (improves readability when comparing
the functions). Use GimpItem variables instead of GimpChannel or
GimpLayer ones. Lots of cleanup.
2003-05-09 Michael Natterer <mitch@gimp.org>
* app/core/gimpimage-crop.c (gimp_image_crop): resize all vectors

View File

@ -27,8 +27,6 @@
#include "base/pixel-region.h"
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpdrawable.h"
#include "gimpimage.h"
#include "gimpimage-crop.h"
#include "gimpimage-guides.h"
@ -61,27 +59,21 @@ typedef AutoCropType (* ColorsEqualFunc) (guchar *,
/* local function prototypes */
static void gimp_image_crop_adjust_guides (GimpImage *gimage,
gint x1,
gint y1,
gint x2,
gint y2);
static AutoCropType gimp_image_crop_guess_bgcolor (GObject *get_color_obj,
GetColorFunc get_color_func,
gint bytes,
gboolean has_alpha,
guchar *color,
gint x1,
gint x2,
gint y1,
gint y2);
static gint gimp_image_crop_colors_equal (guchar *col1,
guchar *col2,
gint bytes);
static gint gimp_image_crop_colors_alpha (guchar *col1,
guchar *col2,
gint bytes);
static AutoCropType gimp_image_crop_guess_bgcolor (GObject *get_color_obj,
GetColorFunc get_color_func,
gint bytes,
gboolean has_alpha,
guchar *color,
gint x1,
gint x2,
gint y1,
gint y2);
static gint gimp_image_crop_colors_equal (guchar *col1,
guchar *col2,
gint bytes);
static gint gimp_image_crop_colors_alpha (guchar *col1,
guchar *col2,
gint bytes);
/* public functions */
@ -95,153 +87,187 @@ gimp_image_crop (GimpImage *gimage,
gboolean active_layer_only,
gboolean crop_layers)
{
GimpLayer *layer;
GimpLayer *floating_layer;
GimpItem *item;
GList *list;
gint width, height;
gint lx1, ly1, lx2, ly2;
gint off_x, off_y;
gint width, height;
g_return_if_fail (gimage != NULL);
g_return_if_fail (GIMP_IS_IMAGE (gimage));
width = x2 - x1;
height = y2 - y1;
/* Make sure new width and height are non-zero */
if (width && height)
if (width < 1 || height < 1)
return;
gimp_set_busy (gimage->gimp);
if (active_layer_only)
{
gimp_set_busy (gimage->gimp);
GimpLayer *layer;
gint off_x, off_y;
if (active_layer_only)
{
gint doff_x, doff_y;
layer = gimp_image_get_active_layer (gimage);
layer = gimp_image_get_active_layer (gimage);
gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
gimp_item_offsets (GIMP_ITEM (layer), &doff_x, &doff_y);
off_x = (doff_x - x1);
off_y = (doff_y - y1);
off_x -= x1;
off_y -= y1;
if (gimp_layer_is_floating_sel (layer))
{
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_LAYER_RESIZE,
_("Resize Layer"));
if (gimp_layer_is_floating_sel (layer))
floating_sel_relax (layer, TRUE);
floating_sel_relax (layer, TRUE);
}
gimp_item_resize (GIMP_ITEM (layer), width, height, off_x, off_y);
gimp_item_resize (GIMP_ITEM (layer), width, height, off_x, off_y);
if (gimp_layer_is_floating_sel (layer))
floating_sel_rigor (layer, TRUE);
if (gimp_layer_is_floating_sel (layer))
{
floating_sel_rigor (layer, TRUE);
gimp_image_undo_group_end (gimage);
}
gimp_image_undo_group_end (gimage);
}
}
else
{
GimpLayer *floating_layer;
GimpItem *item;
GList *list;
floating_layer = gimp_image_floating_sel (gimage);
if (crop_layers)
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_CROP,
_("Crop Image"));
else
{
floating_layer = gimp_image_floating_sel (gimage);
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_RESIZE,
_("Resize Image"));
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_IMAGE_CROP,
_("Crop Image"));
/* relax the floating layer */
if (floating_layer)
floating_sel_relax (floating_layer, TRUE);
/* relax the floating layer */
if (floating_layer)
floating_sel_relax (floating_layer, TRUE);
/* Push the image size to the stack */
gimp_image_undo_push_image_size (gimage, NULL);
/* Push the image size to the stack */
gimp_image_undo_push_image_size (gimage, NULL);
/* Set the new width and height */
gimage->width = width;
gimage->height = height;
/* Set the new width and height */
gimage->width = width;
gimage->height = height;
/* Resize all channels */
for (list = GIMP_LIST (gimage->channels)->list;
list;
list = g_list_next (list))
{
item = (GimpItem *) list->data;
/* Resize all channels */
for (list = GIMP_LIST (gimage->channels)->list;
list;
list = g_list_next (list))
{
item = (GimpItem *) list->data;
gimp_item_resize (item, width, height, -x1, -y1);
}
gimp_item_resize (item, width, height, -x1, -y1);
}
/* Resize all vectors */
for (list = GIMP_LIST (gimage->vectors)->list;
list;
list = g_list_next (list))
{
item = (GimpItem *) list->data;
/* Resize all vectors */
for (list = GIMP_LIST (gimage->vectors)->list;
list;
list = g_list_next (list))
{
item = (GimpItem *) list->data;
gimp_item_resize (item, width, height, -x1, -y1);
}
gimp_item_resize (item, width, height, -x1, -y1);
}
/* Don't forget the selection mask! */
gimp_item_resize (GIMP_ITEM (gimage->selection_mask),
width, height, -x1, -y1);
gimp_image_mask_invalidate (gimage);
/* Don't forget the selection mask! */
gimp_item_resize (GIMP_ITEM (gimage->selection_mask),
width, height, -x1, -y1);
gimp_image_mask_invalidate (gimage);
/* crop all layers */
list = GIMP_LIST (gimage->layers)->list;
/* crop all layers */
list = GIMP_LIST (gimage->layers)->list;
while (list)
{
item = (GimpItem *) list->data;
while (list)
{
GList *next;
list = g_list_next (list);
layer = (GimpLayer *) list->data;
gimp_item_translate (item, -x1, -y1, TRUE);
next = g_list_next (list);
if (crop_layers)
{
gint off_x, off_y;
gint lx1, ly1, lx2, ly2;
gimp_item_translate (GIMP_ITEM (layer), -x1, -y1, TRUE);
gimp_item_offsets (item, &off_x, &off_y);
gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
lx1 = CLAMP (off_x, 0, gimage->width);
ly1 = CLAMP (off_y, 0, gimage->height);
lx2 = CLAMP (gimp_item_width (item) + off_x,
0, gimage->width);
ly2 = CLAMP (gimp_item_height (item) + off_y,
0, gimage->height);
if (crop_layers)
{
lx1 = CLAMP (off_x, 0, gimage->width);
ly1 = CLAMP (off_y, 0, gimage->height);
lx2 = CLAMP ((gimp_item_width (GIMP_ITEM (layer)) + off_x),
0, gimage->width);
ly2 = CLAMP ((gimp_item_height (GIMP_ITEM (layer)) + off_y),
0, gimage->height);
width = lx2 - lx1;
height = ly2 - ly1;
width = lx2 - lx1;
height = ly2 - ly1;
if (width && height)
gimp_item_resize (GIMP_ITEM (layer), width, height,
-(lx1 - off_x),
-(ly1 - off_y));
else
gimp_image_remove_layer (gimage, layer);
}
if (width > 0 && height > 0)
gimp_item_resize (item, width, height,
-(lx1 - off_x),
-(ly1 - off_y));
else
gimp_image_remove_layer (gimage, GIMP_LAYER (item));
}
}
list = next;
}
/* Reposition or remove all guides */
list = gimage->guides;
while (list)
{
GimpGuide *guide = list->data;
gboolean remove_guide = FALSE;
gint new_position = guide->position;
/* Make sure the projection matches the gimage size */
gimp_image_projection_allocate (gimage);
list = g_list_next (list);
/* rigor the floating layer */
if (floating_layer)
floating_sel_rigor (floating_layer, TRUE);
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
new_position -= y1;
if ((guide->position < y1) || (guide->position > y2))
remove_guide = TRUE;
break;
/* Adjust any guides we might have laying about */
gimp_image_crop_adjust_guides (gimage, x1, y1, x2, y2);
case GIMP_ORIENTATION_VERTICAL:
new_position -= x1;
if ((guide->position < x1) || (guide->position > x2))
remove_guide = TRUE;
break;
gimp_image_undo_group_end (gimage);
}
default:
break;
}
gimp_image_update (gimage,
0, 0,
gimage->width,
gimage->height);
if (remove_guide)
gimp_image_remove_guide (gimage, guide, TRUE);
else if (new_position != guide->position)
gimp_image_move_guide (gimage, guide, new_position, TRUE);
}
/* Make sure the projection matches the gimage size */
gimp_image_projection_allocate (gimage);
/* rigor the floating layer */
if (floating_layer)
floating_sel_rigor (floating_layer, TRUE);
gimp_image_undo_group_end (gimage);
gimp_image_update (gimage, 0, 0, gimage->width, gimage->height);
gimp_viewable_size_changed (GIMP_VIEWABLE (gimage));
gimp_image_mask_changed (gimage);
gimp_unset_busy (gimage->gimp);
}
gimp_unset_busy (gimage->gimp);
}
gboolean
@ -396,63 +422,6 @@ gimp_image_crop_auto_shrink (GimpImage *gimage,
/* private functions */
static void
gimp_image_crop_adjust_guides (GimpImage *gimage,
gint x1,
gint y1,
gint x2,
gint y2)
{
GList *list;
list = gimage->guides;
while (list)
{
GimpGuide *guide = list->data;
gboolean remove_guide = FALSE;
list = g_list_next (list);
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
if ((guide->position < y1) || (guide->position > y2))
remove_guide = TRUE;
break;
case GIMP_ORIENTATION_VERTICAL:
if ((guide->position < x1) || (guide->position > x2))
remove_guide = TRUE;
break;
default:
break;
}
if (remove_guide)
{
gimp_image_remove_guide (gimage, guide, TRUE);
}
else
{
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
gimp_image_move_guide (gimage, guide, guide->position - y1, TRUE);
break;
case GIMP_ORIENTATION_VERTICAL:
gimp_image_move_guide (gimage, guide, guide->position - x1, TRUE);
break;
default:
break;
}
}
}
}
static AutoCropType
gimp_image_crop_guess_bgcolor (GObject *get_color_obj,
GetColorFunc get_color_func,

View File

@ -23,7 +23,6 @@
#include "core-types.h"
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpimage.h"
#include "gimpimage-guides.h"
#include "gimpimage-mask.h"
@ -71,8 +70,8 @@ gimp_image_resize (GimpImage *gimage,
gimage->height = new_height;
/* Resize all channels */
for (list = GIMP_LIST (gimage->channels)->list;
list;
for (list = GIMP_LIST (gimage->channels)->list;
list;
list = g_list_next (list))
{
GimpItem *item = list->data;
@ -81,8 +80,8 @@ gimp_image_resize (GimpImage *gimage,
}
/* Resize all vectors */
for (list = GIMP_LIST (gimage->vectors)->list;
list;
for (list = GIMP_LIST (gimage->vectors)->list;
list;
list = g_list_next (list))
{
GimpItem *item = list->data;
@ -90,53 +89,53 @@ gimp_image_resize (GimpImage *gimage,
gimp_item_resize (item, new_width, new_height, offset_x, offset_y);
}
/* Reposition or remove any guides */
list = gimage->guides;
while (list)
{
GimpGuide *guide = list->data;
gboolean remove_guide = FALSE;
gint new_position = 0;
list = g_list_next (list);
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
new_position = guide->position + offset_y;
if (new_position < 0 || new_position > new_height)
remove_guide = TRUE;
break;
case GIMP_ORIENTATION_VERTICAL:
new_position = guide->position + offset_x;
if (new_position < 0 || new_position > new_width)
remove_guide = TRUE;
break;
default:
g_error ("Unknown guide orientation\n");
}
if (remove_guide)
gimp_image_remove_guide (gimage, guide, TRUE);
else
gimp_image_move_guide (gimage, guide, new_position, TRUE);
}
/* Don't forget the selection mask! */
gimp_item_resize (GIMP_ITEM (gimage->selection_mask),
new_width, new_height, offset_x, offset_y);
gimp_image_mask_invalidate (gimage);
/* Reposition all layers */
for (list = GIMP_LIST (gimage->layers)->list;
list;
for (list = GIMP_LIST (gimage->layers)->list;
list;
list = g_list_next (list))
{
GimpLayer *layer = list->data;
GimpItem *item = list->data;
gimp_item_translate (GIMP_ITEM (layer), offset_x, offset_y, TRUE);
gimp_item_translate (item, offset_x, offset_y, TRUE);
}
/* Reposition or remove all guides */
list = gimage->guides;
while (list)
{
GimpGuide *guide = list->data;
gboolean remove_guide = FALSE;
gint new_position = guide->position;
list = g_list_next (list);
switch (guide->orientation)
{
case GIMP_ORIENTATION_HORIZONTAL:
new_position += offset_y;
if (new_position < 0 || new_position > new_height)
remove_guide = TRUE;
break;
case GIMP_ORIENTATION_VERTICAL:
new_position += offset_x;
if (new_position < 0 || new_position > new_width)
remove_guide = TRUE;
break;
default:
break;
}
if (remove_guide)
gimp_image_remove_guide (gimage, guide, TRUE);
else if (new_position != guide->position)
gimp_image_move_guide (gimage, guide, new_position, TRUE);
}
/* Make sure the projection matches the gimage size */

View File

@ -23,7 +23,6 @@
#include "core-types.h"
#include "gimp.h"
#include "gimpchannel.h"
#include "gimpimage.h"
#include "gimpimage-mask.h"
#include "gimpimage-projection.h"
@ -45,21 +44,18 @@ gimp_image_scale (GimpImage *gimage,
GimpProgressFunc progress_func,
gpointer progress_data)
{
GimpItem *item;
GimpLayer *layer;
GimpLayer *floating_layer;
GList *list;
GSList *remove = NULL;
GSList *slist;
GimpGuide *guide;
gint old_width;
gint old_height;
gdouble img_scale_w = 1.0;
gdouble img_scale_h = 1.0;
gint num_channels;
gint num_layers;
gint num_vectors;
gint progress_current = 1;
GimpLayer *floating_layer;
GimpItem *item;
GList *list;
GList *remove = NULL;
gint old_width;
gint old_height;
gdouble img_scale_w = 1.0;
gdouble img_scale_h = 1.0;
gint num_channels;
gint num_layers;
gint num_vectors;
gint progress_current = 1;
g_return_if_fail (GIMP_IS_IMAGE (gimage));
g_return_if_fail (new_width > 0 && new_height > 0);
@ -102,11 +98,9 @@ gimp_image_scale (GimpImage *gimage,
gimp_item_scale (item, new_width, new_height, 0, 0, interpolation_type);
if (progress_func)
{
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
/* Scale all vectors */
@ -119,19 +113,12 @@ gimp_image_scale (GimpImage *gimage,
gimp_item_scale (item, new_width, new_height, 0, 0, interpolation_type);
if (progress_func)
{
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
/* Don't forget the selection mask! */
/* if (channel_is_empty(gimage->selection_mask))
gimp_channel_resize(gimage->selection_mask, new_width, new_height, 0, 0)
else
*/
gimp_item_scale (GIMP_ITEM (gimage->selection_mask), new_width, new_height,
0, 0, interpolation_type);
gimp_image_mask_invalidate (gimage);
@ -148,34 +135,36 @@ gimp_image_scale (GimpImage *gimage,
{
/* Since 0 < img_scale_w, img_scale_h, failure due to one or more
* vanishing scaled layer dimensions. Implicit delete implemented
* here. Upstream warning implemented in resize_check_layer_scaling()
* [resize.c line 1295], which offers the user the chance to bail out.
* here. Upstream warning implemented in resize_check_layer_scaling(),
* which offers the user the chance to bail out.
*/
remove = g_slist_append (remove, item);
remove = g_list_prepend (remove, item);
}
if (progress_func)
{
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
(* progress_func) (0, num_vectors + num_channels + num_layers,
progress_current++,
progress_data);
}
/* We defer removing layers lost to scaling until now so as not to mix
* the operations of iterating over and removal from gimage->layers.
*/
for (slist = remove; slist; slist = g_slist_next (slist))
*/
remove = g_list_reverse (remove);
for (list = remove; list; list = g_list_next (list))
{
layer = slist->data;
GimpLayer *layer = list->data;
gimp_image_remove_layer (gimage, layer);
}
g_slist_free (remove);
/* Scale any Guides */
g_list_free (remove);
/* Scale all Guides */
for (list = gimage->guides; list; list = g_list_next (list))
{
guide = (GimpGuide *) list->data;
GimpGuide *guide = list->data;
switch (guide->orientation)
{
@ -190,7 +179,7 @@ gimp_image_scale (GimpImage *gimage,
break;
default:
g_error("Unknown guide orientation II.\n");
break;
}
}
@ -235,9 +224,7 @@ gimp_image_check_scaling (const GimpImage *gimage,
list;
list = g_list_next (list))
{
GimpItem *item;
item = (GimpItem *) list->data;
GimpItem *item = list->data;
if (! gimp_item_check_scaling (item, new_width, new_height))
return FALSE;