gint guess_new_size (GtkWidget * button, PreviewData * p_data, GuessDir direction) { gint32 disc_layer_ID; GimpDrawable *drawable; gint z1, z2, k; gint z1min, z1max, z2max; gint width, height; gint lw, lh; gint x_off, y_off; gint bpp, c_bpp; GimpPixelRgn rgn_in; guchar *line; gboolean has_alpha; gdouble sum; gint mask_size; gint max_mask_size = 0; gint old_size; gint new_size; disc_layer_ID = p_data->vals->disc_layer_ID; switch (direction) { case GUESS_DIR_HOR: old_size = p_data->old_width; break; case GUESS_DIR_VERT: old_size = p_data->old_height; break; default: g_message("You just found a bug"); return 0; } LAYER_CHECK_ACTION(disc_layer_ID, gtk_dialog_response (GTK_DIALOG (dlg), RESPONSE_REFRESH), old_size); width = gimp_drawable_width (disc_layer_ID); height = gimp_drawable_height (disc_layer_ID); has_alpha = gimp_drawable_has_alpha (disc_layer_ID); bpp = gimp_drawable_bpp (disc_layer_ID); c_bpp = bpp - (has_alpha ? 1 : 0); drawable = gimp_drawable_get (disc_layer_ID); gimp_pixel_rgn_init (&rgn_in, drawable, 0, 0, width, height, FALSE, FALSE); gimp_drawable_offsets (disc_layer_ID, &x_off, &y_off); x_off -= p_data->x_off; y_off -= p_data->y_off; lw = (MIN (p_data->old_width, width + x_off) - MAX (0, x_off)); lh = (MIN (p_data->old_height, height + y_off) - MAX (0, y_off)); switch (direction) { case GUESS_DIR_HOR: z1min = MAX (0, y_off); z1max = MIN (p_data->old_height, height + y_off); z2max = lw; break; case GUESS_DIR_VERT: z1min = MAX (0, x_off); z1max = MIN (p_data->old_width, width + x_off); z2max = lh; break; default: g_message("You just found a bug"); return 0; } line = g_try_new (guchar, bpp * z2max); for (z1 = z1min; z1 < z1max; z1++) { switch (direction) { case GUESS_DIR_HOR: gimp_pixel_rgn_get_row (&rgn_in, line, MAX (0, -x_off), z1 - y_off, z2max); break; case GUESS_DIR_VERT: gimp_pixel_rgn_get_col (&rgn_in, line, z1 - x_off, MAX (0, -y_off), z2max); break; } mask_size = 0; for (z2 = 0; z2 < z2max; z2++) { sum = 0; for (k = 0; k < c_bpp; k++) { sum += line[bpp * z2 + k]; } sum /= (255 * c_bpp); if (has_alpha) { sum *= (gdouble) line[bpp * (z2 + 1) - 1] / 255; } if (sum >= (0.5 / c_bpp)) { mask_size++; } } if (mask_size > max_mask_size) { max_mask_size = mask_size; } } new_size = old_size - max_mask_size; g_free (line); gimp_drawable_detach (drawable); return new_size; }
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; gint32 image_ID; run_mode = param[0].data.d_int32; INIT_I18N (); /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); image_ID = param[1].data.d_image; switch (run_mode) { case GIMP_RUN_NONINTERACTIVE: if (nparams != 4) status = GIMP_PDB_CALLING_ERROR; else threshold = param[3].data.d_int32; break; case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &threshold); if (! dialog (image_ID, drawable)) status = GIMP_PDB_CANCEL; break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &threshold); break; default: break; } /* Make sure that the drawable is RGB color. */ if (status == GIMP_PDB_SUCCESS && gimp_drawable_is_rgb (drawable->drawable_id)) { remove_redeye (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &threshold, sizeof (threshold)); } else { 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 run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpRunMode run_mode; GimpDrawable *drawable; GimpPDBStatusType status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); /* set the tile cache size */ gimp_tile_cache_ntiles (TILE_CACHE_SIZE); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; INIT_I18N(); switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &pvals); /* First acquire information with a dialog */ if (! photocopy_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: pvals.mask_radius = param[3].data.d_float; pvals.sharpness = param[4].data.d_float; pvals.pct_black = param[5].data.d_float; pvals.pct_white = param[6].data.d_float; 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 RGB or GRAY color */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init ("Photocopy"); photocopy (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 (PhotocopyVals)); } else { status = GIMP_PDB_EXECUTION_ERROR; *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = _("Cannot operate on indexed color images."); } } 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]; 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]; GimpDrawable *drawable; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; INIT_I18N (); /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); /* set the tile cache size */ gimp_tile_cache_ntiles (TILE_CACHE_SIZE); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &rvals); /* First acquire information with a dialog */ if (! ripple_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 10) { status = GIMP_PDB_CALLING_ERROR; } else { rvals.period = param[3].data.d_int32; rvals.amplitude = param[4].data.d_int32; rvals.orientation = (param[5].data.d_int32) ? GIMP_ORIENTATION_VERTICAL : GIMP_ORIENTATION_HORIZONTAL; rvals.edges = param[6].data.d_int32; rvals.waveform = param[7].data.d_int32; rvals.antialias = (param[8].data.d_int32) ? TRUE : FALSE; rvals.tile = (param[9].data.d_int32) ? TRUE : FALSE; if (rvals.period < 1) { gimp_message ("Ripple: period must be at least 1.\n"); status = GIMP_PDB_CALLING_ERROR; } if (rvals.edges < SMEAR || rvals.edges > BLANK) status = GIMP_PDB_CALLING_ERROR; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &rvals); 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 (_("Rippling")); /* run the ripple effect */ ripple (drawable, NULL); gimp_progress_update (1.0); 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 (RippleValues)); } else { /* gimp_message ("ripple: cannot operate on indexed color images"); */ status = GIMP_PDB_EXECUTION_ERROR; } } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
static gint32 do_optimizations (GimpRunMode run_mode, gboolean diff_only) { GimpPixelRgn pixel_rgn; static guchar *rawframe = NULL; guchar *srcptr; guchar *destptr; gint row, this_frame_num; guint32 frame_sizebytes; gint32 new_layer_id; DisposeType dispose; guchar *this_frame = NULL; guchar *last_frame = NULL; guchar *opti_frame = NULL; guchar *back_frame = NULL; gint this_delay; gint cumulated_delay = 0; gint last_true_frame = -1; gint buflen; gchar *oldlayer_name; gchar *newlayer_name; gboolean can_combine; gint32 bbox_top, bbox_bottom, bbox_left, bbox_right; gint32 rbox_top, rbox_bottom, rbox_left, rbox_right; switch (opmode) { case OPUNOPTIMIZE: gimp_progress_init (_("Unoptimizing animation")); break; case OPFOREGROUND: gimp_progress_init (_("Removing animation background")); break; case OPBACKGROUND: gimp_progress_init (_("Finding animation background")); break; case OPOPTIMIZE: default: gimp_progress_init (_("Optimizing animation")); break; } width = gimp_image_width (image_id); height = gimp_image_height (image_id); layers = gimp_image_get_layers (image_id, &total_frames); imagetype = gimp_image_base_type (image_id); pixelstep = (imagetype == GIMP_RGB) ? 4 : 2; /* gimp_tile_cache_ntiles(total_frames * (width / gimp_tile_width() + 1) );*/ drawabletype_alpha = (imagetype == GIMP_RGB) ? GIMP_RGBA_IMAGE : ((imagetype == GIMP_INDEXED) ? GIMP_INDEXEDA_IMAGE : GIMP_GRAYA_IMAGE); frame_sizebytes = width * height * pixelstep; this_frame = g_malloc (frame_sizebytes); last_frame = g_malloc (frame_sizebytes); opti_frame = g_malloc (frame_sizebytes); if (opmode == OPBACKGROUND || opmode == OPFOREGROUND) back_frame = g_malloc (frame_sizebytes); total_alpha (this_frame, width*height, pixelstep); total_alpha (last_frame, width*height, pixelstep); new_image_id = gimp_image_new(width, height, imagetype); gimp_image_undo_disable (new_image_id); if (imagetype == GIMP_INDEXED) { palette = gimp_image_get_colormap (image_id, &ncolours); gimp_image_set_colormap (new_image_id, palette, ncolours); } #if 1 if (opmode == OPBACKGROUND || opmode == OPFOREGROUND) { /* iterate through all rows of all frames, find statistical mode for each pixel position. */ gint i,j; guchar **these_rows; guchar **red; guchar **green; guchar **blue; guint **count; guint *num_colours; these_rows = g_new (guchar *, total_frames); red = g_new (guchar *, total_frames); green = g_new (guchar *, total_frames); blue = g_new (guchar *, total_frames); count = g_new (guint *, total_frames); num_colours = g_new (guint, width); for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { these_rows[this_frame_num] = g_malloc(width * pixelstep); red[this_frame_num] = g_new (guchar, width); green[this_frame_num] = g_new (guchar, width); blue[this_frame_num] = g_new (guchar, width); count[this_frame_num] = g_new0(guint, width); } for (row = 0; row < height; row++) { memset(num_colours, 0, width * sizeof(guint)); for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { drawable = gimp_drawable_get (layers[total_frames-(this_frame_num+1)]); dispose = get_frame_disposal (this_frame_num); compose_row(this_frame_num, dispose, row, these_rows[this_frame_num], width, drawable, FALSE ); gimp_drawable_detach(drawable); } for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { for (i=0; i<width; i++) { if (these_rows[this_frame_num][i * pixelstep + pixelstep -1] >= 128) { for (j=0; j<num_colours[i]; j++) { switch (pixelstep) { case 4: if (these_rows[this_frame_num][i * 4 +0] == red[j][i] && these_rows[this_frame_num][i * 4 +1] == green[j][i] && these_rows[this_frame_num][i * 4 +2] == blue[j][i]) { (count[j][i])++; goto same; } break; case 2: if (these_rows[this_frame_num][i * 2 +0] == red[j][i]) { (count[j][i])++; goto same; } break; default: g_error ("Eeep!"); break; } } count[num_colours[i]][i] = 1; red[num_colours[i]][i] = these_rows[this_frame_num][i * pixelstep]; if (pixelstep == 4) { green[num_colours[i]][i] = these_rows[this_frame_num][i * 4 +1]; blue[num_colours[i]][i] = these_rows[this_frame_num][i * 4 +2]; } num_colours[i]++; } same: /* nop */; } } for (i=0; i<width; i++) { guint best_count = 0; guchar best_r = 255, best_g = 0, best_b = 255; for (j=0; j<num_colours[i]; j++) { if (count[j][i] > best_count) { best_count = count[j][i]; best_r = red[j][i]; best_g = green[j][i]; best_b = blue[j][i]; } } back_frame[width * pixelstep * row +i*pixelstep + 0] = best_r; if (pixelstep == 4) { back_frame[width * pixelstep * row +i*pixelstep + 1] = best_g; back_frame[width * pixelstep * row +i*pixelstep + 2] = best_b; } back_frame[width * pixelstep * row +i*pixelstep +pixelstep-1] = (best_count == 0) ? 0 : 255; if (best_count == 0) g_warning("yayyyy!"); } /* memcpy(&back_frame[width * pixelstep * row], these_rows[0], width * pixelstep);*/ } for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { g_free (these_rows[this_frame_num]); g_free (red[this_frame_num]); g_free (green[this_frame_num]); g_free (blue[this_frame_num]); g_free (count[this_frame_num]); } g_free (these_rows); g_free (red); g_free (green); g_free (blue); g_free (count); g_free (num_colours); }
/* do the analyzing */ static void analyze (GimpDrawable *drawable) { GimpPixelRgn srcPR; guchar *src_row, *cmap; gint x, y, numcol; gint x1, y1, x2, y2, w, h; guchar r, g, b; gint a; guchar idx; gboolean gray; gboolean has_alpha; gboolean has_sel; guchar *sel; GimpPixelRgn selPR; gint ofsx, ofsy; GimpDrawable *selDrawable; gimp_progress_init (_("Colorcube Analysis")); if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x1, &y1, &w, &h)) return; x2 = x1 + w; y2 = y1 + h; /* * Get the size of the input image (this will/must be the same * as the size of the output image). */ width = drawable->width; height = drawable->height; bpp = drawable->bpp; has_sel = !gimp_selection_is_empty (imageID); gimp_drawable_offsets (drawable->drawable_id, &ofsx, &ofsy); /* initialize the pixel region */ gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); cmap = gimp_image_get_colormap (imageID, &numcol); gray = (gimp_drawable_is_gray (drawable->drawable_id) || gimp_item_is_channel (drawable->drawable_id)); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); selDrawable = gimp_drawable_get (gimp_image_get_selection (imageID)); gimp_pixel_rgn_init (&selPR, selDrawable, 0, 0, width, height, FALSE, FALSE); /* allocate row buffer */ src_row = g_new (guchar, (x2 - x1) * bpp); sel = g_new (guchar, x2 - x1); for (y = y1; y < y2; y++) { gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y, (x2 - x1)); if (has_sel) gimp_pixel_rgn_get_row (&selPR, sel, x1 + ofsx, y + ofsy, (x2 - x1)); for (x = 0; x < w; x++) { /* Start with full opacity. */ a = 255; /* * If the image is indexed, fetch RGB values * from colormap. */ if (cmap) { idx = src_row[x * bpp]; r = cmap[idx * 3]; g = cmap[idx * 3 + 1]; b = cmap[idx * 3 + 2]; if (has_alpha) a = src_row[x * bpp + 1]; } else if (gray) { r = g = b = src_row[x * bpp]; if (has_alpha) a = src_row[x * bpp + 1]; } else { r = src_row[x * bpp]; g = src_row[x * bpp + 1]; b = src_row[x * bpp + 2]; if (has_alpha) a = src_row[x * bpp + 3]; } if (has_sel) a *= sel[x]; else a *= 255; if (a != 0) insertcolor (r, g, b, (gdouble) a * (1.0 / (255.0 * 255.0))); } /* tell the user what we're doing */ if ((y % 10) == 0) gimp_progress_update ((gdouble) y / (gdouble) (y2 - y1)); } gimp_progress_update (1.0); /* clean up */ gimp_drawable_detach (selDrawable); g_free (src_row); g_free (sel); }
void destroy() { g_free(interface_vals.previewImage); g_free(interface_vals.previewMask); if (interface_vals.mask_drawable != NULL) gimp_drawable_detach(interface_vals.mask_drawable); if (interface_vals.image_drawable != NULL) gimp_drawable_detach(interface_vals.image_drawable); }
/* --------------------------------- * gap_edgeDetectionByBlurDiff * --------------------------------- */ gint32 gap_edgeDetectionByBlurDiff(gint32 activeDrawableId, gdouble blurRadius, gdouble blurResultRadius , gdouble threshold, gint32 shift, gboolean doLevelsAutostretch , gboolean invert) { gint32 blurLayerId; gint32 edgeLayerId; gint32 imageId; GimpDrawable *edgeDrawable; GimpDrawable *refDrawable; GimpDrawable *blurDrawable; imageId = gimp_drawable_get_image(activeDrawableId); edgeLayerId = gimp_layer_copy(activeDrawableId); gimp_image_add_layer (imageId, edgeLayerId, 0 /* stackposition */ ); edgeDrawable = gimp_drawable_get(edgeLayerId); refDrawable = gimp_drawable_get(activeDrawableId); if(blurRadius > 0.0) { p_call_plug_in_gauss_iir2(imageId, edgeLayerId, blurRadius, blurRadius); } blurDrawable = NULL; // blurLayerId = gimp_layer_copy(edgeLayerId); // gimp_image_add_layer (imageId, blurLayerId, 0 /* stackposition */ ); // blurDrawable = gimp_drawable_get(blurLayerId); p_subtract_ref_layer(imageId, edgeDrawable, refDrawable, threshold, shift, invert); //p_subtract_ref_layer(imageId, edgeDrawable, blurDrawable, threshold, shift, invert); if (doLevelsAutostretch) { gimp_levels_stretch(edgeLayerId); } if(blurResultRadius > 0.0) { p_call_plug_in_gauss_iir2(imageId, edgeLayerId, blurResultRadius, blurResultRadius); } if(refDrawable) { gimp_drawable_detach(refDrawable); } if(edgeDrawable) { gimp_drawable_detach(edgeDrawable); } if(blurDrawable) { gimp_drawable_detach(blurDrawable); } return (edgeLayerId); } /* end gap_edgeDetectionByBlurDiff */
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); }
/* ---------------------------------------- * gap_edgeDetection * ---------------------------------------- * * returns the drawable id of a newly created channel * representing edges of the specified image. * * black pixels indicate areas of same or similar colors, * white indicates sharp edges. * */ gint32 gap_edgeDetection(gint32 refDrawableId , gdouble edgeColordiffThreshold , gint32 *countEdgePixels ) { GapEdgeContext edgeContext; GapEdgeContext *ectx; gdouble edgeOpacityThreshold; /* init context */ ectx = &edgeContext; ectx->refDrawable = gimp_drawable_get(refDrawableId); ectx->edgeDrawable = NULL; ectx->edgeColordiffThreshold = CLAMP(edgeColordiffThreshold, 0.0, 1.0); edgeOpacityThreshold = CLAMP((edgeColordiffThreshold * 255), 0, 255); ectx->edgeOpacityThreshold255 = edgeOpacityThreshold; ectx->edgeDrawableId = -1; ectx->countEdgePixels = 0; if(gap_debug) { printf("gap_edgeDetection START edgeColordiffThreshold:%.5f refDrawableId:%d\n" , (float)ectx->edgeColordiffThreshold , (int)refDrawableId ); } if(ectx->refDrawable != NULL) { ectx->pftRef = gimp_pixel_fetcher_new (ectx->refDrawable, FALSE /* shadow */); gimp_pixel_fetcher_set_edge_mode (ectx->pftRef, GIMP_PIXEL_FETCHER_EDGE_BLACK); p_edgeDetection(ectx); gimp_pixel_fetcher_destroy (ectx->pftRef); } if(ectx->refDrawable != NULL) { gimp_drawable_detach(ectx->refDrawable); ectx->refDrawable = NULL; } if(ectx->edgeDrawable != NULL) { gimp_drawable_detach(ectx->edgeDrawable); ectx->edgeDrawable = NULL; } *countEdgePixels = ectx->countEdgePixels; if(gap_debug) { printf("gap_edgeDetection END resulting edgeDrawableId:%d countEdgePixels:%d\n" , (int)ectx->edgeDrawableId , (int)*countEdgePixels ); } return (ectx->edgeDrawableId); } /* end gap_edgeDetection */
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 void run ( const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[3]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; SeparateContext mysc; //enum separate_function func = SEP_NONE; run_mode = param[0].data.d_int32; /* setup for localization */ INIT_I18N (); cmsErrorAction( LCMS_ERROR_IGNORE ); mysc.filename = NULL; if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) ) status = GIMP_PDB_CALLING_ERROR; else if( run_mode == GIMP_RUN_NONINTERACTIVE ) { if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 ) status = GIMP_PDB_CALLING_ERROR; else mysc.filename = g_strdup( param[1].data.d_string ); } else { gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" ); if( size ) { mysc.filename = g_malloc( size ); gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename ); } } if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) { gint i, j, x, y; TIFF *in; guint32 width, height, stripSize, stripCount, stripHeight; gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit; float xres, yres; const gchar *layerNames[] = { "C", "M", "Y", "K" }; guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile; gint32 layers[5], masks[4]; GimpDrawable *drw[4]; GimpPixelRgn rgn[4]; GimpRGB primaries[4] = { { .180, .541, .870, 1.0 }, { .925, .149, .388, 1.0 }, { .929, .862, .129, 1.0 }, { 0, 0, 0, 1.0 } }; gchar *str = NULL; gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) ); #ifdef G_OS_WIN32 { gchar *_filename = NULL; // win32 filename encoding(not UTF-8) _filename = g_win32_locale_filename_from_utf8( mysc.filename ); in = TIFFOpen( _filename ? _filename : mysc.filename, "r" ); g_free( _filename ); } #else in = TIFFOpen( mysc.filename, "r" ); #endif if( !in ) { str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) || ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) || ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) || ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) || ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) { str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { stripCount = TIFFNumberOfStrips( in ); stripSize = TIFFStripSize( in ); TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width ); TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height ); TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight ); TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit ); TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres ); TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres ); #if 0 str = g_strdup_printf( "Photometric : %d BPS : %d SPP : %d\nInkset : %d StripCount : %d", photometric, bps, spp, inkset, stripCount ); gimp_message( str ); g_free( str ); #endif step = ( bps == 16 ) ? 2 : 1; buf = g_malloc( stripSize ); values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB ); gimp_image_set_resolution( values[1].data.d_image, xres, yres ); gimp_context_push(); for( i = 0; i < 4; i++ ) { layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE ); gimp_context_set_foreground( &primaries[i] ); gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[i], i ); masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK ); gimp_layer_add_mask( layers[i], masks[i] ); drw[i] = gimp_drawable_get( masks[i] ); maskbuf[i] = g_malloc( width * stripHeight ); } gimp_context_pop(); layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE ); gimp_drawable_fill( layers[4], GIMP_WHITE_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[4], 4 ); str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName ); gimp_progress_init( str ); g_free( str ); for( i = 0; i < stripCount; i++ ) { guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize ); guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight ); srcbuf = buf; if( bps == 16 ) srcbuf++; for( j = 0; j < 4; j++ ) { gimp_pixel_rgn_init( &( rgn[j] ), drw[j], 0, stripHeight * i, width, rowCount, FALSE, FALSE ); destbuf[j] = maskbuf[j]; } for( y = 0; y < rowCount; y++ ) { for( x = 0; x < width; x++ ) { *destbuf[0]++ = *srcbuf; srcbuf += step; *destbuf[1]++ = *srcbuf; srcbuf += step; *destbuf[2]++ = *srcbuf; srcbuf += step; *destbuf[3]++ = *srcbuf; srcbuf += step; //srcbuf += spp > 4 ? spp - 4 : 0; } } gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount ); gimp_progress_update( (gdouble)i / stripCount ); } g_free( buf ); for( i = 0; i < 4; i++ ) { g_free( maskbuf[i] ); gimp_drawable_detach( drw[i] ); } #ifdef ENABLE_COLOR_MANAGEMENT if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) { GimpParasite *parasite; parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile ); gimp_image_parasite_attach( values[1].data.d_image, parasite ); gimp_parasite_free( parasite ); //g_free( iccProfile ); // This causes clash on TIFFClose( in ). } #endif } TIFFClose( in ); } g_free( baseName ); } else status = GIMP_PDB_CANCEL; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; if( status == GIMP_PDB_SUCCESS ) { *nreturn_vals = 2; values[1].type = GIMP_PDB_IMAGE; if( run_mode != GIMP_RUN_NONINTERACTIVE ) { gimp_image_undo_enable( values[1].data.d_image ); gimp_display_new( values[1].data.d_image ); gimp_displays_flush(); } gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 ); } else *nreturn_vals = 1; g_free( mysc.filename ); }
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 run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { GimpPDBStatusType status; static GimpParam values[1]; GimpDrawable *drawable; GimpRunMode run_mode; INIT_I18N (); 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; drawable = gimp_drawable_get (param[2].data.d_drawable); switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &cvals); if (!colorify_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 4) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) cvals.color = param[3].data.d_color; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &cvals); break; default: break; } if (status == GIMP_PDB_SUCCESS) { gimp_progress_init (_("Colorifying")); colorify (drawable, NULL); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &cvals, sizeof (ColorifyVals)); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } 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 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 (); /* 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 */ gimp_tile_cache_ntiles (TILE_CACHE_SIZE); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &spvals); /* First acquire information with a dialog */ if (! spread_dialog (image_ID, drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 5) { status = GIMP_PDB_CALLING_ERROR; } else { spvals.spread_amount_x= param[3].data.d_float; spvals.spread_amount_y = param[4].data.d_float; } if ((status == GIMP_PDB_SUCCESS) && (spvals.spread_amount_x < 0 || spvals.spread_amount_x > 200) && (spvals.spread_amount_y < 0 || spvals.spread_amount_y > 200)) status = GIMP_PDB_CALLING_ERROR; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &spvals); 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 (_("Spreading")); /* run the spread effect */ spread (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &spvals, sizeof (SpreadValues)); } else { /* gimp_message ("spread: cannot operate on indexed color images"); */ status = GIMP_PDB_EXECUTION_ERROR; } } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
/* 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 n_params, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable = NULL; gint32 image_ID; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint nDlgResponse = -5; init_drawables(); *nreturn_vals = 1; *return_vals = values; /* Initialize i18n support */ bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); #ifdef HAVE_BIND_TEXTDOMAIN_CODESET bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif textdomain (GETTEXT_PACKAGE); run_mode = param[0].data.d_int32; image_ID = param[1].data.d_int32; drawable = gimp_drawable_get (param[2].data.d_drawable); gimp_tile_cache_ntiles (2 * drawable->ntile_cols); /* Initialize with default values */ copyPlugInVals(&default_vals, &vals); vals.image_ID = image_ID; if (strcmp (name, PLUG_IN_PROC) == 0) { switch (run_mode) { case GIMP_RUN_NONINTERACTIVE: if (n_params != 16) { status = GIMP_PDB_CALLING_ERROR; } else { vals.RemoveLighting = param[3].data.d_int32; vals.Resizie = param[4].data.d_int32; vals.Tile = param[5].data.d_int32; vals.newWidth = param[6].data.d_int32; vals.EdgeSpecular = param[7].data.d_int32; vals.defSpecular = param[8].data.d_int32; vals.Depth = param[9].data.d_float; vals.LargeDetails = param[10].data.d_int32; vals.MediumDetails = param[11].data.d_int32; vals.SmallDetails = param[12].data.d_int32; vals.ShapeRecog = param[13].data.d_int32; vals.smoothstep = param[14].data.d_int32; vals.Noise = param[15].data.d_int32; vals.invh = param[16].data.d_int32; vals.ao = param[17].data.d_int32; vals.prev = param[18].data.d_int32; } break; case GIMP_RUN_INTERACTIVE: gimp_ui_init(PLUG_IN_BINARY, 0); /* Possibly retrieve data */ gimp_get_data (DATA_KEY_VALS, &vals); nDlgResponse = InsaneBumpDialog(drawable, PLUG_IN_BINARY, &vals); switch(nDlgResponse) { case 0: status = GIMP_PDB_EXECUTION_ERROR; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gimp_drawable_detach(drawable); return; case 1: gimp_set_data(DATA_KEY_VALS, &vals, sizeof(vals)); default: values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; gimp_drawable_detach(drawable); gimp_displays_flush(); return; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (DATA_KEY_VALS, &vals); break; default: break; } } else { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { render(image_ID, &vals); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); if (run_mode == GIMP_RUN_INTERACTIVE) { gimp_set_data(DATA_KEY_VALS, &vals, sizeof (vals)); } gimp_drawable_detach (drawable); } values[0].type = GIMP_PDB_STATUS; 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]; GimpRunMode run_mode; GimpPDBStatusType status; GimpDrawable *drawable; gint x1, y1, x2, y2; INIT_I18N (); status = GIMP_PDB_SUCCESS; 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 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_bpp = gimp_drawable_bpp (drawable->drawable_id); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); mbvals.center_x = (gdouble) (x1 + x2 - 1) / 2.0; mbvals.center_y = (gdouble) (y1 + y2 - 1) / 2.0; /* Set the tile cache size */ gimp_tile_cache_ntiles (2 * drawable->ntile_cols); switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &mbvals); /* Get information from the dialog */ if (! mblur_dialog (param[1].data.d_image, drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: if (strcmp (name, PLUG_IN_PROC_INWARD) == 0) mbvals.blur_outward = FALSE; if (nparams == 8) { mbvals.center_x = param[6].data.d_float; mbvals.center_y = param[7].data.d_float; } else if (nparams != 6) { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { mbvals.mblur_type = param[3].data.d_int32; mbvals.length = param[4].data.d_int32; mbvals.angle = param[5].data.d_int32; } if ((mbvals.mblur_type < 0) || (mbvals.mblur_type > MBLUR_MAX)) status= GIMP_PDB_CALLING_ERROR; break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &mbvals); break; default: break; } /* Blur the image */ if ((status == GIMP_PDB_SUCCESS) && (gimp_drawable_is_rgb(drawable->drawable_id) || gimp_drawable_is_gray(drawable->drawable_id))) { /* Run! */ has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); mblur (drawable, NULL); /* 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, &mbvals, sizeof (mblur_vals_t)); } else if (status == GIMP_PDB_SUCCESS) status = GIMP_PDB_EXECUTION_ERROR; values[0].data.d_status = status; gimp_drawable_detach (drawable); }
/* Create a layer with the provided image data and add it to the image */ gboolean create_layer(gint32 image_ID, uint8_t *layer_data, gint32 position, gchar *name, gint width, gint height, gint32 offsetx, gint32 offsety) { gint32 layer_ID; #ifdef GIMP_2_9 GeglBuffer *geglbuffer; GeglRectangle extent; #else GimpDrawable *drawable; GimpPixelRgn region; #endif layer_ID = gimp_layer_new(image_ID, name, width, height, GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE); #ifdef GIMP_2_9 /* Retrieve the buffer for the layer */ geglbuffer = gimp_drawable_get_buffer(layer_ID); /* Copy the image data to the region */ gegl_rectangle_set(&extent, 0, 0, width, height); gegl_buffer_set(geglbuffer, &extent, 0, NULL, layer_data, GEGL_AUTO_ROWSTRIDE); /* Flush the drawable and detach */ gegl_buffer_flush(geglbuffer); g_object_unref(geglbuffer); #else /* Retrieve the drawable for the layer */ drawable = gimp_drawable_get(layer_ID); /* Get a pixel region from the layer */ gimp_pixel_rgn_init(®ion, drawable, 0, 0, width, height, FALSE, FALSE); /* Copy the image data to the region */ gimp_pixel_rgn_set_rect(®ion, layer_data, 0, 0, width, height); /* Flush the drawable and detach */ gimp_drawable_flush(drawable); gimp_drawable_detach(drawable); #endif /* Add the new layer to the image */ gimp_image_insert_layer(image_ID, layer_ID, -1, position); /* If layer offsets were provided, use them to position the image */ if (offsetx || offsety) { gimp_layer_set_offsets(layer_ID, offsetx, offsety); } /* TODO: fix this */ return TRUE; }
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, 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; run_mode = param[0].data.d_int32; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; image_ID = param[1].data.d_image; drawable = gimp_drawable_get (param[2].data.d_drawable); switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &pvals); if (! color_to_alpha_dialog (drawable)) { gimp_drawable_detach (drawable); return; } break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 4) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) pvals.color = param[3].data.d_color; break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &pvals); break; default: break; } if (status == GIMP_PDB_SUCCESS && gimp_drawable_is_rgb (drawable->drawable_id) && gimp_item_is_layer (drawable->drawable_id)) { gboolean lock_alpha; gimp_image_undo_group_start (image_ID); /* Add alpha if not present */ gimp_layer_add_alpha (drawable->drawable_id); /* Reget the drawable, bpp might have changed */ drawable = gimp_drawable_get (drawable->drawable_id); /* Unset 'Lock alpha' */ lock_alpha = gimp_layer_get_lock_alpha (drawable->drawable_id); gimp_layer_set_lock_alpha (drawable->drawable_id, FALSE); gimp_progress_init (_("Removing color")); gimp_rgn_iterate2 (drawable, 0 /* unused */, to_alpha_func, NULL); gimp_layer_set_lock_alpha (drawable->drawable_id, lock_alpha); gimp_image_undo_group_end (image_ID); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } gimp_drawable_detach (drawable); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &pvals, sizeof (pvals)); values[0].data.d_status = status; }
static void plugin_run (const gchar *name, gint numof_params, const GimpParam *params, gint *numof_return_vals, GimpParam **return_vals) { GimpPDBStatusType status = GIMP_PDB_SUCCESS; INIT_I18N (); p.run = FALSE; p.run_mode = params[0].data.d_int32; p.image = params[1].data.d_image; p.drawable = gimp_drawable_get(params[2].data.d_drawable); p.drawable_has_alpha = gimp_drawable_has_alpha(p.drawable->drawable_id); if (gimp_drawable_is_rgb (p.drawable->drawable_id)) { switch (p.run_mode) { case GIMP_RUN_INTERACTIVE: params_load_from_gimp (); open_dialog (); break; case GIMP_RUN_NONINTERACTIVE: if (numof_params == 11) { p.params.tile_width = params[3].data.d_int32; p.params.tile_height = params[3].data.d_int32; p.params.division_x = p.drawable->width / p.params.tile_width; p.params.division_y = p.drawable->height / p.params.tile_height; p.params.move_max_rate = params[4].data.d_float; p.params.fractional_type = (FractionalType)params[5].data.d_int32; p.params.wrap_around = params[6].data.d_int32; p.params.centering = params[7].data.d_int32; p.params.background_type = (BackgroundType)params[8].data.d_int32; p.params.background_color = params[9].data.d_color; /* FIXME: this used to be the alpha value params[10].data.d_int32 */ p.run = TRUE; } else { status = GIMP_PDB_CALLING_ERROR; } break; case GIMP_RUN_WITH_LAST_VALS: params_load_from_gimp (); p.run = TRUE; break; } } else { status = GIMP_PDB_EXECUTION_ERROR; } if (status == GIMP_PDB_SUCCESS && p.run) { params_save_to_gimp (); filter (); if (p.run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } gimp_drawable_detach (p.drawable); { static GimpParam return_value[1]; return_value[0].type = GIMP_PDB_STATUS; return_value[0].data.d_status = status; *numof_return_vals = 1; *return_vals = return_value; } }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[2]; GimpRunMode run_mode; GimpDrawable *drawable; GimpPDBStatusType status = GIMP_PDB_SUCCESS; run_mode = param[0].data.d_int32; /* Get the specified drawable */ 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->ntile_rows, drawable->ntile_cols))); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; INIT_I18N(); switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &evals); /* First acquire information with a dialog */ if (! neon_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 5) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { evals.radius = param[3].data.d_float; evals.amount = param[4].data.d_float; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &evals); break; default: break; } /* make sure the drawable exist and is not indexed */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init (_("Neon")); /* run the neon effect */ neon (drawable, evals.radius, evals.amount, NULL); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &evals, sizeof (NeonVals)); } else { status = GIMP_PDB_EXECUTION_ERROR; *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = _("Cannot operate on indexed color images."); } values[0].data.d_status = status; gimp_drawable_detach (drawable); }
gint xjpg_save_drawable (const char *filename, gint32 image_ID, gint32 drawable_ID, gint save_mode, t_JpegSaveVals *jsvals) { GimpPixelRgn pixel_rgn; GimpDrawable *drawable; GimpImageType drawable_type; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; FILE * volatile outfile; guchar *temp, *t; guchar *data; guchar *src, *s; int has_alpha; int rowstride, yend; int i, j; int alpha_offset; guchar alpha_byte; guchar volatile l_alpha_sum; alpha_offset = 0; has_alpha = 0; src = NULL; temp = NULL; data = NULL; l_alpha_sum = 0xff; drawable = gimp_drawable_get (drawable_ID); drawable_type = gimp_drawable_type (drawable_ID); switch (drawable_type) { case GIMP_RGB_IMAGE: case GIMP_GRAY_IMAGE: if(save_mode == JSVM_ALPHA) return FALSE; /* there is no alpha to save */ break; case GIMP_RGBA_IMAGE: case GIMP_GRAYA_IMAGE: break; case GIMP_INDEXED_IMAGE: /*g_message ("jpeg: cannot operate on indexed color images");*/ return FALSE; break; default: /*g_message ("jpeg: cannot operate on unknown image types");*/ return FALSE; break; } gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); /* Step 1: allocate and initialize JPEG compression object */ /* We have to set up the error handler first, in case the initialization * step fails. (Unlikely, but it could happen if you are out of memory.) * This routine fills in the contents of struct jerr, and returns jerr's * address which we place into the link field in cinfo. */ cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; outfile = NULL; /* Establish the setjmp return context for my_error_exit to use. */ if (setjmp (jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, close the input file, and return. */ jpeg_destroy_compress (&cinfo); if (outfile) fclose (outfile); if (drawable) gimp_drawable_detach (drawable); return FALSE; } /* Now we can initialize the JPEG compression object. */ jpeg_create_compress (&cinfo); /* Step 2: specify data destination (eg, a file) */ /* Note: steps 2 and 3 can be done in either order. */ /* Here we use the library-supplied code to send compressed data to a * stdio stream. You can also write your own code to do something else. * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that * requires it in order to write binary files. */ if ((outfile = g_fopen (filename, "wb")) == NULL) { g_message ("can't open %s\n", filename); return FALSE; } jpeg_stdio_dest (&cinfo, outfile); /* Get the input image and a pointer to its data. */ switch (drawable_type) { case GIMP_RGB_IMAGE: case GIMP_GRAY_IMAGE: /* # of color components per pixel */ cinfo.input_components = drawable->bpp; has_alpha = 0; alpha_offset = 0; break; case GIMP_RGBA_IMAGE: case GIMP_GRAYA_IMAGE: if(save_mode == JSVM_ALPHA) { cinfo.input_components = 1; } else { /* # of color components per pixel (minus the GIMP alpha channel) */ cinfo.input_components = drawable->bpp - 1; } alpha_offset = drawable->bpp -1; has_alpha = 1; break; default: return FALSE; break; } /* Step 3: set parameters for compression */ /* First we supply a description of the input image. * Four fields of the cinfo struct must be filled in: */ /* image width and height, in pixels */ cinfo.image_width = drawable->width; cinfo.image_height = drawable->height; /* colorspace of input image */ cinfo.in_color_space = ( (save_mode != JSVM_ALPHA) && (drawable_type == GIMP_RGB_IMAGE || drawable_type == GIMP_RGBA_IMAGE)) ? JCS_RGB : JCS_GRAYSCALE; /* Now use the library's routine to set default compression parameters. * (You must set at least cinfo.in_color_space before calling this, * since the defaults depend on the source color space.) */ jpeg_set_defaults (&cinfo); /* Now you can set any non-default parameters you wish to. * Here we just illustrate the use of quality (quantization table) scaling: */ jpeg_set_quality (&cinfo, (int) (jsvals->quality * 100), TRUE /* limit to baseline-JPEG values */); cinfo.smoothing_factor = (int) (jsvals->smoothing * 100); cinfo.optimize_coding = jsvals->optimize; /* Step 4: Start compressor */ /* TRUE ensures that we will write a complete interchange-JPEG file. * Pass TRUE unless you are very sure of what you're doing. */ jpeg_start_compress (&cinfo, TRUE); /* Step 5: while (scan lines remain to be written) */ /* jpeg_write_scanlines(...); */ /* Here we use the library's state variable cinfo.next_scanline as the * loop counter, so that we don't have to keep track ourselves. * To keep things simple, we pass one scanline per call; you can pass * more if you wish, though. */ /* JSAMPLEs per row in image_buffer */ rowstride = drawable->bpp * drawable->width; temp = (guchar *) g_malloc (cinfo.image_width * cinfo.input_components); data = (guchar *) g_malloc (rowstride * gimp_tile_height ()); src = data; while (cinfo.next_scanline < cinfo.image_height) { if ((cinfo.next_scanline % gimp_tile_height ()) == 0) { yend = cinfo.next_scanline + gimp_tile_height (); yend = MIN (yend, cinfo.image_height); gimp_pixel_rgn_get_rect (&pixel_rgn, data, 0, cinfo.next_scanline, cinfo.image_width, (yend - cinfo.next_scanline)); src = data; } t = temp; s = src; i = cinfo.image_width; switch(save_mode) { case JSVM_DRAWABLE: if(jsvals->clr_transparent) { /* save drawable (clear pixels where alpha is full transparent) */ while (i--) { alpha_byte = s[cinfo.input_components]; for (j = 0; j < cinfo.input_components; j++) { if(alpha_byte != 0) { *t++ = *s++; } else { *t++ = 0; s++; } } if (has_alpha) /* ignore alpha channel */ { s++; } } } else { /* save the drawable as it is (ignore alpha channel) */ while (i--) { for (j = 0; j < cinfo.input_components; j++) { *t++ = *s++; } if (has_alpha) /* ignore alpha channel */ { s++; } } } break; case JSVM_ALPHA: /* save the drawable's alpha cahnnel */ while (i--) { s += alpha_offset; l_alpha_sum &= (*s); /* check all alpha bytes for full opacity */ *t++ = *s++; } break; } src += rowstride; jpeg_write_scanlines (&cinfo, (JSAMPARRAY) &temp, 1); if ((cinfo.next_scanline % 5) == 0) gimp_progress_update ((double) cinfo.next_scanline / (double) cinfo.image_height); } gimp_progress_update (1.0); /* Step 6: Finish compression */ jpeg_finish_compress (&cinfo); /* After finish_compress, we can close the output file. */ fclose (outfile); if((save_mode == JSVM_ALPHA) && (l_alpha_sum == 0xff)) { /* all bytes in the alpha channel are set to 0xff * == full opaque image. We can remove the file * to save diskspace */ g_remove(filename); } /* Step 7: release JPEG compression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_compress (&cinfo); /* free the temporary buffer */ g_free (temp); g_free (data); gimp_drawable_detach (drawable); return TRUE; } /* end xjpg_save_drawable */
/* -------------------------------------------- * gap_locateAreaWithinRadiusWithOffset * -------------------------------------------- * processing starts at reference coords + offest * and continues outwards upto targetMoveRadius for 4 quadrants. * * returns average color difference (0.0 upto 1.0) * where 0.0 indicates exact matching area * and 1.0 indicates all pixel have maximum color diff (when comaring full white agains full black area) */ gdouble gap_locateAreaWithinRadiusWithOffset(gint32 refDrawableId , gint32 refX , gint32 refY , gint32 refShapeRadius , gint32 targetDrawableId , gint32 targetMoveRadius , gint32 *targetX , gint32 *targetY , gint32 offsetX , gint32 offsetY ) { Context contextData; Context *context; gdouble averageColorDiff; gboolean isFinishedFlag; gint idx; gint idy; gdouble maxPixelCount; *targetX = refX; *targetY = refY; /* init Context */ context = &contextData; context->refShapeRadius = refShapeRadius; context->refX = refX; context->refY = refY; context->bestX = refX; context->bestY = refY; context->cancelAttemptCount = 0; context->cancelAttemptFlag = FALSE; context->isFinishedFlag = FALSE; context->requiredPixelCount = MAX(1, ((refShapeRadius * refShapeRadius) / 4)); context->involvedPixelCount = 0; context->sumDiffValue = 0; context->currentDistance = 0; context->bestMatchingPixelCount = 0; context->veryNearDistance = (2 * 2); context->refDrawable = gimp_drawable_get(refDrawableId); context->targetDrawable = gimp_drawable_get(targetDrawableId); maxPixelCount = MAX(context->refDrawable->width, context->targetDrawable->width) * MAX(context->refDrawable->height, context->targetDrawable->height); context->bestMatchingSumDiffValue = maxPixelCount * MAX_DIFF_VALUE_PER_PIXEL; context->bestMatchingDistance = maxPixelCount; context->bestMatchingAvgColordiff = 1.0; averageColorDiff = 1.0; for(idx = 0; idx <= targetMoveRadius; idx ++) { if (context->isFinishedFlag) { break; } for(idy = 0; idy <= targetMoveRadius; idy++) { gint32 dx; gint32 dy; dx = idx; dy = idy; p_attempt_locate_at_current_offset(context, (offsetX + refX) + dx, (offsetY + refY) +dy); if (isFinishedFlag) { break; } if (idx > 0) { p_attempt_locate_at_current_offset(context, (offsetX + refX) - dx, (offsetY + refY) +dy); if (context->isFinishedFlag) { break; } } if (idy > 0) { p_attempt_locate_at_current_offset(context, (offsetX + refX) + dx, (offsetY + refY) -dy); if (context->isFinishedFlag) { break; } } if ((idx > 0) && (idy > 0)) { p_attempt_locate_at_current_offset(context, (offsetX + refX) - dx, (offsetY + refY) -dy); if (context->isFinishedFlag) { break; } } } } if (context->bestMatchingPixelCount > 0) { *targetX = context->bestX; *targetY = context->bestY; averageColorDiff = context->bestMatchingAvgColordiff; if(gap_debug) { printf("gap_locateAreaWithinRadiusWithOffset Result: bestX:%d bestY:%d averageColorDiff:%.5f\n" " sumDiffValues:%d pixelCount:%d\n" " refX:%d refY:%d cancelAttemptCount:%d\n" , (int)context->bestX , (int)context->bestY , (float)averageColorDiff , (int)context->bestMatchingSumDiffValue , (int)context->bestMatchingPixelCount , (int)context->refX , (int)context->refY , (int)context->cancelAttemptCount ); } } if(context->refDrawable != NULL) { gimp_drawable_detach(context->refDrawable); } if(context->targetDrawable != NULL) { gimp_drawable_detach(context->targetDrawable); } return (averageColorDiff); } /* end gap_locateAreaWithinRadiusWithOffset */
static void lcms_image_transform_rgb (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { cmsHTRANSFORM transform = NULL; DWORD last_format = 0; gint *layers; gint num_layers; gint i; layers = gimp_image_get_layers (image, &num_layers); for (i = 0; i < num_layers; i++) { GimpDrawable *drawable = gimp_drawable_get (layers[i]); DWORD format; switch (drawable->bpp) { case 3: format = TYPE_RGB_8; break; case 4: format = TYPE_RGBA_8; break; default: g_warning ("%s: unexpected bpp", G_STRLOC); continue; } if (! transform || format != last_format) { if (transform) cmsDeleteTransform (transform); transform = cmsCreateTransform (src_profile, format, dest_profile, format, intent, bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0); last_format = format; } if (transform) { lcms_drawable_transform (drawable, transform, (gdouble) i / num_layers, (gdouble) (i + 1) / num_layers); } else { g_warning ("cmsCreateTransform() failed!"); } gimp_drawable_detach (drawable); } if (transform) cmsDeleteTransform(transform); g_free (layers); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpDrawable *drawable; run_mode = param[0].data.d_int32; INIT_I18N (); /* Get the specified drawable */ drawable = gimp_drawable_get (param[2].data.d_drawable); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &evals); /* First acquire information with a dialog */ if (! edge_dialog (drawable)) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 5 && nparams != 6) { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { evals.amount = param[3].data.d_float; evals.wrapmode = param[4].data.d_int32; evals.edgemode = nparams > 5 ? param[5].data.d_int32 : SOBEL; } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &evals); break; default: break; } /* make sure the drawable exist and is not indexed */ if (gimp_drawable_is_rgb (drawable->drawable_id) || gimp_drawable_is_gray (drawable->drawable_id)) { gimp_progress_init (_("Edge detection")); /* set the tile cache size */ gimp_tile_cache_ntiles (TILE_CACHE_SIZE); /* run the edge effect */ edge (drawable); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &evals, sizeof (EdgeVals)); } else { /* gimp_message ("edge: cannot operate on indexed color images"); */ status = GIMP_PDB_EXECUTION_ERROR; } values[0].data.d_status = status; gimp_drawable_detach (drawable); }