[gimp] app: use the new Babl palette format to implement indexed images



commit e03dcc074b7fb7f8ba76a7394338e9df8a5bdffc
Author: Michael Natterer <mitch gimp org>
Date:   Sat Mar 17 20:33:47 2012 +0100

    app: use the new Babl palette format to implement indexed images
    
    - keep babl palette formats around in the image in indexed mode
    - create drawables with the right format
    - as first test, convert indexed drawabled to rgb/gray by simply
      calling gegl_buffer_convert()

 app/core/gimpdrawable-convert.c |  168 ++++----------------------------------
 app/core/gimpdrawable.c         |   54 ++++++++++++-
 app/core/gimpdrawable.h         |    3 +
 app/core/gimpimage-colormap.c   |   25 ++++++
 app/core/gimpimage-colormap.h   |   49 ++++++------
 app/core/gimpimage-private.h    |    2 +
 app/core/gimpimage.c            |   25 ++++++-
 7 files changed, 148 insertions(+), 178 deletions(-)
---
diff --git a/app/core/gimpdrawable-convert.c b/app/core/gimpdrawable-convert.c
index e6f6d69..96a7e7e 100644
--- a/app/core/gimpdrawable-convert.c
+++ b/app/core/gimpdrawable-convert.c
@@ -25,7 +25,6 @@
 
 #include "core-types.h"
 
-#include "base/pixel-region.h"
 #include "base/tile-manager.h"
 
 #include "gegl/gimp-gegl-utils.h"
