[krita] /: Merge in softproofing and ocio looks.

Wolthera van Hovell tot Westerflier griffinvalley at gmail.com
Tue Jun 28 15:54:46 UTC 2016


Git commit 0807eeb01d02873019bdc83e39f15f05b4c231d6 by Wolthera van Hovell tot Westerflier.
Committed on 28/06/2016 at 15:50.
Pushed by woltherav into branch 'master'.

Merge in softproofing and ocio looks.

These features allow for better workflow in for Print and VFX respectively.
Check https://docs.krita.org/Soft_Proofing on how to use softproofing.

Looks will still need a little note added to Lut management page.

CCMAIL:kimageshop at kde.org
Fixes T2395

Squashed commit of the following:

commit 38c4fc32021af778b9446a05502c885087bc0ff2
Merge: 5477611 e308ed0
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 28 17:46:16 2016 +0200

    Merge branch 'master' into krita-testing-wolthera

commit 54776118b78a3f32b408de25f9c7b3532630b5df
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 28 17:43:20 2016 +0200

    Add rant why per-shot looks won't work after wasting afternoon on it.

    The tl;dr is that OCIO's documentation is extremely vague.

    Ref T2337

commit a3b224b6958db0c31a2df4ba47d19d87bf9f9833
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Fri Jun 24 13:16:01 2016 +0200

    Fix loading of default gamut warning color.

    Always set the color space of the kocolor, kids.

    ref T2337

commit 652405d3acd67d4e87d788d0b77fb67768a5cc3b
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Fri Jun 24 12:54:17 2016 +0200

    Add adaptation state slider.

    This allows you to set whether or not to adapt the white point, that is,
    to set the white point to the screen white(full slider) or to convert all whiteson screen to the white point of the profile when using absolute colorimetric
    as intent.

    This is useful to simulate paper-colour.

    Ref T2337

commit aea525ca6dc10b6867153da52fcf215a80adc0ba
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Fri Jun 24 10:32:37 2016 +0200

    Fix builds on gcc 6

commit 67f4e5a21f873f5a3d08d3bb90250cb5b5806e2b
Merge: 519f9c1 159a612
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 22:00:22 2016 +0200

    Merge branch 'master' into krita-testing-wolthera

commit 519f9c1fbe43edd6922b0cc5ef4ed85f17fd6dfc
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 19:49:56 2016 +0200

    Add option to set default Proofing Options.

    These will work for images with no proofing options, so, old loaded images
    and new images. With this it is feature complete, and people can start testing.

    Ref T2337
    Ref T1238

commit 062db74d24fb7e656e8a06cbddde560ab03166b6
Merge: 2e057e7 7625539
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 15:16:54 2016 +0200

    Merge branch 'master' into krita-testing-wolthera

commit 2e057e7a5339c3e3657fef562bbe716c672805b4
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 15:15:24 2016 +0200

    Clean up all the debug messages.

    It's... quieter in the terminal now.

    Ref T2337

commit 7ff7e60b5f423cdbeaa4089d8a6e7b2cd33129ca
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 15:01:02 2016 +0200

    Cleanup: Make projection color a defined tag.

commit 604efc8ddb21d38ad8a040b19ac7fa33cfe2e8d9
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 14:50:20 2016 +0200

    Not sure if this isn't the correct code instead...

    Ref T2337

commit 7c669703ff0c7fdf755d8070537c339bbcb02533
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 14:42:04 2016 +0200

    Load embedded proofing profiles if they exist, and add them to the profile registery.

    Needs testing for obvious reasons.

    Ref T2337

commit 119906b23bf0e1a3b8acfaf5828cdfcbaa92e77d
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 14:27:07 2016 +0200

    Add embedding of the proofing profile.

    This is so that we can later unembed them.

    Ref T2337

commit 9ef1dad773605e32d7018ccf7a90c1817d430d89
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 14:15:47 2016 +0200

    Load Warning Colors properly from file.

    Now the out of gamut warning can be written into file as XML
    and loaded from file as XML.

    Ref T2337

commit 6a57cf08fb170e4d32341ede0f3733be3ab1f37e
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 13:49:49 2016 +0200

    Fix naming conventions.

    I was using gamut warnings/alarms, and softproofing and soft proofing.

    The standard is (Out of )Gamut Warnings and Soft Proofing.

    Ref T2337

commit 4faa8b574da039d9dc86f099841bb901495e19a9
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 23 13:37:49 2016 +0200

    Disable softproofing in floating point spaces.

    There's a bunch of little niggling bugs that crop up when soft proofing
    in floating point spaces, amongst which the inability of the proofing
    mechanism to see floating point values higher than 1.0 fall outside of
    the gamut of the color space, let alone recognising whether it can go
    inside the gamut of the proofing space.

    See also http://ninedegreesbelow.com/bug-reports/soft-proofing-problems.html

    For now, it's best to disable softproofing on floating point spaces.
    Might need a more official check, though.

    Ref 2337

commit 91d7da8c41c4200729e87f98269fdf011422bb07
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Wed Jun 22 16:26:52 2016 +0200

    Make views smart enough to track softproof/gamutcheck-state.

    Also add a floating message to say when the softproofing or gamutcheck
    is turned on in the view. Wording may change.

    Ref T2337

commit 5c48dd2c12e37ff0a75e098368449d260ff524bc
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Wed Jun 22 16:26:35 2016 +0200

    Fix Build

commit 6bacfcda6005622669a3f4a47da59a759838797c
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Wed Jun 22 14:45:52 2016 +0200

    Add attempt at saving color to xml.

    This fails due to me not being able to load the xml, due object-bonanza.

    ref T2337

commit 3bbf025b32ae53ff4601f188901541fcb80f63a7
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Wed Jun 22 12:49:06 2016 +0200

    Intitial saving/loading of config.[unstable]

    Works, but might change later.

commit 1f733e28cb7f87fb4bea5a14159e86c5a5dd852f
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 21 20:21:15 2016 +0200

    Refactor the proofing transform system for better caching.

    This now makes the transform separately from the actual transforming,
    which means it's easier to cache and to update. Softproofing is now
    gone from usable to user-friendly.

    Still needs saving/loading and little setting-bugs fixed.

    ref T2337

commit 8371c4179b1a8025e727528c5b7ce09ee3562ec9
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 21 18:20:48 2016 +0200

    Enable Gamut color and proofing intent.

    The image now stored proofing intent, and the monitor intent is the general
    rendering intent.

    This also allows us to set the gamut warning color, however, for updating
    you currently need to switch profiles as well. I'll make a seperate
    generateSoftProofingTransform function, to cache the transform better, so it's
    easier to update.

    Ref 2337

commit 9d9ce38079c60ed04a63a2985a9c5ecb08652626
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 21 14:18:05 2016 +0200

    Add softproofing section to image properties menu.

    Now, the proofing in the image can be changed.

    Also fixes that ugly little square problem with the kocoloractionpopup button.

    Ref T1238, T2337

commit 8d7b4418e798978ed5e4c9fbb28509e7b9e098d4
Merge: e2ee9ff d58645e
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 16 13:28:24 2016 +0200

    Merge remote-tracking branch 'origin/master' into krita-testing-wolthera

commit e2ee9ff5774c80ebb72c02bc02d8ce7a79ace72f
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 14 15:56:50 2016 +0200

    Cache the transform unelegantly.

    This does cause a significant speed-up, but it's a bit fiddly.
    Regardless, the speed-up is enough to make this usable.

commit f643fc7bc2deb9317b6b7ef299f9d76a0c4e2160
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 14 14:49:16 2016 +0200

    Fix softproofing

    It's slow again :/

commit cbc91c076310188456980563e3c061ca1a47147f
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 14 12:45:43 2016 +0200

    Fix setting softproofing and gamutcheck flags.

commit 9ae336ed94207bab7885010720647814c9648e9d
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Tue Jun 14 12:44:50 2016 +0200

    Cache the color space engine to make it faster

    It doesn't fix everything, but it fixes quite a bit.
    Ref T210

commit d43589016b35ea85943c55ff244e83e6bc5cd15a
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Mon Jun 13 17:59:18 2016 +0200

    Add base implementation softproofing with toggles.

    It doesn't really work yet :/

    Ref: T210
    Ref: T2337

commit 7de0256960a6021591217ea3935dba1b39143b58
Author: Boudewijn Rempt <boud at valdyas.org>
Date:   Sun Jun 12 16:10:31 2016 +0200

    Create the proofing transform

    This doesn't use the caching graph stuff, which is too complex
    to refactor for now.

commit 00efd627af23f28555aa33a78a18fdd133934cf3
Author: Boudewijn Rempt <boud at valdyas.org>
Date:   Sun Jun 12 16:10:05 2016 +0200

    Add a per-image proofing settings class

commit d3bd5375b304dfea9282a9ad581130c7ddf8200a
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Sun Jun 12 14:44:50 2016 +0200

    Push work-in-progress proofing

commit bb97947abc29f76913924de9f1d2cb4a2762cf80
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 9 16:42:18 2016 +0200

    Fix copy-paste error

commit 9ed934a8206ea1e11077f9332252b465c0899d1f
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Thu Jun 9 16:30:09 2016 +0200

    Add OCIO Look support.

    The code is based of that of Blender, as I couldn't figure out how else to
    apply looks. The OCIO api wasn't clear about it, nor could I find much information,
    but it somewhat works and doesn't crash.

    Auditors: rempt, dkazakov
    Ref: T210

commit 2819ad66554f33e229729f8d86eb11a01413f23f
Author: Wolthera van Hovell tot Westerflier <griffinvalley at gmail.com>
Date:   Wed Jun 8 12:21:25 2016 +0200

    Add softproofing to the lcms conversion tests

    I am not fully sure if I understand the softproofing function, but the alarm works.

M  +3    -1    krita/krita.xmlgui
M  +20   -0    krita/kritamenu.action
M  +1    -0    libs/image/CMakeLists.txt
A  +33   -0    libs/image/KisProofingConfiguration.h     [License: UNKNOWN]  *
M  +17   -0    libs/image/kis_image.cc
M  +19   -1    libs/image/kis_image.h
M  +38   -0    libs/image/kis_image_config.cpp
M  +5    -0    libs/image/kis_image_config.h
M  +1    -0    libs/pigment/CMakeLists.txt
M  +23   -0    libs/pigment/KoColorConversionTransformationAbstractFactory.h
A  +49   -0    libs/pigment/KoColorProofingConversionTransformation.cpp     [License: LGPL (v2.1+)]
A  +63   -0    libs/pigment/KoColorProofingConversionTransformation.h     [License: LGPL (v2.1+)]
M  +25   -3    libs/pigment/KoColorSpace.cpp
M  +29   -3    libs/pigment/KoColorSpace.h
M  +1    -0    libs/pigment/KoColorSpaceEngine.h
M  +4    -0    libs/pigment/KoColorSpace_p.h
M  +55   -0    libs/ui/KisView.cpp
M  +21   -0    libs/ui/KisView.h
M  +10   -0    libs/ui/KisViewManager.cpp
M  +75   -1    libs/ui/canvas/kis_canvas2.cpp
M  +22   -2    libs/ui/canvas/kis_canvas2.h
M  +45   -1    libs/ui/dialogs/kis_dlg_image_properties.cc
M  +4    -1    libs/ui/dialogs/kis_dlg_image_properties.h
M  +31   -43   libs/ui/dialogs/kis_dlg_preferences.cc
M  +2    -1    libs/ui/dialogs/kis_dlg_preferences.h
M  +124  -50   libs/ui/forms/wdgcolorsettings.ui
M  +124  -26   libs/ui/forms/wdgimageproperties.ui
M  +1    -0    libs/ui/kis_config.cc
M  +0    -1    libs/ui/kis_config.h
M  +56   -2    libs/ui/kra/kis_kra_loader.cpp
M  +42   -2    libs/ui/kra/kis_kra_saver.cpp
M  +1    -0    libs/ui/kra/kis_kra_saver.h
M  +10   -0    libs/ui/kra/kis_kra_tags.h
M  +6    -0    libs/ui/opengl/kis_opengl_canvas2.cpp
M  +24   -2    libs/ui/opengl/kis_opengl_image_textures.cpp
M  +7    -0    libs/ui/opengl/kis_opengl_image_textures.h
M  +29   -0    libs/ui/opengl/kis_texture_tile_update_info.h
M  +107  -7    plugins/color/lcms2engine/IccColorSpaceEngine.cpp
M  +5    -0    plugins/color/lcms2engine/IccColorSpaceEngine.h
M  +41   -0    plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.cpp
M  +2    -0    plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.h
M  +14   -0    plugins/dockers/lut/lutdocker_dock.cpp
M  +29   -0    plugins/dockers/lut/ocio_display_filter.cpp
M  +1    -0    plugins/dockers/lut/ocio_display_filter.h
M  +39   -8    plugins/dockers/lut/wdglut.ui

The files marked with a * at the end have a non valid license. Please read: http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are listed at that page.


http://commits.kde.org/krita/0807eeb01d02873019bdc83e39f15f05b4c231d6

diff --git a/krita/krita.xmlgui b/krita/krita.xmlgui
index 6ff3301..2989646 100644
--- a/krita/krita.xmlgui
+++ b/krita/krita.xmlgui
@@ -2,7 +2,7 @@
 <kpartgui xmlns="http://www.kde.org/standards/kxmlgui/1.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 name="Krita"
-version="92"
+version="93"
 xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0  http://www.kde.org/standards/kxmlgui/1.0/kxmlgui.xsd">
   <MenuBar>
     <Menu name="file" noMerge="1">
@@ -62,6 +62,8 @@ xsi:schemaLocation="http://www.kde.org/standards/kxmlgui/1.0  http://www.kde.org
       <Action name="fullscreen"/>
       <Action name="wrap_around_mode"/>
       <Action name="level_of_detail_mode"/>
+      <Action name="softProof"/>
+      <Action name="gamutCheck"/>
       <Separator/>
       <Menu name="Canvas">
           <text>&Canvas</text>
diff --git a/krita/kritamenu.action b/krita/kritamenu.action
index 41fdecd..21f2cf1 100644
--- a/krita/kritamenu.action
+++ b/krita/kritamenu.action
@@ -528,6 +528,26 @@
       <isCheckable>true</isCheckable>
       <statusTip></statusTip>
     </Action>
+    <Action name="softProof">
+      <icon></icon>
+      <text>Soft Proofing</text>
+      <whatsThis></whatsThis>
+      <toolTip>Turns on Soft Proofing</toolTip>
+      <iconText>Turns on Soft Proofing</iconText>
+      <shortcut>Ctrl+Y</shortcut>
+      <isCheckable>true</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="gamutCheck">
+      <icon></icon>
+      <text>Out of Gamut Warnings</text>
+      <whatsThis></whatsThis>
+      <toolTip>Turns on warnings for colors our of proofed gamut, needs soft proofing to be turned on.</toolTip>
+      <iconText>Turns on warnings for colors our of proofed gamut, needs soft proofing to be turned on.</iconText>
+      <shortcut>Ctrl+Shift+Y</shortcut>
+      <isCheckable>true</isCheckable>
+      <statusTip></statusTip>
+    </Action>
     <Action name="mirror_canvas">
       <icon></icon>
       <text>Mirror View</text>
diff --git a/libs/image/CMakeLists.txt b/libs/image/CMakeLists.txt
index 8368696..0788a0f 100644
--- a/libs/image/CMakeLists.txt
+++ b/libs/image/CMakeLists.txt
@@ -247,6 +247,7 @@ set(kritaimage_LIB_SRCS
    kis_outline_generator.cpp
    kis_layer_composition.cpp
    kis_selection_filters.cpp
+   KisProofingConfiguration.h
    metadata/kis_meta_data_entry.cc
    metadata/kis_meta_data_filter.cc
    metadata/kis_meta_data_filter_p.cc
diff --git a/libs/image/KisProofingConfiguration.h b/libs/image/KisProofingConfiguration.h
new file mode 100644
index 0000000..32ad22d
--- /dev/null
+++ b/libs/image/KisProofingConfiguration.h
@@ -0,0 +1,33 @@
+#ifndef KISPROOFINGCONFIGURATION_H
+#define KISPROOFINGCONFIGURATION_H
+
+#include "KoColor.h"
+#include "KoColorSpace.h"
+#include "KoColorConversionTransformation.h"
+
+/**
+ * @brief The KisProofingConfiguration struct
+ * Little struct that stores the proofing configuration for a given file.
+ * The actual softproofing and gamutcheck toggles are set in the canvas.
+ * intet, conversionflags and warning color have default set to them. This
+ * wasn't possible for profileSpace.
+ */
+struct KisProofingConfiguration {
+    KisProofingConfiguration() : intent(KoColorConversionTransformation::IntentAbsoluteColorimetric),
+                                 conversionFlags(KoColorConversionTransformation::BlackpointCompensation),
+                                 warningColor(KoColor()),
+                                 proofingProfile("Chemical proof"),
+                                 proofingModel("CMYKA"),
+                                 proofingDepth("U8"),
+                                 adaptationState(1.0){}
+    KoColorConversionTransformation::Intent intent;
+    KoColorConversionTransformation::ConversionFlags conversionFlags;
+    KoColor warningColor;
+    QString proofingProfile;
+    QString proofingModel;
+    QString proofingDepth;
+    double adaptationState;
+
+};
+
+#endif // KISPROOFINGCONFIGURATION_H
diff --git a/libs/image/kis_image.cc b/libs/image/kis_image.cc
index 9c52586..7cd3aaf 100644
--- a/libs/image/kis_image.cc
+++ b/libs/image/kis_image.cc
@@ -38,6 +38,7 @@
 #include "KoColor.h"
 #include "KoColorProfile.h"
 #include <KoCompositeOpRegistry.h>
+#include "KisProofingConfiguration.h"
 
 #include "recorder/kis_action_recorder.h"
 #include "kis_adjustment_layer.h"
@@ -145,6 +146,7 @@ public:
     double yres = 1.0;
 
     const KoColorSpace * colorSpace;
+    KisProofingConfiguration *proofingConfig = 0;
 
     KisSelectionSP deselectedGlobalSelection;
     KisGroupLayerSP rootLayer; // The layers are contained in here
@@ -1594,3 +1596,18 @@ KisImageAnimationInterface* KisImage::animationInterface() const
 {
     return m_d->animationInterface;
 }
+
+void KisImage::setProofingConfiguration(KisProofingConfiguration *proofingConfig)
+{
+    m_d->proofingConfig = proofingConfig;
+    emit sigProofingConfigChanged();
+}
+
+KisProofingConfiguration *KisImage::proofingConfiguration() const
+{
+    if (!m_d->proofingConfig) {
+        KisImageConfig cfg;
+        m_d->proofingConfig = cfg.defaultProofingconfiguration();
+    }
+    return m_d->proofingConfig;
+}
diff --git a/libs/image/kis_image.h b/libs/image/kis_image.h
index f0c84a1..ae55056 100644
--- a/libs/image/kis_image.h
+++ b/libs/image/kis_image.h
@@ -53,7 +53,7 @@ class KisLayerComposition;
 class KisSpontaneousJob;
 class KisImageAnimationInterface;
 class KUndo2MagicString;
-
+class KisProofingConfiguration;
 
 namespace KisMetaData
 {
@@ -563,6 +563,18 @@ public:
 
     KisImageAnimationInterface *animationInterface() const;
 
+    /**
+     * @brief setProofingConfiguration, this sets the image's proofing configuration, and signals
+     * the proofingConfiguration has changed.
+     * @param proofingConfig - the kis proofing config that will be used instead.
+     */
+    void setProofingConfiguration(KisProofingConfiguration *proofingConfig);
+    /**
+     * @brief proofingConfiguration
+     * @return the proofing configuration of the image.
+     */
+    KisProofingConfiguration *proofingConfiguration() const;
+
 public:
     bool startIsolatedMode(KisNodeSP node);
     void stopIsolatedMode();
@@ -709,6 +721,12 @@ Q_SIGNALS:
      */
     void sigNodeCollapsedChanged();
 
+    /**
+     * Emitted when the proofing configuration of the image is being changed.
+     *
+     */
+    void sigProofingConfigChanged();
+
 public Q_SLOTS:
     KisCompositeProgressProxy* compositeProgressProxy();
 
diff --git a/libs/image/kis_image_config.cpp b/libs/image/kis_image_config.cpp
index dcbb882..af82e61 100644
--- a/libs/image/kis_image_config.cpp
+++ b/libs/image/kis_image_config.cpp
@@ -21,6 +21,9 @@
 #include <ksharedconfig.h>
 
 #include <KoConfig.h>
+#include <KoColorProfile.h>
+#include <KoColorSpaceRegistry.h>
+#include <KoColorConversionTransformation.h>
 
 #include "kis_debug.h"
 
@@ -394,3 +397,38 @@ void KisImageConfig::setShowAdditionalOnionSkinsSettings(bool value)
 {
     m_config.writeEntry("showAdditionalOnionSkinsSettings", value);
 }
+
+KisProofingConfiguration *KisImageConfig::defaultProofingconfiguration()
+{
+    KisProofingConfiguration *proofingConfig= new KisProofingConfiguration();
+    proofingConfig->proofingProfile = m_config.readEntry("defaultProofingProfileName", "Chemical proof");
+    proofingConfig->proofingModel = m_config.readEntry("defaultProofingProfileModel", "CMYKA");
+    proofingConfig->proofingDepth = m_config.readEntry("defaultProofingProfileDepth", "U8");
+    proofingConfig->intent = (KoColorConversionTransformation::Intent)m_config.readEntry("defaultProofingProfileIntent", 3);
+    if (m_config.readEntry("defaultProofingBlackpointCompensation", true)) {
+        proofingConfig->conversionFlags  |= KoColorConversionTransformation::ConversionFlag::BlackpointCompensation;
+    } else {
+                proofingConfig->conversionFlags  = proofingConfig->conversionFlags & ~KoColorConversionTransformation::ConversionFlag::BlackpointCompensation;
+    }
+    QColor def;
+    def =  m_config.readEntry("defaultProofingGamutwarning", QColor(Qt::gray));
+    KoColor col(KoColorSpaceRegistry::instance()->rgb8());
+    col.fromQColor(def);
+    col.setOpacity(1.0);
+    proofingConfig->warningColor = col;
+    proofingConfig->adaptationState = (double)m_config.readEntry("defaultProofingAdaptationState", 1.0);
+    return proofingConfig;
+}
+
+void KisImageConfig::setDefaultProofingConfig(const KoColorSpace *proofingSpace, int proofingIntent, bool blackPointCompensation, KoColor warningColor, double adaptationState)
+{
+    m_config.writeEntry("defaultProofingProfileName", proofingSpace->profile()->name());
+    m_config.writeEntry("defaultProofingProfileModel", proofingSpace->colorModelId().id());
+    m_config.writeEntry("defaultProofingProfileDepth", proofingSpace->colorDepthId().id());
+    m_config.writeEntry("defaultProofingProfileIntent", proofingIntent);
+    m_config.writeEntry("defaultProofingBlackpointCompensation", blackPointCompensation);
+    QColor c;
+    warningColor.toQColor(&c);
+    m_config.writeEntry("defaultProofingGamutwarning", c);
+    m_config.writeEntry("defaultProofingAdaptationState",adaptationState);
+}
diff --git a/libs/image/kis_image_config.h b/libs/image/kis_image_config.h
index 30ec4c2..aab52a9 100644
--- a/libs/image/kis_image_config.h
+++ b/libs/image/kis_image_config.h
@@ -21,6 +21,7 @@
 
 #include <kconfiggroup.h>
 #include "kritaimage_export.h"
+#include "KisProofingConfiguration.h"
 
 
 class KRITAIMAGE_EXPORT KisImageConfig
@@ -101,6 +102,10 @@ public:
     bool showAdditionalOnionSkinsSettings(bool requestDefault = false) const;
     void setShowAdditionalOnionSkinsSettings(bool value);
 
+    KisProofingConfiguration *defaultProofingconfiguration();
+    void setDefaultProofingConfig(const KoColorSpace *proofingSpace, int proofingIntent, bool blackPointCompensation, KoColor warningColor, double adaptationState);
+
+
 private:
     Q_DISABLE_COPY(KisImageConfig)
 
diff --git a/libs/pigment/CMakeLists.txt b/libs/pigment/CMakeLists.txt
index f72e516..67d1e68 100644
--- a/libs/pigment/CMakeLists.txt
+++ b/libs/pigment/CMakeLists.txt
@@ -47,6 +47,7 @@ set(kritapigment_SRCS
     KoColorConversions.cpp
     KoColorConversionSystem.cpp
     KoColorConversionTransformation.cpp
+    KoColorProofingConversionTransformation.cpp
     KoColorConversionTransformationFactory.cpp
     KoColorModelStandardIds.cpp
     KoColorProfile.cpp
diff --git a/libs/pigment/KoColorConversionTransformationAbstractFactory.h b/libs/pigment/KoColorConversionTransformationAbstractFactory.h
index 2befd1d..449648e 100644
--- a/libs/pigment/KoColorConversionTransformationAbstractFactory.h
+++ b/libs/pigment/KoColorConversionTransformationAbstractFactory.h
@@ -23,12 +23,14 @@
 #include "kritapigment_export.h"
 
 #include <KoColorConversionTransformation.h>
+#include <KoColorProofingConversionTransformation.h>
 
 class KRITAPIGMENT_EXPORT KoColorConversionTransformationAbstractFactory
 {
 public:
     KoColorConversionTransformationAbstractFactory() {}
     virtual ~KoColorConversionTransformationAbstractFactory() {}
+
     /**
      * Creates a color transformation between the source color space and the destination
      * color space.
@@ -40,6 +42,27 @@ public:
                                                                        const KoColorSpace* dstColorSpace,
                                                                        KoColorConversionTransformation::Intent renderingIntent,
                                                                        KoColorConversionTransformation::ConversionFlags conversionFlags) const = 0;
+
+    virtual KoColorProofingConversionTransformation* createColorProofingTransformation(const KoColorSpace* srcColorSpace,
+                                                                       const KoColorSpace* dstColorSpace,
+                                                                       const KoColorSpace* proofingSpace,
+                                                                       KoColorProofingConversionTransformation::Intent renderingIntent,
+                                                                       KoColorProofingConversionTransformation::Intent proofingIntent,
+                                                                       KoColorProofingConversionTransformation::ConversionFlags conversionFlags,
+                                                                       quint8 *gamutWarning,
+                                                                       double adaptationState) const
+    {
+        Q_UNUSED(srcColorSpace);
+        Q_UNUSED(dstColorSpace);
+        Q_UNUSED(proofingSpace);
+        Q_UNUSED(renderingIntent);
+        Q_UNUSED(proofingIntent);
+        Q_UNUSED(conversionFlags);
+        Q_UNUSED(gamutWarning);
+        Q_UNUSED(adaptationState);
+        qFatal("createColorProofinTransform undefined.");
+        return 0;
+    }
 };
 
 #endif
diff --git a/libs/pigment/KoColorProofingConversionTransformation.cpp b/libs/pigment/KoColorProofingConversionTransformation.cpp
new file mode 100644
index 0000000..5c16b41
--- /dev/null
+++ b/libs/pigment/KoColorProofingConversionTransformation.cpp
@@ -0,0 +1,49 @@
+/*
+ *  Copyright (c) 2007 Cyrille Berger <cberger at cberger.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include "KoColorProofingConversionTransformation.h"
+
+#include "KoColorSpace.h"
+
+
+KoColorProofingConversionTransformation::KoColorProofingConversionTransformation(const KoColorSpace* srcCs,
+                                                                 const KoColorSpace* dstCs,
+                                                                 const KoColorSpace* proofingSpace,
+                                                                 Intent renderingIntent,
+                                                                 Intent proofingIntent,
+                                                                 ConversionFlags conversionFlags,
+                                                                 quint8 *gamutWarning,
+                                                                 double adaptationState)
+    : KoColorConversionTransformation(srcCs, dstCs, renderingIntent, conversionFlags)
+{
+    Q_ASSERT(proofingSpace);
+    m_proofingIntent = proofingIntent;
+    m_gamutWarning = gamutWarning;
+    m_adaptationState = adaptationState;
+    m_proofingSpace = proofingSpace;
+}
+
+KoColorProofingConversionTransformation::~KoColorProofingConversionTransformation()
+{
+}
+
+const KoColorSpace* KoColorProofingConversionTransformation::proofingSpace() const
+{
+    return m_proofingSpace;
+}
diff --git a/libs/pigment/KoColorProofingConversionTransformation.h b/libs/pigment/KoColorProofingConversionTransformation.h
new file mode 100644
index 0000000..77915bc
--- /dev/null
+++ b/libs/pigment/KoColorProofingConversionTransformation.h
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (c) 2007 Cyrille Berger <cberger at cberger.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef _KO_COLOR_PROOFING_CONVERSION_TRANSFORMATION_H_
+#define _KO_COLOR_PROOFING_CONVERSION_TRANSFORMATION_H_
+
+#include "KoColorConversionTransformation.h"
+
+#include "kritapigment_export.h"
+
+class KoColorSpace;
+class KoColorConversionCache;
+
+/**
+ * This is the base class of all color transform that convert the color of a pixel
+ */
+class KRITAPIGMENT_EXPORT KoColorProofingConversionTransformation : public KoColorConversionTransformation
+{
+
+public:
+    KoColorProofingConversionTransformation(const KoColorSpace *srcCs,
+                                            const KoColorSpace *dstCs,
+                                            const KoColorSpace *proofingSpace,
+                                            Intent renderingIntent,
+                                            Intent proofingIntent,
+                                            ConversionFlags conversionFlags,
+                                            quint8 *gamutWarning,
+                                            double adaptationState);
+    virtual ~KoColorProofingConversionTransformation();
+
+public:
+
+    /**
+     * @brief proofingSpace
+     * @return the space that is used to proof the color transform
+     */
+    const KoColorSpace *proofingSpace() const;
+
+private:
+
+    Intent m_proofingIntent;
+    quint8 *m_gamutWarning;
+    double m_adaptationState;
+    const KoColorSpace *m_proofingSpace;
+};
+
+#endif
diff --git a/libs/pigment/KoColorSpace.cpp b/libs/pigment/KoColorSpace.cpp
index 238627b..6b71f92 100644
--- a/libs/pigment/KoColorSpace.cpp
+++ b/libs/pigment/KoColorSpace.cpp
@@ -36,6 +36,7 @@
 #include "KoMixColorsOp.h"
 #include "KoConvolutionOp.h"
 #include "KoCompositeOpRegistry.h"
+#include "KoColorSpaceEngine.h"
 
 #include <QThreadStorage>
 #include <QByteArray>
@@ -66,6 +67,7 @@ KoColorSpace::KoColorSpace(const QString &id, const QString &name, KoMixColorsOp
     d->TRCXYY = QPolygonF();
     d->colorants = QVector <qreal> (0);
     d->lumaCoefficients = QVector <qreal> (0);
+    d->iccEngine = 0;
     d->deletability = NotOwnedByRegistry;
 }
 
@@ -119,7 +121,7 @@ QPolygonF KoColorSpace::gamutXYY() const
         if ((colorModelId().id()=="CMYKA" || colorModelId().id()=="LABA") && colorDepthId().id()=="F32") {
             //boundaries for cmyka/laba have trouble getting the max values for Float, and are pretty awkward in general.
             max = this->channels()[0]->getUIMax();
-            
+
         }
         int samples = 5;//amount of samples in our color space.
         QString name = KoColorSpaceRegistry::instance()->colorSpaceFactory("XYZAF32")->defaultProfile();
@@ -175,7 +177,7 @@ QPolygonF KoColorSpace::gamutXYY() const
                         }
                     }
                 }
-                
+
             }
         }
         delete[] data;
