gegl r2384 - in trunk: . gegl/buffer gegl/operation
- From: ok svn gnome org
- To: svn-commits-list gnome org
- Subject: gegl r2384 - in trunk: . gegl/buffer gegl/operation
- Date: Thu, 5 Jun 2008 09:55:48 +0000 (UTC)
Author: ok
Date: Thu Jun 5 09:55:48 2008
New Revision: 2384
URL: http://svn.gnome.org/viewvc/gegl?rev=2384&view=rev
Log:
* gegl/buffer/gegl-buffer-iterator.[ch]: trimmed down
GeglBufferIterator to a tiny babl powered API.
* gegl/buffer/gegl-buffer-access.c: ported to new API.
* gegl/operation/gegl-operation-point-composer.c: ..
* gegl/operation/gegl-operation-point-filter.c: ..
* gegl/operation/gegl-operation-point-render.c: ..
Modified:
trunk/ChangeLog
trunk/gegl/buffer/gegl-buffer-access.c
trunk/gegl/buffer/gegl-buffer-iterator.c
trunk/gegl/buffer/gegl-buffer-iterator.h
trunk/gegl/operation/gegl-operation-point-composer.c
trunk/gegl/operation/gegl-operation-point-filter.c
trunk/gegl/operation/gegl-operation-point-render.c
Modified: trunk/gegl/buffer/gegl-buffer-access.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-access.c (original)
+++ trunk/gegl/buffer/gegl-buffer-access.c Thu Jun 5 09:55:48 2008
@@ -1157,14 +1157,7 @@
GeglBuffer *dst,
const GeglRectangle *dst_rect)
{
- /* FIXME: make gegl_buffer_copy work with COW shared tiles when possible */
-
- GeglRectangle src_line;
- GeglRectangle dst_line;
Babl *fish;
- guchar *temp;
- guint i;
- gint pxsize;
g_return_if_fail (GEGL_IS_BUFFER (src));
g_return_if_fail (GEGL_IS_BUFFER (dst));
@@ -1179,54 +1172,21 @@
dst_rect = src_rect;
}
- pxsize = src->tile_storage->px_size;
fish = babl_fish (src->format, dst->format);
- src_line = *src_rect;
- src_line.height = 1;
-
- dst_line = *dst_rect;
- dst_line.width = src_line.width;
- dst_line.height = src_line.height;
-
- if (gegl_buffer_scan_compatible (src, src_rect->x, src_rect->y,
- dst, dst_rect->x, dst_rect->y)) /* is this check good enough
- * with the shifts we might
- * do?
- */
- {
- GeglBufferScanIterator read;
- GeglBufferScanIterator write;
- gboolean a=FALSE,b=FALSE;
-
- gegl_buffer_scan_iterator_init (&read, src, *dst_rect, FALSE);
- gegl_buffer_scan_iterator_init (&write, dst, *dst_rect, TRUE);
-
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- babl_process (fish, read.data, write.data, write.length);
- }
-
- if (a)
- while (gegl_buffer_scan_iterator_next (&read));
- if (b)
- while (gegl_buffer_scan_iterator_next (&write));
-
- return;
- }
-
- temp = g_malloc (src_line.width * pxsize);
-
- for (i=0; i<src_rect->height; i++)
{
- gegl_buffer_get (src, 1.0, &src_line, dst->format, temp, GEGL_AUTO_ROWSTRIDE);
- gegl_buffer_set (dst, &dst_line, dst->format, temp, GEGL_AUTO_ROWSTRIDE);
- src_line.y++;
- dst_line.y++;
+ GeglRectangle dest_rect_r = *dst_rect;
+ GeglBufferIterator *i;
+ gint read;
+
+ dest_rect_r.width = src_rect->width;
+ dest_rect_r.height = src_rect->height;
+
+ i = gegl_buffer_iterator_new (dst, dest_rect_r, dst->format, GEGL_BUFFER_WRITE);
+ read = gegl_buffer_iterator_add (i, src, *src_rect, src->format, GEGL_BUFFER_READ);
+ while (gegl_buffer_iterator_next (i))
+ babl_process (fish, i->data[read], i->data[0], i->length);
}
- g_free (temp);
}
void
Modified: trunk/gegl/buffer/gegl-buffer-iterator.c
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-iterator.c (original)
+++ trunk/gegl/buffer/gegl-buffer-iterator.c Thu Jun 5 09:55:48 2008
@@ -26,68 +26,106 @@
#include "gegl-types.h"
#include "gegl-buffer-types.h"
#include "gegl-buffer-iterator.h"
+#include "gegl-buffer-private.h"
#include "gegl-tile-storage.h"
-
-gboolean gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i);
-GeglBufferTileIterator *gegl_buffer_tile_iterator_new (GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write);
-void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
- GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write);
+#include "gegl-utils.h"
+typedef struct GeglBufferTileIterator
+{
+ GeglBuffer *buffer;
+ GeglRectangle roi; /* the rectangular region we're iterating over */
+ GeglTile *tile; /* current tile */
+ gpointer data; /* current tile's data */
+
+ gint col; /* the column currently provided for */
+ gint row; /* the row currently provided for */
+ gboolean write;
+ GeglRectangle subrect; /* the subrect that intersected roi */
+ gpointer sub_data; /* pointer to the subdata as indicated by subrect */
+ gint rowstride; /* rowstride for tile, in bytes */
+
+ gint next_col; /* used internally */
+ gint next_row; /* used internally */
+} GeglBufferTileIterator;
+
+typedef struct GeglBufferScanIterator {
+ GeglBufferTileIterator tile_iterator; /* must be first member since we do
+ casting */
+ gint max_size; /* maximum data buffer needed, in bytes */
+ gint length; /* how long the current scan is in pixels */
+ gpointer data; /* the current scans data */
+ GeglRectangle roi; /* the rectangular subregion of data
+ * in the buffer represented by this scan.
+ */
+
+ gint row; /* used internally */
+ gint next_row; /* used internally */
+} GeglBufferScanIterator;
-#define gegl_buffer_scan_iterator_get_x(i) \
- ((((GeglBufferTileIterator*)(i))->roi.x) + \
- (((GeglBufferTileIterator*)(i))->real_col))
-#define gegl_buffer_scan_iterator_get_y(i) \
- ( (((GeglBufferTileIterator*)(i))->roi.y)+ \
- (((GeglBufferTileIterator*)(i))->real_row)+ \
- ((GeglBufferScanIterator*)(i))->real_row)
-
-#define gegl_buffer_scan_iterator_get_rectangle(i,rect_ptr) \
- do{GeglRectangle *foo = rect_ptr;\
- if (foo) {\
- foo->x=gegl_buffer_scan_iterator_get_x(i);\
- foo->y=gegl_buffer_scan_iterator_get_y(i);\
- foo->width= ((GeglBufferTileIterator*)i)->subrect.width;\
- foo->height=((GeglBufferScanIterator*)i)->length/ foo->width;\
- }}while(0)
-
-void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
- GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write)
+typedef struct GeglBufferIterators
+{
+ GeglRectangle roi; /* current region of interest */
+ gint length; /* length of current data in pixels */
+ gpointer data [GEGL_BUFFER_MAX_ITERATORS];
+
+ gint iterators;
+ /* the following is private: */
+ gint iteration_no;
+ GeglRectangle rect [GEGL_BUFFER_MAX_ITERATORS];
+ const Babl *format [GEGL_BUFFER_MAX_ITERATORS];
+ Babl *fish [GEGL_BUFFER_MAX_ITERATORS];
+ Babl *fish_to [GEGL_BUFFER_MAX_ITERATORS];
+ GeglBuffer *buffer [GEGL_BUFFER_MAX_ITERATORS];
+ guint flags [GEGL_BUFFER_MAX_ITERATORS];
+ gpointer buf [GEGL_BUFFER_MAX_ITERATORS];
+ gboolean compatible [GEGL_BUFFER_MAX_ITERATORS];
+ GeglBufferScanIterator i[GEGL_BUFFER_MAX_ITERATORS];
+} GeglBufferIterators;
+
+
+static void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+static gboolean gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i);
+static void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write);
+static gboolean gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i);
+static gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
+ gint x0,
+ gint y0,
+ GeglBuffer *output,
+ gint x1,
+ gint y1);
+
+
+static void gegl_buffer_tile_iterator_init (GeglBufferTileIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
{
g_assert (i);
memset (i, 0, sizeof (GeglBufferTileIterator));
+ if (roi.width == 0 ||
+ roi.height == 0)
+ g_error ("eeek");
i->buffer = buffer;
i->roi = roi;
- i->row = 0;
- i->col = 0;
+ i->next_row = 0;
+ i->next_col = 0;
i->tile = NULL;
- i->real_col = 0;
- i->real_row = 0;
+ i->col = 0;
+ i->row = 0;
i->write = write;
}
-
-GeglBufferTileIterator *
-gegl_buffer_tile_iterator_new (GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write)
-{
- GeglBufferTileIterator *i = g_malloc (sizeof (GeglBufferTileIterator));
- gegl_buffer_tile_iterator_init (i, buffer, roi, write);
- return i;
-}
-
-void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
- GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write)
+static void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ gboolean write)
{
GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
g_assert (i);
@@ -96,21 +134,12 @@
i->max_size = tile_i->buffer->tile_storage->tile_width *
tile_i->buffer->tile_storage->tile_height *
tile_i->buffer->format->format.bytes_per_pixel;
- i->real_row = 0;
+ i->row = 0;
if (write)
gegl_buffer_lock (buffer);
}
-GeglBufferScanIterator *gegl_buffer_scan_iterator_new (GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write)
-{
- GeglBufferScanIterator *i = g_malloc (sizeof (GeglBufferScanIterator));
- gegl_buffer_scan_iterator_init (i, buffer, roi, write);
- return i;
-}
-
-gboolean
+static gboolean
gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i)
{
GeglBufferTileIterator *tile_i = (GeglBufferTileIterator*)i;
@@ -119,60 +148,59 @@
{
gulp:
if (!gegl_buffer_tile_iterator_next (tile_i))
- return FALSE;
+ return FALSE; /* this is where the scan iterator terminates */
+
i->length = tile_i->subrect.width;
- i->rowstride = tile_i->subrect.width;
+ i->next_row = 0;
i->row = 0;
- i->real_row = 0;
+
+ i->roi.x = tile_i->roi.x + tile_i->col;
+ i->roi.y = tile_i->roi.y+ tile_i->row+ i->row;
+ i->roi.width = tile_i->subrect.width;
+ i->roi.height = tile_i->subrect.height;
}
/* we should now have a valid tile */
- if (tile_i->subrect.width == tile_i->buffer->tile_storage->tile_width &&
- i->row < tile_i->subrect.height)
- /* the entire contents of the tile can be expressed as one long scan */
- {
- gint px_size = tile_i->buffer->format->format.bytes_per_pixel;
- guchar *data = tile_i->data;
- i->length = tile_i->subrect.width * tile_i->subrect.height;
- i->rowstride = tile_i->subrect.width;
- i->data = data + px_size * (tile_i->subrect.width * tile_i->subrect.y);
- i->row = tile_i->subrect.height;
- i->real_row = 0;
-/* if (i->rowstride < 0)
- {
- return FALSE;
- }*/
- gegl_buffer_scan_iterator_get_rectangle (i, &(i->roi));
- return TRUE;
- }
- else if (i->row < tile_i->subrect.height)
- /* iterate thorugh the scanlines in the subrect */
- {
- guchar *data = tile_i->sub_data;
- i->data = data + i->row * tile_i->rowstride;
- i->real_row = i->row;
- i->row ++;
- return TRUE;
+ if (i->next_row < tile_i->subrect.height)
+ {
+ if (tile_i->subrect.width == tile_i->buffer->tile_storage->tile_width)
+ /* the entire contents of the tile can be expressed as one long scan */
+ {
+ i->length = tile_i->subrect.width * tile_i->subrect.height;
+ i->data = tile_i->sub_data;
+ i->row = 0;
+ i->next_row = tile_i->subrect.height;
+ return TRUE;
+ }
+ else
+ /* iterate thorugh the scanlines in the subrect */
+ {
+ guchar *data = tile_i->sub_data;
+
+ i->roi.height = 1;
+
+ i->data = data + i->next_row * tile_i->rowstride;
+ i->row = i->next_row;
+ i->next_row ++;
+ return TRUE;
+ }
}
else
{ /* we're done with that tile go get another one if possible */
goto gulp;
}
- if (tile_i->write)
- gegl_buffer_unlock (tile_i->buffer);
-
return FALSE;
}
-gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
- gint x0,
- gint y0,
- GeglBuffer *output,
- gint x1,
- gint y1)
-{
+static gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
+ gint x0,
+ gint y0,
+ GeglBuffer *output,
+ gint x1,
+ gint y1)
+{
if (input->tile_storage->tile_width !=
output->tile_storage->tile_width)
return FALSE;
@@ -194,7 +222,7 @@
return TRUE;
}
-gboolean
+static gboolean
gegl_buffer_tile_iterator_next (GeglBufferTileIterator *i)
{
GeglBuffer *buffer = i->buffer;
@@ -204,8 +232,6 @@
gint buffer_shift_y = buffer->shift_y;
gint buffer_x = buffer->extent.x + buffer_shift_x;
gint buffer_y = buffer->extent.y + buffer_shift_y;
- gint buffer_abyss_x = buffer->abyss.x + buffer_shift_x;
- gint abyss_x_total = buffer_abyss_x + buffer->abyss.width;
if (i->roi.width == 0 || i->roi.height == 0)
return FALSE;
@@ -223,60 +249,25 @@
i->tile = NULL;
}
- if (i->col < i->roi.width)
+ if (i->next_col < i->roi.width)
{ /* return tile on this row */
- gint tiledx = buffer_x + i->col;
- gint tiledy = buffer_y + i->row;
+ gint tiledx = buffer_x + i->next_col;
+ gint tiledy = buffer_y + i->next_row;
gint offsetx = gegl_tile_offset (tiledx, tile_width);
gint offsety = gegl_tile_offset (tiledy, tile_height);
- gint pixels;
-
- if (i->roi.width + offsetx - i->col < tile_width)
- pixels = (i->roi.width + offsetx - i->col) - offsetx;
- else
- pixels = tile_width - offsetx;
- /*if (!(buffer_x + i->col + tile_width >= buffer_abyss_x &&
- buffer_x + i->col < abyss_x_total))
- {
- g_warning ("entire tile in abyss?");
-
- i->col += tile_width - offsetx;
- goto gulp;
- }
- else*/
- {
+ {
i->subrect.x = offsetx;
i->subrect.y = offsety;
-
- i->subrect.width =
- //pixels;
- (i->roi.width - i->col + tile_width < tile_width) ?
- (i->roi.width - i->col + tile_width) - i->subrect.x:
- tile_width - i->subrect.x;
-
-
-
- i->subrect.height = (i->roi.height - i->row + tile_height < tile_height) ?
- (i->roi.height - i->row + tile_height) - i->subrect.y:
- tile_height - i->subrect.y;
-
- if(0){
- gint lskip = (buffer_abyss_x) - (buffer_x + i->col);
- /* gap between left side of tile, and abyss */
- gint rskip = (buffer_x + i->col + i->subrect.width) - abyss_x_total;
- /* gap between right side of tile, and abyss */
-
- if (lskip < 0)
- lskip = 0;
- if (lskip > i->subrect.width)
- lskip = i->subrect.width;
- if (rskip < 0)
- rskip = 0;
- if (rskip > i->subrect.width)
- rskip = i->subrect.width;
- i->subrect.width = i->subrect.width - rskip - lskip;
- }
+ if (i->roi.width + offsetx - i->next_col < tile_width)
+ i->subrect.width = (i->roi.width + offsetx - i->next_col) - offsetx;
+ else
+ i->subrect.width = tile_width - offsetx;
+
+ if (i->roi.height + offsety - i->next_row < tile_height)
+ i->subrect.height = (i->roi.height + offsety - i->next_row) - offsety;
+ else
+ i->subrect.height = tile_height - offsety;
i->tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
gegl_tile_indice (tiledx, tile_width),
@@ -294,27 +285,28 @@
i->sub_data = (guchar*)(i->data) + bpp * (i->subrect.y * tile_width + i->subrect.x);
}
- /* update with new future position (note this means that the
- * coordinates read from the iterator do not make full sense
- * */
- i->real_col = i->col;
- i->real_row = i->row;
- i->col += tile_width - offsetx;
+ i->col = i->next_col;
+ i->row = i->next_row;
+ i->next_col += tile_width - offsetx;
return TRUE;
}
}
else /* move down to next row */
{
- gint tiledy = buffer_y + i->row;
- gint offsety = gegl_tile_offset (tiledy, tile_height);
+ gint tiledy;
+ gint offsety;
- i->real_row = i->row;
- i->real_col = i->col;
- i->row += tile_height - offsety;
- i->col=0;
+ i->row = i->next_row;
+ i->col = i->next_col;
- if (i->row < i->roi.height)
+ tiledy = buffer_y + i->next_row;
+ offsety = gegl_tile_offset (tiledy, tile_height);
+
+ i->next_row += tile_height - offsety;
+ i->next_col=0;
+
+ if (i->next_row < i->roi.height)
{
goto gulp; /* return the first tile in the next row */
}
@@ -323,3 +315,178 @@
}
return FALSE;
}
+
+
+gint
+gegl_buffer_iterator_add (GeglBufferIterator *iterator,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ const Babl *format,
+ guint flags)
+{
+ GeglBufferIterators *i = (gpointer)iterator;
+ gint self = 0;
+ if (i->iterators+1 > GEGL_BUFFER_MAX_ITERATORS)
+ {
+ g_error ("too many iterators (%i)", i->iterators+1);
+ }
+
+ if (i->iterators == 0) /* for sanity, we zero at init */
+ {
+ memset (i, 0, sizeof (GeglBufferIterators));
+ }
+
+ self = i->iterators++;
+
+ i->rect[self]=roi;
+ i->buffer[self]=buffer;
+ if (format)
+ i->format[self]=format;
+ else
+ i->format[self]=buffer->format;
+ i->flags[self]=flags;
+
+ if (self==0) /* The first buffer which is always scan aligned */
+ {
+ i->compatible[self]= TRUE;
+ gegl_buffer_scan_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0) );
+ }
+ else
+ {
+ i->rect[self].width = i->rect[0].width;
+ i->rect[self].height = i->rect[0].height;
+ if (gegl_buffer_scan_compatible (i->buffer[0], i->rect[0].x, i->rect[0].y,
+ i->buffer[self], i->rect[self].x, i->rect[self].y))
+ {
+ i->compatible[self] = TRUE;
+ gegl_buffer_scan_iterator_init (&i->i[self], i->buffer[self], i->rect[self], ((i->flags[self] & GEGL_BUFFER_WRITE) != 0));
+ }
+ else
+ {
+ i->buf[self] = gegl_malloc (i->format[self]->format.bytes_per_pixel *
+ i->i[0].max_size);
+ }
+ }
+
+ if (i->format[self] != i->buffer[self]->format ||
+ i->compatible[self] == FALSE)
+ {
+ i->buf[self] = gegl_malloc (i->format[self]->format.bytes_per_pixel *
+ i->i[0].max_size);
+ if (i->flags[self] & GEGL_BUFFER_READ)
+ i->fish[self] = babl_fish (i->buffer[self]->format, i->format[self]);
+ if (i->flags[self] & GEGL_BUFFER_WRITE)
+ i->fish_to[self] = babl_fish (i->format[self], i->buffer[self]->format);
+ }
+
+ return self;
+}
+
+gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator)
+{
+ GeglBufferIterators *i = (gpointer)iterator;
+ gboolean result = FALSE;
+ gint no;
+ /* first we need to finish off any pending write work */
+
+ if (i->buf[0] == (void*)0xdeadbeef)
+ g_error ("%s called on finished buffer iterator", G_STRFUNC);
+ if (i->iteration_no > 0)
+ {
+ for (no=0; no<i->iterators;no++)
+ {
+ if (i->flags[no] & GEGL_BUFFER_WRITE)
+ {
+ if (i->compatible[no])
+ {
+ if (i->fish_to[no])
+ babl_process (i->fish_to[no], i->buf[no], i->i[no].data, i->i[no].length);
+ }
+ else
+ {
+ GeglRectangle rect = i->roi;
+ rect.x += (i->rect[no].x-i->rect[0].x);
+ rect.y += (i->rect[no].y-i->rect[0].y);
+ gegl_buffer_set (i->buffer[no], &rect, i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
+ }
+ }
+ }
+ }
+
+ g_assert (i->iterators > 0);
+
+ /* then we iterate all */
+ for (no=0; no<i->iterators;no++)
+ {
+ if (i->compatible[no])
+ {
+ gboolean res;
+ res = gegl_buffer_scan_iterator_next (&i->i[no]);
+ if (no == 0)
+ {
+ result = res;
+ i->roi = i->i->roi; /* the "clock" we're operating from is
+ the first buffer*/
+ i->length = i->i->length;
+ }
+ else
+ {
+ g_assert (i->length == i->i->length);
+ }
+
+ /* since they were scan compatible this should be true */
+ if (res != result)
+ {
+ g_print ("%i %i %i\n", res, result);
+ }
+ g_assert (res == result);
+
+ if (i->buf[no]!=NULL)
+ {
+ if (i->flags[no] & GEGL_BUFFER_READ)
+ babl_process (i->fish[no], i->i[no].data, i->buf[no], i->i[no].length);
+ i->data[no]=i->buf[no];
+ }
+ else
+ {
+ i->data[no]=i->i[no].data;
+ }
+ }
+ else
+ {
+ GeglRectangle rect = i->roi;
+ rect.x += (i->rect[no].x-i->rect[0].x);
+ rect.y += (i->rect[no].y-i->rect[0].y);
+ g_assert (i->buf[no]);
+
+ gegl_buffer_get (i->buffer[no], 1.0, &rect, i->format[no], i->buf[no], GEGL_AUTO_ROWSTRIDE);
+ i->data[no]=i->buf[no];
+ }
+ }
+
+ i->iteration_no++;
+
+ if (result == FALSE)
+ {
+ for (no=0; no<i->iterators;no++)
+ {
+ if (i->buf[no])
+ gegl_free (i->buf[no]);
+ i->buf[no]=NULL;
+ }
+ i->buf[0]=(void*)0xdeadbeef;
+ g_free (i);
+ }
+
+ return result;
+}
+
+GeglBufferIterator *gegl_buffer_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ const Babl *format,
+ guint flags)
+{
+ GeglBufferIterator *i = (gpointer)g_new0 (GeglBufferIterators, 1);
+ gegl_buffer_iterator_add (i, buffer, roi, format, flags);
+ return i;
+}
Modified: trunk/gegl/buffer/gegl-buffer-iterator.h
==============================================================================
--- trunk/gegl/buffer/gegl-buffer-iterator.h (original)
+++ trunk/gegl/buffer/gegl-buffer-iterator.h Thu Jun 5 09:55:48 2008
@@ -21,51 +21,77 @@
#define __GEGL_BUFFER_ITERATOR_H__
#include "gegl-buffer.h"
-#include "gegl-buffer-private.h"
-typedef struct GeglBufferTileIterator
+#define GEGL_BUFFER_MAX_ITERATORS 6
+
+#define GEGL_BUFFER_READ 1
+#define GEGL_BUFFER_WRITE 2
+#define GEGL_BUFFER_READWRITE (GEGL_BUFFER_READ|GEGL_BUFFER_WRITE)
+
+typedef struct GeglBufferIterator
{
- GeglBuffer *buffer;
- GeglTile *tile;
GeglRectangle roi;
- gint col;
- gint row;
- gint real_col;
- gint real_row;
- gboolean write;
- GeglRectangle subrect;
- gpointer data;
- gpointer sub_data;
- gint rowstride;
-} GeglBufferTileIterator;
-
-typedef struct GeglBufferScanIterator {
- GeglBufferTileIterator tile_iterator;
- gint max_size; /* in bytes */
- gint rowstride; /* allows computing */
- gint length;
- gint row;
- gint real_row;
- gpointer data;
- GeglRectangle roi;
-} GeglBufferScanIterator;
-
-
-GeglBufferScanIterator *gegl_buffer_scan_iterator_new (GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write);
-
-void gegl_buffer_scan_iterator_init (GeglBufferScanIterator *i,
- GeglBuffer *buffer,
- GeglRectangle roi,
- gboolean write);
-gboolean gegl_buffer_scan_iterator_next (GeglBufferScanIterator *i);
-gboolean gegl_buffer_scan_compatible (GeglBuffer *input,
- gint x0,
- gint y0,
- GeglBuffer *output,
- gint x1,
- gint y1);
+ gint length;
+ gpointer data[GEGL_BUFFER_MAX_ITERATORS];
+} GeglBufferIterator;
+
+
+/**
+ * gegl_buffer_iterator_new:
+ * @buffer: a #GeglBuffer
+ * @roi: the rectangle to iterate over
+ * @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
+ * @flags: whether we need reading or writing to this buffer one of GEGL_BUFFER_READ, GEGL_BUFFER_WRITE and GEGL_BUFFER_READWRITE.
+ *
+ * Create a new buffer iterator, this buffer will be iterated through
+ * in linear chunks, some chunks might be full tiles the coordinates, see
+ * the documentation of gegl_buffer_iterator_next for how to use it and
+ * destroy it.
+ *
+ * Returns: a new buffer iterator that can be used to iterate through the
+ * buffers pixels.
+ */
+GeglBufferIterator * gegl_buffer_iterator_new (GeglBuffer *buffer,
+ GeglRectangle roi,
+ const Babl *format,
+ guint flags);
+
+/**
+ * gegl_buffer_iterator_add:
+ * @iterator: a #GeglBufferIterator
+ * @buffer: a #GeglBuffer
+ * @roi: the rectangle to iterate over
+ * @format: the format we want to process this buffers data in, pass 0 to use the buffers format.
+ * @flags: whether we need reading or writing to this buffer.
+ *
+ * Adds an additional buffer iterator that will be processed in sync with
+ * the original one, if the buffer doesn't align with the other for tile access
+ * the corresponding scans and regions will be serialized automatically using
+ * gegl_buffer_get.
+ *
+ * Returns: an integer handle refering to the indice in the iterator structure
+ * of the added buffer.
+ */
+gint gegl_buffer_iterator_add (GeglBufferIterator *iterator,
+ GeglBuffer *buffer,
+ GeglRectangle roi,
+ const Babl *format,
+ guint flags);
+
+
+/**
+ * gegl_buffer_iterator_next:
+ * @iterator: a #GeglBufferIterator
+ *
+ * Do an iteration, this causes a new set of iterator->data[] to become
+ * available if there is more data to process. Changed data from a previous
+ * iteration step will also be saved now. When there is no more data to
+ * be processed NULL will be returned (and the iterator handle is no longer
+ * valid).
+ *
+ * Returns: TRUE if there is more work FALSE if iteration is complete.
+ */
+gboolean gegl_buffer_iterator_next (GeglBufferIterator *iterator);
#endif
Modified: trunk/gegl/operation/gegl-operation-point-composer.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-point-composer.c (original)
+++ trunk/gegl/operation/gegl-operation-point-composer.c Thu Jun 5 09:55:48 2008
@@ -193,171 +193,33 @@
GeglBuffer *output,
const GeglRectangle *result)
{
+ GeglOperationPointComposerClass *point_composer_class = GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation);
const Babl *in_format = gegl_operation_get_format (operation, "input");
const Babl *aux_format = gegl_operation_get_format (operation, "aux");
const Babl *out_format = gegl_operation_get_format (operation, "output");
if ((result->width > 0) && (result->height > 0))
{
- gfloat *in_buf = NULL, *out_buf = NULL, *aux_buf = NULL;
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, *result, out_format, GEGL_BUFFER_WRITE);
+ gint read = gegl_buffer_iterator_add (i, input, *result, in_format, GEGL_BUFFER_READ);
- if (gegl_buffer_scan_compatible (input, result->x, result->y,
- output, result->x, result->y))
+ if (aux)
{
- gint input_bpp = in_format->format.bytes_per_pixel;
- gint output_bpp = output->format->format.bytes_per_pixel;
- gint aux_bpp = aux?aux->format->format.bytes_per_pixel:1;
-
- Babl *infish;
- Babl *outfish;
- GeglBufferScanIterator read;
- GeglBufferScanIterator write;
- gboolean a = FALSE, b = FALSE;
-
- gegl_buffer_scan_iterator_init (&read, input, *result, FALSE);
- gegl_buffer_scan_iterator_init (&write, output, *result, TRUE);
-
- infish = babl_fish (input->format, in_format);
- outfish = babl_fish (out_format, output->format);
-
- /* FIXME use direct access when possible (avoid conversions and buffers)
- */
- {
- if (aux)
- aux_buf = gegl_malloc (aux_bpp * write.max_size);
-
- if (input->format == in_format &&
- output->format == out_format)
- {
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
-
- if (aux) gegl_buffer_get (aux, 1.0, &write.roi, aux_format, aux_buf,
- GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
- operation,
- read.data,
- aux_buf, /* can be NULL */
- write.data,
- write.length);
- }
- }
- else if (input->format == in_format &&
- output->format != out_format)
- {
- out_buf = gegl_malloc (output_bpp * write.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
-
- if (aux) gegl_buffer_get (aux, 1.0, &write.roi, aux_format, aux_buf,
- GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
- operation,
- read.data,
- aux_buf, /* can be NULL */
- out_buf,
- write.length);
- babl_process (outfish, out_buf, write.data, write.length);
- }
- gegl_free (out_buf);
- }
- else if (input->format != in_format &&
- output->format == out_format)
- {
- in_buf = gegl_malloc (input_bpp * read.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- babl_process (infish, read.data, in_buf, read.length);
-
- if (aux) gegl_buffer_get (aux, 1.0, &write.roi, aux_format, aux_buf,
- GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
- operation,
- in_buf,
- aux_buf, /* can be NULL */
- write.data,
- write.length);
- }
- gegl_free (in_buf);
- }
- else if (input->format != in_format &&
- output->format != out_format)
- {
- in_buf = gegl_malloc (input_bpp * read.max_size);
- out_buf = gegl_malloc (output_bpp * write.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- babl_process (infish, read.data, in_buf, read.length);
-
- if (aux) gegl_buffer_get (aux, 1.0, &write.roi, aux_format, aux_buf,
- GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
- operation,
- in_buf,
- aux_buf, /* can be NULL */
- out_buf,
- write.length);
- babl_process (outfish, out_buf, write.data, write.length);
- }
- gegl_free (in_buf);
- gegl_free (out_buf);
- }
+ gint foo = gegl_buffer_iterator_add (i, aux, *result, aux_format, GEGL_BUFFER_READ);
+ while (gegl_buffer_iterator_next (i))
+ {
+ point_composer_class->process (operation, i->data[read], i->data[foo], i->data[0], i->length);
}
-
- if (aux)
- gegl_free (aux_buf);
- return TRUE;
- }
-
- in_buf = gegl_malloc (in_format->format.bytes_per_pixel *
- output->extent.width * output->extent.height);
- if (in_format == out_format)
- {
- out_buf = in_buf;
}
else
{
- out_buf = gegl_malloc (out_format->format.bytes_per_pixel *
- output->extent.width * output->extent.height);
- }
-
- gegl_buffer_get (input, 1.0, result, in_format, in_buf, GEGL_AUTO_ROWSTRIDE);
-
- if (aux)
- {
- aux_buf = gegl_malloc (aux_format->format.bytes_per_pixel *
- output->extent.width * output->extent.height);
- gegl_buffer_get (aux, 1.0, result, aux_format, aux_buf, GEGL_AUTO_ROWSTRIDE);
+ while (gegl_buffer_iterator_next (i))
+ {
+ point_composer_class->process (operation, i->data[read], NULL, i->data[0], i->length);
+ }
}
- {
- GEGL_OPERATION_POINT_COMPOSER_GET_CLASS (operation)->process (
- operation,
- in_buf,
- aux_buf,
- out_buf,
- output->extent.width * output->extent.height);
- }
-
- gegl_buffer_set (output, NULL, out_format, out_buf, GEGL_AUTO_ROWSTRIDE);
-
- gegl_free (in_buf);
- if (in_format != out_format)
- gegl_free (out_buf);
- if (aux)
- gegl_free (aux_buf);
+ return TRUE;
}
return TRUE;
}
Modified: trunk/gegl/operation/gegl-operation-point-filter.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-point-filter.c (original)
+++ trunk/gegl/operation/gegl-operation-point-filter.c Thu Jun 5 09:55:48 2008
@@ -75,153 +75,11 @@
if ((result->width > 0) && (result->height > 0))
{
- if (gegl_buffer_scan_compatible (input, result->x, result->y,
- output, result->x, result->y))
- /* We can use the fastest possible path with the least possible
- * copies using paralell scan iteratator with possibly direct
- * read write access to buffers.
- */
- {
- gint input_bpp = in_format->format.bytes_per_pixel;
- gint output_bpp = output->format->format.bytes_per_pixel;
- gpointer *in_buf = NULL;
- gpointer *out_buf = NULL;
- Babl *infish;
- Babl *outfish;
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, *result, out_format, GEGL_BUFFER_WRITE);
+ gint read = gegl_buffer_iterator_add (i, input, *result, in_format, GEGL_BUFFER_READ);
+ while (gegl_buffer_iterator_next (i))
+ point_filter_class->process (operation, i->data[read], i->data[0], i->length, &i->roi);
- GeglBufferScanIterator read;
- GeglBufferScanIterator write;
- gegl_buffer_scan_iterator_init (&read, input, *result, FALSE);
- gegl_buffer_scan_iterator_init (&write, output, *result, TRUE);
-
- g_assert (input->tile_storage->tile_width == output->tile_storage->tile_width);
-
-
- infish = babl_fish (input->format, in_format);
- outfish = babl_fish (out_format, output->format);
-
- {
- gboolean a = FALSE, b = FALSE;
- if (in_format == input->format &&
- out_format == output->format)
- {
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- point_filter_class->process (operation, read.data, write.data, write.length, &write.roi);
- }
- }
- else if (in_format == input->format &&
- out_format != output->format)
- {
- out_buf = gegl_malloc (output_bpp * write.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- point_filter_class->process (operation, read.data, out_buf, read.length, &write.roi);
- babl_process (outfish, out_buf, write.data, write.length);
- }
- }
- else if (in_format != input->format &&
- out_format == output->format)
- {
- in_buf = gegl_malloc (input_bpp * read.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- if (read.length < 0)
- continue;
- g_assert (read.length == write.length);
- babl_process (infish, read.data, in_buf, read.length);
- point_filter_class->process (operation, in_buf, write.data, read.length, &write.roi);
- }
- }
- else if (in_format != input->format &&
- out_format != output->format)
- {
- in_buf = gegl_malloc (input_bpp * read.max_size);
- out_buf = gegl_malloc (output_bpp * write.max_size);
- while ( (a = gegl_buffer_scan_iterator_next (&read)) &&
- (b = gegl_buffer_scan_iterator_next (&write)))
- {
- g_assert (read.length == write.length);
- babl_process (infish, read.data, in_buf, read.length);
- point_filter_class->process (operation, in_buf, out_buf, read.length, &write.roi);
- babl_process (outfish, out_buf, write.data, write.length);
- }
- }
-
- if (a)
- while (gegl_buffer_scan_iterator_next (&read));
- if (b)
- while (gegl_buffer_scan_iterator_next (&write));
- }
-
- if (in_buf)
- gegl_free (in_buf);
- if (out_buf)
- gegl_free (out_buf);
- }
-#if 0
- else
- /* do the entire buffer */
- {
- gfloat *in_buf;
- gfloat *out_buf;
- in_buf = gegl_malloc (in_format->format.bytes_per_pixel *
- input->extent.width * input->extent.height);
- out_buf = gegl_malloc (out_format->format.bytes_per_pixel *
- output->extent.width * output->extent.height);
-
- gegl_buffer_get (input, 1.0, result, in_format, in_buf, GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation)->process (
- operation,
- in_buf,
- out_buf,
- output->extent.width * output->extent.height);
-
- gegl_buffer_set (output, result, out_format, out_buf, GEGL_AUTO_ROWSTRIDE);
- gegl_free (in_buf);
- gegl_free (out_buf);
-#else
- else
- /* do it in vertical chunks of 32 scanlines */
- {
- gfloat *in_buf;
- GeglRectangle roi;
- gint skip = 32;
- gfloat *out_buf;
- in_buf = gegl_malloc (in_format->format.bytes_per_pixel * result->width * skip);
- out_buf = gegl_malloc (out_format->format.bytes_per_pixel * result->width * skip);
-
-
- roi = *result;
- while (roi.y < result->y + result->height && skip >0 )
- {
- for (roi.height=skip; (roi.y + skip <= result->y + result->height);
- roi.y+=skip)
- {
- gegl_buffer_get (input, 1.0, &roi, in_format, in_buf, GEGL_AUTO_ROWSTRIDE);
-
- GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation)->process (
- operation,
- in_buf,
- out_buf,
- result->width * skip, &roi);
-
- gegl_buffer_set (output, &roi, out_format, out_buf, GEGL_AUTO_ROWSTRIDE);
- }
- skip /= 2;
- }
-
-
- gegl_free (in_buf);
- gegl_free (out_buf);
- }
-#endif
}
return TRUE;
}
Modified: trunk/gegl/operation/gegl-operation-point-render.c
==============================================================================
--- trunk/gegl/operation/gegl-operation-point-render.c (original)
+++ trunk/gegl/operation/gegl-operation-point-render.c Thu Jun 5 09:55:48 2008
@@ -94,29 +94,12 @@
if ((result->width > 0) && (result->height > 0))
{
- gint output_bpp = output->format->format.bytes_per_pixel;
- gpointer *out_buf = NULL;
- Babl *outfish;
+ GeglBufferIterator *i = gegl_buffer_iterator_new (output, *result, out_format, GEGL_BUFFER_WRITE);
- GeglBufferScanIterator write;
- gegl_buffer_scan_iterator_init (&write, output, *result, TRUE);
-
- outfish = babl_fish (out_format, output->format);
-
-
- out_buf = gegl_malloc (output_bpp * write.max_size);
- while (gegl_buffer_scan_iterator_next (&write))
+ while (gegl_buffer_iterator_next (i))
{
- point_render_class->process (operation, out_buf, write.length, &write.roi);
-
- /* this is the actual write happening directly to the underlying
- * scan on the tile.
- */
- babl_process (outfish, out_buf, write.data, write.length);
+ point_render_class->process (operation, i->data[0], i->length, &i->roi);
}
-
- if (out_buf)
- gegl_free (out_buf);
}
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]