plug-ins/common/illusion.c plug-ins/common/polar.c applied patches from

2007-08-30  Karine Delvare  <edhel@gimp.org>

	* plug-ins/common/illusion.c
	* plug-ins/common/polar.c
	* plug-ins/common/whirlpinch.c: applied patches from Aurimas Juška
	that fixes use of the GimpZoomPreview widget in those plug-ins (see
	bug #356716), and makes illusion handle selections properly.


svn path=/trunk/; revision=23416
This commit is contained in:
Karine Delvare 2007-08-30 16:44:10 +00:00 committed by Karine Delvare
parent 68d4d31ff0
commit 3cb33d8721
4 changed files with 131 additions and 233 deletions

View File

@ -1,3 +1,11 @@
2007-08-30 Karine Delvare <edhel@gimp.org>
* plug-ins/common/illusion.c
* plug-ins/common/polar.c
* plug-ins/common/whirlpinch.c: applied patches from Aurimas Juška
that fixes use of the GimpZoomPreview widget in those plug-ins (see
bug #356716), and makes illusion handle selections properly.
2007-08-30 Raphaël Quinet <raphael@gimp.org>
* authors.xml: updated some entries, added contributors: Nicola

View File

@ -275,100 +275,61 @@ illusion (GimpDrawable *drawable)
static void
illusion_preview (GimpPreview *preview,
GimpDrawable *drawable)
{
guchar **pixels;
guchar *destpixels;
guchar *preview_cache;
gint x, y;
gint sx, sy;
gint preview_width, preview_height;
guchar *src;
guchar *dest;
guchar *src_pixel;
guchar *dest_pixel;
gint bpp;
IllusionParam_t param;
gint width, height;
gint x1, y1, x2, y2;
gint width;
gint height;
gint bpp;
gint center_x;
gint center_y;
gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2);
width = x2 - x1;
height = y2 - y1;
gint x, y, b;
gint xx = 0;
gint yy = 0;
gdouble scale, radius, cx, cy, angle, offset, zoom;
param.pft = gimp_pixel_fetcher_new (drawable, FALSE);
gimp_pixel_fetcher_set_edge_mode (param.pft, GIMP_PIXEL_FETCHER_EDGE_SMEAR);
preview_cache = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&width, &height, &bpp);
param.has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
param.center_x = (x1 + x2) / 2.0;
param.center_y = (y1 + y2) / 2.0;
param.scale = sqrt (width * width + height * height) / 2;
param.offset = (gint) (param.scale / 2);
zoom = gimp_zoom_preview_get_factor (GIMP_ZOOM_PREVIEW (preview));
src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&preview_width, &preview_height, &bpp);
dest = g_malloc (preview_width * preview_height * bpp);
gimp_preview_transform (preview,
drawable->width / 2.0, drawable->height / 2.0,
&center_x, &center_y);
src_pixel = src;
dest_pixel = dest;
pixels = g_new (guchar *, height);
destpixels = g_new (guchar, height * width * bpp);
for (y = 0; y < height; y++)
for (y = 0; y < preview_height; y++)
{
pixels[y] = g_new (guchar, width * bpp);
memcpy (pixels[y],
preview_cache + width * bpp * y,
width * bpp);
}
scale = sqrt (width * width * zoom * zoom + height * height * zoom * zoom) / 2;
offset = (gint) (scale / 2);
for (y = 0; y < height; y++)
{
cy = ((gdouble)y - center_y) / scale;
for (x = 0; x < width; x++)
for (x = 0; x < preview_width; x++)
{
cx = ((gdouble)x - center_x) / scale;
angle = floor (atan2 (cy, cx) * parameters.division / G_PI_2)
* G_PI_2 / parameters.division + (G_PI / parameters.division);
radius = sqrt ((gdouble) (cx * cx + cy * cy));
gimp_preview_untransform (preview, x, y, &sx, &sy);
if (parameters.type1)
{
xx = x - offset * cos (angle);
yy = y - offset * sin (angle);
}
else /* Type 2 */
{
xx = x - offset * sin (angle);
yy = y - offset * cos (angle);
}
illusion_func (sx, sy,
src_pixel, dest_pixel,
bpp,
(gpointer) &param);
xx = CLAMP (xx, 0, width - 1);
yy = CLAMP (yy, 0, height - 1);
if (bpp == 2 || bpp == 4)
{
gdouble alpha1 = pixels[y][x * bpp + bpp - 1];
gdouble alpha2 = pixels[yy][xx * bpp + bpp - 1];
gdouble alpha = (1 - radius) * alpha1 + radius * alpha2;
for (b = 0; alpha > 0 && b < bpp - 1; b++)
{
destpixels[(y * width + x) * bpp+b] =
((1-radius) * alpha1 * pixels[y][x * bpp + b]
+ radius * alpha2 * pixels[yy][xx * bpp + b])/alpha;
}
destpixels[(y * width + x) * bpp + bpp-1] = alpha;
}
else
{
for (b = 0; b < bpp; b++)
destpixels[(y * width + x) * bpp+b] =
(1-radius) * pixels[y][x * bpp + b]
+ radius * pixels[yy][xx * bpp + b];
}
src_pixel += bpp;
dest_pixel += bpp;
}
}
gimp_preview_draw_buffer (preview, destpixels, width * bpp);
for (y = 0; y < height; y++)
g_free (pixels[y]);
g_free (pixels);
gimp_pixel_fetcher_destroy (param.pft);
g_free (destpixels);
g_free (preview_cache);
gimp_preview_draw_buffer (preview, dest, preview_width * bpp);
g_free (dest);
g_free (src);
}
static gboolean

