[gimp/goat-invasion: 575/608] app/libgimp: enable plug-ins on high precision images



commit 4c1540fa3bf4f0ccd2725966d4d446c9b67d4ac1
Author: Michael Natterer <mitch gimp org>
Date:   Tue Apr 24 21:45:35 2012 +0200

    app/libgimp: enable plug-ins on high precision images
    
    Add gimp_plugin_enable_precision() in libgimp which switches the
    plug-in to deal with the drawables' real precision, call it from the
    libgimp GeglBuffer and Babl format APIs. If it's not enabled, let the
    core's plug-in convert the tiles to legacy formats when sending them
    over the wire.

 app/pdb/drawable-cmds.c          |   75 +++++++++++++++++++++++++++++-
 app/pdb/internal-procs.c         |    2 +-
 app/pdb/plug-in-cmds.c           |   96 ++++++++++++++++++++++++++++++++++++++
 app/plug-in/gimpplugin-message.c |   19 +++++++-
 app/plug-in/gimpplugin.c         |   16 ++++++
 app/plug-in/gimpplugin.h         |    4 ++
 libgimp/gimp.def                 |    2 +
 libgimp/gimp.h                   |    1 -
 libgimp/gimpdrawable.c           |   58 +++++++++++++----------
 libgimp/gimpdrawable_pdb.c       |   37 ++++++++++++++-
 libgimp/gimpdrawable_pdb.h       |    1 +
 libgimp/gimpplugin_pdb.c         |   64 +++++++++++++++++++++++++
 libgimp/gimpplugin_pdb.h         |    2 +
 tools/pdbgen/pdb/drawable.pdb    |   46 ++++++++++++++++--
 tools/pdbgen/pdb/plug_in.pdb     |   70 +++++++++++++++++++++++++++-
 15 files changed, 454 insertions(+), 39 deletions(-)
---
diff --git a/app/pdb/drawable-cmds.c b/app/pdb/drawable-cmds.c
index 035f518..cf7ce71 100644
--- a/app/pdb/drawable-cmds.c
+++ b/app/pdb/drawable-cmds.c
@@ -33,6 +33,7 @@
 #include "core/gimpimage.h"
 #include "core/gimpparamspecs.h"
 #include "core/gimptempbuf.h"
+#include "gegl/gimp-babl.h"
 #include "gegl/gimp-gegl-utils.h"
 #include "plug-in/gimpplugin-cleanup.h"
 #include "plug-in/gimpplugin.h"
@@ -47,6 +48,35 @@
 
 
 static GValueArray *
