add an "add_alpha" parameter to allow selected regions to be extracted

2000-03-26  Michael Natterer  <mitch@gimp.org>

	* app/gimage_mask.[ch] (gimage_mask_extract): add an "add_alpha"
	parameter to allow selected regions to be extracted without having
	an alpha channel added.

	* app/global_edit.c: pass add_alpha = TRUE.

	* app/transform_core.[ch]: made the transform core work on
	non-layer drawables even if no selection is present. Fixes #7485
	and #7555.

	- transform_core_cut(): extract the mask without alpha if
	  operating on a non-layer without having a selection.
	- transform_core_paste(): return a boolean indicating success
	  instead of a layer and handle channels correctly.
	- transform_core_do(): if the "floating_tiles" passed to the
	  function are from an un-floated non-layer, treat the whole
	  non-layer as alpha channel and never enter the loop which
	  transforms the (not present) color channels.
	  Also clip the result to ensure that the channel never grows
	  larger then the image.

	* app/tools_cmds.c
	* tools/pdbgen/pdb/tools.pdb: transform_core_paste() returns a
	gboolean now.
This commit is contained in:
Michael Natterer 2000-03-26 18:39:03 +00:00 committed by Michael Natterer
parent 7de34c05d9
commit 5735b2adcd
17 changed files with 323 additions and 306 deletions

View File

@ -1,3 +1,30 @@
2000-03-26 Michael Natterer <mitch@gimp.org>
* app/gimage_mask.[ch] (gimage_mask_extract): add an "add_alpha"
parameter to allow selected regions to be extracted without having
an alpha channel added.
* app/global_edit.c: pass add_alpha = TRUE.
* app/transform_core.[ch]: made the transform core work on
non-layer drawables even if no selection is present. Fixes #7485
and #7555.
- transform_core_cut(): extract the mask without alpha if
operating on a non-layer without having a selection.
- transform_core_paste(): return a boolean indicating success
instead of a layer and handle channels correctly.
- transform_core_do(): if the "floating_tiles" passed to the
function are from an un-floated non-layer, treat the whole
non-layer as alpha channel and never enter the loop which
transforms the (not present) color channels.
Also clip the result to ensure that the channel never grows
larger then the image.
* app/tools_cmds.c
* tools/pdbgen/pdb/tools.pdb: transform_core_paste() returns a
gboolean now.
2000-03-26 Sven Neumann <sven@gimp.org>
* plug-ins/gap/gap_main.c
@ -44,7 +71,7 @@ Sat Mar 25 20:57:24 CET 2000 Stanislav Brabec <utx@penguin.cz>
* app/gimage_cmds.c: corrected the description and help for the
gimp_image_[get|set]_component_* functions.
* app/info_dialog.h: include dialog_handler.h
* app/info_dialog.c: include dialog_handler.h
2000-03-25 Sven Neumann <sven@gimp.org>

View File

