/* --------------------------------------- * gap_drawable_foreground_extract_matting * --------------------------------------- * */ static void gap_drawable_foreground_extract_matting (GimpDrawable *maskDrawable, GimpDrawable *resultDrawable, GappMattingState *state, gfloat start_percentage ) { GappTileManager *tmMask; GappTileManager *tmResult; gint x1, y1; gint x2, y2; gpointer progress_data; gdouble progressDataUnused; if(gap_debug) { printf("extract_matting: START\n"); } g_return_if_fail (state != NULL); progress_data = &progressDataUnused; x1 = 0; y1 = 0; x2 = maskDrawable->width; y2 = maskDrawable->height; tmMask = gapp_tile_manager_new(maskDrawable); tmResult = gapp_tile_manager_new(resultDrawable); matting_foreground_extract (state, tmMask, x1, y1, x2, y2, start_percentage, (MattingProgressFunc) p_progressFunc, progress_data, tmResult); gimp_drawable_update (resultDrawable->drawable_id, x1, y1, x2, y2); gimp_drawable_update (maskDrawable->drawable_id, x1, y1, x2, y2); if(gap_debug) { printf("extract_matting: END\n"); } } /* end gap_drawable_foreground_extract_matting */
/* This function operates on PixelArea, whose width and height are multiply of pixel width, and less than the tile size (to enhance its speed). If any coordinates of mask boundary is not multiply of pixel width (e.g. x1 % pixelwidth != 0), operates on the region whose width or height is the remainder. */ static void pixelize_small (GimpDrawable *drawable, gint pixelwidth, gint pixelheight, gint tile_width, gint tile_height) { GimpPixelRgn src_rgn, dest_rgn; gint bpp, has_alpha; gint x1, y1, x2, y2; gint progress, max_progress; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, x2-x1, y2-y1, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2-x1, y2-y1, TRUE, TRUE); /* Initialize progress */ progress = 0; max_progress = (x2 - x1) * (y2 - y1); bpp = drawable->bpp; has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); area.width = (tile_width / pixelwidth) * pixelwidth; area.height = (tile_height / pixelheight) * pixelheight; area.data= g_new (guchar, (glong) bpp * area.width * area.height); for (area.y = y1; area.y < y2; area.y += area.height - (area.y % area.height)) { area.h = area.height - (area.y % area.height); area.h = MIN (area.h, y2 - area.y); for (area.x = x1; area.x < x2; area.x += area.width - (area.x % area.width)) { area.w = area.width - (area.x % area.width); area.w = MIN(area.w, x2 - area.x); gimp_pixel_rgn_get_rect (&src_rgn, area.data, area.x, area.y, area.w, area.h); pixelize_sub (pixelwidth, pixelheight, bpp, has_alpha); gimp_pixel_rgn_set_rect (&dest_rgn, area.data, area.x, area.y, area.w, area.h); /* Update progress */ progress += area.w * area.h; gimp_progress_update ((double) progress / (double) max_progress); } } g_free(area.data); /* update the pixelized region */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); }
static void octave (GimpDrawable *drawable) { GimpPixelRgn srcPR, destPR; gint x1, y1, x2, y2; gint x, y, width, height; /* initialize pixel regions */ gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE); /* Get the input */ gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); x=x1; y=y1; width=x2-x1; height=y2-y1; /* Run */ octave_region (&srcPR, &destPR, drawable->bpp, x, y, width, height); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1); }
void gimp_layer_mask_set_apply (GimpLayerMask *layer_mask, gboolean apply, gboolean push_undo) { g_return_if_fail (GIMP_IS_LAYER_MASK (layer_mask)); if (layer_mask->apply_mask != apply) { GimpImage *image = GIMP_ITEM (layer_mask)->image; if (push_undo) gimp_image_undo_push_layer_mask_apply (image, _("Apply Layer Mask"), layer_mask); layer_mask->apply_mask = apply ? TRUE : FALSE; if (layer_mask->layer) { GimpDrawable *drawable = GIMP_DRAWABLE (layer_mask->layer); gimp_drawable_update (drawable, 0, 0, gimp_item_width (GIMP_ITEM (drawable)), gimp_item_height (GIMP_ITEM (drawable))); } g_signal_emit (layer_mask, layer_mask_signals[APPLY_CHANGED], 0); } }
void gimp_layer_mask_set_show (GimpLayerMask *layer_mask, gboolean show, gboolean push_undo) { g_return_if_fail (GIMP_IS_LAYER_MASK (layer_mask)); if (layer_mask->show_mask != show) { GimpImage *image = GIMP_ITEM (layer_mask)->image; if (push_undo) gimp_image_undo_push_layer_mask_show (image, _("Show Layer Mask"), layer_mask); layer_mask->show_mask = show ? TRUE : FALSE; if (layer_mask->layer) { GimpDrawable *drawable = GIMP_DRAWABLE (layer_mask->layer); gimp_drawable_update (drawable, 0, 0, gimp_item_width (GIMP_ITEM (drawable)), gimp_item_height (GIMP_ITEM (drawable))); } g_signal_emit (layer_mask, layer_mask_signals[SHOW_CHANGED], 0); } }
static void gimp_text_layer_render_layout (GimpTextLayer *layer, GimpTextLayout *layout) { GimpDrawable *drawable = GIMP_DRAWABLE (layer); GimpItem *item = GIMP_ITEM (layer); GeglBuffer *buffer; cairo_t *cr; cairo_surface_t *surface; gint width; gint height; g_return_if_fail (gimp_drawable_has_alpha (drawable)); width = gimp_item_get_width (item); height = gimp_item_get_height (item); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); cr = cairo_create (surface); gimp_text_layout_render (layout, cr, layer->text->base_dir, FALSE); cairo_destroy (cr); cairo_surface_flush (surface); buffer = gimp_cairo_surface_create_buffer (surface); gegl_buffer_copy (buffer, NULL, gimp_drawable_get_buffer (drawable), NULL); g_object_unref (buffer); cairo_surface_destroy (surface); gimp_drawable_update (drawable, 0, 0, width, height); }
static void waves (GimpDrawable *drawable) { GimpPixelRgn srcPr, dstPr; guchar *src, *dst; guint width, height, bpp, has_alpha; width = drawable->width; height = drawable->height; bpp = drawable->bpp; has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); src = g_new (guchar, width * height * bpp); dst = g_new (guchar, width * height * bpp); gimp_pixel_rgn_init (&srcPr, drawable, 0, 0, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&dstPr, drawable, 0, 0, width, height, TRUE, TRUE); gimp_pixel_rgn_get_rect (&srcPr, src, 0, 0, width, height); wave (src, dst, width, height, bpp, has_alpha, width / 2.0, height / 2.0, wvals.amplitude, wvals.wavelength, wvals.phase, wvals.type == MODE_SMEAR, wvals.reflective, TRUE); gimp_pixel_rgn_set_rect (&dstPr, dst, 0, 0, width, height); g_free (src); g_free (dst); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, 0, 0, width, height); gimp_displays_flush (); }
void gimp_channel_combine_buffer (GimpChannel *mask, GeglBuffer *add_on_buffer, GimpChannelOps op, gint off_x, gint off_y) { GeglBuffer *buffer; gint x, y, w, h; g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GEGL_IS_BUFFER (add_on_buffer)); buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); if (! gimp_gegl_mask_combine_buffer (buffer, add_on_buffer, op, off_x, off_y)) return; gimp_rectangle_intersect (off_x, off_y, gegl_buffer_get_width (add_on_buffer), gegl_buffer_get_height (add_on_buffer), 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h); mask->bounds_known = FALSE; gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
static void compute_image (GimpDrawable *drawable) { GimpDrawable *effect; guchar *scalarfield = NULL; /* Get some useful info on the input drawable */ /* ========================================== */ if (! gimp_drawable_mask_intersect (drawable->drawable_id, &border_x, &border_y, &border_w, &border_h)) return; gimp_progress_init (_("Van Gogh (LIC)")); if (licvals.effect_convolve == 0) generatevectors (); if (licvals.filtlen < 0.1) licvals.filtlen = 0.1; l = licvals.filtlen; dx = dy = licvals.noisemag; minv = licvals.minv / 10.0; maxv = licvals.maxv / 10.0; isteps = licvals.intsteps; source_drw_has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); effect = gimp_drawable_get (licvals.effect_image_id); effect_width = effect->width; effect_height = effect->height; switch (licvals.effect_channel) { case 0: scalarfield = rgb_to_hsl (effect, LIC_HUE); break; case 1: scalarfield = rgb_to_hsl (effect, LIC_SATURATION); break; case 2: scalarfield = rgb_to_hsl (effect, LIC_BRIGHTNESS); break; } compute_lic (drawable, scalarfield, licvals.effect_operator); g_free (scalarfield); /* Update image */ /* ============ */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, border_x, border_y, border_w, border_h); gimp_displays_flush (); }
//------------------------------------------------------------------------- static void c2g_mask (GimpDrawable *drawable, gdouble radius, gdouble amount, gdouble gamma) { GimpPixelRgn srcPR, destPR; gint x1, y1, x2, y2; /* initialize pixel regions */ gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE); /* Get the input */ gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); c2g_region (&srcPR, &destPR, drawable->bpp, radius, amount, gamma, x1, x2, y1, y2, TRUE); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1); }
void gimp_edit_fill (GimpImage *image, GimpDrawable *drawable, GimpFillOptions *options, const gchar *undo_desc) { GeglBuffer *buffer; gint x, y, width, height; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_FILL_OPTIONS (options)); if (! gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height)) return; /* nothing to do, but the fill succeeded */ buffer = gimp_fill_options_create_buffer (options, drawable, GEGL_RECTANGLE (0, 0, width, height)); if (! undo_desc) undo_desc = gimp_fill_options_get_undo_desc (options); gimp_drawable_apply_buffer (drawable, buffer, GEGL_RECTANGLE (0, 0, width, height), TRUE, undo_desc, gimp_context_get_opacity (GIMP_CONTEXT (options)), gimp_context_get_paint_mode (GIMP_CONTEXT (options)), NULL, x, y); g_object_unref (buffer); gimp_drawable_update (drawable, x, y, width, height); }
static void sinus (void) { params p; gint bytes; GimpPixelRgn dest_rgn; gint x1, y1, x2, y2; gpointer pr; gint progress, max_progress; prepare_coef(&p); gimp_drawable_mask_bounds(drawable->drawable_id, &x1, &y1, &x2, &y2); p.width = drawable->width; p.height = drawable->height; bytes = drawable->bpp; gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, x2 - x1, y2 - y1, TRUE,TRUE); progress = 0; max_progress = (x2 - x1) * (y2 - y1); for (pr = gimp_pixel_rgns_register (1, &dest_rgn); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { switch (bytes) { case 4: compute_block_x (dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, 4, assign_block_4, &p); break; case 3: compute_block_x (dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, 3, assign_block_3, &p); break; case 2: compute_block_x (dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, 2, assign_block_2, &p); break; case 1: compute_block_x (dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, 1, assign_block_1, &p); break; } progress += dest_rgn.w * dest_rgn.h; gimp_progress_update ((double) progress / (double) max_progress); } gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1); }
void gimp_channel_combine_mask (GimpChannel *mask, GimpChannel *add_on, GimpChannelOps op, gint off_x, gint off_y) { PixelRegion srcPR, destPR; gint x, y, w, h; g_return_if_fail (GIMP_IS_CHANNEL (mask)); g_return_if_fail (GIMP_IS_CHANNEL (add_on)); if (! gimp_rectangle_intersect (off_x, off_y, gimp_item_get_width (GIMP_ITEM (add_on)), gimp_item_get_height (GIMP_ITEM (add_on)), 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h)) return; pixel_region_init (&srcPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (add_on)), x - off_x, y - off_y, w, h, FALSE); pixel_region_init (&destPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), x, y, w, h, TRUE); switch (op) { case GIMP_CHANNEL_OP_ADD: case GIMP_CHANNEL_OP_REPLACE: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_add, NULL, 2, &srcPR, &destPR); break; case GIMP_CHANNEL_OP_SUBTRACT: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_sub, NULL, 2, &srcPR, &destPR); break; case GIMP_CHANNEL_OP_INTERSECT: pixel_regions_process_parallel ((PixelProcessorFunc) gimp_channel_combine_sub_region_intersect, NULL, 2, &srcPR, &destPR); break; default: g_warning ("%s: unknown operation type", G_STRFUNC); break; } mask->bounds_known = FALSE; gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
void floating_sel_to_layer (GimpLayer *layer) { GimpItem *item; GimpImage *image; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (gimp_layer_is_floating_sel (layer)); item = GIMP_ITEM (layer); if (! (image = gimp_item_get_image (item))) return; /* Check if the floating layer belongs to a channel... */ if (GIMP_IS_CHANNEL (layer->fs.drawable)) { gimp_message (image->gimp, NULL, GIMP_MESSAGE_WARNING, _("Cannot create a new layer from the floating selection " "because it belongs to a layer mask or channel.")); return; } gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER, _("Floating Selection to Layer")); /* restore the contents of the drawable */ floating_sel_restore (layer, item->offset_x, item->offset_y, item->width, item->height); gimp_image_undo_push_fs_to_layer (image, NULL, layer); /* clear the selection */ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer)); /* Set pointers */ layer->fs.drawable = NULL; image->floating_sel = NULL; gimp_item_set_visible (GIMP_ITEM (layer), TRUE, TRUE); gimp_layer_set_lock_alpha (layer, FALSE, TRUE); gimp_image_undo_group_end (image); gimp_object_name_changed (GIMP_OBJECT (layer)); gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, GIMP_ITEM (layer)->width, GIMP_ITEM (layer)->height); gimp_image_floating_selection_changed (image); }
gint32 execute_plugin(GimpDrawable* d, const char *nome, param_type *p) { // gint i; guchar *img, *org; gint x,y,x2,y2,w,h; // guchar *work; GimpPixelRgn region, rgn_org; gint bpp = d->bpp; gimp_drawable_mask_bounds(d->drawable_id, &x, &y, &x2, &y2); w = x2 - x; h = y2 - y; img = malloc(w * h * bpp); org = malloc(w * h * bpp); // work = malloc(d.width * d.height * bpp); gimp_pixel_rgn_init(®ion, d, x, y, w, h, TRUE, TRUE); //este é buffer para gravar a imagem modificada. gimp_pixel_rgn_init(&rgn_org, d, x, y, w, h, FALSE, FALSE); // Esta é a imagem em si gimp_pixel_rgn_get_rect(®ion, img, x, y, w, h); gimp_pixel_rgn_get_rect(&rgn_org, org, x, y, w, h); switch (*nome) { case 'S': super_grow(p, org, img, w, h, bpp); break; case 'G': memcpy(img, org, w * h * bpp); grow(p, org, img, w, h, bpp); break; case 'A': find_iso(p, org, img, w, h, bpp); break; default: make_height_field(p, org, img, w, h, bpp); break; } gimp_pixel_rgn_set_rect(®ion, img, x, y, w, h); /* finish the process */ gimp_drawable_flush (d); gimp_drawable_merge_shadow (d->drawable_id, TRUE); gimp_drawable_update (d->drawable_id, x, y, w, h); gimp_displays_flush(); gimp_drawable_detach(d); free(img); free(org); return GIMP_PDB_SUCCESS; }
void gimp_channel_combine_rect (GimpChannel *mask, GimpChannelOps op, gint x, gint y, gint w, gint h) { GeglBuffer *buffer; g_return_if_fail (GIMP_IS_CHANNEL (mask)); buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)); if (! gimp_gegl_mask_combine_rect (buffer, op, x, y, w, h)) return; gimp_rectangle_intersect (x, y, w, h, 0, 0, gimp_item_get_width (GIMP_ITEM (mask)), gimp_item_get_height (GIMP_ITEM (mask)), &x, &y, &w, &h); /* Determine new boundary */ if (mask->bounds_known && (op == GIMP_CHANNEL_OP_ADD) && ! mask->empty) { if (x < mask->x1) mask->x1 = x; if (y < mask->y1) mask->y1 = y; if ((x + w) > mask->x2) mask->x2 = (x + w); if ((y + h) > mask->y2) mask->y2 = (y + h); } else if (op == GIMP_CHANNEL_OP_REPLACE || mask->empty) { mask->empty = FALSE; mask->x1 = x; mask->y1 = y; mask->x2 = x + w; mask->y2 = y + h; } else { mask->bounds_known = FALSE; } mask->x1 = CLAMP (mask->x1, 0, gimp_item_get_width (GIMP_ITEM (mask))); mask->y1 = CLAMP (mask->y1, 0, gimp_item_get_height (GIMP_ITEM (mask))); mask->x2 = CLAMP (mask->x2, 0, gimp_item_get_width (GIMP_ITEM (mask))); mask->y2 = CLAMP (mask->y2, 0, gimp_item_get_height (GIMP_ITEM (mask))); gimp_drawable_update (GIMP_DRAWABLE (mask), x, y, w, h); }
/* ---------------------------------------- * p_subtract_ref_layer * ---------------------------------------- * setup pixel regions and perform edge detection by subtracting RGB channels * of the orignal (refDrawable) from the blurred copy (edgeDrawable) * and convert the rgb differences to lightness. * * as result of this processing in the edgeDrawable contains a desaturated * colordifference of the original versus blured copy. */ static void p_subtract_ref_layer(gint32 image_id, GimpDrawable *edgeDrawable, GimpDrawable *refDrawable , gdouble threshold, gint32 shift, gboolean invert) { GimpPixelRgn edgePR; GimpPixelRgn refPR; GimpPixelRgn ref2PR; gpointer pr; gdouble threshold01f; gdouble threshold255f; gint threshold255; gint cx; gint cy; threshold01f = CLAMP((threshold / 100.0), 0, 1); threshold255f = 255.0 * threshold01f; threshold255 = threshold255f; p_get_debug_coords_from_guides(image_id, &cx, &cy); gimp_pixel_rgn_init (&edgePR, edgeDrawable, 0, 0 , edgeDrawable->width - shift, edgeDrawable->height - shift , TRUE /* dirty */ , FALSE /* shadow */ ); /* start at shifted offset 0/+1 */ gimp_pixel_rgn_init (&refPR, refDrawable, 0, shift , refDrawable->width - shift, refDrawable->height - shift , FALSE /* dirty */ , FALSE /* shadow */ ); /* start at shifted offset +1/0 */ gimp_pixel_rgn_init (&ref2PR, refDrawable, shift, 0 , refDrawable->width - shift, refDrawable->height - shift , FALSE /* dirty */ , FALSE /* shadow */ ); /* compare pixel areas in tiled portions via pixel region processing loops. */ for (pr = gimp_pixel_rgns_register (3, &edgePR, &refPR, &ref2PR); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { p_colordiffProcessingForOneRegion (&edgePR, &refPR, &ref2PR, threshold01f, invert, cx, cy); } gimp_drawable_flush (edgeDrawable); gimp_drawable_update (edgeDrawable->drawable_id , 0, 0 , edgeDrawable->width, edgeDrawable->height ); } /* end p_subtract_ref_layer */
static void preview_update_preview (GimpPreview *preview, GimpDrawable *drawable) { gint x1, y1; gint width, height; gint bpp; guchar *buffer; GimpPixelRgn src_rgn; GimpPixelRgn preview_rgn; gint32 image_id, src_image_id; gint32 preview_id; GimpDrawable *preview_drawable; bpp = gimp_drawable_bpp (drawable->drawable_id); gimp_preview_get_position (preview, &x1, &y1); gimp_preview_get_size (preview, &width, &height); buffer = g_new (guchar, width * height * bpp); gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE); gimp_pixel_rgn_get_rect (&src_rgn, buffer, x1, y1, width, height); /* set up gimp drawable for rendering preview into */ src_image_id = gimp_drawable_get_image (drawable->drawable_id); image_id = gimp_image_new (width, height, gimp_image_base_type (src_image_id)); preview_id = gimp_layer_new (image_id, "preview", width, height, gimp_drawable_type (drawable->drawable_id), 100, GIMP_NORMAL_MODE); preview_drawable = gimp_drawable_get (preview_id); gimp_image_add_layer (image_id, preview_id, 0); gimp_layer_set_offsets (preview_id, 0, 0); gimp_pixel_rgn_init (&preview_rgn, preview_drawable, 0, 0, width, height, TRUE, TRUE); gimp_pixel_rgn_set_rect (&preview_rgn, buffer, 0, 0, width, height); gimp_drawable_flush (preview_drawable); gimp_drawable_merge_shadow (preview_id, TRUE); gimp_drawable_update (preview_id, 0, 0, width, height); dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE); gimp_pixel_rgn_get_rect (&preview_rgn, buffer, 0, 0, width, height); gimp_preview_draw_buffer (preview, buffer, width * bpp); gimp_image_delete (image_id); g_free (buffer); }
/* Update Gimp image from local pixmap. Canonical postlude for plugins. !!! Called in the postlude but also for debugging: animate results during processing. */ static void post_results_to_gimp( GimpDrawable *drawable, Map targetMap) { pixmap_to_drawable(targetMap, drawable, FIRST_PIXELEL_INDEX); // our pixels to region gimp_drawable_flush(drawable); // regions back to core gimp_drawable_merge_shadow(drawable->drawable_id,TRUE); // temp buffers merged gimp_drawable_update(drawable->drawable_id,0,0,targetMap.width,targetMap.height); gimp_displays_flush(); }
static GimpPDBStatusType run_pspi (const gchar *pdb_name, gint n_params, const GimpParam *param) { GimpRunMode run_mode = param[0].data.d_int32; GimpDrawable *drawable; GimpPDBStatusType status = GIMP_PDB_SUCCESS; PSPlugInEntry *pspie; gint x1, y1, x2, y2; get_saved_plugin_data (); if ((pspie = g_hash_table_lookup (entry_hash, pdb_name)) != NULL) { gchar *name; if (run_mode == GIMP_RUN_NONINTERACTIVE) { if (n_params != standard_nargs) return GIMP_PDB_CALLING_ERROR; } else if (run_mode == GIMP_RUN_INTERACTIVE) { if ((status = pspi_params (pspie)) != GIMP_PDB_SUCCESS) return status; } drawable = gimp_drawable_get (param[2].data.d_drawable); gimp_ui_init (PLUGIN_NAME, TRUE); if ((status = pspi_prepare (pspie, drawable)) != GIMP_PDB_SUCCESS) return status; name = g_strdup_printf (_("Applying %s:"), strrchr (pspie->menu_path, '/') + 1); gimp_progress_init (name); g_free (name); if ((status = pspi_apply (pspie, drawable)) != GIMP_PDB_SUCCESS) return status; gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); gimp_displays_flush (); return GIMP_PDB_SUCCESS; } return GIMP_PDB_CALLING_ERROR; }
static void mblur (GimpDrawable *drawable, GimpPreview *preview) { gint x, y; gint width, height; if (preview) { gimp_preview_get_position (preview, &x, &y); gimp_preview_get_size (preview, &width, &height); } else { gimp_drawable_mask_bounds (drawable->drawable_id, &x, &y, &width, &height); width -= x; height -= y; } if (width < 1 || height < 1) return; if (! preview) gimp_progress_init (_("Motion blurring")); switch (mbvals.mblur_type) { case MBLUR_LINEAR: mblur_linear (drawable, preview, x, y, width, height); break; case MBLUR_RADIAL: mblur_radial (drawable, preview, x, y, width, height); break; case MBLUR_ZOOM: mblur_zoom (drawable, preview, x, y, width, height); break; default: break; } if (! preview) { gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x, y, width, height); } }
gboolean floating_sel_to_layer (GimpLayer *layer, GError **error) { GimpItem *item; GimpImage *image; g_return_val_if_fail (GIMP_IS_LAYER (layer), FALSE); g_return_val_if_fail (gimp_layer_is_floating_sel (layer), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); item = GIMP_ITEM (layer); image = gimp_item_get_image (item); /* Check if the floating layer belongs to a channel */ if (GIMP_IS_CHANNEL (gimp_layer_get_floating_sel_drawable (layer))) { g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED, _("Cannot create a new layer from the floating " "selection because it belongs to a layer mask " "or channel.")); return FALSE; } gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_TO_LAYER, C_("undo-type", "Floating Selection to Layer")); gimp_image_undo_push_fs_to_layer (image, NULL, layer); gimp_drawable_detach_floating_sel (gimp_layer_get_floating_sel_drawable (layer)); gimp_layer_set_floating_sel_drawable (layer, NULL); gimp_item_set_visible (item, TRUE, TRUE); gimp_layer_set_lock_alpha (layer, FALSE, TRUE); gimp_image_undo_group_end (image); /* When the floating selection is converted to/from a normal layer * it does something resembling a name change, so emit the * "name-changed" signal */ gimp_object_name_changed (GIMP_OBJECT (layer)); gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, gimp_item_get_width (item), gimp_item_get_height (item)); return TRUE; }
static void color_rotate (GimpDrawable *drawable) { GimpPixelRgn srcPR, destPR; gint width, height; gint bytes; guchar *src_row, *dest_row; gint row; gint x, y; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x, &y, &width, &height)) { return; } bytes = drawable->bpp; src_row = g_new (guchar, width * bytes); dest_row = g_new (guchar, width * bytes); gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, 0, 0, drawable->width, drawable->height, TRUE, TRUE); for (row = y; row < (y + height); row++) { gimp_pixel_rgn_get_row (&srcPR, src_row, x, row, width); color_rotate_row (src_row, dest_row, row, width, bytes); gimp_pixel_rgn_set_row (&destPR, dest_row, x, row, width); if ((row % 10) == 0) gimp_progress_update ((double) row / (double) height); } /* update the processed region */ gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x, y, width, height); g_free (src_row); g_free (dest_row); }
void gimp_drawable_bucket_fill (GimpDrawable *drawable, GimpFillOptions *options, gboolean fill_transparent, GimpSelectCriterion fill_criterion, gdouble threshold, gboolean sample_merged, gboolean diagonal_neighbors, gdouble seed_x, gdouble seed_y) { GimpImage *image; GeglBuffer *buffer; gdouble mask_x; gdouble mask_y; gint width, height; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (GIMP_IS_FILL_OPTIONS (options)); image = gimp_item_get_image (GIMP_ITEM (drawable)); gimp_set_busy (image->gimp); buffer = gimp_drawable_get_bucket_fill_buffer (drawable, options, fill_transparent, fill_criterion, threshold, sample_merged, diagonal_neighbors, seed_x, seed_y, NULL, &mask_x, &mask_y, &width, &height); if (buffer) { /* Apply it to the image */ gimp_drawable_apply_buffer (drawable, buffer, GEGL_RECTANGLE (0, 0, width, height), TRUE, C_("undo-type", "Bucket Fill"), gimp_context_get_opacity (GIMP_CONTEXT (options)), gimp_context_get_paint_mode (GIMP_CONTEXT (options)), GIMP_LAYER_COLOR_SPACE_AUTO, GIMP_LAYER_COLOR_SPACE_AUTO, gimp_layer_mode_get_paint_composite_mode ( gimp_context_get_paint_mode (GIMP_CONTEXT (options))), NULL, (gint) mask_x, mask_y); g_object_unref (buffer); gimp_drawable_update (drawable, mask_x, mask_y, width, height); } gimp_unset_busy (image->gimp); }
// !!! Note GIMP abbreviates Rgn instead of region, and gimp_ prefix to functions // Compare to plug-ins/pygimp/pygimp-tile.c static gboolean process (GeglOperation *operation, GeglBuffer *data, const GeglRectangle *result) { GeglChantO *o = GEGL_CHANT_PROPERTIES (operation); g_printf("Process sink\n"); if (! o->drawableID) return FALSE; else { GimpDrawable *drawable; const Babl *format; GimpPixelRgn io_pixel_region; gpointer pr; g_printf("result width %d\n", result->width); drawable = gimp_drawable_get(o->drawableID); // format = gegl_operation_get_format (operation, "output"); format = babl_format ("RGBA u8"); // TODO test format of operation with format of drawable gimp_pixel_rgn_init (&io_pixel_region, drawable, result->x, result->y, result->width, result->height, TRUE, TRUE); for (pr = gimp_pixel_rgns_register (1, &io_pixel_region); pr; pr = gimp_pixel_rgns_process (pr)) { GeglRectangle rect = { io_pixel_region.x, io_pixel_region.y, io_pixel_region.w, io_pixel_region.h }; gegl_buffer_get (data, GIMP_SINK_SCALE, &rect, format, io_pixel_region.data, io_pixel_region.rowstride); } /* Drawable is set of tiles private to this sink. Not the same as the caller's, nor the same as the source node's. */ gimp_drawable_flush(drawable); gimp_drawable_merge_shadow(o->drawableID, FALSE); gimp_drawable_update(o->drawableID, result->x, result->y, result->width, result->height); return TRUE; } }
void focusblur_fft_buffer_draw (FblurFftBuffer *fft) { GimpDrawablePreview *preview; gboolean dirty; guint8 *data; GimpPixelRgn pr; if (! fft->source.preview) { preview = NULL; dirty = TRUE; data = fft->source.data; } else { preview = GIMP_DRAWABLE_PREVIEW (fft->source.preview); g_assert (preview != NULL); dirty = FALSE; data = fft->source.data_preview; } g_assert (data != NULL); gimp_pixel_rgn_init (&pr, fft->source.drawable, fft->source.x1, fft->source.y1, fft->source.width, fft->source.height, dirty, TRUE); gimp_pixel_rgn_set_rect (&pr, data, fft->source.x1, fft->source.y1, fft->source.width, fft->source.height); if (! preview) { gimp_drawable_flush (fft->source.drawable); gimp_drawable_merge_shadow (fft->source.drawable->drawable_id, TRUE); gimp_drawable_update (fft->source.drawable->drawable_id, fft->source.x1, fft->source.y1, fft->source.width, fft->source.height); /* this buffer has been dirty */ focusblur_fft_buffer_clear_source (fft); } else { gimp_drawable_preview_draw_region (preview, &pr); } }
void gimp_drawable_foreground_extract_siox (GimpDrawable *mask, SioxState *state, SioxRefinementType refinement, gint smoothness, const gdouble sensitivity[3], gboolean multiblob, GimpProgress *progress) { GeglBuffer *buffer; gint x1, y1; gint x2, y2; g_return_if_fail (GIMP_IS_DRAWABLE (mask)); g_return_if_fail (babl_format_get_bytes_per_pixel (gimp_drawable_get_format (mask)) == 1); g_return_if_fail (state != NULL); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); if (progress) gimp_progress_start (progress, _("Foreground Extraction"), FALSE); if (GIMP_IS_CHANNEL (mask)) { gimp_channel_bounds (GIMP_CHANNEL (mask), &x1, &y1, &x2, &y2); } else { x1 = 0; y1 = 0; x2 = gimp_item_get_width (GIMP_ITEM (mask)); y2 = gimp_item_get_height (GIMP_ITEM (mask)); } buffer = gimp_drawable_get_buffer (mask); siox_foreground_extract (state, refinement, gimp_gegl_buffer_get_tiles (buffer), x1, y1, x2, y2, smoothness, sensitivity, multiblob, (SioxProgressFunc) gimp_progress_set_value, progress); if (progress) gimp_progress_end (progress); gimp_drawable_update (mask, x1, y1, x2, y2); }
void gimp_rgn_iterate2 (GimpDrawable *drawable, GimpRunMode unused, GimpRgnFunc2 func, gpointer data) { GimpPixelRgn srcPR, destPR; gint x1, y1, x2, y2; gpointer pr; gint total_area; gint area_so_far; gint progress_skip; g_return_if_fail (drawable != NULL); gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); total_area = (x2 - x1) * (y2 - y1); if (total_area <= 0) return; area_so_far = 0; progress_skip = 0; /* Initialize the pixel regions. */ gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, (x2 - x1), (y2 - y1), FALSE, FALSE); gimp_pixel_rgn_init (&destPR, drawable, x1, y1, (x2 - x1), (y2 - y1), TRUE, TRUE); for (pr = gimp_pixel_rgns_register (2, &srcPR, &destPR); pr != NULL; pr = gimp_pixel_rgns_process (pr)) { gimp_rgn_render_region (&srcPR, &destPR, func, data); area_so_far += srcPR.w * srcPR.h; if (((progress_skip++) % 10) == 0) gimp_progress_update ((gdouble) area_so_far / (gdouble) total_area); } /* update the processed region */ gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); }
static void gimp_floating_sel_undo_pop (GimpUndo *undo, GimpUndoMode undo_mode, GimpUndoAccumulator *accum) { GimpFloatingSelUndo *floating_sel_undo = GIMP_FLOATING_SEL_UNDO (undo); GimpLayer *floating_layer = GIMP_LAYER (GIMP_ITEM_UNDO (undo)->item); GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum); switch (undo->undo_type) { case GIMP_UNDO_FS_TO_LAYER: if (undo_mode == GIMP_UNDO_MODE_UNDO) { /* Update the preview for the floating sel */ gimp_viewable_invalidate_preview (GIMP_VIEWABLE (floating_layer)); gimp_layer_set_floating_sel_drawable (floating_layer, floating_sel_undo->drawable); gimp_image_set_active_layer (undo->image, floating_layer); gimp_drawable_attach_floating_sel (gimp_layer_get_floating_sel_drawable (floating_layer), floating_layer); } else { gimp_drawable_detach_floating_sel (gimp_layer_get_floating_sel_drawable (floating_layer)); gimp_layer_set_floating_sel_drawable (floating_layer, NULL); } /* When the floating selection is converted to/from a normal * layer it does something resembling a name change, so emit the * "name-changed" signal */ gimp_object_name_changed (GIMP_OBJECT (floating_layer)); gimp_drawable_update (GIMP_DRAWABLE (floating_layer), 0, 0, gimp_item_get_width (GIMP_ITEM (floating_layer)), gimp_item_get_height (GIMP_ITEM (floating_layer))); break; default: g_assert_not_reached (); } }
/* * Red Eye Removal Alorithm, based on using a threshold to detect * red pixels. Having a user-made selection around the eyes will * prevent incorrect pixels from being selected. */ static void remove_redeye (GimpDrawable *drawable) { GimpPixelRgn src_rgn; GimpPixelRgn dest_rgn; gint progress, max_progress; gboolean has_alpha; gint x, y; gint width, height; gint i; gpointer pr; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x, &y, &width, &height)) return; gimp_progress_init (_("Removing red eye")); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); progress = 0; max_progress = width * height; gimp_pixel_rgn_init (&src_rgn, drawable, x, y, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x, y, width, height, TRUE, TRUE); for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), i = 0; pr != NULL; pr = gimp_pixel_rgns_process (pr), i++) { redeye_inner_loop (src_rgn.data, dest_rgn.data, src_rgn.w, src_rgn.h, src_rgn.bpp, has_alpha, src_rgn.rowstride); progress += src_rgn.w * src_rgn.h; if (i % 16 == 0) gimp_progress_update ((gdouble) progress / (gdouble) max_progress); } gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x, y, width, height); }