Made the interpolation type configurable in the scale and transform

2002-02-12  Michael Natterer  <mitch@gimp.org>

	Made the interpolation type configurable in the scale and
	transform options dialogs (#69251):

	* app/base/base-config.[ch]
	* app/config/gimpbaseconfig.[ch]: removed interpolation_type here...

	* app/core/gimpcoreconfig.[ch]
	* app/config/gimpcoreconfig.[ch]: ...and added it here.

	* app/gimprc.c
	* app/gui/preferences-dialog.c: changed accordingly.

	* app/paint-funcs/paint-funcs.[ch]: scale_region: take an
	interpolation_type parameter.

	* app/core/gimpchannel.[ch]
	* app/core/gimpdrawable-transform.[ch]
	* app/core/gimpimage-scale.[ch]
	* app/core/gimplayer.[ch]: pass interpolation_type parameters to all
	scale and transform functions.

	* tools/pdbgen/pdb/image.pdb
	* tools/pdbgen/pdb/layer.pdb
	* tools/pdbgen/pdb/transform_tools.pdb: changed accordingly.

	* app/gui/resize-dialog.[ch]
	* app/tools/transform_options.[ch]: added an interpolation_type menu.

	* app/gui/image-commands.c
	* app/gui/layers-commands.c
	* app/tools/gimptransformtool.c: changed accordingly.

	* app/pdb/image_cmds.c
	* app/pdb/layer_cmds.c
	* app/pdb/transform_tools_cmds.c: regenerated.
This commit is contained in:
Michael Natterer 2002-02-12 02:31:45 +00:00 committed by Michael Natterer
parent 912dc07c1d
commit 733d6335fe
44 changed files with 1042 additions and 732 deletions

View File

@ -1,3 +1,41 @@
2002-02-12 Michael Natterer <mitch@gimp.org>
Made the interpolation type configurable in the scale and
transform options dialogs (#69251):
* app/base/base-config.[ch]
* app/config/gimpbaseconfig.[ch]: removed interpolation_type here...
* app/core/gimpcoreconfig.[ch]
* app/config/gimpcoreconfig.[ch]: ...and added it here.
* app/gimprc.c
* app/gui/preferences-dialog.c: changed accordingly.
* app/paint-funcs/paint-funcs.[ch]: scale_region: take an
interpolation_type parameter.
* app/core/gimpchannel.[ch]
* app/core/gimpdrawable-transform.[ch]
* app/core/gimpimage-scale.[ch]
* app/core/gimplayer.[ch]: pass interpolation_type parameters to all
scale and transform functions.
* tools/pdbgen/pdb/image.pdb
* tools/pdbgen/pdb/layer.pdb
* tools/pdbgen/pdb/transform_tools.pdb: changed accordingly.
* app/gui/resize-dialog.[ch]
* app/tools/transform_options.[ch]: added an interpolation_type menu.
* app/gui/image-commands.c
* app/gui/layers-commands.c
* app/tools/gimptransformtool.c: changed accordingly.
* app/pdb/image_cmds.c
* app/pdb/layer_cmds.c
* app/pdb/transform_tools_cmds.c: regenerated.
2002-02-12 Sven Neumann <sven@gimp.org>
* plug-ins/MapObject/mapobject_preview.c:

View File

@ -349,6 +349,7 @@ image_scale_implement (ImageResize *image_scale)
gimp_image_scale (gimage,
image_scale->resize->width,
image_scale->resize->height,
image_scale->resize->interpolation,
progress_update_and_flush, progress);
progress_end (progress);

View File

@ -1021,7 +1021,9 @@ scale_layer_query_ok_callback (GtkWidget *widget,
floating_sel_relax (layer, TRUE);
gimp_layer_scale (layer,
options->resize->width, options->resize->height,
options->resize->width,
options->resize->height,
options->resize->interpolation,
TRUE);
if (gimp_layer_is_floating_sel (layer))

View File

@ -33,13 +33,12 @@
static GimpBaseConfig static_base_config =
{
INIT_MEMBER(temp_path , NULL),
INIT_MEMBER(swap_path , NULL),
INIT_MEMBER(temp_path , NULL),
INIT_MEMBER(swap_path , NULL),
INIT_MEMBER(tile_cache_size , 33554432),
INIT_MEMBER(stingy_memory_use , FALSE),
INIT_MEMBER(interpolation_type , GIMP_LINEAR_INTERPOLATION),
INIT_MEMBER(num_processors , 1)
INIT_MEMBER(tile_cache_size , 33554432),
INIT_MEMBER(stingy_memory_use, FALSE),
INIT_MEMBER(num_processors , 1)
};
#undef INIT_MEMBER

View File

@ -24,12 +24,11 @@ typedef struct _GimpBaseConfig GimpBaseConfig;
struct _GimpBaseConfig
{
gchar *temp_path;
gchar *swap_path;
guint tile_cache_size;
gboolean stingy_memory_use;
GimpInterpolationType interpolation_type;
gint num_processors;
gchar *temp_path;
gchar *swap_path;
guint tile_cache_size;
gboolean stingy_memory_use;
gint num_processors;
};

View File

@ -51,7 +51,6 @@ enum
PROP_STINGY_MEMORY_USE,
PROP_NUM_PROCESSORS,
PROP_TILE_CACHE_SIZE,
PROP_INTERPOLATION_TYPE,
};
static GObjectClass *parent_class = NULL;
@ -114,10 +113,6 @@ gimp_base_config_class_init (GimpBaseConfigClass *klass)
GIMP_CONFIG_INSTALL_PROP_MEMSIZE (object_class, PROP_TILE_CACHE_SIZE,
"tile-cache-size",
0, G_MAXUINT, 1 << 25);
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_INTERPOLATION_TYPE,
"interpolation-type",
GIMP_TYPE_INTERPOLATION_TYPE,
GIMP_LINEAR_INTERPOLATION);
}
static void
@ -162,9 +157,6 @@ gimp_base_config_set_property (GObject *object,
case PROP_TILE_CACHE_SIZE:
base_config->tile_cache_size = g_value_get_uint (value);
break;
case PROP_INTERPOLATION_TYPE:
base_config->interpolation_type = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@ -198,9 +190,6 @@ gimp_base_config_get_property (GObject *object,
case PROP_TILE_CACHE_SIZE:
g_value_set_uint (value, base_config->tile_cache_size);
break;
case PROP_INTERPOLATION_TYPE:
g_value_set_enum (value, base_config->interpolation_type);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;

View File

@ -37,14 +37,13 @@ typedef struct _GimpBaseConfigClass GimpBaseConfigClass;
struct _GimpBaseConfig
{
GObject parent_instance;
GObject parent_instance;
gchar *temp_path;
gchar *swap_path;
gboolean stingy_memory_use;
guint num_processors;
guint tile_cache_size;
GimpInterpolationType interpolation_type;
gchar *temp_path;
gchar *swap_path;
gboolean stingy_memory_use;
guint num_processors;
guint tile_cache_size;
};
struct _GimpBaseConfigClass

View File

@ -46,6 +46,7 @@ static void gimp_core_config_get_property (GObject *object,
enum
{
PROP_0,
PROP_INTERPOLATION_TYPE,
PROP_PLUG_IN_PATH,
PROP_TOOL_PLUG_IN_PATH,
PROP_MODULE_PATH,
@ -119,6 +120,10 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
object_class->set_property = gimp_core_config_set_property;
object_class->get_property = gimp_core_config_get_property;
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_INTERPOLATION_TYPE,
"interpolation-type",
GIMP_TYPE_INTERPOLATION_TYPE,
GIMP_LINEAR_INTERPOLATION);
GIMP_CONFIG_INSTALL_PROP_PATH (object_class, PROP_PLUG_IN_PATH,
"plug-in-path",
gimp_config_build_plug_in_path ("plug-ins"));
@ -240,6 +245,9 @@ gimp_core_config_set_property (GObject *object,
switch (property_id)
{
case PROP_INTERPOLATION_TYPE:
core_config->interpolation_type = g_value_get_enum (value);
break;
case PROP_PLUG_IN_PATH:
g_free (core_config->plug_in_path);
core_config->plug_in_path = g_value_dup_string (value);
@ -354,6 +362,9 @@ gimp_core_config_get_property (GObject *object,
switch (property_id)
{
case PROP_INTERPOLATION_TYPE:
g_value_set_enum (value, core_config->interpolation_type);
break;
case PROP_PLUG_IN_PATH:
g_value_set_string (value, core_config->plug_in_path);
break;

View File

@ -39,35 +39,36 @@ typedef struct _GimpCoreConfigClass GimpCoreConfigClass;
struct _GimpCoreConfig
{
GimpBaseConfig parent_instance;
GimpBaseConfig parent_instance;
gchar *plug_in_path;
gchar *tool_plug_in_path;
gchar *module_path;
gchar *brush_path;
gchar *pattern_path;
gchar *palette_path;
gchar *gradient_path;
gchar *default_brush;
gchar *default_pattern;
gchar *default_palette;
gchar *default_gradient;
gchar *default_comment;
GimpImageBaseType default_image_type;
gint default_image_width;
gint default_image_height;
GimpUnit default_unit;
gdouble default_xresolution;
gdouble default_yresolution;
GimpUnit default_resolution_unit;
gint levels_of_undo;
gchar *plug_in_rc_path;
gchar *module_load_inhibit;
GimpPreviewSize preview_size;
gboolean write_thumbnails;
gdouble gamma_val;
gboolean install_cmap;
gint min_colors;
GimpInterpolationType interpolation_type;
gchar *plug_in_path;
gchar *tool_plug_in_path;
gchar *module_path;
gchar *brush_path;
gchar *pattern_path;
gchar *palette_path;
gchar *gradient_path;
gchar *default_brush;
gchar *default_pattern;
gchar *default_palette;
gchar *default_gradient;
gchar *default_comment;
GimpImageBaseType default_image_type;
gint default_image_width;
gint default_image_height;
GimpUnit default_unit;
gdouble default_xresolution;
gdouble default_yresolution;
GimpUnit default_resolution_unit;
gint levels_of_undo;
gchar *plug_in_rc_path;
gchar *module_load_inhibit;
GimpPreviewSize preview_size;
gboolean write_thumbnails;
gdouble gamma_val;
gboolean install_cmap;
gint min_colors;
};
struct _GimpCoreConfigClass

View File

@ -79,7 +79,7 @@ static gdouble gimp_drawable_transform_cubic (gdouble dx,
TileManager *
gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
TileManager *float_tiles,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction,
@ -123,9 +123,10 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
alpha = 0;
/* turn interpolation off for simple transformations (e.g. rot90) */
if (gimp_matrix3_is_simple (matrix) ||
base_config->interpolation_type == GIMP_NEAREST_NEIGHBOR_INTERPOLATION)
interpolation = FALSE;
if (gimp_matrix3_is_simple (matrix))
{
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
}
/* Get the background color */
gimp_image_get_background (gimage, drawable, bg_col);
@ -144,7 +145,7 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
bg_col[ALPHA_I_PIX] = TRANSPARENT_OPACITY;
alpha = ALPHA_I_PIX;
/* If the gimage is indexed color, ignore smoothing value */
interpolation = FALSE;
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
break;
default:
g_assert_not_reached ();
@ -230,21 +231,20 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
tile_manager_set_offsets (tiles, tx1, ty1);
/* initialise the pixel_surround accessor */
if (interpolation)
{
if (base_config->interpolation_type == GIMP_CUBIC_INTERPOLATION)
{
pixel_surround_init (&surround, float_tiles, 4, 4, bg_col);
}
else
{
pixel_surround_init (&surround, float_tiles, 2, 2, bg_col);
}
}
else
switch (interpolation_type)
{
case GIMP_CUBIC_INTERPOLATION:
pixel_surround_init (&surround, float_tiles, 4, 4, bg_col);
break;
case GIMP_LINEAR_INTERPOLATION:
pixel_surround_init (&surround, float_tiles, 2, 2, bg_col);
break;
case GIMP_NEAREST_NEIGHBOR_INTERPOLATION:
/* not actually useful, keeps the code cleaner */
pixel_surround_init (&surround, float_tiles, 1, 1, bg_col);
break;
}
width = tile_manager_width (tiles);
@ -292,195 +292,192 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
/* Set the destination pixels */
if (interpolation)
{
if (base_config->interpolation_type == GIMP_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:
* itx to itx + 3, ity to ity + 3
*/
itx = floor (ttx);
ity = floor (tty);
/* check if any part of our region overlaps the buffer */
if ((itx + 2) >= x1 && (itx - 1) < x2 &&
(ity + 2) >= y1 && (ity - 1) < y2 )
{
guchar *data;
gint row;
gdouble dx, dy;
guchar *start;
/* lock the pixel surround */
data = pixel_surround_lock (&surround,
itx - 1 - x1, ity - 1 - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = gimp_drawable_transform_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;
}
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
}
/* 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 =
RINT (a_recip *
gimp_drawable_transform_cubic
(dy,
CUBIC_SCALED_ROW (dx, start, bytes, i),
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
else /* linear */
{
itx = floor (ttx);
ity = floor (tty);
/* expand source area to cover interpolation region
* (which runs from itx to itx + 1, same in y)
*/
if ((itx + 1) >= x1 && itx < x2 &&
(ity + 1) >= y1 && ity < y2 )
{
guchar *data;
gint row;
double dx, dy;
guchar *chan;
/* lock the pixel surround */
data = pixel_surround_lock (&surround, itx - x1, ity - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
}
else if (a_val >= 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT (a_val);
}
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
RINT (a_recip *
BILINEAR (chan[0] * chan[i],
chan[bytes] * chan[bytes+i],
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
}
else /* no interpolation */
switch (interpolation_type)
{
case GIMP_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:
* itx to itx + 3, ity to ity + 3
*/
itx = floor (ttx);
ity = floor (tty);
/* check if any part of our region overlaps the buffer */
if ((itx + 2) >= x1 && (itx - 1) < x2 &&
(ity + 2) >= y1 && (ity - 1) < y2 )
{
guchar *data;
gint row;
gdouble dx, dy;
guchar *start;
/* lock the pixel surround */
data = pixel_surround_lock (&surround,
itx - 1 - x1, ity - 1 - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = gimp_drawable_transform_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;
}
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
}
/* 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 =
RINT (a_recip *
gimp_drawable_transform_cubic
(dy,
CUBIC_SCALED_ROW (dx, start, bytes, i),
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
break;
case GIMP_LINEAR_INTERPOLATION:
itx = floor (ttx);
ity = floor (tty);
/* expand source area to cover interpolation region
* (which runs from itx to itx + 1, same in y)
*/
if ((itx + 1) >= x1 && itx < x2 &&
(ity + 1) >= y1 && ity < y2 )
{
guchar *data;
gint row;
double dx, dy;
guchar *chan;
/* lock the pixel surround */
data = pixel_surround_lock (&surround, itx - x1, ity - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
}
else if (a_val >= 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT (a_val);
}
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
RINT (a_recip *
BILINEAR (chan[0] * chan[i],
chan[bytes] * chan[bytes+i],
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
break;
case GIMP_NEAREST_NEIGHBOR_INTERPOLATION:
itx = floor (ttx);
ity = floor (tty);
@ -497,14 +494,15 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
*d++ = src[0][b];
tile_release (tile[0], FALSE);
}
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
break;
}
/* increment the transformed coordinates */
tx += xinc;
@ -587,7 +585,7 @@ gimp_drawable_transform_tiles_flip (GimpDrawable *drawable,
gboolean
gimp_drawable_transform_affine (GimpDrawable *drawable,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction)
@ -616,7 +614,7 @@ gimp_drawable_transform_affine (GimpDrawable *drawable,
/* transform the buffer */
new_tiles = gimp_drawable_transform_tiles_affine (drawable,
float_tiles,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD,

View File

@ -278,9 +278,10 @@ gimp_channel_set_opacity (GimpChannel *channel,
}
void
gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height)
gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -312,7 +313,7 @@ gimp_channel_scale (GimpChannel *channel,
TRUE);
/* Sclae the channel */
scale_region (&srcPR, &destPR);
scale_region (&srcPR, &destPR, interpolation_type);
/* Push the channel on the undo stack */
undo_push_channel_mod (GIMP_DRAWABLE (channel)->gimage, channel);

View File

@ -105,7 +105,8 @@ void gimp_channel_set_color (GimpChannel *channel,
void gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height);
gint new_height,
GimpInterpolationType interpolation_type);
void gimp_channel_resize (GimpChannel *channel,
gint new_width,
gint new_height,

View File

@ -278,9 +278,10 @@ gimp_channel_set_opacity (GimpChannel *channel,
}
void
gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height)
gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -312,7 +313,7 @@ gimp_channel_scale (GimpChannel *channel,
TRUE);
/* Sclae the channel */
scale_region (&srcPR, &destPR);
scale_region (&srcPR, &destPR, interpolation_type);
/* Push the channel on the undo stack */
undo_push_channel_mod (GIMP_DRAWABLE (channel)->gimage, channel);

View File

@ -105,7 +105,8 @@ void gimp_channel_set_color (GimpChannel *channel,
void gimp_channel_scale (GimpChannel *channel,
gint new_width,
gint new_height);
gint new_height,
GimpInterpolationType interpolation_type);
void gimp_channel_resize (GimpChannel *channel,
gint new_width,
gint new_height,

View File

@ -29,11 +29,12 @@
void
gimp_core_config_init (Gimp *gimp)
{
g_return_if_fail (gimp != NULL);
g_return_if_fail (GIMP_IS_GIMP (gimp));
gimp->config = g_new0 (GimpCoreConfig, 1);
gimp->config->interpolation_type = GIMP_LINEAR_INTERPOLATION;
gimp->config->tool_plug_in_path = NULL;
gimp->config->plug_in_path = NULL;
gimp->config->module_path = NULL;

View File

@ -22,33 +22,35 @@
struct _GimpCoreConfig
{
gchar *plug_in_path;
gchar *tool_plug_in_path;
gchar *module_path;
GimpInterpolationType interpolation_type;
gchar *brush_path;
gchar *pattern_path;
gchar *palette_path;
gchar *gradient_path;
gchar *plug_in_path;
gchar *tool_plug_in_path;
gchar *module_path;
gchar *default_brush;
gchar *default_pattern;
gchar *default_palette;
gchar *default_gradient;
gchar *brush_path;
gchar *pattern_path;
gchar *palette_path;
gchar *gradient_path;
gchar *default_comment;
GimpImageBaseType default_type;
gint default_width;
gint default_height;
GimpUnit default_units;
gdouble default_xresolution;
gdouble default_yresolution;
GimpUnit default_resolution_units;
gchar *default_brush;
gchar *default_pattern;
gchar *default_palette;
gchar *default_gradient;
gint levels_of_undo;
gchar *pluginrc_path;
gchar *module_db_load_inhibit;
gboolean write_thumbnails;
gchar *default_comment;
GimpImageBaseType default_type;
gint default_width;
gint default_height;
GimpUnit default_units;
gdouble default_xresolution;
gdouble default_yresolution;
GimpUnit default_resolution_units;
gint levels_of_undo;
gchar *pluginrc_path;
gchar *module_db_load_inhibit;
gboolean write_thumbnails;
};

View File

@ -79,7 +79,7 @@ static gdouble gimp_drawable_transform_cubic (gdouble dx,
TileManager *
gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
TileManager *float_tiles,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction,
@ -123,9 +123,10 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
alpha = 0;
/* turn interpolation off for simple transformations (e.g. rot90) */
if (gimp_matrix3_is_simple (matrix) ||
base_config->interpolation_type == GIMP_NEAREST_NEIGHBOR_INTERPOLATION)
interpolation = FALSE;
if (gimp_matrix3_is_simple (matrix))
{
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
}
/* Get the background color */
gimp_image_get_background (gimage, drawable, bg_col);
@ -144,7 +145,7 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
bg_col[ALPHA_I_PIX] = TRANSPARENT_OPACITY;
alpha = ALPHA_I_PIX;
/* If the gimage is indexed color, ignore smoothing value */
interpolation = FALSE;
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
break;
default:
g_assert_not_reached ();
@ -230,21 +231,20 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
tile_manager_set_offsets (tiles, tx1, ty1);
/* initialise the pixel_surround accessor */
if (interpolation)
{
if (base_config->interpolation_type == GIMP_CUBIC_INTERPOLATION)
{
pixel_surround_init (&surround, float_tiles, 4, 4, bg_col);
}
else
{
pixel_surround_init (&surround, float_tiles, 2, 2, bg_col);
}
}
else
switch (interpolation_type)
{
case GIMP_CUBIC_INTERPOLATION:
pixel_surround_init (&surround, float_tiles, 4, 4, bg_col);
break;
case GIMP_LINEAR_INTERPOLATION:
pixel_surround_init (&surround, float_tiles, 2, 2, bg_col);
break;
case GIMP_NEAREST_NEIGHBOR_INTERPOLATION:
/* not actually useful, keeps the code cleaner */
pixel_surround_init (&surround, float_tiles, 1, 1, bg_col);
break;
}
width = tile_manager_width (tiles);
@ -292,195 +292,192 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
/* Set the destination pixels */
if (interpolation)
{
if (base_config->interpolation_type == GIMP_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:
* itx to itx + 3, ity to ity + 3
*/
itx = floor (ttx);
ity = floor (tty);
/* check if any part of our region overlaps the buffer */
if ((itx + 2) >= x1 && (itx - 1) < x2 &&
(ity + 2) >= y1 && (ity - 1) < y2 )
{
guchar *data;
gint row;
gdouble dx, dy;
guchar *start;
/* lock the pixel surround */
data = pixel_surround_lock (&surround,
itx - 1 - x1, ity - 1 - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = gimp_drawable_transform_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;
}
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
}
/* 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 =
RINT (a_recip *
gimp_drawable_transform_cubic
(dy,
CUBIC_SCALED_ROW (dx, start, bytes, i),
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
else /* linear */
{
itx = floor (ttx);
ity = floor (tty);
/* expand source area to cover interpolation region
* (which runs from itx to itx + 1, same in y)
*/
if ((itx + 1) >= x1 && itx < x2 &&
(ity + 1) >= y1 && ity < y2 )
{
guchar *data;
gint row;
double dx, dy;
guchar *chan;
/* lock the pixel surround */
data = pixel_surround_lock (&surround, itx - x1, ity - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
}
else if (a_val >= 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT (a_val);
}
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
RINT (a_recip *
BILINEAR (chan[0] * chan[i],
chan[bytes] * chan[bytes+i],
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
}
else /* no interpolation */
switch (interpolation_type)
{
case GIMP_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:
* itx to itx + 3, ity to ity + 3
*/
itx = floor (ttx);
ity = floor (tty);
/* check if any part of our region overlaps the buffer */
if ((itx + 2) >= x1 && (itx - 1) < x2 &&
(ity + 2) >= y1 && (ity - 1) < y2 )
{
guchar *data;
gint row;
gdouble dx, dy;
guchar *start;
/* lock the pixel surround */
data = pixel_surround_lock (&surround,
itx - 1 - x1, ity - 1 - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha of result */
start = &data[alpha];
a_val = gimp_drawable_transform_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;
}
else if (a_val > 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT(a_val);
}
/* 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 =
RINT (a_recip *
gimp_drawable_transform_cubic
(dy,
CUBIC_SCALED_ROW (dx, start, bytes, i),
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
break;
case GIMP_LINEAR_INTERPOLATION:
itx = floor (ttx);
ity = floor (tty);
/* expand source area to cover interpolation region
* (which runs from itx to itx + 1, same in y)
*/
if ((itx + 1) >= x1 && itx < x2 &&
(ity + 1) >= y1 && ity < y2 )
{
guchar *data;
gint row;
double dx, dy;
guchar *chan;
/* lock the pixel surround */
data = pixel_surround_lock (&surround, itx - x1, ity - y1);
row = pixel_surround_rowstride (&surround);
/* the fractional error */
dx = ttx - itx;
dy = tty - ity;
/* calculate alpha value of result pixel */
chan = &data[alpha];
a_val = BILINEAR (chan[0], chan[bytes], chan[row],
chan[row+bytes], dx, dy);
if (a_val <= 0.0)
{
a_recip = 0.0;
d[alpha] = 0.0;
}
else if (a_val >= 255.0)
{
a_recip = 1.0 / a_val;
d[alpha] = 255;
}
else
{
a_recip = 1.0 / a_val;
d[alpha] = RINT (a_val);
}
/* for colour channels c,
* result = bilinear (c * alpha) / bilinear (alpha)
*
* never entered for alpha == 0
*/
for (i = -alpha; i < 0; ++i)
{
chan = &data[alpha];
newval =
RINT (a_recip *
BILINEAR (chan[0] * chan[i],
chan[bytes] * chan[bytes+i],
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;
}
}
/* alpha already done */
d++;
pixel_surround_release (&surround);
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
break;
case GIMP_NEAREST_NEIGHBOR_INTERPOLATION:
itx = floor (ttx);
ity = floor (tty);
@ -497,14 +494,15 @@ gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
*d++ = src[0][b];
tile_release (tile[0], FALSE);
}
}
else /* not in source range */
{
/* increment the destination pointers */
for (b = 0; b < bytes; b++)
*d++ = bg_col[b];
}
}
break;
}
/* increment the transformed coordinates */
tx += xinc;
@ -587,7 +585,7 @@ gimp_drawable_transform_tiles_flip (GimpDrawable *drawable,
gboolean
gimp_drawable_transform_affine (GimpDrawable *drawable,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction)
@ -616,7 +614,7 @@ gimp_drawable_transform_affine (GimpDrawable *drawable,
/* transform the buffer */
new_tiles = gimp_drawable_transform_tiles_affine (drawable,
float_tiles,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD,

View File

@ -35,7 +35,7 @@ typedef enum
TileManager * gimp_drawable_transform_tiles_affine (GimpDrawable *drawable,
TileManager *float_tiles,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction,
@ -46,7 +46,7 @@ TileManager * gimp_drawable_transform_tiles_flip (GimpDrawable *drawable,
InternalOrientationType flip_type);
gboolean gimp_drawable_transform_affine (GimpDrawable *drawable,
gboolean interpolation,
GimpInterpolationType interpolation_type,
gboolean clip_result,
GimpMatrix3 matrix,
GimpTransformDirection direction);

View File

@ -36,11 +36,12 @@
void
gimp_image_scale (GimpImage *gimage,
gint new_width,
gint new_height,
GimpProgressFunc progress_func,
gpointer progress_data)
gimp_image_scale (GimpImage *gimage,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type,
GimpProgressFunc progress_func,
gpointer progress_data)
{
GimpChannel *channel;
GimpLayer *layer;
@ -93,7 +94,7 @@ gimp_image_scale (GimpImage *gimage,
{
channel = (GimpChannel *) list->data;
gimp_channel_scale (channel, new_width, new_height);
gimp_channel_scale (channel, new_width, new_height, interpolation_type);
if (progress_func)
{
@ -109,7 +110,8 @@ gimp_image_scale (GimpImage *gimage,
else
*/
gimp_channel_scale (gimage->selection_mask, new_width, new_height);
gimp_channel_scale (gimage->selection_mask, new_width, new_height,
interpolation_type);
gimp_image_mask_invalidate (gimage);
/* Scale all layers */
@ -119,7 +121,8 @@ gimp_image_scale (GimpImage *gimage,
{
layer = (GimpLayer *) list->data;
if (! gimp_layer_scale_by_factors (layer, img_scale_w, img_scale_h))
if (! gimp_layer_scale_by_factors (layer, img_scale_w, img_scale_h,
interpolation_type))
{
/* Since 0 < img_scale_w, img_scale_h, failure due to one or more
* vanishing scaled layer dimensions. Implicit delete implemented

View File

@ -20,15 +20,16 @@
#define __GIMP_IMAGE_SCALE_H__
void gimp_image_scale (GimpImage *gimage,
gint new_width,
gint new_height,
GimpProgressFunc progress_func,
gpointer progress_data);
void gimp_image_scale (GimpImage *gimage,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type,
GimpProgressFunc progress_func,
gpointer progress_data);
gboolean gimp_image_check_scaling (const GimpImage *gimage,
gint new_width,
gint new_height);
gboolean gimp_image_check_scaling (const GimpImage *gimage,
gint new_width,
gint new_height);
#endif /* __GIMP_IMAGE_SCALE_H__ */

View File

@ -880,11 +880,12 @@ gimp_layer_add_alpha (GimpLayer *layer)
}
static void
gimp_layer_scale_lowlevel (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
gimp_layer_scale_lowlevel (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interpolation_type)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -915,11 +916,14 @@ gimp_layer_scale_lowlevel (GimpLayer *layer,
* resampling because that doesn't necessarily make sense for INDEXED
* images.
*/
if ((GIMP_DRAWABLE (layer)->type == GIMP_INDEXED_IMAGE) ||
(GIMP_DRAWABLE (layer)->type == GIMP_INDEXEDA_IMAGE))
scale_region_no_resample (&srcPR, &destPR);
if (GIMP_IMAGE_TYPE_IS_INDEXED (GIMP_DRAWABLE (layer)->type))
{
scale_region (&srcPR, &destPR, GIMP_NEAREST_NEIGHBOR_INTERPOLATION);
}
else
scale_region (&srcPR, &destPR);
{
scale_region (&srcPR, &destPR, interpolation_type);
}
/* Push the layer on the undo stack */
undo_push_layer_mod (GIMP_DRAWABLE (layer)->gimage, layer);
@ -937,7 +941,9 @@ gimp_layer_scale_lowlevel (GimpLayer *layer,
{
GIMP_DRAWABLE (layer->mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
GIMP_DRAWABLE (layer->mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
gimp_channel_scale (GIMP_CHANNEL (layer->mask), new_width, new_height);
gimp_channel_scale (GIMP_CHANNEL (layer->mask), new_width, new_height,
interpolation_type);
}
/* Make sure we're not caching any old selection info */
@ -1012,9 +1018,10 @@ gimp_layer_check_scaling (const GimpLayer *layer,
* #FALSE if the scaled layer has at least one zero dimension
**/
gboolean
gimp_layer_scale_by_factors (GimpLayer *layer,
gdouble w_factor,
gdouble h_factor)
gimp_layer_scale_by_factors (GimpLayer *layer,
gdouble w_factor,
gdouble h_factor,
GimpInterpolationType interpolation_type)
{
gint new_width, new_height;
gint new_offset_x, new_offset_y;
@ -1034,7 +1041,8 @@ gimp_layer_scale_by_factors (GimpLayer *layer,
{
gimp_layer_scale_lowlevel (layer,
new_width, new_height,
new_offset_x, new_offset_y);
new_offset_x, new_offset_y,
interpolation_type);
return TRUE;
}
@ -1069,10 +1077,11 @@ gimp_layer_scale_by_factors (GimpLayer *layer,
* & painted to new layer tiles
**/
void
gimp_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
gboolean local_origin)
gimp_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type,
gboolean local_origin)
{
gint new_offset_x, new_offset_y;
@ -1103,7 +1112,8 @@ gimp_layer_scale (GimpLayer *layer,
gimp_layer_scale_lowlevel (layer,
new_width, new_height,
new_offset_x, new_offset_y);
new_offset_x, new_offset_y,
interpolation_type);
}
void

View File

@ -126,10 +126,12 @@ void gimp_layer_translate (GimpLayer *layer,
void gimp_layer_add_alpha (GimpLayer *layer);
gboolean gimp_layer_scale_by_factors (GimpLayer *layer,
gdouble w_factor,
gdouble h_factor);
gdouble h_factor,
GimpInterpolationType interpolation_type);
void gimp_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
GimpInterpolationType interpolation_type,
gboolean local_origin);
void gimp_layer_resize (GimpLayer *layer,
gint new_width,

View File

@ -614,7 +614,7 @@ prefs_save_callback (GtkWidget *widget,
update = g_list_append (update, "show-statusbar");
remove = g_list_append (remove, "dont-show-statusbar");
}
if (base_config->interpolation_type != old_interpolation_type)
if (gimp->config->interpolation_type != old_interpolation_type)
{
update = g_list_append (update, "interpolation-type");
}
@ -912,9 +912,9 @@ prefs_cancel_callback (GtkWidget *widget,
gtk_widget_destroy (dlg);
/* restore ordinary gimprc variables */
base_config->interpolation_type = old_interpolation_type;
base_config->num_processors = old_num_processors;
gimp->config->interpolation_type = old_interpolation_type;
gimp->config->default_type = old_default_type;
gimp->config->default_width = old_default_width;
gimp->config->default_height = old_default_height;
@ -1062,11 +1062,11 @@ prefs_toggle_callback (GtkWidget *widget,
}
/* radio buttons */
else if (data == &base_config->interpolation_type ||
data == &gimp->config->default_type ||
data == &gimp->config->write_thumbnails ||
data == &gimprc.trust_dirty_flag ||
data == &gimprc.help_browser ||
else if (data == &gimp->config->interpolation_type ||
data == &gimp->config->default_type ||
data == &gimp->config->write_thumbnails ||
data == &gimprc.trust_dirty_flag ||
data == &gimprc.help_browser ||
data == &gimprc.cursor_mode)
{
*val = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
@ -1550,9 +1550,9 @@ preferences_dialog_create (Gimp *gimp)
edit_tile_cache_size = base_config->tile_cache_size;
/* remember all old values */
old_interpolation_type = base_config->interpolation_type;
old_num_processors = base_config->num_processors;
old_interpolation_type = gimp->config->interpolation_type;
old_default_type = gimp->config->default_type;
old_default_width = gimp->config->default_width;
old_default_height = gimp->config->default_height;
@ -2532,14 +2532,14 @@ preferences_dialog_create (Gimp *gimp)
optionmenu =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (prefs_toggle_callback),
&base_config->interpolation_type,
GINT_TO_POINTER (base_config->interpolation_type),
&gimp->config->interpolation_type,
GINT_TO_POINTER (gimp->config->interpolation_type),
_("Nearest Neighbor (Fast)"),
_("Nearest Neighbor (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION), NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION), NULL,
_("Cubic (Slow)"),
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION), NULL,
NULL);

View File

@ -61,6 +61,9 @@ struct _ResizePrivate
GtkWidget *resolution_se;
GtkWidget *equal_res;
/* interpolation menu */
GtkWidget *interpolation_menu;
gint old_width, old_height;
gdouble old_res_x, old_res_y;
};
@ -144,17 +147,19 @@ resize_widget_new (GimpImage *gimage,
resize = (Resize *) private;
resize->type = type;
resize->target = target;
resize->width = width;
resize->height = height;
resize->resolution_x = resolution_x;
resize->resolution_y = resolution_y;
resize->unit = unit;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->offset_x = 0;
resize->offset_y = 0;
resize->gimage = gimage;
resize->type = type;
resize->target = target;
resize->width = width;
resize->height = height;
resize->resolution_x = resolution_x;
resize->resolution_y = resolution_y;
resize->unit = unit;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->offset_x = 0;
resize->offset_y = 0;
resize->interpolation = gimage->gimp->config->interpolation_type;
/* dialog box */
{
@ -649,6 +654,44 @@ resize_widget_new (GimpImage *gimage,
gtk_widget_show (vbox);
}
/* the interpolation menu */
if (type == ScaleWidget)
{
GtkWidget *hbox;
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Interpolation Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
private->interpolation_menu =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (gimp_menu_item_update),
&resize->interpolation,
GINT_TO_POINTER (resize->interpolation),
_("Nearest Neighbor (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION),
NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION),
NULL,
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION),
NULL,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), private->interpolation_menu,
FALSE, FALSE, 0);
gtk_widget_show (private->interpolation_menu);
}
gtk_widget_show (main_vbox);
/* finally, activate the first entry */
@ -804,6 +847,13 @@ reset_callback (GtkWidget *widget,
resolution_update (resize, private->old_res_x, private->old_res_y);
}
if (resize->type == ScaleWidget)
{
resize->interpolation = resize->gimage->gimp->config->interpolation_type;
gimp_option_menu_set_history (GTK_OPTION_MENU (private->interpolation_menu),
GINT_TO_POINTER (resize->interpolation));
}
}
static void

View File

@ -37,23 +37,27 @@ typedef struct _Resize Resize;
struct _Resize
{
GtkWidget *resize_shell;
GtkWidget *resize_shell;
ResizeType type;
ResizeTarget target;
GimpImage *gimage;
gint width;
gint height;
ResizeType type;
ResizeTarget target;
gdouble resolution_x;
gdouble resolution_y;
GimpUnit unit;
gint width;
gint height;
gdouble ratio_x;
gdouble ratio_y;
gdouble resolution_x;
gdouble resolution_y;
GimpUnit unit;
gint offset_x;
gint offset_y;
gdouble ratio_x;
gdouble ratio_y;
gint offset_x;
gint offset_y;
GimpInterpolationType interpolation;
};

View File

@ -338,12 +338,12 @@ gimprc_init (Gimp *gimp)
{ "swap-path", TT_PATH, NULL, NULL },
{ "tile-cache-size", TT_MEMSIZE, NULL, NULL },
{ "stingy-memory-use", TT_BOOLEAN, NULL, NULL },
{ "interpolation-type", TT_INTERP, NULL, NULL },
{ "num-processors", TT_INT, NULL, NULL }
};
static ParseFunc core_funcs[] =
{
{ "interpolation-type", TT_INTERP, NULL, NULL },
{ "plug-in-path", TT_PATH, NULL, NULL },
{ "module-path", TT_PATH, NULL, NULL },
{ "brush-path", TT_PATH, NULL, NULL },
@ -373,32 +373,32 @@ gimprc_init (Gimp *gimp)
base_funcs[1].val1p = &base_config->swap_path;
base_funcs[2].val1p = &base_config->tile_cache_size;
base_funcs[3].val1p = &base_config->stingy_memory_use;
base_funcs[4].val1p = &base_config->interpolation_type;
base_funcs[5].val1p = &base_config->num_processors;
base_funcs[4].val1p = &base_config->num_processors;
core_funcs[0].val1p = &gimp->config->plug_in_path;
core_funcs[1].val1p = &gimp->config->module_path;
core_funcs[2].val1p = &gimp->config->brush_path;
core_funcs[3].val1p = &gimp->config->pattern_path;
core_funcs[4].val1p = &gimp->config->palette_path;
core_funcs[5].val1p = &gimp->config->gradient_path;
core_funcs[6].val1p = &gimp->config->default_brush;
core_funcs[7].val1p = &gimp->config->default_pattern;
core_funcs[8].val1p = &gimp->config->default_palette;
core_funcs[9].val1p = &gimp->config->default_gradient;
core_funcs[10].val1p = &gimp->config->default_comment;
core_funcs[11].val1p = &gimp->config->default_type;
core_funcs[12].val1p = &gimp->config->default_width;
core_funcs[12].val2p = &gimp->config->default_height;
core_funcs[13].val1p = &gimp->config->default_units;
core_funcs[14].val1p = &gimp->config->default_xresolution;
core_funcs[0].val1p = &gimp->config->interpolation_type;
core_funcs[1].val1p = &gimp->config->plug_in_path;
core_funcs[2].val1p = &gimp->config->module_path;
core_funcs[3].val1p = &gimp->config->brush_path;
core_funcs[4].val1p = &gimp->config->pattern_path;
core_funcs[5].val1p = &gimp->config->palette_path;
core_funcs[6].val1p = &gimp->config->gradient_path;
core_funcs[7].val1p = &gimp->config->default_brush;
core_funcs[8].val1p = &gimp->config->default_pattern;
core_funcs[9].val1p = &gimp->config->default_palette;
core_funcs[10].val1p = &gimp->config->default_gradient;
core_funcs[11].val1p = &gimp->config->default_comment;
core_funcs[12].val1p = &gimp->config->default_type;
core_funcs[13].val1p = &gimp->config->default_width;
core_funcs[13].val2p = &gimp->config->default_height;
core_funcs[14].val1p = &gimp->config->default_units;
core_funcs[15].val1p = &gimp->config->default_xresolution;
core_funcs[16].val1p = &gimp->config->default_resolution_units;
core_funcs[17].val1p = &gimp->config->levels_of_undo;
core_funcs[18].val1p = &gimp->config->pluginrc_path;
core_funcs[19].val1p = &gimp->config->module_db_load_inhibit;
core_funcs[20].val1p = &gimp->config->write_thumbnails;
core_funcs[21].val1p = &gimp->config->tool_plug_in_path;
core_funcs[16].val1p = &gimp->config->default_xresolution;
core_funcs[17].val1p = &gimp->config->default_resolution_units;
core_funcs[18].val1p = &gimp->config->levels_of_undo;
core_funcs[19].val1p = &gimp->config->pluginrc_path;
core_funcs[20].val1p = &gimp->config->module_db_load_inhibit;
core_funcs[21].val1p = &gimp->config->write_thumbnails;
core_funcs[22].val1p = &gimp->config->tool_plug_in_path;
parse_func_hash = g_hash_table_new (g_str_hash, g_str_equal);

View File

@ -349,6 +349,7 @@ image_scale_implement (ImageResize *image_scale)
gimp_image_scale (gimage,
image_scale->resize->width,
image_scale->resize->height,
image_scale->resize->interpolation,
progress_update_and_flush, progress);
progress_end (progress);

View File

@ -1021,7 +1021,9 @@ scale_layer_query_ok_callback (GtkWidget *widget,
floating_sel_relax (layer, TRUE);
gimp_layer_scale (layer,
options->resize->width, options->resize->height,
options->resize->width,
options->resize->height,
options->resize->interpolation,
TRUE);
if (gimp_layer_is_floating_sel (layer))

View File

@ -614,7 +614,7 @@ prefs_save_callback (GtkWidget *widget,
update = g_list_append (update, "show-statusbar");
remove = g_list_append (remove, "dont-show-statusbar");
}
if (base_config->interpolation_type != old_interpolation_type)
if (gimp->config->interpolation_type != old_interpolation_type)
{
update = g_list_append (update, "interpolation-type");
}
@ -912,9 +912,9 @@ prefs_cancel_callback (GtkWidget *widget,
gtk_widget_destroy (dlg);
/* restore ordinary gimprc variables */
base_config->interpolation_type = old_interpolation_type;
base_config->num_processors = old_num_processors;
gimp->config->interpolation_type = old_interpolation_type;
gimp->config->default_type = old_default_type;
gimp->config->default_width = old_default_width;
gimp->config->default_height = old_default_height;
@ -1062,11 +1062,11 @@ prefs_toggle_callback (GtkWidget *widget,
}
/* radio buttons */
else if (data == &base_config->interpolation_type ||
data == &gimp->config->default_type ||
data == &gimp->config->write_thumbnails ||
data == &gimprc.trust_dirty_flag ||
data == &gimprc.help_browser ||
else if (data == &gimp->config->interpolation_type ||
data == &gimp->config->default_type ||
data == &gimp->config->write_thumbnails ||
data == &gimprc.trust_dirty_flag ||
data == &gimprc.help_browser ||
data == &gimprc.cursor_mode)
{
*val = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
@ -1550,9 +1550,9 @@ preferences_dialog_create (Gimp *gimp)
edit_tile_cache_size = base_config->tile_cache_size;
/* remember all old values */
old_interpolation_type = base_config->interpolation_type;
old_num_processors = base_config->num_processors;
old_interpolation_type = gimp->config->interpolation_type;
old_default_type = gimp->config->default_type;
old_default_width = gimp->config->default_width;
old_default_height = gimp->config->default_height;
@ -2532,14 +2532,14 @@ preferences_dialog_create (Gimp *gimp)
optionmenu =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (prefs_toggle_callback),
&base_config->interpolation_type,
GINT_TO_POINTER (base_config->interpolation_type),
&gimp->config->interpolation_type,
GINT_TO_POINTER (gimp->config->interpolation_type),
_("Nearest Neighbor (Fast)"),
_("Nearest Neighbor (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION), NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION), NULL,
_("Cubic (Slow)"),
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION), NULL,
NULL);

View File

@ -61,6 +61,9 @@ struct _ResizePrivate
GtkWidget *resolution_se;
GtkWidget *equal_res;
/* interpolation menu */
GtkWidget *interpolation_menu;
gint old_width, old_height;
gdouble old_res_x, old_res_y;
};
@ -144,17 +147,19 @@ resize_widget_new (GimpImage *gimage,
resize = (Resize *) private;
resize->type = type;
resize->target = target;
resize->width = width;
resize->height = height;
resize->resolution_x = resolution_x;
resize->resolution_y = resolution_y;
resize->unit = unit;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->offset_x = 0;
resize->offset_y = 0;
resize->gimage = gimage;
resize->type = type;
resize->target = target;
resize->width = width;
resize->height = height;
resize->resolution_x = resolution_x;
resize->resolution_y = resolution_y;
resize->unit = unit;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->offset_x = 0;
resize->offset_y = 0;
resize->interpolation = gimage->gimp->config->interpolation_type;
/* dialog box */
{
@ -649,6 +654,44 @@ resize_widget_new (GimpImage *gimage,
gtk_widget_show (vbox);
}
/* the interpolation menu */
if (type == ScaleWidget)
{
GtkWidget *hbox;
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
label = gtk_label_new (_("Interpolation Type:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
private->interpolation_menu =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (gimp_menu_item_update),
&resize->interpolation,
GINT_TO_POINTER (resize->interpolation),
_("Nearest Neighbor (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION),
NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION),
NULL,
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION),
NULL,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), private->interpolation_menu,
FALSE, FALSE, 0);
gtk_widget_show (private->interpolation_menu);
}
gtk_widget_show (main_vbox);
/* finally, activate the first entry */
@ -804,6 +847,13 @@ reset_callback (GtkWidget *widget,
resolution_update (resize, private->old_res_x, private->old_res_y);
}
if (resize->type == ScaleWidget)
{
resize->interpolation = resize->gimage->gimp->config->interpolation_type;
gimp_option_menu_set_history (GTK_OPTION_MENU (private->interpolation_menu),
GINT_TO_POINTER (resize->interpolation));
}
}
static void

View File

@ -37,23 +37,27 @@ typedef struct _Resize Resize;
struct _Resize
{
GtkWidget *resize_shell;
GtkWidget *resize_shell;
ResizeType type;
ResizeTarget target;
GimpImage *gimage;
gint width;
gint height;
ResizeType type;
ResizeTarget target;
gdouble resolution_x;
gdouble resolution_y;
GimpUnit unit;
gint width;
gint height;
gdouble ratio_x;
gdouble ratio_y;
gdouble resolution_x;
gdouble resolution_y;
GimpUnit unit;
gint offset_x;
gint offset_y;
gdouble ratio_x;
gdouble ratio_y;
gint offset_x;
gint offset_y;
GimpInterpolationType interpolation;
};

View File

@ -2895,12 +2895,13 @@ shrink_line (gdouble *dest,
}
static void
get_scaled_row (void **src,
gint y,
gint new_width,
PixelRegion *srcPR,
gdouble *row,
guchar *src_tmp)
get_scaled_row (void **src,
gint y,
gint new_width,
PixelRegion *srcPR,
gdouble *row,
guchar *src_tmp,
GimpInterpolationType interpolation_type)
{
/* get the necesary lines from the source image, scale them,
and put them into src[] */
@ -2913,10 +2914,10 @@ get_scaled_row (void **src,
row, src_tmp, 1);
if (new_width > srcPR->w)
expand_line(src[3], row, srcPR->bytes,
srcPR->w, new_width, base_config->interpolation_type);
srcPR->w, new_width, interpolation_type);
else if (srcPR->w > new_width)
shrink_line(src[3], row, srcPR->bytes,
srcPR->w, new_width, base_config->interpolation_type);
srcPR->w, new_width, interpolation_type);
else /* no scailing needed */
memcpy(src[3], row, sizeof (double) * new_width * srcPR->bytes);
}
@ -2925,8 +2926,9 @@ get_scaled_row (void **src,
}
void
scale_region (PixelRegion *srcPR,
PixelRegion *destPR)
scale_region (PixelRegion *srcPR,
PixelRegion *destPR,
GimpInterpolationType interpolation_type)
{
gdouble *src[4];
guchar *src_tmp;
@ -2940,11 +2942,11 @@ scale_region (PixelRegion *srcPR,
gint old_y = -4, new_y;
gint x, y;
if (base_config->interpolation_type == GIMP_NEAREST_NEIGHBOR_INTERPOLATION)
{
scale_region_no_resample (srcPR, destPR);
return;
}
if (interpolation_type == GIMP_NEAREST_NEIGHBOR_INTERPOLATION)
{
scale_region_no_resample (srcPR, destPR);
return;
}
orig_width = srcPR->w;
orig_height = srcPR->h;
@ -2985,7 +2987,8 @@ scale_region (PixelRegion *srcPR,
const double inv_ratio = 1.0 / y_rat;
if (y == 0) /* load the first row if this it the first time through */
get_scaled_row((void **)&src[0], 0, width, srcPR, row,
src_tmp);
src_tmp,
interpolation_type);
new_y = (int)((y) * y_rat);
frac = 1.0 - (y*y_rat - new_y);
for (x = 0; x < width*bytes; x++)
@ -2995,14 +2998,16 @@ scale_region (PixelRegion *srcPR,
max--;
get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
src_tmp);
src_tmp,
interpolation_type);
while (max > 0)
{
for (x = 0; x < width*bytes; x++)
accum[x] += src[3][x];
get_scaled_row((void **)&src[0], ++new_y, width, srcPR, row,
src_tmp);
src_tmp,
interpolation_type);
max--;
}
frac = (y + 1)*y_rat - ((int)((y + 1)*y_rat));
@ -3020,10 +3025,11 @@ scale_region (PixelRegion *srcPR,
{ /* get the necesary lines from the source image, scale them,
and put them into src[] */
get_scaled_row((void **)&src[0], old_y + 2, width, srcPR, row,
src_tmp);
src_tmp,
interpolation_type);
old_y++;
}
switch(base_config->interpolation_type)
switch(interpolation_type)
{
case GIMP_CUBIC_INTERPOLATION:
{
@ -3055,7 +3061,8 @@ scale_region (PixelRegion *srcPR,
else /* height == orig_height */
{
get_scaled_row((void **)&src[0], y, width, srcPR, row,
src_tmp);
src_tmp,
interpolation_type);
memcpy(accum, src[3], sizeof(double) * width * bytes);
}
if (pixel_region_has_alpha(srcPR))

View File

@ -314,7 +314,8 @@ void gaussian_blur_region (PixelRegion *, double, double);
void border_region (PixelRegion *, gint16, gint16);
void scale_region (PixelRegion *, PixelRegion *);
void scale_region (PixelRegion *, PixelRegion *,
GimpInterpolationType);
void scale_region_no_resample (PixelRegion *, PixelRegion *);

View File

@ -35,6 +35,7 @@
#include "core/gimp.h"
#include "core/gimpchannel.h"
#include "core/gimpcontainer.h"
#include "core/gimpcoreconfig.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage-crop.h"
#include "core/gimpimage-duplicate.h"
@ -534,7 +535,9 @@ image_scale_invoker (Gimp *gimp,
if (success)
{
gimp_image_scale (gimage, new_width, new_height, NULL, NULL);
gimp_image_scale (gimage, new_width, new_height,
gimp->config->interpolation_type,
NULL, NULL);
}
return procedural_db_return_args (&image_scale_proc, success);

View File

@ -31,6 +31,8 @@
#include "base/base-enums.h"
#include "core/core-enums.h"
#include "core/core-types.h"
#include "core/gimp.h"
#include "core/gimpcoreconfig.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "core/gimplayermask.h"
@ -401,7 +403,7 @@ layer_scale_invoker (Gimp *gimp,
if (floating_layer)
floating_sel_relax (floating_layer, TRUE);
gimp_layer_scale (layer, new_width, new_height, local_origin);
gimp_layer_scale (layer, new_width, new_height, gimp->config->interpolation_type, local_origin);
if (floating_layer)
floating_sel_rigor (floating_layer, TRUE);

View File

@ -29,6 +29,8 @@
#include "procedural_db.h"
#include "core/core-types.h"
#include "core/gimp.h"
#include "core/gimpcoreconfig.h"
#include "core/gimpdrawable-transform-utils.h"
#include "core/gimpdrawable-transform.h"
#include "core/gimpdrawable.h"
@ -137,6 +139,7 @@ perspective_invoker (Gimp *gimp,
gint x1, y1, x2, y2;
gdouble trans_info[8];
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
drawable = gimp_drawable_get_by_ID (gimp, args[0].value.pdb_int);
if (drawable == NULL)
@ -176,9 +179,14 @@ perspective_invoker (Gimp *gimp,
trans_info[Y3],
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -283,6 +291,7 @@ rotate_invoker (Gimp *gimp,
gdouble angle;
gint x1, y1, x2, y2;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
drawable = gimp_drawable_get_by_ID (gimp, args[0].value.pdb_int);
if (drawable == NULL)
@ -301,9 +310,14 @@ rotate_invoker (Gimp *gimp,
angle,
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -372,6 +386,7 @@ scale_invoker (Gimp *gimp,
gint x1, y1, x2, y2;
gdouble trans_info[4];
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
drawable = gimp_drawable_get_by_ID (gimp, args[0].value.pdb_int);
if (drawable == NULL)
@ -402,9 +417,14 @@ scale_invoker (Gimp *gimp,
trans_info[Y1],
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -494,6 +514,7 @@ shear_invoker (Gimp *gimp,
gdouble magnitude;
gint x1, y1, x2, y2;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
drawable = gimp_drawable_get_by_ID (gimp, args[0].value.pdb_int);
if (drawable == NULL)
@ -521,9 +542,14 @@ shear_invoker (Gimp *gimp,
magnitude,
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -602,6 +628,7 @@ transform_2d_invoker (Gimp *gimp,
gdouble dest_x;
gdouble dest_y;
GimpMatrix3 matrix;
GimpInterpolationType interpolation_type;
drawable = gimp_drawable_get_by_ID (gimp, args[0].value.pdb_int);
if (drawable == NULL)
@ -632,9 +659,14 @@ transform_2d_invoker (Gimp *gimp,
gimp_matrix3_rotate (matrix, angle);
gimp_matrix3_translate (matrix, dest_x, dest_y);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);

View File

@ -25,6 +25,8 @@
#include "tools-types.h"
#include "core/gimp.h"
#include "core/gimpcoreconfig.h"
#include "core/gimptoolinfo.h"
#include "gimprotatetool.h"
@ -81,14 +83,14 @@ transform_options_init (TransformOptions *options,
/* the main vbox */
vbox = options->tool_options.main_vbox;
options->smoothing = options->smoothing_d = TRUE;
options->show_path = options->show_path_d = TRUE;
options->clip = options->clip_d = FALSE;
options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD;
options->grid_size = options->grid_size_d = 32;
options->show_grid = options->show_grid_d = TRUE;
options->constrain_1 = options->constrain_1_d = FALSE;
options->constrain_2 = options->constrain_2_d = FALSE;
options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD;
options->interpolation = tool_info->gimp->config->interpolation_type;
options->show_path = options->show_path_d = TRUE;
options->clip = options->clip_d = FALSE;
options->grid_size = options->grid_size_d = 32;
options->show_grid = options->show_grid_d = TRUE;
options->constrain_1 = options->constrain_1_d = FALSE;
options->constrain_2 = options->constrain_2_d = FALSE;
frame = gimp_radio_group_new2 (TRUE, _("Transform Direction"),
G_CALLBACK (gimp_radio_button_update),
@ -108,14 +110,37 @@ transform_options_init (TransformOptions *options,
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* the smoothing toggle button */
options->smoothing_w = gtk_check_button_new_with_label (_("Smoothing"));
gtk_box_pack_start (GTK_BOX (vbox), options->smoothing_w, FALSE, FALSE, 0);
gtk_widget_show (options->smoothing_w);
/* the interpolation menu */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
g_signal_connect (G_OBJECT (options->smoothing_w), "toggled",
G_CALLBACK (gimp_toggle_button_update),
&options->smoothing);
label = gtk_label_new (_("Interpolation:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
options->interpolation_w =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (gimp_menu_item_update),
&options->interpolation,
GINT_TO_POINTER (options->interpolation),
_("None (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION),
NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION),
NULL,
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION),
NULL,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), options->interpolation_w, FALSE, FALSE, 0);
gtk_widget_show (options->interpolation_w);
/* the clip resulting image toggle button */
options->clip_w = gtk_check_button_new_with_label (_("Clip Result"));
@ -255,8 +280,11 @@ transform_options_reset (GimpToolOptions *tool_options)
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->direction_w[0]),
GINT_TO_POINTER (options->direction_d));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w),
options->smoothing_d);
options->interpolation =
tool_options->tool_info->gimp->config->interpolation_type;
gimp_option_menu_set_history (GTK_OPTION_MENU (options->interpolation_w),
GINT_TO_POINTER (options->interpolation));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w),
options->clip_d);

View File

@ -33,9 +33,9 @@ struct _TransformOptions
GimpTransformDirection direction_d;
GtkWidget *direction_w[2]; /* 2 radio buttons */
gboolean smoothing;
gboolean smoothing_d;
GtkWidget *smoothing_w;
GimpInterpolationType interpolation;
/* GimpInterpolationType interpolation_d; (from gimprc) */
GtkWidget *interpolation_w;
gboolean clip;
gboolean clip_d;

View File

@ -823,7 +823,7 @@ gimp_transform_tool_transform_tiles (GimpTransformTool *transform_tool,
ret = gimp_drawable_transform_tiles_affine (gimp_image_active_drawable (tool->gdisp->gimage),
transform_tool->original,
options->smoothing,
options->interpolation,
options->clip,
transform_tool->transform,
options->direction,

View File

@ -25,6 +25,8 @@
#include "tools-types.h"
#include "core/gimp.h"
#include "core/gimpcoreconfig.h"
#include "core/gimptoolinfo.h"
#include "gimprotatetool.h"
@ -81,14 +83,14 @@ transform_options_init (TransformOptions *options,
/* the main vbox */
vbox = options->tool_options.main_vbox;
options->smoothing = options->smoothing_d = TRUE;
options->show_path = options->show_path_d = TRUE;
options->clip = options->clip_d = FALSE;
options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD;
options->grid_size = options->grid_size_d = 32;
options->show_grid = options->show_grid_d = TRUE;
options->constrain_1 = options->constrain_1_d = FALSE;
options->constrain_2 = options->constrain_2_d = FALSE;
options->direction = options->direction_d = GIMP_TRANSFORM_FORWARD;
options->interpolation = tool_info->gimp->config->interpolation_type;
options->show_path = options->show_path_d = TRUE;
options->clip = options->clip_d = FALSE;
options->grid_size = options->grid_size_d = 32;
options->show_grid = options->show_grid_d = TRUE;
options->constrain_1 = options->constrain_1_d = FALSE;
options->constrain_2 = options->constrain_2_d = FALSE;
frame = gimp_radio_group_new2 (TRUE, _("Transform Direction"),
G_CALLBACK (gimp_radio_button_update),
@ -108,14 +110,37 @@ transform_options_init (TransformOptions *options,
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
/* the smoothing toggle button */
options->smoothing_w = gtk_check_button_new_with_label (_("Smoothing"));
gtk_box_pack_start (GTK_BOX (vbox), options->smoothing_w, FALSE, FALSE, 0);
gtk_widget_show (options->smoothing_w);
/* the interpolation menu */
hbox = gtk_hbox_new (FALSE, 4);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
g_signal_connect (G_OBJECT (options->smoothing_w), "toggled",
G_CALLBACK (gimp_toggle_button_update),
&options->smoothing);
label = gtk_label_new (_("Interpolation:"));
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
options->interpolation_w =
gimp_option_menu_new2 (FALSE,
G_CALLBACK (gimp_menu_item_update),
&options->interpolation,
GINT_TO_POINTER (options->interpolation),
_("None (Fastest)"),
GINT_TO_POINTER (GIMP_NEAREST_NEIGHBOR_INTERPOLATION),
NULL,
_("Linear"),
GINT_TO_POINTER (GIMP_LINEAR_INTERPOLATION),
NULL,
_("Cubic (Slowest & Best)"),
GINT_TO_POINTER (GIMP_CUBIC_INTERPOLATION),
NULL,
NULL);
gtk_box_pack_start (GTK_BOX (hbox), options->interpolation_w, FALSE, FALSE, 0);
gtk_widget_show (options->interpolation_w);
/* the clip resulting image toggle button */
options->clip_w = gtk_check_button_new_with_label (_("Clip Result"));
@ -255,8 +280,11 @@ transform_options_reset (GimpToolOptions *tool_options)
gimp_radio_group_set_active (GTK_RADIO_BUTTON (options->direction_w[0]),
GINT_TO_POINTER (options->direction_d));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->smoothing_w),
options->smoothing_d);
options->interpolation =
tool_options->tool_info->gimp->config->interpolation_type;
gimp_option_menu_set_history (GTK_OPTION_MENU (options->interpolation_w),
GINT_TO_POINTER (options->interpolation));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->clip_w),
options->clip_d);

View File

@ -33,9 +33,9 @@ struct _TransformOptions
GimpTransformDirection direction_d;
GtkWidget *direction_w[2]; /* 2 radio buttons */
gboolean smoothing;
gboolean smoothing_d;
GtkWidget *smoothing_w;
GimpInterpolationType interpolation;
/* GimpInterpolationType interpolation_d; (from gimprc) */
GtkWidget *interpolation_w;
gboolean clip;
gboolean clip_d;

View File

@ -323,7 +323,9 @@ HELP
headers => [ qw("core/gimpimage-scale.h") ],
code => <<'CODE'
{
gimp_image_scale (gimage, new_width, new_height, NULL, NULL);
gimp_image_scale (gimage, new_width, new_height,
gimp->config->interpolation_type,
NULL, NULL);
}
CODE
);
@ -1498,8 +1500,9 @@ CODE
@headers = qw(<string.h> "core/gimp.h" "core/gimpcontainer.h"
"core/gimplist.h" "core/gimpunit.h" "base/temp-buf.h"
"libgimpmath/gimpmath.h" "libgimpbase/gimpbase.h"
"core/gimpcoreconfig.h" "core/gimplist.h" "core/gimpunit.h"
"base/temp-buf.h" "libgimpmath/gimpmath.h"
"libgimpbase/gimpbase.h"
"libgimp/gimpintl.h");
$extra{app}->{code} = <<'CODE';

View File

@ -97,8 +97,13 @@ HELP
$args .= $_->{name};
}
&layer_change_invoke("LAYER_\U$op\E",
"gimp_layer_$op (layer, new_width, new_height, $args);");
if ($op eq 'scale') {
&layer_change_invoke("LAYER_\U$op\E",
"gimp_layer_$op (layer, new_width, new_height, gimp->config->interpolation_type, $args);");
} else {
&layer_change_invoke("LAYER_\U$op\E",
"gimp_layer_$op (layer, new_width, new_height, $args);");
}
}
sub layer_get_prop_proc {
@ -550,7 +555,8 @@ HELP
$date = '1998';
CODE
@headers = qw("core/gimplist.h" "pdb_glue.h");
@headers = qw("core/gimplist.h" "core/gimp.h" "core/gimpcoreconfig.h"
"pdb_glue.h");
unshift @procs, qw(layer_new layer_copy layer_create_mask layer_scale
layer_resize layer_delete layer_translate layer_add_alpha

View File

@ -125,7 +125,8 @@ HELP
%invoke = (
vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[8]',
'GimpMatrix3 matrix' ],
'GimpMatrix3 matrix',
'GimpInterpolationType interpolation_type' ],
code => <<'CODE'
{
gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
@ -142,9 +143,14 @@ HELP
trans_info[Y3],
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Perspective the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -182,7 +188,8 @@ HELP
@outargs = ( &drawable_out_arg('rotated') );
%invoke = (
vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix' ],
vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix',
'GimpInterpolationType interpolation_type' ],
code => <<'CODE'
{
gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
@ -192,9 +199,14 @@ HELP
angle,
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Rotate the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -241,7 +253,8 @@ HELP
%invoke = (
vars => [ 'gint x1, y1, x2, y2', 'gdouble trans_info[4]',
'GimpMatrix3 matrix' ],
'GimpMatrix3 matrix',
'GimpInterpolationType interpolation_type' ],
code => <<'CODE'
{
if (trans_info[X0] < trans_info[X1] &&
@ -257,9 +270,14 @@ HELP
trans_info[Y1],
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Scale the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -307,7 +325,8 @@ HELP
@outargs = ( &drawable_out_arg('sheared') );
%invoke = (
vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix' ],
vars => [ 'gint x1, y1, x2, y2', 'GimpMatrix3 matrix',
'GimpInterpolationType interpolation_type' ],
code => <<'CODE'
{
gimp_drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
@ -322,9 +341,14 @@ HELP
magnitude,
matrix);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Shear the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -377,7 +401,8 @@ HELP
@outargs = ( &drawable_out_arg('transformed') );
%invoke = (
vars => [ 'GimpMatrix3 matrix' ],
vars => [ 'GimpMatrix3 matrix',
'GimpInterpolationType interpolation_type' ],
code => <<'CODE'
{
/* Assemble the transformation matrix */
@ -387,9 +412,14 @@ HELP
gimp_matrix3_rotate (matrix, angle);
gimp_matrix3_translate (matrix, dest_x, dest_y);
if (interpolation)
interpolation_type = gimp->config->interpolation_type;
else
interpolation_type = GIMP_NEAREST_NEIGHBOR_INTERPOLATION;
/* Transform the selection */
success = gimp_drawable_transform_affine (drawable,
interpolation,
interpolation_type,
FALSE,
matrix,
GIMP_TRANSFORM_FORWARD);
@ -398,7 +428,8 @@ CODE
);
}
@headers = qw("libgimpmath/gimpmath.h" "core/gimpdrawable-transform.h"
@headers = qw("libgimpmath/gimpmath.h" "core/gimp.h"
"core/gimpcoreconfig.h" "core/gimpdrawable-transform.h"
"core/gimpdrawable-transform-utils.h" "core/gimpdrawable.h");
@procs = qw(flip perspective rotate scale shear transform_2d);