[gimp/metadata-browser] app: port simple rotating and flipping to GEGL



commit dd0e1e2f912dfaafad92e799a9940fc31513deaa
Author: Michael Natterer <mitch gimp org>
Date:   Mon Mar 19 19:57:55 2012 +0100

    app: port simple rotating and flipping to GEGL
    
    Which requires making the entire copy/paste apparatus aware of the
    Babl format of the passed around tile managers.

 app/core/gimp-edit.c              |    5 +-
 app/core/gimpdrawable-transform.c |  319 +++++++++++++++++++++++++------------
 app/core/gimpdrawable-transform.h |    5 +
 app/core/gimpdrawable.c           |    6 +
 app/core/gimplayer.c              |    5 +-
 app/core/gimplayer.h              |    1 +
 app/core/gimpselection.c          |   36 ++++-
 app/core/gimpselection.h          |    1 +
 app/tools/gimpfliptool.c          |    3 +
 app/tools/gimppaintoptions-gui.c  |    1 +
 app/tools/gimpsheartool.c         |    1 +
 app/tools/gimptransformoptions.c  |    1 +
 app/tools/gimptransformtool.c     |    8 +-
 app/tools/gimptransformtool.h     |    1 +
 app/tools/gimptransformtoolundo.c |    1 +
 15 files changed, 279 insertions(+), 115 deletions(-)
