[gimp] Bug 630748 - display filters do not work



commit 5cae0bf65c9720c3b7b142240724c42e18bbca14
Author: Omari Stephens <xsdg xsdg org>
Date:   Sun Jan 23 07:28:33 2011 +0000

    Bug 630748 - display filters do not work
    
    Create and use Cairo-compatible API for display filters. Also
    includes logic changes to the display filters to deal with cairo's
    ARGB32 pre-multiplied buffer format.

 app/display/gimpdisplayshell-render.c  |   31 +++-----
 libgimpwidgets/gimpcolordisplay.c      |   43 +++++++++++
 libgimpwidgets/gimpcolordisplay.h      |    9 ++-
 libgimpwidgets/gimpcolordisplaystack.c |   42 ++++++++++
 libgimpwidgets/gimpcolordisplaystack.h |   38 +++++-----
 modules/display-filter-color-blind.c   |  131 ++++++++++++++++----------------
 modules/display-filter-gamma.c         |   85 +++++++++++----------
 modules/display-filter-high-contrast.c |   83 +++++++++++----------
 modules/display-filter-lcms.c          |  119 ++++++++++++++++++-----------
 modules/display-filter-proof.c         |  112 +++++++++++++++++-----------
 plug-ins/pygimp/gimpui.defs            |   20 +++++
 11 files changed, 444 insertions(+), 269 deletions(-)
