static AutoCropType gimp_image_crop_guess_bgcolor (GimpPickable *pickable, gint bytes, gboolean has_alpha, guchar *color, gint x1, gint x2, gint y1, gint y2) { guchar tl[4]; guchar tr[4]; guchar bl[4]; guchar br[4]; gint i; for (i = 0; i < bytes; i++) color[i] = 0; /* First check if there's transparency to crop. If not, guess the * background-color to see if at least 2 corners are equal. */ if (! gimp_pickable_get_pixel_at (pickable, x1, y1, tl) || ! gimp_pickable_get_pixel_at (pickable, x1, y2, tr) || ! gimp_pickable_get_pixel_at (pickable, x2, y1, bl) || ! gimp_pickable_get_pixel_at (pickable, x2, y2, br)) { return AUTO_CROP_NOTHING; } if (has_alpha) { gint alpha = bytes - 1; if ((tl[alpha] == 0 && tr[alpha] == 0) || (tl[alpha] == 0 && bl[alpha] == 0) || (tr[alpha] == 0 && br[alpha] == 0) || (bl[alpha] == 0 && br[alpha] == 0)) { return AUTO_CROP_ALPHA; } } if (gimp_image_crop_colors_equal (tl, tr, bytes) || gimp_image_crop_colors_equal (tl, bl, bytes)) { memcpy (color, tl, bytes); return AUTO_CROP_COLOR; } if (gimp_image_crop_colors_equal (br, bl, bytes) || gimp_image_crop_colors_equal (br, tr, bytes)) { memcpy (color, br, bytes); return AUTO_CROP_COLOR; } return AUTO_CROP_NOTHING; }
gboolean gimp_pickable_pick_color (GimpPickable *pickable, gint x, gint y, gboolean sample_average, gdouble average_radius, gpointer pixel, GimpRGB *color) { const Babl *format; gdouble sample[4]; g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE); format = gimp_pickable_get_format (pickable); if (! gimp_pickable_get_pixel_at (pickable, x, y, format, sample)) return FALSE; gimp_pickable_pixel_to_srgb (pickable, format, sample, color); if (pixel) memcpy (pixel, sample, babl_format_get_bytes_per_pixel (format)); if (sample_average) { gint count = 0; gdouble color_avg[4] = { 0.0, 0.0, 0.0, 0.0 }; gint radius = (gint) average_radius; gint i, j; format = babl_format ("RaGaBaA double"); for (i = x - radius; i <= x + radius; i++) for (j = y - radius; j <= y + radius; j++) if (gimp_pickable_get_pixel_at (pickable, i, j, format, sample)) { count++; color_avg[RED] += sample[RED]; color_avg[GREEN] += sample[GREEN]; color_avg[BLUE] += sample[BLUE]; color_avg[ALPHA] += sample[ALPHA]; } sample[RED] = color_avg[RED] / count; sample[GREEN] = color_avg[GREEN] / count; sample[BLUE] = color_avg[BLUE] / count; sample[ALPHA] = color_avg[ALPHA] / count; gimp_pickable_pixel_to_srgb (pickable, format, sample, color); } return TRUE; }
gboolean gimp_pickable_get_color_at (GimpPickable *pickable, gint x, gint y, GimpRGB *color) { guchar pixel[32]; g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE); g_return_val_if_fail (color != NULL, FALSE); if (! gimp_pickable_get_pixel_at (pickable, x, y, NULL, pixel)) return FALSE; gimp_rgba_set_pixel (color, gimp_pickable_get_format (pickable), pixel); return TRUE; }
gboolean gimp_pickable_get_color_at (GimpPickable *pickable, gint x, gint y, GimpRGB *color) { guchar pixel[4]; guchar col[4]; g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE); g_return_val_if_fail (color != NULL, FALSE); if (! gimp_pickable_get_pixel_at (pickable, x, y, pixel)) return FALSE; gimp_image_get_color (gimp_pickable_get_image (pickable), gimp_pickable_get_image_type (pickable), pixel, col); gimp_rgba_set_uchar (color, col[0], col[1], col[2], col[3]); return TRUE; }
gboolean gimp_pickable_pick_color (GimpPickable *pickable, gint x, gint y, gboolean sample_average, gdouble average_radius, GimpRGB *color, gint *color_index) { const Babl *format; gdouble pixel[4]; g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE); format = babl_format ("RGBA double"); if (! gimp_pickable_get_pixel_at (pickable, x, y, format, pixel)) return FALSE; if (sample_average) { gint count = 0; gdouble color_avg[4] = { 0.0, 0.0, 0.0, 0.0 }; gint radius = (gint) average_radius; gint i, j; for (i = x - radius; i <= x + radius; i++) for (j = y - radius; j <= y + radius; j++) if (gimp_pickable_get_pixel_at (pickable, i, j, format, pixel)) { count++; color_avg[RED] += pixel[RED]; color_avg[GREEN] += pixel[GREEN]; color_avg[BLUE] += pixel[BLUE]; color_avg[ALPHA] += pixel[ALPHA]; } pixel[RED] = color_avg[RED] / count; pixel[GREEN] = color_avg[GREEN] / count; pixel[BLUE] = color_avg[BLUE] / count; pixel[ALPHA] = color_avg[ALPHA] / count; } gimp_rgba_set_pixel (color, format, pixel); if (color_index) { format = gimp_pickable_get_format (pickable); if (babl_format_is_palette (format) && ! sample_average) { guchar indexed_pixel[4]; gimp_pickable_get_pixel_at (pickable, x, y, format, indexed_pixel); *color_index = indexed_pixel[0]; } else { *color_index = -1; } } return TRUE; }
static gboolean gimp_smudge_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options) { GimpSmudge *smudge = GIMP_SMUDGE (paint_core); GimpImage *image; TempBuf *area; PixelRegion srcPR; gint bytes; gint x, y, w, h; image = gimp_item_get_image (GIMP_ITEM (drawable)); if (gimp_drawable_is_indexed (drawable)) return FALSE; area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); if (! area) return FALSE; /* adjust the x and y coordinates to the upper left corner of the brush */ gimp_smudge_brush_coords (paint_core, &x, &y, &w, &h); /* Allocate the accumulation buffer */ bytes = gimp_drawable_bytes (drawable); smudge->accum_data = g_malloc (w * h * bytes); /* If clipped, prefill the smudge buffer with the color at the * brush position. */ if (x != area->x || y != area->y || w != area->width || h != area->height) { guchar fill[4]; gimp_pickable_get_pixel_at (GIMP_PICKABLE (drawable), CLAMP ((gint) paint_core->cur_coords.x, 0, gimp_item_width (GIMP_ITEM (drawable)) - 1), CLAMP ((gint) paint_core->cur_coords.y, 0, gimp_item_height (GIMP_ITEM (drawable)) - 1), fill); pixel_region_init_data (&srcPR, smudge->accum_data, bytes, bytes * w, 0, 0, w, h); color_region (&srcPR, fill); } pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), area->x, area->y, area->width, area->height, FALSE); pixel_region_init_data (&smudge->accumPR, smudge->accum_data, bytes, bytes * w, area->x - x, area->y - y, area->width, area->height); /* copy the region under the original painthit. */ copy_region (&srcPR, &smudge->accumPR); pixel_region_init_data (&smudge->accumPR, smudge->accum_data, bytes, bytes * w, area->x - x, area->y - y, area->width, area->height); return TRUE; }
gboolean gimp_pickable_pick_color (GimpPickable *pickable, gint x, gint y, gboolean sample_average, gdouble average_radius, GimpRGB *color, gint *color_index) { GimpImage *image; GimpImageType type; guchar pixel[4]; guchar col[4]; g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE); if (! gimp_pickable_get_pixel_at (pickable, x, y, pixel)) return FALSE; image = gimp_pickable_get_image (pickable); type = gimp_pickable_get_image_type (pickable); if (sample_average) { gint count = 0; gint color_avg[4] = { 0, 0, 0, 0 }; gint radius = (gint) average_radius; gint i, j; for (i = x - radius; i <= x + radius; i++) for (j = y - radius; j <= y + radius; j++) if (gimp_pickable_get_pixel_at (pickable, i, j, pixel)) { count++; gimp_image_get_color (image, type, pixel, col); color_avg[RED] += col[RED]; color_avg[GREEN] += col[GREEN]; color_avg[BLUE] += col[BLUE]; color_avg[ALPHA] += col[ALPHA]; } col[RED] = (guchar) ((color_avg[RED] + count / 2) / count); col[GREEN] = (guchar) ((color_avg[GREEN] + count / 2) / count); col[BLUE] = (guchar) ((color_avg[BLUE] + count / 2) / count); col[ALPHA] = (guchar) ((color_avg[ALPHA] + count / 2) / count); } else { gimp_image_get_color (image, type, pixel, col); } gimp_rgba_set_uchar (color, col[RED], col[GREEN], col[BLUE], col[ALPHA]); if (color_index) { if (GIMP_IMAGE_TYPE_IS_INDEXED (type) && ! sample_average) *color_index = pixel[0]; else *color_index = -1; } return TRUE; }