app: port gimp_scan_convert_render_full() to GeglBufferIterator

This commit is contained in:
Michael Natterer
2012-03-20 23:14:00 +01:00
parent 3441d009f8
commit 113f01feb2

View File

@ -19,7 +19,7 @@
#include <string.h> #include <string.h>
#include <glib-object.h> #include <gegl.h>
#include <cairo.h> #include <cairo.h>
@ -28,9 +28,10 @@
#include "core-types.h" #include "core-types.h"
#include "base/pixel-region.h"
#include "base/tile-manager.h" #include "base/tile-manager.h"
#include "gegl/gimp-gegl-utils.h"
#include "gimpbezierdesc.h" #include "gimpbezierdesc.h"
#include "gimpscanconvert.h" #include "gimpscanconvert.h"
@ -454,13 +455,16 @@ gimp_scan_convert_render_full (GimpScanConvert *sc,
gboolean antialias, gboolean antialias,
guchar value) guchar value)
{ {
PixelRegion maskPR; GeglBuffer *buffer;
gpointer pr; const Babl *format;
cairo_t *cr; GeglBufferIterator *iter;
cairo_surface_t *surface; GeglRectangle *roi;
cairo_path_t path; cairo_t *cr;
gint x, y; cairo_surface_t *surface;
gint width, height; cairo_path_t path;
gint bpp;
gint x, y;
gint width, height;
g_return_if_fail (sc != NULL); g_return_if_fail (sc != NULL);
g_return_if_fail (tiles != NULL); g_return_if_fail (tiles != NULL);
@ -477,55 +481,61 @@ gimp_scan_convert_render_full (GimpScanConvert *sc,
&x, &y, &width, &height)) &x, &y, &width, &height))
return; return;
pixel_region_init (&maskPR, tiles, x, y, width, height, TRUE);
path.status = CAIRO_STATUS_SUCCESS; path.status = CAIRO_STATUS_SUCCESS;
path.data = (cairo_path_data_t *) sc->path_data->data; path.data = (cairo_path_data_t *) sc->path_data->data;
path.num_data = sc->path_data->len; path.num_data = sc->path_data->len;
for (pr = pixel_regions_register (1, &maskPR); buffer = gimp_tile_manager_create_buffer (tiles, NULL, TRUE);
pr != NULL; format = gegl_buffer_get_format (buffer);
pr = pixel_regions_process (pr))
bpp = babl_format_get_bytes_per_pixel (format);
iter = gegl_buffer_iterator_new (buffer, NULL, format,
GEGL_BUFFER_WRITE);
roi = &iter->roi[0];
while (gegl_buffer_iterator_next (iter))
{ {
guchar *data = iter->data[0];
guchar *tmp_buf = NULL; guchar *tmp_buf = NULL;
const gint stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8, const gint stride = cairo_format_stride_for_width (CAIRO_FORMAT_A8,
maskPR.w); roi->width);
/* cairo rowstrides are always multiples of 4, whereas /* cairo rowstrides are always multiples of 4, whereas
* maskPR.rowstride can be anything, so to be able to create an * maskPR.rowstride can be anything, so to be able to create an
* image surface, we maybe have to create our own temporary * image surface, we maybe have to create our own temporary
* buffer * buffer
*/ */
if (maskPR.rowstride != stride) if (roi->width * bpp != stride)
{ {
const guchar *src = maskPR.data; const guchar *src = data;
guchar *dest; guchar *dest;
dest = tmp_buf = g_alloca (stride * maskPR.h); dest = tmp_buf = g_alloca (roi->width * roi->height * bpp);
if (! replace) if (! replace)
{ {
gint i; gint i;
for (i = 0; i < maskPR.h; i++) for (i = 0; i < roi->height; i++)
{ {
memcpy (dest, src, maskPR.w); memcpy (dest, src, roi->width * bpp);
src += maskPR.rowstride; src += roi->width * bpp;
dest += stride; dest += stride;
} }
} }
} }
surface = cairo_image_surface_create_for_data (tmp_buf ? surface = cairo_image_surface_create_for_data (tmp_buf ?
tmp_buf : maskPR.data, tmp_buf : data,
CAIRO_FORMAT_A8, CAIRO_FORMAT_A8,
maskPR.w, maskPR.h, roi->width, roi->height,
stride); stride);
cairo_surface_set_device_offset (surface, cairo_surface_set_device_offset (surface,
-off_x - maskPR.x, -off_x - roi->x,
-off_y - maskPR.y); -off_y - roi->y);
cr = cairo_create (surface); cr = cairo_create (surface);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
@ -575,17 +585,19 @@ gimp_scan_convert_render_full (GimpScanConvert *sc,
if (tmp_buf) if (tmp_buf)
{ {
guchar *dest = maskPR.data; guchar *dest = data;
const guchar *src = tmp_buf; const guchar *src = tmp_buf;
gint i; gint i;
for (i = 0; i < maskPR.h; i++) for (i = 0; i < roi->height; i++)
{ {
memcpy (dest, src, maskPR.w); memcpy (dest, src, roi->width * bpp);
src += stride; src += stride;
dest += maskPR.rowstride; dest += roi->width * bpp;
} }
} }
} }
g_object_unref (buffer);
} }