---
diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c
index 2c8b416..cf7cfe5 100644
--- a/app/display/gimpdisplayshell-render.c
+++ b/app/display/gimpdisplayshell-render.c
@@ -160,28 +160,23 @@ gimp_display_shell_render (GimpDisplayShell *shell,
 
   switch (type)
     {
-      case GIMP_RGBA_IMAGE:
-        render_image_rgb_a (&info);
-        break;
-      case GIMP_GRAYA_IMAGE:
-        render_image_gray_a (&info);
-        break;
-      default:
-        g_warning ("%s: unsupported projection type (%d)", G_STRFUNC, type);
-        g_assert_not_reached ();
+    case GIMP_RGBA_IMAGE:
+      render_image_rgb_a (&info);
+      break;
+    case GIMP_GRAYA_IMAGE:
+      render_image_gray_a (&info);
+      break;
+    default:
+      g_warning ("%s: unsupported projection type (%d)", G_STRFUNC, type);
+      g_assert_not_reached ();
     }
 
+  cairo_surface_mark_dirty (shell->render_surface);
+
   /*  apply filters to the rendered projection  */
-#if 0
   if (shell->filter_stack)
-    gimp_color_display_stack_convert (shell->filter_stack,
-                                      shell->render_buf,
-                                      w, h,
-                                      3,
-                                      3 * GIMP_DISPLAY_RENDER_BUF_WIDTH);
-#endif
-
-  cairo_surface_mark_dirty (shell->render_surface);
+    gimp_color_display_stack_convert_surface (shell->filter_stack,
+                                              shell->render_surface);
 
   if (shell->mask)
     {
diff --git a/libgimpwidgets/gimpcolordisplay.c b/libgimpwidgets/gimpcolordisplay.c
index 328618c..5216b4a 100644
--- a/libgimpwidgets/gimpcolordisplay.c
+++ b/libgimpwidgets/gimpcolordisplay.c
@@ -140,6 +140,7 @@ gimp_color_display_class_init (GimpColorDisplayClass *klass)
   klass->stock_id        = GIMP_STOCK_DISPLAY_FILTER;
 
   klass->clone           = NULL;
+  klass->convert_surface = NULL;
   klass->convert         = NULL;
   klass->load_state      = NULL;
   klass->save_state      = NULL;
@@ -334,6 +335,46 @@ gimp_color_display_clone (GimpColorDisplay *display)
   return GIMP_COLOR_DISPLAY (gimp_config_duplicate (GIMP_CONFIG (display)));
 }
 
+/**
+ * gimp_color_display_convert_surface:
+ * @display: a #GimpColorDisplay
+ * @surface: a #cairo_image_surface_t of type ARGB32
+ *
+ * Converts all pixels in @surface.
+ *
+ * Since: GIMP 2.8
+ **/
+void
+gimp_color_display_convert_surface (GimpColorDisplay *display,
+                                    cairo_surface_t  *surface)
+{
+  g_return_if_fail (GIMP_IS_COLOR_DISPLAY (display));
+  g_return_if_fail (surface != NULL);
+  g_return_if_fail (cairo_surface_get_type (surface) ==
+                    CAIRO_SURFACE_TYPE_IMAGE);
+
+  if (display->enabled &&
+      GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert_surface)
+    {
+      cairo_surface_flush (surface);
+      GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert_surface (display, surface);
+      cairo_surface_mark_dirty (surface);
+    }
+}
+
+/**
+ * gimp_color_display_convert:
+ * @display: a #GimpColorDisplay
+ * @buf: the pixel buffer to convert
+ * @width: the width of the buffer
+ * @height: the height of the buffer
+ * @bpp: the number of bytes per pixel
+ * @bpl: the buffer's rowstride
+ *
+ * Converts all pixels in @buf.
+ *
+ * Deprecated: GIMP 2.8: Use gimp_color_display_convert_surface() instead.
+ **/
 void
 gimp_color_display_convert (GimpColorDisplay *display,
                             guchar            *buf,
@@ -344,6 +385,8 @@ gimp_color_display_convert (GimpColorDisplay *display,
 {
   g_return_if_fail (GIMP_IS_COLOR_DISPLAY (display));
 
+  /*  implementing the convert method is deprecated
+   */
   if (display->enabled && GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert)
     GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert (display, buf,
                                                      width, height,
diff --git a/libgimpwidgets/gimpcolordisplay.h b/libgimpwidgets/gimpcolordisplay.h
index d187c63..9b6a806 100644
--- a/libgimpwidgets/gimpcolordisplay.h
+++ b/libgimpwidgets/gimpcolordisplay.h
@@ -56,6 +56,7 @@ struct _GimpColorDisplayClass
   /*  implementing the GimpColorDisplay::clone method is deprecated       */
   GimpColorDisplay * (* clone)           (GimpColorDisplay *display);
 
+  /*  implementing the GimpColorDisplay::convert method is deprecated     */
   void               (* convert)         (GimpColorDisplay *display,
                                           guchar           *buf,
                                           gint              width,
@@ -80,8 +81,10 @@ struct _GimpColorDisplayClass
 
   const gchar  *stock_id;
 
+  void               (* convert_surface) (GimpColorDisplay *display,
+                                          cairo_surface_t  *surface);
+
   /* Padding for future expansion */
-  void (* _gimp_reserved2) (void);
   void (* _gimp_reserved3) (void);
   void (* _gimp_reserved4) (void);
 };
@@ -95,12 +98,16 @@ GimpColorDisplay * gimp_color_display_new         (GType             display_typ
 
 GimpColorDisplay * gimp_color_display_clone       (GimpColorDisplay *display);
 
+void           gimp_color_display_convert_surface (GimpColorDisplay *display,
+                                                   cairo_surface_t  *surface);
+#ifndef GIMP_DISABLE_DEPRECATED
 void           gimp_color_display_convert         (GimpColorDisplay *display,
                                                    guchar           *buf,
                                                    gint              width,
                                                    gint              height,
                                                    gint              bpp,
                                                    gint              bpl);
+#endif
 void           gimp_color_display_load_state      (GimpColorDisplay *display,
                                                    GimpParasite     *state);
 GimpParasite * gimp_color_display_save_state      (GimpColorDisplay *display);
diff --git a/libgimpwidgets/gimpcolordisplaystack.c b/libgimpwidgets/gimpcolordisplaystack.c
index 8b32fa4..90b9d69 100644
--- a/libgimpwidgets/gimpcolordisplaystack.c
+++ b/libgimpwidgets/gimpcolordisplaystack.c
@@ -27,6 +27,7 @@
 
 #include "gimpwidgetstypes.h"
 
+#undef GIMP_DISABLE_DEPRECATED
 #include "gimpcolordisplay.h"
 #include "gimpcolordisplaystack.h"
 #include "gimpwidgetsmarshal.h"
@@ -283,6 +284,47 @@ gimp_color_display_stack_reorder_down (GimpColorDisplayStack *stack,
     }
 }
 
+/**
+ * gimp_color_display_stack_convert_surface:
+ * @display: a #GimpColorDisplayStack
+ * @surface: a #cairo_image_surface_t of type ARGB32
+ *
+ * Runs all the stack's filters on all pixels in @surface.
+ *
+ * Since: GIMP 2.8
+ **/
+void
+gimp_color_display_stack_convert_surface (GimpColorDisplayStack *stack,
+                                          cairo_surface_t       *surface)
+{
+  GList *list;
+
+  g_return_if_fail (GIMP_IS_COLOR_DISPLAY_STACK (stack));
+  g_return_if_fail (surface != NULL);
+  g_return_if_fail (cairo_surface_get_type (surface) ==
+                    CAIRO_SURFACE_TYPE_IMAGE);
+
+  for (list = stack->filters; list; list = g_list_next (list))
+    {
+      GimpColorDisplay *display = list->data;
+
+      gimp_color_display_convert_surface (display, surface);
+    }
+}
+
+/**
+ * gimp_color_display_stack_convert:
+ * @display: a #GimpColorDisplayStack
+ * @buf: the pixel buffer to convert
+ * @width: the width of the buffer
+ * @height: the height of the buffer
+ * @bpp: the number of bytes per pixel
+ * @bpl: the buffer's rowstride
+ *
+ * Converts all pixels in @buf.
+ *
+ * Deprecated: GIMP 2.8: Use gimp_color_display_stack_convert_surface() instead.
+ **/
 void
 gimp_color_display_stack_convert (GimpColorDisplayStack *stack,
                                   guchar                *buf,
diff --git a/libgimpwidgets/gimpcolordisplaystack.h b/libgimpwidgets/gimpcolordisplaystack.h
index 727d2a3..d561cdd 100644
--- a/libgimpwidgets/gimpcolordisplaystack.h
+++ b/libgimpwidgets/gimpcolordisplaystack.h
@@ -71,24 +71,26 @@ GType                   gimp_color_display_stack_get_type (void) G_GNUC_CONST;
 GimpColorDisplayStack * gimp_color_display_stack_new      (void);
 GimpColorDisplayStack * gimp_color_display_stack_clone    (GimpColorDisplayStack *stack);
 
-void   gimp_color_display_stack_changed      (GimpColorDisplayStack *stack);
-
-void   gimp_color_display_stack_add          (GimpColorDisplayStack *stack,
-                                              GimpColorDisplay      *display);
-void   gimp_color_display_stack_remove       (GimpColorDisplayStack *stack,
-                                              GimpColorDisplay      *display);
-void   gimp_color_display_stack_reorder_up   (GimpColorDisplayStack *stack,
-                                              GimpColorDisplay      *display);
-void   gimp_color_display_stack_reorder_down (GimpColorDisplayStack *stack,
-                                              GimpColorDisplay      *display);
-
-void   gimp_color_display_stack_convert      (GimpColorDisplayStack *stack,
-                                              guchar                *buf,
-                                              gint                   width,
-                                              gint                   height,
-                                              gint                   bpp,
-                                              gint                   bpl);
-
+void   gimp_color_display_stack_changed         (GimpColorDisplayStack *stack);
+
+void   gimp_color_display_stack_add             (GimpColorDisplayStack *stack,
+                                                 GimpColorDisplay      *display);
+void   gimp_color_display_stack_remove          (GimpColorDisplayStack *stack,
+                                                 GimpColorDisplay      *display);
+void   gimp_color_display_stack_reorder_up      (GimpColorDisplayStack *stack,
+                                                 GimpColorDisplay      *display);
+void   gimp_color_display_stack_reorder_down    (GimpColorDisplayStack *stack,
+                                                 GimpColorDisplay      *display);
+void   gimp_color_display_stack_convert_surface (GimpColorDisplayStack *stack,
+                                                 cairo_surface_t       *surface);
+#ifndef GIMP_DISABLE_DEPRECATED
+void   gimp_color_display_stack_convert         (GimpColorDisplayStack *stack,
+                                                 guchar                *buf,
+                                                 gint                   width,
+                                                 gint                   height,
+                                                 gint                   bpp,
+                                                 gint                   bpl);
+#endif
 
 G_END_DECLS
 
diff --git a/modules/display-filter-color-blind.c b/modules/display-filter-color-blind.c
index 4e6159c..dcad8cb 100644
--- a/modules/display-filter-color-blind.c
+++ b/modules/display-filter-color-blind.c
@@ -112,28 +112,24 @@ enum
 };
 
 
-GType              cdisplay_colorblind_get_type      (void);
-
-static void        cdisplay_colorblind_set_property  (GObject               *object,
-                                                      guint                  property_id,
-                                                      const GValue          *value,
-                                                      GParamSpec            *pspec);
-static void        cdisplay_colorblind_get_property  (GObject               *object,
-                                                      guint                  property_id,
-                                                      GValue                *value,
-                                                      GParamSpec            *pspec);
-
-static void        cdisplay_colorblind_convert       (GimpColorDisplay      *display,
-                                                      guchar                *buf,
-                                                      gint                   w,
-                                                      gint                   h,
-                                                      gint                   bpp,
-                                                      gint                   bpl);
-static GtkWidget * cdisplay_colorblind_configure      (GimpColorDisplay     *display);
-static void        cdisplay_colorblind_changed        (GimpColorDisplay     *display);
-
-static void        cdisplay_colorblind_set_deficiency (CdisplayColorblind   *colorblind,
-                                                       ColorblindDeficiency  value);
+GType              cdisplay_colorblind_get_type        (void);
+
+static void        cdisplay_colorblind_set_property    (GObject               *object,
+                                                        guint                  property_id,
+                                                        const GValue          *value,
+                                                        GParamSpec            *pspec);
+static void        cdisplay_colorblind_get_property    (GObject               *object,
+                                                        guint                  property_id,
+                                                        GValue                *value,
+                                                        GParamSpec            *pspec);
+
+static void        cdisplay_colorblind_convert_surface (GimpColorDisplay      *display,
+                                                        cairo_surface_t       *surface);
+static GtkWidget * cdisplay_colorblind_configure       (GimpColorDisplay      *display);
+static void        cdisplay_colorblind_changed         (GimpColorDisplay      *display);
+
+static void        cdisplay_colorblind_set_deficiency  (CdisplayColorblind    *colorblind,
+                                                        ColorblindDeficiency   value);
 
 
   /* The RGB<->LMS transforms above are computed from the human cone
@@ -147,7 +143,7 @@ static void        cdisplay_colorblind_set_deficiency (CdisplayColorblind   *col
    * following are the gamma estimates that we have used in the
    * Vischeck code. Many colorblind users have viewed our simulations
    * and told us that they "work" (simulated and original images are
-   * indistinguishabled).
+   * indistinguishable).
    */
 
 static const gfloat gammaRGB = 2.1;
@@ -248,8 +244,8 @@ cdisplay_colorblind_class_init (CdisplayColorblindClass *klass)
   GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
   GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
-  object_class->get_property = cdisplay_colorblind_get_property;
-  object_class->set_property = cdisplay_colorblind_set_property;
+  object_class->get_property     = cdisplay_colorblind_get_property;
+  object_class->set_property     = cdisplay_colorblind_set_property;
 
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_DEFICIENCY,
                                  "deficiency", NULL,
@@ -257,13 +253,13 @@ cdisplay_colorblind_class_init (CdisplayColorblindClass *klass)
                                  DEFAULT_DEFICIENCY,
                                  0);
 
-  display_class->name        = _("Color Deficient Vision");
-  display_class->help_id     = "gimp-colordisplay-colorblind";
-  display_class->stock_id    = GIMP_STOCK_DISPLAY_FILTER_COLORBLIND;
+  display_class->name            = _("Color Deficient Vision");
+  display_class->help_id         = "gimp-colordisplay-colorblind";
+  display_class->stock_id        = GIMP_STOCK_DISPLAY_FILTER_COLORBLIND;
 
-  display_class->convert     = cdisplay_colorblind_convert;
-  display_class->configure   = cdisplay_colorblind_configure;
-  display_class->changed     = cdisplay_colorblind_changed;
+  display_class->convert_surface = cdisplay_colorblind_convert_surface;
+  display_class->configure       = cdisplay_colorblind_configure;
+  display_class->changed         = cdisplay_colorblind_changed;
 }
 
 static void
@@ -359,55 +355,61 @@ lut_lookup (gfloat        value,
 }
 
 static void
-cdisplay_colorblind_convert (GimpColorDisplay *display,
-                             guchar           *buf,
-                             gint              width,
-                             gint              height,
-                             gint              bpp,
-                             gint              bpl)
+cdisplay_colorblind_convert_surface (GimpColorDisplay *display,
+                                     cairo_surface_t  *surface)
 {
   CdisplayColorblind *colorblind = CDISPLAY_COLORBLIND (display);
-  const gfloat        a1 = colorblind->a1;
-  const gfloat        b1 = colorblind->b1;
-  const gfloat        c1 = colorblind->c1;
-  const gfloat        a2 = colorblind->a2;
-  const gfloat        b2 = colorblind->b2;
-  const gfloat        c2 = colorblind->c2;
-  gfloat              tmp;
-  gfloat              red, green, blue;
-  gfloat              redOld, greenOld;
-  guchar             *b;
-  gint                x, y;
-
-  /* Require 3 bytes per pixel (assume RGB) */
-  if (bpp != 3)
+  gint            width  = cairo_image_surface_get_width (surface);
+  gint            height = cairo_image_surface_get_height (surface);
+  gint            stride = cairo_image_surface_get_stride (surface);
+  guchar         *buf    = cairo_image_surface_get_data (surface);
+  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
+  const gfloat    a1     = colorblind->a1;
+  const gfloat    b1     = colorblind->b1;
+  const gfloat    c1     = colorblind->c1;
+  const gfloat    a2     = colorblind->a2;
+  const gfloat    b2     = colorblind->b2;
+  const gfloat    c2     = colorblind->c2;
+  gfloat          tmp;
+  gfloat          red, green, blue;
+  gfloat          redOld, greenOld;
+  guchar          r, g, b, a;
+  gint            x, y, skip;
+
+  /* Require ARGB32 pixel format */
+  if (fmt != CAIRO_FORMAT_ARGB32)
     return;
 
-  for (y = 0; y < height; y++, buf += bpl)
-    for (x = 0, b = buf; x < width; x++, b += bpp)
+  skip = stride - 4 * width;
+
+  for (y = 0; y < height; y++, buf += skip)
+    for (x = 0; x < width; x++, buf += 4)
       {
         guint32 pixel;
         guint   index;
 
         /* First check our cache */
-        pixel = b[0] << 16 | b[1] << 8 | b[2];
+        GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
+        pixel = r << 16 | g << 8 | b;
         index = pixel % COLOR_CACHE_SIZE;
 
         if (colorblind->cache[2 * index] == pixel)
           {
             pixel = colorblind->cache[2 * index + 1];
 
-            b[2] = pixel & 0xFF; pixel >>= 8;
-            b[1] = pixel & 0xFF; pixel >>= 8;
-            b[0] = pixel & 0xFF;
+            b = pixel & 0xFF; pixel >>= 8;
+            g = pixel & 0xFF; pixel >>= 8;
+            r = pixel & 0xFF;
+
+            GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
 
             continue;
           }
 
         /* Remove gamma to linearize RGB intensities */
-        red   = colorblind->gamma_lut[b[0]];
-        green = colorblind->gamma_lut[b[1]];
-        blue  = colorblind->gamma_lut[b[2]];
+        red   = colorblind->gamma_lut[r];
+        green = colorblind->gamma_lut[g];
+        blue  = colorblind->gamma_lut[b];
 
         /* Convert to LMS (dot product with transform matrix) */
         redOld   = red;
@@ -459,13 +461,14 @@ cdisplay_colorblind_convert (GimpColorDisplay *display,
         blue  = redOld * lms2rgb[6] + greenOld * lms2rgb[7] + blue * lms2rgb[8];
 
         /* Apply gamma to go back to non-linear intensities */
-        b[0] = lut_lookup (red,   colorblind->gamma_lut);
-        b[1] = lut_lookup (green, colorblind->gamma_lut);
-        b[2] = lut_lookup (blue,  colorblind->gamma_lut);
+        r = lut_lookup (red,   colorblind->gamma_lut);
+        g = lut_lookup (green, colorblind->gamma_lut);
+        b = lut_lookup (blue,  colorblind->gamma_lut);
+        GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
 
         /* Put the result into our cache */
         colorblind->cache[2 * index]     = pixel;
-        colorblind->cache[2 * index + 1] = b[0] << 16 | b[1] << 8 | b[2];
+        colorblind->cache[2 * index + 1] = r << 16 | g << 8 | b;
       }
 }
 
diff --git a/modules/display-filter-gamma.c b/modules/display-filter-gamma.c
index f228b76..797bd16 100644
--- a/modules/display-filter-gamma.c
+++ b/modules/display-filter-gamma.c
@@ -61,26 +61,22 @@ enum
 };
 
 
-GType              cdisplay_gamma_get_type     (void);
-
-static void        cdisplay_gamma_set_property (GObject            *object,
-                                                guint               property_id,
-                                                const GValue       *value,
-                                                GParamSpec         *pspec);
-static void        cdisplay_gamma_get_property (GObject            *object,
-                                                guint               property_id,
-                                                GValue             *value,
-                                                GParamSpec         *pspec);
-
-static void        cdisplay_gamma_convert      (GimpColorDisplay   *display,
-                                                guchar             *buf,
-                                                gint                w,
-                                                gint                h,
-                                                 gint               bpp,
-                                                gint                bpl);
-static GtkWidget * cdisplay_gamma_configure    (GimpColorDisplay   *display);
-static void        cdisplay_gamma_set_gamma    (CdisplayGamma      *gamma,
-                                                gdouble             value);
+GType              cdisplay_gamma_get_type        (void);
+
+static void        cdisplay_gamma_set_property    (GObject            *object,
+                                                   guint               property_id,
+                                                   const GValue       *value,
+                                                   GParamSpec         *pspec);
+static void        cdisplay_gamma_get_property    (GObject            *object,
+                                                   guint               property_id,
+                                                   GValue             *value,
+                                                   GParamSpec         *pspec);
+
+static void        cdisplay_gamma_convert_surface (GimpColorDisplay   *display,
+                                                   cairo_surface_t    *surface);
+static GtkWidget * cdisplay_gamma_configure       (GimpColorDisplay   *display);
+static void        cdisplay_gamma_set_gamma       (CdisplayGamma      *gamma,
+                                                   gdouble             value);
 
 
 static const GimpModuleInfo cdisplay_gamma_info =
@@ -117,20 +113,20 @@ cdisplay_gamma_class_init (CdisplayGammaClass *klass)
   GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
   GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
-  object_class->get_property = cdisplay_gamma_get_property;
-  object_class->set_property = cdisplay_gamma_set_property;
+  object_class->get_property     = cdisplay_gamma_get_property;
+  object_class->set_property     = cdisplay_gamma_set_property;
 
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_GAMMA,
                                    "gamma", NULL,
                                    0.01, 10.0, DEFAULT_GAMMA,
                                    0);
 
-  display_class->name        = _("Gamma");
-  display_class->help_id     = "gimp-colordisplay-gamma";
-  display_class->stock_id    = GIMP_STOCK_DISPLAY_FILTER_GAMMA;
+  display_class->name            = _("Gamma");
+  display_class->help_id         = "gimp-colordisplay-gamma";
+  display_class->stock_id        = GIMP_STOCK_DISPLAY_FILTER_GAMMA;
 
-  display_class->convert     = cdisplay_gamma_convert;
-  display_class->configure   = cdisplay_gamma_configure;
+  display_class->convert_surface = cdisplay_gamma_convert_surface;
+  display_class->configure       = cdisplay_gamma_configure;
 }
 
 static void
@@ -182,15 +178,20 @@ cdisplay_gamma_set_property (GObject      *object,
 }
 
 static void
-cdisplay_gamma_convert (GimpColorDisplay *display,
-                        guchar           *buf,
-                        gint              width,
-                        gint              height,
-                        gint              bpp,
-                        gint              bpl)
+cdisplay_gamma_convert_surface (GimpColorDisplay *display,
+                                cairo_surface_t  *surface)
 {
-  CdisplayGamma *gamma = CDISPLAY_GAMMA (display);
-  gint           i, j  = height;
+  CdisplayGamma  *gamma  = CDISPLAY_GAMMA (display);
+  gint            width  = cairo_image_surface_get_width (surface);
+  gint            height = cairo_image_surface_get_height (surface);
+  gint            stride = cairo_image_surface_get_stride (surface);
+  guchar         *buf    = cairo_image_surface_get_data (surface);
+  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
+  gint            i, j, skip;
+  gint            r, g, b, a;
+
+  if (fmt != CAIRO_FORMAT_ARGB32)
+    return;
 
   /* You will not be using the entire buffer most of the time.
    * Hence, the simplistic code for this is as follows:
@@ -203,18 +204,22 @@ cdisplay_gamma_convert (GimpColorDisplay *display,
    *   }
    */
 
-  width *= bpp;
-  bpl -= width;
+  j = height;
+  skip = stride - 4 * width;
 
   while (j--)
     {
       i = width;
       while (i--)
         {
-          *buf = gamma->lookup[*buf];
-          buf++;
+          GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
+          r = gamma->lookup[r];
+          g = gamma->lookup[g];
+          b = gamma->lookup[b];
+          GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
+          buf += 4;
         }
-      buf += bpl;
+      buf += skip;
     }
 }
 
diff --git a/modules/display-filter-high-contrast.c b/modules/display-filter-high-contrast.c
index 48091ad..550acee 100644
--- a/modules/display-filter-high-contrast.c
+++ b/modules/display-filter-high-contrast.c
@@ -61,26 +61,22 @@ enum
 };
 
 
