mirror of https://github.com/GNOME/gimp.git
added get_pixel_at() method to the GimpPickable interface. This gives
2007-04-27 Sven Neumann <sven@gimp.org> * app/core/gimppickable.[ch]: added get_pixel_at() method to the GimpPickable interface. This gives direct access to the pixel without converting it to an RGB color. * app/core/gimpdrawable.c * app/core/gimpimagemap.c * app/core/gimpprojection.c: implement the new method and also use it to reimplement get_color_at(). * app/core/gimpimage-crop.c (gimp_image_crop_guess_bgcolor): use gimp_pickable_get_pixel_at(). Fixes auto-shrink on indexed and grayscale images. svn path=/trunk/; revision=22359
This commit is contained in:
parent
7b7affa9b0
commit
7c1fc759f5
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2007-04-27 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/core/gimppickable.[ch]: added get_pixel_at() method to the
|
||||
GimpPickable interface. This gives direct access to the pixel
|
||||
without converting it to an RGB color.
|
||||
|
||||
* app/core/gimpdrawable.c
|
||||
* app/core/gimpimagemap.c
|
||||
* app/core/gimpprojection.c: implement the new method and also use
|
||||
it to reimplement get_color_at().
|
||||
|
||||
* app/core/gimpimage-crop.c (gimp_image_crop_guess_bgcolor): use
|
||||
gimp_pickable_get_pixel_at(). Fixes auto-shrink on indexed and
|
||||
grayscale images.
|
||||
|
||||
2007-04-27 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* plug-ins/common/sunras.c (set_color_table): guard against a
|
||||
|
|
|
@ -115,6 +115,10 @@ static void gimp_drawable_transform (GimpItem *item,
|
|||
GimpTransformResize clip_result,
|
||||
GimpProgress *progress);
|
||||
|
||||
static gboolean gimp_drawable_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel);
|
||||
static guchar * gimp_drawable_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y);
|
||||
|
@ -236,6 +240,7 @@ gimp_drawable_pickable_iface_init (GimpPickableInterface *iface)
|
|||
iface->get_image_type = (GimpImageType (*) (GimpPickable *pickable)) gimp_drawable_type;
|
||||
iface->get_bytes = (gint (*) (GimpPickable *pickable)) gimp_drawable_bytes;
|
||||
iface->get_tiles = (TileManager * (*) (GimpPickable *pickable)) gimp_drawable_get_tiles;
|
||||
iface->get_pixel_at = gimp_drawable_get_pixel_at;
|
||||
iface->get_color_at = gimp_drawable_get_color_at;
|
||||
}
|
||||
|
||||
|
@ -588,37 +593,47 @@ gimp_drawable_transform (GimpItem *item,
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_drawable_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel)
|
||||
{
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (pickable);
|
||||
|
||||
/* do not make this a g_return_if_fail() */
|
||||
if (x < 0 || x >= GIMP_ITEM (drawable)->width ||
|
||||
y < 0 || y >= GIMP_ITEM (drawable)->height)
|
||||
return FALSE;
|
||||
|
||||
read_pixel_data_1 (gimp_drawable_get_tiles (drawable), x, y, pixel);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guchar *
|
||||
gimp_drawable_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (pickable);
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
|
||||
Tile *tile;
|
||||
guchar *src;
|
||||
guchar *dest;
|
||||
guchar pixel[4];
|
||||
|
||||
/* do not make this a g_return_if_fail() */
|
||||
if (x < 0 || x >= GIMP_ITEM (drawable)->width ||
|
||||
y < 0 || y >= GIMP_ITEM (drawable)->height)
|
||||
if (! gimp_drawable_get_pixel_at (pickable, x, y, pixel))
|
||||
return NULL;
|
||||
|
||||
dest = g_new (guchar, 5);
|
||||
|
||||
tile = tile_manager_get_tile (gimp_drawable_get_tiles (drawable), x, y,
|
||||
TRUE, FALSE);
|
||||
src = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
|
||||
|
||||
gimp_image_get_color (image, gimp_drawable_type (drawable), src, dest);
|
||||
gimp_image_get_color (gimp_item_get_image (GIMP_ITEM (drawable)),
|
||||
gimp_drawable_type (drawable),
|
||||
pixel, dest);
|
||||
|
||||
if (gimp_drawable_is_indexed (drawable))
|
||||
dest[4] = src[0];
|
||||
dest[4] = pixel[0];
|
||||
else
|
||||
dest[4] = 0;
|
||||
|
||||
tile_release (tile, FALSE);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
|
|
@ -429,12 +429,11 @@ gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
|
|||
gint y1,
|
||||
gint y2)
|
||||
{
|
||||
AutoCropType retval = AUTO_CROP_NOTHING;
|
||||
guchar *tl = NULL;
|
||||
guchar *tr = NULL;
|
||||
guchar *bl = NULL;
|
||||
guchar *br = NULL;
|
||||
gint i;
|
||||
guchar tl[4];
|
||||
guchar tr[4];
|
||||
guchar bl[4];
|
||||
guchar br[4];
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < bytes; i++)
|
||||
color[i] = 0;
|
||||
|
@ -443,11 +442,13 @@ gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
|
|||
* background-color to see if at least 2 corners are equal.
|
||||
*/
|
||||
|
||||
if (! (tl = gimp_pickable_get_color_at (pickable, x1, y1)) ||
|
||||
! (tr = gimp_pickable_get_color_at (pickable, x1, y2)) ||
|
||||
! (bl = gimp_pickable_get_color_at (pickable, x2, y1)) ||
|
||||
! (br = gimp_pickable_get_color_at (pickable, x2, y2)))
|
||||
goto done;
|
||||
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)
|
||||
{
|
||||
|
@ -458,8 +459,7 @@ gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
|
|||
(tr[alpha] == 0 && br[alpha] == 0) ||
|
||||
(bl[alpha] == 0 && br[alpha] == 0))
|
||||
{
|
||||
retval = AUTO_CROP_ALPHA;
|
||||
goto done;
|
||||
return AUTO_CROP_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,22 +467,17 @@ gimp_image_crop_guess_bgcolor (GimpPickable *pickable,
|
|||
gimp_image_crop_colors_equal (tl, bl, bytes))
|
||||
{
|
||||
memcpy (color, tl, bytes);
|
||||
retval = AUTO_CROP_COLOR;
|
||||
return AUTO_CROP_COLOR;
|
||||
}
|
||||
else if (gimp_image_crop_colors_equal (br, bl, bytes) ||
|
||||
|
||||
if (gimp_image_crop_colors_equal (br, bl, bytes) ||
|
||||
gimp_image_crop_colors_equal (br, tr, bytes))
|
||||
{
|
||||
memcpy (color, br, bytes);
|
||||
retval = AUTO_CROP_COLOR;
|
||||
return AUTO_CROP_COLOR;
|
||||
}
|
||||
|
||||
done:
|
||||
g_free (tl);
|
||||
g_free (tr);
|
||||
g_free (bl);
|
||||
g_free (br);
|
||||
|
||||
return retval;
|
||||
return AUTO_CROP_NOTHING;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -69,6 +69,10 @@ static GimpImage * gimp_image_map_get_image (GimpPickable *pickable);
|
|||
static GimpImageType gimp_image_map_get_image_type (GimpPickable *pickable);
|
||||
static gint gimp_image_map_get_bytes (GimpPickable *pickable);
|
||||
static TileManager * gimp_image_map_get_tiles (GimpPickable *pickable);
|
||||
static gboolean gimp_image_map_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel);
|
||||
static guchar * gimp_image_map_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y);
|
||||
|
@ -109,6 +113,7 @@ gimp_image_map_pickable_iface_init (GimpPickableInterface *iface)
|
|||
iface->get_image_type = gimp_image_map_get_image_type;
|
||||
iface->get_bytes = gimp_image_map_get_bytes;
|
||||
iface->get_tiles = gimp_image_map_get_tiles;
|
||||
iface->get_pixel_at = gimp_image_map_get_pixel_at;
|
||||
iface->get_color_at = gimp_image_map_get_color_at;
|
||||
}
|
||||
|
||||
|
@ -190,10 +195,11 @@ gimp_image_map_get_tiles (GimpPickable *pickable)
|
|||
return gimp_pickable_get_tiles (GIMP_PICKABLE (image_map->drawable));
|
||||
}
|
||||
|
||||
static guchar *
|
||||
gimp_image_map_get_color_at (GimpPickable *pickable,
|
||||
static gboolean
|
||||
gimp_image_map_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y)
|
||||
gint y,
|
||||
guchar *pixel)
|
||||
{
|
||||
GimpImageMap *image_map = GIMP_IMAGE_MAP (pickable);
|
||||
GimpItem *item = GIMP_ITEM (image_map->drawable);
|
||||
|
@ -212,38 +218,50 @@ gimp_image_map_get_color_at (GimpPickable *pickable,
|
|||
if (x >= offset_x && x < offset_x + width &&
|
||||
y >= offset_y && y < offset_y + height)
|
||||
{
|
||||
guchar src[5];
|
||||
guchar *dest;
|
||||
|
||||
dest = g_new (guchar, 5);
|
||||
|
||||
read_pixel_data_1 (image_map->undo_tiles,
|
||||
x - offset_x,
|
||||
y - offset_y,
|
||||
src);
|
||||
pixel);
|
||||
|
||||
gimp_image_get_color (gimp_item_get_image (item),
|
||||
gimp_drawable_type (image_map->drawable),
|
||||
src, dest);
|
||||
|
||||
if (gimp_drawable_is_indexed (image_map->drawable))
|
||||
dest[4] = src[0];
|
||||
else
|
||||
dest[4] = 0;
|
||||
|
||||
return dest;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return gimp_pickable_get_color_at (GIMP_PICKABLE (image_map->drawable),
|
||||
x, y);
|
||||
return gimp_pickable_get_pixel_at (GIMP_PICKABLE (image_map->drawable),
|
||||
x, y, pixel);
|
||||
}
|
||||
else /* out of bounds error */
|
||||
{
|
||||
return NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static guchar *
|
||||
gimp_image_map_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GimpImageMap *image_map = GIMP_IMAGE_MAP (pickable);
|
||||
guchar *dest;
|
||||
guchar pixel[4];
|
||||
|
||||
if (! gimp_image_map_get_pixel_at (pickable, x, y, pixel))
|
||||
return NULL;
|
||||
|
||||
dest = g_new (guchar, 5);
|
||||
|
||||
gimp_image_get_color (gimp_item_get_image (GIMP_ITEM (image_map->drawable)),
|
||||
gimp_drawable_type (image_map->drawable),
|
||||
pixel, dest);
|
||||
|
||||
if (gimp_drawable_is_indexed (image_map->drawable))
|
||||
dest[4] = pixel[0];
|
||||
else
|
||||
dest[4] = 0;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
GimpImageMap *
|
||||
gimp_image_map_new (GimpDrawable *drawable,
|
||||
const gchar *undo_desc)
|
||||
|
|
|
@ -129,6 +129,25 @@ gimp_pickable_get_tiles (GimpPickable *pickable)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_pickable_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel)
|
||||
{
|
||||
GimpPickableInterface *pickable_iface;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_PICKABLE (pickable), FALSE);
|
||||
g_return_val_if_fail (pixel != NULL, FALSE);
|
||||
|
||||
pickable_iface = GIMP_PICKABLE_GET_INTERFACE (pickable);
|
||||
|
||||
if (pickable_iface->get_pixel_at)
|
||||
return pickable_iface->get_pixel_at (pickable, x, y, pixel);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
guchar *
|
||||
gimp_pickable_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
|
|
|
@ -41,6 +41,10 @@ struct _GimpPickableInterface
|
|||
GimpImageType (* get_image_type) (GimpPickable *pickable);
|
||||
gint (* get_bytes) (GimpPickable *pickable);
|
||||
TileManager * (* get_tiles) (GimpPickable *pickable);
|
||||
gboolean (* get_pixel_at) (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel);
|
||||
guchar * (* get_color_at) (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y);
|
||||
|
@ -57,6 +61,10 @@ GimpImage * gimp_pickable_get_image (GimpPickable *pickable);
|
|||
GimpImageType gimp_pickable_get_image_type (GimpPickable *pickable);
|
||||
gint gimp_pickable_get_bytes (GimpPickable *pickable);
|
||||
TileManager * gimp_pickable_get_tiles (GimpPickable *pickable);
|
||||
gboolean gimp_pickable_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel);
|
||||
guchar * gimp_pickable_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y);
|
||||
|
|
|
@ -51,6 +51,10 @@ static gint64 gimp_projection_get_memsize (GimpObject *object,
|
|||
gint64 *gui_size);
|
||||
|
||||
static void gimp_projection_pickable_flush (GimpPickable *pickable);
|
||||
static gboolean gimp_projection_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel);
|
||||
static guchar * gimp_projection_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y);
|
||||
|
@ -158,6 +162,7 @@ gimp_projection_pickable_iface_init (GimpPickableInterface *iface)
|
|||
iface->get_image_type = (GimpImageType (*) (GimpPickable *pickable)) gimp_projection_get_image_type;
|
||||
iface->get_bytes = (gint (*) (GimpPickable *pickable)) gimp_projection_get_bytes;
|
||||
iface->get_tiles = (TileManager * (*) (GimpPickable *pickable)) gimp_projection_get_tiles;
|
||||
iface->get_pixel_at = gimp_projection_get_pixel_at;
|
||||
iface->get_color_at = gimp_projection_get_color_at;
|
||||
iface->get_opacity_at = gimp_projection_get_opacity_at;
|
||||
}
|
||||
|
@ -211,28 +216,39 @@ gimp_projection_pickable_flush (GimpPickable *pickable)
|
|||
gimp_projection_flush_now (proj);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_projection_get_pixel_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y,
|
||||
guchar *pixel)
|
||||
{
|
||||
GimpProjection *proj = GIMP_PROJECTION (pickable);
|
||||
|
||||
if (x < 0 || y < 0 || x >= proj->image->width || y >= proj->image->height)
|
||||
return FALSE;
|
||||
|
||||
read_pixel_data_1 (gimp_projection_get_tiles (proj), x, y, pixel);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static guchar *
|
||||
gimp_projection_get_color_at (GimpPickable *pickable,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
GimpProjection *proj = GIMP_PROJECTION (pickable);
|
||||
Tile *tile;
|
||||
guchar *src;
|
||||
guchar *dest;
|
||||
guchar pixel[4];
|
||||
|
||||
if (x < 0 || y < 0 || x >= proj->image->width || y >= proj->image->height)
|
||||
if (! gimp_projection_get_pixel_at (pickable, x, y, pixel))
|
||||
return NULL;
|
||||
|
||||
dest = g_new (guchar, 5);
|
||||
tile = tile_manager_get_tile (gimp_projection_get_tiles (proj),
|
||||
x, y, TRUE, FALSE);
|
||||
src = tile_data_pointer (tile, x % TILE_WIDTH, y % TILE_HEIGHT);
|
||||
gimp_image_get_color (proj->image, gimp_projection_get_image_type (proj),
|
||||
src, dest);
|
||||
|
||||
gimp_image_get_color (proj->image, gimp_projection_get_image_type (proj),
|
||||
pixel, dest);
|
||||
dest[4] = 0;
|
||||
tile_release (tile, FALSE);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue