[gimp/alxsa-image-simulation-intent-bpc] core: Add simulation intent and BPC to GimpImage




commit 4445718cb089c8053bc893a61ba3bda236f03901
Author: Alx Sa <cmyk student gmail com>
Date:   Wed Aug 10 15:01:15 2022 +0000

    core: Add simulation intent and BPC to GimpImage
    
    Adds a simulation_bpc and simulation_intent to GimpImage to allow
    plug-ins to access it
    for CMYK import/export.
    Four pdb functions were added to enable this access:
    image_get_simulation_bpc (), image_set_simulation_bpc (),
    image_get_simulation_intent (), and image_set_simulation_intent ().
    Next, it updates menu options and code to support GimpImage's
    internal simulation intent and bpc.
    New 'simulation-intent-changed' and 'simulation-bpc-changed signal
    are emitted via
    GimpColorManagedInterface so that relevant tools
    (such as the
    CYMK color picker, GimpColorFrame, and future pop-overs)
     are aware of these changes.

 app/actions/image-actions.c             |  41 ++++-----
 app/actions/image-commands.c            |  30 +++----
 app/core/gimpimage-color-profile.c      |  51 +++++++++++
 app/core/gimpimage-color-profile.h      |   9 ++
 app/core/gimpimage-private.h            |   6 +-
 app/core/gimpimage.c                    |  48 ++++++++++
 app/display/gimpdisplayshell-handlers.c |  36 +++++++-
 app/display/gimpdisplayshell-profile.c  |  24 ++---
 app/display/gimpdisplayshell.c          |  27 +++++-
 app/pdb/internal-procs.c                |   2 +-
 app/widgets/gimpfgbgeditor.c            |   3 +-
 app/widgets/gimpfgbgview.c              |   3 +-
 app/widgets/gimpviewrenderer.c          |  22 +++--
 libgimp/gimp.def                        |   4 +
 libgimp/gimpimagecolorprofile.c         |  77 ++++++++++++++++
 libgimp/gimpimagecolorprofile.h         |   9 ++
 libgimp/gimpimagecolorprofile_pdb.c     | 152 ++++++++++++++++++++++++++++++++
 libgimp/gimpimagecolorprofile_pdb.h     |  56 ++++++------
 libgimpcolor/gimpcolor.def              |   4 +
 libgimpcolor/gimpcolormanaged.c         | 105 ++++++++++++++++++++++
 libgimpcolor/gimpcolormanaged.h         |  43 ++++++---
 libgimpwidgets/gimpcolorarea.c          |   4 +-
 libgimpwidgets/gimpcolorscale.c         |   3 +-
 libgimpwidgets/gimpcolorselect.c        |   3 +-
 libgimpwidgets/gimppreviewarea.c        |   3 +-
 libgimpwidgets/gimpwidgetsutils.c       |  21 +++--
 libgimpwidgets/gimpwidgetsutils.h       |   4 +-
 modules/color-selector-water.c          |   3 +-
 modules/gimpcolorwheel.c                |   3 +-
 pdb/groups/image_color_profile.pdb      | 134 ++++++++++++++++++++++++++--
 30 files changed, 805 insertions(+), 125 deletions(-)
---
diff --git a/app/actions/image-actions.c b/app/actions/image-actions.c
index 7ef19056e9..6afdae8fc8 100644
--- a/app/actions/image-actions.c
+++ b/app/actions/image-actions.c
@@ -410,9 +410,6 @@ image_actions_update (GimpActionGroup *group,
                       gpointer         data)
 {
   GimpImage        *image          = action_data_get_image (data);
-  GimpDisplay      *display        = action_data_get_display (data);
-  GimpDisplayShell *shell          = NULL;
-  GimpColorConfig  *color_config   = NULL;
   gboolean          is_indexed     = FALSE;
   gboolean          is_u8_gamma    = FALSE;
   gboolean          is_double      = FALSE;
@@ -504,34 +501,28 @@ image_actions_update (GimpActionGroup *group,
       profile_srgb = gimp_image_get_use_srgb_profile (image, &profile_hidden);
       profile      = (gimp_image_get_color_profile (image) != NULL);
 
-      if (display)
+      switch (gimp_image_get_simulation_intent (image))
         {
-          shell        = gimp_display_get_shell (display);
-          color_config = gimp_display_shell_get_color_config (shell);
-
-          switch (gimp_color_config_get_simulation_intent (color_config))
-            {
-            case GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL:
-              action = "image-softproof-intent-perceptual";
-              break;
+        case GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL:
+          action = "image-softproof-intent-perceptual";
+          break;
 
-            case GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC:
-              action = "image-softproof-intent-relative-colorimetric";
-              break;
+        case GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC:
+          action = "image-softproof-intent-relative-colorimetric";
+          break;
 
-            case GIMP_COLOR_RENDERING_INTENT_SATURATION:
-              action = "image-softproof-intent-saturation";
-              break;
+        case GIMP_COLOR_RENDERING_INTENT_SATURATION:
+          action = "image-softproof-intent-saturation";
+          break;
 
-            case GIMP_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
-              action = "image-softproof-intent-absolute-colorimetric";
-              break;
-            }
+        case GIMP_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
+          action = "image-softproof-intent-absolute-colorimetric";
+          break;
+        }
 
-          gimp_action_group_set_action_active (group, action, TRUE);
+      gimp_action_group_set_action_active (group, action, TRUE);
 
-          s_bpc  = gimp_color_config_get_simulation_bpc (color_config);
-        }
+      s_bpc  = gimp_image_get_simulation_bpc (image);
     }
   else
     {
diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c
index 7857c2f3a1..b48b1ad76a 100644
--- a/app/actions/image-commands.c
+++ b/app/actions/image-commands.c
@@ -1635,21 +1635,19 @@ image_softproof_intent_cmd_callback (GimpAction *action,
                                      GVariant   *value,
                                      gpointer    data)
 {
+  GimpImage                 *image;
   GimpDisplayShell          *shell;
-  GimpColorConfig           *color_config;
   GimpColorRenderingIntent   intent;
+  return_if_no_image (image, data);
   return_if_no_shell (shell, data);
 
   intent = (GimpColorRenderingIntent) g_variant_get_int32 (value);
 
-  color_config = gimp_display_shell_get_color_config (shell);
-
-  if (intent != gimp_color_config_get_simulation_intent (color_config))
+  if (intent != gimp_image_get_simulation_intent (image))
     {
-      g_object_set (color_config,
-                    "simulation-rendering-intent", intent,
-                    NULL);
+      gimp_image_set_simulation_intent (image, intent);
       shell->color_config_set = TRUE;
+      gimp_color_managed_simulation_intent_changed (GIMP_COLOR_MANAGED (shell));
     }
 }
 
@@ -1658,20 +1656,18 @@ image_softproof_bpc_cmd_callback (GimpAction *action,
                                   GVariant   *value,
                                   gpointer    data)
 {
-  GimpDisplayShell *shell;
-  GimpColorConfig  *color_config;
-  gboolean          active;
+  GimpImage                 *image;
+  GimpDisplayShell          *shell;
+  gboolean                   bpc;
+  return_if_no_image (image, data);
   return_if_no_shell (shell, data);
 
-  color_config = gimp_display_shell_get_color_config (shell);
+  bpc = g_variant_get_boolean (value);
 
-  active = g_variant_get_boolean (value);
-
-  if (active != gimp_color_config_get_simulation_bpc (color_config))
+  if (bpc != gimp_image_get_simulation_bpc (image))
     {
-      g_object_set (color_config,
-                    "simulation-use-black-point-compensation", active,
-                    NULL);
+      gimp_image_set_simulation_bpc (image, bpc);
       shell->color_config_set = TRUE;
+      gimp_color_managed_simulation_bpc_changed (GIMP_COLOR_MANAGED (shell));
     }
 }
diff --git a/app/core/gimpimage-color-profile.c b/app/core/gimpimage-color-profile.c
index bafa51d52c..9bd1f8f22f 100644
--- a/app/core/gimpimage-color-profile.c
+++ b/app/core/gimpimage-color-profile.c
@@ -456,6 +456,57 @@ gimp_image_set_simulation_profile (GimpImage         *image,
                                      NULL);
 }
 
