[gimp/goat-invasion] app: add format parameter to GimpPickable::get_pixel_at()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/goat-invasion] app: add format parameter to GimpPickable::get_pixel_at()
- Date: Sat, 21 Apr 2012 08:08:56 +0000 (UTC)
commit 9e5d2dfe2fdb891b43174e177dbbcbbb9dbd2551
Author: Michael Natterer <mitch gimp org>
Date: Sat Apr 21 10:03:32 2012 +0200
app: add format parameter to GimpPickable::get_pixel_at()
allowing NULL for the pickable's native format. Fix and simplify auto
cropping to always use "R'G'B'A u8".
app/core/gimpdrawable.c | 9 ++--
app/core/gimpimage-crop.c | 103 ++++++++++++++++++--------------------------
app/core/gimpimagemap.c | 11 +++--
app/core/gimppickable.c | 64 ++++++++++++++-------------
app/core/gimppickable.h | 6 ++-
app/core/gimpprojection.c | 9 ++--
6 files changed, 95 insertions(+), 107 deletions(-)
---
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 37e5dea..4573977 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -118,7 +118,8 @@ static void gimp_drawable_transform (GimpItem *item,
static gboolean gimp_drawable_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel);
+ const Babl *format,
+ gpointer pixel);
static void gimp_drawable_real_update (GimpDrawable *drawable,
gint x,
gint y,
@@ -636,7 +637,8 @@ static gboolean
gimp_drawable_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel)
+ const Babl *format,
+ gpointer pixel)
{
GimpDrawable *drawable = GIMP_DRAWABLE (pickable);
@@ -646,8 +648,7 @@ gimp_drawable_get_pixel_at (GimpPickable *pickable,
return FALSE;
gegl_buffer_sample (gimp_drawable_get_buffer (drawable),
- x, y, NULL, pixel,
- gimp_drawable_get_format (drawable),
+ x, y, NULL, pixel, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
return TRUE;
diff --git a/app/core/gimpimage-crop.c b/app/core/gimpimage-crop.c
index cb36f40..36a20d9 100644
--- a/app/core/gimpimage-crop.c
+++ b/app/core/gimpimage-crop.c
@@ -48,26 +48,21 @@ typedef enum
typedef AutoCropType (* ColorsEqualFunc) (guchar *col1,
- guchar *col2,
- gint bytes);
+ guchar *col2);
/* local function prototypes */
static AutoCropType gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
- gint bytes,
- gboolean has_alpha,
guchar *color,
gint x1,
gint x2,
gint y1,
gint y2);
static gint gimp_image_crop_colors_equal (guchar *col1,
- guchar *col2,
- gint bytes);
+ guchar *col2);
static gint gimp_image_crop_colors_alpha (guchar *col1,
- guchar *col2,
- gint bytes);
+ guchar *col2);
/* public functions */
@@ -310,11 +305,9 @@ gimp_image_crop_auto_shrink (GimpImage *image,
GeglRectangle rect;
ColorsEqualFunc colors_equal_func;
guchar bgcolor[MAX_CHANNELS] = { 0, 0, 0, 0 };
- gboolean has_alpha;
guchar *buf = NULL;
gint width, height;
const Babl *format;
- gint bytes;
gint x, y, abort;
gboolean retval = FALSE;
@@ -349,13 +342,10 @@ gimp_image_crop_auto_shrink (GimpImage *image,
gimp_pickable_flush (pickable);
- format = gimp_pickable_get_format (pickable);
- bytes = babl_format_get_bytes_per_pixel (format);
- has_alpha = babl_format_has_alpha (format);
+ format = babl_format ("R'G'B'A u8");
- switch (gimp_image_crop_guess_bgcolor (pickable,
- bytes, has_alpha, bgcolor,
- x1, x2-1, y1, y2-1))
+ switch (gimp_image_crop_guess_bgcolor (pickable, bgcolor,
+ x1, x2 - 1, y1, y2 - 1))
{
case AUTO_CROP_ALPHA:
colors_equal_func = (ColorsEqualFunc) gimp_image_crop_colors_alpha;
@@ -377,7 +367,7 @@ gimp_image_crop_auto_shrink (GimpImage *image,
* the smaller side first instead of defaulting to width --Sven
*/
- buf = g_malloc (MAX (width, height) * bytes);
+ buf = g_malloc (MAX (width, height) * 4);
/* Check how many of the top lines are uniform/transparent. */
rect.x = x1;
@@ -389,11 +379,10 @@ gimp_image_crop_auto_shrink (GimpImage *image,
for (y = y1; y < y2 && !abort; y++)
{
rect.y = y;
- /* XXX use an appropriate format here */
- gegl_buffer_get (buffer, &rect, 1.0, NULL, buf,
+ gegl_buffer_get (buffer, &rect, 1.0, format, buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
for (x = 0; x < width && !abort; x++)
- abort = !(colors_equal_func) (bgcolor, buf + x * bytes, bytes);
+ abort = ! colors_equal_func (bgcolor, buf + x * 4);
}
if (y == y2 && !abort)
goto FINISH;
@@ -409,10 +398,10 @@ gimp_image_crop_auto_shrink (GimpImage *image,
for (y = y2; y > y1 && !abort; y--)
{
rect.y = y - 1;
- gegl_buffer_get (buffer, &rect, 1.0, NULL, buf,
+ gegl_buffer_get (buffer, &rect, 1.0, format, buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
for (x = 0; x < width && !abort; x++)
- abort = !(colors_equal_func) (bgcolor, buf + x * bytes, bytes);
+ abort = ! colors_equal_func (bgcolor, buf + x * 4);
}
y2 = y + 1;
@@ -429,10 +418,10 @@ gimp_image_crop_auto_shrink (GimpImage *image,
for (x = x1; x < x2 && !abort; x++)
{
rect.x = x;
- gegl_buffer_get (buffer, &rect, 1.0, NULL, buf,
+ gegl_buffer_get (buffer, &rect, 1.0, format, buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
for (y = 0; y < height && !abort; y++)
- abort = !(colors_equal_func) (bgcolor, buf + y * bytes, bytes);
+ abort = ! colors_equal_func (bgcolor, buf + y * 4);
}
x1 = x - 1;
@@ -446,10 +435,10 @@ gimp_image_crop_auto_shrink (GimpImage *image,
for (x = x2; x > x1 && !abort; x--)
{
rect.x = x - 1;
- gegl_buffer_get (buffer, &rect, 1.0, NULL, buf,
+ gegl_buffer_get (buffer, &rect, 1.0, format, buf,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
for (y = 0; y < height && !abort; y++)
- abort = !(colors_equal_func) (bgcolor, buf + y * bytes, bytes);
+ abort = ! colors_equal_func (bgcolor, buf + y * 4);
}
x2 = x + 1;
@@ -472,59 +461,53 @@ gimp_image_crop_auto_shrink (GimpImage *image,
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++)
+ const Babl *format = babl_format ("R'G'B'A u8");
+ guchar tl[4];
+ guchar tr[4];
+ guchar bl[4];
+ guchar br[4];
+ gint i;
+
+ for (i = 0; i < 4; 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))
+ if (! gimp_pickable_get_pixel_at (pickable, x1, y1, format, tl) ||
+ ! gimp_pickable_get_pixel_at (pickable, x1, y2, format, tr) ||
+ ! gimp_pickable_get_pixel_at (pickable, x2, y1, format, bl) ||
+ ! gimp_pickable_get_pixel_at (pickable, x2, y2, format, br))
{
return AUTO_CROP_NOTHING;
}
- if (has_alpha)
+ 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))
{
- 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;
- }
+ return AUTO_CROP_ALPHA;
}
- if (gimp_image_crop_colors_equal (tl, tr, bytes) ||
- gimp_image_crop_colors_equal (tl, bl, bytes))
+ if (gimp_image_crop_colors_equal (tl, tr) ||
+ gimp_image_crop_colors_equal (tl, bl))
{
- memcpy (color, tl, bytes);
+ memcpy (color, tl, 4);
return AUTO_CROP_COLOR;
}
- if (gimp_image_crop_colors_equal (br, bl, bytes) ||
- gimp_image_crop_colors_equal (br, tr, bytes))
+ if (gimp_image_crop_colors_equal (br, bl) ||
+ gimp_image_crop_colors_equal (br, tr))
{
- memcpy (color, br, bytes);
+ memcpy (color, br, 4);
return AUTO_CROP_COLOR;
}
@@ -533,12 +516,11 @@ gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
static int
gimp_image_crop_colors_equal (guchar *col1,
- guchar *col2,
- gint bytes)
+ guchar *col2)
{
gint b;
- for (b = 0; b < bytes; b++)
+ for (b = 0; b < 4; b++)
{
if (col1[b] != col2[b])
return FALSE;
@@ -549,8 +531,7 @@ gimp_image_crop_colors_equal (guchar *col1,
static gboolean
gimp_image_crop_colors_alpha (guchar *dummy,
- guchar *col,
- gint bytes)
+ guchar *col)
{
- return (col[bytes - 1] == 0);
+ return (col[ALPHA] == 0);
}
diff --git a/app/core/gimpimagemap.c b/app/core/gimpimagemap.c
index 3e1c4dd..a2d9ddd 100644
--- a/app/core/gimpimagemap.c
+++ b/app/core/gimpimagemap.c
@@ -96,7 +96,8 @@ static TileManager * gimp_image_map_get_tiles (GimpPickable *pick
static gboolean gimp_image_map_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel);
+ const Babl *format,
+ gpointer pixel);
static void gimp_image_map_update_undo_buffer
(GimpImageMap *image_map,
@@ -280,7 +281,8 @@ static gboolean
gimp_image_map_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel)
+ const Babl *format,
+ gpointer pixel)
{
GimpImageMap *image_map = GIMP_IMAGE_MAP (pickable);
GimpItem *item = GIMP_ITEM (image_map->drawable);
@@ -301,8 +303,7 @@ gimp_image_map_get_pixel_at (GimpPickable *pickable,
{
gegl_buffer_sample (image_map->undo_buffer,
x - offset_x, y - offset_y,
- NULL, pixel,
- gimp_drawable_get_format (image_map->drawable),
+ NULL, pixel, format,
GEGL_SAMPLER_NEAREST,
GEGL_ABYSS_NONE);
@@ -311,7 +312,7 @@ gimp_image_map_get_pixel_at (GimpPickable *pickable,
}
return gimp_pickable_get_pixel_at (GIMP_PICKABLE (image_map->drawable),
- x, y, pixel);
+ x, y, format, pixel);
}
return FALSE;
diff --git a/app/core/gimppickable.c b/app/core/gimppickable.c
index 138a69b..319a80c 100644
--- a/app/core/gimppickable.c
+++ b/app/core/gimppickable.c
@@ -155,17 +155,21 @@ gboolean
gimp_pickable_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel)
+ const Babl *format,
+ gpointer pixel)
{
GimpPickableInterface *pickable_iface;
g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE);
g_return_val_if_fail (pixel != NULL, FALSE);
+ if (! format)
+ format = gimp_pickable_get_format (pickable);
+
pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
if (pickable_iface->get_pixel_at)
- return pickable_iface->get_pixel_at (pickable, x, y, pixel);
+ return pickable_iface->get_pixel_at (pickable, x, y, format, pixel);
return FALSE;
}
@@ -181,7 +185,7 @@ gimp_pickable_get_color_at (GimpPickable *pickable,
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))
+ if (! gimp_pickable_get_pixel_at (pickable, x, y, NULL, pixel))
return FALSE;
gimp_rgba_set_pixel (color, gimp_pickable_get_format (pickable), pixel);
@@ -216,17 +220,14 @@ gimp_pickable_pick_color (GimpPickable *pickable,
gint *color_index)
{
const Babl *format;
- const Babl *fish;
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;
+ format = babl_format ("R'G'B'A u8");
- format = gimp_pickable_get_format (pickable);
- fish = babl_fish (format, babl_format ("R'G'B'A u8"));
+ if (! gimp_pickable_get_pixel_at (pickable, x, y, format, pixel))
+ return FALSE;
if (sample_average)
{
@@ -237,41 +238,42 @@ gimp_pickable_pick_color (GimpPickable *pickable,
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))
+ if (gimp_pickable_get_pixel_at (pickable, i, j, format, pixel))
{
count++;
- babl_process (fish, pixel, col, 1);
-
- color_avg[RED] += col[RED];
- color_avg[GREEN] += col[GREEN];
- color_avg[BLUE] += col[BLUE];
- color_avg[ALPHA] += col[ALPHA];
+ color_avg[RED] += pixel[RED];
+ color_avg[GREEN] += pixel[GREEN];
+ color_avg[BLUE] += pixel[BLUE];
+ color_avg[ALPHA] += pixel[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);
+ pixel[RED] = (guchar) ((color_avg[RED] + count / 2) / count);
+ pixel[GREEN] = (guchar) ((color_avg[GREEN] + count / 2) / count);
+ pixel[BLUE] = (guchar) ((color_avg[BLUE] + count / 2) / count);
+ pixel[ALPHA] = (guchar) ((color_avg[ALPHA] + count / 2) / count);
}
- else
- {
- babl_process (fish, pixel, col, 1);
- }
-
gimp_rgba_set_uchar (color,
- col[RED],
- col[GREEN],
- col[BLUE],
- col[ALPHA]);
+ pixel[RED],
+ pixel[GREEN],
+ pixel[BLUE],
+ pixel[ALPHA]);
if (color_index)
{
+ format = gimp_pickable_get_format (pickable);
+
if (babl_format_is_palette (format) && ! sample_average)
- *color_index = pixel[0];
+ {
+ gimp_pickable_get_pixel_at (pickable, x, y, format, pixel);
+
+ *color_index = pixel[0];
+ }
else
- *color_index = -1;
+ {
+ *color_index = -1;
+ }
}
return TRUE;
diff --git a/app/core/gimppickable.h b/app/core/gimppickable.h
index 2477bd5..c894a81 100644
--- a/app/core/gimppickable.h
+++ b/app/core/gimppickable.h
@@ -44,7 +44,8 @@ struct _GimpPickableInterface
gboolean (* get_pixel_at) (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel);
+ const Babl *format,
+ gpointer pixel);
gint (* get_opacity_at) (GimpPickable *pickable,
gint x,
gint y);
@@ -62,7 +63,8 @@ TileManager * gimp_pickable_get_tiles (GimpPickable *pickable);
gboolean gimp_pickable_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel);
+ const Babl *format,
+ gpointer pixel);
gboolean gimp_pickable_get_color_at (GimpPickable *pickable,
gint x,
gint y,
diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c
index 406606c..028c485 100644
--- a/app/core/gimpprojection.c
+++ b/app/core/gimpprojection.c
@@ -67,7 +67,8 @@ static TileManager * gimp_projection_get_tiles (GimpPickable *picka
static gboolean gimp_projection_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel);
+ const Babl *format,
+ gpointer pixel);
static gint gimp_projection_get_opacity_at (GimpPickable *pickable,
gint x,
gint y);
@@ -338,7 +339,8 @@ static gboolean
gimp_projection_get_pixel_at (GimpPickable *pickable,
gint x,
gint y,
- guchar *pixel)
+ const Babl *format,
+ gpointer pixel)
{
GeglBuffer *buffer = gimp_projection_get_buffer (pickable);
@@ -348,8 +350,7 @@ gimp_projection_get_pixel_at (GimpPickable *pickable,
y >= gegl_buffer_get_height (buffer))
return FALSE;
- gegl_buffer_sample (buffer, x, y, NULL, pixel,
- gimp_projection_get_format (pickable),
+ gegl_buffer_sample (buffer, x, y, NULL, pixel, format,
GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]