@ -192,7 +192,7 @@ edit_cut (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* Next, cut the mask portion from the gimage */
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (cut && empty == FALSE)
@ -243,7 +243,7 @@ edit_copy (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* First, copy the masked portion of the gimage */
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE);
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (copy && empty == FALSE)

View File

@ -192,7 +192,7 @@ edit_cut (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* Next, cut the mask portion from the gimage */
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (cut && empty == FALSE)
@ -243,7 +243,7 @@ edit_copy (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* First, copy the masked portion of the gimage */
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE);
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (copy && empty == FALSE)

View File

@ -183,7 +183,8 @@ TileManager *
gimage_mask_extract (GImage *gimage,
GimpDrawable *drawable,
gboolean cut_gimage,
gboolean keep_indexed)
gboolean keep_indexed,
gboolean add_alpha)
{
TileManager * tiles;
Channel * sel_mask;
@ -216,17 +217,23 @@ gimage_mask_extract (GImage *gimage,
switch (drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
bytes = 4; type = RGB; break;
bytes = add_alpha ? 4 : drawable->bytes;
type = RGB;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
bytes = 2; type = GRAY; break;
bytes = add_alpha ? 2 : drawable->bytes;
type = GRAY;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
if (keep_indexed)
{
bytes = 2; type = GRAY;
bytes = add_alpha ? 2 : drawable->bytes;
type = GRAY;
}
else
{
bytes = 4; type = INDEXED;
bytes = add_alpha ? 4 : drawable->bytes;
type = INDEXED;
}
break;
default:
@ -347,7 +354,7 @@ gimage_mask_float (GImage *gimage,
undo_push_group_start (gimage, FLOAT_MASK_UNDO);
/* Cut the selected region */
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
/* Create a new layer from the buffer */
layer = layer_new_from_tiles (gimage, gimp_drawable_type_with_alpha(drawable), tiles,

View File

@ -49,7 +49,8 @@ void gimage_mask_translate (GImage *gimage,
TileManager * gimage_mask_extract (GImage *gimage,
GimpDrawable *drawable,
gboolean cut_gimage,
gboolean keep_indexed);
gboolean keep_indexed,
gboolean add_alpha);
Layer * gimage_mask_float (GImage *gimage,
GimpDrawable *drawable,

View File

@ -183,7 +183,8 @@ TileManager *
gimage_mask_extract (GImage *gimage,
GimpDrawable *drawable,
gboolean cut_gimage,
gboolean keep_indexed)
gboolean keep_indexed,
gboolean add_alpha)
{
TileManager * tiles;
Channel * sel_mask;
@ -216,17 +217,23 @@ gimage_mask_extract (GImage *gimage,
switch (drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
bytes = 4; type = RGB; break;
bytes = add_alpha ? 4 : drawable->bytes;
type = RGB;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
bytes = 2; type = GRAY; break;
bytes = add_alpha ? 2 : drawable->bytes;
type = GRAY;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
if (keep_indexed)
{
bytes = 2; type = GRAY;
bytes = add_alpha ? 2 : drawable->bytes;
type = GRAY;
}
else
{
bytes = 4; type = INDEXED;
bytes = add_alpha ? 4 : drawable->bytes;
type = INDEXED;
}
break;
default:
@ -347,7 +354,7 @@ gimage_mask_float (GImage *gimage,
undo_push_group_start (gimage, FLOAT_MASK_UNDO);
/* Cut the selected region */
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
/* Create a new layer from the buffer */
layer = layer_new_from_tiles (gimage, gimp_drawable_type_with_alpha(drawable), tiles,

View File

@ -49,7 +49,8 @@ void gimage_mask_translate (GImage *gimage,
TileManager * gimage_mask_extract (GImage *gimage,
GimpDrawable *drawable,
gboolean cut_gimage,
gboolean keep_indexed);
gboolean keep_indexed,
gboolean add_alpha);
Layer * gimage_mask_float (GImage *gimage,
GimpDrawable *drawable,

View File

@ -192,7 +192,7 @@ edit_cut (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* Next, cut the mask portion from the gimage */
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (cut && empty == FALSE)
@ -243,7 +243,7 @@ edit_copy (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* First, copy the masked portion of the gimage */
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE);
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE, TRUE);
/* Only crop if the gimage mask wasn't empty */
if (copy && empty == FALSE)

View File

@ -538,7 +538,7 @@ transform_core_doit (Tool *tool,
new_tiles = (* transform_core->trans_func) (tool, gdisp_ptr, FINISH);
(* transform_core->trans_func) (tool, gdisp_ptr, INIT);
transform_core_recalc (tool, gdisp_ptr);
if (new_tiles)
@ -1171,8 +1171,8 @@ transform_core_do (GImage *gimage,
alpha = 0;
/* turn interpolation off for simple transformations (e.g. rot90) */
if (gimp_matrix3_is_simple (matrix)
|| interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
if (gimp_matrix3_is_simple (matrix) ||
interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
interpolation = FALSE;
/* Get the background color */
@ -1196,6 +1196,17 @@ transform_core_do (GImage *gimage,
break;
}
/* enable rotating un-floated non-layers */
if (float_tiles->bpp == 1)
{
bg_col[0] = OPAQUE_OPACITY;
/* setting alpha = 0 will cause the channel's value to be treated
* as alpha and the color channel loops never to be entered
*/
alpha = 0;
}
if (transform_tool_direction () == TRANSFORM_CORRECTIVE)
{
/* keep the original matrix here, so we dont need to recalculate
@ -1218,7 +1229,7 @@ transform_core_do (GImage *gimage,
y2 = y1 + float_tiles->height;
/* Find the bounding coordinates */
if (active_tool && transform_tool_clip ())
if (alpha == 0 || (active_tool && transform_tool_clip ()))
{
tx1 = x1;
ty1 = y1;
@ -1272,9 +1283,9 @@ transform_core_do (GImage *gimage,
pixel_surround_init (&surround, float_tiles, 1, 1, bg_col);
}
width = tiles->width;
width = tiles->width;
height = tiles->height;
bytes = tiles->bpp;
bytes = tiles->bpp;
dest = g_new (guchar, width * bytes);
@ -1319,10 +1330,8 @@ transform_core_do (GImage *gimage,
if (interpolation)
{
if (interpolation_type == CUBIC_INTERPOLATION)
{
/* ttx & tty are the subpixel coordinates of the point in
* the original selection's floating buffer.
* We need the four integer pixel coords around them:
@ -1352,33 +1361,35 @@ transform_core_do (GImage *gimage,
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = cubic (dy,
CUBIC_ROW (dx, start, bytes),
CUBIC_ROW (dx, start + row, bytes),
start = &data[alpha];
a_val = cubic (dy,
CUBIC_ROW (dx, start, bytes),
CUBIC_ROW (dx, start + row, bytes),
CUBIC_ROW (dx, start + row + row, bytes),
CUBIC_ROW (dx, start + row + row + row, bytes));
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0;
d[alpha] = 0;
}
else if (a_val > 255.0)
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
d[alpha] = RINT(a_val);
}
/* for colour channels c,
* result = bicubic (c * alpha) / bicubic (alpha)
*/
for (i = -alpha; i < 0; ++i)
/* for colour channels c,
* result = bicubic (c * alpha) / bicubic (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
start = &data[alpha];
newval =
@ -1388,24 +1399,24 @@ transform_core_do (GImage *gimage,
CUBIC_SCALED_ROW (dx, start + row, bytes, i),
CUBIC_SCALED_ROW (dx, start + row + row, bytes, i),
CUBIC_SCALED_ROW (dx, start + row + row + row, bytes, i)));
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
pixel_surround_release (&surround);
}
else /* not in source range */
{
@ -1441,10 +1452,10 @@ transform_core_do (GImage *gimage,
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
@ -1462,8 +1473,10 @@ transform_core_do (GImage *gimage,
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
@ -1473,21 +1486,22 @@ transform_core_do (GImage *gimage,
chan[row] * chan[row+i],
chan[row+bytes] * chan[row+bytes+i],
dx, dy));
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
}
/* already set alpha */
d++;
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
@ -1552,13 +1566,16 @@ transform_core_cut (GImage *gimage,
/* extract the selected mask if there is a selection */
if (! gimage_mask_is_empty (gimage))
{
tiles = gimage_mask_extract (gimage, drawable, TRUE, TRUE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, TRUE, TRUE);
*new_layer = TRUE;
}
/* otherwise, just copy the layer */
else
{
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE);
if (GIMP_IS_LAYER (drawable))
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, TRUE);
else
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, FALSE);
*new_layer = FALSE;
}
@ -1567,23 +1584,27 @@ transform_core_cut (GImage *gimage,
/* Paste a transform to the gdisplay */
Layer *
gboolean
transform_core_paste (GImage *gimage,
GimpDrawable *drawable,
TileManager *tiles,
gboolean new_layer)
{
Layer *layer;
Layer *floating_layer;
Layer *layer = NULL;
Channel *channel = NULL;
Layer *floating_layer;
if (new_layer)
{
layer = layer_new_from_tiles (gimage, gimp_drawable_type_with_alpha(drawable), tiles, _("Transformation"),
layer = layer_new_from_tiles (gimage,
gimp_drawable_type_with_alpha (drawable),
tiles,
_("Transformation"),
OPAQUE_OPACITY, NORMAL_MODE);
if (!layer)
{
g_warning ("transform_core_paste: layer_new_frome_tiles() failed");
return NULL;
return FALSE;
}
GIMP_DRAWABLE (layer)->offset_x = tiles->x;
GIMP_DRAWABLE (layer)->offset_y = tiles->y;
@ -1599,55 +1620,61 @@ transform_core_paste (GImage *gimage,
/* Free the tiles */
tile_manager_destroy (tiles);
return layer;
return TRUE;
}
else
{
if (GIMP_IS_LAYER (drawable))
layer = GIMP_LAYER (drawable);
else if (GIMP_IS_CHANNEL (drawable))
channel = GIMP_CHANNEL (drawable);
else
return NULL;
return FALSE;
layer_add_alpha (layer);
if (layer)
layer_add_alpha (layer);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
floating_sel_relax (floating_layer, TRUE);
gdisplays_update_area (gimage,
GIMP_DRAWABLE (layer)->offset_x,
GIMP_DRAWABLE (layer)->offset_y,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
drawable->offset_x,
drawable->offset_y,
drawable->width,
drawable->height);
/* Push an undo */
undo_push_layer_mod (gimage, layer);
if (layer)
undo_push_layer_mod (gimage, layer);
else if (channel)
undo_push_channel_mod (gimage, channel);
/* set the current layer's data */
GIMP_DRAWABLE(layer)->tiles = tiles;
drawable->tiles = tiles;
/* Fill in the new layer's attributes */
GIMP_DRAWABLE (layer)->width = tiles->width;
GIMP_DRAWABLE (layer)->height = tiles->height;
GIMP_DRAWABLE (layer)->bytes = tiles->bpp;
GIMP_DRAWABLE (layer)->offset_x = tiles->x;
GIMP_DRAWABLE (layer)->offset_y = tiles->y;
drawable->width = tiles->width;
drawable->height = tiles->height;
drawable->bytes = tiles->bpp;
drawable->offset_x = tiles->x;
drawable->offset_y = tiles->y;
if (floating_layer)
floating_sel_rigor (floating_layer, TRUE);
drawable_update (GIMP_DRAWABLE (layer),
drawable_update (drawable,
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
gimp_drawable_width (drawable),
gimp_drawable_height (drawable));
/* if we were operating on the floating selection, then it's boundary
* and previews need invalidating
*/
if (layer == floating_layer)
if (drawable == (GimpDrawable *) floating_layer)
floating_sel_invalidate (floating_layer);
return layer;
return TRUE;
}
}

View File

@ -163,7 +163,7 @@ TileManager * transform_core_do (GImage *gimage,
TileManager * transform_core_cut (GImage *gimage,
GimpDrawable *drawable,
gboolean *new_layer);
Layer * transform_core_paste (GImage *gimage,
gboolean transform_core_paste (GImage *gimage,
GimpDrawable *drawable,
TileManager *tiles,
gboolean new_layer);

View File

@ -1565,7 +1565,6 @@ flip_invoker (Argument *args)
gint32 flip_type;
GimpImage *gimage;
TileManager *float_tiles, *new_tiles;
Layer *layer;
gboolean new_layer;
drawable = gimp_drawable_get_ID (args[0].value.pdb_int);
@ -1606,10 +1605,7 @@ flip_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = (layer != NULL);
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -2107,7 +2103,6 @@ perspective_invoker (Argument *args)
gboolean interpolation;
GimpImage *gimage;
TileManager *float_tiles, *new_tiles;
Layer *layer;
gboolean new_layer;
double cx, cy;
double scalex, scaley;
@ -2175,10 +2170,7 @@ perspective_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -2388,7 +2380,6 @@ rotate_invoker (Argument *args)
gdouble angle;
GimpImage *gimage;
TileManager *float_tiles, *new_tiles;
Layer *layer;
gboolean new_layer;
double cx, cy;
GimpMatrix3 matrix;
@ -2428,10 +2419,7 @@ rotate_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -2500,7 +2488,6 @@ scale_invoker (Argument *args)
gboolean interpolation;
GimpImage *gimage;
TileManager *float_tiles, *new_tiles;
Layer *layer;
gboolean new_layer;
double scalex, scaley;
double trans_info[4];
@ -2555,10 +2542,7 @@ scale_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -2647,7 +2631,6 @@ shear_invoker (Argument *args)
gdouble magnitude;
GimpImage *gimage;
TileManager *float_tiles, *new_tiles;
Layer *layer;
gboolean new_layer;
double cx, cy;
GimpMatrix3 matrix;
@ -2698,10 +2681,7 @@ shear_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;

View File

@ -538,7 +538,7 @@ transform_core_doit (Tool *tool,
new_tiles = (* transform_core->trans_func) (tool, gdisp_ptr, FINISH);
(* transform_core->trans_func) (tool, gdisp_ptr, INIT);
transform_core_recalc (tool, gdisp_ptr);
if (new_tiles)
@ -1171,8 +1171,8 @@ transform_core_do (GImage *gimage,
alpha = 0;
/* turn interpolation off for simple transformations (e.g. rot90) */
if (gimp_matrix3_is_simple (matrix)
|| interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
if (gimp_matrix3_is_simple (matrix) ||
interpolation_type == NEAREST_NEIGHBOR_INTERPOLATION)
interpolation = FALSE;
/* Get the background color */
@ -1196,6 +1196,17 @@ transform_core_do (GImage *gimage,
break;
}
/* enable rotating un-floated non-layers */
if (float_tiles->bpp == 1)
{
bg_col[0] = OPAQUE_OPACITY;
/* setting alpha = 0 will cause the channel's value to be treated
* as alpha and the color channel loops never to be entered
*/
alpha = 0;
}
if (transform_tool_direction () == TRANSFORM_CORRECTIVE)
{
/* keep the original matrix here, so we dont need to recalculate
@ -1218,7 +1229,7 @@ transform_core_do (GImage *gimage,
y2 = y1 + float_tiles->height;
/* Find the bounding coordinates */
if (active_tool && transform_tool_clip ())
if (alpha == 0 || (active_tool && transform_tool_clip ()))
{
tx1 = x1;
ty1 = y1;
@ -1272,9 +1283,9 @@ transform_core_do (GImage *gimage,
pixel_surround_init (&surround, float_tiles, 1, 1, bg_col);
}
width = tiles->width;
width = tiles->width;
height = tiles->height;
bytes = tiles->bpp;
bytes = tiles->bpp;
dest = g_new (guchar, width * bytes);
@ -1319,10 +1330,8 @@ transform_core_do (GImage *gimage,
if (interpolation)
{
if (interpolation_type == CUBIC_INTERPOLATION)
{
/* ttx & tty are the subpixel coordinates of the point in
* the original selection's floating buffer.
* We need the four integer pixel coords around them:
@ -1352,33 +1361,35 @@ transform_core_do (GImage *gimage,
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = cubic (dy,
CUBIC_ROW (dx, start, bytes),
CUBIC_ROW (dx, start + row, bytes),
start = &data[alpha];
a_val = cubic (dy,
CUBIC_ROW (dx, start, bytes),
CUBIC_ROW (dx, start + row, bytes),
CUBIC_ROW (dx, start + row + row, bytes),
CUBIC_ROW (dx, start + row + row + row, bytes));
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0;
d[alpha] = 0;
}
else if (a_val > 255.0)
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
d[alpha] = RINT(a_val);
}
/* for colour channels c,
* result = bicubic (c * alpha) / bicubic (alpha)
*/
for (i = -alpha; i < 0; ++i)
/* for colour channels c,
* result = bicubic (c * alpha) / bicubic (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
start = &data[alpha];
newval =
@ -1388,24 +1399,24 @@ transform_core_do (GImage *gimage,
CUBIC_SCALED_ROW (dx, start + row, bytes, i),
CUBIC_SCALED_ROW (dx, start + row + row, bytes, i),
CUBIC_SCALED_ROW (dx, start + row + row + row, bytes, i)));
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
pixel_surround_release (&surround);
}
else /* not in source range */
{
@ -1441,10 +1452,10 @@ transform_core_do (GImage *gimage,
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
@ -1462,8 +1473,10 @@ transform_core_do (GImage *gimage,
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
@ -1473,21 +1486,22 @@ transform_core_do (GImage *gimage,
chan[row] * chan[row+i],
chan[row+bytes] * chan[row+bytes+i],
dx, dy));
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
if (newval <= 0)
{
*d++ = 0;
}
else if (newval > 255)
{
*d++ = 255;
}
else
{
*d++ = newval;
}
}
/* already set alpha */
d++;
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
@ -1552,13 +1566,16 @@ transform_core_cut (GImage *gimage,
/* extract the selected mask if there is a selection */
if (! gimage_mask_is_empty (gimage))
{
tiles = gimage_mask_extract (gimage, drawable, TRUE, TRUE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, TRUE, TRUE);
*new_layer = TRUE;
}
/* otherwise, just copy the layer */
else
{
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE);
if (GIMP_IS_LAYER (drawable))
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, TRUE);
else
tiles = gimage_mask_extract (gimage, drawable, FALSE, TRUE, FALSE);
*new_layer = FALSE;
}
@ -1567,23 +1584,27 @@ transform_core_cut (GImage *gimage,
/* Paste a transform to the gdisplay */
Layer *
gboolean
transform_core_paste (GImage *gimage,
GimpDrawable *drawable,
TileManager *tiles,
gboolean new_layer)
{
Layer *layer;
Layer *floating_layer;
Layer *layer = NULL;
Channel *channel = NULL;
Layer *floating_layer;
if (new_layer)
{
layer = layer_new_from_tiles (gimage, gimp_drawable_type_with_alpha(drawable), tiles, _("Transformation"),
layer = layer_new_from_tiles (gimage,
gimp_drawable_type_with_alpha (drawable),
tiles,
_("Transformation"),
OPAQUE_OPACITY, NORMAL_MODE);
if (!layer)
{
g_warning ("transform_core_paste: layer_new_frome_tiles() failed");
return NULL;
return FALSE;
}
GIMP_DRAWABLE (layer)->offset_x = tiles->x;
GIMP_DRAWABLE (layer)->offset_y = tiles->y;
@ -1599,55 +1620,61 @@ transform_core_paste (GImage *gimage,
/* Free the tiles */
tile_manager_destroy (tiles);
return layer;
return TRUE;
}
else
{
if (GIMP_IS_LAYER (drawable))
layer = GIMP_LAYER (drawable);
else if (GIMP_IS_CHANNEL (drawable))
channel = GIMP_CHANNEL (drawable);
else
return NULL;
return FALSE;
layer_add_alpha (layer);
if (layer)
layer_add_alpha (layer);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
floating_sel_relax (floating_layer, TRUE);
gdisplays_update_area (gimage,
GIMP_DRAWABLE (layer)->offset_x,
GIMP_DRAWABLE (layer)->offset_y,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
drawable->offset_x,
drawable->offset_y,
drawable->width,
drawable->height);
/* Push an undo */
undo_push_layer_mod (gimage, layer);
if (layer)
undo_push_layer_mod (gimage, layer);
else if (channel)
undo_push_channel_mod (gimage, channel);
/* set the current layer's data */
GIMP_DRAWABLE(layer)->tiles = tiles;
drawable->tiles = tiles;
/* Fill in the new layer's attributes */
GIMP_DRAWABLE (layer)->width = tiles->width;
GIMP_DRAWABLE (layer)->height = tiles->height;
GIMP_DRAWABLE (layer)->bytes = tiles->bpp;
GIMP_DRAWABLE (layer)->offset_x = tiles->x;
GIMP_DRAWABLE (layer)->offset_y = tiles->y;
drawable->width = tiles->width;
drawable->height = tiles->height;
drawable->bytes = tiles->bpp;
drawable->offset_x = tiles->x;
drawable->offset_y = tiles->y;
if (floating_layer)
floating_sel_rigor (floating_layer, TRUE);
drawable_update (GIMP_DRAWABLE (layer),
drawable_update (drawable,
0, 0,
GIMP_DRAWABLE (layer)->width,
GIMP_DRAWABLE (layer)->height);
gimp_drawable_width (drawable),
gimp_drawable_height (drawable));
/* if we were operating on the floating selection, then it's boundary
* and previews need invalidating
*/
if (layer == floating_layer)
if (drawable == (GimpDrawable *) floating_layer)
floating_sel_invalidate (floating_layer);
return layer;
return TRUE;
}
}

View File

@ -163,7 +163,7 @@ TileManager * transform_core_do (GImage *gimage,
TileManager * transform_core_cut (GImage *gimage,
GimpDrawable *drawable,
gboolean *new_layer);
Layer * transform_core_paste (GImage *gimage,
gboolean transform_core_paste (GImage *gimage,
GimpDrawable *drawable,
TileManager *tiles,
gboolean new_layer);

View File

@ -688,7 +688,7 @@ HELP
%invoke = (
headers => [ qw("flip_tool.h" "transform_core.h" "undo.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer' ],
'gboolean new_layer' ],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
@ -719,10 +719,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = (layer != NULL);
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -982,7 +979,7 @@ HELP
headers => [ qw("perspective_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'double scalex, scaley', 'double trans_info[8]',
'GimpMatrix3 m, matrix' ],
code => <<'CODE'
@ -1024,10 +1021,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1105,7 +1099,7 @@ HELP
%invoke = (
headers => [ qw("rotate_tool.h" "transform_core.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1134,10 +1128,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1188,7 +1179,7 @@ HELP
headers => [ qw("scale_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double scalex, scaley',
'gboolean new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1225,10 +1216,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1279,7 +1267,7 @@ HELP
headers => [ qw("shear_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1315,10 +1303,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;

View File

@ -688,7 +688,7 @@ HELP
%invoke = (
headers => [ qw("flip_tool.h" "transform_core.h" "undo.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer' ],
'gboolean new_layer' ],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
@ -719,10 +719,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = (layer != NULL);
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -982,7 +979,7 @@ HELP
headers => [ qw("perspective_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'double scalex, scaley', 'double trans_info[8]',
'GimpMatrix3 m, matrix' ],
code => <<'CODE'
@ -1024,10 +1021,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1105,7 +1099,7 @@ HELP
%invoke = (
headers => [ qw("rotate_tool.h" "transform_core.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1134,10 +1128,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1188,7 +1179,7 @@ HELP
headers => [ qw("scale_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double scalex, scaley',
'gboolean new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1225,10 +1216,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1279,7 +1267,7 @@ HELP
headers => [ qw("shear_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1315,10 +1303,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;

View File

@ -688,7 +688,7 @@ HELP
%invoke = (
headers => [ qw("flip_tool.h" "transform_core.h" "undo.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer' ],
'gboolean new_layer' ],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
@ -719,10 +719,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = (layer != NULL);
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -982,7 +979,7 @@ HELP
headers => [ qw("perspective_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'double scalex, scaley', 'double trans_info[8]',
'GimpMatrix3 m, matrix' ],
code => <<'CODE'
@ -1024,10 +1021,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1105,7 +1099,7 @@ HELP
%invoke = (
headers => [ qw("rotate_tool.h" "transform_core.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1134,10 +1128,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1188,7 +1179,7 @@ HELP
headers => [ qw("scale_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double scalex, scaley',
'gboolean new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1225,10 +1216,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1279,7 +1267,7 @@ HELP
headers => [ qw("shear_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1315,10 +1303,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;

View File

@ -688,7 +688,7 @@ HELP
%invoke = (
headers => [ qw("flip_tool.h" "transform_core.h" "undo.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer' ],
'gboolean new_layer' ],
code => <<'CODE'
{
gimage = drawable_gimage (GIMP_DRAWABLE (drawable));
@ -719,10 +719,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = (layer != NULL);
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -982,7 +979,7 @@ HELP
headers => [ qw("perspective_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'double scalex, scaley', 'double trans_info[8]',
'GimpMatrix3 m, matrix' ],
code => <<'CODE'
@ -1024,10 +1021,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1105,7 +1099,7 @@ HELP
%invoke = (
headers => [ qw("rotate_tool.h" "transform_core.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1134,10 +1128,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1188,7 +1179,7 @@ HELP
headers => [ qw("scale_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double scalex, scaley',
'gboolean new_layer', 'double scalex, scaley',
'double trans_info[4]', 'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1225,10 +1216,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;
@ -1279,7 +1267,7 @@ HELP
headers => [ qw("shear_tool.h" "transform_core.h"
"tile_manager_pvt.h") ],
vars => [ 'GimpImage *gimage', 'TileManager *float_tiles, *new_tiles',
'Layer *layer', 'gboolean new_layer', 'double cx, cy',
'gboolean new_layer', 'double cx, cy',
'GimpMatrix3 matrix' ],
code => <<'CODE'
{
@ -1315,10 +1303,7 @@ HELP
tile_manager_destroy (float_tiles);
if (new_tiles)
{
layer = transform_core_paste (gimage, drawable, new_tiles, new_layer);
success = layer != NULL;
}
success = transform_core_paste (gimage, drawable, new_tiles, new_layer);
else
success = FALSE;