+GimpColorRenderingIntent
+gimp_image_get_simulation_intent (GimpImage *image)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image),
+                        GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC);
+
+  return GIMP_IMAGE_GET_PRIVATE (image)->simulation_intent;
+}
+
+void
+gimp_image_set_simulation_intent (GimpImage               *image,
+                                  GimpColorRenderingIntent intent)
+{
+  GimpImagePrivate *private;
+
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+
+  private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (intent != private->simulation_intent)
+    {
+      private->simulation_intent = intent;
+      gimp_color_managed_simulation_intent_changed (GIMP_COLOR_MANAGED (image));
+    }
+}
+
+gboolean
+gimp_image_get_simulation_bpc (GimpImage *image)
+{
+  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
+
+  return GIMP_IMAGE_GET_PRIVATE (image)->simulation_bpc;
+}
+
+void
+gimp_image_set_simulation_bpc (GimpImage *image,
+                               gboolean   bpc)
+{
+  GimpImagePrivate *private;
+
+  g_return_if_fail (GIMP_IS_IMAGE (image));
+
+  private = GIMP_IMAGE_GET_PRIVATE (image);
+
+  if (bpc != private->simulation_bpc)
+    {
+      private->simulation_bpc = bpc;
+      gimp_color_managed_simulation_bpc_changed (GIMP_COLOR_MANAGED (image));
+    }
+}
+
 gboolean
 gimp_image_validate_color_profile_by_format (const Babl         *format,
                                              GimpColorProfile   *profile,
diff --git a/app/core/gimpimage-color-profile.h b/app/core/gimpimage-color-profile.h
index 4302045502..5fd415b598 100644
--- a/app/core/gimpimage-color-profile.h
+++ b/app/core/gimpimage-color-profile.h
@@ -73,6 +73,15 @@ GimpColorProfile   * gimp_image_get_simulation_profile (GimpImage           *ima
 gboolean             gimp_image_set_simulation_profile (GimpImage           *image,
                                                         GimpColorProfile    *profile);
 
+GimpColorRenderingIntent
+                     gimp_image_get_simulation_intent  (GimpImage           *image);
+void                 gimp_image_set_simulation_intent  (GimpImage                *image,
+                                                        GimpColorRenderingIntent intent);
+
+gboolean             gimp_image_get_simulation_bpc     (GimpImage           *image);
+void                 gimp_image_set_simulation_bpc     (GimpImage           *image,
+                                                        gboolean             bpc);
+
 gboolean             gimp_image_validate_color_profile_by_format
                                                        (const Babl          *format,
                                                         GimpColorProfile    *profile,
diff --git a/app/core/gimpimage-private.h b/app/core/gimpimage-private.h
index 2beda44946..f9ab5b0c32 100644
--- a/app/core/gimpimage-private.h
+++ b/app/core/gimpimage-private.h
@@ -63,7 +63,11 @@ struct _GimpImagePrivate
   GimpColorProfile  *color_profile;         /*  image's color profile        */
   const Babl        *layer_space;           /*  image's Babl layer space     */
   GimpColorProfile  *hidden_profile;        /*  hidden by "use sRGB"         */
-  GimpColorProfile  *simulation_profile;    /*  image's softproof profile    */
+
+  /* image's simulation/soft-proofing settings */
+  GimpColorProfile         *simulation_profile;
+  GimpColorRenderingIntent  simulation_intent;
+  gboolean                  simulation_bpc;
 
   /*  Cached color transforms: from layer to sRGB u8 and double, and back    */
   gboolean            color_transforms_created;
diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c
index 3adeb390f8..1599ff68c2 100644
--- a/app/core/gimpimage.c
+++ b/app/core/gimpimage.c
@@ -203,6 +203,16 @@ static GimpColorProfile *
 static void
       gimp_image_color_managed_simulation_profile_changed (GimpColorManaged  *managed);
 
+static GimpColorRenderingIntent
+      gimp_image_color_managed_get_simulation_intent      (GimpColorManaged  *managed);
+static void
+      gimp_image_color_managed_simulation_intent_changed  (GimpColorManaged  *managed);
+
+static gboolean
+      gimp_image_color_managed_get_simulation_bpc         (GimpColorManaged  *managed);
+static void
+      gimp_image_color_managed_simulation_bpc_changed     (GimpColorManaged  *managed);
+
 static void        gimp_image_projectable_flush  (GimpProjectable   *projectable,
                                                   gboolean           invalidate_preview);
 static GeglRectangle gimp_image_get_bounding_box (GimpProjectable   *projectable);
@@ -707,6 +717,10 @@ gimp_color_managed_iface_init (GimpColorManagedInterface *iface)
   iface->profile_changed            = gimp_image_color_managed_profile_changed;
   iface->get_simulation_profile     = gimp_image_color_managed_get_simulation_profile;
   iface->simulation_profile_changed = gimp_image_color_managed_simulation_profile_changed;
+  iface->get_simulation_intent      = gimp_image_color_managed_get_simulation_intent;
+  iface->simulation_intent_changed  = gimp_image_color_managed_simulation_intent_changed;
+  iface->get_simulation_bpc         = gimp_image_color_managed_get_simulation_bpc;
+  iface->simulation_bpc_changed     = gimp_image_color_managed_simulation_bpc_changed;
 }
 
 static void
@@ -1465,6 +1479,40 @@ gimp_image_color_managed_simulation_profile_changed (GimpColorManaged *managed)
   gimp_viewable_invalidate_preview (GIMP_VIEWABLE (image));
 }
 
+static GimpColorRenderingIntent
+gimp_image_color_managed_get_simulation_intent (GimpColorManaged *managed)
+{
+  GimpImage *image = GIMP_IMAGE (managed);
+
+  return gimp_image_get_simulation_intent (image);
+}
+
+static void
+gimp_image_color_managed_simulation_intent_changed (GimpColorManaged *managed)
+{
+  GimpImage *image = GIMP_IMAGE (managed);
+
+  gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
+  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (image));
+}
+
+static gboolean
+gimp_image_color_managed_get_simulation_bpc (GimpColorManaged *managed)
+{
+  GimpImage *image = GIMP_IMAGE (managed);
+
+  return gimp_image_get_simulation_bpc (image);
+}
+
+static void
+gimp_image_color_managed_simulation_bpc_changed (GimpColorManaged *managed)
+{
+  GimpImage *image = GIMP_IMAGE (managed);
+
+  gimp_projectable_structure_changed (GIMP_PROJECTABLE (image));
+  gimp_viewable_invalidate_preview (GIMP_VIEWABLE (image));
+}
+
 static void
 gimp_image_projectable_flush (GimpProjectable *projectable,
                               gboolean         invalidate_preview)
