gboolean gimp_gegl_mask_is_empty (GeglBuffer *buffer) { GeglBufferIterator *iter; g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE); iter = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("Y float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *data = iter->data[0]; gint i; for (i = 0; i < iter->length; i++) { if (data[i]) { gegl_buffer_iterator_stop (iter); return FALSE; } } } return TRUE; }
static gboolean gegl_operation_point_render_process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglPad *pad; const Babl *out_format; GeglOperationPointRenderClass *point_render_class; point_render_class = GEGL_OPERATION_POINT_RENDER_GET_CLASS (operation); pad = gegl_node_get_pad (operation->node, "output"); out_format = gegl_pad_get_format (pad); if (!out_format) { g_warning ("%s", gegl_node_get_debug_name (operation->node)); } g_assert (out_format); if ((result->width > 0) && (result->height > 0)) { GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (i)) point_render_class->process (operation, i->data[0], i->length, &i->roi[0], level); } return TRUE; }
static void cdisplay_gamma_convert_buffer (GimpColorDisplay *display, GeglBuffer *buffer, GeglRectangle *area) { CdisplayGamma *gamma = CDISPLAY_GAMMA (display); GeglBufferIterator *iter; gdouble one_over_gamma; one_over_gamma = 1.0 / gamma->gamma; iter = gegl_buffer_iterator_new (buffer, area, 0, babl_format ("R'G'B'A float"), GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *data = iter->data[0]; gint count = iter->length; while (count--) { *data = pow (*data, one_over_gamma); data++; *data = pow (*data, one_over_gamma); data++; *data = pow (*data, one_over_gamma); data++; data++; } } }
static void tile_request_end(MyPaintTiledSurface *tiled_surface, MyPaintTileRequest *request) { MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)tiled_surface; if (buffer_is_native(self)) { GeglBufferIterator *iterator = (GeglBufferIterator *)request->context; if (iterator) { gegl_buffer_iterator_next(iterator); request->context = NULL; } } else { // Push our linear buffer back into the GeglBuffer const int tile_size = tiled_surface->tile_size; GeglRectangle tile_bbox; g_assert(request->buffer); gegl_rectangle_set(&tile_bbox, request->tx*tile_size, request->ty*tile_size, tile_size, tile_size); gegl_buffer_set(self->buffer, &tile_bbox, 0, self->format, request->buffer, GEGL_AUTO_ROWSTRIDE); gegl_free(request->buffer); } }
static gboolean gegl_operation_point_filter_process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result) { const Babl *in_format = gegl_operation_get_format (operation, "input"); const Babl *out_format = gegl_operation_get_format (operation, "output"); GeglOperationPointFilterClass *point_filter_class; point_filter_class = GEGL_OPERATION_POINT_FILTER_GET_CLASS (operation); if ((result->width > 0) && (result->height > 0)) { { GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, out_format, GEGL_BUFFER_WRITE); gint read = /*output == input ? 0 :*/ gegl_buffer_iterator_add (i, input, result, in_format, GEGL_BUFFER_READ); /* using separate read and write iterators for in-place ideally a single * readwrite indice would be sufficient */ while (gegl_buffer_iterator_next (i)) point_filter_class->process (operation, i->data[read], i->data[0], i->length, &i->roi[0]); } } return TRUE; }
gboolean gimp_gegl_mask_is_empty (GeglBuffer *buffer) { GeglBufferIterator *iter; const Babl *format; gint bpp; g_return_val_if_fail (GEGL_IS_BUFFER (buffer), FALSE); format = gegl_buffer_get_format (buffer); bpp = babl_format_get_bytes_per_pixel (format); iter = gegl_buffer_iterator_new (buffer, NULL, 0, format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE, 1); while (gegl_buffer_iterator_next (iter)) { if (! gegl_memeq_zero (iter->items[0].data, bpp * iter->length)) { gegl_buffer_iterator_stop (iter); return FALSE; } } return TRUE; }
static void cpn_affine_transform_clamp (GeglBuffer *buffer, gdouble min, gdouble max) { GeglBufferIterator *gi; gdouble scale = 1.0 / (max - min); gdouble offset = - min; /* We want to scale values linearly, regardless of the format of the buffer */ gegl_buffer_set_format (buffer, babl_format ("Y double")); gi = gegl_buffer_iterator_new (buffer, NULL, 0, NULL, GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (gi)) { guint k; double *data; data = (double*) gi->data[0]; for (k = 0; k < gi->length; k++) { data[k] = CLAMP ((data[k] + offset) * scale, 0.0, 1.0); } } }
void gimp_gegl_combine_mask (GeglBuffer *mask_buffer, const GeglRectangle *mask_rect, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, gdouble opacity) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (mask_buffer, mask_rect, 0, babl_format ("Y float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, babl_format ("Y float"), GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { const gfloat *mask = iter->data[0]; gfloat *dest = iter->data[1]; gint count = iter->length; while (count--) { *dest *= *mask * opacity; mask += 1; dest += 1; } } }
static void buffer_get_min_max (GeglBuffer *buffer, gfloat *min, gfloat *max) { GeglBufferIterator *gi; gint c; gi = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("RGB float"), GEGL_ACCESS_READ, GEGL_ABYSS_NONE); for (c = 0; c < 3; c++) { min[c] = G_MAXFLOAT; max[c] = -G_MAXFLOAT; } while (gegl_buffer_iterator_next (gi)) { gfloat *buf = gi->data[0]; gint i; for (i = 0; i < gi->length; i++) { for (c = 0; c < 3; c++) { min[c] = MIN (buf [i * 3 + c], min[c]); max[c] = MAX (buf [i * 3 + c], max[c]); } } } }
static void mean_rectangle_noalloc (GeglBuffer *input, GeglRectangle *rect, GeglColor *color) { GeglBufferIterator *gi; gfloat col[] = {0.0, 0.0, 0.0, 0.0}; gint c; gi = gegl_buffer_iterator_new (input, rect, 0, babl_format ("RaGaBaA float"), GEGL_ACCESS_READ, GEGL_ABYSS_CLAMP); while (gegl_buffer_iterator_next (gi)) { gint k; gfloat *data = (gfloat*) gi->data[0]; for (k = 0; k < gi->length; k++) { for (c = 0; c < 4; c++) col[c] += data[c]; data += 4; } } for (c = 0; c < 4; c++) col[c] /= rect->width * rect->height; gegl_color_set_pixel (color, babl_format ("RaGaBaA float"), col); }
/* * blend_pixels patched 8-24-05 to fix bug #163721. Note that this change * causes the function to treat src1 and src2 asymmetrically. This gives the * right behavior for the smudge tool, which is the only user of this function * at the time of patching. If you want to use the function for something * else, caveat emptor. */ void gimp_gegl_smudge_blend (GeglBuffer *top_buffer, const GeglRectangle *top_rect, GeglBuffer *bottom_buffer, const GeglRectangle *bottom_rect, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, gdouble blend) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (top_buffer, top_rect, 0, babl_format ("RGBA float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, bottom_buffer, bottom_rect, 0, babl_format ("RGBA float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, babl_format ("RGBA float"), GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { const gfloat *top = iter->data[0]; const gfloat *bottom = iter->data[1]; gfloat *dest = iter->data[2]; gint count = iter->length; const gfloat blend1 = 1.0 - blend; const gfloat blend2 = blend; while (count--) { const gfloat a1 = blend1 * bottom[3]; const gfloat a2 = blend2 * top[3]; const gfloat a = a1 + a2; gint b; if (a == 0) { for (b = 0; b < 4; b++) dest[b] = 0; } else { for (b = 0; b < 3; b++) dest[b] = bottom[b] + (bottom[b] * a1 + top[b] * a2 - a * bottom[b]); dest[3] = a; } top += 4; bottom += 4; dest += 4; } } }
static void transfer_registration_color (GeglBuffer *src, GeglBuffer **dst, gint count) { GimpRGB color, test; GeglBufferIterator *gi; const Babl *src_format, *dst_format; gint i, src_bpp, dst_bpp; gdouble white; gimp_context_get_foreground (&color); white = 1.0; src_format = gegl_buffer_get_format (src); src_bpp = babl_format_get_bytes_per_pixel (src_format); dst_format = gegl_buffer_get_format (dst[0]); dst_bpp = babl_format_get_bytes_per_pixel (dst_format); gi = gegl_buffer_iterator_new (src, NULL, 0, NULL, GEGL_BUFFER_READ, GEGL_ABYSS_NONE); for (i = 0; i < count; i++) { gegl_buffer_iterator_add (gi, dst[i], NULL, 0, NULL, GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); } while (gegl_buffer_iterator_next (gi)) { guint j, k; gpointer src_data, dst_data[MAX_EXTRACT_IMAGES]; src_data = gi->data[0]; for (j = 0; j < count; j++) dst_data[j] = gi->data[j+1]; for (k = 0; k < gi->length; k++) { gulong pos; pos = k * src_bpp; gimp_rgba_set_pixel (&test, src_format, ((guchar *)src_data) + pos); if (gimp_rgb_distance (&test, &color) < 1e-6) { for (j = 0; j < count; j++) { gpointer data; data = dst_data[j]; babl_process (babl_fish (babl_format ("Y double"), dst_format), &white, (guchar *)data + (k * dst_bpp), 1); } } } } }
static void process_standard (GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, guint *channel_bits, GeglRandom *rand, GeglDitherStrategy dither_strategy) { GeglBufferIterator *gi; guint channel_mask [4]; generate_channel_masks (channel_bits, channel_mask); gi = gegl_buffer_iterator_new (input, result, 0, babl_format ("R'G'B'A u16"), GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (gi, output, result, 0, babl_format ("R'G'B'A u16"), GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (gi)) { guint y; for (y = 0; y < gi->roi->height; y++) { switch (dither_strategy) { case GEGL_DITHER_NONE: process_row_no_dither (gi, channel_mask, channel_bits, y); break; case GEGL_DITHER_RANDOM: process_row_random (gi, channel_mask, channel_bits, y, rand); break; case GEGL_DITHER_RESILIENT: process_row_resilient (gi, channel_mask, channel_bits, y, rand); break; case GEGL_DITHER_RANDOM_COVARIANT: process_row_random_covariant (gi, channel_mask, channel_bits, y, rand); break; case GEGL_DITHER_BAYER: process_row_bayer (gi, channel_mask, channel_bits, y); break; case GEGL_DITHER_FLOYD_STEINBERG: /* Done separately */ break; default: process_row_no_dither (gi, channel_mask, channel_bits, y); } } } }
TEST () { GeglBuffer *buffer2, *buffer; GeglRectangle bound = {0, 0, 20, 20}; GeglRectangle dest = {4, 4, 4, 6}; float *blank = g_malloc0 (100000); gchar *temp = g_malloc0 (100000); test_start (); buffer2 = gegl_buffer_new (&bound, babl_format ("Y float")); buffer = gegl_buffer_new (&bound, babl_format ("Y float")); vgrad (buffer2); gegl_buffer_set (buffer2, &dest, 1, babl_format ("Y float"), blank, GEGL_AUTO_ROWSTRIDE); print_buffer (buffer2); gegl_buffer_get (buffer2, &bound, 0.5, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); gegl_buffer_set (buffer, &bound, 0, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE); print_buffer (buffer); vgrad (buffer2); { GeglBufferIterator *iterator = gegl_buffer_iterator_new (buffer2, &dest, 1, babl_format ("Y float"), GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iterator)) { int i; gfloat *d = iterator->data[0]; for (i = 0; i < iterator->length; i++) d[i] = 0; } } print_buffer (buffer2); gegl_buffer_get (buffer2, &bound, 0.5, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); gegl_buffer_set (buffer, &bound, 0, babl_format ("Y float"), temp, GEGL_AUTO_ROWSTRIDE); print_buffer (buffer); g_object_unref (buffer); g_object_unref (buffer2); test_end (); }
void mask_components_onto (GeglBuffer *src_buffer, GeglBuffer *aux_buffer, GeglBuffer *dst_buffer, GeglRectangle *roi, GimpComponentMask mask, gboolean linear_mode) { GeglBufferIterator *iter; const Babl *iterator_format; if (linear_mode) iterator_format = babl_format ("RGBA float"); else iterator_format = babl_format ("R'G'B'A float"); iter = gegl_buffer_iterator_new (dst_buffer, roi, 0, iterator_format, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, src_buffer, roi, 0, iterator_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, aux_buffer, roi, 0, iterator_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *dest = (gfloat *)iter->data[0]; gfloat *src = (gfloat *)iter->data[1]; gfloat *aux = (gfloat *)iter->data[2]; glong samples = iter->length; while (samples--) { dest[RED] = (mask & GIMP_COMPONENT_MASK_RED) ? aux[RED] : src[RED]; dest[GREEN] = (mask & GIMP_COMPONENT_MASK_GREEN) ? aux[GREEN] : src[GREEN]; dest[BLUE] = (mask & GIMP_COMPONENT_MASK_BLUE) ? aux[BLUE] : src[BLUE]; dest[ALPHA] = (mask & GIMP_COMPONENT_MASK_ALPHA) ? aux[ALPHA] : src[ALPHA]; src += 4; aux += 4; dest += 4; } } }
static void tile_request_start(MyPaintTiledSurface *tiled_surface, MyPaintTileRequest *request) { MyPaintGeglTiledSurface *self = (MyPaintGeglTiledSurface *)tiled_surface; const int tile_size = tiled_surface->tile_size; GeglRectangle tile_bbox; gegl_rectangle_set(&tile_bbox, request->tx * tile_size, request->ty * tile_size, tile_size, tile_size); int read_write_flags; if (request->readonly) { read_write_flags = GEGL_BUFFER_READ; } else { read_write_flags = GEGL_BUFFER_READWRITE; // Extend the bounding box gegl_rectangle_bounding_box(&self->extent_rect, &self->extent_rect, &tile_bbox); gboolean success = gegl_buffer_set_extent(self->buffer, &self->extent_rect); g_assert(success); } if (buffer_is_native(self)) { GeglBufferIterator *iterator = gegl_buffer_iterator_new(self->buffer, &tile_bbox, 0, self->format, read_write_flags, GEGL_ABYSS_NONE); // Read out gboolean completed = gegl_buffer_iterator_next(iterator); g_assert(completed); if (iterator->length != tile_size*tile_size) { g_critical("Unable to get tile aligned access to GeglBuffer"); request->buffer = NULL; } else { request->buffer = (uint16_t *)(iterator->data[0]); } // So we can finish the iterator in tile_request_end() request->context = (void *)iterator; } else { // Extract a linear rectangular chunk of appropriate BablFormat, // potentially triggering copying and color conversions request->buffer = alloc_for_format(self->format, tile_size*tile_size); gegl_buffer_get(self->buffer, &tile_bbox, 1, self->format, request->buffer, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); g_assert(request->buffer); } }
void gimp_gegl_combine_mask_weird (GeglBuffer *mask_buffer, const GeglRectangle *mask_rect, GeglBuffer *dest_buffer, const GeglRectangle *dest_rect, gdouble opacity, gboolean stipple) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (mask_buffer, mask_rect, 0, babl_format ("Y float"), GEGL_BUFFER_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0, babl_format ("Y float"), GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { const gfloat *mask = iter->data[0]; gfloat *dest = iter->data[1]; gint count = iter->length; if (stipple) { while (count--) { dest[0] += (1.0 - dest[0]) * *mask * opacity; mask += 1; dest += 1; } } else { while (count--) { if (opacity > dest[0]) dest[0] += (opacity - dest[0]) * *mask * opacity; mask += 1; dest += 1; } } } }
static gboolean operation_source_process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *result, gint level) { const Babl *out_format = gegl_operation_get_format (operation, "output"); if ((result->width > 0) && (result->height > 0)) { GeglBufferIterator *iter; if (gegl_operation_use_opencl (operation) && babl_format_get_n_components (out_format) == 4 && babl_format_get_type (out_format, 0) == babl_type ("float")) { GeglBufferClIterator *cl_iter; gboolean err; GEGL_NOTE (GEGL_DEBUG_OPENCL, "GEGL_OPERATION_POINT_RENDER: %s", GEGL_OPERATION_GET_CLASS (operation)->name); cl_iter = gegl_buffer_cl_iterator_new (output, result, out_format, GEGL_CL_BUFFER_WRITE); while (gegl_buffer_cl_iterator_next (cl_iter, &err) && !err) { err = checkerboard_cl_process (operation, cl_iter->tex[0], cl_iter->size[0], &cl_iter->roi[0], level); if (err) { gegl_buffer_cl_iterator_stop (cl_iter); break; } } if (err) GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", GEGL_OPERATION_GET_CLASS (operation)->name); else return TRUE; } iter = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) checkerboard_process (operation, iter->data[0], iter->length, &iter->roi[0], level); } return TRUE; }
static gboolean process (GeglOperation *operation, GeglBuffer *out_buf, const GeglRectangle *roi, gint level) { GeglBufferIterator *iter; const Babl *out_format = gegl_operation_get_format (operation, "output"); if (gegl_operation_use_opencl (operation)) { GeglBufferClIterator *cl_iter; gboolean err; GEGL_NOTE (GEGL_DEBUG_OPENCL, "GEGL_OPERATION_POINT_RENDER: %s", GEGL_OPERATION_GET_CLASS (operation)->name); cl_iter = gegl_buffer_cl_iterator_new (out_buf, roi, out_format, GEGL_CL_BUFFER_WRITE); while (gegl_buffer_cl_iterator_next (cl_iter, &err) && !err) { err = cl_process (operation, cl_iter->tex[0], cl_iter->roi); if (err) { gegl_buffer_cl_iterator_stop (cl_iter); break; } } if (err) GEGL_NOTE (GEGL_DEBUG_OPENCL, "Error: %s", GEGL_OPERATION_GET_CLASS (operation)->name); else return TRUE; } iter = gegl_buffer_iterator_new (out_buf, roi, level, out_format, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) c_process (operation, iter->data[0], &iter->roi[0]); return TRUE; }
static void fill_rect (GeglBuffer *buffer, const GeglRectangle *roi, gfloat value ) { GeglBufferIterator *gi; gi = gegl_buffer_iterator_new (buffer, roi, 0, NULL, GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (gi)) { gfloat *buf = gi->data[0]; gint i; for (i=0; i<gi->length; i++) { buf[i]=value; } } }
void canvas_buffer_to_paint_buf_alpha (GimpTempBuf *paint_buf, GeglBuffer *canvas_buffer, gint x_offset, gint y_offset) { /* Copy the canvas buffer in rect to the paint buffer's alpha channel */ GeglRectangle roi; GeglBufferIterator *iter; const guint paint_stride = gimp_temp_buf_get_width (paint_buf); gfloat *paint_data = (gfloat *) gimp_temp_buf_get_data (paint_buf); roi.x = x_offset; roi.y = y_offset; roi.width = gimp_temp_buf_get_width (paint_buf); roi.height = gimp_temp_buf_get_height (paint_buf); iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0, babl_format ("Y float"), GEGL_ACCESS_READ, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *canvas_pixel = (gfloat *)iter->data[0]; int iy, ix; for (iy = 0; iy < iter->roi[0].height; iy++) { int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x - roi.x; float *paint_pixel = &paint_data[paint_offset * 4]; for (ix = 0; ix < iter->roi[0].width; ix++) { paint_pixel[3] *= *canvas_pixel; canvas_pixel += 1; paint_pixel += 4; } } } }
static void buffer_get_auto_strech_data (GeglBuffer *buffer, AutostretchData *data) { gfloat smin = G_MAXFLOAT; gfloat smax = -G_MAXFLOAT; gfloat vmin = G_MAXFLOAT; gfloat vmax = -G_MAXFLOAT; GeglBufferIterator *gi; gi = gegl_buffer_iterator_new (buffer, NULL, 0, babl_format ("HSVA float"), GEGL_ACCESS_READ, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (gi)) { gfloat *buf = gi->data[0]; gint i; for (i = 0; i < gi->length; i++) { gfloat sval = buf[1]; gfloat vval = buf[2]; smin = MIN (sval, smin); smax = MAX (sval, smax); vmin = MIN (vval, vmin); vmax = MAX (vval, vmax); buf += 4; } } if (data) { data->slo = smin; data->sdiff = smax - smin; data->vlo = vmin; data->vdiff = vmax - vmin; } }
static void cdisplay_proof_convert_buffer (GimpColorDisplay *display, GeglBuffer *buffer, GeglRectangle *area) { CdisplayProof *proof = CDISPLAY_PROOF (display); GeglBufferIterator *iter; if (! proof->transform) return; iter = gegl_buffer_iterator_new (buffer, area, 0, babl_format ("R'G'B'A float"), GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *data = iter->data[0]; cmsDoTransform (proof->transform, data, data, iter->length); } }
static void cdisplay_lcms_convert_buffer (GimpColorDisplay *display, GeglBuffer *buffer, GeglRectangle *area) { CdisplayLcms *lcms = CDISPLAY_LCMS (display); GeglBufferIterator *iter; if (! lcms->transform) return; iter = gegl_buffer_iterator_new (buffer, area, 0, babl_format ("R'G'B'A float"), GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gfloat *data = iter->data[0]; cmsDoTransform (lcms->transform, data, data, iter->length); } }
static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *output, const GeglRectangle *result, gint level) { AutostretchData data; GeglBufferIterator *gi; buffer_get_auto_strech_data (input, &data); clean_autostretch_data (&data); gi = gegl_buffer_iterator_new (input, result, 0, babl_format ("HSVA float"), GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (gi, output, result, 0, babl_format ("HSVA float"), GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (gi)) { gfloat *in = gi->data[0]; gfloat *out = gi->data[1]; gint i; for (i = 0; i < gi->length; i++) { out[0] = in[0]; /* Keep hue */ out[1] = (in[1] - data.slo) / data.sdiff; out[2] = (in[2] - data.vlo) / data.vdiff; out[3] = in[3]; /* Keep alpha */ in += 4; out += 4; } } return TRUE; }
void gimp_gegl_index_to_mask (GeglBuffer *indexed_buffer, const GeglRectangle *indexed_rect, const Babl *indexed_format, GeglBuffer *mask_buffer, const GeglRectangle *mask_rect, gint index) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (indexed_buffer, indexed_rect, 0, indexed_format, GEGL_ACCESS_READ, GEGL_ABYSS_NONE); gegl_buffer_iterator_add (iter, mask_buffer, mask_rect, 0, babl_format ("Y float"), GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { const guchar *indexed = iter->data[0]; gfloat *mask = iter->data[1]; gint count = iter->length; while (count--) { if (*indexed == index) *mask = 1.0; else *mask = 0.0; indexed++; mask++; } } }
static void render_blob (GeglBuffer *buffer, GeglRectangle *rect, GimpBlob *blob) { GeglBufferIterator *iter; GeglRectangle *roi; iter = gegl_buffer_iterator_new (buffer, rect, 0, babl_format ("Y u8"), GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); roi = &iter->roi[0]; while (gegl_buffer_iterator_next (iter)) { guchar *d = iter->data[0]; gint h = roi->height; gint y; for (y = 0; y < h; y++, d += roi->width * 1) { render_blob_line (blob, d, roi->x, roi->y + y, roi->width); } } }
static void gimp_image_convert_profile_rgb (GimpImage *image, GimpColorProfile *src_profile, GimpColorProfile *dest_profile, GimpColorRenderingIntent intent, gboolean bpc, GimpProgress *progress) { GList *layers; GList *list; gint n_drawables; gint nth_drawable; layers = gimp_image_get_layer_list (image); n_drawables = g_list_length (layers); for (list = layers, nth_drawable = 0; list; list = g_list_next (list), nth_drawable++) { GimpDrawable *drawable = list->data; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; const Babl *iter_format; cmsUInt32Number lcms_format; cmsUInt32Number flags; cmsHTRANSFORM transform; if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable))) continue; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); iter_format = gimp_color_profile_get_format (gimp_drawable_get_format (drawable), &lcms_format); flags = cmsFLAGS_NOOPTIMIZE; if (bpc) flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; transform = cmsCreateTransform (src_lcms, lcms_format, dest_lcms, lcms_format, intent, flags); if (transform) { GeglBuffer *buffer; GeglBufferIterator *iter; buffer = gimp_drawable_get_buffer (drawable); gimp_drawable_push_undo (drawable, NULL, NULL, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); iter = gegl_buffer_iterator_new (buffer, NULL, 0, iter_format, GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { cmsDoTransform (transform, iter->data[0], iter->data[0], iter->length); } gimp_drawable_update (drawable, 0, 0, gegl_buffer_get_width (buffer), gegl_buffer_get_height (buffer)); cmsDeleteTransform (transform); } if (progress) gimp_progress_set_value (progress, (gdouble) nth_drawable / (gdouble) n_drawables); } g_list_free (layers); }
static GeglBuffer * gradient_precalc_shapeburst (GimpImage *image, GimpDrawable *drawable, const GeglRectangle *region, gdouble dist, GimpProgress *progress) { GimpChannel *mask; GeglBuffer *dist_buffer; GeglBuffer *temp_buffer; GeglNode *shapeburst; gdouble max; gfloat max_iteration; gimp_progress_set_text (progress, _("Calculating distance map")); /* allocate the distance map */ dist_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, region->width, region->height), babl_format ("Y float")); /* allocate the selection mask copy * XXX: its format should be the same of gimp:shapeburst input buffer * porting the op to 'float' should be reflected here as well */ temp_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, region->width, region->height), babl_format ("Y u8")); mask = gimp_image_get_mask (image); /* If the image mask is not empty, use it as the shape burst source */ if (! gimp_channel_is_empty (mask)) { gint x, y, width, height; gint off_x, off_y; gimp_item_mask_intersect (GIMP_ITEM (drawable), &x, &y, &width, &height); gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y); /* copy the mask to the temp mask */ gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), GEGL_RECTANGLE (x + off_x, y + off_y, width, height), temp_buffer, GEGL_RECTANGLE (0, 0, 0, 0)); } else { /* If the intended drawable has an alpha channel, use that */ if (gimp_drawable_has_alpha (drawable)) { const Babl *component_format; component_format = babl_format ("A u8"); /* extract the aplha into the temp mask */ gegl_buffer_set_format (temp_buffer, component_format); gegl_buffer_copy (gimp_drawable_get_buffer (drawable), GEGL_RECTANGLE (region->x, region->y, region->width, region->height), temp_buffer, GEGL_RECTANGLE (0, 0, 0, 0)); gegl_buffer_set_format (temp_buffer, NULL); } else { GeglColor *white = gegl_color_new ("white"); /* Otherwise, just fill the shapeburst to white */ gegl_buffer_set_color (temp_buffer, NULL, white); g_object_unref (white); } } shapeburst = gegl_node_new_child (NULL, "operation", "gimp:shapeburst", NULL); gimp_gegl_progress_connect (shapeburst, progress, NULL); gimp_gegl_apply_operation (temp_buffer, NULL, NULL, shapeburst, dist_buffer, NULL); gegl_node_get (shapeburst, "max-iterations", &max, NULL); g_object_unref (shapeburst); max_iteration = max; g_object_unref (temp_buffer); /* normalize the shapeburst with the max iteration */ if (max_iteration > 0) { GeglBufferIterator *iter; iter = gegl_buffer_iterator_new (dist_buffer, NULL, 0, NULL, GEGL_BUFFER_READWRITE, GEGL_ABYSS_NONE); while (gegl_buffer_iterator_next (iter)) { gint count = iter->length; gfloat *data = iter->data[0]; while (count--) *data++ /= max_iteration; } } return dist_buffer; }
static gboolean gimp_operation_cage_coef_calc_process (GeglOperation *operation, GeglBuffer *output, const GeglRectangle *roi) { GimpOperationCageCoefCalc *occc = GIMP_OPERATION_CAGE_COEF_CALC (operation); GimpCageConfig *config = GIMP_CAGE_CONFIG (occc->config); Babl *format = babl_format_n (babl_type ("float"), 2 * gimp_cage_config_get_n_points (config)); GeglBufferIterator *it; guint n_cage_vertices; GimpCagePoint *current, *last; if (! config) return FALSE; n_cage_vertices = gimp_cage_config_get_n_points (config); it = gegl_buffer_iterator_new (output, roi, format, GEGL_BUFFER_READWRITE); while (gegl_buffer_iterator_next (it)) { /* iterate inside the roi */ gint n_pixels = it->length; gint x = it->roi->x; /* initial x */ gint y = it->roi->y; /* and y coordinates */ gint j; gfloat *coef = it->data[0]; while(n_pixels--) { if (gimp_cage_config_point_inside(config, x, y)) { last = &(g_array_index (config->cage_points, GimpCagePoint, 0)); for( j = 0; j < n_cage_vertices; j++) { GimpVector2 v1,v2,a,b,p; gdouble BA,SRT,L0,L1,A0,A1,A10,L10, Q,S,R, absa; current = &(g_array_index (config->cage_points, GimpCagePoint, (j+1) % n_cage_vertices)); v1 = last->src_point; v2 = current->src_point; p.x = x; p.y = y; a.x = v2.x - v1.x; a.y = v2.y - v1.y; absa = gimp_vector2_length (&a); b.x = v1.x - x; b.y = v1.y - y; Q = a.x * a.x + a.y * a.y; S = b.x * b.x + b.y * b.y; R = 2.0 * (a.x * b.x + a.y * b.y); BA = b.x * a.y - b.y * a.x; SRT = sqrt(4.0 * S * Q - R * R); L0 = log(S); L1 = log(S + Q + R); A0 = atan2(R, SRT) / SRT; A1 = atan2(2.0 * Q + R, SRT) / SRT; A10 = A1 - A0; L10 = L1 - L0; /* edge coef */ coef[j + n_cage_vertices] = (-absa / (4.0 * G_PI)) * ((4.0*S-(R*R)/Q) * A10 + (R / (2.0 * Q)) * L10 + L1 - 2.0); if (isnan(coef[j + n_cage_vertices])) { coef[j + n_cage_vertices] = 0.0; } /* vertice coef */ if (!gimp_operation_cage_coef_calc_is_on_straight (&v1, &v2, &p)) { coef[j] += (BA / (2.0 * G_PI)) * (L10 /(2.0*Q) - A10 * (2.0 + R / Q)); coef[(j+1)%n_cage_vertices] -= (BA / (2.0 * G_PI)) * (L10 / (2.0 * Q) - A10 * (R / Q)); } last = current; } } coef += 2 * n_cage_vertices; /* update x and y coordinates */ x++; if (x >= (it->roi->x + it->roi->width)) { x = it->roi->x; y++; } } } return TRUE; }