static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpPDBStatusType status; GimpRunMode run_mode; gdouble xhsiz, yhsiz; GimpRGB background; status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); /* Get the active drawable info */ drawable = gimp_drawable_get (param[2].data.d_drawable); img_width = gimp_drawable_width (drawable->drawable_id); img_height = gimp_drawable_height (drawable->drawable_id); img_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); gimp_drawable_mask_bounds (drawable->drawable_id, &sel_x1, &sel_y1, &sel_x2, &sel_y2); /* Calculate scaling parameters */ sel_width = sel_x2 - sel_x1; sel_height = sel_y2 - sel_y1; cen_x = (double) (sel_x1 + sel_x2 - 1) / 2.0; cen_y = (double) (sel_y1 + sel_y2 - 1) / 2.0; xhsiz = (double) (sel_width - 1) / 2.0; yhsiz = (double) (sel_height - 1) / 2.0; if (xhsiz < yhsiz) { scale_x = yhsiz / xhsiz; scale_y = 1.0; } else if (xhsiz > yhsiz) { scale_x = 1.0; scale_y = xhsiz / yhsiz; } else { scale_x = 1.0; scale_y = 1.0; } /* Get background color */ gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 0.0); gimp_drawable_get_color_uchar (drawable->drawable_id, &background, back_color); /* See how we will run */ switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &pcvals); /* Get information from the dialog */ if (! polarize_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are present */ if (nparams != 8) { status = GIMP_PDB_CALLING_ERROR; } else { pcvals.circle = param[3].data.d_float; pcvals.angle = param[4].data.d_float; pcvals.backwards = param[5].data.d_int32; pcvals.inverse = param[6].data.d_int32; pcvals.polrec = param[7].data.d_int32; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &pcvals); break; default: break; } /* Distort the image */ if ((status == GIMP_PDB_SUCCESS) && (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id))) { /* Set the tile cache size */ gimp_tile_cache_ntiles (2 * (drawable->width + gimp_tile_width() - 1) / gimp_tile_width ()); /* Run! */ polarize (drawable); /* If run mode is interactive, flush displays */ if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &pcvals, sizeof (polarize_vals_t)); } else if (status == GIMP_PDB_SUCCESS) status = GIMP_PDB_EXECUTION_ERROR; values[0].data.d_status = status; gimp_drawable_detach (drawable); }
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 run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpRGB background; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpRunMode run_mode; run_mode = param[0].data.d_int32; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; INIT_I18N (); drawable = gimp_drawable_get (param[2].data.d_drawable); drawable_width = drawable->width; drawable_height = drawable->height; /* Get background color */ gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 0.0); gimp_drawable_get_color_uchar (drawable->drawable_id, &background, background_color); /* Set the tile cache size */ gimp_tile_cache_ntiles (2 * MAX (drawable->ntile_rows, drawable->ntile_cols)); *nreturn_vals = 1; *return_vals = values; switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &vals); if (! lens_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 9) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { vals.centre_x = param[3].data.d_float; vals.centre_y = param[4].data.d_float; vals.square_a = param[5].data.d_float; vals.quad_a = param[6].data.d_float; vals.scale_a = param[7].data.d_float; vals.brighten = param[8].data.d_float; } break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &vals); break; default: break; } if ( status == GIMP_PDB_SUCCESS ) { lens_distort (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &vals, sizeof (LensValues)); gimp_drawable_detach (drawable); } values[0].data.d_status = status; }