diff --git a/app/display/gimpdisplayshell-handlers.c b/app/display/gimpdisplayshell-handlers.c
index ad8f69b0e0..51c0d2c1db 100644
--- a/app/display/gimpdisplayshell-handlers.c
+++ b/app/display/gimpdisplayshell-handlers.c
@@ -132,6 +132,12 @@ static void   gimp_display_shell_profile_changed_handler    (GimpColorManaged *i
 static void   gimp_display_shell_simulation_profile_changed_handler
                                                             (GimpColorManaged *image,
                                                              GimpDisplayShell *shell);
+static void   gimp_display_shell_simulation_intent_changed_handler
+                                                            (GimpColorManaged *image,
+                                                             GimpDisplayShell *shell);
+static void   gimp_display_shell_simulation_bpc_changed_handler
+                                                            (GimpColorManaged *image,
+                                                             GimpDisplayShell *shell);
 static void   gimp_display_shell_saved_handler              (GimpImage        *image,
                                                              GFile            *file,
                                                              GimpDisplayShell *shell);
@@ -288,6 +294,12 @@ gimp_display_shell_connect (GimpDisplayShell *shell)
   g_signal_connect (image, "simulation-profile-changed",
                     G_CALLBACK (gimp_display_shell_simulation_profile_changed_handler),
                     shell);
+  g_signal_connect (image, "simulation-intent-changed",
+                    G_CALLBACK (gimp_display_shell_simulation_intent_changed_handler),
+                    shell);
+  g_signal_connect (image, "simulation-bpc-changed",
+                    G_CALLBACK (gimp_display_shell_simulation_bpc_changed_handler),
+                    shell);
   g_signal_connect (image, "saved",
                     G_CALLBACK (gimp_display_shell_saved_handler),
                     shell);
@@ -528,6 +540,12 @@ gimp_display_shell_disconnect (GimpDisplayShell *shell)
   g_signal_handlers_disconnect_by_func (image,
                                         gimp_display_shell_simulation_profile_changed_handler,
                                         shell);
+  g_signal_handlers_disconnect_by_func (image,
+                                        gimp_display_shell_simulation_intent_changed_handler,
+                                        shell);
+  g_signal_handlers_disconnect_by_func (image,
+                                        gimp_display_shell_simulation_bpc_changed_handler,
+                                        shell);
   g_signal_handlers_disconnect_by_func (image,
                                         gimp_display_shell_precision_changed_handler,
                                         shell);
@@ -940,6 +958,22 @@ gimp_display_shell_simulation_profile_changed_handler (GimpColorManaged *image,
   gimp_color_managed_simulation_profile_changed (GIMP_COLOR_MANAGED (shell));
 }
 
+static void
+gimp_display_shell_simulation_intent_changed_handler (GimpColorManaged *image,
+                                                      GimpDisplayShell *shell)
+{
+  gimp_display_shell_profile_update (shell);
+  gimp_color_managed_simulation_intent_changed (GIMP_COLOR_MANAGED (shell));
+}
+
+static void
+gimp_display_shell_simulation_bpc_changed_handler (GimpColorManaged *image,
+                                                   GimpDisplayShell *shell)
+{
+  gimp_display_shell_profile_update (shell);
+  gimp_color_managed_simulation_bpc_changed (GIMP_COLOR_MANAGED (shell));
+}
+
 static void
 gimp_display_shell_saved_handler (GimpImage        *image,
                                   GFile            *file,
@@ -1207,8 +1241,6 @@ gimp_display_shell_color_config_notify_handler (GObject          *config,
       if (! strcmp (param_spec->name, "mode")                                 ||
           ! strcmp (param_spec->name, "display-rendering-intent")             ||
           ! strcmp (param_spec->name, "display-use-black-point-compensation") ||
-          ! strcmp (param_spec->name, "simulation-rendering-intent")          ||
-          ! strcmp (param_spec->name, "simulation-use-black-point-compensation") ||
           ! strcmp (param_spec->name, "simulation-gamut-check"))
         {
           if (shell->color_config_set)
diff --git a/app/display/gimpdisplayshell-profile.c b/app/display/gimpdisplayshell-profile.c
index 2eb457bde3..3be4863925 100644
--- a/app/display/gimpdisplayshell-profile.c
+++ b/app/display/gimpdisplayshell-profile.c
@@ -83,13 +83,15 @@ gimp_display_shell_profile_finalize (GimpDisplayShell *shell)
 void
 gimp_display_shell_profile_update (GimpDisplayShell *shell)
 {
-  GimpImage        *image;
-  GimpColorProfile *src_profile;
-  const Babl       *src_format;
-  GimpColorProfile *filter_profile;
-  const Babl       *filter_format;
-  const Babl       *dest_format;
-  GimpColorProfile *proof_profile;
+  GimpImage               *image;
+  GimpColorProfile        *src_profile;
+  const Babl              *src_format;
+  GimpColorProfile        *filter_profile;
+  const Babl              *filter_format;
+  const Babl              *dest_format;
+  GimpColorProfile        *proof_profile;
+  GimpColorRenderingIntent simulation_intent = -1;
+  gboolean                 simulation_bpc    = FALSE;
 
   gimp_display_shell_profile_free (shell);
 
@@ -104,6 +106,8 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
     return;
 
   proof_profile = gimp_color_managed_get_simulation_profile (GIMP_COLOR_MANAGED (image));
+  simulation_intent = gimp_color_managed_get_simulation_intent (GIMP_COLOR_MANAGED (image));
+  simulation_bpc = gimp_color_managed_get_simulation_bpc (GIMP_COLOR_MANAGED (image));
 
   src_format = gimp_projectable_get_format (GIMP_PROJECTABLE (image));
 
@@ -158,7 +162,9 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell)
                                      filter_profile,
                                      filter_format,
                                      dest_format,
-                                     proof_profile);
+                                     proof_profile,
+                                     simulation_intent,
+                                     simulation_bpc);
 
   if (shell->filter_transform || shell->profile_transform)
     {
@@ -236,8 +242,6 @@ gimp_display_shell_color_config_notify (GimpColorConfig  *config,
   if (! strcmp (pspec->name, "mode")                                    ||
       ! strcmp (pspec->name, "display-rendering-intent")                ||
       ! strcmp (pspec->name, "display-use-black-point-compensation")    ||
-      ! strcmp (pspec->name, "simulation-rendering-intent")             ||
-      ! strcmp (pspec->name, "simulation-use-black-point-compensation") ||
       ! strcmp (pspec->name, "simulation-gamut-check"))
     {
       gboolean     managed   = FALSE;
diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c
index 1cd00c5c21..f475b204f2 100644
--- a/app/display/gimpdisplayshell.c
+++ b/app/display/gimpdisplayshell.c
@@ -164,7 +164,10 @@ static GimpColorProfile *
 static void      gimp_display_shell_profile_changed(GimpColorManaged *managed);
 static void    gimp_display_shell_simulation_profile_changed
                                                    (GimpColorManaged *managed);
-
+static void    gimp_display_shell_simulation_intent_changed
+                                                   (GimpColorManaged *managed);
+static void    gimp_display_shell_simulation_bpc_changed
+                                                   (GimpColorManaged *managed);
 static void      gimp_display_shell_zoom_button_callback
                                                    (GimpDisplayShell *shell,
                                                     GtkWidget        *zoom_button);
@@ -309,6 +312,8 @@ gimp_color_managed_iface_init (GimpColorManagedInterface *iface)
   iface->get_color_profile          = gimp_display_shell_get_color_profile;
   iface->profile_changed            = gimp_display_shell_profile_changed;
   iface->simulation_profile_changed = gimp_display_shell_simulation_profile_changed;
+  iface->simulation_intent_changed  = gimp_display_shell_simulation_intent_changed;
+  iface->simulation_bpc_changed     = gimp_display_shell_simulation_bpc_changed;
 }
 
 static void
@@ -1096,6 +1101,24 @@ gimp_display_shell_simulation_profile_changed (GimpColorManaged *managed)
   gimp_display_shell_render_invalidate_full (shell);
 }
 
+static void
+gimp_display_shell_simulation_intent_changed (GimpColorManaged *managed)
+{
+  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (managed);
+
+  gimp_display_shell_expose_full (shell);
+  gimp_display_shell_render_invalidate_full (shell);
+}
+
+static void
+gimp_display_shell_simulation_bpc_changed (GimpColorManaged *managed)
+{
+  GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (managed);
+
+  gimp_display_shell_expose_full (shell);
+  gimp_display_shell_render_invalidate_full (shell);
+}
+
 static void
 gimp_display_shell_zoom_button_callback (GimpDisplayShell *shell,
                                          GtkWidget        *zoom_button)
@@ -1369,6 +1392,8 @@ gimp_display_shell_reconnect (GimpDisplayShell *shell)
 
   gimp_color_managed_profile_changed (GIMP_COLOR_MANAGED (shell));
   gimp_display_shell_simulation_profile_changed (GIMP_COLOR_MANAGED (shell));
+  gimp_display_shell_simulation_intent_changed (GIMP_COLOR_MANAGED (shell));
+  gimp_display_shell_simulation_bpc_changed (GIMP_COLOR_MANAGED (shell));
 
   gimp_display_shell_scroll_clamp_and_update (shell);
 
diff --git a/app/pdb/internal-procs.c b/app/pdb/internal-procs.c
index 6e1de6ade6..0feff1e800 100644
--- a/app/pdb/internal-procs.c
+++ b/app/pdb/internal-procs.c
@@ -30,7 +30,7 @@
 #include "internal-procs.h"
 
 
-/* 758 procedures registered total */
+/* 75862 procedures registered total */
 
 void
 internal_procs_init (GimpPDB *pdb)
diff --git a/app/widgets/gimpfgbgeditor.c b/app/widgets/gimpfgbgeditor.c
index b0d51df77d..7b992d554e 100644
--- a/app/widgets/gimpfgbgeditor.c
+++ b/app/widgets/gimpfgbgeditor.c
@@ -795,7 +795,8 @@ gimp_fg_bg_editor_create_transform (GimpFgBgEditor *editor)
                                          profile,
                                          babl_format ("R'G'B'A double"),
                                          babl_format ("R'G'B'A double"),
-                                         NULL);
+                                         NULL,
+                                         -1, FALSE);
     }
 }
 