-GType              cdisplay_contrast_get_type     (void);
-
-static void        cdisplay_contrast_set_property (GObject          *object,
-                                                   guint             property_id,
-                                                   const GValue     *value,
-                                                   GParamSpec       *pspec);
-static void        cdisplay_contrast_get_property (GObject          *object,
-                                                   guint             property_id,
-                                                   GValue           *value,
-                                                   GParamSpec       *pspec);
-
-static void        cdisplay_contrast_convert      (GimpColorDisplay *display,
-                                                   guchar           *buf,
-                                                   gint              w,
-                                                   gint              h,
-                                                   gint              bpp,
-                                                   gint              bpl);
-static GtkWidget * cdisplay_contrast_configure    (GimpColorDisplay *display);
-static void        cdisplay_contrast_set_contrast (CdisplayContrast *contrast,
-                                                   gdouble           value);
+GType              cdisplay_contrast_get_type        (void);
+
+static void        cdisplay_contrast_set_property    (GObject          *object,
+                                                      guint             property_id,
+                                                      const GValue     *value,
+                                                      GParamSpec       *pspec);
+static void        cdisplay_contrast_get_property    (GObject          *object,
+                                                      guint             property_id,
+                                                      GValue           *value,
+                                                      GParamSpec       *pspec);
+
+static void        cdisplay_contrast_convert_surface (GimpColorDisplay *display,
+                                                      cairo_surface_t  *surface);
+static GtkWidget * cdisplay_contrast_configure       (GimpColorDisplay *display);
+static void        cdisplay_contrast_set_contrast    (CdisplayContrast *contrast,
+                                                      gdouble           value);
 
 
 static const GimpModuleInfo cdisplay_contrast_info =