@@ -230,7 +232,7 @@ QPolygonF KoColorSpace::estimatedTRCXYY() const
                 for (int j=0; j<5; j++){
                     channelValuesF.fill(0.0);
                     channelValuesF[i] = ((max/4)*(j));
-                    
+
                     fromNormalisedChannelsValue(data, channelValuesF);
 
                     convertPixelsTo(data, data2, xyzColorSpace, 1, KoColorConversionTransformation::IntentAbsoluteColorimetric,         KoColorConversionTransformation::adjustmentConversionFlags());
@@ -435,6 +437,26 @@ bool KoColorSpace::convertPixelsTo(const quint8 * src,
     return true;
 }
 
+KoColorConversionTransformation * KoColorSpace::createProofingTransform(const KoColorSpace *dstColorSpace, const KoColorSpace *proofingSpace, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::Intent proofingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags, quint8 *gamutWarning, double adaptationState) const
+{
+    if (!d->iccEngine) {
+        d->iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc");
+    }
+    if (!d->iccEngine) return 0;
+
+    return d->iccEngine->createColorProofingTransformation(this, dstColorSpace, proofingSpace, renderingIntent, proofingIntent, conversionFlags, gamutWarning, adaptationState);
+}
+
+bool KoColorSpace::proofPixelsTo(const quint8 *src,
+                                 quint8 *dst,
+                                 quint32 numPixels,
+                                 KoColorConversionTransformation *proofingTransform) const
+{
+    proofingTransform->transform(src, dst, numPixels);
+
+    //the transform is deleted in the destructor.
+    return true;
+}
 
 void KoColorSpace::bitBlt(const KoColorSpace* srcSpace, const KoCompositeOp::ParameterInfo& params, const KoCompositeOp* op,
                           KoColorConversionTransformation::Intent renderingIntent,
diff --git a/libs/pigment/KoColorSpace.h b/libs/pigment/KoColorSpace.h
index f29b8e9..a25f963 100644
--- a/libs/pigment/KoColorSpace.h
+++ b/libs/pigment/KoColorSpace.h
@@ -29,6 +29,7 @@
 
 #include "KoColorSpaceConstants.h"
 #include "KoColorConversionTransformation.h"
+#include "KoColorProofingConversionTransformation.h"
 #include "KoCompositeOp.h"
 #include <KoID.h>
 #include "kritapigment_export.h"
@@ -107,17 +108,17 @@ public:
      * maybe convert to 3d space in future?
      */
     QPolygonF gamutXYY() const;
-    
+
     /*
      * @returns a polygon with 5 samples per channel converted to xyY, but unlike
      * gamutxyY it focuses on the luminance. This then can be used to visualise
      * the approximate trc of a given colorspace.
      */
     QPolygonF estimatedTRCXYY() const;
-    
+
     QVector <qreal> colorants() const;
     QVector <qreal> lumaCoefficients() const;
-    
+
     //========== Channels =====================================================//
 
     /// Return a list describing all the channels this color model has. The order
@@ -371,6 +372,31 @@ public:
                                  KoColorConversionTransformation::Intent renderingIntent,
                                  KoColorConversionTransformation::ConversionFlags conversionFlags) const;
 
+    virtual KoColorConversionTransformation *createProofingTransform(const KoColorSpace * dstColorSpace,
+                                                             const KoColorSpace * proofingSpace,
+                                                             KoColorConversionTransformation::Intent renderingIntent,
+                                                             KoColorConversionTransformation::Intent proofingIntent,
+                                                             KoColorConversionTransformation::ConversionFlags conversionFlags,
+                                                             quint8 *gamutWarning, double adaptationState) const;
+    /**
+     * @brief proofPixelsTo
+     * @param src
+     * @param dst
+     * @param dstColorSpace the colorspace to which we go to.
+     * @param proofingSpace the proofing space.
+     * @param numPixels the amount of pixels.
+     * @param renderingIntent the rendering intent used for rendering.
+     * @param proofingIntent the intent used for proofing.
+     * @param conversionFlags the conversion flags.
+     * @param gamutWarning the data() of a KoColor.
+     * @param adaptationState the state of adaptation, only affects absolute colorimetric.
+     * @return
+     */
+    virtual bool proofPixelsTo(const quint8 * src,
+                               quint8 * dst,
+                               quint32 numPixels,
+                               KoColorConversionTransformation *proofingTransform) const;
+
 //============================== Manipulation functions ==========================//
 
 
diff --git a/libs/pigment/KoColorSpaceEngine.h b/libs/pigment/KoColorSpaceEngine.h
index defba56..115a8a6 100644
--- a/libs/pigment/KoColorSpaceEngine.h
+++ b/libs/pigment/KoColorSpaceEngine.h
@@ -45,6 +45,7 @@ public:
     const QString& name() const;
     virtual void addProfile(const QString &filename) = 0;
     virtual void removeProfile(const QString &filename) = 0;
+
 private:
     struct Private;
     Private* const d;
diff --git a/libs/pigment/KoColorSpace_p.h b/libs/pigment/KoColorSpace_p.h
index 1a82f24..c8e1323 100644
--- a/libs/pigment/KoColorSpace_p.h
+++ b/libs/pigment/KoColorSpace_p.h
@@ -21,6 +21,8 @@
 #define _KOCOLORSPACE_P_H_
 
 #include "KoColorSpace.h"
+#include "KoColorSpaceEngine.h"
+#include "KoColorConversionTransformation.h"
 #include <QThreadStorage>
 #include <QPolygonF>
 
@@ -45,6 +47,8 @@ struct Q_DECL_HIDDEN KoColorSpace::Private {
     QVector <qreal> colorants;
     QVector <qreal> lumaCoefficients;
 
+    KoColorSpaceEngine *iccEngine;
+
     Deletability deletability;
 };
 
diff --git a/libs/ui/KisView.cpp b/libs/ui/KisView.cpp
index b606976..d56bd46 100644
--- a/libs/ui/KisView.cpp
+++ b/libs/ui/KisView.cpp
@@ -147,6 +147,9 @@ public:
     QPointer<KisFloatingMessage> savedFloatingMessage;
     KisSignalCompressor floatingMessageCompressor;
 
+    bool softProofing = false;
+    bool gamutCheck = false;
+
     // Hmm sorry for polluting the private class with such a big inner class.
     // At the beginning it was a little struct :)
     class StatusBarItem
@@ -805,6 +808,58 @@ KisSelectionSP KisView::selection()
     return 0;
 }
 
+void KisView::slotSoftProofing(bool softProofing)
+{
+    d->softProofing = softProofing;
+    QString message;
+    if (canvasBase()->image()->colorSpace()->colorDepthId().id().contains("F"))
+    {
+        message = i18n("Soft Proofing doesn't work in floating point.");
+        viewManager()->showFloatingMessage(message,QIcon());
+        return;
+    }
+    if (softProofing){
+        message = i18n("Soft Proofing turned on.");
+    } else {
+        message = i18n("Soft Proofing turned off.");
+    }
+    viewManager()->showFloatingMessage(message,QIcon());
+    canvasBase()->slotSoftProofing(softProofing);
+}
+
+void KisView::slotGamutCheck(bool gamutCheck)
+{
+    d->gamutCheck = gamutCheck;
+    QString message;
+    if (canvasBase()->image()->colorSpace()->colorDepthId().id().contains("F"))
+    {
+        message = i18n("Gamut Warnings don't work in floating point.");
+        viewManager()->showFloatingMessage(message,QIcon());
+        return;
+    }
+
+    if (gamutCheck){
+        message = i18n("Gamut Warnings turned on.");
+        if (!d->softProofing){
+            message += "\n "+i18n("But Soft Proofing is still off.");
+        }
+    } else {
+        message = i18n("Gamut Warnings turned off.");
+    }
+    viewManager()->showFloatingMessage(message,QIcon());
+    canvasBase()->slotGamutCheck(gamutCheck);
+}
+
+bool KisView::softProofing()
+{
+    return d->softProofing;
+}
+
+bool KisView::gamutCheck()
+{
+    return d->gamutCheck;
+}
+
 void KisView::slotLoadingFinished()
 {
     if (!document()) return;
diff --git a/libs/ui/KisView.h b/libs/ui/KisView.h
index acf2c27..03902f3 100644
--- a/libs/ui/KisView.h
+++ b/libs/ui/KisView.h
@@ -192,6 +192,16 @@ public:
     KisNodeSP currentNode() const;
     KisLayerSP currentLayer() const;
     KisMaskSP currentMask() const;
+    /**
+     * @brief softProofing
+     * @return whether or not we're softproofing in this view.
+     */
+    bool softProofing();
+    /**
+     * @brief gamutCheck
+     * @return whether or not we're using gamut warnings in this view.
+     */
+    bool gamutCheck();
 
     /// Convenience method to get at the active selection (the
     /// selection of the current layer, or, if that does not exist,
@@ -216,6 +226,16 @@ public Q_SLOTS:
      * @todo rename to something more generic
      */
     void slotClearStatusText();
+    /**
+     * @brief slotSoftProofing set whether or not we're softproofing in this view.
+     * Will be setting the same in the canvas belonging to the view.
+     */
+    void slotSoftProofing(bool softProofing);
+    /**
+     * @brief slotGamutCheck set whether or not we're gamutchecking in this view.
+     * Will be setting the same in the vans belonging to the view.
+     */
+    void slotGamutCheck(bool gamutCheck);
 
     bool queryClose();
 
@@ -254,6 +274,7 @@ public Q_SLOTS:
     void slotImageResolutionChanged();
     void slotImageSizeChanged(const QPointF &oldStillPoint, const QPointF &newStillPoint);
 
+
 private:
 
     class Private;
diff --git a/libs/ui/KisViewManager.cpp b/libs/ui/KisViewManager.cpp
index 26517f2..bf410d7 100644
--- a/libs/ui/KisViewManager.cpp
+++ b/libs/ui/KisViewManager.cpp
@@ -208,6 +208,8 @@ public:
     KisAction *zoomTo100pct;
     KisAction *zoomIn;
     KisAction *zoomOut;
+    KisAction *softProof;
+    KisAction *gamutCheck;
 
     KisSelectionManager selectionManager;
     KisGuidesManager guidesManager;
@@ -356,6 +358,9 @@ void KisViewManager::setCurrentView(KisView *view)
 
     }
 
+    d->softProof->setChecked(view->softProofing());
+    d->gamutCheck->setChecked(view->gamutCheck());
+
     QPointer<KisView>imageView = qobject_cast<KisView*>(view);
 
     if (imageView) {
@@ -384,6 +389,9 @@ void KisViewManager::setCurrentView(KisView *view)
         d->viewConnections.addUniqueConnection(d->zoomIn, SIGNAL(triggered()), imageView->zoomController()->zoomAction(), SLOT(zoomIn()));
         d->viewConnections.addUniqueConnection(d->zoomOut, SIGNAL(triggered()), imageView->zoomController()->zoomAction(), SLOT(zoomOut()));
 
+        d->viewConnections.addUniqueConnection(d->softProof, SIGNAL(toggled(bool)), view, SLOT(slotSoftProofing(bool)) );
+        d->viewConnections.addUniqueConnection(d->gamutCheck, SIGNAL(toggled(bool)), view, SLOT(slotGamutCheck(bool)) );
+
         imageView->zoomManager()->setShowRulers(d->showRulersAction->isChecked());
         imageView->zoomManager()->setRulersTrackMouse(d->rulersTrackMouseAction->isChecked());
 
@@ -602,6 +610,8 @@ void KisViewManager::createActions()
     d->resetCanvasRotation = actionManager()->createAction("reset_canvas_rotation");
     d->wrapAroundAction    = actionManager()->createAction("wrap_around_mode");
     d->levelOfDetailAction = actionManager()->createAction("level_of_detail_mode");
+    d->softProof           = actionManager()->createAction("softProof");
+    d->gamutCheck          = actionManager()->createAction("gamutCheck");
 
     KisAction *tAction = actionManager()->createAction("showStatusBar");
     tAction->setChecked(cfg.showStatusBar());
diff --git a/libs/ui/canvas/kis_canvas2.cpp b/libs/ui/canvas/kis_canvas2.cpp
index d51879d..d532126 100644
--- a/libs/ui/canvas/kis_canvas2.cpp
+++ b/libs/ui/canvas/kis_canvas2.cpp
@@ -74,6 +74,9 @@
 #include "opengl/kis_opengl.h"
 #include "kis_fps_decoration.h"
 
+#include "KoColorConversionTransformation.h"
+#include "KisProofingConfiguration.h"
+
 #include <kis_favorite_resource_manager.h>
 #include <kis_popup_palette.h>
 
@@ -110,6 +113,10 @@ public:
     QRect savedUpdateRect;
 
     QBitArray channelFlags;
+    KisProofingConfiguration *proofingConfig = 0;
+    bool softProofing = false;
+    bool gamutCheck = false;
+    bool proofingConfigUpdated = false;
 
     KisPopupPalette *popupPalette = 0;
     KisDisplayColorConverter displayColorConverter;
@@ -180,7 +187,6 @@ void KisCanvas2::setup()
     connect(kritaShapeController, SIGNAL(currentLayerChanged(const KoShapeLayer*)),
             globalShapeManager()->selection(), SIGNAL(currentLayerChanged(const KoShapeLayer*)));
 
-
     connect(&m_d->updateSignalCompressor, SIGNAL(timeout()), SLOT(slotDoCanvasUpdate()));
 }
 