diff --git a/app/widgets/gimpfgbgview.c b/app/widgets/gimpfgbgview.c
index 7da1803dc6..a91393aac5 100644
--- a/app/widgets/gimpfgbgview.c
+++ b/app/widgets/gimpfgbgview.c
@@ -256,7 +256,8 @@ gimp_fg_bg_view_create_transform (GimpFgBgView *view)
                                          profile,
                                          babl_format ("R'G'B'A double"),
                                          babl_format ("R'G'B'A double"),
-                                         NULL);
+                                         NULL,
+                                         -1, FALSE);
     }
 }
 
diff --git a/app/widgets/gimpviewrenderer.c b/app/widgets/gimpviewrenderer.c
index 8edfe4d547..44de23f12d 100644
--- a/app/widgets/gimpviewrenderer.c
+++ b/app/widgets/gimpviewrenderer.c
@@ -1028,9 +1028,11 @@ gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
                                         const Babl       *src_format,
                                         const Babl       *dest_format)
 {
-  GimpColorProfile *profile;
-  GimpColorProfile *proof_profile = NULL;
-  GimpImage        *image;
+  GimpColorProfile         *profile;
+  GimpColorProfile         *proof_profile     = NULL;
+  GimpColorRenderingIntent  simulation_intent = -1;
+  gboolean                  simulation_bpc    = FALSE;
+  GimpImage                *image;
 
   g_return_val_if_fail (GIMP_IS_VIEW_RENDERER (renderer), NULL);
   g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
@@ -1066,8 +1068,14 @@ gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
     {
       image = gimp_context_get_image (GIMP_CONTEXT (renderer->context));
       if (image)
-        proof_profile =
-          gimp_color_managed_get_simulation_profile (GIMP_COLOR_MANAGED (image));
+        {
+          proof_profile =
+            gimp_color_managed_get_simulation_profile (GIMP_COLOR_MANAGED (image));
+          simulation_intent =
+            gimp_color_managed_get_simulation_intent (GIMP_COLOR_MANAGED (image));
+          simulation_bpc =
+            gimp_color_managed_get_simulation_bpc (GIMP_COLOR_MANAGED (image));
+        }
     }
 
   renderer->priv->profile_transform =
@@ -1076,7 +1084,9 @@ gimp_view_renderer_get_color_transform (GimpViewRenderer *renderer,
                                      profile,
                                      src_format,
                                      dest_format,
-                                     proof_profile);
+                                     proof_profile,
+                                     simulation_intent,
+                                     simulation_bpc);
 
   return renderer->priv->profile_transform;
 }
diff --git a/libgimp/gimp.def b/libgimp/gimp.def
index c51a56bfff..b7223f35a8 100644
--- a/libgimp/gimp.def
+++ b/libgimp/gimp.def
@@ -417,6 +417,8 @@ EXPORTS
        gimp_image_get_selected_drawables
        gimp_image_get_selected_layers
        gimp_image_get_selection
+       gimp_image_get_simulation_bpc
+       gimp_image_get_simulation_intent
        gimp_image_get_simulation_profile
        gimp_image_get_tattoo_state
        gimp_image_get_thumbnail
@@ -493,6 +495,8 @@ EXPORTS
        gimp_image_set_metadata
        gimp_image_set_resolution
        gimp_image_set_selected_layers
+       gimp_image_set_simulation_bpc
+       gimp_image_set_simulation_intent
        gimp_image_set_simulation_profile
        gimp_image_set_simulation_profile_from_file
        gimp_image_set_tattoo_state
diff --git a/libgimp/gimpimagecolorprofile.c b/libgimp/gimpimagecolorprofile.c
index 4c9f5b5140..d1c5e2070d 100644
--- a/libgimp/gimpimagecolorprofile.c
+++ b/libgimp/gimpimagecolorprofile.c
@@ -161,6 +161,83 @@ gimp_image_set_simulation_profile (GimpImage        *image,
   return _gimp_image_set_simulation_profile (image, length, data);
 }
 