View File

@ -723,76 +723,65 @@ static void
dialog_update_preview (GimpDrawable *drawable,
GimpPreview *preview)
{
gdouble left, right, bottom, top;
gdouble dx, dy;
gdouble px, py;
gdouble cx = 0.0, cy = 0.0;
gint ix, iy;
gint x, y;
gint width, height;
gint bpp;
gdouble scale_x, scale_y;
guchar *p_ul, *i;
GimpRGB background;
guchar outside[4];
guchar *buffer, *preview_cache;
guchar k;
gdouble cx, cy;
gint x, y;
gint sx, sy;
gint width, height;
guchar *pixel;
guchar outside[4];
GimpRGB background;
guchar *dest;
gint j;
gint bpp;
GimpPixelFetcher *pft;
guchar in_pixels[4][4];
guchar *in_values[4];
for (j = 0; j < 4; j++)
in_values[j] = in_pixels[j];
pft = gimp_pixel_fetcher_new (drawable, FALSE);
gimp_context_get_background (&background);
gimp_rgb_set_alpha (&background, 0.0);
gimp_drawable_get_color_uchar (drawable->drawable_id, &background, outside);
gimp_pixel_fetcher_set_bg_color (pft, &background);
gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_SMEAR);
left = sel_x1;
right = sel_x2 - 1;
bottom = sel_y2 - 1;
top = sel_y1;
preview_cache = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&width, &height, &bpp);
dx = (right - left) / (width - 1);
dy = (bottom - top) / (height - 1);
scale_x = (double) width / (right - left + 1);
scale_y = (double) height / (bottom - top + 1);
py = top;
buffer = g_new (guchar, bpp * width * height);
p_ul = buffer;
dest = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&width, &height, &bpp);
pixel = dest;
for (y = 0; y < height; y++)
{
px = left;
for (x = 0; x < width; x++)
{
calc_undistorted_coords (px, py, &cx, &cy);
gimp_preview_untransform (preview, x, y, &sx, &sy);
if (calc_undistorted_coords ((gdouble)sx, (gdouble)sy,
&cx, &cy))
{
cx = (cx - left) * scale_x;
cy = (cy - top) * scale_y;
gimp_pixel_fetcher_get_pixel (pft, cx, cy, in_pixels[0]);
gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy, in_pixels[1]);
gimp_pixel_fetcher_get_pixel (pft, cx, cy + 1, in_pixels[2]);
gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy + 1, in_pixels[3]);
ix = (int) (cx + 0.5);
iy = (int) (cy + 0.5);
if ((ix >= 0) && (ix < width) &&
(iy >= 0) && (iy < height))
i = preview_cache + bpp * (width * iy + ix);
gimp_bilinear_pixels_8 (pixel, cx, cy, bpp,
img_has_alpha, in_values);
}
else
i = outside;
{
for (j = 0; j < bpp; j++)
pixel[j] = outside[j];
}
for (k = 0; k < bpp; k ++)
p_ul[k] = i[k];
p_ul += bpp;
px += dx;
pixel += bpp;
}
py += dy;
}
gimp_preview_draw_buffer (preview, buffer, bpp * width);
gimp_pixel_fetcher_destroy (pft);
g_free (buffer);
g_free (preview_cache);
gimp_preview_draw_buffer (preview, dest, width * bpp);
g_free (dest);
}

View File

