static void polarize_func (gint x, gint y, guchar *dest, gint bpp, gpointer data) { double cx, cy; if (calc_undistorted_coords (x, y, &cx, &cy)) { guchar pixel1[4], pixel2[4], pixel3[4], pixel4[4]; guchar *values[4]; GimpPixelFetcher *pft = (GimpPixelFetcher*) data; values[0] = pixel1; values[1] = pixel2; values[2] = pixel3; values[3] = pixel4; gimp_pixel_fetcher_get_pixel (pft, cx, cy, pixel1); gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy, pixel2); gimp_pixel_fetcher_get_pixel (pft, cx, cy + 1, pixel3); gimp_pixel_fetcher_get_pixel (pft, cx + 1, cy + 1, pixel4); gimp_bilinear_pixels_8 (dest, cx, cy, bpp, img_has_alpha, values); } else { gint b; for (b = 0; b < bpp; b++) { dest[b] = back_color[b]; } } }
static void dialog_update_preview (GimpDrawable *drawable, GimpPreview *preview) { 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); dest = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview), &width, &height, &bpp); pixel = dest; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { gimp_preview_untransform (preview, x, y, &sx, &sy); if (calc_undistorted_coords ((gdouble)sx, (gdouble)sy, &cx, &cy)) { 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]); gimp_bilinear_pixels_8 (pixel, cx, cy, bpp, img_has_alpha, in_values); } else { for (j = 0; j < bpp; j++) pixel[j] = outside[j]; } pixel += bpp; } } gimp_pixel_fetcher_destroy (pft); gimp_preview_draw_buffer (preview, dest, width * bpp); g_free (dest); }
static void wave (guchar *src, guchar *dst, gint width, gint height, gint bypp, gboolean has_alpha, gdouble cen_x, gdouble cen_y, gdouble amplitude, gdouble wavelength, gdouble phase, gboolean smear, gboolean reflective, gboolean verbose) { glong rowsiz; guchar *p; guchar *dest; gint x1, y1, x2, y2; gint x, y; gint prog_interval = 0; gint x1_in, y1_in, x2_in, y2_in; gdouble xhsiz, yhsiz; /* Half size of selection */ gdouble radius, radius2; /* Radius and radius^2 */ gdouble amnt, d; gdouble needx, needy; gdouble dx, dy; gdouble xscale, yscale; gint xi, yi; guchar *values[4]; guchar zeroes[4] = { 0, 0, 0, 0 }; phase = phase * G_PI / 180.0; rowsiz = width * bypp; if (verbose) { gimp_progress_init (_("Waving")); prog_interval = height / 10; } x1 = y1 = 0; x2 = width; y2 = height; /* Compute wave radii (semiaxes) */ xhsiz = (double) (x2 - x1) / 2.0; yhsiz = (double) (y2 - y1) / 2.0; /* These are the necessary scaling factors to turn the wave ellipse into a large circle */ if (xhsiz < yhsiz) { xscale = yhsiz / xhsiz; yscale = 1.0; } else if (xhsiz > yhsiz) { xscale = 1.0; yscale = xhsiz / yhsiz; } else { xscale = 1.0; yscale = 1.0; } radius = MAX (xhsiz, yhsiz); radius2 = radius * radius; /* Wave the image! */ dst += y1 * rowsiz + x1 * bypp; wavelength *= 2; for (y = y1; y < y2; y++) { dest = dst; if (verbose && (y % prog_interval == 0)) gimp_progress_update ((double) y / (double) height); for (x = x1; x < x2; x++) { /* Distance from current point to wave center, scaled */ dx = (x - cen_x) * xscale; dy = (y - cen_y) * yscale; /* Distance^2 to center of *circle* (our scaled ellipse) */ d = sqrt (dx * dx + dy * dy); /* Use the formula described above. */ /* Calculate waved point and scale again to ellipsify */ /* * Reflective waves are strange - the effect is much * more like a mirror which is in the shape of * the wave than anything else. */ if (reflective) { amnt = amplitude * fabs (sin (((d / wavelength) * (2.0 * G_PI) + phase))); needx = (amnt * dx) / xscale + cen_x; needy = (amnt * dy) / yscale + cen_y; } else { amnt = amplitude * sin (((d / wavelength) * (2.0 * G_PI) + phase)); needx = (amnt + dx) / xscale + cen_x; needy = (amnt + dy) / yscale + cen_y; } /* Calculations complete; now copy the proper pixel */ if (smear) { xi = CLAMP (needx, 0, width - 2); yi = CLAMP (needy, 0, height - 2); } else { xi = needx; yi = needy; } p = src + rowsiz * yi + xi * bypp; x1_in = WITHIN (0, xi, width - 1); y1_in = WITHIN (0, yi, height - 1); x2_in = WITHIN (0, xi + 1, width - 1); y2_in = WITHIN (0, yi + 1, height - 1); if (x1_in && y1_in) values[0] = p; else values[0] = zeroes; if (x2_in && y1_in) values[1] = p + bypp; else values[1] = zeroes; if (x1_in && y2_in) values[2] = p + rowsiz; else values[2] = zeroes; if (x2_in && y2_in) values[3] = p + bypp + rowsiz; else values[3] = zeroes; gimp_bilinear_pixels_8 (dest, needx, needy, bypp, has_alpha, values); dest += bypp; } dst += rowsiz; } if (verbose) gimp_progress_update (1.0); }