@@ -117,20 +113,20 @@ cdisplay_contrast_class_init (CdisplayContrastClass *klass)
   GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
   GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
-  object_class->get_property = cdisplay_contrast_get_property;
-  object_class->set_property = cdisplay_contrast_set_property;
+  object_class->get_property     = cdisplay_contrast_get_property;
+  object_class->set_property     = cdisplay_contrast_set_property;
 
   GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CONTRAST,
                                    "contrast", NULL,
                                    0.01, 10.0, DEFAULT_CONTRAST,
                                    0);
 
-  display_class->name        = _("Contrast");
-  display_class->help_id     = "gimp-colordisplay-contrast";
-  display_class->stock_id    = GIMP_STOCK_DISPLAY_FILTER_CONTRAST;
+  display_class->name            = _("Contrast");
+  display_class->help_id         = "gimp-colordisplay-contrast";
+  display_class->stock_id        = GIMP_STOCK_DISPLAY_FILTER_CONTRAST;
 
-  display_class->convert     = cdisplay_contrast_convert;
-  display_class->configure   = cdisplay_contrast_configure;
+  display_class->convert_surface = cdisplay_contrast_convert_surface;
+  display_class->configure       = cdisplay_contrast_configure;
 }
 
 static void
@@ -182,15 +178,20 @@ cdisplay_contrast_set_property (GObject      *object,
 }
 
 static void