@@ -453,6 +459,7 @@ void KisCanvas2::initializeImage()
 
     connect(image, SIGNAL(sigImageUpdated(QRect)), SLOT(startUpdateCanvasProjection(QRect)), Qt::DirectConnection);
     connect(this, SIGNAL(sigCanvasCacheUpdated()), SLOT(updateCanvasProjection()));
+    connect(image, SIGNAL(sigProofingConfigChanged()), SLOT(slotChangeProofingConfig()));
     connect(image, SIGNAL(sigSizeChanged(const QPointF&, const QPointF&)), SLOT(startResizingImage()), Qt::DirectConnection);
     connect(this, SIGNAL(sigContinueResizeImage(qint32,qint32)), SLOT(finishResizingImage(qint32,qint32)));
 
@@ -544,6 +551,73 @@ KisExposureGammaCorrectionInterface* KisCanvas2::exposureGammaCorrectionInterfac
         KisDumbExposureGammaCorrectionInterface::instance();
 }
 
+void KisCanvas2::setProofingOptions(bool softProof, bool gamutCheck)
+{
+    m_d->proofingConfig = this->image()->proofingConfiguration();
+    if (!m_d->proofingConfig) {
+        qDebug()<<"Canvas: No proofing config found, generating one.";
+        KisImageConfig cfg;
+        m_d->proofingConfig = cfg.defaultProofingconfiguration();
+    }
+    KoColorConversionTransformation::ConversionFlags conversionFlags = m_d->proofingConfig->conversionFlags;
+
+    if (softProof && this->image()->colorSpace()->colorDepthId().id().contains("U")) {
+        conversionFlags |= KoColorConversionTransformation::SoftProofing;
+    } else {
+        conversionFlags = conversionFlags &  ~KoColorConversionTransformation::SoftProofing;
+    }
+    if (gamutCheck && softProof && this->image()->colorSpace()->colorDepthId().id().contains("U")) {
+        conversionFlags |= KoColorConversionTransformation::GamutCheck;
+    } else {
+        conversionFlags = conversionFlags & ~KoColorConversionTransformation::GamutCheck;
+    }
+    m_d->proofingConfig->conversionFlags = conversionFlags;
+
+    m_d->proofingConfigUpdated = true;
+    startUpdateInPatches(this->image()->bounds());
+
+}
+
+void KisCanvas2::slotSoftProofing(bool softProofing)
+{
+    m_d->softProofing = softProofing;
+    setProofingOptions(m_d->softProofing, m_d->gamutCheck);
+}
+
+void KisCanvas2::slotGamutCheck(bool gamutCheck)
+{
+    m_d->gamutCheck = gamutCheck;
+    setProofingOptions(m_d->softProofing, m_d->gamutCheck);
+}
+
+void KisCanvas2::slotChangeProofingConfig()
+{
+    setProofingOptions(m_d->softProofing, m_d->gamutCheck);
+}
+
+void KisCanvas2::setProofingConfigUpdated(bool updated)
+{
+    m_d->proofingConfigUpdated = updated;
+}
+
+bool KisCanvas2::proofingConfigUpdated()
+{
+    return m_d->proofingConfigUpdated;
+}
+
+KisProofingConfiguration *KisCanvas2::proofingConfiguration() const
+{
+    if (!m_d->proofingConfig) {
+        m_d->proofingConfig = this->image()->proofingConfiguration();
+        if (!m_d->proofingConfig) {
+            qDebug()<<"Canvas: No proofing config found, generating one.";
+            KisImageConfig cfg;
+            m_d->proofingConfig = cfg.defaultProofingconfiguration();
+        }
+    }
+    return m_d->proofingConfig;
+}
+
 void KisCanvas2::startResizingImage()
 {
     KisImageWSP image = this->image();
diff --git a/libs/ui/canvas/kis_canvas2.h b/libs/ui/canvas/kis_canvas2.h
index 93b0c18..36d2ae7 100644
--- a/libs/ui/canvas/kis_canvas2.h
+++ b/libs/ui/canvas/kis_canvas2.h
@@ -74,7 +74,7 @@ public:
      * @param viewConverter the viewconverter for converting between
      *                       window and document coordinates.
      */
-    KisCanvas2(KisCoordinatesConverter* coordConverter, KoCanvasResourceManager *resourceManager, KisView *view, KoShapeBasedDocumentBase* sc);
+    KisCanvas2(KisCoordinatesConverter *coordConverter, KoCanvasResourceManager *resourceManager, KisView *view, KoShapeBasedDocumentBase *sc);
 
     virtual ~KisCanvas2();
 
@@ -164,8 +164,25 @@ public: // KisCanvas2 methods
     void setDisplayFilter(KisDisplayFilter *displayFilter);
     KisDisplayFilter *displayFilter() const;
 
-    KisDisplayColorConverter* displayColorConverter() const;
+    KisDisplayColorConverter *displayColorConverter() const;
     KisExposureGammaCorrectionInterface* exposureGammaCorrectionInterface() const;
+    /**
+     * @brief setProofingOptions
+     * set the options for softproofing, without affecting the proofing options as stored inside the image.
+     */
+    void setProofingOptions(bool softProof, bool gamutCheck);
+    KisProofingConfiguration *proofingConfiguration() const;
+    /**
+     * @brief setProofingConfigUpdated This function is to set whether the proofing config is updated,
+     * this is needed for determining whether or not to generate a new proofing transform.
+     * @param updated whether it's updated. Just set it to false in normal usage.
+     */
+    void setProofingConfigUpdated(bool updated);
+    /**
+     * @brief proofingConfigUpdated ask the canvas whether or not it updated the proofing config.
+     * @return whether or not the proofing config is updated, if so, a new proofing transform needs to be made
+     * in KisOpenGL canvas.
+     */bool proofingConfigUpdated();
 
     void setCursor(const QCursor &cursor);
     KisAnimationFrameCacheSP frameCache() const;
@@ -196,6 +213,9 @@ public Q_SLOTS:
     /// Bools indicating canvasmirroring.
     bool xAxisMirrored() const;
     bool yAxisMirrored() const;
+    void slotSoftProofing(bool softProofing);
+    void slotGamutCheck(bool gamutCheck);
+    void slotChangeProofingConfig();
 
     void channelSelectionChanged();
 
diff --git a/libs/ui/dialogs/kis_dlg_image_properties.cc b/libs/ui/dialogs/kis_dlg_image_properties.cc
index 8a795e5..244cb97 100644
--- a/libs/ui/dialogs/kis_dlg_image_properties.cc
+++ b/libs/ui/dialogs/kis_dlg_image_properties.cc
@@ -33,7 +33,9 @@
 
 #include <KoColorSpace.h>
 #include "KoColorProfile.h"
+#include "KoColorSpaceRegistry.h"
 #include "KoColor.h"
+#include "KoColorConversionTransformation.h"
 #include "KoColorPopupAction.h"
 #include "kis_icon_utils.h"
 #include "KoID.h"
@@ -66,9 +68,9 @@ KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, QWidget *parent,
 
     m_page->lblResolutionValue->setText(QLocale().toString(image->xRes()*72, 2)); // XXX: separate values for x & y?
 
+    //Set the canvas projection color:
     m_defaultColorAction = new KoColorPopupAction(this);
     m_defaultColorAction->setCurrentColor(m_image->defaultProjectionColor());
-    m_defaultColorAction->setIcon(KisIconUtils::loadIcon("format-stroke-color"));
     m_defaultColorAction->setToolTip(i18n("Change the background color of the image"));
     m_page->bnBackgroundColor->setDefaultAction(m_defaultColorAction);
 
@@ -78,8 +80,36 @@ KisDlgImageProperties::KisDlgImageProperties(KisImageWSP image, QWidget *parent,
 
     connect(m_defaultColorAction, SIGNAL(colorChanged(const KoColor&)), this, SLOT(setCurrentColor()));
 
+    //Set the color space
     m_page->colorSpaceSelector->setCurrentColorSpace(image->colorSpace());
 
+    //set the proofing space
+    m_proofingConfig = m_image->proofingConfiguration();
+    m_page->proofSpaceSelector->setCurrentColorSpace(KoColorSpaceRegistry::instance()->colorSpace(m_proofingConfig->proofingModel, m_proofingConfig->proofingDepth,m_proofingConfig->proofingProfile));
+
+    m_page->cmbIntent->setCurrentIndex((int)m_proofingConfig->intent);
+
+    m_page->ckbBlackPointComp->setChecked(m_proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
+
+    m_gamutWarning = new KoColorPopupAction(this);
+    m_gamutWarning->setCurrentColor(m_proofingConfig->warningColor);
+    m_gamutWarning->setToolTip(i18n("Set color used for warning"));
+    m_page->gamutAlarm->setDefaultAction(m_gamutWarning);
+    m_page->sldAdaptationState->setMaximum(20);
+    m_page->sldAdaptationState->setMinimum(0);
+    m_page->sldAdaptationState->setValue((int)m_proofingConfig->adaptationState*20);
+
+    KisSignalCompressor *softProofConfigCompressor = new KisSignalCompressor(500, KisSignalCompressor::POSTPONE,this);
+
+    connect(m_gamutWarning, SIGNAL(colorChanged(KoColor)), softProofConfigCompressor, SLOT(start()));
+    connect(m_page->proofSpaceSelector, SIGNAL(colorSpaceChanged(const KoColorSpace*)), softProofConfigCompressor, SLOT(start()));
+    connect(m_page->cmbIntent, SIGNAL(currentIndexChanged(int)), softProofConfigCompressor, SLOT(start()));
+    connect(m_page->ckbBlackPointComp, SIGNAL(stateChanged(int)), softProofConfigCompressor, SLOT(start()));
+    connect(m_page->sldAdaptationState, SIGNAL(valueChanged(int)), softProofConfigCompressor, SLOT(start()));
+
+    connect(softProofConfigCompressor, SIGNAL(timeout()), this, SLOT(setProofingConfig()));
+
+    //annotations
     vKisAnnotationSP_it beginIt = image->beginAnnotations();
     vKisAnnotationSP_it endIt = image->endAnnotations();
 
@@ -115,6 +145,20 @@ void KisDlgImageProperties::setCurrentColor()
     KisLayerUtils::changeImageDefaultProjectionColor(m_image, m_defaultColorAction->currentKoColor());
 }
 
+void KisDlgImageProperties::setProofingConfig()
+{
+    m_proofingConfig->conversionFlags = KoColorConversionTransformation::HighQuality;
+    if (m_page->ckbBlackPointComp) m_proofingConfig->conversionFlags |= KoColorConversionTransformation::BlackpointCompensation;
+    m_proofingConfig->intent = (KoColorConversionTransformation::Intent)m_page->cmbIntent->currentIndex();
+    m_proofingConfig->proofingProfile = m_page->proofSpaceSelector->currentColorSpace()->profile()->name();
+    m_proofingConfig->proofingModel = m_page->proofSpaceSelector->currentColorSpace()->colorModelId().id();
+    m_proofingConfig->proofingDepth = "U8";//default to this
+    m_proofingConfig->warningColor = m_gamutWarning->currentKoColor();
+    m_proofingConfig->adaptationState = (double)m_page->sldAdaptationState->value()/20.0;
+    qDebug()<<"set proofing config in properties: "<<m_proofingConfig->proofingProfile;
+    m_image->setProofingConfiguration(m_proofingConfig);
+}
+
 void KisDlgImageProperties::setAnnotation(const QString &type)
 {
     KisAnnotationSP annotation = m_image->annotation(type);
diff --git a/libs/ui/dialogs/kis_dlg_image_properties.h b/libs/ui/dialogs/kis_dlg_image_properties.h
index eff9da1..5302ea6 100644
--- a/libs/ui/dialogs/kis_dlg_image_properties.h
+++ b/libs/ui/dialogs/kis_dlg_image_properties.h
@@ -19,7 +19,7 @@
 #define KIS_DLG_IMAGE_PROPERTIES_H_
 
 #include <KoDialog.h>
-
+#include "KisProofingConfiguration.h"
 #include <kis_types.h>
 #include "ui_wdgimageproperties.h"
 
@@ -53,11 +53,14 @@ private Q_SLOTS:
 
     void setAnnotation(const QString& type);
     void setCurrentColor();
+    void setProofingConfig();
 private:
 
     WdgImageProperties * m_page;
     KisImageWSP m_image;
     KoColorPopupAction *m_defaultColorAction;
+    KoColorPopupAction *m_gamutWarning;
+    KisProofingConfiguration *m_proofingConfig;
 };
 
 
diff --git a/libs/ui/dialogs/kis_dlg_preferences.cc b/libs/ui/dialogs/kis_dlg_preferences.cc
index 7e5cd57..6657074 100644
--- a/libs/ui/dialogs/kis_dlg_preferences.cc
+++ b/libs/ui/dialogs/kis_dlg_preferences.cc
@@ -64,11 +64,14 @@
 #include "widgets/kis_cmb_idlist.h"
 #include "KoColorSpace.h"
 #include "KoColorSpaceRegistry.h"
+#include "KoColorConversionTransformation.h"
 #include "kis_cursor.h"
 #include "kis_config.h"
 #include "kis_canvas_resource_provider.h"
 #include "kis_preference_set_registry.h"
 #include "kis_color_manager.h"
+#include "KisProofingConfiguration.h"
+#include "kis_image_config.h"
 
 #include "slider_and_spin_box_sync.h"
 
@@ -309,18 +312,10 @@ ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
     m_page->cmbWorkingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
     m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
 
-    m_page->cmbPrintingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
-    m_page->cmbPrintingColorSpace->setCurrent(cfg.printerColorSpace());
-
     m_page->bnAddColorProfile->setIcon(KisIconUtils::loadIcon("document-open"));
     m_page->bnAddColorProfile->setToolTip( i18n("Open Color Profile") );
     connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));
 
-    refillPrintProfiles(KoID(cfg.printerColorSpace(), ""));
-
-    //hide printing settings
-    m_page->groupBox2->hide();
-
     QGridLayout *monitorProfileGrid = new QGridLayout(m_page->monitorprofileholder);
     for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
         QLabel *lbl = new QLabel(i18nc("The number of the screen", "Screen %1:", i + 1));
@@ -339,12 +334,26 @@ ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
         }
     }
 