@@ -91,175 +90,44 @@ void
 gimp_drawable_convert_tiles_rgb (GimpDrawable *drawable,
                                  TileManager  *new_tiles)
 {
-  GimpImageType type;
-  gboolean      has_alpha;
+  GeglBuffer *dest_buffer;
+  gboolean    has_alpha;
 
   g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (! gimp_drawable_is_rgb (drawable));
   g_return_if_fail (new_tiles != NULL);
 
-  type      = gimp_drawable_type (drawable);
   has_alpha = gimp_drawable_has_alpha (drawable);
 
   g_return_if_fail (tile_manager_bpp (new_tiles) == (has_alpha ? 4 : 3));
 
-  switch (GIMP_IMAGE_TYPE_BASE_TYPE (type))
-    {
-    case GIMP_GRAY:
-      {
-        GeglBuffer *dest_buffer;
-
-        dest_buffer = gimp_tile_manager_create_buffer (new_tiles, TRUE);
-
-        gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
-                          dest_buffer, NULL);
-
-        g_object_unref (dest_buffer);
-      }
-      break;
-
-    case GIMP_INDEXED:
-      {
-        PixelRegion   srcPR, destPR;
-        gint          row, col;
-        gint          offset;
-        const guchar *src, *s;
-        guchar       *dest, *d;
-        const guchar *cmap;
-        gpointer      pr;
-
-        cmap = gimp_drawable_get_colormap (drawable);
-
-        pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (drawable)),
-                           gimp_item_get_height (GIMP_ITEM (drawable)),
-                           FALSE);
-        pixel_region_init (&destPR, new_tiles,
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (drawable)),
-                           gimp_item_get_height (GIMP_ITEM (drawable)),
-                           TRUE);
-
-        for (pr = pixel_regions_register (2, &srcPR, &destPR);
-             pr != NULL;
-             pr = pixel_regions_process (pr))
-          {
-            src  = srcPR.data;
-            dest = destPR.data;
-
-            for (row = 0; row < srcPR.h; row++)
-              {
-                s = src;
-                d = dest;
-
-                for (col = 0; col < srcPR.w; col++)
-                  {
-                    offset = *s++ * 3;
-                    d[RED] = cmap[offset + 0];
-                    d[GREEN] = cmap[offset + 1];
-                    d[BLUE] = cmap[offset + 2];
-
-                    d += 3;
-                    if (has_alpha)
-                      *d++ = *s++;
-                  }
-
-                src += srcPR.rowstride;
-                dest += destPR.rowstride;
-              }
-          }
-      }
-      break;
-
-    default:
-      break;
-    }
+  dest_buffer = gimp_tile_manager_create_buffer (new_tiles, TRUE);
+
+  gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
+                    dest_buffer, NULL);
+
+  g_object_unref (dest_buffer);
 }
 
 void
 gimp_drawable_convert_tiles_grayscale (GimpDrawable *drawable,
                                        TileManager  *new_tiles)
 {
-  GimpImageType type;
-  gboolean      has_alpha;
+  GeglBuffer *dest_buffer;
+  gboolean    has_alpha;
 
   g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+  g_return_if_fail (! gimp_drawable_is_gray (drawable));
   g_return_if_fail (new_tiles != NULL);
 
-  type      = gimp_drawable_type (drawable);
   has_alpha = gimp_drawable_has_alpha (drawable);
 
   g_return_if_fail (tile_manager_bpp (new_tiles) == (has_alpha ? 2 : 1));
 
-  switch (GIMP_IMAGE_TYPE_BASE_TYPE (type))
-    {
-    case GIMP_RGB:
-      {
-        GeglBuffer *dest_buffer;
-
-        dest_buffer = gimp_tile_manager_create_buffer (new_tiles, TRUE);
-
-        gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
-                          dest_buffer, NULL);
-
-        g_object_unref (dest_buffer);
-      }
-      break;
-
-    case GIMP_INDEXED:
-      {
-        PixelRegion   srcPR, destPR;
-        gint          row, col;
-        gint          offset, val;
-        const guchar *src, *s;
-        guchar       *dest, *d;
-        const guchar *cmap;
-        gpointer      pr;
-
-        cmap = gimp_drawable_get_colormap (drawable);
-
-        pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (drawable)),
-                           gimp_item_get_height (GIMP_ITEM (drawable)),
-                           FALSE);
-        pixel_region_init (&destPR, new_tiles,
-                           0, 0,
-                           gimp_item_get_width  (GIMP_ITEM (drawable)),
-                           gimp_item_get_height (GIMP_ITEM (drawable)),
-                           TRUE);
-
-        for (pr = pixel_regions_register (2, &srcPR, &destPR);
-             pr != NULL;
-             pr = pixel_regions_process (pr))
-          {
-            src = srcPR.data;
-            dest = destPR.data;
-
-            for (row = 0; row < srcPR.h; row++)
-              {
-                s = src;
-                d = dest;
-
-                for (col = 0; col < srcPR.w; col++)
-                  {
-                    offset = *s++ * 3;
-                    val = GIMP_RGB_LUMINANCE (cmap[offset+0],
-                                              cmap[offset+1],
-                                              cmap[offset+2]) + 0.5;
-                    *d++ = (guchar) val;
-                    if (has_alpha)
-                      *d++ = *s++;
-                  }
-
-                src += srcPR.rowstride;
-                dest += destPR.rowstride;
-              }
-          }
-      }
-      break;
-
-    default:
-      break;
-    }
+  dest_buffer = gimp_tile_manager_create_buffer (new_tiles, TRUE);
+
+  gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
+                    dest_buffer, NULL);
+
+  g_object_unref (dest_buffer);
 }
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index 51251aa..5e249b0 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -1500,8 +1500,10 @@ static GeglBuffer *
 gimp_drawable_create_buffer (GimpDrawable *drawable,
                              gboolean      write)
 {
-  return gimp_tile_manager_create_buffer (gimp_drawable_get_tiles (drawable),
-                                          write);
+  TileManager *tiles  = gimp_drawable_get_tiles (drawable);
+  const Babl  *format = gimp_drawable_get_babl_format (drawable);
+
+  return gimp_tile_manager_create_buffer_with_format (tiles, format, write);
 }
 
 GeglBuffer *
@@ -1535,6 +1537,29 @@ gimp_drawable_get_write_buffer (GimpDrawable *drawable)
   return drawable->private->write_buffer;
 }
 