+/**
+ * gimp_image_get_simulation_intent:
+ * @image: The image.
+ *
+ * Returns the image's simulation rendering intent
+ *
+ * This procedure returns the image's simulation rendering intent.
+ *
+ * Returns: (transfer full): The image's #GimpColorRenderingIntent.
+ *
+ * Since: 3.0
+ **/
+GimpColorRenderingIntent
+gimp_image_get_simulation_intent (GimpImage *image)
+{
+  return _gimp_image_get_simulation_intent (image);
+}
+
+/**
+ * gimp_image_set_simulation_intent:
+ * @image:  The image.
+ * @intent: A #GimpColorRenderingIntent
+ *
+ * Sets the image's simulation rendering intent
+ *
+ * This procedure sets the image's simulation rendering intent.
+ *
+ * Since: 3.0
+ **/
+void
+gimp_image_set_simulation_intent (GimpImage                *image,
+                                  GimpColorRenderingIntent intent)
+{
+  _gimp_image_set_simulation_intent (image, intent);
+}
+
+/**
+ * gimp_image_get_simulation_bpc:
+ * @image: The image.
+ *
+ * Returns whether the image has Black Point Compensation enabled
+ * for its simulation
+ *
+ * This procedure returns whether the image has
+ * Black Point Compensation enabled for its simulation
+ *
+ * Returns: (transfer full): A gboolean indicating whether the image
+ * has Black Point Compensation enabled for its simulation
+ *
+ * Since: 3.0
+ **/
+gboolean
+gimp_image_get_simulation_bpc (GimpImage *image)
+{
+  return _gimp_image_get_simulation_bpc (image);
+}
+
+/**
+ * gimp_image_set_simulation_bpc:
+ * @image: The image.
+ * @bpc:   A gboolean
+ *
+ * Sets whether the image has Black Point Compensation enabled
+ * for its simulation
+ *
+ * This procedure sets the image's Black Point Compensation enabled
+ * status
+ *
+ * Since: 3.0
+ **/
+void
+gimp_image_set_simulation_bpc (GimpImage *image,
+                               gboolean   bpc)
+{
+  _gimp_image_set_simulation_bpc (image, bpc);
+}
+
 /**
  * gimp_image_get_effective_color_profile:
  * @image: The image.
diff --git a/libgimp/gimpimagecolorprofile.h b/libgimp/gimpimagecolorprofile.h
index 92e4e60123..9c8d5265cb 100644
--- a/libgimp/gimpimagecolorprofile.h
+++ b/libgimp/gimpimagecolorprofile.h
@@ -38,6 +38,15 @@ GimpColorProfile * gimp_image_get_simulation_profile      (GimpImage
 gboolean           gimp_image_set_simulation_profile      (GimpImage                 *image,
                                                            GimpColorProfile          *profile);
 
+GimpColorRenderingIntent
+                   gimp_image_get_simulation_intent       (GimpImage                 *image);
+void               gimp_image_set_simulation_intent       (GimpImage                 *image,
+                                                           GimpColorRenderingIntent   intent);
+
+gboolean           gimp_image_get_simulation_bpc          (GimpImage                 *image);
+void               gimp_image_set_simulation_bpc          (GimpImage                 *image,
+                                                           gboolean                   bpc);
+
 GimpColorProfile * gimp_image_get_effective_color_profile (GimpImage                 *image);
 
 gboolean           gimp_image_convert_color_profile       (GimpImage                 *image,
diff --git a/libgimp/gimpimagecolorprofile_pdb.c b/libgimp/gimpimagecolorprofile_pdb.c
index 08504f6e01..c201c98b83 100644
--- a/libgimp/gimpimagecolorprofile_pdb.c
+++ b/libgimp/gimpimagecolorprofile_pdb.c
@@ -350,6 +350,158 @@ gimp_image_set_simulation_profile_from_file (GimpImage *image,
   return success;
 }
 
+/**
+ * _gimp_image_get_simulation_intent:
+ * @image: The image.
+ *
+ * Returns the image's simulation rendering intent
+ *
+ * This procedure returns the image's simulation rendering intent.
+ *
+ * Returns: The image's simulation rendering intent.
+ *
+ * Since: 3.0
+ **/
+GimpColorRenderingIntent
+_gimp_image_get_simulation_intent (GimpImage *image)
+{
+  GimpValueArray *args;
+  GimpValueArray *return_vals;
+  GimpColorRenderingIntent intent = 0;
+
+  args = gimp_value_array_new_from_types (NULL,
+                                          GIMP_TYPE_IMAGE, image,
+                                          G_TYPE_NONE);
+
+  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
+                                              "gimp-image-get-simulation-intent",
+                                              args);
+  gimp_value_array_unref (args);
+
+  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+    intent = GIMP_VALUES_GET_ENUM (return_vals, 1);
+
+  gimp_value_array_unref (return_vals);
+
+  return intent;
+}
+
+/**
+ * _gimp_image_set_simulation_intent:
+ * @image: The image.
+ * @intent: A GimpColorRenderingIntent.
+ *
+ * Sets the image's simulation rendering intent
+ *
+ * This procedure sets the image's simulation rendering intent.
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.0
+ **/
+gboolean
+_gimp_image_set_simulation_intent (GimpImage                *image,
+                                   GimpColorRenderingIntent  intent)
+{
+  GimpValueArray *args;
+  GimpValueArray *return_vals;
+  gboolean success = TRUE;
+
+  args = gimp_value_array_new_from_types (NULL,
+                                          GIMP_TYPE_IMAGE, image,
+                                          GIMP_TYPE_COLOR_RENDERING_INTENT, intent,
+                                          G_TYPE_NONE);
+
+  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
+                                              "gimp-image-set-simulation-intent",
+                                              args);
+  gimp_value_array_unref (args);
+
+  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
+
+  gimp_value_array_unref (return_vals);
+
+  return success;
+}
+
+/**
+ * _gimp_image_get_simulation_bpc:
+ * @image: The image.
+ *
+ * Returns whether the image has Black Point Compensation enabled for
+ * its simulation
+ *
+ * This procedure returns whether the image has Black Point
+ * Compensation enabled for its simulation
+ *
+ * Returns: The Black Point Compensation status.
+ *
+ * Since: 3.0
+ **/
+gboolean
+_gimp_image_get_simulation_bpc (GimpImage *image)
+{
+  GimpValueArray *args;
+  GimpValueArray *return_vals;
+  gboolean bpc = FALSE;
+
+  args = gimp_value_array_new_from_types (NULL,
+                                          GIMP_TYPE_IMAGE, image,
+                                          G_TYPE_NONE);
+
+  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
+                                              "gimp-image-get-simulation-bpc",
+                                              args);
+  gimp_value_array_unref (args);
+
+  if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
+    bpc = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
+
+  gimp_value_array_unref (return_vals);
+
+  return bpc;
+}
+
+/**
+ * _gimp_image_set_simulation_bpc:
+ * @image: The image.
+ * @bpc: The Black Point Compensation status.
+ *
+ * Sets whether the image has Black Point Compensation enabled for its
+ * simulation
+ *
+ * This procedure whether the image has Black Point Compensation
+ * enabled for its simulation
+ *
+ * Returns: TRUE on success.
+ *
+ * Since: 3.0
+ **/
+gboolean
+_gimp_image_set_simulation_bpc (GimpImage *image,
+                                gboolean   bpc)
+{
+  GimpValueArray *args;
+  GimpValueArray *return_vals;
+  gboolean success = TRUE;
+
+  args = gimp_value_array_new_from_types (NULL,
+                                          GIMP_TYPE_IMAGE, image,
+                                          G_TYPE_BOOLEAN, bpc,
+                                          G_TYPE_NONE);
+
+  return_vals = gimp_pdb_run_procedure_array (gimp_get_pdb (),
+                                              "gimp-image-set-simulation-bpc",
+                                              args);
+  gimp_value_array_unref (args);
+
+  success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
+
+  gimp_value_array_unref (return_vals);
+
+  return success;
+}
+
 /**
  * _gimp_image_convert_color_profile:
  * @image: The image.
diff --git a/libgimp/gimpimagecolorprofile_pdb.h b/libgimp/gimpimagecolorprofile_pdb.h
index ac49fc8f9f..834f78d500 100644
--- a/libgimp/gimpimagecolorprofile_pdb.h
+++ b/libgimp/gimpimagecolorprofile_pdb.h
@@ -32,31 +32,37 @@ G_BEGIN_DECLS
 /* For information look into the C source or the html documentation */
 
 
-G_GNUC_INTERNAL guint8*  _gimp_image_get_color_profile               (GimpImage                *image,
-                                                                      gint                     *num_bytes);
-G_GNUC_INTERNAL guint8*  _gimp_image_get_effective_color_profile     (GimpImage                *image,
-                                                                      gint                     *num_bytes);
-G_GNUC_INTERNAL gboolean _gimp_image_set_color_profile               (GimpImage                *image,
-                                                                      gint                      num_bytes,
-                                                                      const guint8             
*color_profile);
-gboolean                 gimp_image_set_color_profile_from_file      (GimpImage                *image,
-                                                                      GFile                    *file);
-G_GNUC_INTERNAL guint8*  _gimp_image_get_simulation_profile          (GimpImage                *image,
-                                                                      gint                     *num_bytes);
-G_GNUC_INTERNAL gboolean _gimp_image_set_simulation_profile          (GimpImage                *image,
-                                                                      gint                      num_bytes,
-                                                                      const guint8             
*color_profile);
-gboolean                 gimp_image_set_simulation_profile_from_file (GimpImage                *image,
-                                                                      GFile                    *file);
-G_GNUC_INTERNAL gboolean _gimp_image_convert_color_profile           (GimpImage                *image,
-                                                                      gint                      num_bytes,
-                                                                      const guint8             
*color_profile,
-                                                                      GimpColorRenderingIntent  intent,
-                                                                      gboolean                  bpc);
-gboolean                 gimp_image_convert_color_profile_from_file  (GimpImage                *image,
-                                                                      GFile                    *file,
-                                                                      GimpColorRenderingIntent  intent,
-                                                                      gboolean                  bpc);
+G_GNUC_INTERNAL guint8*                  _gimp_image_get_color_profile               (GimpImage              
  *image,
+                                                                                      gint                   
  *num_bytes);