-    if (m_page->cmbPrintProfile->contains(cfg.printerProfile()))
-        m_page->cmbPrintProfile->setCurrentIndex(m_page->cmbPrintProfile->findText(cfg.printerProfile()));
-
     m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
     m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
 
+    KisImageConfig cfgImage;
+
+    KisProofingConfiguration *proofingConfig = cfgImage.defaultProofingconfiguration();
+    m_gamutWarning = new KoColorPopupAction(this);
+    m_gamutWarning->setToolTip(i18n("Set default color used for out of Gamut Warning"));
+    m_gamutWarning->setCurrentColor(proofingConfig->warningColor);
+    m_page->gamutAlarm->setDefaultAction(m_gamutWarning);
+    m_page->sldAdaptationState->setMaximum(20);
+    m_page->sldAdaptationState->setMinimum(0);
+    m_page->sldAdaptationState->setValue((int)proofingConfig->adaptationState*20);
+
+    const KoColorSpace *proofingSpace =  KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,proofingConfig->proofingDepth,proofingConfig->proofingProfile);
+    m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
+
+    m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
+    m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
+
     m_pasteBehaviourGroup.addButton(m_page->radioPasteWeb, PASTE_ASSUME_WEB);
     m_pasteBehaviourGroup.addButton(m_page->radioPasteMonitor, PASTE_ASSUME_MONITOR);
     m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, PASTE_ASK);
@@ -360,8 +369,6 @@ ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
 
     toggleAllowMonitorProfileSelection(cfg.useSystemMonitorProfile());
 
-    connect(m_page->cmbPrintingColorSpace, SIGNAL(activated(const KoID &)),
-            this, SLOT(refillPrintProfiles(const KoID &)));
 }
 
 void ColorSettingsTab::installProfile()
@@ -389,7 +396,6 @@ void ColorSettingsTab::installProfile()
 
     KisConfig cfg;
     refillMonitorProfiles(KoID("RGBA", ""));
-    refillPrintProfiles(KoID(cfg.printerColorSpace(), ""));
 
     for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
         if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
@@ -397,10 +403,6 @@ void ColorSettingsTab::installProfile()
         }
     }
 
-    if (m_page->cmbPrintProfile->contains(cfg.printerProfile()))
-        m_page->cmbPrintProfile->setCurrentIndex(m_page->cmbPrintProfile->findText(cfg.printerProfile()));
-
-
 }
 
 void ColorSettingsTab::toggleAllowMonitorProfileSelection(bool useSystemProfile)
@@ -438,12 +440,18 @@ void ColorSettingsTab::setDefault()
 {
     m_page->cmbWorkingColorSpace->setCurrent("RGBA");
 
-    m_page->cmbPrintingColorSpace->setCurrent("CMYK");
-    refillPrintProfiles(KoID("CMYK", ""));
-
     refillMonitorProfiles(KoID("RGBA", ""));
 
     KisConfig cfg;
+    KisImageConfig cfgImage;
+    KisProofingConfiguration *proofingConfig =  cfgImage.defaultProofingconfiguration();
+    const KoColorSpace *proofingSpace =  KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,proofingConfig->proofingDepth,proofingConfig->proofingProfile);
+    m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
+    m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
+    m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
+    m_page->sldAdaptationState->setValue(0);
+
+    m_gamutWarning->setCurrentColor(proofingConfig->warningColor);
 
     m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
     m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
@@ -485,24 +493,6 @@ void ColorSettingsTab::refillMonitorProfiles(const KoID & s)
     }
 }
 
-void ColorSettingsTab::refillPrintProfiles(const KoID & s)
-{
-    const KoColorSpaceFactory * csf = KoColorSpaceRegistry::instance()->colorSpaceFactory(s.id());
-
-    m_page->cmbPrintProfile->clear();
-
-    if (!csf)
-        return;
-
-    QList<const KoColorProfile *> profileList = KoColorSpaceRegistry::instance()->profilesFor(csf);
-
-    Q_FOREACH (const KoColorProfile *profile, profileList) {
-        if (profile->isSuitableForPrinting())
-            m_page->cmbPrintProfile->addSqueezedItem(profile->name());
-    }
-
-    m_page->cmbPrintProfile->setCurrent(csf->defaultProfile());
-}
 
 //---------------------------------------------------------------------------------------------------
 
@@ -532,7 +522,6 @@ TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget
 
 
 //---------------------------------------------------------------------------------------------------
-#include "kis_image_config.h"
 #include "kis_acyclic_signal_connector.h"
 
 int getTotalRAM() {
@@ -714,7 +703,6 @@ DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
     c.fromQColor(cfg.selectionOverlayMaskColor());
     m_selectionOverlayColorAction = new KoColorPopupAction(this);
     m_selectionOverlayColorAction->setCurrentColor(c);
-    m_selectionOverlayColorAction->setIcon(KisIconUtils::loadIcon("format-stroke-color"));
     m_selectionOverlayColorAction->setToolTip(i18n("Change the background color of the image"));
     btnSelectionOverlayColor->setDefaultAction(m_selectionOverlayColorAction);
 
@@ -1001,9 +989,9 @@ bool KisDlgPreferences::editPreferences()
             }
         }
         cfg.setWorkingColorSpace(dialog->m_colorSettings->m_page->cmbWorkingColorSpace->currentItem().id());
-        cfg.setPrinterColorSpace(dialog->m_colorSettings->m_page->cmbPrintingColorSpace->currentItem().id());
-        cfg.setPrinterProfile(dialog->m_colorSettings->m_page->cmbPrintProfile->itemHighlighted());
 
+        KisImageConfig cfgImage;
+        cfgImage.setDefaultProofingConfig(dialog->m_colorSettings->m_page->proofingSpaceSelector->currentColorSpace(), dialog->m_colorSettings->m_page->cmbProofingIntent->currentIndex(), dialog->m_colorSettings->m_page->ckbProofBlackPoint->isChecked(), dialog->m_colorSettings->m_gamutWarning->currentKoColor(), (double)dialog->m_colorSettings->m_page->sldAdaptationState->value()/20);
         cfg.setUseBlackPointCompensation(dialog->m_colorSettings->m_page->chkBlackpoint->isChecked());
         cfg.setAllowLCMSOptimization(dialog->m_colorSettings->m_page->chkAllowLCMSOptimization->isChecked());
         cfg.setPasteBehaviour(dialog->m_colorSettings->m_pasteBehaviourGroup.checkedId());
diff --git a/libs/ui/dialogs/kis_dlg_preferences.h b/libs/ui/dialogs/kis_dlg_preferences.h
index c4ec62e..ea04494 100644
--- a/libs/ui/dialogs/kis_dlg_preferences.h
+++ b/libs/ui/dialogs/kis_dlg_preferences.h
@@ -25,6 +25,7 @@
 #include <QWidget>
 
 #include <kpagedialog.h>
+#include "KoColorPopupAction.h"
 
 #include "kis_global.h"
 
@@ -149,13 +150,13 @@ public:
 private Q_SLOTS:
 
     void refillMonitorProfiles(const KoID & s);
-    void refillPrintProfiles(const KoID & s);
     void installProfile();
     void toggleAllowMonitorProfileSelection(bool useSystemProfile);
 
 public:
     void setDefault();
     WdgColorSettings  *m_page;
+    KoColorPopupAction *m_gamutWarning;
     QButtonGroup m_pasteBehaviourGroup;
     QList<QLabel*> m_monitorProfileLabels;
     QList<SqueezedComboBox*> m_monitorProfileWidgets;
diff --git a/libs/ui/forms/wdgcolorsettings.ui b/libs/ui/forms/wdgcolorsettings.ui
index 0fd8dda..0bbdca5 100644
--- a/libs/ui/forms/wdgcolorsettings.ui
+++ b/libs/ui/forms/wdgcolorsettings.ui
@@ -16,7 +16,16 @@
   <layout class="QVBoxLayout" name="verticalLayout_4">
    <item>
     <layout class="QHBoxLayout">
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -65,17 +74,35 @@
       </item>
       <item>
        <layout class="QHBoxLayout">
-        <property name="margin">
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
          <number>0</number>
         </property>
         <item>
-         <widget class="QWidget" name="monitorprofileholder"/>
+         <widget class="QWidget" name="monitorprofileholder" native="true"/>
         </item>
        </layout>
       </item>
       <item>
        <layout class="QHBoxLayout">
-        <property name="margin">
+        <property name="leftMargin">
+         <number>0</number>
+        </property>
+        <property name="topMargin">
+         <number>0</number>
+        </property>
+        <property name="rightMargin">
+         <number>0</number>
+        </property>
+        <property name="bottomMargin">
          <number>0</number>
         </property>
         <item>
@@ -154,56 +181,88 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox2">
+    <widget class="QGroupBox" name="grpProofingOptions">
      <property name="enabled">
       <bool>true</bool>
      </property>
      <property name="title">
-      <string>Printing</string>
+      <string>Soft Proof Options</string>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <layout class="QGridLayout" name="gridLayout_2">
-        <item row="0" column="0">
-         <widget class="QLabel" name="lbldefaultprinterspace">
-          <property name="text">
-           <string>Default printer color model:</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-         </widget>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="5" column="1">
+       <widget class="QToolButton" name="gamutAlarm">
+        <property name="text">
+         <string>...</string>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="0">
+       <widget class="QLabel" name="lblProofingIntent">
+        <property name="text">
+         <string>Proofing Rendering Intent:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="0" colspan="4">
+       <widget class="KisColorSpaceSelector" name="proofingSpaceSelector" native="true"/>
+      </item>
+      <item row="5" column="2" colspan="2">
+       <widget class="QCheckBox" name="ckbProofBlackPoint">
+        <property name="text">
+         <string>Back Point Compensation</string>
+        </property>
+       </widget>
+      </item>
+      <item row="5" column="0">
+       <widget class="QLabel" name="lblGamutWarning">
+        <property name="text">
+         <string>Gamut Warning:</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+       </widget>
+      </item>
+      <item row="3" column="1" colspan="3">
+       <widget class="QComboBox" name="cmbProofingIntent">
+        <item>
+         <property name="text">
+          <string>Perceptual</string>
+         </property>
         </item>
-        <item row="1" column="0">
-         <widget class="QLabel" name="textLabel4">
-          <property name="toolTip">
-           <string>The icm profile for your calibrated printer</string>
-          </property>
-          <property name="text">
-           <string>Default &printer profile:</string>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-          </property>
-          <property name="buddy">
-           <cstring>cmbPrintProfile</cstring>
-          </property>
-         </widget>
+        <item>
+         <property name="text">
+          <string>Relative Colorimetric</string>
+         </property>
         </item>
-        <item row="0" column="1">
-         <widget class="KisCmbIDList" name="cmbPrintingColorSpace">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-         </widget>
+        <item>
+         <property name="text">
+          <string>Saturation</string>
+         </property>
         </item>
-        <item row="1" column="1">
-         <widget class="SqueezedComboBox" name="cmbPrintProfile"/>
+        <item>
+         <property name="text">
+          <string>Absolute Colorimetric</string>
+         </property>
         </item>
-       </layout>
+       </widget>
+      </item>
+      <item row="4" column="1" colspan="3">
+       <widget class="QSlider" name="sldAdaptationState">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+       </widget>
+      </item>
+      <item row="4" column="0">
+       <widget class="QLabel" name="lblAdaptationState">
+        <property name="text">
+         <string>Adaptation State:</string>
+        </property>
+        <property name="alignment">
+         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+        </property>
+       </widget>
       </item>
      </layout>
     </widget>
@@ -250,7 +309,16 @@
      <property name="spacing">
       <number>6</number>
      </property>
-     <property name="margin">
+     <property name="leftMargin">
+      <number>0</number>
+     </property>
+     <property name="topMargin">
+      <number>0</number>
+     </property>
+     <property name="rightMargin">
+      <number>0</number>
+     </property>
+     <property name="bottomMargin">
       <number>0</number>
      </property>
      <item>
@@ -295,19 +363,25 @@
  </widget>
  <customwidgets>
   <customwidget>
+   <class>KisColorSpaceSelector</class>
+   <extends>QWidget</extends>
+   <header>widgets/kis_color_space_selector.h</header>
+   <container>1</container>
+  </customwidget>
+  <customwidget>
    <class>KComboBox</class>
    <extends>QComboBox</extends>
    <header>kcombobox.h</header>
   </customwidget>
   <customwidget>
-   <class>SqueezedComboBox</class>
+   <class>KisCmbIDList</class>
    <extends>QComboBox</extends>
-   <header>widgets/squeezedcombobox.h</header>
+   <header>widgets/kis_cmb_idlist.h</header>
   </customwidget>
   <customwidget>
-   <class>KisCmbIDList</class>
+   <class>SqueezedComboBox</class>
    <extends>QComboBox</extends>
-   <header>widgets/kis_cmb_idlist.h</header>
+   <header>widgets/squeezedcombobox.h</header>
   </customwidget>
  </customwidgets>
  <resources/>
diff --git a/libs/ui/forms/wdgimageproperties.ui b/libs/ui/forms/wdgimageproperties.ui
index ddc54d9..8a03c54 100644
--- a/libs/ui/forms/wdgimageproperties.ui
+++ b/libs/ui/forms/wdgimageproperties.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>448</width>
-    <height>340</height>
+    <height>568</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -138,31 +138,6 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="QGroupBox" name="grpMode">
-     <property name="title">
-      <string>Mode</string>
-     </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
-      <item>
-       <widget class="KisColorSpaceSelector" name="colorSpaceSelector"/>
-      </item>
-      <item>
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string><html><head/><body><p><span style=" font-weight:600;">Note:</span> This changes only the colorspace of the rendered image. To convert the colorspace of the layers, use Convert Image Colorspace.</p></body></html></string>
-        </property>
-        <property name="textFormat">
-         <enum>Qt::RichText</enum>
-        </property>
-        <property name="wordWrap">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
    <item row="2" column="0">
     <widget class="QGroupBox" name="grpAnnotations">
      <property name="title">
@@ -219,6 +194,129 @@
      </property>
     </spacer>
    </item>
