[gimp] app: allow to "cast" a buffer's pixel format to another one



commit a898491b3fe3fdb4cba91eac95ee288edbddb4f4
Author: Michael Natterer <mitch gimp org>
Date:   Fri Mar 16 13:21:53 2012 +0100

    app: allow to "cast" a buffer's pixel format to another one
    
    as long as it has the same number of bytes. Add
    gimp_tile_manager_create_buffer_with_format() for that purpose,
    register a format that contains's only a u8 alpha byte, and use that
    to extract alpha from drawables.

 app/core/gimpchannel.c                |   20 ++++++++++++--------
 app/core/gimplayer.c                  |   17 +++++++++++------
 app/gegl/gimp-gegl-utils.c            |   10 +++++++++-
 app/gegl/gimp-gegl-utils.h            |    3 +++
 app/gegl/gimp-gegl.c                  |    6 ++++++
 app/gegl/gimptilebackendtilemanager.c |   11 ++++++++++-
 app/gegl/gimptilebackendtilemanager.h |    1 +
 7 files changed, 52 insertions(+), 16 deletions(-)
---
diff --git a/app/core/gimpchannel.c b/app/core/gimpchannel.c
index 16fd6d7..78f1ea4 100644
--- a/app/core/gimpchannel.c
+++ b/app/core/gimpchannel.c
@@ -39,6 +39,8 @@
 
 #include "gegl/gimp-gegl-nodes.h"
 
+#include "gegl/gimp-gegl-utils.h"
+
 #include "gimp.h"
 #include "gimp-utils.h"
 #include "gimpcontainer.h"
@@ -1654,9 +1656,10 @@ gimp_channel_new_from_alpha (GimpImage     *image,
                              const GimpRGB *color)
 {
   GimpChannel *channel;
+  TileManager *dest_tiles;
+  GeglBuffer  *dest_buffer;
   gint         width;
   gint         height;
-  PixelRegion  srcPR, destPR;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
@@ -1669,14 +1672,15 @@ gimp_channel_new_from_alpha (GimpImage     *image,
 
   gimp_channel_clear (channel, NULL, FALSE);
 
-  pixel_region_init (&srcPR,
-                     gimp_drawable_get_tiles (drawable),
-                     0, 0, width, height, FALSE);
-  pixel_region_init (&destPR,
-                     gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
-                     0, 0, width, height, TRUE);
+  dest_tiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (channel));
+  dest_buffer = gimp_tile_manager_create_buffer_with_format (dest_tiles,
+                                                             babl_format ("A u8"),
+                                                             TRUE);
+
+  gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
+                    dest_buffer, NULL);
 