-cdisplay_contrast_convert (GimpColorDisplay *display,
-                           guchar           *buf,
-                           gint              width,
-                           gint              height,
-                           gint              bpp,
-                           gint              bpl)
+cdisplay_contrast_convert_surface (GimpColorDisplay *display,
+                                   cairo_surface_t  *surface)
 {
   CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
-  gint              i, j     = height;
+  gint              width    = cairo_image_surface_get_width (surface);
+  gint              height   = cairo_image_surface_get_height (surface);
+  gint              stride   = cairo_image_surface_get_stride (surface);
+  guchar           *buf      = cairo_image_surface_get_data (surface);
+  cairo_format_t    fmt      = cairo_image_surface_get_format (surface);
+  gint              i, j, skip;
+  gint              r, g, b, a;
+
+  if (fmt != CAIRO_FORMAT_ARGB32)
+    return;
 
   /* You will not be using the entire buffer most of the time.
    * Hence, the simplistic code for this is as follows:
@@ -203,18 +204,22 @@ cdisplay_contrast_convert (GimpColorDisplay *display,
    *   }
    */
 
-  width *= bpp;
-  bpl -= width;
+  j = height;
+  skip = stride - 4 * width;
 
   while (j--)
     {
       i = width;
       while (i--)
         {
-          *buf = contrast->lookup[*buf];
-          buf++;
+          GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
+          r = contrast->lookup[r];
+          g = contrast->lookup[g];
+          b = contrast->lookup[b];
+          GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
+          buf += 4;
         }
-      buf += bpl;
+      buf += skip;
     }
 }
 