+G_GNUC_INTERNAL guint8*                  _gimp_image_get_effective_color_profile     (GimpImage              
  *image,
+                                                                                      gint                   
  *num_bytes);
+G_GNUC_INTERNAL gboolean                 _gimp_image_set_color_profile               (GimpImage              
  *image,
+                                                                                      gint                   
   num_bytes,
+                                                                                      const guint8           
  *color_profile);
+gboolean                                 gimp_image_set_color_profile_from_file      (GimpImage              
  *image,
+                                                                                      GFile                  
  *file);
+G_GNUC_INTERNAL guint8*                  _gimp_image_get_simulation_profile          (GimpImage              
  *image,
+                                                                                      gint                   
  *num_bytes);
+G_GNUC_INTERNAL gboolean                 _gimp_image_set_simulation_profile          (GimpImage              
  *image,
+                                                                                      gint                   
   num_bytes,
+                                                                                      const guint8           
  *color_profile);
+gboolean                                 gimp_image_set_simulation_profile_from_file (GimpImage              
  *image,
+                                                                                      GFile                  
  *file);
+G_GNUC_INTERNAL GimpColorRenderingIntent _gimp_image_get_simulation_intent           (GimpImage              
  *image);
+G_GNUC_INTERNAL gboolean                 _gimp_image_set_simulation_intent           (GimpImage              
  *image,
+                                                                                      
GimpColorRenderingIntent  intent);
+G_GNUC_INTERNAL gboolean                 _gimp_image_get_simulation_bpc              (GimpImage              
  *image);
+G_GNUC_INTERNAL gboolean                 _gimp_image_set_simulation_bpc              (GimpImage              
  *image,
+                                                                                      gboolean               
   bpc);
+G_GNUC_INTERNAL gboolean                 _gimp_image_convert_color_profile           (GimpImage              
  *image,
+                                                                                      gint                   
   num_bytes,
+                                                                                      const guint8           
  *color_profile,
+                                                                                      
GimpColorRenderingIntent  intent,
+                                                                                      gboolean               
   bpc);
+gboolean                                 gimp_image_convert_color_profile_from_file  (GimpImage              
  *image,
+                                                                                      GFile                  
  *file,
+                                                                                      
GimpColorRenderingIntent  intent,
+                                                                                      gboolean               
   bpc);
 
 
 G_END_DECLS
diff --git a/libgimpcolor/gimpcolor.def b/libgimpcolor/gimpcolor.def
index 7b40b20570..a016f042d4 100644
--- a/libgimpcolor/gimpcolor.def
+++ b/libgimpcolor/gimpcolor.def
@@ -21,9 +21,13 @@ EXPORTS
        gimp_cmyka_set_uchar
        gimp_color_managed_get_color_profile
        gimp_color_managed_get_icc_profile
+       gimp_color_managed_get_simulation_bpc
+       gimp_color_managed_get_simulation_intent
        gimp_color_managed_get_simulation_profile
        gimp_color_managed_get_type
        gimp_color_managed_profile_changed
+       gimp_color_managed_simulation_bpc_changed
+       gimp_color_managed_simulation_intent_changed
        gimp_color_managed_simulation_profile_changed
        gimp_color_profile_get_copyright
        gimp_color_profile_get_description
diff --git a/libgimpcolor/gimpcolormanaged.c b/libgimpcolor/gimpcolormanaged.c
index 4dc5a3e213..eed26fc1b8 100644
--- a/libgimpcolor/gimpcolormanaged.c
+++ b/libgimpcolor/gimpcolormanaged.c
@@ -43,6 +43,8 @@ enum
 {
   PROFILE_CHANGED,
   SIMULATION_PROFILE_CHANGED,
+  SIMULATION_INTENT_CHANGED,
+  SIMULATION_BPC_CHANGED,
   LAST_SIGNAL
 };
 
@@ -76,6 +78,24 @@ gimp_color_managed_default_init (GimpColorManagedInterface *iface)
                                    simulation_profile_changed),
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
+
+  gimp_color_managed_signals[SIMULATION_INTENT_CHANGED] =
+    g_signal_new ("simulation-intent-changed",
+                  G_TYPE_FROM_INTERFACE (iface),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpColorManagedInterface,
+                                   simulation_intent_changed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+
+  gimp_color_managed_signals[SIMULATION_BPC_CHANGED] =
+    g_signal_new ("simulation-bpc-changed",
+                  G_TYPE_FROM_INTERFACE (iface),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpColorManagedInterface,
+                                   simulation_bpc_changed),
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
 }
 
 
@@ -162,6 +182,59 @@ gimp_color_managed_get_simulation_profile (GimpColorManaged *managed)
   return NULL;
 }
 