+void
+gimp_drawable_recreate_buffers (GimpDrawable *drawable)
+{
+  g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
+
+  if (drawable->private->read_buffer)
+    {
+      g_object_unref (drawable->private->read_buffer);
+      drawable->private->read_buffer = NULL;
+    }
+
+  if (drawable->private->write_buffer)
+    {
+      g_object_unref (drawable->private->write_buffer);
+      drawable->private->write_buffer = NULL;
+    }
+
+  if (drawable->private->tile_source_node)
+    gegl_node_set (drawable->private->tile_source_node,
+                   "buffer", gimp_drawable_get_read_buffer (drawable),
+                   NULL);
+}
+
 TileManager *
 gimp_drawable_get_tiles (GimpDrawable *drawable)
 {
@@ -1824,9 +1849,32 @@ gimp_drawable_fill_by_type (GimpDrawable *drawable,
 const Babl *
 gimp_drawable_get_babl_format (const GimpDrawable *drawable)
 {
+  GimpImageType type;
+
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
 
-  return gimp_bpp_to_babl_format (gimp_drawable_bytes (drawable), TRUE);
+  type = gimp_drawable_type (drawable);
+
+  switch (type)
+    {
+    case GIMP_RGB_IMAGE:    return babl_format ("RGB u8");
+    case GIMP_RGBA_IMAGE:   return babl_format ("RGBA u8");
+    case GIMP_GRAY_IMAGE:   return babl_format ("Y u8");
+    case GIMP_GRAYA_IMAGE:  return babl_format ("YA u8");
+    case GIMP_INDEXED_IMAGE:
+    case GIMP_INDEXEDA_IMAGE:
+      {
+        GimpImage *image = gimp_item_get_image (GIMP_ITEM (drawable));
+
+        return (type == GIMP_INDEXED_IMAGE ?
+                gimp_image_colormap_get_rgb_format (image) :
+                gimp_image_colormap_get_rgba_format (image));
+      }
+    }
+
+  g_warn_if_reached ();
+
+  return NULL;
 }
 
 gboolean
diff --git a/app/core/gimpdrawable.h b/app/core/gimpdrawable.h
index c9c4c1a..c99ff43 100644
--- a/app/core/gimpdrawable.h
+++ b/app/core/gimpdrawable.h
@@ -181,6 +181,9 @@ void            gimp_drawable_init_src_region    (GimpDrawable       *drawable,
 GeglBuffer    * gimp_drawable_get_read_buffer    (GimpDrawable       *drawable);
 GeglBuffer    * gimp_drawable_get_write_buffer   (GimpDrawable       *drawable);
 
+/* FIXME gegl migration hack */
+void            gimp_drawable_recreate_buffers   (GimpDrawable       *drawable);
+
 TileManager   * gimp_drawable_get_tiles          (GimpDrawable       *drawable);
 void            gimp_drawable_set_tiles          (GimpDrawable       *drawable,
                                                   gboolean            push_undo,
diff --git a/app/core/gimpimage-colormap.c b/app/core/gimpimage-colormap.c
index 0a0e7e5..9653299 100644
--- a/app/core/gimpimage-colormap.c
+++ b/app/core/gimpimage-colormap.c
@@ -71,6 +71,10 @@ gimp_image_colormap_init (GimpImage *image)
   private->colormap = g_new0 (guchar, GIMP_IMAGE_COLORMAP_SIZE);
   private->palette  = GIMP_PALETTE (gimp_palette_new (NULL, palette_name));
 
+  /* FIXME name palette */
+  private->babl_palette_rgb  = babl_new_palette (NULL, FALSE);
+  private->babl_palette_rgba = babl_new_palette (NULL, TRUE);
+
   gimp_palette_set_columns  (private->palette, 16);
 
   gimp_data_make_internal (GIMP_DATA (private->palette), palette_id);
@@ -118,6 +122,27 @@ gimp_image_colormap_free (GimpImage *image)
 
   g_object_unref (private->palette);
   private->palette = NULL;
+
+  babl_palette_reset (private->babl_palette_rgb);
+  babl_palette_reset (private->babl_palette_rgba);
+  private->babl_palette_rgb = NULL;
+  private->babl_palette_rgba = NULL;
+}
+
+const Babl *
+gimp_image_colormap_get_rgb_format  (GimpImage *image)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+
+  return GIMP_IMAGE_GET_PRIVATE (image)->babl_palette_rgb;
+}
+
+const Babl *
+gimp_image_colormap_get_rgba_format (GimpImage *image)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
+
+  return GIMP_IMAGE_GET_PRIVATE (image)->babl_palette_rgba;
 }
 
 GimpPalette *
diff --git a/app/core/gimpimage-colormap.h b/app/core/gimpimage-colormap.h
index 54be91e..9eb0694 100644
--- a/app/core/gimpimage-colormap.h
+++ b/app/core/gimpimage-colormap.h
@@ -22,29 +22,32 @@
 #define GIMP_IMAGE_COLORMAP_SIZE 768
 
 
-void           gimp_image_colormap_init        (GimpImage       *image);
-void           gimp_image_colormap_dispose     (GimpImage       *image);
-void           gimp_image_colormap_free        (GimpImage       *image);
-
-GimpPalette  * gimp_image_get_colormap_palette (GimpImage       *image);
-
-const guchar * gimp_image_get_colormap         (const GimpImage *image);
-gint           gimp_image_get_colormap_size    (const GimpImage *image);
-void           gimp_image_set_colormap         (GimpImage       *image,
-                                                const guchar    *colormap,
-                                                gint             n_colors,
-                                                gboolean         push_undo);
-
-void           gimp_image_get_colormap_entry   (GimpImage       *image,
-                                                gint             color_index,
-                                                GimpRGB         *color);
-void           gimp_image_set_colormap_entry   (GimpImage       *image,
-                                                gint             color_index,
-                                                const GimpRGB   *color,
-                                                gboolean         push_undo);
-
-void           gimp_image_add_colormap_entry   (GimpImage       *image,
-                                                const GimpRGB   *color);
+void           gimp_image_colormap_init            (GimpImage       *image);
+void           gimp_image_colormap_dispose         (GimpImage       *image);
+void           gimp_image_colormap_free            (GimpImage       *image);
+
+const Babl   * gimp_image_colormap_get_rgb_format  (GimpImage       *image);
+const Babl   * gimp_image_colormap_get_rgba_format (GimpImage       *image);
+
+GimpPalette  * gimp_image_get_colormap_palette     (GimpImage       *image);
+
+const guchar * gimp_image_get_colormap             (const GimpImage *image);
+gint           gimp_image_get_colormap_size        (const GimpImage *image);
+void           gimp_image_set_colormap             (GimpImage       *image,
+                                                    const guchar    *colormap,
+                                                    gint             n_colors,
+                                                    gboolean         push_undo);
+
+void           gimp_image_get_colormap_entry       (GimpImage       *image,
+                                                    gint             color_index,
+                                                    GimpRGB         *color);
+void           gimp_image_set_colormap_entry       (GimpImage       *image,
+                                                    gint             color_index,
+                                                    const GimpRGB   *color,
+                                                    gboolean         push_undo);
+
+void           gimp_image_add_colormap_entry       (GimpImage       *image,
+                                                    const GimpRGB   *color);
 
 
 #endif /* __GIMP_IMAGE_COLORMAP_H__ */
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index b966ba0..913b6fe 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -50,6 +50,8 @@ struct _GimpImagePrivate
   guchar            *colormap;              /*  colormap (for indexed)       */
   gint               n_colors;              /*  # of colors (for indexed)    */
   GimpPalette       *palette;               /*  palette of colormap          */
+  Babl              *babl_palette_rgb;      /*  palette's RGB Babl format    */
+  Babl              *babl_palette_rgba;     /*  palette's RGBA Babl format   */
 
   gint               dirty;                 /*  dirty flag -- # of ops       */
   guint              dirty_time;            /*  time when image became dirty */
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 2dd6408..a43741c 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -1156,6 +1156,15 @@ gimp_image_get_description (GimpViewable  *viewable,
 static void
 gimp_image_real_mode_changed (GimpImage *image)
 {
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+  GList            *layers;
+  GList            *layer;
+
+  /* FIXME gegl migration hack */
+  layers = gimp_item_stack_get_item_list (GIMP_ITEM_STACK (private->layers->container));
+  g_list_foreach (layers, (GFunc) gimp_drawable_recreate_buffers, NULL);
+  g_list_free (layers);
+
   gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
 }
 
@@ -1177,10 +1186,22 @@ static void
 gimp_image_real_colormap_changed (GimpImage *image,
                                   gint       color_index)
 {
-  if (gimp_image_base_type (image) == GIMP_INDEXED)
+  GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (private->colormap)
     {
-      GimpImagePrivate *private = GIMP_IMAGE_GET_PRIVATE (image);
+      babl_palette_set_palette (private->babl_palette_rgb,
+                                babl_format ("RGB u8"),
+                                private->colormap,
+                                private->n_colors);
+      babl_palette_set_palette (private->babl_palette_rgba,
+                                babl_format ("RGB u8"),
+                                private->colormap,
+                                private->n_colors);
+    }
 
+  if (gimp_image_base_type (image) == GIMP_INDEXED)
+    {
       gimp_image_color_hash_invalidate (image, color_index);
 
       /* A colormap alteration affects the whole image */



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