diff --git a/modules/display-filter-lcms.c b/modules/display-filter-lcms.c
index 5cd5da3..bde1610 100644
--- a/modules/display-filter-lcms.c
+++ b/modules/display-filter-lcms.c
@@ -51,7 +51,7 @@
 #define CDISPLAY_IS_LCMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_LCMS))
 
 
-typedef struct _CdisplayLcms CdisplayLcms;
+typedef struct _CdisplayLcms      CdisplayLcms;
 typedef struct _CdisplayLcmsClass CdisplayLcmsClass;
 
 struct _CdisplayLcms
@@ -67,32 +67,28 @@ struct _CdisplayLcmsClass
 };
 
 
-GType               cdisplay_lcms_get_type     (void);
+GType               cdisplay_lcms_get_type             (void);
 
-static void         cdisplay_lcms_finalize     (GObject           *object);
+static void         cdisplay_lcms_finalize             (GObject           *object);
 
-static GtkWidget  * cdisplay_lcms_configure    (GimpColorDisplay  *display);
-static void         cdisplay_lcms_convert      (GimpColorDisplay  *display,
-                                                guchar            *buf,
-                                                gint               width,
-                                                gint               height,
-                                                gint               bpp,
-                                                gint               bpl);
-static void         cdisplay_lcms_changed      (GimpColorDisplay  *display);
+static GtkWidget  * cdisplay_lcms_configure            (GimpColorDisplay  *display);
+static void         cdisplay_lcms_convert_surface      (GimpColorDisplay  *display,
+                                                        cairo_surface_t   *surface);
+static void         cdisplay_lcms_changed              (GimpColorDisplay  *display);
 
-static cmsHPROFILE  cdisplay_lcms_get_rgb_profile      (CdisplayLcms *lcms);
-static cmsHPROFILE  cdisplay_lcms_get_display_profile  (CdisplayLcms *lcms);
-static cmsHPROFILE  cdisplay_lcms_get_printer_profile  (CdisplayLcms *lcms);
+static cmsHPROFILE  cdisplay_lcms_get_rgb_profile      (CdisplayLcms      *lcms);
+static cmsHPROFILE  cdisplay_lcms_get_display_profile  (CdisplayLcms      *lcms);
+static cmsHPROFILE  cdisplay_lcms_get_printer_profile  (CdisplayLcms      *lcms);
 
-static void         cdisplay_lcms_attach_labelled      (GtkTable     *table,
-                                                        gint          row,
-                                                        const gchar  *text,
-                                                        GtkWidget    *widget);
-static void         cdisplay_lcms_update_profile_label (CdisplayLcms *lcms,
-                                                        const gchar  *name);
-static void         cdisplay_lcms_notify_profile       (GObject      *config,
-                                                        GParamSpec   *pspec,
-                                                        CdisplayLcms *lcms);
+static void         cdisplay_lcms_attach_labelled      (GtkTable          *table,
+                                                        gint               row,
+                                                        const gchar       *text,
+                                                        GtkWidget         *widget);
+static void         cdisplay_lcms_update_profile_label (CdisplayLcms      *lcms,
+                                                        const gchar       *name);
+static void         cdisplay_lcms_notify_profile       (GObject           *config,
+                                                        GParamSpec        *pspec,
+                                                        CdisplayLcms      *lcms);
 
 
 static const GimpModuleInfo cdisplay_lcms_info =
@@ -128,15 +124,15 @@ cdisplay_lcms_class_init (CdisplayLcmsClass *klass)
   GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
   GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
-  object_class->finalize = cdisplay_lcms_finalize;
+  object_class->finalize         = cdisplay_lcms_finalize;
 
-  display_class->name        = _("Color Management");
-  display_class->help_id     = "gimp-colordisplay-lcms";
-  display_class->stock_id    = GIMP_STOCK_DISPLAY_FILTER_LCMS;
+  display_class->name            = _("Color Management");
+  display_class->help_id         = "gimp-colordisplay-lcms";
+  display_class->stock_id        = GIMP_STOCK_DISPLAY_FILTER_LCMS;
 
-  display_class->configure   = cdisplay_lcms_configure;
-  display_class->convert     = cdisplay_lcms_convert;
-  display_class->changed     = cdisplay_lcms_changed;
+  display_class->configure       = cdisplay_lcms_configure;
+  display_class->convert_surface = cdisplay_lcms_convert_surface;
+  display_class->changed         = cdisplay_lcms_changed;
 
   cmsErrorAction (LCMS_ERROR_IGNORE);
 }
