static gboolean process (GeglOperation *op, void *in_buf, void *out_buf, glong samples, const GeglRectangle *roi, gint level) { GeglProperties *o = GEGL_PROPERTIES (op); CmParamsType *mix = (CmParamsType*) o->user_data; gdouble red_norm, green_norm, blue_norm; gfloat *in, *out; g_assert (mix != NULL); red_norm = cm_calculate_norm (mix, &mix->red); green_norm = cm_calculate_norm (mix, &mix->green); blue_norm = cm_calculate_norm (mix, &mix->blue); in = in_buf; out = out_buf; if (mix->has_alpha) { while (samples--) { cm_process_pixel (mix, in, out, red_norm, green_norm, blue_norm); out[3] = in[3]; in += 4; out += 4; } } else { while (samples--) { cm_process_pixel (mix, in, out, red_norm, green_norm, blue_norm); in += 3; out += 3; } } return TRUE; }
static void cm_preview (CmParamsType *mix, GimpPreview *preview) { guchar *src, *s; guchar *dst, *d; gint x, y; gdouble red_norm, green_norm, blue_norm, black_norm; gint width, height, bpp; GimpDrawable *drawable; red_norm = cm_calculate_norm (mix, &mix->red); green_norm = cm_calculate_norm (mix, &mix->green); blue_norm = cm_calculate_norm (mix, &mix->blue); black_norm = cm_calculate_norm (mix, &mix->black); drawable = gimp_zoom_preview_get_drawable (GIMP_ZOOM_PREVIEW (preview)); src = s = gimp_zoom_preview_get_source (GIMP_ZOOM_PREVIEW (preview), &width, &height, &bpp); dst = d = g_new (guchar, width * height * bpp); for (y = 0; y < height; y++) { for (x = 0; x < width; x++, s += bpp, d += bpp) { cm_process_pixel (mix, s, d, red_norm, green_norm, blue_norm, black_norm); if (bpp == 4) d[3] = s[3]; } } gimp_preview_draw_buffer (GIMP_PREVIEW (preview), dst, bpp * width); g_free (src); g_free (dst); }
static void channel_mixer (CmParamsType *mix, GimpDrawable *drawable) { GimpPixelRgn src_rgn, dest_rgn; gpointer pr; gboolean has_alpha; gdouble red_norm, green_norm, blue_norm, black_norm; gint i, total, processed = 0; gint x1, y1; gint width, height; if (! gimp_drawable_mask_intersect (drawable->drawable_id, &x1, &y1, &width, &height)) return; red_norm = cm_calculate_norm (mix, &mix->red); green_norm = cm_calculate_norm (mix, &mix->green); blue_norm = cm_calculate_norm (mix, &mix->blue); black_norm = cm_calculate_norm (mix, &mix->black); has_alpha = gimp_drawable_has_alpha (drawable->drawable_id); gimp_pixel_rgn_init (&src_rgn, drawable, x1, y1, width, height, FALSE, FALSE); gimp_pixel_rgn_init (&dest_rgn, drawable, x1, y1, width, height, TRUE, TRUE); total = width * height; for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), i = 0; pr != NULL; pr = gimp_pixel_rgns_process (pr), i++) { const guchar *src = src_rgn.data; guchar *dest = dest_rgn.data; gint x, y; for (y = 0; y < src_rgn.h; y++) { const guchar *s = src; guchar *d = dest; if (has_alpha) { for (x = 0; x < src_rgn.w; x++, s += 4, d += 4) { cm_process_pixel (mix, s, d, red_norm, green_norm, blue_norm, black_norm); d[3] = s[3]; } } else { for (x = 0; x < src_rgn.w; x++, s += 3, d += 3) { cm_process_pixel (mix, s, d, red_norm, green_norm, blue_norm, black_norm); } } src += src_rgn.rowstride; dest += dest_rgn.rowstride; } processed += src_rgn.w * src_rgn.h; if (i % 16 == 0) gimp_progress_update ((gdouble) processed / (gdouble) total); } gimp_progress_update (1.0); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, width, height); }