+   <item row="1" column="0">
+    <widget class="QTabWidget" name="grpColorM">
+     <property name="currentIndex">
+      <number>0</number>
+     </property>
+     <widget class="QWidget" name="grpMode">
+      <attribute name="title">
+       <string>Image Color Space</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout">
+       <item>
+        <widget class="KisColorSpaceSelector" name="colorSpaceSelector" native="true"/>
+       </item>
+       <item>
+        <widget class="QLabel" name="label_2">
+         <property name="text">
+          <string><html><head/><body><p><span style=" font-weight:600;">Note:</span> This changes only the colorspace of the rendered image. To convert the colorspace of the layers, use Convert Image Colorspace.</p></body></html></string>
+         </property>
+         <property name="textFormat">
+          <enum>Qt::RichText</enum>
+         </property>
+         <property name="wordWrap">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="grpSoftProof">
+      <attribute name="title">
+       <string>Softproofing</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="3" column="1">
+        <widget class="QToolButton" name="gamutAlarm">
+         <property name="text">
+          <string>...</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="0">
+        <widget class="QLabel" name="lblGamutWarning">
+         <property name="text">
+          <string>Gamut Warning:</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QLabel" name="lblAdaptationState">
+         <property name="layoutDirection">
+          <enum>Qt::LeftToRight</enum>
+         </property>
+         <property name="text">
+          <string>Adaptation State:</string>
+         </property>
+         <property name="alignment">
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1" colspan="3">
+        <widget class="QSlider" name="sldAdaptationState">
+         <property name="toolTip">
+          <string><html><head/><body><p>Set how much you wish to correct the adaptation state. This will affect how <span style=" font-style:italic;">Absolute Colorimetric</span> changes the whites of your image. In Layman's terms: how much do you wish to have the color management correct the paper-color to screen white while using <span style=" font-style:italic;">Absolute Colorimetric</span>?</p></body></html></string>
+         </property>
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="2" colspan="2">
+        <widget class="QCheckBox" name="ckbBlackPointComp">
+         <property name="toolTip">
+          <string><html><head/><body><p>Black Point compensation matches the darkest color of the source device to the darkest color of the destination device. Relative Colorimetric without Black Point Compensation will show the difference between the darkest values. With blackpoint compensation, black is black.</p></body></html></string>
+         </property>
+         <property name="text">
+          <string>Black Point Compensation</string>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="0" colspan="4">
+        <widget class="KisColorSpaceSelector" name="proofSpaceSelector" native="true"/>
+       </item>
+       <item row="1" column="0" colspan="4">
+        <widget class="QGroupBox" name="groupBox">
+         <property name="title">
+          <string>Rendering Intent</string>
+         </property>
+         <layout class="QFormLayout" name="formLayout_2">
+          <item row="0" column="0" colspan="2">
+           <widget class="QComboBox" name="cmbIntent">
+            <property name="currentIndex">
+             <number>0</number>
+            </property>
+            <item>
+             <property name="text">
+              <string>Perceptual</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Relative Colorimetric</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Saturation</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Absolute Colorimetric</string>
+             </property>
+            </item>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
   </layout>
  </widget>
  <customwidgets>
diff --git a/libs/ui/kis_config.cc b/libs/ui/kis_config.cc
index 452b06b..61b7d92 100644
--- a/libs/ui/kis_config.cc
+++ b/libs/ui/kis_config.cc
@@ -33,6 +33,7 @@
 
 #include <KisDocument.h>
 
+#include <KoColor.h>
 #include <KoColorSpaceRegistry.h>
 #include <KoColorModelStandardIds.h>
 #include <KoColorProfile.h>
diff --git a/libs/ui/kis_config.h b/libs/ui/kis_config.h
index 51810c6..2d09bb2 100644
--- a/libs/ui/kis_config.h
+++ b/libs/ui/kis_config.h
@@ -479,7 +479,6 @@ public:
     QString customFFMpegPath(bool defaultValue = false) const;
     void setCustomFFMpegPath(const QString &value) const;
 