@@ -257,24 +253,55 @@ cdisplay_lcms_configure (GimpColorDisplay *display)
 }
 
 static void
-cdisplay_lcms_convert (GimpColorDisplay *display,
-                       guchar           *buf,
-                       gint              width,
-                       gint              height,
-                       gint              bpp,
-                       gint              bpl)
+cdisplay_lcms_convert_surface (GimpColorDisplay *display,
+                               cairo_surface_t  *surface)
 {
-  CdisplayLcms *lcms = CDISPLAY_LCMS (display);
-  gint          y;
-
-  if (bpp != 3)
+  CdisplayLcms   *lcms   = CDISPLAY_LCMS (display);
+  gint            width  = cairo_image_surface_get_width (surface);
+  gint            height = cairo_image_surface_get_height (surface);
+  gint            stride = cairo_image_surface_get_stride (surface);
+  guchar         *buf    = cairo_image_surface_get_data (surface);
+  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
+  guchar         *rowbuf;
+  gint            x, y;
+  guchar          r, g, b, a;
+
+  if (fmt != CAIRO_FORMAT_ARGB32)
     return;
 
   if (! lcms->transform)
     return;
 
-  for (y = 0; y < height; y++, buf += bpl)
-    cmsDoTransform (lcms->transform, buf, buf, width);
+  rowbuf = g_malloc (stride);
+
+  for (y = 0; y < height; y++, buf += stride)
+    {
+      /* Switch buf from ARGB premul to ARGB non-premul, since lcms ignores the
+       * alpha channel.  The macro takes care of byte order.
+       */
+      for (x = 0; x < width; x++)
+        {
+          GIMP_CAIRO_ARGB32_GET_PIXEL (buf + 4*x, r, g, b, a);
+          rowbuf[4*x+0] = a;
+          rowbuf[4*x+1] = r;
+          rowbuf[4*x+2] = g;
+          rowbuf[4*x+3] = b;
+        }
+
+      cmsDoTransform (lcms->transform, rowbuf, rowbuf, width);
+
+      /* And back to ARGB premul */
+      for (x = 0; x < width; x++)
+        {
+          a = rowbuf[4*x+0];
+          r = rowbuf[4*x+1];
+          g = rowbuf[4*x+2];
+          b = rowbuf[4*x+3];
+          GIMP_CAIRO_ARGB32_SET_PIXEL (buf + 4*x, r, g, b, a);
+        }
+    }
+
+  g_free (rowbuf);
 }
 
 static void
@@ -339,8 +366,8 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
           cmsSetAlarmCodes (r, g, b);
         }
 
-      lcms->transform = cmsCreateProofingTransform (src_profile,  TYPE_RGB_8,
-                                                    dest_profile, TYPE_RGB_8,
+      lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_ARGB_8,
+                                                    dest_profile, TYPE_ARGB_8,
                                                     proof_profile,
                                                     config->simulation_intent,
                                                     config->display_intent,
@@ -355,8 +382,8 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
       if (! dest_profile)
        dest_profile = cmsCreate_sRGBProfile ();
 
-      lcms->transform = cmsCreateTransform (src_profile,  TYPE_RGB_8,
-                                            dest_profile, TYPE_RGB_8,
+      lcms->transform = cmsCreateTransform (src_profile, TYPE_ARGB_8,
+                                            dest_profile, TYPE_ARGB_8,
                                             config->display_intent,
                                             flags);
     }
diff --git a/modules/display-filter-proof.c b/modules/display-filter-proof.c
index 8c14dd7..a9e722b 100644
--- a/modules/display-filter-proof.c
+++ b/modules/display-filter-proof.c
@@ -38,7 +38,7 @@
 #define CDISPLAY_IS_PROOF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_PROOF))
 
 
-typedef struct _CdisplayProof CdisplayProof;
+typedef struct _CdisplayProof      CdisplayProof;
 typedef struct _CdisplayProofClass CdisplayProofClass;
 
 struct _CdisplayProof
@@ -67,27 +67,23 @@ enum
 };
 
 
-GType              cdisplay_proof_get_type     (void);
+GType              cdisplay_proof_get_type        (void);
 
-static void        cdisplay_proof_finalize     (GObject          *object);
-static void        cdisplay_proof_get_property (GObject          *object,
-                                                guint             property_id,
-                                                GValue           *value,
-                                                GParamSpec       *pspec);
-static void        cdisplay_proof_set_property (GObject          *object,
-                                                guint             property_id,
-                                                const GValue     *value,
-                                                GParamSpec       *pspec);
+static void        cdisplay_proof_finalize        (GObject          *object);
+static void        cdisplay_proof_get_property    (GObject          *object,
+                                                   guint             property_id,
+                                                   GValue           *value,
+                                                   GParamSpec       *pspec);
+static void        cdisplay_proof_set_property    (GObject          *object,
+                                                   guint             property_id,
+                                                   const GValue     *value,
+                                                   GParamSpec       *pspec);
 
 
-static void        cdisplay_proof_convert      (GimpColorDisplay *display,
-                                                guchar           *buf,
-                                                gint              width,
-                                                gint              height,
-                                                gint              bpp,
-                                                gint              bpl);
-static GtkWidget * cdisplay_proof_configure    (GimpColorDisplay *display);
-static void        cdisplay_proof_changed      (GimpColorDisplay *display);
+static void        cdisplay_proof_convert_surface (GimpColorDisplay *display,
+                                                   cairo_surface_t  *surface);
+static GtkWidget * cdisplay_proof_configure       (GimpColorDisplay *display);
+static void        cdisplay_proof_changed         (GimpColorDisplay *display);
 
 
 static const GimpModuleInfo cdisplay_proof_info =
@@ -123,9 +119,9 @@ cdisplay_proof_class_init (CdisplayProofClass *klass)
   GObjectClass          *object_class  = G_OBJECT_CLASS (klass);
   GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
 