---
diff --git a/app/core/gimp-edit.c b/app/core/gimp-edit.c
index dd65d84..b716ad6 100644
--- a/app/core/gimp-edit.c
+++ b/app/core/gimp-edit.c
@@ -581,6 +581,7 @@ gimp_edit_extract (GimpImage     *image,
                    GError       **error)
 {
   TileManager *tiles;
+  const Babl  *format;
   gint         offset_x;
   gint         offset_y;
 
@@ -591,7 +592,7 @@ gimp_edit_extract (GimpImage     *image,
   tiles = gimp_selection_extract (GIMP_SELECTION (gimp_image_get_mask (image)),
                                   pickable, context,
                                   cut_pixels, FALSE, FALSE,
-                                  &offset_x, &offset_y, error);
+                                  &format, &offset_x, &offset_y, error);
 
   if (cut_pixels)
     gimp_image_undo_group_end (image);
@@ -601,7 +602,7 @@ gimp_edit_extract (GimpImage     *image,
       GeglBuffer *temp;
       GimpBuffer *buffer;
 
-      temp = gimp_tile_manager_create_buffer (tiles, NULL, TRUE);
+      temp = gimp_tile_manager_create_buffer (tiles, format, TRUE);
       tile_manager_unref (tiles);
 
       buffer = gimp_buffer_new (temp, _("Global Buffer"),
diff --git a/app/core/gimpdrawable-transform.c b/app/core/gimpdrawable-transform.c
index 65f2352..b55fa81 100644
--- a/app/core/gimpdrawable-transform.c
+++ b/app/core/gimpdrawable-transform.c
@@ -20,9 +20,11 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <cairo.h>
 #include <gegl.h>
 
 #include "libgimpbase/gimpbase.h"
+#include "libgimpcolor/gimpcolor.h"
 #include "libgimpmath/gimpmath.h"
 
 #include "core-types.h"
@@ -30,7 +32,7 @@
 #include "base/pixel-region.h"
 #include "base/tile-manager.h"
 
-#include "paint-funcs/paint-funcs.h"
+#include "gegl/gimp-gegl-utils.h"
 
 #include "gimp.h"
 #include "gimp-transform-region.h"
@@ -67,6 +69,7 @@ TileManager *
 gimp_drawable_transform_tiles_affine (GimpDrawable           *drawable,
                                       GimpContext            *context,
                                       TileManager            *orig_tiles,
+                                      const Babl             *orig_format,
                                       gint                    orig_offset_x,
                                       gint                    orig_offset_y,
                                       const GimpMatrix3      *matrix,
@@ -156,6 +159,7 @@ TileManager *
 gimp_drawable_transform_tiles_flip (GimpDrawable        *drawable,
                                     GimpContext         *context,
                                     TileManager         *orig_tiles,
+                                    const Babl          *orig_format,
                                     gint                 orig_offset_x,
                                     gint                 orig_offset_y,
                                     GimpOrientationType  flip_type,
@@ -164,23 +168,23 @@ gimp_drawable_transform_tiles_flip (GimpDrawable        *drawable,
                                     gint                *new_offset_x,
                                     gint                *new_offset_y)
 {
-  GimpImage   *image;
-  TileManager *new_tiles;
-  PixelRegion  srcPR, destPR;
-  gint         orig_x, orig_y;
-  gint         orig_width, orig_height;
-  gint         orig_bpp;
-  gint         new_x, new_y;
-  gint         new_width, new_height;
-  gint         i;
+  TileManager   *new_tiles;
+  GeglBuffer    *src_buffer;
+  GeglBuffer    *dest_buffer;
+  GeglRectangle  src_rect;
+  GeglRectangle  dest_rect;
+  gint           orig_x, orig_y;
+  gint           orig_width, orig_height;
+  gint           orig_bpp;
+  gint           new_x, new_y;
+  gint           new_width, new_height;
+  gint           i;
 
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (orig_tiles != NULL, NULL);
 
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
-
   orig_x      = orig_offset_x;
   orig_y      = orig_offset_y;
   orig_width  = tile_manager_width (orig_tiles);
@@ -210,26 +214,29 @@ gimp_drawable_transform_tiles_flip (GimpDrawable        *drawable,
     }
 
   new_tiles = tile_manager_new (new_width, new_height, orig_bpp);
+  dest_buffer = gimp_tile_manager_create_buffer (new_tiles, orig_format, TRUE);
 
   if (clip_result && (new_x != orig_x || new_y != orig_y))
     {
-      guchar bg_color[MAX_CHANNELS];
-      gint   clip_x, clip_y;
-      gint   clip_width, clip_height;
+      GimpRGB    bg;
+      GeglColor *color;
+      gint       clip_x, clip_y;
+      gint       clip_width, clip_height;
 
       *new_offset_x = orig_x;
       *new_offset_y = orig_y;
 
-      gimp_image_get_background (image, context, gimp_drawable_type (drawable),
-                                 bg_color);
-
       /*  "Outside" a channel is transparency, not the bg color  */
       if (GIMP_IS_CHANNEL (drawable))
-        bg_color[0] = TRANSPARENT_OPACITY;
+        gimp_rgba_set (&bg, 0.0, 0.0, 0.0, 0.0);
+      else
+        gimp_context_get_background (context, &bg);
+
+      color = gegl_color_new (NULL);
+      gimp_gegl_color_set_rgba (color, &bg);
 
-      pixel_region_init (&destPR, new_tiles,
-                         0, 0, new_width, new_height, TRUE);
-      color_region (&destPR, bg_color);
+      gegl_buffer_set_color (dest_buffer, NULL, color);
+      g_object_unref (color);
 
       if (gimp_rectangle_intersect (orig_x, orig_y, orig_width, orig_height,
                                     new_x, new_y, new_width, new_height,
@@ -255,33 +262,54 @@ gimp_drawable_transform_tiles_flip (GimpDrawable        *drawable,
     }
 
   if (new_width == 0 && new_height == 0)
-    return new_tiles;
+    {
+      g_object_unref (dest_buffer);
+      return new_tiles;
+    }
+
+  src_buffer = gimp_tile_manager_create_buffer (orig_tiles, orig_format, FALSE);
 
   switch (flip_type)
     {
     case GIMP_ORIENTATION_HORIZONTAL:
+      src_rect.x      = orig_x;
+      src_rect.y      = orig_y;
+      src_rect.width  = 1;
+      src_rect.height = orig_height;
+
+      dest_rect.x      = new_x + new_width - 1;
+      dest_rect.y      = new_y;
+      dest_rect.width  = 1;
+      dest_rect.height = new_height;
+
       for (i = 0; i < orig_width; i++)
         {
-          pixel_region_init (&srcPR, orig_tiles,
-                             i + orig_x, orig_y,
-                             1, orig_height, FALSE);
-          pixel_region_init (&destPR, new_tiles,
-                             new_x + new_width - i - 1, new_y,
-                             1, new_height, TRUE);
-          copy_region (&srcPR, &destPR);
+          src_rect.x  = i + orig_x;
+          dest_rect.x = new_x + new_width - i - 1;
+
+          gegl_buffer_copy (src_buffer, &src_rect,
+                            dest_buffer, &dest_rect);
         }
       break;
 
     case GIMP_ORIENTATION_VERTICAL:
+      src_rect.x      = orig_x;
+      src_rect.y      = orig_y;
+      src_rect.width  = orig_width;
+      src_rect.height = 1;
+
+      dest_rect.x      = new_x;
+      dest_rect.y      = new_y + new_height - 1;
+      dest_rect.width  = new_width;
+      dest_rect.height = 1;
+
       for (i = 0; i < orig_height; i++)
         {
-          pixel_region_init (&srcPR, orig_tiles,
-                             orig_x, i + orig_y,
-                             orig_width, 1, FALSE);
-          pixel_region_init (&destPR, new_tiles,
-                             new_x, new_y + new_height - i - 1,
-                             new_width, 1, TRUE);
-          copy_region (&srcPR, &destPR);
+          src_rect.y  = i + orig_y;
+          dest_rect.y = new_y + new_height - i - 1;
+
+          gegl_buffer_copy (src_buffer, &src_rect,
+                            dest_buffer, &dest_rect);
         }
       break;
 
@@ -289,6 +317,9 @@ gimp_drawable_transform_tiles_flip (GimpDrawable        *drawable,
       break;
     }
 
+  g_object_unref (src_buffer);
+  g_object_unref (dest_buffer);
+
   return new_tiles;
 }
 
@@ -330,6 +361,7 @@ TileManager *
 gimp_drawable_transform_tiles_rotate (GimpDrawable     *drawable,
                                       GimpContext      *context,
                                       TileManager      *orig_tiles,
+                                      const Babl       *orig_format,
                                       gint              orig_offset_x,
                                       gint              orig_offset_y,
                                       GimpRotationType  rotate_type,
@@ -339,24 +371,22 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable     *drawable,
                                       gint             *new_offset_x,
                                       gint             *new_offset_y)
 {
-  GimpImage   *image;
-  TileManager *new_tiles;
-  PixelRegion  srcPR, destPR;
-  guchar      *buf = NULL;
-  gint         orig_x, orig_y;
-  gint         orig_width, orig_height;
-  gint         orig_bpp;
-  gint         new_x, new_y;
-  gint         new_width, new_height;
-  gint         i, j, k;
+  TileManager   *new_tiles;
+  GeglBuffer    *src_buffer;
+  GeglBuffer    *dest_buffer;
+  GeglRectangle  src_rect;
+  GeglRectangle  dest_rect;
+  gint           orig_x, orig_y;
+  gint           orig_width, orig_height;
+  gint           orig_bpp;
+  gint           new_x, new_y;
+  gint           new_width, new_height;
 
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
   g_return_val_if_fail (orig_tiles != NULL, NULL);
 
-  image = gimp_item_get_image (GIMP_ITEM (drawable));
-
   orig_x      = orig_offset_x;
   orig_y      = orig_offset_y;
   orig_width  = tile_manager_width (orig_tiles);
@@ -401,25 +431,28 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable     *drawable,
                       new_width != orig_width || new_height != orig_height))
 
     {
-      guchar bg_color[MAX_CHANNELS];
-      gint   clip_x, clip_y;
-      gint   clip_width, clip_height;
+      GimpRGB    bg;
+      GeglColor *color;
+      gint       clip_x, clip_y;
+      gint       clip_width, clip_height;
 
       new_tiles = tile_manager_new (orig_width, orig_height, orig_bpp);
+      dest_buffer = gimp_tile_manager_create_buffer (new_tiles, orig_format, TRUE);
 
       *new_offset_x = orig_x;
       *new_offset_y = orig_y;
 
-      gimp_image_get_background (image, context, gimp_drawable_type (drawable),
-                                 bg_color);
-
       /*  "Outside" a channel is transparency, not the bg color  */
       if (GIMP_IS_CHANNEL (drawable))
-        bg_color[0] = TRANSPARENT_OPACITY;
+        gimp_rgba_set (&bg, 0.0, 0.0, 0.0, 0.0);
+      else
+        gimp_context_get_background (context, &bg);
 
-      pixel_region_init (&destPR, new_tiles,
-                         0, 0, orig_width, orig_height, TRUE);
-      color_region (&destPR, bg_color);
+      color = gegl_color_new (NULL);
+      gimp_gegl_color_set_rgba (color, &bg);
+
+      gegl_buffer_set_color (dest_buffer, NULL, color);
+      g_object_unref (color);
 
       if (gimp_rectangle_intersect (orig_x, orig_y, orig_width, orig_height,
                                     new_x, new_y, new_width, new_height,
@@ -482,6 +515,7 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable     *drawable,
   else
     {
       new_tiles = tile_manager_new (new_width, new_height, orig_bpp);
+      dest_buffer = gimp_tile_manager_create_buffer (new_tiles, orig_format, TRUE);
 
       *new_offset_x = new_x;
       *new_offset_y = new_y;
@@ -493,67 +527,126 @@ gimp_drawable_transform_tiles_rotate (GimpDrawable     *drawable,
     }
 
   if (new_width < 1 || new_height < 1)
-    return new_tiles;
+    {
+      g_object_unref (dest_buffer);
+      return new_tiles;
+    }
 
-  pixel_region_init (&srcPR, orig_tiles,
-                     orig_x, orig_y, orig_width, orig_height, FALSE);
-  pixel_region_init (&destPR, new_tiles,
-                     new_x, new_y, new_width, new_height, TRUE);
+  src_buffer = gimp_tile_manager_create_buffer (orig_tiles, orig_format, FALSE);
+
+  src_rect.x      = orig_x;
+  src_rect.y      = orig_y;
+  src_rect.width  = orig_width;
+  src_rect.height = orig_height;
+
+  dest_rect.x      = new_x;
+  dest_rect.y      = new_y;
+  dest_rect.width  = new_width;
+  dest_rect.height = new_height;
 
   switch (rotate_type)
     {
     case GIMP_ROTATE_90:
-      g_assert (new_height == orig_width);
-      buf = g_new (guchar, new_height * orig_bpp);
+      {
+        guchar *buf = g_new (guchar, new_height * orig_bpp);
+        gint    i;
 
-      for (i = 0; i < orig_height; i++)
-        {
-          pixel_region_get_row (&srcPR, orig_x, orig_y + orig_height - 1 - i,
-                                orig_width, buf, 1);
-          pixel_region_set_col (&destPR, new_x + i, new_y, new_height, buf);
-        }
+        g_assert (new_height == orig_width);
+
+        src_rect.y      = orig_y + orig_height - 1;
+        src_rect.height = 1;
+
+        dest_rect.x     = new_x;
+        dest_rect.width = 1;
+
+        for (i = 0; i < orig_height; i++)
+          {
+            src_rect.y  = orig_y + orig_height - 1 - i;
+            dest_rect.x = new_x + i;
+
+            gegl_buffer_get (src_buffer, 1.0, &src_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+            gegl_buffer_set (dest_buffer, &dest_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+          }
+
+        g_free (buf);
+      }
       break;
 
     case GIMP_ROTATE_180:
-      g_assert (new_width == orig_width);
-      buf = g_new (guchar, new_width * orig_bpp);
+      {
+        guchar *buf = g_new (guchar, new_width * orig_bpp);
+        gint    i, j, k;
 
-      for (i = 0; i < orig_height; i++)
-        {
-          pixel_region_get_row (&srcPR, orig_x, orig_y + orig_height - 1 - i,
-                                orig_width, buf, 1);
+        g_assert (new_width == orig_width);
 
-          for (j = 0; j < orig_width / 2; j++)
-            {
-              guchar *left  = buf + j * orig_bpp;
-              guchar *right = buf + (orig_width - 1 - j) * orig_bpp;
-
-              for (k = 0; k < orig_bpp; k++)
-                {
-                  guchar tmp = left[k];
-                  left[k]    = right[k];
-                  right[k]   = tmp;
-                }
-            }
+        src_rect.y      = orig_y + orig_height - 1;
+        src_rect.height = 1;
 
-          pixel_region_set_row (&destPR, new_x, new_y + i, new_width, buf);
-        }
+        dest_rect.y      = new_y;
+        dest_rect.height = 1;
+
+        for (i = 0; i < orig_height; i++)
+          {
+            src_rect.y  = orig_y + orig_height - 1 - i;
+            dest_rect.y = new_y + i;
+
+            gegl_buffer_get (src_buffer, 1.0, &src_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+
+            for (j = 0; j < orig_width / 2; j++)
+              {
+                guchar *left  = buf + j * orig_bpp;
+                guchar *right = buf + (orig_width - 1 - j) * orig_bpp;
+
+                for (k = 0; k < orig_bpp; k++)
+                  {
+                    guchar tmp = left[k];
+                    left[k]    = right[k];
+                    right[k]   = tmp;
+                  }
+              }
+
+            gegl_buffer_set (dest_buffer, &dest_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+          }
+
+        g_free (buf);
+      }
       break;
 
     case GIMP_ROTATE_270:
-      g_assert (new_width == orig_height);
-      buf = g_new (guchar, new_width * orig_bpp);
+      {
+        guchar *buf = g_new (guchar, new_width * orig_bpp);
+        gint    i;
 
-      for (i = 0; i < orig_width; i++)
-        {
-          pixel_region_get_col (&srcPR, orig_x + orig_width - 1 - i, orig_y,
-                                orig_height, buf, 1);
-          pixel_region_set_row (&destPR, new_x, new_y + i, new_width, buf);
-        }
+        g_assert (new_width == orig_height);
+
+        src_rect.x     = orig_x + orig_width - 1;
+        src_rect.width = 1;
+
+        dest_rect.y      = new_y;
+        dest_rect.height = 1;
+
+        for (i = 0; i < orig_width; i++)
+          {
+            src_rect.x  = orig_x + orig_width - 1 - i;
+            dest_rect.y = new_y + i;
+
+            gegl_buffer_get (src_buffer, 1.0, &src_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+            gegl_buffer_set (dest_buffer, &dest_rect, NULL, buf,
+                             GEGL_AUTO_ROWSTRIDE);
+          }
+
+        g_free (buf);
+      }
       break;
     }
 
-  g_free (buf);
+  g_object_unref (src_buffer);
+  g_object_unref (dest_buffer);
 
   return new_tiles;
 }
@@ -570,6 +663,7 @@ gimp_drawable_transform_affine (GimpDrawable           *drawable,
 {
   GimpImage    *image;
   TileManager  *orig_tiles;
+  const Babl   *orig_format;
   gint          orig_offset_x;
   gint          orig_offset_y;
   gboolean      new_layer;
@@ -590,6 +684,7 @@ gimp_drawable_transform_affine (GimpDrawable           *drawable,
 
   /* Cut/Copy from the specified drawable */
   orig_tiles = gimp_drawable_transform_cut (drawable, context,
+                                            &orig_format,
                                             &orig_offset_x, &orig_offset_y,
                                             &new_layer);
 
@@ -622,6 +717,7 @@ gimp_drawable_transform_affine (GimpDrawable           *drawable,
       /* transform the buffer */
       new_tiles = gimp_drawable_transform_tiles_affine (drawable, context,
                                                         orig_tiles,
+                                                        orig_format,
                                                         orig_offset_x,
                                                         orig_offset_y,
                                                         matrix,
@@ -639,6 +735,7 @@ gimp_drawable_transform_affine (GimpDrawable           *drawable,
       if (new_tiles)
         {
           result = gimp_drawable_transform_paste (drawable, new_tiles,
+                                                  orig_format,
                                                   new_offset_x, new_offset_y,
                                                   new_layer);
           tile_manager_unref (new_tiles);
@@ -660,6 +757,7 @@ gimp_drawable_transform_flip (GimpDrawable        *drawable,
 {
   GimpImage    *image;
   TileManager  *orig_tiles;
+  const Babl   *orig_format;
   gint          orig_offset_x;
   gint          orig_offset_y;
   gboolean      new_layer;
@@ -678,6 +776,7 @@ gimp_drawable_transform_flip (GimpDrawable        *drawable,
 
   /* Cut/Copy from the specified drawable */
   orig_tiles = gimp_drawable_transform_cut (drawable, context,
+                                            &orig_format,
                                             &orig_offset_x, &orig_offset_y,
                                             &new_layer);
 
@@ -709,6 +808,7 @@ gimp_drawable_transform_flip (GimpDrawable        *drawable,
         {
           new_tiles = gimp_drawable_transform_tiles_flip (drawable, context,
                                                           orig_tiles,
+                                                          orig_format,
                                                           orig_offset_x,
                                                           orig_offset_y,
                                                           flip_type, axis,
@@ -723,6 +823,7 @@ gimp_drawable_transform_flip (GimpDrawable        *drawable,
       if (new_tiles)
         {
           result = gimp_drawable_transform_paste (drawable, new_tiles,
+                                                  orig_format,
                                                   new_offset_x, new_offset_y,
                                                   new_layer);
           tile_manager_unref (new_tiles);
@@ -745,6 +846,7 @@ gimp_drawable_transform_rotate (GimpDrawable     *drawable,
 {
   GimpImage    *image;
   TileManager  *orig_tiles;
+  const Babl   *orig_format;
   gint          orig_offset_x;
   gint          orig_offset_y;
   gboolean      new_layer;
@@ -763,6 +865,7 @@ gimp_drawable_transform_rotate (GimpDrawable     *drawable,
 
   /* Cut/Copy from the specified drawable */
   orig_tiles = gimp_drawable_transform_cut (drawable, context,
+                                            &orig_format,
                                             &orig_offset_x, &orig_offset_y,
                                             &new_layer);
 
@@ -793,6 +896,7 @@ gimp_drawable_transform_rotate (GimpDrawable     *drawable,
       /* transform the buffer */
       new_tiles = gimp_drawable_transform_tiles_rotate (drawable, context,
                                                         orig_tiles,
+                                                        orig_format,
                                                         orig_offset_x,
                                                         orig_offset_y,
                                                         rotate_type,
@@ -807,6 +911,7 @@ gimp_drawable_transform_rotate (GimpDrawable     *drawable,
       if (new_tiles)
         {
           result = gimp_drawable_transform_paste (drawable, new_tiles,
+                                                  orig_format,
                                                   new_offset_x, new_offset_y,
                                                   new_layer);
           tile_manager_unref (new_tiles);
@@ -822,6 +927,7 @@ gimp_drawable_transform_rotate (GimpDrawable     *drawable,
 TileManager *
 gimp_drawable_transform_cut (GimpDrawable *drawable,
                              GimpContext  *context,
+                             const Babl  **format,
                              gint         *offset_x,
                              gint         *offset_y,
                              gboolean     *new_layer)
@@ -832,6 +938,7 @@ gimp_drawable_transform_cut (GimpDrawable *drawable,
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+  g_return_val_if_fail (format != NULL, NULL);
   g_return_val_if_fail (offset_x != NULL, NULL);
   g_return_val_if_fail (offset_y != NULL, NULL);
   g_return_val_if_fail (new_layer != NULL, NULL);
@@ -853,6 +960,7 @@ gimp_drawable_transform_cut (GimpDrawable *drawable,
                                           GIMP_PICKABLE (drawable),
                                           context,
                                           TRUE, FALSE, TRUE,
+                                          format,
                                           offset_x, offset_y,
                                           NULL);
           /*  clear the selection  */
@@ -863,6 +971,7 @@ gimp_drawable_transform_cut (GimpDrawable *drawable,
       else
         {
           tiles = NULL;
+          *format = NULL;
           *new_layer = FALSE;
         }
     }
@@ -872,6 +981,7 @@ gimp_drawable_transform_cut (GimpDrawable *drawable,
                                       GIMP_PICKABLE (drawable),
                                       context,
                                       FALSE, TRUE, GIMP_IS_LAYER (drawable),
+                                      format,
                                       offset_x, offset_y,
                                       NULL);
 
@@ -884,6 +994,7 @@ gimp_drawable_transform_cut (GimpDrawable *drawable,
 GimpDrawable *
 gimp_drawable_transform_paste (GimpDrawable *drawable,
                                TileManager  *tiles,
+                               const Babl   *format,
                                gint          offset_x,
                                gint          offset_y,
                                gboolean      new_layer)
@@ -895,6 +1006,7 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
   g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
   g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
   g_return_val_if_fail (tiles != NULL, NULL);
+  g_return_val_if_fail (format != NULL, NULL);
 
   image = gimp_item_get_image (GIMP_ITEM (drawable));
 
@@ -910,7 +1022,7 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
   if (new_layer)
     {
       layer =
-        gimp_layer_new_from_tiles (tiles, image,
+        gimp_layer_new_from_tiles (tiles, format, image,
                                    gimp_drawable_type_with_alpha (drawable),
                                    _("Transformation"),
                                    GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE);
@@ -925,8 +1037,7 @@ gimp_drawable_transform_paste (GimpDrawable *drawable,
     {
       GimpImageType drawable_type;
 
-      if (GIMP_IS_LAYER (drawable) && (tile_manager_bpp (tiles) == 2 ||
-                                       tile_manager_bpp (tiles) == 4))
+      if (GIMP_IS_LAYER (drawable) && babl_format_has_alpha (format))
         {
           drawable_type = gimp_drawable_type_with_alpha (drawable);
         }
diff --git a/app/core/gimpdrawable-transform.h b/app/core/gimpdrawable-transform.h
index 4f35138..000c63c 100644
--- a/app/core/gimpdrawable-transform.h
+++ b/app/core/gimpdrawable-transform.h
@@ -22,6 +22,7 @@
 TileManager  * gimp_drawable_transform_tiles_affine (GimpDrawable           *drawable,
                                                      GimpContext            *context,
                                                      TileManager            *orig_tiles,
+                                                     const Babl             *orig_format,
                                                      gint                    orig_offset_x,
                                                      gint                    orig_offset_y,
                                                      const GimpMatrix3      *matrix,
@@ -35,6 +36,7 @@ TileManager  * gimp_drawable_transform_tiles_affine (GimpDrawable           *dra
 TileManager  * gimp_drawable_transform_tiles_flip   (GimpDrawable           *drawable,
                                                      GimpContext            *context,
                                                      TileManager            *orig_tiles,
+                                                     const Babl             *orig_format,
                                                      gint                    orig_offset_x,
                                                      gint                    orig_offset_y,
                                                      GimpOrientationType     flip_type,
@@ -46,6 +48,7 @@ TileManager  * gimp_drawable_transform_tiles_flip   (GimpDrawable           *dra
 TileManager  * gimp_drawable_transform_tiles_rotate (GimpDrawable           *drawable,
                                                      GimpContext            *context,
                                                      TileManager            *orig_tiles,
+                                                     const Babl             *orig_format,
                                                      gint                    orig_offset_x,
                                                      gint                    orig_offset_y,
                                                      GimpRotationType        rotate_type,
@@ -79,11 +82,13 @@ GimpDrawable * gimp_drawable_transform_rotate       (GimpDrawable           *dra
 
 TileManager  * gimp_drawable_transform_cut          (GimpDrawable           *drawable,
                                                      GimpContext            *context,
+                                                     const Babl            **format,
                                                      gint                   *offset_x,
                                                      gint                   *offset_y,
                                                      gboolean               *new_layer);
 GimpDrawable * gimp_drawable_transform_paste        (GimpDrawable           *drawable,
                                                      TileManager            *tiles,
+                                                     const Babl             *format,
                                                      gint                    offset_x,
                                                      gint                    offset_y,
                                                      gboolean                new_layer);
diff --git a/app/core/gimpdrawable.c b/app/core/gimpdrawable.c
index cffe5c4..640554d 100644
--- a/app/core/gimpdrawable.c
+++ b/app/core/gimpdrawable.c
@@ -651,6 +651,7 @@ gimp_drawable_flip (GimpItem            *item,
 
   tiles = gimp_drawable_transform_tiles_flip (drawable, context,
                                               gimp_drawable_get_tiles (drawable),
+                                              gimp_drawable_get_format (drawable),
                                               off_x, off_y,
                                               flip_type, axis,
                                               clip_result,
@@ -659,6 +660,7 @@ gimp_drawable_flip (GimpItem            *item,
   if (tiles)
     {
       gimp_drawable_transform_paste (drawable, tiles,
+                                     gimp_drawable_get_format (drawable),
                                      new_off_x, new_off_y, FALSE);
       tile_manager_unref (tiles);
     }
@@ -681,6 +683,7 @@ gimp_drawable_rotate (GimpItem         *item,
 
   tiles = gimp_drawable_transform_tiles_rotate (drawable, context,
                                                 gimp_drawable_get_tiles (drawable),
+                                                gimp_drawable_get_format (drawable),
                                                 off_x, off_y,
                                                 rotate_type, center_x, center_y,
                                                 clip_result,
@@ -689,6 +692,7 @@ gimp_drawable_rotate (GimpItem         *item,
   if (tiles)
     {
       gimp_drawable_transform_paste (drawable, tiles,
+                                     gimp_drawable_get_format (drawable),
                                      new_off_x, new_off_y, FALSE);
       tile_manager_unref (tiles);
     }
@@ -713,6 +717,7 @@ gimp_drawable_transform (GimpItem               *item,
 
   tiles = gimp_drawable_transform_tiles_affine (drawable, context,
                                                 gimp_drawable_get_tiles (drawable),
+                                                gimp_drawable_get_format (drawable),
                                                 off_x, off_y,
                                                 matrix, direction,
                                                 interpolation_type,
@@ -724,6 +729,7 @@ gimp_drawable_transform (GimpItem               *item,
   if (tiles)
     {
       gimp_drawable_transform_paste (drawable, tiles,
+                                     gimp_drawable_get_format (drawable),
                                      new_off_x, new_off_y, FALSE);
       tile_manager_unref (tiles);
     }
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 42f60dc..478b052 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -1138,6 +1138,7 @@ gimp_layer_new_from_buffer (GeglBuffer           *buffer,
 /**
  * gimp_layer_new_from_tiles:
  * @tiles:      The buffer to make the new layer from.
+ * @format:     The tiles' pixel format
  * @dest_image: The image the new layer will be added to.
  * @type:       The #GimpImageType of the new layer.
  * @name:       The new layer's name.
@@ -1152,6 +1153,7 @@ gimp_layer_new_from_buffer (GeglBuffer           *buffer,
  **/
 GimpLayer *
 gimp_layer_new_from_tiles (TileManager          *tiles,
+                           const Babl           *format,
                            GimpImage            *dest_image,
                            GimpImageType         type,
                            const gchar          *name,
@@ -1162,9 +1164,10 @@ gimp_layer_new_from_tiles (TileManager          *tiles,
   GimpLayer  *layer;
 
   g_return_val_if_fail (tiles != NULL, NULL);
+  g_return_val_if_fail (format != NULL, NULL);
   g_return_val_if_fail (GIMP_IS_IMAGE (dest_image), NULL);
 
-  buffer = gimp_tile_manager_create_buffer (tiles, NULL, FALSE);
+  buffer = gimp_tile_manager_create_buffer (tiles, format, FALSE);
 
   layer = gimp_layer_new_from_buffer (buffer, dest_image, type,
                                       name, opacity, mode);
diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h
index cf14eb0..3903a36 100644
--- a/app/core/gimplayer.h
+++ b/app/core/gimplayer.h
@@ -90,6 +90,7 @@ GimpLayer     * gimp_layer_new_from_buffer     (GeglBuffer           *buffer,
                                                 gdouble               opacity,
                                                 GimpLayerModeEffects  mode);
 GimpLayer     * gimp_layer_new_from_tiles      (TileManager          *tiles,
+                                                const Babl           *format,
                                                 GimpImage            *dest_image,
                                                 GimpImageType         type,
                                                 const gchar          *name,
diff --git a/app/core/gimpselection.c b/app/core/gimpselection.c
index e70fcbf..4cd4ad2 100644
--- a/app/core/gimpselection.c
+++ b/app/core/gimpselection.c
@@ -620,6 +620,7 @@ gimp_selection_extract (GimpSelection *selection,
                         gboolean       cut_image,
                         gboolean       keep_indexed,
                         gboolean       add_alpha,
+                        const Babl   **format,
                         gint          *offset_x,
                         gint          *offset_y,
                         GError       **error)
@@ -640,6 +641,7 @@ gimp_selection_extract (GimpSelection *selection,
   if (GIMP_IS_ITEM (pickable))
     g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (pickable)), NULL);
   g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
+  g_return_val_if_fail (format != NULL, NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
   image = gimp_pickable_get_image (pickable);
@@ -675,25 +677,41 @@ gimp_selection_extract (GimpSelection *selection,
   switch (GIMP_IMAGE_TYPE_BASE_TYPE (gimp_pickable_get_image_type (pickable)))
     {
     case GIMP_RGB:
-      bytes = add_alpha ? 4 : gimp_pickable_get_bytes (pickable);
+      if (add_alpha)
+        *format = gimp_pickable_get_format_with_alpha (pickable);
+      else
+        *format = gimp_pickable_get_format (pickable);
+
       base_type = GIMP_RGB;
       break;
 
     case GIMP_GRAY:
-      bytes = add_alpha ? 2 : gimp_pickable_get_bytes (pickable);
+      if (add_alpha)
+        *format = gimp_pickable_get_format_with_alpha (pickable);
+      else
+        *format = gimp_pickable_get_format (pickable);
+
       base_type = GIMP_GRAY;
       break;
 
     case GIMP_INDEXED:
       if (keep_indexed)
         {
-          bytes = add_alpha ? 2 : gimp_pickable_get_bytes (pickable);
+          if (add_alpha)
+            *format = gimp_pickable_get_format_with_alpha (pickable);
+          else
+            *format = gimp_pickable_get_format (pickable);
+
           base_type = GIMP_GRAY;
         }
       else
         {
-          bytes = (add_alpha ||
-                   GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_pickable_get_image_type (pickable))) ? 4 : 3;
+          if (add_alpha ||
+              GIMP_IMAGE_TYPE_HAS_ALPHA (gimp_pickable_get_image_type (pickable)))
+            *format = babl_format ("RGBA u8");
+          else
+            *format = babl_format ("RGB u8");
+
           base_type = GIMP_INDEXED;
         }
       break;
@@ -703,6 +721,8 @@ gimp_selection_extract (GimpSelection *selection,
       break;
     }
 
+  bytes = babl_format_get_bytes_per_pixel (*format);
+
   gimp_image_get_background (image, context,
                              gimp_pickable_get_image_type (pickable),
                              bg_color);
@@ -821,6 +841,7 @@ gimp_selection_float (GimpSelection *selection,
   GimpImage   *image;
   GimpLayer   *layer;
   TileManager *tiles;
+  const Babl  *format;
   gint         x1, y1;
   gint         x2, y2;
 
@@ -848,7 +869,8 @@ gimp_selection_float (GimpSelection *selection,
 
   /*  Cut or copy the selected region  */
   tiles = gimp_selection_extract (selection, GIMP_PICKABLE (drawable), context,
-                                  cut_image, FALSE, TRUE, &x1, &y1, NULL);
+                                  cut_image, FALSE, TRUE,
+                                  &format, &x1, &y1, NULL);
 
   /*  Clear the selection  */
   gimp_channel_clear (GIMP_CHANNEL (selection), NULL, TRUE);
@@ -857,7 +879,7 @@ gimp_selection_float (GimpSelection *selection,
    *  because it may be different from the image's type if we cut from
    *  a channel or layer mask
    */
-  layer = gimp_layer_new_from_tiles (tiles,
+  layer = gimp_layer_new_from_tiles (tiles, format,
                                      image,
                                      gimp_drawable_type_with_alpha (drawable),
                                      _("Floated Layer"),
diff --git a/app/core/gimpselection.h b/app/core/gimpselection.h
index e1cf29c..5315e0f 100644
--- a/app/core/gimpselection.h
+++ b/app/core/gimpselection.h
@@ -64,6 +64,7 @@ TileManager * gimp_selection_extract       (GimpSelection *selection,
                                             gboolean       cut_image,
                                             gboolean       keep_indexed,
                                             gboolean       add_alpha,
+                                            const Babl   **format,
                                             gint          *offset_x,
                                             gint          *offset_y,
                                             GError       **error);
diff --git a/app/tools/gimpfliptool.c b/app/tools/gimpfliptool.c
index edb102d..3b75d91 100644
--- a/app/tools/gimpfliptool.c
+++ b/app/tools/gimpfliptool.c
@@ -61,6 +61,7 @@ static gchar       * gimp_flip_tool_get_undo_desc (GimpTransformTool *tool);
 static TileManager * gimp_flip_tool_transform     (GimpTransformTool *tool,
                                                    GimpItem          *item,
                                                    TileManager       *orig_tiles,
+                                                   const Babl        *orig_format,
                                                    gint               orig_offset_x,
                                                    gint               orig_offset_y,
                                                    gint              *new_offset_x,
@@ -201,6 +202,7 @@ static TileManager *
 gimp_flip_tool_transform (GimpTransformTool *trans_tool,
                           GimpItem          *active_item,
                           TileManager       *orig_tiles,
+                          const Babl        *orig_format,
                           gint               orig_offset_x,
                           gint               orig_offset_y,
                           gint              *new_offset_x,
@@ -240,6 +242,7 @@ gimp_flip_tool_transform (GimpTransformTool *trans_tool,
       ret = gimp_drawable_transform_tiles_flip (GIMP_DRAWABLE (active_item),
                                                 context,
                                                 orig_tiles,
+                                                orig_format,
                                                 orig_offset_x,
                                                 orig_offset_y,
                                                 options->flip_type, axis,
diff --git a/app/tools/gimppaintoptions-gui.c b/app/tools/gimppaintoptions-gui.c
index 9b3929f..ae29100 100644
--- a/app/tools/gimppaintoptions-gui.c
+++ b/app/tools/gimppaintoptions-gui.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "libgimpwidgets/gimpwidgets.h"
diff --git a/app/tools/gimpsheartool.c b/app/tools/gimpsheartool.c
index 084a89f..1eae0e3 100644
--- a/app/tools/gimpsheartool.c
+++ b/app/tools/gimpsheartool.c
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "libgimpmath/gimpmath.h"
diff --git a/app/tools/gimptransformoptions.c b/app/tools/gimptransformoptions.c
index b4e310e..6e47e93 100644
--- a/app/tools/gimptransformoptions.c
+++ b/app/tools/gimptransformoptions.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "libgimpconfig/gimpconfig.h"
diff --git a/app/tools/gimptransformtool.c b/app/tools/gimptransformtool.c
index 497b80a..4c72eaa 100644
--- a/app/tools/gimptransformtool.c
+++ b/app/tools/gimptransformtool.c
@@ -126,6 +126,7 @@ static TileManager *
                  gimp_transform_tool_real_transform         (GimpTransformTool     *tr_tool,
                                                              GimpItem              *item,
                                                              TileManager           *orig_tiles,
+                                                             const Babl            *orig_format,
                                                              gint                   orig_offset_x,
                                                              gint                   orig_offset_y,
                                                              gint                  *new_offset_x,
@@ -963,6 +964,7 @@ static TileManager *
 gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
                                     GimpItem          *active_item,
                                     TileManager       *orig_tiles,
+                                    const Babl        *orig_format,
                                     gint               orig_offset_x,
                                     gint               orig_offset_y,
                                     gint              *new_offset_x,
@@ -1003,6 +1005,7 @@ gimp_transform_tool_real_transform (GimpTransformTool *tr_tool,
       ret = gimp_drawable_transform_tiles_affine (GIMP_DRAWABLE (active_item),
                                                   context,
                                                   orig_tiles,
+                                                  orig_format,
                                                   orig_offset_x,
                                                   orig_offset_y,
                                                   &tr_tool->transform,
@@ -1048,6 +1051,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
   GimpImage            *image          = gimp_display_get_image (display);
   GimpItem             *active_item    = NULL;
   TileManager          *orig_tiles     = NULL;
+  const Babl           *orig_format    = NULL;
   gint                  orig_offset_x;
   gint                  orig_offset_y;
   TileManager          *new_tiles;
@@ -1117,6 +1121,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
         {
           orig_tiles = gimp_drawable_transform_cut (tool->drawable,
                                                     context,
+                                                    &orig_format,
                                                     &orig_offset_x,
                                                     &orig_offset_y,
                                                     &new_layer);
@@ -1138,6 +1143,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
   new_tiles = GIMP_TRANSFORM_TOOL_GET_CLASS (tr_tool)->transform (tr_tool,
                                                                   active_item,
                                                                   orig_tiles,
+                                                                  orig_format,
                                                                   orig_offset_x,
                                                                   orig_offset_y,
                                                                   &new_offset_x,
@@ -1155,7 +1161,7 @@ gimp_transform_tool_transform (GimpTransformTool *tr_tool,
            *  undo...
            */
           gimp_drawable_transform_paste (tool->drawable,
-                                         new_tiles,
+                                         new_tiles, orig_format,
                                          new_offset_x, new_offset_y,
                                          new_layer);
           tile_manager_unref (new_tiles);
diff --git a/app/tools/gimptransformtool.h b/app/tools/gimptransformtool.h
index 290d576..eba86e5 100644
--- a/app/tools/gimptransformtool.h
+++ b/app/tools/gimptransformtool.h
@@ -108,6 +108,7 @@ struct _GimpTransformToolClass
   TileManager * (* transform)     (GimpTransformTool *tool,
                                    GimpItem          *item,
                                    TileManager       *orig_tiles,
+                                   const Babl        *orig_format,
                                    gint               orig_offset_x,
                                    gint               orig_offset_y,
                                    gint              *new_offset_x,
diff --git a/app/tools/gimptransformtoolundo.c b/app/tools/gimptransformtoolundo.c
index 726a61a..7140d91 100644
--- a/app/tools/gimptransformtoolundo.c
+++ b/app/tools/gimptransformtoolundo.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <gegl.h>
 #include <gtk/gtk.h>
 
 #include "tools-types.h"



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