gimp r26769 - in trunk: . app/base
- From: neo svn gnome org
- To: svn-commits-list gnome org
- Subject: gimp r26769 - in trunk: . app/base
- Date: Tue, 26 Aug 2008 07:24:56 +0000 (UTC)
Author: neo
Date: Tue Aug 26 07:24:55 2008
New Revision: 26769
URL: http://svn.gnome.org/viewvc/gimp?rev=26769&view=rev
Log:
2008-08-26 Sven Neumann <sven gimp org>
* app/base/pixel-surround.c: attempt to fix the newly introduced
smear edge mode.
Modified:
trunk/ChangeLog
trunk/app/base/pixel-surround.c
Modified: trunk/app/base/pixel-surround.c
==============================================================================
--- trunk/app/base/pixel-surround.c (original)
+++ trunk/app/base/pixel-surround.c Tue Aug 26 07:24:55 2008
@@ -49,99 +49,13 @@
PixelSurroundMode mode;
};
+static const guchar * pixel_surround_get_data (PixelSurround *surround,
+ gint x,
+ gint y,
+ gint *w,
+ gint *h,
+ gint *rowstride);
-/* inlining this function gives a few percent speedup */
-static inline const guchar *
-pixel_surround_get_data (PixelSurround *surround,
- gint x,
- gint y,
- gint *w,
- gint *h,
- gint *rowstride)
-{
- /* do we still have a tile lock that we can use? */
- if (surround->tile)
- {
- if (x < surround->tile_x || x >= surround->tile_x + surround->tile_w ||
- y < surround->tile_y || y >= surround->tile_y + surround->tile_h)
- {
- tile_release (surround->tile, FALSE);
- surround->tile = NULL;
- }
- }
-
- /* if not, try to get one for the target pixel */
- if (! surround->tile)
- {
- surround->tile = tile_manager_get_tile (surround->mgr, x, y, TRUE, FALSE);
-
- if (surround->tile)
- {
- /* store offset and size of the locked tile */
- surround->tile_x = x & ~(TILE_WIDTH - 1);
- surround->tile_y = y & ~(TILE_HEIGHT - 1);
- surround->tile_w = tile_ewidth (surround->tile);
- surround->tile_h = tile_eheight (surround->tile);
- }
- }
-
- if (surround->tile)
- {
- *w = surround->tile_x + surround->tile_w - x;
- *h = surround->tile_y + surround->tile_h - y;
-
- *rowstride = surround->tile_w * surround->bpp;
-
- 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
- {
- /* return a pointer to a virtual background tile */
- if (x < 0)
- *w = MIN (- x, surround->w);
- else
- *w = surround->w;
-
- if (y < 0)
- *h = MIN (- y, surround->h);
- else
- *h = surround->h;
-
- *rowstride = surround->rowstride;
-
- return surround->bg;
- }
-}
/**
* pixel_surround_new:
@@ -319,3 +233,177 @@
g_slice_free (PixelSurround, surround);
}
+
+
+enum
+{
+ LEFT = 1 << 0,
+ RIGHT = 1 << 1,
+ TOP = 1 << 2,
+ BOTTOM = 1 << 3
+};
+
+static void
+pixel_surround_fill_row (PixelSurround *surround,
+ const guchar *src,
+ gint w)
+{
+ guchar *dest = surround->bg;
+ gint bytes = MIN (w, surround->w) * surround->bpp;
+ gint rows = surround->h;
+
+ while (rows--)
+ {
+ memcpy (dest, src, bytes);
+ dest += surround->rowstride;
+ }
+}
+
+static void
+pixel_surround_fill_col (PixelSurround *surround,
+ const guchar *src,
+ gint rowstride,
+ gint h)
+{
+ guchar *dest = surround->bg;
+ gint cols = surround->w;
+ gint rows = MIN (h, surround->h);
+
+ while (cols--)
+ {
+ const guchar *s = src;
+ guchar *d = dest;
+ gint r = rows;
+
+ while (r--)
+ {
+ memcpy (d, s, surround->bpp);
+
+ s += rowstride;
+ d += surround->rowstride;
+ }
+
+ dest += surround->bpp;
+ }
+}
+
+static const guchar *
+pixel_surround_get_data (PixelSurround *surround,
+ gint x,
+ gint y,
+ gint *w,
+ gint *h,
+ gint *rowstride)
+{
+ /* do we still have a tile lock that we can use? */
+ if (surround->tile)
+ {
+ if (x < surround->tile_x || x >= surround->tile_x + surround->tile_w ||
+ y < surround->tile_y || y >= surround->tile_y + surround->tile_h)
+ {
+ tile_release (surround->tile, FALSE);
+ surround->tile = NULL;
+ }
+ }
+
+ /* if not, try to get one for the target pixel */
+ if (! surround->tile)
+ {
+ surround->tile = tile_manager_get_tile (surround->mgr, x, y, TRUE, FALSE);
+
+ if (surround->tile)
+ {
+ /* store offset and size of the locked tile */
+ surround->tile_x = x & ~(TILE_WIDTH - 1);
+ surround->tile_y = y & ~(TILE_HEIGHT - 1);
+ surround->tile_w = tile_ewidth (surround->tile);
+ surround->tile_h = tile_eheight (surround->tile);
+ }
+ }
+
+ if (surround->tile)
+ {
+ *w = surround->tile_x + surround->tile_w - x;
+ *h = surround->tile_y + surround->tile_h - y;
+
+ *rowstride = surround->tile_w * surround->bpp;
+
+ return tile_data_pointer (surround->tile, x, y);
+ }
+
+ switch (surround->mode)
+ {
+ case PIXEL_SURROUND_SMEAR:
+ {
+ const guchar *edata;
+ gint ex = x;
+ gint ey = y;
+ gint estride;
+ gint ecode = 0;
+
+ if (ex < 0)
+ {
+ ex = 0;
+ ecode |= LEFT;
+ }
+ else if (ex > surround->xmax)
+ {
+ ex = surround->xmax;
+ ecode |= RIGHT;
+ }
+
+ if (ey < 0)
+ {
+ ey = 0;
+ ecode |= TOP;
+ }
+ else if (ey > surround->ymax)
+ {
+ ey = surround->ymax;
+ ecode |= BOTTOM;
+ }
+
+ /* call ourselves with corrected coordinates */
+ edata = pixel_surround_get_data (surround, ex, ey, w, h, &estride);
+
+ /* fill the virtual background tile */
+ switch (ecode)
+ {
+ case (TOP | LEFT):
+ case (TOP | RIGHT):
+ case (BOTTOM | LEFT):
+ case (BOTTOM | RIGHT):
+ pixel_surround_set_bg (surround, edata);
+ break;
+
+ case (TOP):
+ case (BOTTOM):
+ pixel_surround_fill_row (surround, edata, *w);
+ break;
+
+ case (LEFT):
+ case (RIGHT):
+ pixel_surround_fill_col (surround, edata, estride, *h);
+ break;
+ }
+ }
+ break;
+
+ case PIXEL_SURROUND_BACKGROUND:
+ if (x < 0)
+ *w = MIN (- x, surround->w);
+ else
+ *w = surround->w;
+ if (y < 0)
+ *h = MIN (- y, surround->h);
+ else
+ *h = surround->h;
+ break;
+ }
+
+ /* return a pointer to the virtual background tile */
+
+ *rowstride = surround->rowstride;
+
+ return surround->bg;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]