/* The main rotate function */ static void rotate (void) { GimpDrawable *drawable; gint32 *layers; gint i; gint nlayers; gint32 guide_ID; GuideInfo *guide; GList *guides = NULL; GList *list; if (rotvals.angle == 0) return; /* if there's a selection and we try to rotate the whole image */ /* create an error message and exit */ if (rotvals.everything) { if (! gimp_selection_is_empty (image_ID)) { gimp_message (_("You can not rotate the whole image if there's a selection.")); gimp_drawable_detach (active_drawable); return; } if (gimp_item_is_layer (active_drawable->drawable_id) && gimp_layer_is_floating_sel (active_drawable->drawable_id)) { gimp_message (_("You can not rotate the whole image if there's a floating selection.")); gimp_drawable_detach (active_drawable); return; } } else /* if we are trying to rotate a channel or a mask, create an error message and exit */ { if (! gimp_item_is_layer (active_drawable->drawable_id)) { gimp_message (_("Sorry, channels and masks can not be rotated.")); gimp_drawable_detach (active_drawable); return; } } gimp_progress_init (_("Rotating")); gimp_image_undo_group_start (image_ID); if (rotvals.everything) /* rotate the whole image */ { gint32 width = gimp_image_width (image_ID); gint32 height = gimp_image_height (image_ID); gimp_drawable_detach (active_drawable); layers = gimp_image_get_layers (image_ID, &nlayers); for (i = 0; i < nlayers; i++) { drawable = gimp_drawable_get (layers[i]); rotate_drawable (drawable); gimp_drawable_detach (drawable); } g_free (layers); /* build a list of all guides and remove them */ guide_ID = 0; while ((guide_ID = gimp_image_find_next_guide (image_ID, guide_ID)) != 0) { guide = g_new (GuideInfo, 1); guide->ID = guide_ID; guide->orientation = gimp_image_get_guide_orientation (image_ID, guide_ID); guide->position = gimp_image_get_guide_position (image_ID, guide_ID); guides = g_list_prepend (guides, guide); } for (list = guides; list; list = list->next) { guide = (GuideInfo *) list->data; gimp_image_delete_guide (image_ID, guide->ID); } /* if rotation is not 180 degrees, resize the image */ /* Do it now after the guides are removed, since */ /* gimp_image_resize() moves the guides. */ if (rotvals.angle != 2) gimp_image_resize (image_ID, height, width, 0, 0); /* add the guides back to the image */ if (guides) { switch (rotvals.angle) { case 1: for (list = guides; list; list = list->next) { guide = (GuideInfo *)list->data; if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL) gimp_image_add_vguide (image_ID, height - guide->position); else gimp_image_add_hguide (image_ID, guide->position); g_free (guide); } break; case 2: for (list = guides; list; list = list->next) { guide = (GuideInfo *)list->data; if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL) gimp_image_add_hguide (image_ID, height - guide->position); else gimp_image_add_vguide (image_ID, width - guide->position); g_free (guide); } break; case 3: for (list = guides; list; list = list->next) { guide = (GuideInfo *)list->data; if (guide->orientation == GIMP_ORIENTATION_HORIZONTAL) gimp_image_add_vguide (image_ID, guide->position); else gimp_image_add_hguide (image_ID, width - guide->position); g_free (guide); } break; default: break; } g_list_free (guides); } } else /* rotate only the active layer */ { /* check for active selection and float it */ if (! gimp_selection_is_empty (image_ID) && ! gimp_layer_is_floating_sel (active_drawable->drawable_id)) { active_drawable = gimp_drawable_get (gimp_selection_float (image_ID, active_drawable->drawable_id, 0, 0)); } rotate_drawable (active_drawable); gimp_drawable_detach (active_drawable); } gimp_image_undo_group_end (image_ID); return; }
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; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gboolean no_dialog; INIT_I18N (); gegl_init (NULL, NULL); run_mode = param[0].data.d_int32; no_dialog = (strcmp (name, "plug-in-sel2path") == 0); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; image_ID = param[1].data.d_image; if (image_ID < 0) { g_warning ("plug-in-sel2path needs a valid image ID"); return; } if (gimp_selection_is_empty (image_ID)) { g_message (_("No selection to convert")); return; } fit_set_default_params (&selVals); if (!no_dialog) { switch (run_mode) { case GIMP_RUN_INTERACTIVE: if (gimp_get_data_size ("plug-in-sel2path-advanced") > 0) { gimp_get_data ("plug-in-sel2path-advanced", &selVals); } if (!sel2path_dialog (&selVals)) return; /* Get the current settings */ fit_set_params (&selVals); break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 23) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) { selVals.align_threshold = param[3].data.d_float; selVals.corner_always_threshold = param[4].data.d_float; selVals.corner_surround = param[5].data.d_int8; selVals.corner_threshold = param[6].data.d_float; selVals.error_threshold = param[7].data.d_float; selVals.filter_alternative_surround = param[8].data.d_int8; selVals.filter_epsilon = param[9].data.d_float; selVals.filter_iteration_count = param[10].data.d_int8; selVals.filter_percent = param[11].data.d_float; selVals.filter_secondary_surround = param[12].data.d_int8; selVals.filter_surround = param[13].data.d_int8; selVals.keep_knees = param[14].data.d_int8; selVals.line_reversion_threshold = param[15].data.d_float; selVals.line_threshold = param[16].data.d_float; selVals.reparameterize_improvement = param[17].data.d_float; selVals.reparameterize_threshold = param[18].data.d_float; selVals.subdivide_search = param[19].data.d_float; selVals.subdivide_surround = param[20].data.d_int8; selVals.subdivide_threshold = param[21].data.d_float; selVals.tangent_surround = param[22].data.d_int8; fit_set_params (&selVals); } break; case GIMP_RUN_WITH_LAST_VALS: if(gimp_get_data_size ("plug-in-sel2path-advanced") > 0) { gimp_get_data ("plug-in-sel2path-advanced", &selVals); /* Set up the last values */ fit_set_params (&selVals); } break; default: break; } } sel2path (image_ID); values[0].data.d_status = status; if (status == GIMP_PDB_SUCCESS) { dialog_print_selVals(&selVals); if (run_mode == GIMP_RUN_INTERACTIVE && !no_dialog) gimp_set_data ("plug-in-sel2path-advanced", &selVals, sizeof(SELVALS)); } }
static gboolean lcms_image_apply_profile (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, const gchar *filename, GimpColorRenderingIntent intent, gboolean bpc) { gint32 saved_selection = -1; gimp_image_undo_group_start (image); if (! lcms_image_set_profile (image, dest_profile, filename, FALSE)) { gimp_image_undo_group_end (image); return FALSE; } { gchar *src = lcms_icc_profile_get_desc (src_profile); gchar *dest = lcms_icc_profile_get_desc (dest_profile); /* ICC color profile conversion */ gimp_progress_init_printf (_("Converting from '%s' to '%s'"), src, dest); g_printerr ("lcms: converting from '%s' to '%s'\n", src, dest); g_free (dest); g_free (src); } if (! gimp_selection_is_empty (image)) { saved_selection = gimp_selection_save (image); gimp_selection_none (image); } switch (gimp_image_base_type (image)) { case GIMP_RGB: lcms_image_transform_rgb (image, src_profile, dest_profile, intent, bpc); break; case GIMP_GRAY: g_warning ("colorspace conversion not implemented for " "grayscale images"); break; case GIMP_INDEXED: lcms_image_transform_indexed (image, src_profile, dest_profile, intent, bpc); break; } if (saved_selection != -1) { gimp_image_select_item (image, GIMP_CHANNEL_OP_REPLACE, saved_selection); gimp_image_remove_channel (image, saved_selection); } gimp_progress_update (1.0); gimp_image_undo_group_end (image); return TRUE; }
/* -------------------------------------------- * gap_fg_from_selection_exec_apply_run * -------------------------------------------- * generate a tri map from the current selection by filling the shrinked * shape with white, the expanded shape with black and the borderline * between shrinked and expanded selection with medium gray. * the trimap is attached as layermask to the input drawable, * and used as input for the foreground selection via alpha matting algorithm, * that creates a resulting layer with trimmed selection. * */ gint gap_fg_from_selection_exec_apply_run (gint32 image_id, gint32 drawable_id , gboolean doProgress, gboolean doFlush , GapFgSelectValues *fsValPtr) { GimpRGB color; gint32 activeSelection; gint32 shrinkedSelection; gint32 trimap; gboolean hadSelection; gint rc; rc = 0; trimap = -1; activeSelection = -1; shrinkedSelection = -1; hadSelection = FALSE; gimp_context_push(); gimp_image_undo_group_start(image_id); if (gimp_selection_is_empty(image_id) == TRUE) { if (gimp_drawable_has_alpha(drawable_id) == FALSE) { /* if the layer has no alpha select all */ gimp_selection_all(image_id); } else { gimp_selection_layer_alpha(drawable_id); } activeSelection = gimp_selection_save(image_id); } else { activeSelection = gimp_selection_save(image_id); hadSelection = TRUE; } trimap = gimp_layer_get_mask(drawable_id); if (trimap < 0) { /* create trimap as new layermask */ trimap = gimp_layer_create_mask(drawable_id, GIMP_ADD_BLACK_MASK); gimp_layer_add_mask(drawable_id, trimap); } else { /* use BLACK color to fill the already existing layermask * (note that gimp_drawable_fill is used to fill the entire mask * regardless to the current selection) */ color.r = 0.0; color.g = 0.0; color.b = 0.0; color.a = 1.0; gimp_context_set_background (&color); gimp_drawable_fill(trimap, GIMP_BACKGROUND_FILL); } gimp_selection_sharpen(image_id); if (fsValPtr->innerRadius > 0) { gimp_selection_shrink(image_id, fsValPtr->innerRadius); } shrinkedSelection = gimp_selection_save(image_id); /* use WHITE color to mark foreground regions */ color.r = 1.0; color.g = 1.0; color.b = 1.0; color.a = 1.0; gimp_context_set_background (&color); gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL); gimp_selection_load(activeSelection); gimp_selection_sharpen(image_id); if (fsValPtr->outerRadius > 0) { gimp_selection_grow(image_id, fsValPtr->outerRadius); } gimp_selection_combine(shrinkedSelection, GIMP_CHANNEL_OP_SUBTRACT); /* use medium GRAY to mark undefined regions */ color.r = 0.5; color.g = 0.5; color.b = 0.5; color.a = 1.0; gimp_context_set_background (&color); gimp_edit_fill(trimap, GIMP_BACKGROUND_FILL); gimp_selection_none(image_id); /* perform the foreground selection (that creates the resulting layer) */ { GapFgExtractValues fgExtractValues; GapFgExtractValues *fgValPtr; fgValPtr = &fgExtractValues; fgValPtr->input_drawable_id = drawable_id; fgValPtr->tri_map_drawable_id = trimap; fgValPtr->create_result = TRUE; fgValPtr->create_layermask = fsValPtr->create_layermask; fgValPtr->lock_color = fsValPtr->lock_color; fgValPtr->colordiff_threshold = fsValPtr->colordiff_threshold; rc = gap_fg_matting_exec_apply_run (image_id, drawable_id , doProgress, doFlush , fgValPtr ); } /* restore original selection */ if (hadSelection == TRUE) { gimp_selection_load(activeSelection); } gimp_image_undo_group_end(image_id); gimp_context_pop(); return (rc); } /* end gap_fg_from_selection_exec_apply_run */
/* do the analyzing */ static void analyze (GimpDrawable *drawable) { GimpPixelRgn srcPR; guchar *src_row, *cmap; gint x, y, numcol; gint x1, y1, x2, y2; 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")); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); /* * 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 < x2 - x1; 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); }