gint image_setup (GimpDrawable *drawable, gint interactive) { /* Set the tile cache size */ /* ======================= */ gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width() - 1) / gimp_tile_width ()); /* Get some useful info on the input drawable */ /* ========================================== */ input_drawable = drawable; output_drawable = drawable; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &border_x, &border_y, &border_w, &border_h)) return FALSE; width = input_drawable->width; height = input_drawable->height; gimp_pixel_rgn_init (&source_region, input_drawable, 0, 0, width, height, FALSE, FALSE); maxcounter = (glong) width * (glong) height; if (mapvals.transparent_background == TRUE) { gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); } else { gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 1.0); } /* Assume at least RGB */ /* =================== */ in_channels = 3; if (gimp_drawable_has_alpha (input_drawable->drawable_id) == TRUE) in_channels++; if (interactive == TRUE) { preview_rgb_stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, PREVIEW_WIDTH); preview_rgb_data = g_new0 (guchar, preview_rgb_stride * PREVIEW_HEIGHT); preview_surface = cairo_image_surface_create_for_data (preview_rgb_data, CAIRO_FORMAT_RGB24, PREVIEW_WIDTH, PREVIEW_HEIGHT, preview_rgb_stride); } return TRUE; }
gint image_setup (GimpDrawable *drawable, gint interactive) { /* Set the tile cache size */ /* ======================= */ gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width() - 1) / gimp_tile_width ()); /* Get some useful info on the input drawable */ /* ========================================== */ input_drawable = drawable; output_drawable = drawable; gimp_drawable_mask_bounds (drawable->drawable_id, &border_x1, &border_y1, &border_x2, &border_y2); width = input_drawable->width; height = input_drawable->height; gimp_pixel_rgn_init (&source_region, input_drawable, 0, 0, width, height, FALSE, FALSE); maxcounter = (glong) width * (glong) height; if (mapvals.transparent_background == TRUE) { gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); } else { gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 1.0); } /* Assume at least RGB */ /* =================== */ in_channels = 3; if (gimp_drawable_has_alpha (input_drawable->drawable_id) == TRUE) in_channels++; if (interactive == TRUE) { preview_rgb_data = g_new0 (guchar, PREVIEW_HEIGHT * PREVIEW_WIDTH * 3); } return TRUE; }
static gboolean sel2path (gint32 image_ID) { gint32 selection_ID; GimpDrawable *sel_drawable; pixel_outline_list_type olt; spline_list_array_type splines; gimp_selection_bounds (image_ID, &has_sel, &sel_x1, &sel_y1, &sel_x2, &sel_y2); sel_width = sel_x2 - sel_x1; sel_height = sel_y2 - sel_y1; /* Now get the selection channel */ selection_ID = gimp_image_get_selection (image_ID); if (selection_ID < 0) return FALSE; sel_drawable = gimp_drawable_get (selection_ID); if (gimp_drawable_bpp (selection_ID) != 1) { g_warning ("Internal error. Selection bpp > 1"); return FALSE; } gimp_pixel_rgn_init (&selection_rgn, sel_drawable, sel_x1, sel_y1, sel_width, sel_height, FALSE, FALSE); gimp_tile_cache_ntiles (2 * (sel_drawable->width + gimp_tile_width () - 1) / gimp_tile_width ()); olt = find_outline_pixels (); splines = fitted_splines (olt); do_points (splines, image_ID); gimp_drawable_detach (sel_drawable); gimp_displays_flush (); return TRUE; }
/** * gimp_tile_cache_ntiles: * @ntiles: number of tiles that should fit into the cache * * Sets the size of the tile cache on the plug-in side. This function * is similar to gimp_tile_cache_size() but supports specifying the * number of tiles directly. * * If your plug-in access pixels tile-by-tile, it doesn't need a tile * cache at all. If however the plug-in accesses drawable pixel data * row-by-row, it should set the tile cache large enough to hold the * number of tiles per row. Double this size if your plug-in uses * shadow tiles. **/ void gimp_tile_cache_ntiles (gulong ntiles) { max_cache_size = (ntiles * gimp_tile_width () * gimp_tile_height () * 4); }
static void run (const gchar *name, gint n_params, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 image_id; *nreturn_vals = 1; *return_vals = values; run_mode = param[0].data.d_int32; if (run_mode == GIMP_RUN_NONINTERACTIVE) { if (n_params != 3) { status = GIMP_PDB_CALLING_ERROR; } } if (status == GIMP_PDB_SUCCESS) { /* Get the specified drawable */ drawable = gimp_drawable_get(param[2].data.d_drawable); image_id = param[1].data.d_image; /* Make sure that the drawable is gray or RGB or indexed */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id) || gimp_drawable_is_indexed (drawable->drawable_id)) { gimp_progress_init ("Autocropping..."); gimp_tile_cache_ntiles (1 + (drawable->width > drawable->height ? (drawable->width / gimp_tile_width()) : (drawable->height / gimp_tile_height()))); do_acrop(drawable, image_id); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); gimp_drawable_detach (drawable); } else { status = GIMP_PDB_EXECUTION_ERROR; } } values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; }
static void pixelize (GimpDrawable *drawable, GimpPreview *preview) { gint tile_width; gint tile_height; gint pixelwidth; gint pixelheight; tile_width = gimp_tile_width (); tile_height = gimp_tile_height (); pixelwidth = pvals.pixelwidth; pixelheight = pvals.pixelheight; if (pixelwidth < 0) pixelwidth = - pixelwidth; if (pixelwidth < 1) pixelwidth = 1; if (pixelheight < 0) pixelheight = - pixelheight; if (pixelheight < 1) pixelheight = 1; if (pixelwidth >= tile_width || pixelheight >= tile_height || preview) pixelize_large (drawable, pixelwidth, pixelheight, preview); else pixelize_small (drawable, pixelwidth, pixelheight, tile_width, tile_height); }
/* main function */ static void run (const gchar *name, gint n_params, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpDrawable *drawable; run_mode = param[0].data.d_int32; INIT_I18N (); *nreturn_vals = 2; *return_vals = values; if (run_mode == GIMP_RUN_NONINTERACTIVE) { if (n_params != 3) status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { drawable = gimp_drawable_get (param[2].data.d_drawable); imageID = param[1].data.d_image; if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id) || gimp_drawable_is_indexed (drawable->drawable_id)) { memset (hist_red, 0, sizeof (hist_red)); memset (hist_green, 0, sizeof (hist_green)); memset (hist_blue, 0, sizeof (hist_blue)); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); analyze (drawable); /* show dialog after we analyzed image */ if (run_mode != GIMP_RUN_NONINTERACTIVE) doDialog (); } else status = GIMP_PDB_EXECUTION_ERROR; gimp_drawable_detach (drawable); } values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; values[1].type = GIMP_PDB_INT32; values[1].data.d_int32 = uniques; }
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 = GIMP_PDB_SUCCESS; GimpRunMode run_mode; gint32 image_ID; INIT_I18N(); run_mode = param[0].data.d_int32; /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); image_ID = param[1].data.d_image; /* Make sure that the drawable is gray or RGB color */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init (_("Auto-Stretching HSV")); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); autostretch_hsv (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } else if (gimp_drawable_is_indexed (drawable->drawable_id)) { indexed_autostretch_hsv (image_ID); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } else { /* gimp_message ("autostretch_hsv: cannot operate on indexed color images"); */ status = GIMP_PDB_EXECUTION_ERROR; } *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static void scatter_hsv (GimpDrawable *drawable) { gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); gimp_progress_init (_("HSV Noise")); gimp_rgn_iterate2 (drawable, 0 /* unused */, scatter_hsv_func, NULL); gimp_drawable_detach (drawable); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; Current.drawable = gimp_drawable_get (param[2].data.d_drawable); Current.mask = gimp_drawable_get (gimp_image_get_selection (param[1].data.d_image)); if (gimp_drawable_is_rgb (Current.drawable->drawable_id)) { if (color_rotate_dialog ()) { gimp_progress_init (_("Rotating the colors")); gimp_tile_cache_ntiles (2 * (Current.drawable->width / gimp_tile_width () + 1)); color_rotate (Current.drawable); gimp_displays_flush (); } else { status = GIMP_PDB_CANCEL; } } else { status = GIMP_PDB_EXECUTION_ERROR; } values[0].data.d_status = status; if (status == GIMP_PDB_SUCCESS) gimp_drawable_detach (Current.drawable); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; gint32 image_ID; GimpRunMode run_mode; gint pwidth; gint pheight; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint sel_width; gint sel_height; 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 specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); image_ID = param[1].data.d_image; gimp_drawable_mask_bounds (drawable->drawable_id, &sel_x1, &sel_y1, &sel_x2, &sel_y2); sel_width = sel_x2 - sel_x1; sel_height = sel_y2 - sel_y1; /* Calculate preview size */ if (sel_width > sel_height) { pwidth = MIN (sel_width, PREVIEW_SIZE); pheight = sel_height * pwidth / sel_width; } else { pheight = MIN (sel_height, PREVIEW_SIZE); pwidth = sel_width * pheight / sel_height; } preview_width = MAX (pwidth, 2); preview_height = MAX (pheight, 2); /* See how we will run */ switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data ("plug_in_fractalexplorer", &wvals); /* Get information from the dialog */ if (!explorer_dialog ()) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are present */ if (nparams != 22) { status = GIMP_PDB_CALLING_ERROR; } else { wvals.fractaltype = param[3].data.d_int8; wvals.xmin = param[4].data.d_float; wvals.xmax = param[5].data.d_float; wvals.ymin = param[6].data.d_float; wvals.ymax = param[7].data.d_float; wvals.iter = param[8].data.d_float; wvals.cx = param[9].data.d_float; wvals.cy = param[10].data.d_float; wvals.colormode = param[11].data.d_int8; wvals.redstretch = param[12].data.d_float; wvals.greenstretch = param[13].data.d_float; wvals.bluestretch = param[14].data.d_float; wvals.redmode = param[15].data.d_int8; wvals.greenmode = param[16].data.d_int8; wvals.bluemode = param[17].data.d_int8; wvals.redinvert = param[18].data.d_int8; wvals.greeninvert = param[19].data.d_int8; wvals.blueinvert = param[20].data.d_int8; wvals.ncolors = CLAMP (param[21].data.d_int32, 2, MAXNCOLORS); } make_color_map(); break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data ("plug_in_fractalexplorer", &wvals); make_color_map (); break; default: break; } xmin = wvals.xmin; xmax = wvals.xmax; ymin = wvals.ymin; ymax = wvals.ymax; cx = wvals.cx; cy = wvals.cy; if (status == GIMP_PDB_SUCCESS) { /* Make sure that the drawable is not indexed */ if (! gimp_drawable_is_indexed (drawable->drawable_id)) { gimp_progress_init (_("Rendering fractal")); /* Set the tile cache size */ gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width() + 1)); /* Run! */ explorer (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data ("plug_in_fractalexplorer", &wvals, sizeof (explorer_vals_t)); } else { status = GIMP_PDB_EXECUTION_ERROR; } } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static void rotate_drawable (GimpDrawable *drawable) { GimpPixelRgn srcPR, destPR; gint width, height; gint longside; gint bytes; gint row, col; gint offsetx, offsety; gboolean was_lock_alpha = FALSE; guchar *buffer; guchar *src_row, *dest_row; /* initialize */ row = 0; /* Get the size of the input drawable. */ width = drawable->width; height = drawable->height; bytes = drawable->bpp; if (gimp_layer_get_lock_alpha (drawable->drawable_id)) { was_lock_alpha = TRUE; gimp_layer_set_lock_alpha (drawable->drawable_id, FALSE); } if (rotvals.angle == 2) /* we're rotating by 180° */ { gimp_tile_cache_ntiles (2 * (width / gimp_tile_width() + 1)); gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE); src_row = (guchar *) g_malloc (width * bytes); dest_row = (guchar *) g_malloc (width * bytes); for (row = 0; row < height; row++) { gimp_pixel_rgn_get_row (&srcPR, src_row, 0, row, width); for (col = 0; col < width; col++) { memcpy (dest_row + col * bytes, src_row + (width - 1 - col) * bytes, bytes); } gimp_pixel_rgn_set_row (&destPR, dest_row, 0, (height - row - 1), width); if ((row % 5) == 0) gimp_progress_update ((double) row / (double) height); } g_free (src_row); g_free (dest_row); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, width, height); } else /* we're rotating by 90° or 270° */ { (width > height) ? (longside = width) : (longside = height); gimp_layer_resize (drawable->drawable_id, longside, longside, 0, 0); drawable = gimp_drawable_get (drawable->drawable_id); gimp_drawable_flush (drawable); gimp_tile_cache_ntiles ((longside / gimp_tile_width () + 1) + (longside / gimp_tile_height () + 1)); gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, longside, longside, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, longside, longside, TRUE, TRUE); buffer = g_malloc (longside * bytes); if (rotvals.angle == 1) /* we're rotating by 90° */ { for (row = 0; row < height; row++) { gimp_pixel_rgn_get_row (&srcPR, buffer, 0, row, width); gimp_pixel_rgn_set_col (&destPR, buffer, (height - row - 1), 0, width); if ((row % 5) == 0) gimp_progress_update ((double) row / (double) height); } } else /* we're rotating by 270° */ { for (col = 0; col < width; col++) { gimp_pixel_rgn_get_col (&srcPR, buffer, col, 0, height); gimp_pixel_rgn_set_row (&destPR, buffer, 0, (width - col - 1), height); if ((col % 5) == 0) gimp_progress_update ((double) col / (double) width); } } g_free (buffer); gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, height, width); gimp_layer_resize (drawable->drawable_id, height, width, 0, 0); drawable = gimp_drawable_get (drawable->drawable_id); gimp_drawable_flush (drawable); gimp_drawable_update (drawable->drawable_id, 0, 0, height, width); } gimp_drawable_offsets (drawable->drawable_id, &offsetx, &offsety); rotate_compute_offsets (&offsetx, &offsety, gimp_image_width (image_ID), gimp_image_height (image_ID), width, height); gimp_layer_set_offsets (drawable->drawable_id, offsetx, offsety); if (was_lock_alpha) gimp_layer_set_lock_alpha (drawable->drawable_id, TRUE); return; }
/* This function is nearly identical to the function 'tile_cache_insert' * in the file 'tile_cache.c' which is part of the main gimp application. */ static void gimp_tile_cache_insert (GimpTile *tile) { GList *list; if (!tile_hash_table) { tile_hash_table = g_hash_table_new (g_direct_hash, NULL); max_tile_size = gimp_tile_width () * gimp_tile_height () * 4; } /* First check and see if the tile is already * in the cache. In that case we will simply place * it at the end of the tile list to indicate that * it was the most recently accessed tile. */ list = g_hash_table_lookup (tile_hash_table, tile); if (list) { /* The tile was already in the cache. Place it at * the end of the tile list. */ /* If the tile is already at the end of the list, we are done */ if (list == tile_list_tail) return; /* At this point we have at least two elements in our list */ g_assert (tile_list_head != tile_list_tail); tile_list_head = g_list_remove_link (tile_list_head, list); tile_list_tail = g_list_last (g_list_concat (tile_list_tail, list)); } else { /* The tile was not in the cache. First check and see * if there is room in the cache. If not then we'll have * to make room first. Note: it might be the case that the * cache is smaller than the size of a tile in which case * it won't be possible to put it in the cache. */ if ((cur_cache_size + max_tile_size) > max_cache_size) { while (tile_list_head && (cur_cache_size + max_cache_size * FREE_QUANTUM) > max_cache_size) { gimp_tile_cache_flush ((GimpTile *) tile_list_head->data); } if ((cur_cache_size + max_tile_size) > max_cache_size) return; } /* Place the tile at the end of the tile list. */ tile_list_tail = g_list_append (tile_list_tail, tile); if (! tile_list_head) tile_list_head = tile_list_tail; tile_list_tail = g_list_last (tile_list_tail); /* Add the tiles list node to the tile hash table. */ g_hash_table_insert (tile_hash_table, tile, tile_list_tail); /* Note the increase in the number of bytes the cache * is referencing. */ cur_cache_size += max_tile_size; /* Reference the tile so that it won't be returned to * the main gimp application immediately. */ tile->ref_count++; } }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; INIT_I18N (); run_mode = param[0].data.d_int32; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &pvals); /* First acquire information with a dialog */ if (! nova_dialog (drawable)) { gimp_drawable_detach (drawable); return; } break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 9) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { pvals.xcenter = param[3].data.d_int32; pvals.ycenter = param[4].data.d_int32; pvals.color = param[5].data.d_color; pvals.radius = param[6].data.d_int32; pvals.nspoke = param[7].data.d_int32; pvals.randomhue = param[8].data.d_int32; } if ((status == GIMP_PDB_SUCCESS) && pvals.radius <= 0) status = GIMP_PDB_CALLING_ERROR; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &pvals); break; default: break; } if (status == GIMP_PDB_SUCCESS) { /* Make sure that the drawable is gray or RGB color */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init (_("Rendering supernova")); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); nova (drawable, NULL); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &pvals, sizeof (NovaValues)); } else { /* gimp_message ("nova: cannot operate on indexed color images"); */ status = GIMP_PDB_EXECUTION_ERROR; } } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static void run (const gchar *name, gint n_params, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; gint32 image_ID; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); run_mode = param[0].data.d_int32; image_ID = param[1].data.d_int32; drawable = gimp_drawable_get (param[2].data.d_drawable); if (run_mode == GIMP_RUN_NONINTERACTIVE) { if (n_params != 18) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { grid_cfg.hwidth = MAX (0, param[3].data.d_int32); grid_cfg.hspace = MAX (1, param[4].data.d_int32); grid_cfg.hoffset = MAX (0, param[5].data.d_int32); grid_cfg.hcolor = param[6].data.d_color; gimp_rgb_set_alpha (&(grid_cfg.hcolor), ((double) param[7].data.d_int8) / 255.0); grid_cfg.vwidth = MAX (0, param[8].data.d_int32); grid_cfg.vspace = MAX (1, param[9].data.d_int32); grid_cfg.voffset = MAX (0, param[10].data.d_int32); grid_cfg.vcolor = param[11].data.d_color; gimp_rgb_set_alpha (&(grid_cfg.vcolor), ((double) param[12].data.d_int8) / 255.0); grid_cfg.iwidth = MAX (0, param[13].data.d_int32); grid_cfg.ispace = MAX (0, param[14].data.d_int32); grid_cfg.ioffset = MAX (0, param[15].data.d_int32); grid_cfg.icolor = param[16].data.d_color; gimp_rgb_set_alpha (&(grid_cfg.icolor), ((double) (guint) param[17].data.d_int8) / 255.0); } } else { gimp_context_get_foreground (&grid_cfg.hcolor); grid_cfg.vcolor = grid_cfg.icolor = grid_cfg.hcolor; /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &grid_cfg); } if (run_mode == GIMP_RUN_INTERACTIVE) { if (!dialog (image_ID, drawable)) { /* The dialog was closed, or something similarly evil happened. */ status = GIMP_PDB_EXECUTION_ERROR; } } if (grid_cfg.hspace <= 0 || grid_cfg.vspace <= 0) { status = GIMP_PDB_EXECUTION_ERROR; } if (status == GIMP_PDB_SUCCESS) { gimp_progress_init (_("Drawing grid")); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); grid (image_ID, drawable, NULL); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &grid_cfg, sizeof (grid_cfg)); gimp_drawable_detach (drawable); } values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; }
static inline void filter (void) { static void (* overlap)(guchar *, const guchar *); GimpPixelRgn src; GimpPixelRgn dst; GimpRGB color; guchar pixel[4]; gint division_x; gint division_y; gint offset_x; gint offset_y; Tile *tiles; gint numof_tiles; Tile *t; gint i; gint x; gint y; gint move_max_pixels; gint clear_x0; gint clear_y0; gint clear_x1; gint clear_y1; gint clear_width; gint clear_height; guchar *pixels; guchar *buffer; gint dindex; gint sindex; gint px, py; GRand *gr; gr = g_rand_new (); /* INITIALIZE */ gimp_pixel_rgn_init (&src, p.drawable, 0, 0, p.drawable->width, p.drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&dst, p.drawable, 0, 0, p.drawable->width, p.drawable->height, TRUE, TRUE); pixels = g_new (guchar, p.drawable->bpp * p.drawable->width * p.drawable->height); buffer = g_new (guchar, p.drawable->bpp * p.params.tile_width * p.params.tile_height); overlap = p.drawable_has_alpha ? overlap_RGBA : overlap_RGB; gimp_progress_init (_("Paper Tile")); gimp_drawable_mask_bounds (p.drawable->drawable_id, &p.selection.x0, &p.selection.y0, &p.selection.x1, &p.selection.y1); p.selection.width = p.selection.x1 - p.selection.x0; p.selection.height = p.selection.y1 - p.selection.y0; gimp_tile_cache_ntiles (2 * (p.selection.width / gimp_tile_width () + 1)); /* TILES */ division_x = p.params.division_x; division_y = p.params.division_y; if (p.params.fractional_type == FRACTIONAL_TYPE_FORCE) { if (0 < p.drawable->width % p.params.tile_width) division_x++; if (0 < p.drawable->height % p.params.tile_height) division_y++; if (p.params.centering) { if (1 < p.drawable->width % p.params.tile_width) { division_x++; offset_x = (p.drawable->width % p.params.tile_width) / 2 - p.params.tile_width; } else { offset_x = 0; } if (1 < p.drawable->height % p.params.tile_height) { division_y++; offset_y = (p.drawable->height % p.params.tile_height) / 2 - p.params.tile_height; } else { offset_y = 0; } } else { offset_x = 0; offset_y = 0; } } else { if (p.params.centering) { offset_x = (p.drawable->width % p.params.tile_width) / 2; offset_y = (p.drawable->height % p.params.tile_height) / 2; } else { offset_x = 0; offset_y = 0; } } move_max_pixels = p.params.move_max_rate * p.params.tile_width / 100.0; numof_tiles = division_x * division_y; t = tiles = g_new(Tile, numof_tiles); for (y = 0; y < division_y; y++) { gint srcy = offset_y + p.params.tile_height * y; for (x = 0; x < division_x; x++, t++) { gint srcx = offset_x + p.params.tile_width * x; if (srcx < 0) { t->x = 0; t->width = srcx + p.params.tile_width; } else if (srcx + p.params.tile_width < p.drawable->width) { t->x = srcx; t->width = p.params.tile_width; } else { t->x = srcx; t->width = p.drawable->width - srcx; } if (srcy < 0) { t->y = 0; t->height = srcy + p.params.tile_height; } else if (srcy + p.params.tile_height < p.drawable->height) { t->y = srcy; t->height = p.params.tile_height; } else { t->y = srcy; t->height = p.drawable->height - srcy; } t->z = g_rand_int (gr); random_move (&t->move_x, &t->move_y, move_max_pixels); } } qsort (tiles, numof_tiles, sizeof *tiles, tile_compare); gimp_pixel_rgn_get_rect (&src, pixels, 0, 0, p.drawable->width, p.drawable->height); if (p.params.fractional_type == FRACTIONAL_TYPE_IGNORE) { clear_x0 = offset_x; clear_y0 = offset_y; clear_width = p.params.tile_width * division_x; clear_height = p.params.tile_height * division_y; } else { clear_x0 = 0; clear_y0 = 0; clear_width = p.drawable->width; clear_height = p.drawable->height; } clear_x1 = clear_x0 + clear_width; clear_y1 = clear_y0 + clear_height; switch (p.params.background_type) { case BACKGROUND_TYPE_TRANSPARENT: for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for (i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = 0; } } } break; case BACKGROUND_TYPE_INVERTED: for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); pixels[dindex+0] = 255 - pixels[dindex+0]; pixels[dindex+1] = 255 - pixels[dindex+1]; pixels[dindex+2] = 255 - pixels[dindex+2]; } } break; case BACKGROUND_TYPE_IMAGE: break; case BACKGROUND_TYPE_FOREGROUND: gimp_context_get_foreground (&color); gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]); pixel[3] = 255; for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for (i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; case BACKGROUND_TYPE_BACKGROUND: gimp_context_get_background (&color); gimp_rgb_get_uchar (&color, &pixel[0], &pixel[1], &pixel[2]); pixel[3] = 255; for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for(i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; case BACKGROUND_TYPE_COLOR: gimp_rgba_get_uchar (&p.params.background_color, pixel, pixel + 1, pixel + 2, pixel + 3); for (y = clear_y0; y < clear_y1; y++) { for (x = clear_x0; x < clear_x1; x++) { dindex = p.drawable->bpp * (p.drawable->width * y + x); for(i = 0; i < p.drawable->bpp; i++) { pixels[dindex+i] = pixel[i]; } } } break; } /* DRAW */ for (t = tiles, i = 0; i < numof_tiles; i++, t++) { gint x0 = t->x + t->move_x; gint y0 = t->y + t->move_y; gimp_pixel_rgn_get_rect (&src, buffer, t->x, t->y, t->width, t->height); for (y = 0; y < t->height; y++) { py = y0 + y; for (x = 0; x < t->width; x++) { px = x0 + x; sindex = p.drawable->bpp * (t->width * y + x); if (0 <= px && px < p.drawable->width && 0 <= py && py < p.drawable->height) { dindex = p.drawable->bpp * (p.drawable->width * py + px); overlap(&pixels[dindex], &buffer[sindex]); } else if (p.params.wrap_around) { px = (px + p.drawable->width) % p.drawable->width; py = (py + p.drawable->height) % p.drawable->height; dindex = p.drawable->bpp * (p.drawable->width * py + px); overlap(&pixels[dindex], &buffer[sindex]); } } } gimp_progress_update ((gdouble) i / (gdouble) numof_tiles); } gimp_pixel_rgn_set_rect (&dst, pixels, 0, 0, p.drawable->width, p.drawable->height); gimp_progress_update (1.0); gimp_drawable_flush (p.drawable); gimp_drawable_merge_shadow (p.drawable->drawable_id, TRUE); gimp_drawable_update (p.drawable->drawable_id, p.selection.x0, p.selection.y0, p.selection.width, p.selection.height); g_rand_free (gr); g_free (buffer); g_free (pixels); g_free (tiles); }
gboolean draw_page_cairo (GtkPrintContext *context, PrintData *data) { GimpDrawable *drawable = gimp_drawable_get (data->drawable_id); GimpPixelRgn region; cairo_t *cr; cairo_surface_t *surface; guchar *pixels; gdouble cr_width; gdouble cr_height; gdouble cr_dpi_x; gdouble cr_dpi_y; gint width; gint height; gint stride; gint y; gdouble scale_x; gdouble scale_y; width = drawable->width; height = drawable->height; gimp_tile_cache_ntiles (width / gimp_tile_width () + 1); cr = gtk_print_context_get_cairo_context (context); cr_width = gtk_print_context_get_width (context); cr_height = gtk_print_context_get_height (context); cr_dpi_x = gtk_print_context_get_dpi_x (context); cr_dpi_y = gtk_print_context_get_dpi_y (context); scale_x = cr_dpi_x / data->xres; scale_y = cr_dpi_y / data->yres; #if 0 /* print header if it is requested */ if (data->show_info_header) { draw_info_header (context, cr, data); /* In points */ #define HEADER_HEIGHT (20 * 72.0 / 25.4) cairo_translate (cr, 0, HEADER_HEIGHT); cr_height -= HEADER_HEIGHT; } #endif cairo_translate (cr, data->offset_x / cr_dpi_x * 72.0, data->offset_y / cr_dpi_y * 72.0); cairo_scale (cr, scale_x, scale_y); gimp_pixel_rgn_init (®ion, drawable, 0, 0, width, height, FALSE, FALSE); surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height); pixels = cairo_image_surface_get_data (surface); stride = cairo_image_surface_get_stride (surface); for (y = 0; y < height; y++, pixels += stride) { gimp_pixel_rgn_get_row (®ion, pixels, 0, y, width); switch (drawable->bpp) { case 3: convert_from_rgb (pixels, width); break; case 4: convert_from_rgba (pixels, width); break; } if (y % 16 == 0) gimp_progress_update ((gdouble) y / (gdouble) height); } cairo_set_source_surface (cr, surface, 0, 0); cairo_rectangle (cr, 0, 0, width, height); cairo_fill (cr); cairo_surface_destroy (surface); gimp_progress_update (1.0); gimp_drawable_detach (drawable); return TRUE; }
/* main function */ static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpRunMode runmode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpDrawable *drawable; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; runmode = param[0].data.d_int32; drawable = gimp_drawable_get (param[2].data.d_drawable); switch (runmode) { case GIMP_RUN_INTERACTIVE: /* retrieve stored arguments (if any) */ gimp_get_data (PLUG_IN_PROC, &xargs); /* initialize using foreground color */ gimp_context_get_foreground (&xargs.from); if (! exchange_dialog (drawable)) return; break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &xargs); /* * instead of recalling the last-set values, * run with the current foreground as 'from' * color, making ALT-F somewhat more useful. */ gimp_context_get_foreground (&xargs.from); break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 12) { status = GIMP_PDB_EXECUTION_ERROR; } else { gimp_rgb_set_uchar (&xargs.from, param[3].data.d_int8, param[4].data.d_int8, param[5].data.d_int8); gimp_rgb_set_uchar (&xargs.to, param[6].data.d_int8, param[7].data.d_int8, param[8].data.d_int8); gimp_rgb_set_uchar (&xargs.threshold, param[9].data.d_int8, param[10].data.d_int8, param[11].data.d_int8); } break; default: break; } if (status == GIMP_PDB_SUCCESS) { if (gimp_drawable_is_rgb (drawable->drawable_id)) { gimp_progress_init (_("Color Exchange")); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); exchange (drawable, NULL); gimp_drawable_detach (drawable); /* store our settings */ if (runmode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &xargs, sizeof (myParams)); /* and flush */ if (runmode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } else status = GIMP_PDB_EXECUTION_ERROR; } values[0].data.d_status = status; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint x, y, width, height; run_mode = param[0].data.d_int32; INIT_I18N (); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; drawable = gimp_drawable_get (param[2].data.d_drawable); if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x, &y, &width, &height) || width < MIN_GAUSSIAN_SCALE || height < MIN_GAUSSIAN_SCALE) { status = GIMP_PDB_EXECUTION_ERROR; gimp_drawable_detach (drawable); values[0].data.d_status = status; return; } gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &rvals); /* First acquire information with a dialog */ if (! retinex_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 7) { status = GIMP_PDB_CALLING_ERROR; } else { rvals.scale = (param[3].data.d_int32); rvals.nscales = (param[4].data.d_int32); rvals.scales_mode = (param[5].data.d_int32); rvals.cvar = (param[6].data.d_float); } break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &rvals); break; default: break; } if ((status == GIMP_PDB_SUCCESS) && (gimp_drawable_is_rgb (drawable->drawable_id))) { gimp_progress_init (_("Retinex")); retinex (drawable, NULL); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &rvals, sizeof (RetinexParams)); } else { status = GIMP_PDB_EXECUTION_ERROR; } gimp_drawable_detach (drawable); values[0].data.d_status = status; }
static void clear_curled_region (gint32 drawable_id) { GimpPixelRgn src_rgn, dest_rgn; gpointer pr; gint x = 0; gint y = 0; guint x1, y1, i; guchar *dest, *src, *pp, *sp; guint alpha_pos, progress, max_progress; GimpDrawable *drawable; max_progress = 2 * sel_width * sel_height; progress = max_progress / 2; drawable = gimp_drawable_get (drawable_id); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); gimp_pixel_rgn_init (&src_rgn, drawable, sel_x, sel_y, true_sel_width, true_sel_height, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, sel_x, sel_y, true_sel_width, true_sel_height, TRUE, TRUE); alpha_pos = dest_rgn.bpp - 1; for (pr = gimp_pixel_rgns_register (2, &dest_rgn, &src_rgn); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { dest = dest_rgn.data; src = src_rgn.data; for (y1 = dest_rgn.y; y1 < dest_rgn.y + dest_rgn.h; y1++) { sp = src; pp = dest; for (x1 = dest_rgn.x; x1 < dest_rgn.x + dest_rgn.w; x1++) { /* Map coordinates to get the curl correct... */ switch (curl.orientation) { case CURL_ORIENTATION_VERTICAL: x = (CURL_EDGE_RIGHT (curl.edge) ? x1 - sel_x : sel_width - 1 - (x1 - sel_x)); y = (CURL_EDGE_UPPER (curl.edge) ? y1 - sel_y : sel_height - 1 - (y1 - sel_y)); break; case CURL_ORIENTATION_HORIZONTAL: x = (CURL_EDGE_LOWER (curl.edge) ? y1 - sel_y : sel_width - 1 - (y1 - sel_y)); y = (CURL_EDGE_LEFT (curl.edge) ? x1 - sel_x : sel_height - 1 - (x1 - sel_x)); break; } for (i = 0; i < alpha_pos; i++) pp[i] = sp[i]; if (right_of_diagr (x, y) || (right_of_diagm (x, y) && below_diagb (x, y) && !inside_circle (x, y))) { /* Right of the curl */ pp[alpha_pos] = 0; } else { pp[alpha_pos] = sp[alpha_pos]; } pp += dest_rgn.bpp; sp += src_rgn.bpp; } src += src_rgn.rowstride; dest += dest_rgn.rowstride; } progress += dest_rgn.w * dest_rgn.h; gimp_progress_update ((double) progress / (double) max_progress); } gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable_id, TRUE); gimp_drawable_update (drawable_id, sel_x, sel_y, true_sel_width, true_sel_height); gimp_drawable_detach (drawable); }
static gint32 do_curl_effect (gint32 drawable_id) { gint x = 0; gint y = 0; gboolean color_image; gint x1, y1, k; guint alpha_pos, progress, max_progress; gdouble intensity, alpha; GimpVector2 v, dl, dr; gdouble dl_mag, dr_mag, angle, factor; guchar *pp, *dest, fore_grayval, back_grayval; guchar *gradsamp; GimpPixelRgn dest_rgn; gpointer pr; gint32 curl_layer_id; guchar *grad_samples = NULL; color_image = gimp_drawable_is_rgb (drawable_id); curl_layer = gimp_drawable_get (gimp_layer_new (image_id, _("Curl Layer"), true_sel_width, true_sel_height, color_image ? GIMP_RGBA_IMAGE : GIMP_GRAYA_IMAGE, 100, GIMP_NORMAL_MODE)); curl_layer_id = curl_layer->drawable_id; gimp_image_insert_layer (image_id, curl_layer->drawable_id, gimp_item_get_parent (drawable_id), drawable_position); gimp_drawable_fill (curl_layer->drawable_id, GIMP_FILL_TRANSPARENT); gimp_drawable_offsets (drawable_id, &x1, &y1); gimp_layer_set_offsets (curl_layer->drawable_id, sel_x + x1, sel_y + y1); gimp_tile_cache_ntiles (2 * (curl_layer->width / gimp_tile_width () + 1)); gimp_pixel_rgn_init (&dest_rgn, curl_layer, 0, 0, true_sel_width, true_sel_height, TRUE, TRUE); /* Init shade_under */ gimp_vector2_set (&dl, -sel_width, -sel_height); dl_mag = gimp_vector2_length (&dl); gimp_vector2_set (&dr, -(sel_width - right_tangent.x), -(sel_height - right_tangent.y)); dr_mag = gimp_vector2_length (&dr); alpha = acos (gimp_vector2_inner_product (&dl, &dr) / (dl_mag * dr_mag)); /* Init shade_curl */ fore_grayval = GIMP_RGB_LUMINANCE (fore_color[0], fore_color[1], fore_color[2]) + 0.5; back_grayval = GIMP_RGB_LUMINANCE (back_color[0], back_color[1], back_color[2]) + 0.5; /* Gradient Samples */ switch (curl.colors) { case CURL_COLORS_FG_BG: break; case CURL_COLORS_GRADIENT: grad_samples = get_gradient_samples (curl_layer->drawable_id, FALSE); break; case CURL_COLORS_GRADIENT_REVERSE: grad_samples = get_gradient_samples (curl_layer->drawable_id, TRUE); break; } max_progress = 2 * sel_width * sel_height; progress = 0; alpha_pos = dest_rgn.bpp - 1; /* Main loop */ for (pr = gimp_pixel_rgns_register (1, &dest_rgn); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { dest = dest_rgn.data; for (y1 = dest_rgn.y; y1 < dest_rgn.y + dest_rgn.h; y1++) { pp = dest; for (x1 = dest_rgn.x; x1 < dest_rgn.x + dest_rgn.w; x1++) { /* Map coordinates to get the curl correct... */ switch (curl.orientation) { case CURL_ORIENTATION_VERTICAL: x = CURL_EDGE_RIGHT (curl.edge) ? x1 : sel_width - 1 - x1; y = CURL_EDGE_UPPER (curl.edge) ? y1 : sel_height - 1 - y1; break; case CURL_ORIENTATION_HORIZONTAL: x = CURL_EDGE_LOWER (curl.edge) ? y1 : sel_width - 1 - y1; y = CURL_EDGE_LEFT (curl.edge) ? x1 : sel_height - 1 - x1; break; } if (left_of_diagl (x, y)) { /* uncurled region */ for (k = 0; k <= alpha_pos; k++) pp[k] = 0; } else if (right_of_diagr (x, y) || (right_of_diagm (x, y) && below_diagb (x, y) && !inside_circle (x, y))) { /* curled region */ for (k = 0; k <= alpha_pos; k++) pp[k] = 0; } else { v.x = -(sel_width - x); v.y = -(sel_height - y); angle = acos (gimp_vector2_inner_product (&v, &dl) / (gimp_vector2_length (&v) * dl_mag)); if (inside_circle (x, y) || below_diagb (x, y)) { /* Below the curl. */ factor = angle / alpha; for (k = 0; k < alpha_pos; k++) pp[k] = 0; pp[alpha_pos] = (curl.shade ? (guchar) ((float) 255 * (float) factor) : 0); } else { /* On the curl */ switch (curl.colors) { case CURL_COLORS_FG_BG: intensity = pow (sin (G_PI * angle / alpha), 1.5); if (color_image) { pp[0] = (intensity * back_color[0] + (1.0 - intensity) * fore_color[0]); pp[1] = (intensity * back_color[1] + (1.0 - intensity) * fore_color[1]); pp[2] = (intensity * back_color[2] + (1.0 - intensity) * fore_color[2]); } else pp[0] = (intensity * back_grayval + (1 - intensity) * fore_grayval); pp[alpha_pos] = (guchar) ((double) 255.99 * (1.0 - intensity * (1.0 - curl.opacity))); break; case CURL_COLORS_GRADIENT: case CURL_COLORS_GRADIENT_REVERSE: /* Calculate position in Gradient */ intensity = (angle/alpha) + sin (G_PI*2 * angle/alpha) * 0.075; /* Check boundaries */ intensity = CLAMP (intensity, 0.0, 1.0); gradsamp = (grad_samples + ((guint) (intensity * NGRADSAMPLES)) * dest_rgn.bpp); if (color_image) { pp[0] = gradsamp[0]; pp[1] = gradsamp[1]; pp[2] = gradsamp[2]; } else pp[0] = gradsamp[0]; pp[alpha_pos] = (guchar) ((double) gradsamp[alpha_pos] * (1.0 - intensity * (1.0 - curl.opacity))); break; } } } pp += dest_rgn.bpp; } dest += dest_rgn.rowstride; } progress += dest_rgn.w * dest_rgn.h; gimp_progress_update ((double) progress / (double) max_progress); } gimp_progress_update (1.0); gimp_drawable_flush (curl_layer); gimp_drawable_merge_shadow (curl_layer->drawable_id, FALSE); gimp_drawable_update (curl_layer->drawable_id, 0, 0, curl_layer->width, curl_layer->height); gimp_drawable_detach (curl_layer); g_free (grad_samples); return curl_layer_id; }
static void blur (GimpDrawable *drawable) { gint i, ii, channels; gint x1, y1, x2, y2; GimpPixelRgn rgn_in, rgn_out; guchar **row; guchar *outrow; gint width, height; gimp_progress_init ("My Blur..."); /* Gets upper left and lower right coordinates, * and layers number in the image */ gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); width = x2 - x1; height = y2 - y1; channels = gimp_drawable_bpp (drawable->drawable_id); /* Allocate a big enough tile cache */ gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); /* Initialises two PixelRgns, one to read original data, * and the other to write output data. That second one will * be merged at the end by the call to * gimp_drawable_merge_shadow() */ gimp_pixel_rgn_init (&rgn_in, drawable, x1, y1, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&rgn_out, drawable, x1, y1, width, height, TRUE, TRUE); /* Allocate memory for input and output tile rows */ init_mem (&row, &outrow, width * channels); for (ii = -radius; ii <= radius; ii++) { gimp_pixel_rgn_get_row (&rgn_in, row[radius + ii], x1, y1 + CLAMP (ii, 0, height - 1), width); } for (i = 0; i < height; i++) { /* To be done for each tile row */ process_row (row, outrow, x1, y1, width, height, channels, i); gimp_pixel_rgn_set_row (&rgn_out, outrow, x1, i + y1, width); /* shift tile rows to insert the new one at the end */ shuffle (&rgn_in, row, x1, y1, width, height, i); if (i % 10 == 0) gimp_progress_update ((gdouble) i / (gdouble) height); } /* We could also put that in a separate function but it's * rather simple */ for (ii = 0; ii < 2 * radius + 1; ii++) g_free (row[ii]); g_free (row); g_free (outrow); /* Update the modified region */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, width, height); }
static void value_propagate_body (GimpDrawable *drawable, GimpPreview *preview) { GimpImageType dtype; ModeParam operation; GimpPixelRgn srcRgn, destRgn; guchar *here, *best, *dest; guchar *dest_row, *prev_row, *cur_row, *next_row; guchar *pr, *cr, *nr, *swap; gint width, height, bytes, index; gint begx, begy, endx, endy, x, y, dx; gint left_index, right_index, up_index, down_index; gpointer tmp; GimpRGB foreground; /* calculate neighbors' indexes */ left_index = (vpvals.direction_mask & (1 << Left2Right)) ? -1 : 0; right_index = (vpvals.direction_mask & (1 << Right2Left)) ? 1 : 0; up_index = (vpvals.direction_mask & (1 << Top2Bottom)) ? -1 : 0; down_index = (vpvals.direction_mask & (1 << Bottom2Top)) ? 1 : 0; operation = modes[vpvals.propagate_mode]; tmp = NULL; dtype = gimp_drawable_type (drawable->drawable_id); bytes = drawable->bpp; /* Here I use the algorithm of blur.c */ if (preview) { gimp_preview_get_position (preview, &begx, &begy); gimp_preview_get_size (preview, &width, &height); endx = begx + width; endy = begy + height; } else { if (! gimp_drawable_mask_intersect (drawable->drawable_id, &begx, &begy, &width, &height)) return; endx = begx + width; endy = begy + height; } gimp_tile_cache_ntiles (2 * ((width) / gimp_tile_width () + 1)); prev_row = g_new (guchar, (width + 2) * bytes); cur_row = g_new (guchar, (width + 2) * bytes); next_row = g_new (guchar, (width + 2) * bytes); dest_row = g_new (guchar, width * bytes); gimp_pixel_rgn_init (&srcRgn, drawable, begx, begy, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&destRgn, drawable, begx, begy, width, height, (preview == NULL), TRUE); pr = prev_row + bytes; cr = cur_row + bytes; nr = next_row + bytes; prepare_row (&srcRgn, pr, begx, (0 < begy) ? begy : begy - 1, endx-begx); prepare_row (&srcRgn, cr, begx, begy, endx-begx); best = g_new (guchar, bytes); if (!preview) gimp_progress_init (_("Value Propagate")); gimp_context_get_foreground (&foreground); gimp_rgb_get_uchar (&foreground, fore+0, fore+1, fore+2); /* start real job */ for (y = begy ; y < endy ; y++) { prepare_row (&srcRgn, nr, begx, ((y+1) < endy) ? y+1 : endy, endx-begx); for (index = 0; index < (endx - begx) * bytes; index++) dest_row[index] = cr[index]; for (x = 0 ; x < endx - begx; x++) { dest = dest_row + (x * bytes); here = cr + (x * bytes); /* *** copy source value to best value holder *** */ memcpy (best, here, bytes); if (operation.initializer) (* operation.initializer)(dtype, bytes, best, here, &tmp); /* *** gather neighbors' values: loop-unfolded version *** */ if (up_index == -1) for (dx = left_index ; dx <= right_index ; dx++) (* operation.updater)(dtype, bytes, here, pr+((x+dx)*bytes), best, tmp); for (dx = left_index ; dx <= right_index ; dx++) if (dx != 0) (* operation.updater)(dtype, bytes, here, cr+((x+dx)*bytes), best, tmp); if (down_index == 1) for (dx = left_index ; dx <= right_index ; dx++) (* operation.updater)(dtype, bytes, here, nr+((x+dx)*bytes), best, tmp); /* *** store it to dest_row*** */ (* operation.finalizer)(dtype, bytes, best, here, dest, tmp); } /* now store destline to destRgn */ gimp_pixel_rgn_set_row (&destRgn, dest_row, begx, y, endx - begx); /* shift the row pointers */ swap = pr; pr = cr; cr = nr; nr = swap; if (((y % 16) == 0) && !preview) gimp_progress_update ((gdouble) y / (gdouble) (endy - begy)); } if (preview) { gimp_drawable_preview_draw_region (GIMP_DRAWABLE_PREVIEW (preview), &destRgn); } else { /* update the region */ gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, begx, begy, endx-begx, endy-begy); } }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpDrawable *drawable; GimpRunMode run_mode; #ifdef TIMER GTimer *timer = g_timer_new (); #endif run_mode = param[0].data.d_int32; *return_vals = values; *nreturn_vals = 1; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; INIT_I18N (); /* * Get drawable information... */ drawable = gimp_drawable_get (param[2].data.d_drawable); gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data ("plug_in_colour2grey-local-"PLUG_IN_VERSION, &c2g_params); /* Reset default values show preview unmodified */ /* initialize pixel regions and buffer */ if (! c2g_mask_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 6) { status = GIMP_PDB_CALLING_ERROR; } else { c2g_params.radius = param[3].data.d_float; c2g_params.amount = param[4].data.d_float; c2g_params.gamma = param[5].data.d_float; /* make sure there are legal values */ if ((c2g_params.radius < 0.0) || (c2g_params.amount < 0.0)) status = GIMP_PDB_CALLING_ERROR; } break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data ("plug_in_colour2grey-local-"PLUG_IN_VERSION, &c2g_params); break; default: break; } if (status ==GIMP_PDB_SUCCESS) { drawable = gimp_drawable_get (param[2].data.d_drawable); /* here we go */ c2g_mask (drawable, c2g_params.radius, c2g_params.amount, c2g_params.gamma); gimp_displays_flush (); /* set data for next use of filter */ gimp_set_data ("plug_in_c2g_mask2-"PLUG_IN_VERSION, &c2g_params, sizeof (C2gMaskParams)); gimp_drawable_detach(drawable); values[0].data.d_status = status; } #ifdef TIMER g_printerr ("%f seconds\n", g_timer_elapsed (timer, NULL)); g_timer_destroy (timer); #endif }
static void run (const gchar *name, /* name of plugin */ gint nparams, /* number of in-paramters */ const GimpParam * param, /* in-parameters */ gint *nreturn_vals, /* number of out-parameters */ GimpParam ** return_vals) /* out-parameters */ { const gchar *l_env; gint32 image_id = -1; gboolean doProgress; gboolean doFlush; GapLastvalAnimatedCallInfo animCallInfo; /* Get the runmode from the in-parameters */ GimpRunMode run_mode = param[0].data.d_int32; /* status variable, use it to check for errors in invocation usualy only during non-interactive calling */ GimpPDBStatusType status = GIMP_PDB_SUCCESS; /* always return at least the status to the caller. */ static GimpParam values[2]; INIT_I18N(); l_env = g_getenv("GAP_DEBUG"); if(l_env != NULL) { if((*l_env != 'n') && (*l_env != 'N')) gap_debug = 1; } if(gap_debug) { printf("\n\nDEBUG: run %s\n", name); } if(strcmp(name, GAP_DETAIL_TRACKING_XML_ALIGNER_PLUG_IN_NAME) == 0) { runXmlAlign(name, nparams, param, nreturn_vals, return_vals); return; } if(strcmp(name, GAP_EXACT_ALIGNER_PLUG_IN_NAME) == 0) { runExactAlign(name, nparams, param, nreturn_vals, return_vals); return; } doProgress = FALSE; doFlush = FALSE; /* initialize the return of the status */ values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; values[1].type = GIMP_PDB_DRAWABLE; values[1].data.d_drawable = -1; *nreturn_vals = 2; *return_vals = values; /* init default values and Possibly retrieve data from a previous interactive run */ gap_detail_tracking_get_values(&fiVals); /* get image and drawable */ image_id = param[1].data.d_int32; /* how are we running today? */ switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* detail tracking primary feature is intended to work without dialog interaction * when ivoked by menu or keyboard shortcut using PLUG_IN_NAME. * This plug in also registers with a 2nd variant PLUG_IN_NAME_CFG * where the user can configure the options (for one gimp session) */ if(strcmp(name, PLUG_IN_NAME_CFG) ==0) { gboolean dialogOk; if (fiVals.coordsRelToFrame1) { /* default offsets for handle at center */ fiVals.offsX = gimp_image_width(image_id) / 2.0; fiVals.offsY = gimp_image_height(image_id) / 2.0; } dialogOk = gap_detail_tracking_dialog(&fiVals); if( dialogOk != TRUE) { status = GIMP_PDB_CALLING_ERROR; } } doProgress = TRUE; doFlush = TRUE; break; case GIMP_RUN_NONINTERACTIVE: /* check to see if invoked with the correct number of parameters */ if (nparams == global_number_in_args) { fiVals.refShapeRadius = param[3].data.d_int32; fiVals.targetMoveRadius = param[4].data.d_int32; fiVals.loacteColodiffThreshold = param[5].data.d_float; fiVals.coordsRelToFrame1 = (param[6].data.d_int32 == 0) ? FALSE : TRUE; fiVals.offsX = param[7].data.d_int32; fiVals.offsY = param[8].data.d_int32; fiVals.offsRotate = param[9].data.d_float; fiVals.enableScaling = (param[10].data.d_int32 == 0) ? FALSE : TRUE; fiVals.bgLayerIsReference = (param[11].data.d_int32 == 0) ? FALSE : TRUE; fiVals.removeMidlayers = (param[12].data.d_int32 == 0) ? FALSE : TRUE; fiVals.moveLogFile[0] = '\0'; if(param[13].data.d_string != NULL) { g_snprintf(fiVals.moveLogFile, sizeof(fiVals.moveLogFile) -1, "%s", param[13].data.d_string); } } else { status = GIMP_PDB_CALLING_ERROR; } break; case GIMP_RUN_WITH_LAST_VALS: animCallInfo.animatedCallInProgress = FALSE; gimp_get_data(GAP_LASTVAL_KEY_ANIMATED_CALL_INFO, &animCallInfo); if(animCallInfo.animatedCallInProgress != TRUE) { doProgress = TRUE; doFlush = TRUE; } break; default: break; } if (status == GIMP_PDB_SUCCESS) { gulong cache_ntiles; gulong regionTileWidth; gulong regionTileHeight; gimp_image_undo_group_start (image_id); /* this plug in repeatedly accesses the same tiles in the same pixel regionsarea * therefore tile caching is essential for performance reason * therefore calculate optimal tile cache size (but limit to 300 tiles that should be enogh * in most practical use cases) */ regionTileWidth = 1 + (2 * (fiVals.targetMoveRadius + fiVals.refShapeRadius))/ gimp_tile_width() ; regionTileHeight = 1 + (2 * (fiVals.targetMoveRadius + fiVals.refShapeRadius))/ gimp_tile_height() ; /* processing may track 2 details in different regions of same size */ cache_ntiles = (regionTileWidth * regionTileHeight) * 2; gimp_tile_cache_ntiles (MAX(300, cache_ntiles)); /* Run the main function */ values[1].data.d_drawable = gap_track_detail_on_top_layers(image_id, doProgress, &fiVals); gimp_image_undo_group_end (image_id); if (values[1].data.d_drawable < 0) { status = GIMP_PDB_CALLING_ERROR; } /* If run mode is interactive, flush displays, else (script) don't * do it, as the screen updates would make the scripts slow */ if (doFlush) { gimp_displays_flush (); } } values[0].data.d_status = status; } /* end run */
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 run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; gint32 image_ID; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; INIT_I18N (); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; /* Get the specified image and drawable */ image_ID = param[1].data.d_image; drawable = gimp_drawable_get (param[2].data.d_drawable); /* set the tile cache size so that the gaussian blur works well */ gimp_tile_cache_ntiles (2 * (MAX (drawable->width, drawable->height) / gimp_tile_width () + 1)); if (strcmp (name, PLUG_IN_PROC) == 0) { switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &dogvals); /* First acquire information with a dialog */ if (! dog_dialog (image_ID, drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 7) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { dogvals.inner = param[3].data.d_float; dogvals.outer = param[4].data.d_float; dogvals.normalize = param[5].data.d_int32; dogvals.invert = param[6].data.d_int32; } if (status == GIMP_PDB_SUCCESS && (dogvals.inner <= 0.0 && dogvals.outer <= 0.0)) status = GIMP_PDB_CALLING_ERROR; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &dogvals); break; default: break; } } else { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { /* Make sure that the drawable is gray or RGB color */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init (_("DoG Edge Detect")); /* run the Difference of Gaussians */ gimp_image_undo_group_start (image_ID); dog (image_ID, drawable, dogvals.inner, dogvals.outer, TRUE); gimp_image_undo_group_end (image_ID); gimp_progress_update (1.0); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &dogvals, sizeof (DoGValues)); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } else { g_message (_("Cannot operate on indexed color images.")); status = GIMP_PDB_EXECUTION_ERROR; } gimp_drawable_detach (drawable); } values[0].data.d_status = status; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpRunMode run_mode; INIT_I18N (); 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; /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); /* See how we will run */ switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &wvals); /* Get information from the dialog */ if (!alienmap2_dialog ()) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are present */ if (nparams != 13) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { wvals.redfrequency = param[3].data.d_float; wvals.redangle = param[4].data.d_float; wvals.greenfrequency = param[5].data.d_float; wvals.greenangle = param[6].data.d_float; wvals.bluefrequency = param[7].data.d_float; wvals.blueangle = param[8].data.d_float; wvals.colormodel = param[9].data.d_int8; wvals.redmode = param[10].data.d_int8 ? TRUE : FALSE; wvals.greenmode = param[11].data.d_int8 ? TRUE : FALSE; wvals.bluemode = param[12].data.d_int8 ? TRUE : FALSE; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &wvals); break; default: break; } if (status == GIMP_PDB_SUCCESS) { /* Make sure that the drawable is RGB or RGBA */ if (gimp_drawable_is_rgb (drawable->drawable_id)) { gimp_progress_init (_("Alien Map: Transforming")); /* Set the tile cache size */ gimp_tile_cache_ntiles (2 * (drawable->width / gimp_tile_width () + 1)); /* Run! */ alienmap2 (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &wvals, sizeof (alienmap2_vals_t)); } else { /* gimp_message("This filter only applies on RGB_MODEL-images"); */ status = GIMP_PDB_EXECUTION_ERROR; } } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; INIT_I18N (); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; /* Set default values */ /* ================== */ set_default_settings (); /* Possibly retrieve data */ /* ====================== */ gimp_get_data (PLUG_IN_PROC, &licvals); /* Get the specified drawable */ /* ========================== */ drawable = gimp_drawable_get (param[2].data.d_drawable); if (status == GIMP_PDB_SUCCESS) { /* Make sure that the drawable is RGBA or RGB color */ /* ================================================ */ if (gimp_drawable_is_rgb (drawable->drawable_id)) { /* Set the tile cache size */ /* ======================= */ gimp_tile_cache_ntiles (2*(drawable->width / gimp_tile_width () + 1)); switch (run_mode) { case GIMP_RUN_INTERACTIVE: if (create_main_dialog ()) compute_image (drawable); gimp_set_data (PLUG_IN_PROC, &licvals, sizeof (LicValues)); break; case GIMP_RUN_WITH_LAST_VALS: compute_image (drawable); break; default: break; } } else status = GIMP_PDB_EXECUTION_ERROR; } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; gint sel_x1, sel_y1, sel_x2, sel_y2; gint img_height, img_width, img_bpp, img_has_alpha; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status; *nreturn_vals = 1; *return_vals = values; status = GIMP_PDB_SUCCESS; if (param[0].type != GIMP_PDB_INT32) status = GIMP_PDB_CALLING_ERROR; run_mode = param[0].data.d_int32; INIT_I18N (); if (param[2].type != GIMP_PDB_DRAWABLE) status = GIMP_PDB_CALLING_ERROR; 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_bpp = gimp_drawable_bpp (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); if (!gimp_drawable_is_rgb (drawable->drawable_id)) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { gr = g_rand_new (); memset (&qbist_info, 0, sizeof (qbist_info)); create_info (&qbist_info.info); qbist_info.oversampling = 4; switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &qbist_info); /* Get information from the dialog */ if (dialog_run ()) { status = GIMP_PDB_SUCCESS; gimp_set_data (PLUG_IN_PROC, &qbist_info, sizeof (QbistInfo)); } else status = GIMP_PDB_EXECUTION_ERROR; break; case GIMP_RUN_NONINTERACTIVE: status = GIMP_PDB_CALLING_ERROR; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &qbist_info); status = GIMP_PDB_SUCCESS; break; default: status = GIMP_PDB_CALLING_ERROR; break; } if (status == GIMP_PDB_SUCCESS) { GimpPixelRgn imagePR; gpointer pr; gimp_tile_cache_ntiles ((drawable->width + gimp_tile_width () - 1) / gimp_tile_width ()); gimp_pixel_rgn_init (&imagePR, drawable, 0, 0, img_width, img_height, TRUE, TRUE); optimize (&qbist_info.info); gimp_progress_init (_("Qbist")); for (pr = gimp_pixel_rgns_register (1, &imagePR); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { gint row; for (row = 0; row < imagePR.h; row++) { qbist (&qbist_info.info, imagePR.data + row * imagePR.rowstride, imagePR.x, imagePR.y + row, imagePR.w, sel_x2 - sel_x1, sel_y2 - sel_y1, imagePR.bpp, qbist_info.oversampling); } gimp_progress_update ((gfloat) (imagePR.y - sel_y1) / (gfloat) (sel_y2 - sel_y1)); } gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, sel_x1, sel_y1, (sel_x2 - sel_x1), (sel_y2 - sel_y1)); gimp_displays_flush (); } g_rand_free (gr); } values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gimp_drawable_detach (drawable); }