-
     template<class T>
     void writeEntry(const QString& name, const T& value) {
         m_cfg.writeEntry(name, value);
diff --git a/libs/ui/kra/kis_kra_loader.cpp b/libs/ui/kra/kis_kra_loader.cpp
index 5715946..3552675 100644
--- a/libs/ui/kra/kis_kra_loader.cpp
+++ b/libs/ui/kra/kis_kra_loader.cpp
@@ -29,6 +29,7 @@
 
 #include <KoStore.h>
 #include <KoColorSpaceRegistry.h>
+#include <KoColorSpaceEngine.h>
 #include <KoColorProfile.h>
 #include <KoDocumentInfo.h>
 #include <KoFileDialog.h>
@@ -75,6 +76,8 @@
 #include "kis_time_range.h"
 #include "kis_grid_config.h"
 #include "kis_guides_config.h"
+#include "kis_image_config.h"
+#include "KisProofingConfiguration.h"
 
 /*
 
@@ -263,6 +266,24 @@ KisImageWSP KisKraLoader::loadXML(const KoXmlElement& element)
                 return KisImageWSP(0);
             }
         }
+        KisImageConfig cfgImage;
+        KisProofingConfiguration *proofingConfig = cfgImage.defaultProofingconfiguration();
+        if (!(attr = element.attribute(PROOFINGPROFILENAME)).isNull()) {
+            proofingConfig->proofingProfile = attr;
+        }
+        if (!(attr = element.attribute(PROOFINGMODEL)).isNull()) {
+            proofingConfig->proofingModel = attr;
+        }
+        if (!(attr = element.attribute(PROOFINGDEPTH)).isNull()) {
+            proofingConfig->proofingDepth = attr;
+        }
+        if (!(attr = element.attribute(PROOFINGINTENT)).isNull()) {
+            proofingConfig->intent = (KoColorConversionTransformation::Intent) KisDomUtils::toInt(attr);
+        }
+
+        if (!(attr = element.attribute(PROOFINGADAPTATIONSTATE)).isNull()) {
+            proofingConfig->adaptationState = KisDomUtils::toDouble(attr);
+        }
 
         if (m_d->document) {
             image = new KisImage(m_d->document->createUndoStore(), width, height, cs, name);
@@ -273,22 +294,32 @@ KisImageWSP KisKraLoader::loadXML(const KoXmlElement& element)
         image->setResolution(xres, yres);
         loadNodes(element, image, const_cast<KisGroupLayer*>(image->rootLayer().data()));
 
+
         KoXmlNode child;
         for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
             KoXmlElement e = child.toElement();
-            if(e.tagName() == "ProjectionBackgroundColor") {
-                if (e.hasAttribute("ColorData")) {
+            if(e.tagName() == CANVASPROJECTIONCOLOR) {
+                if (e.hasAttribute(COLORBYTEDATA)) {
                     QByteArray colorData = QByteArray::fromBase64(e.attribute("ColorData").toLatin1());
                     KoColor color((const quint8*)colorData.data(), image->colorSpace());
                     image->setDefaultProjectionColor(color);
                 }
             }
 
+            if(e.tagName()== PROOFINGWARNINGCOLOR) {
+                QDomDocument dom;
+                KoXml::asQDomElement(dom, e);
+                QDomElement eq = dom.firstChildElement();
+                proofingConfig->warningColor = KoColor::fromXML(eq.firstChildElement(), Integer8BitsColorDepthID.id(), QHash<QString, QString>());
+            }
+
             if (e.tagName().toLower() == "animation") {
                 loadAnimationMetadata(e, image);
             }
         }
 
+        image->setProofingConfiguration(proofingConfig);
+
         for (child = element.lastChild(); !child.isNull(); child = child.previousSibling()) {
             KoXmlElement e = child.toElement();
             if(e.tagName() == "compositions") {
@@ -335,6 +366,29 @@ void KisKraLoader::loadBinaryData(KoStore * store, KisImageWSP image, const QStr
             }
         }
     }
+    //load the embed proofing profile, it only needs to be loaded into Krita, not assigned.
+    location = external ? QString() : uri;
+    location += m_d->imageName + ICC_PROOFING_PATH;
+    if (store->hasFile(location)) {
+        if (store->open(location)) {
+            QByteArray proofingData;
+            proofingData.resize(store->size());
+            bool proofingProfileRes = (store->read(proofingData.data(), store->size())>-1);
+            store->close();
+            if (proofingProfileRes)
+            {
+                const KoColorProfile *proofingProfile = KoColorSpaceRegistry::instance()->createColorProfile(image->proofingConfiguration()->proofingModel, image->proofingConfiguration()->proofingDepth, proofingData);
+                if (proofingProfile->valid()){
+
+                    //if (KoColorSpaceEngineRegistry::instance()->get("icc")) {
+                    //    KoColorSpaceEngineRegistry::instance()->get("icc")->addProfile(proofingProfile->fileName());
+                    //}
+                    KoColorSpaceRegistry::instance()->addProfile(proofingProfile);
+                }
+            }
+        }
+    }
+
 
     // Load the layers data: if there is a profile associated with a layer it will be set now.
     KisKraLoadVisitor visitor(image, store, m_d->layerFilenames, m_d->imageName, m_d->syntaxVersion);
diff --git a/libs/ui/kra/kis_kra_saver.cpp b/libs/ui/kra/kis_kra_saver.cpp
index f5dfacd..ea5f2e6 100644
--- a/libs/ui/kra/kis_kra_saver.cpp
+++ b/libs/ui/kra/kis_kra_saver.cpp
@@ -55,6 +55,7 @@
 #include "kis_dom_utils.h"
 #include "kis_grid_config.h"
 #include "kis_guides_config.h"
+#include "KisProofingConfiguration.h"
 
 
 using namespace KRA;
@@ -102,6 +103,12 @@ QDomElement KisKraSaver::saveXML(QDomDocument& doc,  KisImageWSP image)
     }
     imageElement.setAttribute(X_RESOLUTION, KisDomUtils::toString(image->xRes()*72.0));
     imageElement.setAttribute(Y_RESOLUTION, KisDomUtils::toString(image->yRes()*72.0));
+    //now the proofing options:
+    imageElement.setAttribute(PROOFINGPROFILENAME, KisDomUtils::toString(image->proofingConfiguration()->proofingProfile));
+    imageElement.setAttribute(PROOFINGMODEL, KisDomUtils::toString(image->proofingConfiguration()->proofingModel));
+    imageElement.setAttribute(PROOFINGDEPTH, KisDomUtils::toString(image->proofingConfiguration()->proofingDepth));
+    imageElement.setAttribute(PROOFINGINTENT, KisDomUtils::toString(image->proofingConfiguration()->intent));
+    imageElement.setAttribute(PROOFINGADAPTATIONSTATE, KisDomUtils::toString(image->proofingConfiguration()->adaptationState));
 
     quint32 count = 1; // We don't save the root layer, but it does count
     KisSaveXmlVisitor visitor(doc, imageElement, count, m_d->doc->url().toLocalFile(), true);
@@ -114,6 +121,7 @@ QDomElement KisKraSaver::saveXML(QDomDocument& doc,  KisImageWSP image)
     m_d->keyframeFilenames = visitor.keyframeFileNames();
 
     saveBackgroundColor(doc, imageElement, image);
+    saveWarningColor(doc, imageElement, image);
     saveCompositions(doc, imageElement, image);
     saveAssistantsList(doc,imageElement);
     saveGrid(doc,imageElement);
@@ -225,6 +233,26 @@ bool KisKraSaver::saveBinaryData(KoStore* store, KisImageWSP image, const QStrin
         }
     }
 
+    //This'll embed the profile used for proofing into the kra file.
+    if (image->proofingConfiguration()) {
+        const KoColorProfile *proofingProfile = KoColorSpaceRegistry::instance()->profileByName(image->proofingConfiguration()->proofingProfile);
+        if (proofingProfile && proofingProfile->valid()) {
+            QByteArray proofingProfileRaw = proofingProfile->rawData();
+            if (!proofingProfileRaw.isEmpty()) {
+                annotation = new KisAnnotation(ICCPROOFINGPROFILE, proofingProfile->name(), proofingProfile->rawData());
+            }
+        }
+        if (annotation) {
+            location = external ? QString() : uri;
+            location += m_d->imageName + ICC_PROOFING_PATH;
+            if (store->open(location)) {
+                store->write(annotation->annotation());
+                store->close();
+            }
+        }
+
+    }
+
     {
         KisPSDLayerStyleCollectionResource collection("not-nexists.asl");
         KIS_ASSERT_RECOVER_NOOP(!collection.valid());
@@ -267,13 +295,25 @@ QStringList KisKraSaver::errorMessages() const
 
 void KisKraSaver::saveBackgroundColor(QDomDocument& doc, QDomElement& element, KisImageWSP image)
 {
-    QDomElement e = doc.createElement("ProjectionBackgroundColor");
+    QDomElement e = doc.createElement(CANVASPROJECTIONCOLOR);
     KoColor color = image->defaultProjectionColor();
     QByteArray colorData = QByteArray::fromRawData((const char*)color.data(), color.colorSpace()->pixelSize());
-    e.setAttribute("ColorData", QString(colorData.toBase64()));
+    e.setAttribute(COLORBYTEDATA, QString(colorData.toBase64()));
     element.appendChild(e);
 }
 
+void KisKraSaver::saveWarningColor(QDomDocument& doc, QDomElement& element, KisImageWSP image)
+{
+    if (image->proofingConfiguration()) {
+        QDomElement e = doc.createElement(PROOFINGWARNINGCOLOR);
+        KoColor color = image->proofingConfiguration()->warningColor;
+        color.toXML(doc, e);
+        //QByteArray colorData = QByteArray::fromRawData((const char*)color.data(), color.colorSpace()->pixelSize());
+        //e.setAttribute("ColorData", QString(colorData.toBase64()));
+        element.appendChild(e);
+    }
+}
+
 void KisKraSaver::saveCompositions(QDomDocument& doc, QDomElement& element, KisImageWSP image)
 {
     if (!image->compositions().isEmpty()) {
diff --git a/libs/ui/kra/kis_kra_saver.h b/libs/ui/kra/kis_kra_saver.h
index 7c9180f..2f8ef5b 100644
--- a/libs/ui/kra/kis_kra_saver.h
+++ b/libs/ui/kra/kis_kra_saver.h
@@ -47,6 +47,7 @@ public:
 
 private:
     void saveBackgroundColor(QDomDocument& doc, QDomElement& element, KisImageWSP image);
+    void saveWarningColor(QDomDocument& doc, QDomElement& element, KisImageWSP image);
     void saveCompositions(QDomDocument& doc, QDomElement& element, KisImageWSP image);
     bool saveAssistants(KoStore *store,QString uri, bool external);
     bool saveAssistantsList(QDomDocument& doc, QDomElement& element);
diff --git a/libs/ui/kra/kis_kra_tags.h b/libs/ui/kra/kis_kra_tags.h
index ea3fc71..fc27a59 100644
--- a/libs/ui/kra/kis_kra_tags.h
+++ b/libs/ui/kra/kis_kra_tags.h
@@ -37,6 +37,7 @@ const QString SEPARATOR = "/";
 const QString SHAPE_LAYER_PATH = "/shapelayers/";
 const QString EXIF_PATH = "/annotations/exif";
 const QString ICC_PATH = "/annotations/icc";
+const QString ICC_PROOFING_PATH = "/annotations/proofing/icc";
 const QString LAYER_STYLES_PATH = "/annotations/layerstyles.asl";
 const QString ASSISTANTS_PATH = "/assistants/";
 const QString LAYER_PATH = "/layers/";
@@ -109,6 +110,15 @@ const QString ACTIVE = "active";
 const QString LAYER_STYLE_UUID = "layerstyle";
 const QString PASS_THROUGH_MODE = "passthrough";
 const QString KEYFRAME_FILE = "keyframes";
+const QString PROOFINGPROFILENAME = "proofing-profile-name";
+const QString PROOFINGMODEL = "proofing-model";
+const QString PROOFINGDEPTH = "proofing-depth";
+const QString PROOFINGINTENT = "proofing-intent";
+const QString PROOFINGWARNINGCOLOR ="ProofingWarningColor";
+const QString PROOFINGADAPTATIONSTATE = "proofing-adaptation-state";
+const QString ICCPROOFINGPROFILE ="icc-proofing-profile";
+const QString CANVASPROJECTIONCOLOR = "ProjectionBackgroundColor";
+const QString COLORBYTEDATA = "ColorData";
 }
 
 
diff --git a/libs/ui/opengl/kis_opengl_canvas2.cpp b/libs/ui/opengl/kis_opengl_canvas2.cpp
index 91149c3..4d003dd 100644
--- a/libs/ui/opengl/kis_opengl_canvas2.cpp
+++ b/libs/ui/opengl/kis_opengl_canvas2.cpp
@@ -94,6 +94,7 @@ public:
 
     KisDisplayFilter* displayFilter;
     KisOpenGL::FilterMode filterMode;
+    bool proofingConfigIsUpdated=false;
 
     GLsync glSyncObject{0};
 
@@ -217,6 +218,7 @@ void KisOpenGLCanvas2::initializeGL()
     initializeOpenGLFunctions();
 
     KisConfig cfg;
+    d->openGLImageTextures->setProofingConfig(canvas()->proofingConfiguration());
     d->openGLImageTextures->initGL(context()->functions());
     d->openGLImageTextures->generateCheckerTexture(createCheckersImage(cfg.checkSize()));
     initializeCheckerShader();
@@ -788,6 +790,10 @@ void KisOpenGLCanvas2::finishResizingImage(qint32 w, qint32 h)
 KisUpdateInfoSP KisOpenGLCanvas2::startUpdateCanvasProjection(const QRect & rc, const QBitArray &channelFlags)
 {
     d->openGLImageTextures->setChannelFlags(channelFlags);
+    if (canvas()->proofingConfigUpdated()) {
+        d->openGLImageTextures->setProofingConfig(canvas()->proofingConfiguration());
+        canvas()->setProofingConfigUpdated(false);
+    }
     return d->openGLImageTextures->updateCache(rc);
 }
 
diff --git a/libs/ui/opengl/kis_opengl_image_textures.cpp b/libs/ui/opengl/kis_opengl_image_textures.cpp
index 835d41e..fa0c25f 100644
--- a/libs/ui/opengl/kis_opengl_image_textures.cpp
+++ b/libs/ui/opengl/kis_opengl_image_textures.cpp
@@ -51,6 +51,9 @@ KisOpenGLImageTextures::ImageTexturesMap KisOpenGLImageTextures::imageTexturesMa
 KisOpenGLImageTextures::KisOpenGLImageTextures()
     : m_image(0)
     , m_monitorProfile(0)
+    , m_proofingConfig(0)
+    , m_proofingTransform(0)
+    , m_createNewProofingTransform(true)
     , m_tilesDestinationColorSpace(0)
     , m_internalColorManagementActive(true)
     , m_checkerTexture(0)
@@ -65,7 +68,6 @@ KisOpenGLImageTextures::KisOpenGLImageTextures()
     m_conversionFlags = KoColorConversionTransformation::HighQuality;
     if (cfg.useBlackPointCompensation()) m_conversionFlags |= KoColorConversionTransformation::BlackpointCompensation;
     if (!cfg.allowLCMSOptimization()) m_conversionFlags |= KoColorConversionTransformation::NoOptimization;
-
     m_useOcio = cfg.useOcio();
 }
 
@@ -77,7 +79,10 @@ KisOpenGLImageTextures::KisOpenGLImageTextures(KisImageWSP image,
     , m_monitorProfile(monitorProfile)
     , m_renderingIntent(renderingIntent)
     , m_conversionFlags(conversionFlags)
+    , m_proofingConfig(0)
+    , m_proofingTransform(0)
     , m_tilesDestinationColorSpace(0)
+    , m_createNewProofingTransform(true)
     , m_internalColorManagementActive(true)
     , m_checkerTexture(0)
     , m_glFuncs(0)
@@ -324,8 +329,19 @@ KisOpenGLUpdateInfoSP KisOpenGLImageTextures::updateCacheImpl(const QRect& rect,
             if (tileInfo->valid()) {
                 tileInfo->retrieveData(m_image, channelFlags, m_onlyOneChannelSelected, m_selectedChannelIndex);
 
+                //create transform
+                if (m_createNewProofingTransform) {
+                    const KoColorSpace *proofingSpace = KoColorSpaceRegistry::instance()->colorSpace(m_proofingConfig->proofingModel,m_proofingConfig->proofingDepth,m_proofingConfig->proofingProfile);
+                    m_proofingTransform = tileInfo->generateProofingTransform(dstCS, proofingSpace, m_renderingIntent, m_proofingConfig->intent, m_proofingConfig->conversionFlags, m_proofingConfig->warningColor, m_proofingConfig->adaptationState);
+                    m_createNewProofingTransform = false;
+                }
+
                 if (convertColorSpace) {
-                    tileInfo->convertTo(dstCS, m_renderingIntent, m_conversionFlags);
+                    if (m_proofingConfig && m_proofingTransform && m_proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::SoftProofing)) {
+                        tileInfo->proofTo(dstCS, m_proofingConfig->conversionFlags, m_proofingTransform);
+                    } else {
+                        tileInfo->convertTo(dstCS, m_renderingIntent, m_conversionFlags);
+                    }
                 }
 
                 info->tileList.append(tileInfo);
@@ -449,6 +465,12 @@ void KisOpenGLImageTextures::setChannelFlags(const QBitArray &channelFlags)
     m_onlyOneChannelSelected = (selectedChannels == 1);
 }
 
+void KisOpenGLImageTextures::setProofingConfig(KisProofingConfiguration *proofingConfig)
+{
+    m_proofingConfig = proofingConfig;
+    m_createNewProofingTransform = true;
+}
+
 void KisOpenGLImageTextures::getTextureSize(KisGLTexturesInfo *texturesInfo)
 {
     KisConfig cfg;
diff --git a/libs/ui/opengl/kis_opengl_image_textures.h b/libs/ui/opengl/kis_opengl_image_textures.h
index d681366..b23e9ab 100644
--- a/libs/ui/opengl/kis_opengl_image_textures.h
+++ b/libs/ui/opengl/kis_opengl_image_textures.h
@@ -27,6 +27,8 @@
 
 #include "canvas/kis_update_info.h"
 #include "opengl/kis_texture_tile.h"
+#include "KisProofingConfiguration.h"
+#include <KoColorProofingConversionTransformation.h>
 
 class KisOpenGLImageTextures;
 class QOpenGLFunctions;
@@ -79,6 +81,7 @@ public:
     void initGL(QOpenGLFunctions *f);
 
     void setChannelFlags(const QBitArray &channelFlags);
+    void setProofingConfig(KisProofingConfiguration*);
 
     bool internalColorManagementActive() const;
     bool setInternalColorManagementActive(bool value);
@@ -160,6 +163,10 @@ private:
     KoColorConversionTransformation::Intent m_renderingIntent;
     KoColorConversionTransformation::ConversionFlags m_conversionFlags;
 
+    KisProofingConfiguration *m_proofingConfig;
+    KoColorConversionTransformation *m_proofingTransform;
+    bool m_createNewProofingTransform;
+
     /**
      * If the destination color space coincides with the one of the image,
      * then effectively, there is no conversion happens. That is used
diff --git a/libs/ui/opengl/kis_texture_tile_update_info.h b/libs/ui/opengl/kis_texture_tile_update_info.h
index 6b3841e..8a0a174 100644
--- a/libs/ui/opengl/kis_texture_tile_update_info.h
+++ b/libs/ui/opengl/kis_texture_tile_update_info.h
@@ -209,6 +209,35 @@ public:
         }
     }
 
+    void proofTo(const KoColorSpace* dstCS,
+                   KoColorConversionTransformation::ConversionFlags conversionFlags,
+                   KoColorConversionTransformation *proofingTransform)
+    {
+        if (dstCS == m_patchColorSpace && conversionFlags == KoColorConversionTransformation::Empty) return;
+
+        if (m_patchRect.isValid()) {
+            const qint32 numPixels = m_patchRect.width() * m_patchRect.height();
+            const quint32 conversionCacheLength = numPixels * dstCS->pixelSize();
+
+            m_conversionCache.ensureNotSmaller(conversionCacheLength);
+            m_patchColorSpace->proofPixelsTo(m_patchPixels.data(), m_conversionCache.data(), numPixels, proofingTransform);
+
+            m_patchColorSpace = dstCS;
+            m_conversionCache.swap(m_patchPixels);
+            m_patchPixelsLength = conversionCacheLength;
+        }
+    }
+
+    KoColorConversionTransformation *generateProofingTransform(const KoColorSpace* dstCS, const KoColorSpace* proofingSpace,
+                                                       KoColorConversionTransformation::Intent renderingIntent,
+                                                       KoColorConversionTransformation::Intent proofingIntent,
+                                                       KoColorConversionTransformation::ConversionFlags conversionFlags,
+                                                       KoColor gamutWarning,
+                                                       double adaptationState)
+    {
+        return m_patchColorSpace->createProofingTransform(dstCS, proofingSpace, renderingIntent, proofingIntent, conversionFlags, gamutWarning.data(), adaptationState);
+    }
+
     inline quint8* data() const {
         return m_patchPixels.data();
     }
diff --git a/plugins/color/lcms2engine/IccColorSpaceEngine.cpp b/plugins/color/lcms2engine/IccColorSpaceEngine.cpp
index ce7ec30..7fe0ed5 100644
--- a/plugins/color/lcms2engine/IccColorSpaceEngine.cpp
+++ b/plugins/color/lcms2engine/IccColorSpaceEngine.cpp
@@ -48,7 +48,7 @@ public:
                 || srcCs->colorDepthId() == Integer16BitsColorDepthID) {
 
             if ((srcProfile->name().contains(QLatin1String("linear"), Qt::CaseInsensitive) ||
-                    dstProfile->name().contains(QLatin1String("linear"), Qt::CaseInsensitive)) &&
+                 dstProfile->name().contains(QLatin1String("linear"), Qt::CaseInsensitive)) &&
                     !conversionFlags.testFlag(KoColorConversionTransformation::NoOptimization)) {
                 conversionFlags |= KoColorConversionTransformation::NoOptimization;
             }
@@ -79,7 +79,86 @@ public:
         qint32 dstPixelSize = dstColorSpace()->pixelSize();
 
         cmsDoTransform(m_transform, const_cast<quint8 *>(src), dst, numPixels);
+        // Lcms does nothing to the destination alpha channel so we must convert that manually.
+        while (numPixels > 0) {
+            qreal alpha = srcColorSpace()->opacityF(src);
+            dstColorSpace()->setOpacity(dst, alpha, 1);
+
+            src += srcPixelSize;
+            dst += dstPixelSize;
+            numPixels--;
+        }
+
+    }
+private:
+    mutable cmsHTRANSFORM m_transform;
+};
 
+class KoLcmsColorProofingConversionTransformation : public KoColorProofingConversionTransformation
+{
+public:
+    KoLcmsColorProofingConversionTransformation(const KoColorSpace *srcCs, quint32 srcColorSpaceType, LcmsColorProfileContainer *srcProfile,
+                                                const KoColorSpace *dstCs, quint32 dstColorSpaceType, LcmsColorProfileContainer *dstProfile,
+                                                const KoColorSpace *proofingSpace,
+                                                Intent renderingIntent,
+                                                Intent proofingIntent,
+                                                ConversionFlags conversionFlags,
+                                                quint8 *gamutWarning,
+                                                double adaptationState
+                                                )
+        : KoColorProofingConversionTransformation(srcCs, dstCs, proofingSpace, renderingIntent, proofingIntent, conversionFlags, gamutWarning, adaptationState)
+        , m_transform(0)
+    {
+        Q_ASSERT(srcCs);
+        Q_ASSERT(dstCs);
+        Q_ASSERT(renderingIntent < 4);
+
+        if (srcCs->colorDepthId() == Integer8BitsColorDepthID
+                || srcCs->colorDepthId() == Integer16BitsColorDepthID) {
+
+            if ((srcProfile->name().contains(QLatin1String("linear"), Qt::CaseInsensitive) ||
+                 dstProfile->name().contains(QLatin1String("linear"), Qt::CaseInsensitive)) &&
+                    !conversionFlags.testFlag(KoColorConversionTransformation::NoOptimization)) {
+                conversionFlags |= KoColorConversionTransformation::NoOptimization;
+            }
+        }
+
+        quint16 alarm[cmsMAXCHANNELS];//this seems to be bgr???
+        alarm[0] = (cmsUInt16Number)gamutWarning[2]*256;
+        alarm[1] = (cmsUInt16Number)gamutWarning[1]*256;
+        alarm[2] = (cmsUInt16Number)gamutWarning[0]*256;
+        cmsSetAlarmCodes(alarm);
+        cmsSetAdaptationState(adaptationState);
+
+        m_transform = cmsCreateProofingTransform(srcProfile->lcmsProfile(),
+                                                 srcColorSpaceType,
+                                                 dstProfile->lcmsProfile(),
+                                                 dstColorSpaceType,
+                                                 dynamic_cast<const IccColorProfile *>(proofingSpace->profile())->asLcms()->lcmsProfile(),
+                                                 renderingIntent,
+                                                 proofingIntent,
+                                                 conversionFlags);
+        cmsSetAdaptationState(1);
+
+        Q_ASSERT(m_transform);
+    }
+
+    ~KoLcmsColorProofingConversionTransformation()
+    {
+        cmsDeleteTransform(m_transform);
+    }
+
+public:
+
+    virtual void transform(const quint8 *src, quint8 *dst, qint32 numPixels) const
+    {
+        Q_ASSERT(m_transform);
+
+        qint32 srcPixelSize = srcColorSpace()->pixelSize();
+        qint32 dstPixelSize = dstColorSpace()->pixelSize();
+        //cmsSetAdaptationState(0);
+
+        cmsDoTransform(m_transform, const_cast<quint8 *>(src), dst, numPixels);
         // Lcms does nothing to the destination alpha channel so we must convert that manually.
         while (numPixels > 0) {
             qreal alpha = srcColorSpace()->opacityF(src);
@@ -89,6 +168,7 @@ public:
             dst += dstPixelSize;
             numPixels--;
         }
+        //cmsSetAdaptationState(1);
 
     }
 private:
@@ -148,19 +228,39 @@ void IccColorSpaceEngine::removeProfile(const QString &filename)
 }
 
 KoColorConversionTransformation *IccColorSpaceEngine::createColorTransformation(const KoColorSpace *srcColorSpace,
-        const KoColorSpace *dstColorSpace,
-        KoColorConversionTransformation::Intent renderingIntent,
-        KoColorConversionTransformation::ConversionFlags conversionFlags) const
+                                                                                const KoColorSpace *dstColorSpace,
+                                                                                KoColorConversionTransformation::Intent renderingIntent,
+                                                                                KoColorConversionTransformation::ConversionFlags conversionFlags) const
 {
     Q_ASSERT(srcColorSpace);
     Q_ASSERT(dstColorSpace);
 
     return new KoLcmsColorConversionTransformation(
-               srcColorSpace, computeColorSpaceType(srcColorSpace),
-               dynamic_cast<const IccColorProfile *>(srcColorSpace->profile())->asLcms(), dstColorSpace, computeColorSpaceType(dstColorSpace),
-               dynamic_cast<const IccColorProfile *>(dstColorSpace->profile())->asLcms(), renderingIntent, conversionFlags);
+                srcColorSpace, computeColorSpaceType(srcColorSpace),
+                dynamic_cast<const IccColorProfile *>(srcColorSpace->profile())->asLcms(), dstColorSpace, computeColorSpaceType(dstColorSpace),
+                dynamic_cast<const IccColorProfile *>(dstColorSpace->profile())->asLcms(), renderingIntent, conversionFlags);
 
 }
+KoColorProofingConversionTransformation *IccColorSpaceEngine::createColorProofingTransformation(const KoColorSpace *srcColorSpace,
+                                                                                                const KoColorSpace *dstColorSpace,
+                                                                                                const KoColorSpace *proofingSpace,
+                                                                                                KoColorConversionTransformation::Intent renderingIntent,
+                                                                                                KoColorConversionTransformation::Intent proofingIntent,
+                                                                                                KoColorConversionTransformation::ConversionFlags conversionFlags,
+                                                                                                quint8 *gamutWarning,
+                                                                                                double adaptationState) const
+{
+    Q_ASSERT(srcColorSpace);
+    Q_ASSERT(dstColorSpace);
+
+    return new KoLcmsColorProofingConversionTransformation(
+                srcColorSpace, computeColorSpaceType(srcColorSpace),
+                dynamic_cast<const IccColorProfile *>(srcColorSpace->profile())->asLcms(), dstColorSpace, computeColorSpaceType(dstColorSpace),
+                dynamic_cast<const IccColorProfile *>(dstColorSpace->profile())->asLcms(), proofingSpace, renderingIntent, proofingIntent, conversionFlags, gamutWarning,
+                adaptationState
+                );
+}
+
 quint32 IccColorSpaceEngine::computeColorSpaceType(const KoColorSpace *cs) const
 {
     Q_ASSERT(cs);
diff --git a/plugins/color/lcms2engine/IccColorSpaceEngine.h b/plugins/color/lcms2engine/IccColorSpaceEngine.h
index 4f8be53..cc1654c 100644
--- a/plugins/color/lcms2engine/IccColorSpaceEngine.h
+++ b/plugins/color/lcms2engine/IccColorSpaceEngine.h
@@ -33,6 +33,11 @@ public:
             const KoColorSpace *dstColorSpace,
             KoColorConversionTransformation::Intent renderingIntent,
             KoColorConversionTransformation::ConversionFlags conversionFlags) const;
+    virtual KoColorProofingConversionTransformation *createColorProofingTransformation(const KoColorSpace *srcColorSpace,
+            const KoColorSpace *dstColorSpace,
+            const KoColorSpace *proofingSpace,
+            KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::Intent proofingIntent,
+            KoColorConversionTransformation::ConversionFlags conversionFlags, quint8 *gamutWarning, double adaptationState) const;
     quint32 computeColorSpaceType(const KoColorSpace *cs) const;
 private:
     struct Private;
diff --git a/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.cpp b/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.cpp
index 86bc111..6b16178 100644
--- a/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.cpp
+++ b/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.cpp
@@ -170,4 +170,45 @@ void TestKoLcmsColorProfile::testConversion()
 
 }
 
+void TestKoLcmsColorProfile::testProofingConversion()
+{
+    const KoColorSpace *sRgb = KoColorSpaceRegistry::instance()->rgb16("sRGB built-in");
+    Q_ASSERT(sRgb);
+    const KoColorSpace *lab = KoColorSpaceRegistry::instance()->lab16();//there's only one lab profile, replace with it's name.
+    Q_ASSERT(lab);
+
+    quint16 src[4];//the following ought to give us a purple only possible in lab. I can't seem to proof this away, somehow...
+    src[0] = 32896;
+    src[1] = 65535;
+    src[2] = 0;
+    src[3] = 65535;
+
+    quint16 dst[4];
+    memset(&dst, 0, 8);
+
+    cmsHPROFILE sRgbProfile = cmsCreate_sRGBProfile();
+    cmsHPROFILE LabProfile = cmsCreateLab4Profile(NULL);
+
+    quint16 alarm[4];//cyan!
+    alarm[0] = 65535;
+    alarm[1] = 0;
+    alarm[2] = 0;
+    alarm[3] = 65535;
+    cmsSetAlarmCodes(alarm);
+
+    cmsHTRANSFORM tf = cmsCreateProofingTransform(LabProfile,
+                                          TYPE_Lab_16,
+                                          LabProfile,
+                                          TYPE_Lab_16,
+                                          sRgbProfile,
+                                          INTENT_ABSOLUTE_COLORIMETRIC,
+                                          INTENT_ABSOLUTE_COLORIMETRIC,
+                                          cmsFLAGS_SOFTPROOFING|cmsFLAGS_GAMUTCHECK);
+
+    cmsDoTransform(tf, (quint8 *)&src, (quint8 *)&dst, 1);
+
+    qDebug()<<dst[0]<<","<<dst[1]<<","<<dst[2]<<","<<dst[3];
+    Q_ASSERT(dst[0] != alarm[0]);
+
+}
 QTEST_MAIN(TestKoLcmsColorProfile)
diff --git a/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.h b/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.h
index 4f98bcd..6d23c3d 100644
--- a/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.h
+++ b/plugins/color/lcms2engine/tests/TestKoLcmsColorProfile.h
@@ -11,6 +11,8 @@ class TestKoLcmsColorProfile : public QObject
     void testProfileCreationFromChromaticities();
 private Q_SLOTS:
     void testConversion();
+    void testProofingConversion();
+
 };
 
 #endif
diff --git a/plugins/dockers/lut/lutdocker_dock.cpp b/plugins/dockers/lut/lutdocker_dock.cpp
index 1114f15..54bc04d 100644
--- a/plugins/dockers/lut/lutdocker_dock.cpp
+++ b/plugins/dockers/lut/lutdocker_dock.cpp
@@ -164,6 +164,7 @@ LutDockerDock::LutDockerDock()
     connect(m_cmbInputColorSpace, SIGNAL(currentIndexChanged(int)), SLOT(updateDisplaySettings()));
     connect(m_cmbDisplayDevice, SIGNAL(currentIndexChanged(int)), SLOT(updateDisplaySettings()));
     connect(m_cmbView, SIGNAL(currentIndexChanged(int)), SLOT(updateDisplaySettings()));
+    connect(m_cmbLook, SIGNAL(currentIndexChanged(int)), SLOT(updateDisplaySettings()));
     connect(m_cmbComponents, SIGNAL(currentIndexChanged(int)), SLOT(updateDisplaySettings()));
 
     m_draggingSlider = false;
@@ -357,6 +358,8 @@ void LutDockerDock::enableControls()
     m_cmbDisplayDevice->setEnabled(ocioEnabled && externalColorManagementEnabled);
     m_lblView->setEnabled(ocioEnabled && externalColorManagementEnabled);
     m_cmbView->setEnabled(ocioEnabled && externalColorManagementEnabled);
+    m_lblLook->setEnabled(ocioEnabled && externalColorManagementEnabled);
+    m_cmbLook->setEnabled(ocioEnabled && externalColorManagementEnabled);
 
     bool enableConfigPath = m_colorManagement->currentIndex() == (int) KisConfig::OCIO_CONFIG;
 
@@ -379,6 +382,7 @@ void LutDockerDock::updateDisplaySettings()
         m_displayFilter->inputColorSpaceName = m_ocioConfig->getColorSpaceNameByIndex(m_cmbInputColorSpace->currentIndex());
         m_displayFilter->displayDevice = m_ocioConfig->getDisplay(m_cmbDisplayDevice->currentIndex());
         m_displayFilter->view = m_ocioConfig->getView(m_displayFilter->displayDevice, m_cmbView->currentIndex());
+        m_displayFilter->look = m_ocioConfig->getLookNameByIndex(m_cmbLook->currentIndex());
         m_displayFilter->gamma = m_gammaDoubleWidget->value();
         m_displayFilter->exposure = m_exposureDoubleWidget->value();
         m_displayFilter->swizzle = (OCIO_CHANNEL_SWIZZLE)m_cmbComponents->currentIndex();
@@ -531,6 +535,16 @@ void LutDockerDock::refillControls()
     }
 
     refillViewCombobox();
+
+    {
+        KisSignalsBlocker LookComboLocker(m_cmbLook);
+        m_cmbLook->clear();
+        int numLooks = m_ocioConfig->getNumLooks();
+        for (int k = 0; k < numLooks; k++) {
+           m_cmbLook->addSqueezedItem(QString::fromUtf8(m_ocioConfig->getLookNameByIndex(k)));
+        }
+        m_cmbLook->addSqueezedItem(i18nc("Item to indicate no look transform being selected","None"));
+    }
     updateDisplaySettings();
 }
 
diff --git a/plugins/dockers/lut/ocio_display_filter.cpp b/plugins/dockers/lut/ocio_display_filter.cpp
index 70e4c50..6f8bbe0 100644
--- a/plugins/dockers/lut/ocio_display_filter.cpp
+++ b/plugins/dockers/lut/ocio_display_filter.cpp
@@ -39,6 +39,7 @@ OcioDisplayFilter::OcioDisplayFilter(KisExposureGammaCorrectionInterface *interf
     , inputColorSpaceName(0)
     , displayDevice(0)
     , view(0)
+    , look(0)
     , swizzle(RGBA)
     , m_interface(interface)
     , m_lut3dTexID(0)
@@ -124,12 +125,40 @@ void OcioDisplayFilter::updateProcessor()
     if (!inputColorSpaceName) {
         inputColorSpaceName = config->getColorSpaceNameByIndex(0);
     }
+    if (!look) {
+	look = config->getLookNameByIndex(0);
+    }
+
+    if (!displayDevice || !view || !inputColorSpaceName) {
+        return;
+    }
 
     OCIO::DisplayTransformRcPtr transform = OCIO::DisplayTransform::Create();
     transform->setInputColorSpaceName(inputColorSpaceName);
     transform->setDisplay(displayDevice);
     transform->setView(view);
 
+    /**
+     * Look support:
+     * As the OCIO docs will tell you, looks are a aesthetic transform that is
+     * added onto the mix.
+     * A view+display can have it's own assigned Look, or list of looks, and these
+     * can be overriden optionally.
+     * What the OCIO docs won't tell you is that a display transform won't use the
+     * looks attached to it unless "skipColorSpaceConversions" is false...
+     * I have no idea what "skipColorSpaceConversions" is beyond what it says on the
+     * tin. It is not mentioned in the documentation anywhere. Or on the website.
+     * Or how to set it. Or unset it. Why it is apparantly set true to begin with.
+     * Only that, apparantly, this was done with non-color data in mind...
+     *
+     * Until there's clear documentation on how to use this feature, I am afraid the
+     * override is all we can offer.
+     */
+    if (config->getLook(look)) {
+       transform->setLooksOverride(look);
+       transform->setLooksOverrideEnabled(true);
+    }
+
     OCIO::GroupTransformRcPtr approximateTransform = OCIO::GroupTransform::Create();
 
     // fstop exposure control -- not sure how that translates to our exposure
diff --git a/plugins/dockers/lut/ocio_display_filter.h b/plugins/dockers/lut/ocio_display_filter.h
index 2622156..304bcc0 100644
--- a/plugins/dockers/lut/ocio_display_filter.h
+++ b/plugins/dockers/lut/ocio_display_filter.h
@@ -64,6 +64,7 @@ public:
     const char *inputColorSpaceName;
     const char *displayDevice;
     const char *view;
+    const char *look;
     OCIO_CHANNEL_SWIZZLE swizzle;
     float exposure;
     float gamma;
diff --git a/plugins/dockers/lut/wdglut.ui b/plugins/dockers/lut/wdglut.ui
index 8480d5e..d90dcfb 100644
--- a/plugins/dockers/lut/wdglut.ui
+++ b/plugins/dockers/lut/wdglut.ui
@@ -2,6 +2,14 @@
 <ui version="4.0">
  <class>WdgLut</class>
  <widget class="QWidget" name="WdgLut">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>357</width>
+    <height>286</height>
+   </rect>
+  </property>
   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
    <property name="spacing">
     <number>0</number>
@@ -88,7 +96,7 @@
           </property>
          </widget>
         </item>
-        <item row="6" column="0">
+        <item row="7" column="0">
          <widget class="QLabel" name="label_5">
           <property name="text">
            <string>Components:</string>
@@ -121,7 +129,7 @@
           </property>
          </widget>
         </item>
-        <item row="7" column="0">
+        <item row="8" column="0">
          <widget class="QLabel" name="label_7">
           <property name="text">
            <string>Exposure:</string>
@@ -147,8 +155,8 @@
           </property>
          </widget>
         </item>
-        <item row="7" column="1">
-         <widget class="KisDoubleWidget" name="m_exposureDoubleWidget">
+        <item row="8" column="1">
+         <widget class="KisDoubleWidget" name="m_exposureDoubleWidget" native="true">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -232,7 +240,7 @@
           </item>
          </layout>
         </item>
-        <item row="6" column="1">
+        <item row="7" column="1">
          <widget class="SqueezedComboBox" name="m_cmbComponents">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -242,8 +250,8 @@
           </property>
          </widget>
         </item>
-        <item row="8" column="1">
-         <widget class="KisDoubleWidget" name="m_gammaDoubleWidget">
+        <item row="9" column="1">
+         <widget class="KisDoubleWidget" name="m_gammaDoubleWidget" native="true">
           <property name="sizePolicy">
            <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
             <horstretch>0</horstretch>
@@ -252,7 +260,7 @@
           </property>
          </widget>
         </item>
-        <item row="8" column="0">
+        <item row="9" column="0">
          <widget class="QLabel" name="label_8">
           <property name="text">
            <string>Gamma:</string>
@@ -310,6 +318,23 @@
           </item>
          </widget>
         </item>
+        <item row="6" column="0">
+         <widget class="QLabel" name="m_lblLook">
+          <property name="text">
+           <string>Look:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="6" column="1">
+         <widget class="SqueezedComboBox" name="m_cmbLook">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+         </widget>
+        </item>
        </layout>
       </item>
       <item>
@@ -328,6 +353,12 @@
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>0</width>
+            <height>0</height>
+           </size>
+          </property>
          </spacer>
         </item>
         <item>


More information about the kimageshop mailing list