Commit 09454fb2 authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

some general cleanup.

2005-09-03  Michael Natterer  <mitch@gimp.org>

	* app/base/pixel-region.[ch]: some general cleanup.

	(pixel_region_init_temp_buf)
	(pixel_region_init_data): new functions which initialize pixel
	regions on TempBufs and on raw contiguous arrays of pixel data.

	(pixel_region_configure): fixed a bug that has probably been there
	forever: when processing contiguous (non-tiled) data, interpret
	the original x and y coordinates of the region as offsets into
	the data. Before this fix, the initial x and y were simply ignored
	(by using them in a broken way), thus always forcing the upper
	left corner of the region being the beginning of the passed data.

	Lots of code was working around this problem by setting the
	pixel_region's data pointer to the proper starting pixel of the
	region in the middle the buffer.

	* libgimp/gimppixelrgn.c: some general cleanup.

	(gimp_pixel_rgn_configure): same fix as above. Fortunately, nobody
	seems to know that libgimp pixel regions can be used on arrays of
	data, just as core ones. Only two plug-ins were using this
	feature, and they are antique and written by spencer and federico,
	respectively. They both don't use offsets into the buffers and are
	not affected by this change. It's highly unlikely that anybody out
	there knows/uses this feature, so it can IMHO be safely changed.

	* app/base/temp-buf.c
	* app/core/gimpbuffer.c
	* app/core/gimpdrawable-combine.c
	* app/core/gimpdrawable-preview.c
	* app/core/gimpimage-preview.c
	* app/core/gimplayer.c
	* app/paint/gimpbrushcore.c
	* app/paint/gimpclone.c
	* app/paint/gimpconvolve.c
	* app/paint/gimpdodgeburn.c
	* app/paint/gimppaintcore.c
	* app/paint/gimpsmudge.c
	* app/tools/gimpiscissorstool.c
	* app/tools/gimppainttool.c: use the pixel_region_init_foo()
	functions instead of initializing regions of TempBufs and raw data
	manually. Removed lots of workarounds for the broken offset
	handling. The changed places of code are much more readable now.