-  object_class->finalize     = cdisplay_proof_finalize;
-  object_class->get_property = cdisplay_proof_get_property;
-  object_class->set_property = cdisplay_proof_set_property;
+  object_class->finalize         = cdisplay_proof_finalize;
+  object_class->get_property     = cdisplay_proof_get_property;
+  object_class->set_property     = cdisplay_proof_set_property;
 
   GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_INTENT,
                                  "intent", NULL,
@@ -141,13 +137,13 @@ cdisplay_proof_class_init (CdisplayProofClass *klass)
                                  GIMP_CONFIG_PATH_FILE, NULL,
                                  0);
 
-  display_class->name        = _("Color Proof");
-  display_class->help_id     = "gimp-colordisplay-proof";
-  display_class->stock_id    = GIMP_STOCK_DISPLAY_FILTER_PROOF;
+  display_class->name            = _("Color Proof");
+  display_class->help_id         = "gimp-colordisplay-proof";
+  display_class->stock_id        = GIMP_STOCK_DISPLAY_FILTER_PROOF;
 
-  display_class->convert     = cdisplay_proof_convert;
-  display_class->configure   = cdisplay_proof_configure;
-  display_class->changed     = cdisplay_proof_changed;
+  display_class->convert_surface = cdisplay_proof_convert_surface;
+  display_class->configure       = cdisplay_proof_configure;
+  display_class->changed         = cdisplay_proof_changed;
 
   cmsErrorAction (LCMS_ERROR_IGNORE);
 }
@@ -238,24 +234,55 @@ cdisplay_proof_set_property (GObject      *object,
 }
 
 static void
-cdisplay_proof_convert (GimpColorDisplay *display,
-                        guchar           *buf,
-                        gint              width,
-                        gint              height,
-                        gint              bpp,
-                        gint              bpl)
+cdisplay_proof_convert_surface (GimpColorDisplay *display,
+                                cairo_surface_t  *surface)
 {
-  CdisplayProof *proof = CDISPLAY_PROOF (display);
-  gint           y;
-
-  if (bpp != 3)
+  CdisplayProof  *proof  = CDISPLAY_PROOF (display);
+  gint            width  = cairo_image_surface_get_width (surface);
+  gint            height = cairo_image_surface_get_height (surface);
+  gint            stride = cairo_image_surface_get_stride (surface);
+  guchar         *buf    = cairo_image_surface_get_data (surface);
+  cairo_format_t  fmt    = cairo_image_surface_get_format (surface);
+  guchar         *rowbuf;
+  gint            x, y;
+  guchar          r, g, b, a;
+
+  if (fmt != CAIRO_FORMAT_ARGB32)
     return;
 
   if (! proof->transform)
     return;
 
-  for (y = 0; y < height; y++, buf += bpl)
-    cmsDoTransform (proof->transform, buf, buf, width);
+  rowbuf = g_malloc (stride);
+
+  for (y = 0; y < height; y++, buf += stride)
+    {
+      /* Switch buf from ARGB premul to ARGB non-premul, since lcms ignores the
+       * alpha channel.  The macro takes care of byte order.
+       */
+      for (x = 0; x < width; x++)
+        {
+          GIMP_CAIRO_ARGB32_GET_PIXEL (buf + 4*x, r, g, b, a);
+          rowbuf[4*x+0] = a;
+          rowbuf[4*x+1] = r;
+          rowbuf[4*x+2] = g;
+          rowbuf[4*x+3] = b;
+        }
+
+      cmsDoTransform (proof->transform, rowbuf, rowbuf, width);
+
+      /* And back to ARGB premul */
+      for (x = 0; x < width; x++)
+        {
+          a = rowbuf[4*x+0];
+          r = rowbuf[4*x+1];
+          g = rowbuf[4*x+2];
+          b = rowbuf[4*x+3];
+          GIMP_CAIRO_ARGB32_SET_PIXEL (buf + 4*x, r, g, b, a);
+        }
+    }
+
+  g_free (rowbuf);
 }
 
 static void
@@ -442,9 +469,8 @@ cdisplay_proof_changed (GimpColorDisplay *display)
       if (proof->bpc)
         flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
 
-      proof->transform = cmsCreateProofingTransform (rgbProfile,
-                                                     TYPE_RGB_8,
-                                                     rgbProfile, TYPE_RGB_8,
+      proof->transform = cmsCreateProofingTransform (rgbProfile, TYPE_ARGB_8,
+                                                     rgbProfile, TYPE_ARGB_8,
                                                      proofProfile,
                                                      proof->intent,
                                                      proof->intent,
diff --git a/plug-ins/pygimp/gimpui.defs b/plug-ins/pygimp/gimpui.defs
index 3319451..e0efe32 100644
--- a/plug-ins/pygimp/gimpui.defs
+++ b/plug-ins/pygimp/gimpui.defs
@@ -798,6 +798,15 @@
   (return-type "GimpColorDisplay*")
 )
 
+(define-method convert_surface
+  (of-object "GimpColorDisplay")
+  (c-name "gimp_color_display_convert_surface")
+  (return-type "none")
+  (parameters
+    '("cairo_surface_t*" "surface")
+  )
+)
+
 (define-method convert
   (of-object "GimpColorDisplay")
   (c-name "gimp_color_display_convert")
@@ -809,6 +818,7 @@
     '("gint" "bpp")
     '("gint" "bpl")
   )
+  (deprecated "use convert_surface(cairo_surface_t*) instead")
 )
 
 (define-method load_state
@@ -934,6 +944,15 @@
   )
 )
 
+(define-method convert_surface
+  (of-object "GimpColorDisplayStack")
+  (c-name "gimp_color_display_stack_convert_surface")
+  (return-type "none")
+  (parameters
+    '("cairo_surface_t*" "surface")
+  )
+)
+
 (define-method convert
   (of-object "GimpColorDisplayStack")
   (c-name "gimp_color_display_stack_convert")
@@ -945,6 +964,7 @@
     '("gint" "bpp")
     '("gint" "bpl")
   )
+  (deprecated "use convert_surface(cairo_surface_t*) instead")
 )
 
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]