@ -611,122 +611,62 @@ static void
dialog_update_preview (GimpDrawable *drawable,
GimpPreview *preview)
{
gdouble left, right, bottom, top;
gdouble dx, dy;
gdouble px, py;
gdouble cx, cy;
gint ix, iy;
gint x, y;
gdouble whirl;
gdouble scale_x, scale_y;
guchar *p_ul, *p_lr, *i;
guchar outside[4];
GimpRGB background;
gint width, height;
guchar *src, *dest;
gint j;
gimp_context_get_background (&background);
switch (img_bpp)
{
case 1:
outside[0] = outside[1] = outside [2] = gimp_rgb_luminance_uchar (&background);
outside[3] = 255;
break;
case 2:
outside[0] = outside[1] = outside [2] = gimp_rgb_luminance_uchar (&background);
outside[3] = 0;
break;
case 3:
gimp_rgb_get_uchar (&background,
&outside[0], &outside[1], &outside[2]);
outside[3] = 255;
break;
case 4:
gimp_rgb_get_uchar (&background,
&outside[0], &outside[1], &outside[2]);
outside[3] = 0;
break;
}
left = sel_x1;
right = sel_x2 - 1;
bottom = sel_y2 - 1;
top = sel_y1;
src = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&width, &height, &img_bpp);
dest = g_new (guchar, width * height * img_bpp);
dx = (right - left) / (width - 1);
dy = (bottom - top) / (height - 1);
gdouble cx, cy;
gint x, y;
gint sx, sy;
gint width, height;
guchar *pixel;
GimpRGB background;
guchar *dest;
gint j;
gint bpp;
GimpPixelFetcher *pft;
guchar in_pixels[4][4];
guchar *in_values[4];
gdouble whirl;
whirl = wpvals.whirl * G_PI / 180.0;
radius2 = radius * radius * wpvals.radius;
scale_x = (double) width / (right - left + 1);
scale_y = (double) height / (bottom - top + 1);
for (j = 0; j < 4; j++)
in_values[j] = in_pixels[j];
py = top;
pft = gimp_pixel_fetcher_new (drawable, FALSE);
p_ul = dest;
p_lr = dest + img_bpp * (width * height - 1);
gimp_context_get_background (&background);
gimp_rgb_set_alpha (&background, 0.0);
gimp_pixel_fetcher_set_bg_color (pft, &background);
gimp_pixel_fetcher_set_edge_mode (pft, GIMP_PIXEL_FETCHER_EDGE_SMEAR);
for (y = 0; y <= (height / 2); y++)
dest = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview),
&width, &height, &bpp);
pixel = dest;
for (y = 0; y < height; y++)
{
px = left;
for (x = 0; x < width; x++)
{
calc_undistorted_coords (px, py, whirl, wpvals.pinch, &cx, &cy);
gimp_preview_untransform (preview, x, y, &sx, &sy);
calc_undistorted_coords ((gdouble)sx, (gdouble)sy,
whirl, wpvals.pinch,
&cx, &cy);
cx = (cx - left) * scale_x;
cy = (cy - top) * scale_y;
gimp_pixel_fetcher_get_pixel (pft, cx, cy, in_pixels[0]);
gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy, in_pixels[1]);
gimp_pixel_fetcher_get_pixel (pft, cx, cy + 1, in_pixels[2]);
gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy + 1, in_pixels[3]);
/* Upper left mirror */
gimp_bilinear_pixels_8 (pixel, cx, cy, bpp,
img_has_alpha, in_values);
ix = (int) (cx + 0.5);
iy = (int) (cy + 0.5);
if ((ix >= 0) && (ix < width) &&
(iy >= 0) && (iy < height))
i = src + img_bpp * (width * iy + ix);
else
i = outside;
for (j = 0; j < img_bpp; j++)
p_ul[j] = i[j];
p_ul += img_bpp;
/* Lower right mirror */
ix = width - ix - 1;
iy = height - iy - 1;
if ((ix >= 0) && (ix < width) &&
(iy >= 0) && (iy < height))
i = src + img_bpp * (width * iy + ix);
else
i = outside;
for (j = 0; j < img_bpp; j++)
p_lr[j] = i[j];
p_lr -= img_bpp;
px += dx;
pixel += bpp;
}
py += dy;
}
gimp_preview_draw_buffer (preview, dest, width * img_bpp);
gimp_pixel_fetcher_destroy (pft);
g_free (src);
gimp_preview_draw_buffer (preview, dest, width * bpp);
g_free (dest);
}