parent 760a2eca
2005-09-03 Michael Natterer <mitch@gimp.org>
* app/base/pixel-region.[ch]: some general cleanup.
(pixel_region_init_temp_buf)
(pixel_region_init_data): new functions which initialize pixel
regions on TempBufs and on raw contiguous arrays of pixel data.
(pixel_region_configure): fixed a bug that has probably been there
forever: when processing contiguous (non-tiled) data, interpret
the original x and y coordinates of the region as offsets into
the data. Before this fix, the initial x and y were simply ignored
(by using them in a broken way), thus always forcing the upper
left corner of the region being the beginning of the passed data.
Lots of code was working around this problem by setting the
pixel_region's data pointer to the proper starting pixel of the
region in the middle the buffer.
* libgimp/gimppixelrgn.c: some general cleanup.
(gimp_pixel_rgn_configure): same fix as above. Fortunately, nobody
seems to know that libgimp pixel regions can be used on arrays of
data, just as core ones. Only two plug-ins were using this
feature, and they are antique and written by spencer and federico,
respectively. They both don't use offsets into the buffers and are
not affected by this change. It's highly unlikely that anybody out
there knows/uses this feature, so it can IMHO be safely changed.
* app/base/temp-buf.c
* app/core/gimpbuffer.c
* app/core/gimpdrawable-combine.c
* app/core/gimpdrawable-preview.c
* app/core/gimpimage-preview.c
* app/core/gimplayer.c
* app/paint/gimpbrushcore.c
* app/paint/gimpclone.c
* app/paint/gimpconvolve.c
* app/paint/gimpdodgeburn.c
* app/paint/gimppaintcore.c
* app/paint/gimpsmudge.c
* app/tools/gimpiscissorstool.c
* app/tools/gimppainttool.c: use the pixel_region_init_foo()
functions instead of initializing regions of TempBufs and raw data
manually. Removed lots of workarounds for the broken offset
handling. The changed places of code are much more readable now.
2005-09-03 Sven Neumann <sven@gimp.org>
* app/tools/gimpcolorbalancetool.c
......
......@@ -26,6 +26,7 @@
#include "base-types.h"
#include "pixel-region.h"
#include "temp-buf.h"
#include "tile-manager.h"
#include "tile.h"
......@@ -52,16 +53,67 @@ pixel_region_init (PixelRegion *PR,
gint h,
gboolean dirty)
{
PR->tiles = tiles;
PR->curtile = NULL;
PR->data = NULL;
PR->bytes = tile_manager_bpp (tiles);
PR->rowstride = PR->bytes * TILE_WIDTH;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = dirty;
PR->data = NULL;
PR->tiles = tiles;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = tile_manager_bpp (tiles);
PR->rowstride = PR->bytes * TILE_WIDTH;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = dirty;
PR->process_count = 0;
}
void
pixel_region_init_temp_buf (PixelRegion *PR,
TempBuf *temp_buf,
gint x,
gint y,
gint w,
gint h)
{
PR->data = temp_buf_data (temp_buf);
PR->tiles = NULL;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = temp_buf->bytes;
PR->rowstride = temp_buf->width * temp_buf->bytes;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = FALSE;
PR->process_count = 0;
}
void
pixel_region_init_data (PixelRegion *PR,
guchar *data,
gint bytes,
gint rowstride,
gint x,
gint y,
gint w,
gint h)
{
PR->data = data;
PR->tiles = NULL;
PR->curtile = NULL;
PR->offx = 0;
PR->offy = 0;
PR->bytes = bytes;
PR->rowstride = rowstride;
PR->x = x;
PR->y = y;
PR->w = w;
PR->h = h;
PR->dirty = FALSE;
PR->process_count = 0;
}
void
......@@ -73,9 +125,8 @@ pixel_region_resize (PixelRegion *PR,
{
/* If the data is non-null, data is contiguous--need to advance */
if (PR->data != NULL)
{
PR->data += (y - PR->y) * PR->rowstride + (x - PR->x) * PR->bytes;
}
PR->data += ((y - PR->y) * PR->rowstride +
(x - PR->x) * PR->bytes);
/* update sizes for both contiguous and tiled regions */
PR->x = x;
......@@ -251,23 +302,24 @@ PixelRegionIterator *
pixel_regions_register (gint num_regions,
...)
{
PixelRegion *PR;
PixelRegionHolder *PRH;
PixelRegionIterator *PRI;
gboolean found;
va_list ap;
PRI = g_new0 (PixelRegionIterator, 1);
PRI->dirty_tiles = 1;
if (num_regions < 1)
return NULL;
PRI = g_new0 (PixelRegionIterator, 1);
PRI->dirty_tiles = 1;
va_start (ap, num_regions);
found = FALSE;
while (num_regions --)
{
PixelRegionHolder *PRH;
PixelRegion *PR;
PR = va_arg (ap, PixelRegion *);
PRH = g_new0 (PixelRegionHolder, 1);
......@@ -279,9 +331,9 @@ pixel_regions_register (gint num_regions,
if (PR->data)
PR->tiles = NULL;
PRH->original_data = PR->data;
PRH->startx = PR->x;
PRH->starty = PR->y;
PRH->original_data = PR->data;
PRH->startx = PR->x;
PRH->starty = PR->y;
PRH->PR->process_count = 0;
if (!found)
......@@ -305,8 +357,7 @@ pixel_regions_register (gint num_regions,
PixelRegionIterator *
pixel_regions_process (PixelRegionIterator *PRI)
{
GSList *list;
PixelRegionHolder *PRH;
GSList *list;
PRI->process_count++;
......@@ -314,7 +365,7 @@ pixel_regions_process (PixelRegionIterator *PRI)
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PRH = (PixelRegionHolder *) list->data;
PixelRegionHolder *PRH = list->data;
if ((PRH->PR != NULL) && (PRH->PR->process_count != PRI->process_count))
{
......@@ -337,7 +388,7 @@ pixel_regions_process (PixelRegionIterator *PRI)
if ((PRH->PR->x - PRH->startx) >= PRI->region_width)
{
PRH->PR->x = PRH->startx;
PRH->PR->x = PRH->startx;
PRH->PR->y += PRI->portion_height;
}
}
......@@ -349,8 +400,7 @@ pixel_regions_process (PixelRegionIterator *PRI)
void
pixel_regions_process_stop (PixelRegionIterator *PRI)
{
GSList *list;
PixelRegionHolder *PRH;
GSList *list;
PRI->process_count++;
......@@ -358,7 +408,7 @@ pixel_regions_process_stop (PixelRegionIterator *PRI)
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PRH = (PixelRegionHolder *) list->data;
PixelRegionHolder *PRH = list->data;
if ((PRH->PR != NULL) && (PRH->PR->process_count != PRI->process_count))
{
......@@ -394,10 +444,9 @@ pixel_regions_process_stop (PixelRegionIterator *PRI)
static gint
get_portion_height (PixelRegionIterator *PRI)
{
GSList *list;
PixelRegionHolder *PRH;
gint min_height = G_MAXINT;
gint height;
GSList *list;
gint min_height = G_MAXINT;
gint height;
/* Find the minimum height to the next vertical tile
* (in the case of a tile manager) or to the end of the
......@@ -406,7 +455,7 @@ get_portion_height (PixelRegionIterator *PRI)
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PRH = (PixelRegionHolder *) list->data;
PixelRegionHolder *PRH = list->data;
if (PRH->PR)
{
......@@ -422,7 +471,9 @@ get_portion_height (PixelRegionIterator *PRI)
(PRI->region_height - (PRH->PR->y - PRH->starty)));
}
else
height = (PRI->region_height - (PRH->PR->y - PRH->starty));
{
height = (PRI->region_height - (PRH->PR->y - PRH->starty));
}
if (height < min_height)
min_height = height;
......@@ -436,10 +487,9 @@ get_portion_height (PixelRegionIterator *PRI)
static gint
get_portion_width (PixelRegionIterator *PRI)
{
GSList *list;
PixelRegionHolder *PRH;
gint min_width = G_MAXINT;
gint width;
GSList *list;
gint min_width = G_MAXINT;
gint width;
/* Find the minimum width to the next vertical tile
* (in the case of a tile manager) or to the end of
......@@ -448,7 +498,7 @@ get_portion_width (PixelRegionIterator *PRI)
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PRH = (PixelRegionHolder *) list->data;
PixelRegionHolder *PRH = list->data;
if (PRH->PR)
{
......@@ -464,7 +514,9 @@ get_portion_width (PixelRegionIterator *PRI)
(PRI->region_width - (PRH->PR->x - PRH->startx)));
}
else
width = (PRI->region_width - (PRH->PR->x - PRH->startx));
{
width = (PRI->region_width - (PRH->PR->x - PRH->startx));
}
if (width < min_width)
min_width = width;
......@@ -478,14 +530,14 @@ get_portion_width (PixelRegionIterator *PRI)
static PixelRegionIterator *
pixel_regions_configure (PixelRegionIterator *PRI)
{
PixelRegionHolder *PRH;
GSList *list;
GSList *list;
/* Determine the portion width and height */
PRI->portion_width = get_portion_width (PRI);
PRI->portion_height = get_portion_height (PRI);
if (PRI->portion_width == 0 || PRI->portion_height == 0)
if (PRI->portion_width == 0 ||
PRI->portion_height == 0)
{
/* free the pixel regions list */
if (PRI->pixel_regions)
......@@ -504,7 +556,7 @@ pixel_regions_configure (PixelRegionIterator *PRI)
for (list = PRI->pixel_regions; list; list = g_slist_next (list))
{
PRH = (PixelRegionHolder *) list->data;
PixelRegionHolder *PRH = list->data;
if ((PRH->PR != NULL) && (PRH->PR->process_count != PRI->process_count))
{
......@@ -543,9 +595,9 @@ pixel_region_configure (PixelRegionHolder *PRH,
}
else
{
PRH->PR->data = PRH->original_data +
(PRH->PR->y - PRH->starty) * PRH->PR->rowstride +
(PRH->PR->x - PRH->startx) * PRH->PR->bytes;
PRH->PR->data = (PRH->original_data +
PRH->PR->y * PRH->PR->rowstride +
PRH->PR->x * PRH->PR->bytes);
}
PRH->PR->w = PRI->portion_width;
......
......@@ -60,48 +60,62 @@ struct _PixelRegionIterator
/* PixelRegion functions */
void pixel_region_init (PixelRegion *PR,
TileManager *tiles,
gint x,
gint y,
gint w,
gint h,
void pixel_region_init (PixelRegion *PR,
TileManager *tiles,
gint x,
gint y,
gint w,
gint h,
gboolean dirty);
void pixel_region_resize (PixelRegion *PR,
gint x,
gint y,
gint w,
void pixel_region_init_temp_buf (PixelRegion *PR,
TempBuf *temp_buf,
gint x,
gint y,
gint w,
gint h);
void pixel_region_init_data (PixelRegion *PR,
guchar *data,
gint bytes,
gint rowstride,
gint x,
gint y,
gint w,
gint h);
void pixel_region_resize (PixelRegion *PR,
gint x,
gint y,
gint w,
gint h);
void pixel_region_get_async (PixelRegion *PR,
gint ulx,
gint uly,
gint lrx,
void pixel_region_get_async (PixelRegion *PR,
gint ulx,
gint uly,
gint lrx,
gint lry);
void pixel_region_get_row (PixelRegion *PR,
gint x,
gint y,
gint w,
guchar *data,
void pixel_region_get_row (PixelRegion *PR,
gint x,
gint y,
gint w,
guchar *data,
gint subsample);
void pixel_region_set_row (PixelRegion *PR,
gint x,
gint y,
gint w,
void pixel_region_set_row (PixelRegion *PR,
gint x,
gint y,
gint w,
guchar *data);
void pixel_region_get_col (PixelRegion *PR,
gint x,
gint y,
gint h,
guchar *data,
void pixel_region_get_col (PixelRegion *PR,
gint x,
gint y,
gint h,
guchar *data,
gint subsample);
void pixel_region_set_col (PixelRegion *PR,
gint x,
gint y,
gint h,
void pixel_region_set_col (PixelRegion *PR,
gint x,
gint y,
gint h,
guchar *data);
gboolean pixel_region_has_alpha (PixelRegion *PR);
PixelRegionIterator * pixel_regions_register (gint num_regions,
PixelRegionIterator * pixel_regions_register (gint num_regions,
...);
PixelRegionIterator * pixel_regions_process (PixelRegionIterator *PRI);
void pixel_regions_process_stop (PixelRegionIterator *PRI);
......
......@@ -448,17 +448,8 @@ temp_buf_copy_area (TempBuf *src,
}
/* Copy the region */
srcPR.bytes = src->bytes;
srcPR.w = width;
srcPR.h = height;
srcPR.rowstride = src->bytes * src->width;
srcPR.data = temp_buf_data (src) + (y1 * srcPR.rowstride +
x1 * srcPR.bytes);
destPR.bytes = dest->bytes;
destPR.rowstride = new->bytes * new->width;
destPR.data = temp_buf_data (new) + (dest_y * destPR.rowstride +
dest_x * destPR.bytes);
pixel_region_init_temp_buf (&srcPR, src, x1, y1, width, height);
pixel_region_init_temp_buf (&destPR, new, dest_x, dest_y, width, height);
copy_region (&srcPR, &destPR);
......
......@@ -252,13 +252,8 @@ gimp_buffer_get_new_preview (GimpViewable *viewable,
else
temp_buf = temp_buf_new (buffer_width, buffer_height, bytes, 0, 0, NULL);
destPR.bytes = temp_buf->bytes;
destPR.x = 0;
destPR.y = 0;
destPR.w = temp_buf->width;
destPR.h = temp_buf->height;
destPR.rowstride = temp_buf->width * destPR.bytes;
destPR.data = temp_buf_data (temp_buf);
pixel_region_init_temp_buf (&destPR, temp_buf,
0, 0, temp_buf->width, temp_buf->height);
if (buffer_height > height || buffer_width > width)
{
......
......@@ -252,30 +252,20 @@ gimp_drawable_real_replace_region (GimpDrawable *drawable,
(x2 - x1), (y2 - y1),
FALSE);
tempPR.bytes = 1;
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = x2 - x1;
tempPR.h = y2 - y1;
tempPR.rowstride = tempPR.w * tempPR.bytes;
tempPR.data = temp_data = g_malloc (tempPR.h * tempPR.rowstride);
temp_data = g_malloc ((y2 - y1) * (x2 - x1));
pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
0, 0, x2 - x1, y2 - y1);
copy_region (&mask2PR, &tempPR);
/* apparently, region operations can mutate some PR data. */
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = x2 - x1;
tempPR.h = y2 - y1;
tempPR.data = temp_data;
pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
0, 0, x2 - x1, y2 - y1);
apply_mask_to_region (&tempPR, maskPR, OPAQUE_OPACITY);
tempPR.x = 0;
tempPR.y = 0;
tempPR.w = x2 - x1;
tempPR.h = y2 - y1;
tempPR.data = temp_data;
pixel_region_init_data (&tempPR, temp_data, 1, x2 - x1,
0, 0, x2 - x1, y2 - y1);
combine_regions_replace (&src1PR, src2PR, &destPR, &tempPR, NULL,
opacity * 255.999,
......
......@@ -167,13 +167,8 @@ gimp_drawable_get_sub_preview (GimpDrawable *drawable,
preview_buf = temp_buf_new (dest_width, dest_height, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.x = 0;
destPR.y = 0;
destPR.w = dest_width;
destPR.h = dest_height;
destPR.rowstride = dest_width * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
pixel_region_init_temp_buf (&destPR, preview_buf,
0, 0, dest_width, dest_height);
if (GIMP_IS_LAYER (drawable))
{
......
......@@ -264,14 +264,8 @@ gimp_image_get_new_preview (GimpViewable *viewable,
if (x2 == x1 || y2 == y1)
continue;
src1PR.bytes = comp->bytes;
src1PR.x = x1;
src1PR.y = y1;
src1PR.w = (x2 - x1);
src1PR.h = (y2 - y1);
src1PR.rowstride = comp->width * src1PR.bytes;
src1PR.data = (temp_buf_data (comp) +
y1 * src1PR.rowstride + x1 * src1PR.bytes);
pixel_region_init_temp_buf (&src1PR, comp,
x1, y1, x2 - x1, y2 - y1);
if (use_sub_preview)
{
......@@ -284,13 +278,8 @@ gimp_image_get_new_preview (GimpViewable *viewable,
g_assert (layer_buf);
g_assert (layer_buf->bytes <= comp->bytes);
src2PR.bytes = layer_buf->bytes;
src2PR.x = 0;
src2PR.y = 0;
src2PR.w = src1PR.w;
src2PR.h = src1PR.h;
src2PR.rowstride = layer_buf->width * src2PR.bytes;
src2PR.data = temp_buf_data (layer_buf);
pixel_region_init_temp_buf (&src2PR, layer_buf,
0, 0, src1PR.w, src1PR.h);
}
else
{
......@@ -299,15 +288,8 @@ gimp_image_get_new_preview (GimpViewable *viewable,
g_assert (layer_buf);
g_assert (layer_buf->bytes <= comp->bytes);
src2PR.bytes = layer_buf->bytes;
src2PR.x = src1PR.x;
src2PR.y = src1PR.y;
src2PR.w = src1PR.w;
src2PR.h = src1PR.h;
src2PR.rowstride = layer_buf->width * src2PR.bytes;
src2PR.data = (temp_buf_data (layer_buf) +
(y1 - y) * src2PR.rowstride +
(x1 - x) * src2PR.bytes);
pixel_region_init_temp_buf (&src2PR, layer_buf,
x1 - x, y1 - y, src1PR.w, src1PR.h);
}
if (layer->mask && layer->mask->apply_mask)
......@@ -321,28 +303,16 @@ gimp_image_get_new_preview (GimpViewable *viewable,
x2 - x1,
y2 - y1);
maskPR.bytes = mask_buf->bytes;
maskPR.x = 0;
maskPR.y = 0;
maskPR.w = src1PR.w;
maskPR.h = src1PR.h;
maskPR.rowstride = mask_buf->width * mask_buf->bytes;
maskPR.data = mask_buf_data (mask_buf);
pixel_region_init_temp_buf (&maskPR, mask_buf,
0, 0, src1PR.w, maskPR.h);
}
else
{
mask_buf = gimp_viewable_get_preview (GIMP_VIEWABLE (layer->mask),
w, h);
maskPR.bytes = mask_buf->bytes;
maskPR.x = src1PR.x;
maskPR.y = src1PR.y;
maskPR.w = src1PR.w;
maskPR.h = src1PR.h;
maskPR.rowstride = mask_buf->width * mask_buf->bytes;
maskPR.data = (mask_buf_data (mask_buf) +
(y1 - y) * maskPR.rowstride +
(x1 - x) * maskPR.bytes);
pixel_region_init_temp_buf (&maskPR, mask_buf,
x1 - x, y1 - y, src1PR.w, maskPR.h);
}