+/**
+ * gimp_color_managed_get_simulation_intent:
+ * @managed: an object the implements the #GimpColorManaged interface
+ *
+ * This function always returns a #GimpColorRenderingIntent
+ *
+ * Returns: (transfer full): The @managed's simulation #GimpColorRenderingIntent.
+ *
+ * Since: 3.0
+ **/
+GimpColorRenderingIntent
+gimp_color_managed_get_simulation_intent (GimpColorManaged *managed)
+{
+  GimpColorManagedInterface *iface;
+
+  g_return_val_if_fail (GIMP_IS_COLOR_MANAGED (managed),
+                        GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC);
+
+  iface = GIMP_COLOR_MANAGED_GET_IFACE (managed);
+
+  if (iface->get_simulation_intent)
+    return iface->get_simulation_intent (managed);
+
+  return GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC;
+}
+
+/**
+ * gimp_color_managed_get_simulation_bpc:
+ * @managed: an object the implements the #GimpColorManaged interface
+ *
+ * This function always returns a gboolean representing whether
+ * Black Point Compensation is enabled
+ *
+ * Returns: (transfer full): The @managed's simulation Black Point Compensation value.
+ *
+ * Since: 3.0
+ **/
+gboolean
+gimp_color_managed_get_simulation_bpc (GimpColorManaged *managed)
+{
+  GimpColorManagedInterface *iface;
+
+  g_return_val_if_fail (GIMP_IS_COLOR_MANAGED (managed), FALSE);
+
+  iface = GIMP_COLOR_MANAGED_GET_IFACE (managed);
+
+  if (iface->get_simulation_bpc)
+    return iface->get_simulation_bpc (managed);
+
+  return FALSE;
+}
+
+
 /**
  * gimp_color_managed_profile_changed:
  * @managed: an object that implements the #GimpColorManaged interface
@@ -193,3 +266,35 @@ gimp_color_managed_simulation_profile_changed (GimpColorManaged *managed)
 
   g_signal_emit (managed, gimp_color_managed_signals[SIMULATION_PROFILE_CHANGED], 0);
 }
+
+/**
+ * gimp_color_managed_simulation_intent_changed:
+ * @managed: an object that implements the #GimpColorManaged interface
+ *
+ * Emits the "simulation-intent-changed" signal.
+ *
+ * Since: 3.0
+ **/
+void
+gimp_color_managed_simulation_intent_changed (GimpColorManaged *managed)
+{
+  g_return_if_fail (GIMP_IS_COLOR_MANAGED (managed));
+
+  g_signal_emit (managed, gimp_color_managed_signals[SIMULATION_INTENT_CHANGED], 0);
+}
+
+/**
+ * gimp_color_managed_simulation_bpc_changed:
+ * @managed: an object that implements the #GimpColorManaged interface
+ *
+ * Emits the "simulation-bpc-changed" signal.
+ *
+ * Since: 3.0
+ **/
+void
+gimp_color_managed_simulation_bpc_changed (GimpColorManaged *managed)
+{
+  g_return_if_fail (GIMP_IS_COLOR_MANAGED (managed));
+
+  g_signal_emit (managed, gimp_color_managed_signals[SIMULATION_BPC_CHANGED], 0);
+}
diff --git a/libgimpcolor/gimpcolormanaged.h b/libgimpcolor/gimpcolormanaged.h
index cf36ffad7c..7bab1c68ff 100644
--- a/libgimpcolor/gimpcolormanaged.h
+++ b/libgimpcolor/gimpcolormanaged.h
@@ -45,6 +45,10 @@ G_DECLARE_INTERFACE (GimpColorManaged, gimp_color_managed, GIMP, COLOR_MANAGED,
  *                     by the object
  * @get_simulation_profile: Returns the simulation #GimpColorProfile of the
  *                          pixels managed by the object
+ * @get_simulation_rendering_intent: Returns the simulation #GimpColorRenderingIntent
+ *                                   of the pixels managed by the object
+ * @get_simulation_bpc: Returns whether black point compensation is enabled for the
+ *                      simulation of the pixels managed by the object
  **/
 struct _GimpColorManagedInterface
 {
@@ -60,29 +64,44 @@ struct _GimpColorManagedInterface
    *
    * Since: 2.4
    */
-  const guint8     * (* get_icc_profile)            (GimpColorManaged *managed,
-                                                     gsize            *len);
+  const guint8     * (* get_icc_profile)                     (GimpColorManaged *managed,
+                                                              gsize            *len);
 
   /*  signals  */
-  void               (* profile_changed)            (GimpColorManaged *managed);
+  void               (* profile_changed)                     (GimpColorManaged *managed);
 
-  void               (* simulation_profile_changed) (GimpColorManaged *managed);
+  void               (* simulation_profile_changed)          (GimpColorManaged *managed);
+
+  void               (* simulation_intent_changed)           (GimpColorManaged *managed);
+
+  void               (* simulation_bpc_changed)              (GimpColorManaged *managed);
 
   /*  virtual functions  */
-  GimpColorProfile * (* get_color_profile)      (GimpColorManaged *managed);
-  GimpColorProfile * (* get_simulation_profile) (GimpColorManaged *managed);
+  GimpColorProfile * (* get_color_profile)               (GimpColorManaged *managed);
+  GimpColorProfile * (* get_simulation_profile)          (GimpColorManaged *managed);
+  GimpColorRenderingIntent
+                     (* get_simulation_intent)           (GimpColorManaged *managed);
+  gboolean           (* get_simulation_bpc)              (GimpColorManaged *managed);
 };
 
 
-const guint8     * gimp_color_managed_get_icc_profile            (GimpColorManaged *managed,
-                                                                  gsize            *len);
-GimpColorProfile * gimp_color_managed_get_color_profile          (GimpColorManaged *managed);
+const guint8     *       gimp_color_managed_get_icc_profile            (GimpColorManaged *managed,
+                                                                        gsize            *len);
+GimpColorProfile *       gimp_color_managed_get_color_profile          (GimpColorManaged *managed);
+
+GimpColorProfile *       gimp_color_managed_get_simulation_profile     (GimpColorManaged *managed);
+
+GimpColorRenderingIntent gimp_color_managed_get_simulation_intent      (GimpColorManaged *managed);
+
+gboolean                 gimp_color_managed_get_simulation_bpc         (GimpColorManaged *managed);
+
+void                     gimp_color_managed_profile_changed            (GimpColorManaged *managed);
 
-GimpColorProfile * gimp_color_managed_get_simulation_profile     (GimpColorManaged *managed);
+void                     gimp_color_managed_simulation_profile_changed (GimpColorManaged *managed);
 
-void               gimp_color_managed_profile_changed            (GimpColorManaged *managed);
+void                     gimp_color_managed_simulation_intent_changed  (GimpColorManaged *managed);
 
-void               gimp_color_managed_simulation_profile_changed (GimpColorManaged *managed);
+void                     gimp_color_managed_simulation_bpc_changed     (GimpColorManaged *managed);
 
 
 G_END_DECLS
diff --git a/libgimpwidgets/gimpcolorarea.c b/libgimpwidgets/gimpcolorarea.c
index 604d2e9c23..a29d95b22c 100644
--- a/libgimpwidgets/gimpcolorarea.c
+++ b/libgimpwidgets/gimpcolorarea.c
@@ -46,6 +46,7 @@
  **/
 
 
+#define RGBA_EPSILON        1e-6
 #define DRAG_PREVIEW_SIZE   32
 #define DRAG_ICON_OFFSET    -8
 
@@ -1025,7 +1026,8 @@ gimp_color_area_create_transform (GimpColorArea *area)
                                                          profile,
                                                          format,
                                                          format,
-                                                         NULL);
+                                                         NULL,
+                                                         -1, FALSE);
     }
 }
 
diff --git a/libgimpwidgets/gimpcolorscale.c b/libgimpwidgets/gimpcolorscale.c
index 0bf7f665fe..35300ea97b 100644
--- a/libgimpwidgets/gimpcolorscale.c
+++ b/libgimpwidgets/gimpcolorscale.c
@@ -943,7 +943,8 @@ gimp_color_scale_create_transform (GimpColorScale *scale)
                                                          profile,
                                                          format,
                                                          format,
-                                                         NULL);
+                                                         NULL,
+                                                         -1, FALSE);
     }
 }
 
diff --git a/libgimpwidgets/gimpcolorselect.c b/libgimpwidgets/gimpcolorselect.c
index af7a119f29..8eb1f78ffe 100644
--- a/libgimpwidgets/gimpcolorselect.c
+++ b/libgimpwidgets/gimpcolorselect.c
@@ -1957,7 +1957,8 @@ gimp_color_select_create_transform (GimpColorSelect *select)
                                                            profile,
                                                            format,
                                                            format,
-                                                           NULL);
+                                                           NULL,
+                                                           -1, FALSE);
     }
 }
 
diff --git a/libgimpwidgets/gimppreviewarea.c b/libgimpwidgets/gimppreviewarea.c
index 424d0c1246..41f9ff3412 100644
--- a/libgimpwidgets/gimppreviewarea.c
+++ b/libgimpwidgets/gimppreviewarea.c
@@ -438,7 +438,8 @@ gimp_preview_area_create_transform (GimpPreviewArea *area)
                                                          profile,
                                                          format,
                                                          format,
-                                                         NULL);
+                                                         NULL,
+                                                         -1, FALSE);
     }
 }
 