+drawable_get_format_invoker (GimpProcedure      *procedure,
+                             Gimp               *gimp,
+                             GimpContext        *context,
+                             GimpProgress       *progress,
+                             const GValueArray  *args,
+                             GError            **error)
+{
+  gboolean success = TRUE;
+  GValueArray *return_vals;
+  GimpDrawable *drawable;
+  gchar *format = NULL;
+
+  drawable = gimp_value_get_drawable (&args->values[0], gimp);
+
+  if (success)
+    {
+      format = g_strdup (babl_get_name (gimp_drawable_get_format (drawable)));
+    }
+
+  return_vals = gimp_procedure_get_return_values (procedure, success,
+                                                  error ? *error : NULL);
+
+  if (success)
+    g_value_take_string (&return_vals->values[1], format);
+
+  return return_vals;
+}
+
+static GValueArray *
 drawable_type_invoker (GimpProcedure      *procedure,
                        Gimp               *gimp,
                        GimpContext        *context,
@@ -239,7 +269,18 @@ drawable_bpp_invoker (GimpProcedure      *procedure,
 
   if (success)
     {
-      bpp = gimp_drawable_bytes (drawable);
+      const Babl *format = gimp_drawable_get_format (drawable);
+
+      if (! gimp->plug_in_manager->current_plug_in ||
+          ! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
+        {
+          if (! gimp_drawable_is_indexed (drawable) /* XXX fixme */)
+            format = gimp_babl_format (gimp_babl_format_get_base_type (format),
+                                       GIMP_PRECISION_U8,
+                                       babl_format_has_alpha (format));
+        }
+
+      bpp = babl_format_get_bytes_per_pixel (format);
     }
 
   return_vals = gimp_procedure_get_return_values (procedure, success,
@@ -889,6 +930,36 @@ register_drawable_procs (GimpPDB *pdb)
   GimpProcedure *procedure;
 
   /*
+   * gimp-drawable-get-format
+   */
+  procedure = gimp_procedure_new (drawable_get_format_invoker);
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "gimp-drawable-get-format");
+  gimp_procedure_set_static_strings (procedure,
+                                     "gimp-drawable-get-format",
+                                     "Returns the drawable's Babl format",
+                                     "This procedure returns the drawable's Babl format.",
+                                     "Michael Natterer <mitch gimp org>",
+                                     "Michael Natterer",
+                                     "2012",
+                                     NULL);
+  gimp_procedure_add_argument (procedure,
+                               gimp_param_spec_drawable_id ("drawable",
+                                                            "drawable",
+                                                            "The drawable",
+                                                            pdb->gimp, FALSE,
+                                                            GIMP_PARAM_READWRITE));
+  gimp_procedure_add_return_value (procedure,
+                                   gimp_param_spec_string ("format",
+                                                           "format",
+                                                           "The drawable's Babl format",
+                                                           FALSE, FALSE, FALSE,
+                                                           NULL,
+                                                           GIMP_PARAM_READWRITE));
+  gimp_pdb_register_procedure (pdb, procedure);
+  g_object_unref (procedure);
+
+  /*
    * gimp-drawable-type
    */
   procedure = gimp_procedure_new (drawable_type_invoker);
@@ -1079,7 +1150,7 @@ register_drawable_procs (GimpPDB *pdb)
   gimp_procedure_set_static_strings (procedure,
                                      "gimp-drawable-bpp",
                                      "Returns the bytes per pixel.",
-                                     "This procedure returns the number of bytes per pixel (or the number of channels) for the specified drawable.",
+                                     "This procedure returns the number of bytes per pixel, which corresponds to the number of components unless 'gimp-plugin-enable-precision' was called.",
                                      "Spencer Kimball & Peter Mattis",
                                      "Spencer Kimball & Peter Mattis",
                                      "1995-1996",
diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c
index a257b9c..069cc9c 100644
--- a/app/pdb/internal-procs.c
+++ b/app/pdb/internal-procs.c
@@ -28,7 +28,7 @@
 #include "internal-procs.h"
 
 
-/* 667 procedures registered total */
+/* 670 procedures registered total */
 
 void
 internal_procs_init (GimpPDB *pdb)
diff --git a/app/pdb/plug-in-cmds.c b/app/pdb/plug-in-cmds.c
index cab7722..c69408c 100644
--- a/app/pdb/plug-in-cmds.c
+++ b/app/pdb/plug-in-cmds.c
@@ -340,6 +340,62 @@ plugin_get_pdb_error_handler_invoker (GimpProcedure      *procedure,
   return return_vals;
 }
 
+static GValueArray *
+plugin_enable_precision_invoker (GimpProcedure      *procedure,
+                                 Gimp               *gimp,
+                                 GimpContext        *context,
+                                 GimpProgress       *progress,
+                                 const GValueArray  *args,
+                                 GError            **error)
+{
+  gboolean success = TRUE;
+  GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+  if (plug_in)
+    {
+      gimp_plug_in_enable_precision (plug_in);
+    }
+  else
+    {
+      success = FALSE;
+    }
+
+  return gimp_procedure_get_return_values (procedure, success,
+                                           error ? *error : NULL);
+}
+
+static GValueArray *
+plugin_precision_enabled_invoker (GimpProcedure      *procedure,
+                                  Gimp               *gimp,
+                                  GimpContext        *context,
+                                  GimpProgress       *progress,
+                                  const GValueArray  *args,
+                                  GError            **error)
+{
+  gboolean success = TRUE;
+  GValueArray *return_vals;
+  gboolean enabled = FALSE;
+
+  GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+  if (plug_in)
+    {
+      enabled = gimp_plug_in_precision_enabled (plug_in);
+    }
+  else
+    {
+      success = FALSE;
+    }
+
+  return_vals = gimp_procedure_get_return_values (procedure, success,
+                                                  error ? *error : NULL);
+
+  if (success)
+    g_value_set_boolean (&return_vals->values[1], enabled);
+
+  return return_vals;
+}
+
 void
 register_plug_in_procs (GimpPDB *pdb)
 {
@@ -648,4 +704,44 @@ register_plug_in_procs (GimpPDB *pdb)
                                                       GIMP_PARAM_READWRITE));
   gimp_pdb_register_procedure (pdb, procedure);
   g_object_unref (procedure);
+
+  /*
+   * gimp-plugin-enable-precision
+   */
+  procedure = gimp_procedure_new (plugin_enable_precision_invoker);
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "gimp-plugin-enable-precision");
+  gimp_procedure_set_static_strings (procedure,
+                                     "gimp-plugin-enable-precision",
+                                     "Switches this plug-in to using the real bit depth of drawables.",
+                                     "Switches this plug-in to using the real bit depth of drawables. This setting can only be enabled, and not disabled again during the lifetime of the plug-in. Using 'gimp-drawable-get-buffer', 'gimp-drawable-get-shadow-buffer' or 'gimp-drawable-get-format' will automatically call this function.",
+                                     "Michael Natterer <mitch gimp org>",
+                                     "Michael Natterer",
+                                     "2012",
+                                     NULL);
+  gimp_pdb_register_procedure (pdb, procedure);
+  g_object_unref (procedure);
+
+  /*
+   * gimp-plugin-precision-enabled
+   */
+  procedure = gimp_procedure_new (plugin_precision_enabled_invoker);
+  gimp_object_set_static_name (GIMP_OBJECT (procedure),
+                               "gimp-plugin-precision-enabled");
+  gimp_procedure_set_static_strings (procedure,
+                                     "gimp-plugin-precision-enabled",
+                                     "Whether this plug-in is using the real bit depth of drawables.",
+                                     "Returns whether this plug-in is using the real bit depth of drawables, which can be more than 8 bits per channel.",
+                                     "Michael Natterer <mitch gimp org>",
+                                     "Michael Natterer",
+                                     "2012",
+                                     NULL);
+  gimp_procedure_add_return_value (procedure,
+                                   g_param_spec_boolean ("enabled",
+                                                         "enabled",
+                                                         "Whether precision is enabled",
+                                                         FALSE,
+                                                         GIMP_PARAM_READWRITE));
+  gimp_pdb_register_procedure (pdb, procedure);
+  g_object_unref (procedure);
 }
diff --git a/app/plug-in/gimpplugin-message.c b/app/plug-in/gimpplugin-message.c
index 766d409..1c28d71 100644
--- a/app/plug-in/gimpplugin-message.c
+++ b/app/plug-in/gimpplugin-message.c
@@ -29,6 +29,7 @@
 
 #include "plug-in-types.h"
 
+#include "gegl/gimp-babl.h"
 #include "gegl/gimp-gegl-tile-compat.h"
 
 #include "core/gimp.h"
@@ -310,9 +311,16 @@ gimp_plug_in_handle_tile_put (GimpPlugIn *plug_in,
       return;
     }
 
-  /* XXX use an appropriate format here */
   format = gegl_buffer_get_format (buffer);
 
+  if (! gimp_plug_in_precision_enabled (plug_in) &&
+      ! gimp_drawable_is_indexed (drawable) /* XXX fixme */)
+    {
+      format = gimp_babl_format (gimp_babl_format_get_base_type (format),
+                                 GIMP_PRECISION_U8,
+                                 babl_format_has_alpha (format));
+    }
+
   if (tile_data.use_shm)
     {
       gegl_buffer_set (buffer, &tile_rect, 0, format,
@@ -402,9 +410,16 @@ gimp_plug_in_handle_tile_get (GimpPlugIn *plug_in,
       return;
     }
 
-  /* XXX use an appropriate format here */
   format = gegl_buffer_get_format (buffer);
 
+  if (! gimp_plug_in_precision_enabled (plug_in) &&
+      ! gimp_drawable_is_indexed (drawable) /* XXX fixme */)
+    {
+      format = gimp_babl_format (gimp_babl_format_get_base_type (format),
+                                 GIMP_PRECISION_U8,
+                                 babl_format_has_alpha (format));
+    }
+
   tile_size = (babl_format_get_bytes_per_pixel (format) *
                tile_rect.width * tile_rect.height);
 
diff --git a/app/plug-in/gimpplugin.c b/app/plug-in/gimpplugin.c
index 8de7c49..b474584 100644
--- a/app/plug-in/gimpplugin.c
+++ b/app/plug-in/gimpplugin.c
@@ -1032,3 +1032,19 @@ gimp_plug_in_remove_temp_proc (GimpPlugIn             *plug_in,
   gimp_plug_in_manager_remove_temp_proc (plug_in->manager, proc);
   g_object_unref (proc);
 }
+
+void
+gimp_plug_in_enable_precision (GimpPlugIn *plug_in)
+{
+  g_return_if_fail (GIMP_IS_PLUG_IN (plug_in));
+
+  plug_in->precision = TRUE;
+}
+
+gboolean
+gimp_plug_in_precision_enabled (GimpPlugIn *plug_in)
+{
+  g_return_val_if_fail (GIMP_IS_PLUG_IN (plug_in), FALSE);
+
+  return plug_in->precision;
+}
diff --git a/app/plug-in/gimpplugin.h b/app/plug-in/gimpplugin.h
index 94ec4aa..519e045 100644
--- a/app/plug-in/gimpplugin.h
+++ b/app/plug-in/gimpplugin.h
@@ -47,6 +47,7 @@ struct _GimpPlugIn
   GimpPlugInCallMode   call_mode;       /*  QUERY, INIT or RUN                */
   guint                open : 1;        /*  Is the plug-in open?              */
   guint                hup : 1;         /*  Did we receive a G_IO_HUP         */
+  guint                precision : 1;   /*  True drawable precision enabled   */
   GPid                 pid;             /*  Plug-in's process id              */
 
   GIOChannel          *my_read;         /*  App's read and write channels     */
@@ -119,5 +120,8 @@ void          gimp_plug_in_set_error_handler (GimpPlugIn             *plug_in,
 GimpPDBErrorHandler
               gimp_plug_in_get_error_handler (GimpPlugIn             *plug_in);
 
+void          gimp_plug_in_enable_precision  (GimpPlugIn             *plug_in);
+gboolean      gimp_plug_in_precision_enabled (GimpPlugIn             *plug_in);
+
 
 #endif /* __GIMP_PLUG_IN_H__ */
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index efc0244..f6c9fbf 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -667,11 +667,13 @@ EXPORTS
 	gimp_pixel_rgns_register
 	gimp_pixel_rgns_register2
 	gimp_plugin_domain_register
+	gimp_plugin_enable_precision
 	gimp_plugin_get_pdb_error_handler
 	gimp_plugin_help_register
 	gimp_plugin_icon_register
 	gimp_plugin_menu_branch_register
 	gimp_plugin_menu_register
+	gimp_plugin_precision_enabled
 	gimp_plugin_set_pdb_error_handler
 	gimp_posterize
 	gimp_procedural_db_dump
diff --git a/libgimp/gimp.h b/libgimp/gimp.h
index f6ae86a..5d7bafd 100644
--- a/libgimp/gimp.h
+++ b/libgimp/gimp.h
@@ -315,7 +315,6 @@ void           gimp_destroy_paramdefs   (GimpParamDef    *paramdefs,
  */
 const gchar  * gimp_get_pdb_error       (void);
 
-
 /* Return various constants given by the GIMP core at plug-in config time.
  */
 guint          gimp_tile_width          (void) G_GNUC_CONST;
diff --git a/libgimp/gimpdrawable.c b/libgimp/gimpdrawable.c
index e6c7965..9da4c24 100644
--- a/libgimp/gimpdrawable.c
+++ b/libgimp/gimpdrawable.c
@@ -668,6 +668,8 @@ gimp_drawable_get_buffer (gint32 drawable_ID)
 {
   GimpDrawable *drawable;
 
+  gimp_plugin_enable_precision ();
+
   drawable = gimp_drawable_get (drawable_ID);
 
   if (drawable)
@@ -705,6 +707,8 @@ gimp_drawable_get_shadow_buffer (gint32 drawable_ID)
 {
   GimpDrawable *drawable;
 
+  gimp_plugin_enable_precision ();
+
   drawable = gimp_drawable_get (drawable_ID);
 
   if (drawable)
@@ -735,38 +739,42 @@ gimp_drawable_get_shadow_buffer (gint32 drawable_ID)
 const Babl *
 gimp_drawable_get_format (gint32 drawable_ID)
 {
-  switch (gimp_drawable_type (drawable_ID))
+  const Babl *format     = NULL;
+  gchar      *format_str = _gimp_drawable_get_format (drawable_ID);
+
+  if (format_str)
     {
-    case GIMP_RGB_IMAGE:   return babl_format ("R'G'B' u8");
-    case GIMP_RGBA_IMAGE:  return babl_format ("R'G'B'A u8");
-    case GIMP_GRAY_IMAGE:  return babl_format ("Y' u8");
-    case GIMP_GRAYA_IMAGE: return babl_format ("Y'A u8");
-    case GIMP_INDEXED_IMAGE:
-    case GIMP_INDEXEDA_IMAGE:
-      {
-        gint32      image_ID = gimp_item_get_image (drawable_ID);
-        const Babl *pala;
-        const Babl *pal;
-        guchar     *cmap;
-        gint        n_cols;
+      gimp_plugin_enable_precision ();
 
-        cmap = gimp_image_get_colormap (image_ID, &n_cols);
+      if (gimp_drawable_is_indexed (drawable_ID))
+        {
+          gint32      image_ID = gimp_item_get_image (drawable_ID);
+          const Babl *palette;
+          const Babl *palette_alpha;
+          guchar     *colormap;
+          gint        n_colors;
 
-        babl_new_palette (NULL, &pal, &pala);
-        babl_palette_set_palette (pal, babl_format ("R'G'B' u8"),
-                                  cmap, n_cols);
+          colormap = gimp_image_get_colormap (image_ID, &n_colors);
 
-        g_free (cmap);
+          babl_new_palette (format_str, &palette, &palette_alpha);
+          babl_palette_set_palette (palette,
+                                    babl_format ("R'G'B' u8"),
+                                    colormap, n_colors);
 
-        if (gimp_drawable_type (drawable_ID) == GIMP_INDEXEDA_IMAGE)
-          return pala;
+          g_free (colormap);
 
-        return pal;
-      }
+          if (gimp_drawable_has_alpha (drawable_ID))
+            format = palette;
+          else
+            format = palette_alpha;
+        }
+      else
+        {
+          format = babl_format (format_str);
+        }
 
-    default:
-      g_warn_if_reached ();
+      g_free (format_str);
     }
 
-  return NULL;
+  return format;
 }
diff --git a/libgimp/gimpdrawable_pdb.c b/libgimp/gimpdrawable_pdb.c
index 134bb71..8337837 100644
--- a/libgimp/gimpdrawable_pdb.c
+++ b/libgimp/gimpdrawable_pdb.c
@@ -40,6 +40,38 @@
 
 
 /**
+ * _gimp_drawable_get_format:
+ * @drawable_ID: The drawable.
+ *
+ * Returns the drawable's Babl format
+ *
+ * This procedure returns the drawable's Babl format.
+ *
+ * Returns: The drawable's Babl format.
+ *
+ * Since: GIMP 2.10
+ **/
+gchar *
+_gimp_drawable_get_format (gint32 drawable_ID)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gchar *format = NULL;
+
+  return_vals = gimp_run_procedure ("gimp-drawable-get-format",
+                                    &nreturn_vals,
+                                    GIMP_PDB_DRAWABLE, drawable_ID,
+                                    GIMP_PDB_END);
+
+  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
+    format = g_strdup (return_vals[1].data.d_string);
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return format;
+}
+
+/**
  * gimp_drawable_type:
  * @drawable_ID: The drawable.
  *
@@ -233,8 +265,9 @@ gimp_drawable_is_indexed (gint32 drawable_ID)
  *
  * Returns the bytes per pixel.
  *
- * This procedure returns the number of bytes per pixel (or the number
- * of channels) for the specified drawable.
+ * This procedure returns the number of bytes per pixel, which
+ * corresponds to the number of components unless
+ * gimp_plugin_enable_precision() was called.
  *
  * Returns: Bytes per pixel.
  **/
diff --git a/libgimp/gimpdrawable_pdb.h b/libgimp/gimpdrawable_pdb.h
index a0bfb5a..6ad3054 100644
--- a/libgimp/gimpdrawable_pdb.h
+++ b/libgimp/gimpdrawable_pdb.h
@@ -32,6 +32,7 @@ G_BEGIN_DECLS
 /* For information look into the C source or the html documentation */
 
 
+G_GNUC_INTERNAL gchar*   _gimp_drawable_get_format        (gint32                      drawable_ID);
 GimpImageType            gimp_drawable_type               (gint32                      drawable_ID);
 GimpImageType            gimp_drawable_type_with_alpha    (gint32                      drawable_ID);
 gboolean                 gimp_drawable_has_alpha          (gint32                      drawable_ID);
diff --git a/libgimp/gimpplugin_pdb.c b/libgimp/gimpplugin_pdb.c
index 86fc690..1708f31 100644
--- a/libgimp/gimpplugin_pdb.c
+++ b/libgimp/gimpplugin_pdb.c
@@ -291,3 +291,67 @@ gimp_plugin_get_pdb_error_handler (void)
 
   return handler;
 }
+
+/**
+ * gimp_plugin_enable_precision:
+ *
+ * Switches this plug-in to using the real bit depth of drawables.
+ *
+ * Switches this plug-in to using the real bit depth of drawables. This
+ * setting can only be enabled, and not disabled again during the
+ * lifetime of the plug-in. Using gimp_drawable_get_buffer(),
+ * gimp_drawable_get_shadow_buffer() or gimp_drawable_get_format() will
+ * automatically call this function.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: GIMP 2.10
+ **/
+gboolean
+gimp_plugin_enable_precision (void)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gboolean success = TRUE;
+
+  return_vals = gimp_run_procedure ("gimp-plugin-enable-precision",
+                                    &nreturn_vals,
+                                    GIMP_PDB_END);
+
+  success = return_vals[0].data.d_status == GIMP_PDB_SUCCESS;
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return success;
+}
+
+/**
+ * gimp_plugin_precision_enabled:
+ *
+ * Whether this plug-in is using the real bit depth of drawables.
+ *
+ * Returns whether this plug-in is using the real bit depth of
+ * drawables, which can be more than 8 bits per channel.
+ *
+ * Returns: Whether precision is enabled.
+ *
+ * Since: GIMP 2.10
+ **/
+gboolean
+gimp_plugin_precision_enabled (void)
+{
+  GimpParam *return_vals;
+  gint nreturn_vals;
+  gboolean enabled = FALSE;
+
+  return_vals = gimp_run_procedure ("gimp-plugin-precision-enabled",
+                                    &nreturn_vals,
+                                    GIMP_PDB_END);
+
+  if (return_vals[0].data.d_status == GIMP_PDB_SUCCESS)
+    enabled = return_vals[1].data.d_int32;
+
+  gimp_destroy_params (return_vals, nreturn_vals);
+
+  return enabled;
+}
diff --git a/libgimp/gimpplugin_pdb.h b/libgimp/gimpplugin_pdb.h
index 2f15099..5bd54df 100644
--- a/libgimp/gimpplugin_pdb.h
+++ b/libgimp/gimpplugin_pdb.h
@@ -46,6 +46,8 @@ G_GNUC_INTERNAL gboolean _gimp_plugin_icon_register        (const gchar
                                                             const guint8        *icon_data);
 gboolean                 gimp_plugin_set_pdb_error_handler (GimpPDBErrorHandler  handler);
 GimpPDBErrorHandler      gimp_plugin_get_pdb_error_handler (void);
+gboolean                 gimp_plugin_enable_precision      (void);
+gboolean                 gimp_plugin_precision_enabled     (void);
 
 
 G_END_DECLS
diff --git a/tools/pdbgen/pdb/drawable.pdb b/tools/pdbgen/pdb/drawable.pdb
index 14eeb08..d5feba9 100644
--- a/tools/pdbgen/pdb/drawable.pdb
+++ b/tools/pdbgen/pdb/drawable.pdb
@@ -264,6 +264,31 @@ CODE
     );
 }
 
+sub drawable_get_format {
+    $blurb = "Returns the drawable's Babl format";
+    $help  = "This procedure returns the drawable's Babl format.";
+
+    &mitch_pdb_misc('2012', '2.10');
+
+    @inargs = (
+	{ name => 'drawable', type => 'drawable',
+	  desc => 'The drawable' }
+    );
+
+    @outargs = (
+	{ name => 'format', type => 'string', wrap => 1,
+	  desc => "The drawable's Babl format" }
+    );
+
+    %invoke = (
+	code => <<'CODE'
+{
+  format = g_strdup (babl_get_name (gimp_drawable_get_format (drawable)));
+}
+CODE
+    );
+}
+
 sub drawable_type {
     $blurb = "Returns the drawable's type.";
     $help  = "This procedure returns the drawable's type.";
@@ -446,8 +471,8 @@ sub drawable_bpp {
     $blurb = 'Returns the bytes per pixel.';
 
     $help = <<'HELP';
-This procedure returns the number of bytes per pixel (or the number of
-channels) for the specified drawable.
+This procedure returns the number of bytes per pixel, which corresponds to
+the number of components unless gimp_plugin_enable_precision() was called.
 HELP
 
     &std_pdb_misc;
@@ -465,7 +490,18 @@ HELP
     %invoke = (
 	code => <<'CODE'
 {
-  bpp = gimp_drawable_bytes (drawable);
+  const Babl *format = gimp_drawable_get_format (drawable);
+
+  if (! gimp->plug_in_manager->current_plug_in ||
+      ! gimp_plug_in_precision_enabled (gimp->plug_in_manager->current_plug_in))
+    {
+      if (! gimp_drawable_is_indexed (drawable) /* XXX fixme */)
+        format = gimp_babl_format (gimp_babl_format_get_base_type (format),
+                                   GIMP_PRECISION_U8,
+                                   babl_format_has_alpha (format));
+    }
+
+  bpp = babl_format_get_bytes_per_pixel (format);
 }
 CODE
     );
@@ -907,6 +943,7 @@ CODE
 
 
 @headers = qw("config/gimpcoreconfig.h"
+              "gegl/gimp-babl.h"
               "gegl/gimp-gegl-utils.h"
               "core/gimp.h"
               "core/gimpdrawable-offset.h"
@@ -914,7 +951,8 @@ CODE
               "gimppdb-utils.h"
               "gimp-intl.h");
 
- procs = qw(drawable_type
+ procs = qw(drawable_get_format
+            drawable_type
             drawable_type_with_alpha
             drawable_has_alpha
             drawable_is_rgb
diff --git a/tools/pdbgen/pdb/plug_in.pdb b/tools/pdbgen/pdb/plug_in.pdb
index a172de7..b6dac0f 100644
--- a/tools/pdbgen/pdb/plug_in.pdb
+++ b/tools/pdbgen/pdb/plug_in.pdb
@@ -353,6 +353,70 @@ CODE
     );
 }
 
+sub plugin_enable_precision {
+    $blurb = "Switches this plug-in to using the real bit depth of drawables.";
+
+    $help = <<HELP;
+Switches this plug-in to using the real bit depth of drawables. This
+setting can only be enabled, and not disabled again during the
+lifetime of the plug-in. Using gimp_drawable_get_buffer(),
+gimp_drawable_get_shadow_buffer() or gimp_drawable_get_format() will
+automatically call this function.
+HELP
+
+    &mitch_pdb_misc('2012', '2.10');
+
+    %invoke = (
+        code => <<'CODE'
+{
+  GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+  if (plug_in)
+    {
+      gimp_plug_in_enable_precision (plug_in);
+    }
+  else
+    {
+      success = FALSE;
+    }
+}
+CODE
+    );
+}
+
+sub plugin_precision_enabled {
+    $blurb = "Whether this plug-in is using the real bit depth of drawables.";
+
+    $help = <<HELP;
+Returns whether this plug-in is using the real bit depth of drawables,
+which can be more than 8 bits per channel.
+HELP
+
+    &mitch_pdb_misc('2012', '2.10');
+
+    @outargs = (
+	{ name => 'enabled', type => 'boolean',
+	  desc => "Whether precision is enabled" }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  GimpPlugIn *plug_in = gimp->plug_in_manager->current_plug_in;
+
+  if (plug_in)
+    {
+      enabled = gimp_plug_in_precision_enabled (plug_in);
+    }
+  else
+    {
+      success = FALSE;
+    }
+}
+CODE
+    );
+}
+
 @headers = qw(<string.h>
               <stdlib.h>
               "libgimpbase/gimpbase.h"
@@ -371,9 +435,11 @@ CODE
             plugin_menu_branch_register
             plugin_icon_register
             plugin_set_pdb_error_handler
-            plugin_get_pdb_error_handler);
+            plugin_get_pdb_error_handler
+            plugin_enable_precision
+            plugin_precision_enabled);
 
-%exports = (app => [ procs], lib => [ procs[1,2,3,4,5,6,7]]);
+%exports = (app => [ procs], lib => [ procs[1,2,3,4,5,6,7,8,9]]);
 
 $desc = 'Plug-in';
 $doc_title = 'gimpplugin';



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