[gimp] app: add gimp_gegl_convert_color_profile()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_gegl_convert_color_profile()
- Date: Fri, 14 Aug 2015 20:41:20 +0000 (UTC)
commit b03f0fc6e25001f0e76f801bd9537821047aeb29
Author: Michael Natterer <mitch gimp org>
Date: Fri Aug 14 22:39:18 2015 +0200
app: add gimp_gegl_convert_color_profile()
which converts a buffer with a profile into another one with another
profile. The function tries to avoid the lcms transform by checking if
a simple gegl_buffer_copy() has the same result.
app/gegl/Makefile.am | 1 +
app/gegl/gimp-gegl-loops.c | 106 +++++++++++++++++++++++++++++++++++++++++++
app/gegl/gimp-gegl-loops.h | 107 ++++++++++++++++++++++++--------------------
3 files changed, 165 insertions(+), 49 deletions(-)
---
diff --git a/app/gegl/Makefile.am b/app/gegl/Makefile.am
index 5217fdf..3b6ccef 100644
--- a/app/gegl/Makefile.am
+++ b/app/gegl/Makefile.am
@@ -9,6 +9,7 @@ AM_CPPFLAGS = \
$(CAIRO_CFLAGS) \
$(GEGL_CFLAGS) \
$(GDK_PIXBUF_CFLAGS) \
+ $(LCMS_CFLAGS) \
-I$(includedir)
noinst_LIBRARIES = libappgegl.a
diff --git a/app/gegl/gimp-gegl-loops.c b/app/gegl/gimp-gegl-loops.c
index dcf1015..52c5359 100644
--- a/app/gegl/gimp-gegl-loops.c
+++ b/app/gegl/gimp-gegl-loops.c
@@ -20,9 +20,14 @@
#include "config.h"
+#include <lcms2.h>
+
+#include <cairo.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gegl.h>
#include "libgimpmath/gimpmath.h"
+#include "libgimpcolor/gimpcolor.h"
#include "gimp-gegl-types.h"
@@ -618,3 +623,104 @@ gimp_gegl_replace (GeglBuffer *top_buffer,
}
}
}
+
+static gboolean
+gimp_color_profile_can_gegl_copy (GimpColorProfile *src_profile,
+ GimpColorProfile *dest_profile)
+{
+ static GimpColorProfile *srgb_profile = NULL;
+ static GimpColorProfile *linear_rgb_profile = NULL;
+
+ if (gimp_color_profile_is_equal (src_profile, dest_profile))
+ return TRUE;
+
+ if (! srgb_profile)
+ {
+ srgb_profile = gimp_color_profile_new_srgb ();
+ linear_rgb_profile = gimp_color_profile_new_linear_rgb ();
+ }
+
+ if ((gimp_color_profile_is_equal (src_profile, srgb_profile) ||
+ gimp_color_profile_is_equal (src_profile, linear_rgb_profile))
+ &&
+ (gimp_color_profile_is_equal (dest_profile, srgb_profile) ||
+ gimp_color_profile_is_equal (dest_profile, linear_rgb_profile)))
+ return TRUE;
+
+ return FALSE;
+}
+
+void
+gimp_gegl_convert_color_profile (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GimpColorProfile *src_profile,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ GimpColorProfile *dest_profile,
+ GimpColorRenderingIntent intent,
+ gboolean bpc)
+{
+ const Babl *src_format;
+ const Babl *dest_format;
+ cmsHPROFILE src_lcms;
+ cmsHPROFILE dest_lcms;
+ cmsUInt32Number lcms_src_format;
+ cmsUInt32Number lcms_dest_format;
+ cmsUInt32Number flags;
+ cmsHTRANSFORM transform;
+
+ /* FIXME: we need the unconditional full copy only in two cases:
+ * - if we return without doing anything
+ * - if there is an alpha channel, because lcms doesn't copy it
+ */
+ gegl_buffer_copy (src_buffer, src_rect, GEGL_ABYSS_NONE,
+ dest_buffer, dest_rect);
+
+ src_format = gegl_buffer_get_format (src_buffer);
+ dest_format = gegl_buffer_get_format (dest_buffer);
+
+ if ((gimp_babl_format_get_base_type (src_format) != GIMP_RGB) ||
+ (gimp_babl_format_get_base_type (dest_format) != GIMP_RGB))
+ return;
+
+ if (gimp_color_profile_can_gegl_copy (src_profile, dest_profile))
+ return;
+
+ src_lcms = gimp_color_profile_get_lcms_profile (src_profile);
+ dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);
+
+ src_format = gimp_color_profile_get_format (src_format, &lcms_src_format);
+ dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format);
+
+ flags = cmsFLAGS_NOOPTIMIZE;
+
+ if (bpc)
+ flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
+
+ transform = cmsCreateTransform (src_lcms, lcms_src_format,
+ dest_lcms, lcms_dest_format,
+ intent, flags);
+
+ if (transform)
+ {
+ GeglBufferIterator *iter;
+
+ iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0,
+ src_format,
+ GEGL_ACCESS_READ,
+ GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
+ dest_format,
+ GEGL_ACCESS_WRITE,
+ GEGL_ABYSS_NONE);
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ cmsDoTransform (transform,
+ iter->data[0], iter->data[1], iter->length);
+ }
+
+ cmsDeleteTransform (transform);
+ }
+}
diff --git a/app/gegl/gimp-gegl-loops.h b/app/gegl/gimp-gegl-loops.h
index f166967..1938af9 100644
--- a/app/gegl/gimp-gegl-loops.h
+++ b/app/gegl/gimp-gegl-loops.h
@@ -25,61 +25,70 @@
/* this is a pretty stupid port of concolve_region() that only works
* on a linear source buffer
*/
-void gimp_gegl_convolve (GeglBuffer *src_buffer,
- const GeglRectangle *src_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- const gfloat *kernel,
- gint kernel_size,
- gdouble divisor,
- GimpConvolutionType mode,
- gboolean alpha_weighting);
+void gimp_gegl_convolve (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ const gfloat *kernel,
+ gint kernel_size,
+ gdouble divisor,
+ GimpConvolutionType mode,
+ gboolean alpha_weighting);
-void gimp_gegl_dodgeburn (GeglBuffer *src_buffer,
- const GeglRectangle *src_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble exposure,
- GimpDodgeBurnType type,
- GimpTransferMode mode);
+void gimp_gegl_dodgeburn (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble exposure,
+ GimpDodgeBurnType type,
+ GimpTransferMode mode);
-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);
+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);
-void gimp_gegl_apply_mask (GeglBuffer *mask_buffer,
- const GeglRectangle *mask_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble opacity);
+void gimp_gegl_apply_mask (GeglBuffer *mask_buffer,
+ const GeglRectangle *mask_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble opacity);
-void gimp_gegl_combine_mask (GeglBuffer *mask_buffer,
- const GeglRectangle *mask_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble opacity);
+void gimp_gegl_combine_mask (GeglBuffer *mask_buffer,
+ const GeglRectangle *mask_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble opacity);
-void gimp_gegl_combine_mask_weird (GeglBuffer *mask_buffer,
- const GeglRectangle *mask_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble opacity,
- gboolean stipple);
+void gimp_gegl_combine_mask_weird (GeglBuffer *mask_buffer,
+ const GeglRectangle *mask_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble opacity,
+ gboolean stipple);
-void gimp_gegl_replace (GeglBuffer *top_buffer,
- const GeglRectangle *top_rect,
- GeglBuffer *bottom_buffer,
- const GeglRectangle *bottom_rect,
- GeglBuffer *mask_buffer,
- const GeglRectangle *mask_rect,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect,
- gdouble opacity,
- const gboolean *affect);
+void gimp_gegl_replace (GeglBuffer *top_buffer,
+ const GeglRectangle *top_rect,
+ GeglBuffer *bottom_buffer,
+ const GeglRectangle *bottom_rect,
+ GeglBuffer *mask_buffer,
+ const GeglRectangle *mask_rect,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ gdouble opacity,
+ const gboolean *affect);
+
+void gimp_gegl_convert_color_profile (GeglBuffer *src_buffer,
+ const GeglRectangle *src_rect,
+ GimpColorProfile *src_profile,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ GimpColorProfile *dest_profile,
+ GimpColorRenderingIntent intent,
+ gboolean bpc);
#endif /* __GIMP_GEGL_LOOPS_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]