-  extract_alpha_region (&srcPR, NULL, &destPR);
+  g_object_unref (dest_buffer);
 
   channel->bounds_known = FALSE;
 
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index d72819b..b172848 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1607,13 +1607,18 @@ gimp_layer_create_mask (const GimpLayer *layer,
     case GIMP_ADD_ALPHA_TRANSFER_MASK:
       if (gimp_drawable_has_alpha (drawable))
         {
-          pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
-                             0, 0,
-                             gimp_item_get_width  (item),
-                             gimp_item_get_height (item),
-                             FALSE);
+          TileManager *dest_tiles;
+          GeglBuffer  *dest_buffer;
 
-          extract_alpha_region (&srcPR, NULL, &destPR);
+          dest_tiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (mask));
+          dest_buffer = gimp_tile_manager_create_buffer_with_format (dest_tiles,
+                                                                     babl_format ("A u8"),
+                                                                     TRUE);
+
+          gegl_buffer_copy (gimp_drawable_get_read_buffer (drawable), NULL,
+                            dest_buffer, NULL);
+
+          g_object_unref (dest_buffer);
 
           if (add_mask_type == GIMP_ADD_ALPHA_TRANSFER_MASK)
             {
diff --git a/app/gegl/gimp-gegl-utils.c b/app/gegl/gimp-gegl-utils.c
index 163a53e..3b2b5d7 100644
--- a/app/gegl/gimp-gegl-utils.c
+++ b/app/gegl/gimp-gegl-utils.c
@@ -161,10 +161,18 @@ GeglBuffer *
 gimp_tile_manager_create_buffer (TileManager *tm,
                                  gboolean     write)
 {
+  return gimp_tile_manager_create_buffer_with_format (tm, NULL, write);
+}
+
+GeglBuffer *
+gimp_tile_manager_create_buffer_with_format (TileManager *tm,
+                                             const Babl  *format,
+                                             gboolean     write)
+{
   GeglTileBackend *backend;
   GeglBuffer      *buffer;
 
-  backend = gimp_tile_backend_tile_manager_new (tm, write);
+  backend = gimp_tile_backend_tile_manager_new (tm, format, write);
   buffer = gegl_buffer_new_for_backend (NULL, backend);
   g_object_unref (backend);
 
diff --git a/app/gegl/gimp-gegl-utils.h b/app/gegl/gimp-gegl-utils.h
index 1482704..cb5dd99 100644
--- a/app/gegl/gimp-gegl-utils.h
+++ b/app/gegl/gimp-gegl-utils.h
@@ -32,6 +32,9 @@ const gchar * gimp_interpolation_to_gegl_filter (GimpInterpolationType  interpol
 
 GeglBuffer  * gimp_tile_manager_create_buffer   (TileManager           *tm,
                                                  gboolean               write);
+GeglBuffer *  gimp_tile_manager_create_buffer_with_format (TileManager *tm,
+                                                           const Babl  *format,
+                                                           gboolean     write);
 
 void          gimp_gegl_buffer_refetch_tiles    (GeglBuffer            *buffer);
 
diff --git a/app/gegl/gimp-gegl.c b/app/gegl/gimp-gegl.c
index 6240a62..5c415db 100644
--- a/app/gegl/gimp-gegl.c
+++ b/app/gegl/gimp-gegl.c
@@ -93,6 +93,12 @@ gimp_gegl_init (Gimp *gimp)
                     G_CALLBACK (gimp_gegl_notify_tile_cache_size),
                     NULL);
 
+  babl_format_new ("name", "A u8",
+                   babl_model ("RGBA"),
+                   babl_type ("u8"),
+                   babl_component ("A"),
+                   NULL);
+
   g_type_class_ref (GIMP_TYPE_OPERATION_BRIGHTNESS_CONTRAST);
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_COEF_CALC);
   g_type_class_ref (GIMP_TYPE_OPERATION_CAGE_TRANSFORM);
diff --git a/app/gegl/gimptilebackendtilemanager.c b/app/gegl/gimptilebackendtilemanager.c
index 6953575..333ad93 100644
--- a/app/gegl/gimptilebackendtilemanager.c
+++ b/app/gegl/gimptilebackendtilemanager.c
@@ -248,6 +248,7 @@ gimp_tile_write (GimpTileBackendTileManager *backend_tm,
 
 GeglTileBackend *
 gimp_tile_backend_tile_manager_new (TileManager *tm,
+                                    const Babl  *format,
                                     gboolean     write)
 {
   GeglTileBackend            *ret;
@@ -258,10 +259,18 @@ gimp_tile_backend_tile_manager_new (TileManager *tm,
   gint             bpp    = tile_manager_bpp (tm);
   GeglRectangle    rect   = { 0, 0, width, height };
 
+  g_return_val_if_fail (format == NULL ||
+                        babl_format_get_bytes_per_pixel (format) ==
+                        babl_format_get_bytes_per_pixel (gimp_bpp_to_babl_format (bpp, TRUE)),
+                        NULL);
+
+  if (! format)
+    format = gimp_bpp_to_babl_format (bpp, TRUE);
+
   ret = g_object_new (GIMP_TYPE_TILE_BACKEND_TILE_MANAGER,
                       "tile-width",  TILE_WIDTH,
                       "tile-height", TILE_HEIGHT,
-                      "format",      gimp_bpp_to_babl_format (bpp, TRUE),
+                      "format",      format,
                       NULL);
   backend_tm = GIMP_TILE_BACKEND_TILE_MANAGER (ret);
   backend_tm->priv->write = write;
diff --git a/app/gegl/gimptilebackendtilemanager.h b/app/gegl/gimptilebackendtilemanager.h
index 12e97d5..0f68f63 100644
--- a/app/gegl/gimptilebackendtilemanager.h
+++ b/app/gegl/gimptilebackendtilemanager.h
@@ -53,6 +53,7 @@ struct _GimpTileBackendTileManagerClass
 GType             gimp_tile_backend_tile_manager_get_type (void) G_GNUC_CONST;
 
 GeglTileBackend * gimp_tile_backend_tile_manager_new      (TileManager *tm,
+                                                           const Babl  *format,
                                                            gboolean     write);
 
 



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