void gimp_paint_core_cleanup (GimpPaintCore *core) { g_return_if_fail (GIMP_IS_PAINT_CORE (core)); if (core->undo_tiles) { tile_manager_unref (core->undo_tiles); core->undo_tiles = NULL; } if (core->saved_proj_tiles) { tile_manager_unref (core->saved_proj_tiles); core->saved_proj_tiles = NULL; } if (core->canvas_tiles) { tile_manager_unref (core->canvas_tiles); core->canvas_tiles = NULL; } if (core->orig_buf) { temp_buf_free (core->orig_buf); core->orig_buf = NULL; } if (core->orig_proj_buf) { temp_buf_free (core->orig_proj_buf); core->orig_proj_buf = NULL; } if (core->canvas_buf) { temp_buf_free (core->canvas_buf); core->canvas_buf = NULL; } }
static void gimp_perspective_clone_finalize (GObject *object) { GimpPerspectiveClone *clone = GIMP_PERSPECTIVE_CLONE (object); if (clone->src_area) { temp_buf_free (clone->src_area); clone->src_area = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
void gimp_undo_refresh_preview (GimpUndo *undo, GimpContext *context) { g_return_if_fail (GIMP_IS_UNDO (undo)); g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context)); if (undo->preview_idle_id) return; if (undo->preview) { temp_buf_free (undo->preview); undo->preview = NULL; gimp_undo_create_preview (undo, context, FALSE); } }
static void gimp_undo_finalize (GObject *object) { GimpUndo *undo = GIMP_UNDO (object); if (undo->preview_idle_id) { g_source_remove (undo->preview_idle_id); undo->preview_idle_id = 0; } if (undo->preview) { temp_buf_free (undo->preview); undo->preview = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
static void gimp_pattern_clipboard_buffer_changed (Gimp *gimp, GimpPattern *pattern) { if (pattern->mask) { temp_buf_free (pattern->mask); pattern->mask = NULL; } if (gimp->global_buffer) { gint width; gint height; gint bytes; PixelRegion bufferPR; PixelRegion maskPR; width = MIN (gimp_buffer_get_width (gimp->global_buffer), 2048); height = MIN (gimp_buffer_get_height (gimp->global_buffer), 2048); bytes = gimp_buffer_get_bytes (gimp->global_buffer); pattern->mask = temp_buf_new (width, height, bytes, 0, 0, NULL); pixel_region_init (&bufferPR, gimp_buffer_get_tiles (gimp->global_buffer), 0, 0, width, height, FALSE); pixel_region_init_temp_buf (&maskPR, pattern->mask, 0, 0, width, height); copy_region (&bufferPR, &maskPR); } else { guchar color[3] = { 255, 255, 255 }; pattern->mask = temp_buf_new (16, 16, 3, 0, 0, color); } gimp_data_dirty (GIMP_DATA (pattern)); }
static void gimp_brush_generated_dirty (GimpData *data) { GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data); GimpBrush *gbrush = GIMP_BRUSH (brush); if (gbrush->mask) temp_buf_free (gbrush->mask); gbrush->mask = gimp_brush_generated_calc (brush, brush->shape, brush->radius, brush->spikes, brush->hardness, brush->aspect_ratio, brush->angle, &gbrush->x_axis, &gbrush->y_axis); GIMP_DATA_CLASS (parent_class)->dirty (data); }
static void preview_cache_remove_smallest (GSList **plist) { GSList *list; TempBuf *smallest = NULL; #ifdef PREVIEW_CACHE_DEBUG g_print ("preview_cache_remove_smallest\n"); #endif for (list = *plist; list; list = list->next) { if (!smallest) { smallest = list->data; } else { TempBuf *this = list->data; if (smallest->height * smallest->width > this->height * this->width) { smallest = this; } } } if (smallest) { *plist = g_slist_remove (*plist, smallest); #ifdef PREVIEW_CACHE_DEBUG g_print ("preview_cache_remove_smallest: removed %d x %d\n", smallest->width, smallest->height); #endif temp_buf_free (smallest); } }
void gimp_drawable_bucket_fill_full (GimpDrawable *drawable, GimpBucketFillMode fill_mode, gint paint_mode, gdouble opacity, gboolean do_seed_fill, gboolean fill_transparent, GimpSelectCriterion fill_criterion, gdouble threshold, gboolean sample_merged, gdouble x, gdouble y, const GimpRGB *color, GimpPattern *pattern) { GimpImage *image; TileManager *buf_tiles; PixelRegion bufPR, maskPR; GimpChannel *mask = NULL; gint bytes; gint x1, y1, x2, y2; guchar col[MAX_CHANNELS]; TempBuf *pat_buf = NULL; gboolean new_buf = FALSE; gboolean selection; g_return_if_fail (GIMP_IS_DRAWABLE (drawable)); g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable))); g_return_if_fail (fill_mode != GIMP_PATTERN_BUCKET_FILL || GIMP_IS_PATTERN (pattern)); g_return_if_fail (fill_mode == GIMP_PATTERN_BUCKET_FILL || color != NULL); image = gimp_item_get_image (GIMP_ITEM (drawable)); bytes = gimp_drawable_bytes (drawable); selection = gimp_item_mask_bounds (GIMP_ITEM (drawable), &x1, &y1, &x2, &y2); if ((x1 == x2) || (y1 == y2)) return; if (fill_mode == GIMP_FG_BUCKET_FILL || fill_mode == GIMP_BG_BUCKET_FILL) { guchar tmp_col[MAX_CHANNELS]; gimp_rgb_get_uchar (color, &tmp_col[RED], &tmp_col[GREEN], &tmp_col[BLUE]); gimp_image_transform_color (image, gimp_drawable_type (drawable), col, GIMP_RGB, tmp_col); col[gimp_drawable_bytes_with_alpha (drawable) - 1] = OPAQUE_OPACITY; } else if (fill_mode == GIMP_PATTERN_BUCKET_FILL) { pat_buf = gimp_image_transform_temp_buf (image, gimp_drawable_type (drawable), pattern->mask, &new_buf); } else { g_warning ("%s: invalid fill_mode passed", G_STRFUNC); return; } gimp_set_busy (image->gimp); /* Do a seed bucket fill...To do this, calculate a new * contiguous region. If there is a selection, calculate the * intersection of this region with the existing selection. */ if (do_seed_fill) { mask = gimp_image_contiguous_region_by_seed (image, drawable, sample_merged, TRUE, (gint) threshold, fill_transparent, fill_criterion, (gint) x, (gint) y); if (selection) { gint off_x = 0; gint off_y = 0; if (! sample_merged) gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); gimp_channel_combine_mask (mask, gimp_image_get_mask (image), GIMP_CHANNEL_OP_INTERSECT, -off_x, -off_y); } gimp_channel_bounds (mask, &x1, &y1, &x2, &y2); /* make sure we handle the mask correctly if it was sample-merged */ if (sample_merged) { GimpItem *item; gint off_x, off_y; item = GIMP_ITEM (drawable); /* Limit the channel bounds to the drawable's extents */ gimp_item_get_offset (item, &off_x, &off_y); x1 = CLAMP (x1, off_x, (off_x + gimp_item_get_width (item))); y1 = CLAMP (y1, off_y, (off_y + gimp_item_get_height (item))); x2 = CLAMP (x2, off_x, (off_x + gimp_item_get_width (item))); y2 = CLAMP (y2, off_y, (off_y + gimp_item_get_height (item))); pixel_region_init (&maskPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), x1, y1, (x2 - x1), (y2 - y1), TRUE); /* translate mask bounds to drawable coords */ x1 -= off_x; y1 -= off_y; x2 -= off_x; y2 -= off_y; } else { pixel_region_init (&maskPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)), x1, y1, (x2 - x1), (y2 - y1), TRUE); } /* if the image doesn't have an alpha channel, make sure that * the buf_tiles have. We need the alpha channel to fill with * the region calculated above */ if (! gimp_drawable_has_alpha (drawable)) bytes++; } else if (fill_mode == GIMP_PATTERN_BUCKET_FILL && (pat_buf->bytes == 2 || pat_buf->bytes == 4)) { /* If pattern being applied has an alpha channel, add one to the * buf_tiles. */ if (! gimp_drawable_has_alpha (drawable)) bytes++; } buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes); pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE); switch (fill_mode) { case GIMP_FG_BUCKET_FILL: case GIMP_BG_BUCKET_FILL: if (mask) color_region_mask (&bufPR, &maskPR, col); else color_region (&bufPR, col); break; case GIMP_PATTERN_BUCKET_FILL: if (mask) pattern_region (&bufPR, &maskPR, pat_buf, x1, y1); else pattern_region (&bufPR, NULL, pat_buf, x1, y1); break; } /* Apply it to the image */ pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE); gimp_drawable_apply_region (drawable, &bufPR, TRUE, C_("undo-type", "Bucket Fill"), opacity, paint_mode, NULL, NULL, x1, y1); tile_manager_unref (buf_tiles); /* update the image */ gimp_drawable_update (drawable, x1, y1, x2 - x1, y2 - y1); /* free the mask */ if (mask) g_object_unref (mask); if (new_buf) temp_buf_free (pat_buf); gimp_unset_busy (image->gimp); }
static void gimp_drawable_stroke_scan_convert (GimpDrawable *drawable, GimpStrokeOptions *options, GimpScanConvert *scan_convert) { GimpContext *context = GIMP_CONTEXT (options); GimpImage *image; gdouble width; TileManager *base; TileManager *mask; gint x, y, w, h; gint bytes; gint off_x, off_y; guchar bg[1] = { 0, }; PixelRegion maskPR, basePR; image = gimp_item_get_image (GIMP_ITEM (drawable)); /* must call gimp_channel_is_empty() instead of relying on * gimp_drawable_mask_intersect() because the selection pretends to * be empty while it is being stroked, to prevent masking itself. */ if (gimp_channel_is_empty (gimp_image_get_mask (image))) { x = 0; y = 0; w = gimp_item_width (GIMP_ITEM (drawable)); h = gimp_item_height (GIMP_ITEM (drawable)); } else if (! gimp_drawable_mask_intersect (drawable, &x, &y, &w, &h)) { return; } gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y); width = options->width; if (options->unit != GIMP_UNIT_PIXEL) { gimp_scan_convert_set_pixel_ratio (scan_convert, image->yresolution / image->xresolution); width *= (image->yresolution / _gimp_unit_get_factor (image->gimp, options->unit)); } gimp_scan_convert_stroke (scan_convert, width, options->join_style, options->cap_style, options->miter_limit, options->dash_offset, options->dash_info); /* fill a 1-bpp Tilemanager with black, this will describe the shape * of the stroke. */ mask = tile_manager_new (w, h, 1); pixel_region_init (&maskPR, mask, 0, 0, w, h, TRUE); color_region (&maskPR, bg); /* render the stroke into it */ gimp_scan_convert_render (scan_convert, mask, x + off_x, y + off_y, options->antialias); bytes = gimp_drawable_bytes_with_alpha (drawable); base = tile_manager_new (w, h, bytes); pixel_region_init (&basePR, base, 0, 0, w, h, TRUE); pixel_region_init (&maskPR, mask, 0, 0, w, h, FALSE); switch (options->style) { case GIMP_STROKE_STYLE_SOLID: { guchar tmp_col[MAX_CHANNELS] = { 0, }; guchar col[MAX_CHANNELS] = { 0, }; gimp_rgb_get_uchar (&context->foreground, &tmp_col[RED_PIX], &tmp_col[GREEN_PIX], &tmp_col[BLUE_PIX]); gimp_image_transform_color (image, gimp_drawable_type (drawable), col, GIMP_RGB, tmp_col); col[bytes - 1] = OPAQUE_OPACITY; color_region_mask (&basePR, &maskPR, col); } break; case GIMP_STROKE_STYLE_PATTERN: { GimpPattern *pattern; TempBuf *pat_buf; gboolean new_buf; pattern = gimp_context_get_pattern (context); pat_buf = gimp_image_transform_temp_buf (image, gimp_drawable_type (drawable), pattern->mask, &new_buf); pattern_region (&basePR, &maskPR, pat_buf, x, y); if (new_buf) temp_buf_free (pat_buf); } break; } /* Apply to drawable */ pixel_region_init (&basePR, base, 0, 0, w, h, FALSE); gimp_drawable_apply_region (drawable, &basePR, TRUE, _("Render Stroke"), gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), NULL, x, y); tile_manager_unref (mask); tile_manager_unref (base); gimp_drawable_update (drawable, x, y, w, h); }
static void gimp_brush_clipboard_buffer_changed (Gimp *gimp, GimpBrush *brush) { gint width; gint height; if (brush->mask) { temp_buf_free (brush->mask); brush->mask = NULL; } if (brush->pixmap) { temp_buf_free (brush->pixmap); brush->pixmap = NULL; } if (gimp->global_buffer) { TileManager *tiles = gimp_buffer_get_tiles (gimp->global_buffer); GimpImageType type = gimp_buffer_get_image_type (gimp->global_buffer); width = MIN (gimp_buffer_get_width (gimp->global_buffer), 1024); height = MIN (gimp_buffer_get_height (gimp->global_buffer), 1024); brush->mask = temp_buf_new (width, height, 1, 0, 0, NULL); brush->pixmap = temp_buf_new (width, height, 3, 0, 0, NULL); /* copy the alpha channel into the brush's mask */ if (GIMP_IMAGE_TYPE_HAS_ALPHA (type)) { PixelRegion bufferPR; PixelRegion maskPR; pixel_region_init (&bufferPR, tiles, 0, 0, width, height, FALSE); pixel_region_init_temp_buf (&maskPR, brush->mask, 0, 0, width, height); extract_alpha_region (&bufferPR, NULL, &maskPR); } else { PixelRegion maskPR; guchar opaque = OPAQUE_OPACITY; pixel_region_init_temp_buf (&maskPR, brush->mask, 0, 0, width, height); color_region (&maskPR, &opaque); } /* copy the color channels into the brush's pixmap */ if (GIMP_IMAGE_TYPE_IS_RGB (type)) { PixelRegion bufferPR; PixelRegion pixmapPR; pixel_region_init (&bufferPR, tiles, 0, 0, width, height, FALSE); pixel_region_init_temp_buf (&pixmapPR, brush->pixmap, 0, 0, width, height); if (GIMP_IMAGE_TYPE_HAS_ALPHA (type)) copy_color (&bufferPR, &pixmapPR); else copy_region (&bufferPR, &pixmapPR); } else { PixelRegion bufferPR; PixelRegion tempPR; TempBuf *temp = temp_buf_new (width, height, 1, 0, 0, NULL); pixel_region_init (&bufferPR, tiles, 0, 0, width, height, FALSE); pixel_region_init_temp_buf (&tempPR, temp, 0, 0, width, height); if (GIMP_IMAGE_TYPE_HAS_ALPHA (type)) copy_component (&bufferPR, &tempPR, 0); else copy_region (&bufferPR, &tempPR); temp_buf_copy (temp, brush->pixmap); temp_buf_free (temp); } } else { guchar color = 0; width = 17; height = 17; brush->mask = temp_buf_new (width, height, 1, 0, 0, &color); } brush->x_axis.x = width / 2; brush->x_axis.y = 0; brush->y_axis.x = 0; brush->y_axis.y = height / 2; gimp_data_dirty (GIMP_DATA (brush)); }