changed to silently return in case of out-of-bounds access. There's code

2008-08-25  Sven Neumann  <sven@gimp.org>

	* app/base/tile-manager.c (read_pixel_data_1): changed to 
silently
	return in case of out-of-bounds access. There's code that relies
	on this.

	* app/base/pixel-surround.[ch]: added SMEAR as another edge
	strategy for the PixelSurround helper.

	* core/gimp-transform-region.c: changed accordingly.


svn path=/trunk/; revision=26767
This commit is contained in:
Sven Neumann 2008-08-25 20:38:52 +00:00 committed by Sven Neumann
parent 106072e3b8
commit 972309fe48
5 changed files with 89 additions and 28 deletions

View File

@ -1,3 +1,14 @@
2008-08-25 Sven Neumann <sven@gimp.org>
* app/base/tile-manager.c (read_pixel_data_1): changed to silently
return in case of out-of-bounds access. There's code that relies
on this.
* app/base/pixel-surround.[ch]: added SMEAR as another edge
strategy for the PixelSurround helper.
* core/gimp-transform-region.c: changed accordingly.
2008-08-25 Sven Neumann <sven@gimp.org>
* app/paint-funcs/scale-region.c: reverted last change; it was bogus.

View File

@ -33,6 +33,8 @@
struct _PixelSurround
{
TileManager *mgr; /* tile manager to access tiles from */
gint xmax; /* largest x coordinate in tile manager */
gint ymax; /* largest y coordinate in tile manager */
gint bpp; /* bytes per pixel in tile manager */
gint w; /* width of pixel surround area */
gint h; /* height of pixel surround area */
@ -44,6 +46,7 @@ struct _PixelSurround
gint rowstride; /* rowstride of buffers */
guchar *bg; /* buffer filled with background color */
guchar *buf; /* buffer used for combining tile data */
PixelSurroundMode mode;
};
@ -89,8 +92,37 @@ pixel_surround_get_data (PixelSurround *surround,
*rowstride = surround->tile_w * surround->bpp;
return tile_data_pointer (surround->tile,
x % TILE_WIDTH, y % TILE_HEIGHT);
return tile_data_pointer (surround->tile, x, y);
}
else if (surround->mode == PIXEL_SURROUND_SMEAR)
{
gint dummy;
if (x < 0)
{
x = 0;
*w = 1;
}
else if (x > surround->xmax)
{
x = surround->xmax;
*w = 1;
}
if (y < 0)
{
y = 0;
*h = 1;
}
else if (y > surround->ymax)
{
y = surround->ymax;
*h = 1;
}
/* call ourselves with corrected coordinates */
return pixel_surround_get_data (surround,
x, y, &dummy, &dummy, rowstride);
}
else
{
@ -121,29 +153,37 @@ pixel_surround_get_data (PixelSurround *surround,
* Return value: a new #PixelSurround.
*/
PixelSurround *
pixel_surround_new (TileManager *tiles,
gint width,
gint height,
const guchar bg[MAX_CHANNELS])
pixel_surround_new (TileManager *tiles,
gint width,
gint height,
PixelSurroundMode mode)
{
PixelSurround *surround;
guchar *dest;
gint pixels;
g_return_val_if_fail (tiles != NULL, NULL);
surround = g_slice_new0 (PixelSurround);
surround->mgr = tiles;
surround->xmax = tile_manager_width (surround->mgr) - 1;
surround->ymax = tile_manager_height (surround->mgr) - 1;
surround->bpp = tile_manager_bpp (tiles);
surround->w = width;
surround->h = height;
surround->rowstride = width * surround->bpp;
surround->bg = g_new (guchar, surround->rowstride * height);
surround->bg = g_new0 (guchar, surround->rowstride * height);
surround->buf = g_new (guchar, surround->rowstride * height);
surround->mode = mode;
dest = surround->bg;
pixels = width * height;
return surround;
}
void
pixel_surround_set_bg (PixelSurround *surround,
const guchar *bg)
{
guchar *dest = surround->bg;
gint pixels = surround->w * surround->h;
while (pixels--)
{
@ -152,8 +192,6 @@ pixel_surround_new (TileManager *tiles,
for (i = 0; i < surround->bpp; i++)
*dest++ = bg[i];
}
return surround;
}
/**

View File

@ -24,24 +24,31 @@
* region around a pixel in a tile manager
*/
typedef enum
{
PIXEL_SURROUND_SMEAR,
PIXEL_SURROUND_BACKGROUND
} PixelSurroundMode;
PixelSurround * pixel_surround_new (TileManager *tiles,
gint width,
gint height,
const guchar bg[MAX_CHANNELS]);
PixelSurround * pixel_surround_new (TileManager *tiles,
gint width,
gint height,
PixelSurroundMode mode);
void pixel_surround_set_bg (PixelSurround *surround,
const guchar *bg);
/* return a pointer to a buffer which contains all the surrounding pixels
* strategy: if we are in the middle of a tile, use the tile storage
* otherwise just copy into our own malloced buffer and return that
*/
const guchar * pixel_surround_lock (PixelSurround *surround,
gint x,
gint y,
gint *rowstride);
const guchar * pixel_surround_lock (PixelSurround *surround,
gint x,
gint y,
gint *rowstride);
void pixel_surround_release (PixelSurround *surround);
void pixel_surround_destroy (PixelSurround *surround);
void pixel_surround_release (PixelSurround *surround);
void pixel_surround_destroy (PixelSurround *surround);
#endif /* __PIXEL_SURROUND_H__ */

View File

@ -757,7 +757,8 @@ read_pixel_data_1 (TileManager *tm,
{
const gint num = tile_manager_get_tile_num (tm, x, y);
g_return_if_fail (num >= 0);
if (num < 0)
return;
if (num != tm->cached_num) /* must fetch a new tile */
{

View File

@ -394,7 +394,8 @@ gimp_transform_region_linear (TileManager *orig_tiles,
gint n;
gpointer pr;
surround = pixel_surround_new (orig_tiles, 2, 2, bg_color);
surround = pixel_surround_new (orig_tiles, 2, 2, PIXEL_SURROUND_BACKGROUND);
pixel_surround_set_bg (surround, bg_color);
uinc = m->coeff[0][0];
vinc = m->coeff[1][0];
@ -496,7 +497,8 @@ gimp_transform_region_cubic (TileManager *orig_tiles,
gint n;
gpointer pr;
surround = pixel_surround_new (orig_tiles, 4, 4, bg_color);
surround = pixel_surround_new (orig_tiles, 4, 4, PIXEL_SURROUND_BACKGROUND);
pixel_surround_set_bg (surround, bg_color);
uinc = m->coeff[0][0];
vinc = m->coeff[1][0];
@ -599,7 +601,9 @@ gimp_transform_region_lanczos (TileManager *orig_tiles,
gpointer pr;
surround = pixel_surround_new (orig_tiles,
LANCZOS_WIDTH2, LANCZOS_WIDTH2, bg_color);
LANCZOS_WIDTH2, LANCZOS_WIDTH2,
PIXEL_SURROUND_BACKGROUND);
pixel_surround_set_bg (surround, bg_color);
/* allocate and fill lanczos lookup table */
lanczos = create_lanczos_lookup ();