diff --git a/libgimpwidgets/gimpwidgetsutils.c b/libgimpwidgets/gimpwidgetsutils.c
index 33b0e606cf..5e3a530749 100644
--- a/libgimpwidgets/gimpwidgetsutils.c
+++ b/libgimpwidgets/gimpwidgetsutils.c
@@ -866,12 +866,14 @@ transform_cache_config_notify (GObject          *config,
  * Since: 2.10
  **/
 GimpColorTransform *
-gimp_widget_get_color_transform (GtkWidget        *widget,
-                                 GimpColorConfig  *config,
-                                 GimpColorProfile *src_profile,
-                                 const Babl       *src_format,
-                                 const Babl       *dest_format,
-                                 GimpColorProfile *softproof_profile)
+gimp_widget_get_color_transform (GtkWidget               *widget,
+                                 GimpColorConfig         *config,
+                                 GimpColorProfile        *src_profile,
+                                 const Babl              *src_format,
+                                 const Babl              *dest_format,
+                                 GimpColorProfile        *softproof_profile,
+                                 GimpColorRenderingIntent simulation_intent,
+                                 gboolean                 simulation_bpc)
 {
   static gboolean     initialized   = FALSE;
   GimpColorProfile   *proof_profile = NULL;
@@ -947,7 +949,8 @@ gimp_widget_get_color_transform (GtkWidget        *widget,
   cache->src_format    = src_format;
   cache->dest_profile  = dest_profile;
   cache->dest_format   = dest_format;
-  cache->proof_profile = proof_profile;
+  if (proof_profile)
+    cache->proof_profile = g_object_ref (proof_profile);
 
   cache->notify_id =
     g_signal_connect (cache->config, "notify",
@@ -960,7 +963,7 @@ gimp_widget_get_color_transform (GtkWidget        *widget,
     {
       GimpColorTransformFlags flags = 0;
 
-      if (gimp_color_config_get_simulation_bpc (config))
+      if (simulation_bpc)
         flags |= GIMP_COLOR_TRANSFORM_FLAGS_BLACK_POINT_COMPENSATION;
 
       if (! gimp_color_config_get_simulation_optimize (config))
@@ -990,7 +993,7 @@ gimp_widget_get_color_transform (GtkWidget        *widget,
                                            cache->dest_profile,
                                            cache->dest_format,
                                            cache->proof_profile,
-                                           gimp_color_config_get_simulation_intent (config),
+                                           simulation_intent,
                                            gimp_color_config_get_display_intent (config),
                                            flags);
     }
diff --git a/libgimpwidgets/gimpwidgetsutils.h b/libgimpwidgets/gimpwidgetsutils.h
index 7de3e18cd4..58a5da1513 100644
--- a/libgimpwidgets/gimpwidgetsutils.h
+++ b/libgimpwidgets/gimpwidgetsutils.h
@@ -61,7 +61,9 @@ GimpColorTransform * gimp_widget_get_color_transform (GtkWidget         *widget,
                                                       GimpColorProfile  *src_profile,
                                                       const Babl        *src_format,
                                                       const Babl        *dest_format,
-                                                      GimpColorProfile  *softproof_profile);
+                                                      GimpColorProfile  *softproof_profile,
+                                                      GimpColorRenderingIntent simulation_intent,
+                                                      gboolean           simulation_bpc);
 
 
 G_END_DECLS
diff --git a/modules/color-selector-water.c b/modules/color-selector-water.c
index ee04e6e48b..748a6012e3 100644
--- a/modules/color-selector-water.c
+++ b/modules/color-selector-water.c
@@ -269,7 +269,8 @@ colorsel_water_create_transform (ColorselWater *water)
                                                           profile,
                                                           format,
                                                           format,
-                                                          NULL);
+                                                          NULL,
+                                                          -1, FALSE);
     }
 }
 
diff --git a/modules/gimpcolorwheel.c b/modules/gimpcolorwheel.c
index 3f35ef86bd..9c93bcc187 100644
--- a/modules/gimpcolorwheel.c
+++ b/modules/gimpcolorwheel.c
@@ -1552,7 +1552,8 @@ gimp_color_wheel_create_transform (GimpColorWheel *wheel)
                                                          profile,
                                                          format,
                                                          format,
-                                                         NULL);
+                                                         NULL,
+                                                         -1, FALSE);
     }
 }
 
diff --git a/pdb/groups/image_color_profile.pdb b/pdb/groups/image_color_profile.pdb
index 3bf8e9abb0..f1ba2a6763 100644
--- a/pdb/groups/image_color_profile.pdb
+++ b/pdb/groups/image_color_profile.pdb
@@ -265,6 +265,9 @@ sub image_set_simulation_profile {
     $help = <<'HELP';
 This procedure sets the image's simulation color profile, or unsets it if NULL is
 passed as 'color_profile'. This procedure does no color conversion.
+However, it will change the pixel format of all layers to contain the
+babl space matching the profile. You must call this procedure before
+adding layers to the image.
 HELP
 
     &alxsa_pdb_misc('2022', '3.0');
@@ -297,9 +300,7 @@ HELP
           g_object_unref (profile);
         }
       else
-        {
-          success = FALSE;
-        }
+        success = FALSE;
     }
   else
     {
@@ -316,7 +317,10 @@ sub image_set_simulation_profile_from_file {
     $help = <<'HELP';
 This procedure sets the image's simulation color profile from a file containing
 an ICC profile, or unsets it if NULL is passed as 'file'. This
-procedure does no color conversion.
+procedure does no color conversion. However, it will change the pixel
+format of all layers to contain the babl space matching the
+profile. You must call this procedure before adding layers to the
+image.
 HELP
 
     &alxsa_pdb_misc('2022', '3.0');
@@ -343,9 +347,7 @@ HELP
           g_object_unref (profile);
         }
       else
-        {
-          success = FALSE;
-        }
+        success = FALSE;
     }
   else
     {
@@ -356,6 +358,120 @@ CODE
     );
 }
 
+sub image_get_simulation_intent {
+    $blurb = "Returns the image's simulation rendering intent";
+
+    $help = <<'HELP';
+This procedure returns the image's simulation rendering intent.
+HELP
+
+    &alxsa_pdb_misc('2022', '3.0');
+
+    $lib_private = 1;
+
+    @inargs = (
+        { name => 'image', type => 'image',
+          desc => 'The image' }
+    );
+
+    @outargs = (
+        { name => 'intent', type => 'enum GimpColorRenderingIntent',
+          desc => "The image's simulation rendering intent." }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  intent = gimp_image_get_simulation_intent (image);
+}
+CODE
+    );
+}
+
+sub image_set_simulation_intent {
+    $blurb = "Sets the image's simulation rendering intent";
+
+    $help = <<'HELP';
+This procedure sets the image's simulation rendering intent.
+HELP
+
+    &alxsa_pdb_misc('2022', '3.0');
+
+    $lib_private = 1;
+
+    @inargs = (
+        { name => 'image', type => 'image',
+          desc => 'The image' },
+        { name => 'intent', type => 'enum GimpColorRenderingIntent',
+          desc => 'A GimpColorRenderingIntent' }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  gimp_image_set_simulation_intent (image, intent);
+}
+CODE
+    );
+}
+
+sub image_get_simulation_bpc {
+    $blurb = "Returns whether the image has Black Point Compensation enabled for its simulation";
+
+    $help = <<'HELP';
+This procedure returns whether the image has Black Point Compensation enabled for its simulation
+HELP
+
+    &alxsa_pdb_misc('2022', '3.0');
+
+    $lib_private = 1;
+
+    @inargs = (
+        { name => 'image', type => 'image',
+          desc => 'The image' }
+    );
+
+    @outargs = (
+        { name => 'bpc', type => 'boolean',
+          desc => "The Black Point Compensation status." }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  bpc = gimp_image_get_simulation_bpc (image);
+}
+CODE
+    );
+}
+
+sub image_set_simulation_bpc {
+    $blurb = "Sets whether the image has Black Point Compensation enabled for its simulation";
+
+    $help = <<'HELP';
+This procedure whether the image has Black Point Compensation enabled for its simulation
+HELP
+
+    &alxsa_pdb_misc('2022', '3.0');
+
+    $lib_private = 1;
+
+    @inargs = (
+        { name => 'image', type => 'image',
+          desc => 'The image' },
+        { name => 'bpc', type => 'boolean',
+          desc => 'The Black Point Compensation status.' }
+    );
+
+    %invoke = (
+        code => <<'CODE'
+{
+  gimp_image_set_simulation_bpc (image, bpc);
+}
+CODE
+    );
+}
+
 sub image_convert_color_profile {
     $blurb = "Convert the image's layers to a color profile";
 
@@ -472,6 +588,10 @@ CODE
             image_get_simulation_profile
             image_set_simulation_profile
             image_set_simulation_profile_from_file
+            image_get_simulation_intent
+            image_set_simulation_intent
+            image_get_simulation_bpc
+            image_set_simulation_bpc
             image_convert_color_profile
             image_convert_color_profile_from_file);
 


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