[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [krita] /: Merge in Krita-testing-wolthera
From:       Wolthera_van_Hövell <griffinvalley () gmail ! com>
Date:       2016-01-31 14:18:40
Message-ID: E1aPsps-0001RB-CK () scm ! kde ! org
[Download RAW message or body]

Git commit 290c81bfc240d5b6e06d8c1f244250c5615bd2a9 by Wolthera van Hövell.
Committed on 31/01/2016 at 14:17.
Pushed by woltherav into branch 'master'.

Merge in Krita-testing-wolthera

Make a clean build for best results!

Squashed commit of the following:

commit fdc03dbfd47d8071303bd4c58394d70b58ab1f4e
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 31 15:16:37 2016 +0100

    Cleanup

    This introduces a little bug in the trc again, but I suposse this works for now.

commit c42e5c93cd9f33dc92927100c5aa47c5d8814b8b
Merge: 4b5806d c2706b3
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 31 12:45:40 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 4b5806d06ce7c7ad06245489355f4e0f5573f0b7
Merge: 5f4ae5e 97a2851
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Jan 30 17:25:57 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 5f4ae5e01ec4596172908502fff048ff10ff41a2
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Jan 30 16:04:59 2016 +0100

    Make the trc curve widget work for cmyk

commit 95ba47ebe0b1a5394621ef82c7e280746b9c42d4
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Jan 30 16:04:16 2016 +0100

    Fix build

commit a814301c23ff75b88808038729455805ce1d7005
Merge: 2089d33 1a0554c
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Jan 29 08:41:00 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 2089d335a7f5b928edf5d3245268bf2e49d2ac46
Merge: 597780c 96d2211
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Jan 29 08:37:28 2016 +0100

    Merge branch 'krita-testing-wolthera' of git://anongit.kde.org/krita into \
krita-testing-wolthera

commit 96d22115b4006cf0be51d9525c9c4bd43c879bcd
Merge: 952bbc6 7d1d542
Author: Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>
Date:   Sat Jan 23 12:05:09 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 597780c56793abb5d7e140aae1708bb37226b9f3
Merge: 952bbc6 7167c6b
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Jan 14 20:08:23 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 952bbc6e41eff0cb726ac92d2c9ac22b3e632487
Merge: 35fe231 d592d52
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Jan 14 16:49:15 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 35fe23104a7f41c823eb22bcdd43791ad9f12001
Merge: 36b940c 30c07ba
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Jan 14 14:30:57 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 36b940ca0dc4c334ecf8ed65422e0e6f9c48622a
Merge: 028a00f 8089c94
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Jan 12 18:55:54 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 028a00f84c7431f9a31c08e3f1545d3d47d155b8
Merge: c31a412 fe9c554
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Jan 12 14:21:42 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit c31a412d2baf4dba97760e44c03895f89fe0cedb
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 10 19:16:37 2016 +0100

    Make some small changes to get cmyk/lab f32 to show up somewhat sensibly.

    ref T210

commit 9a466509d349a7077468bc6b30a899bb3df66bde
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 10 16:40:32 2016 +0100

    Draw semi-transparent triangle for the matrix-shapers.

    Still not sure if we should keep the gamut dots on there or not...

commit d1614f470e094b278d2c34eca66d448523b81e38
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 10 15:04:42 2016 +0100

    Display embedded copyright string.

    This is not translator friendly, but I think copyright is important enough for \
that.

    Ref T210

commit 1739e7d010089e8c61489d586a5ecfb122c88787
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Jan 10 12:14:09 2016 +0100

    Change method to use normalised channels. Also fixes crash in XYZA 32bit/float

    Not sure what to do for 32bitfloat in case of LAB and CMYK.

    Ref T429, T210

commit f9cbaa135e449864ca4298a7f3c9f34187c68fcf
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Jan 9 21:56:33 2016 +0100

    Add gamut point calculation thingy.

    This allows us to investigate CMYK and other cLUT only colorspaces in the \
colorspace browser.  Also good for future gamut checking.

    Things that don't work:
    * Anything but 8bit colorspace, proly due to architecture stuffs. Maybe use from \
normalised instead  of quint8 data...
    * Matrix profiles still default to relative colorimetric, which is kinda annoying
    * Need to investigate how to get the correct conversion flags over.
    * XYZA32bit float doesnt work...?

    Other:
    * Need to clean up
    * Need to check if I can get whitepoint/colorants simplified into the cs.
    * Need to see if this is also possible for the trc.
    * Maybe investigate boundary-checking-thingy for CMYK.

    Ref T429

commit 8680486f3c64b9d6ebf4f175b8ca776120d64c1e
Merge: 613e10c 31aebe6
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Jan 6 14:11:35 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 613e10c8888abd11467d9176a7b00109d5cfa981
Merge: c8e2959 6131b4c
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Jan 5 18:48:00 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit c8e29598d95f69d724727f9ad9dd07c2f98e0eba
Merge: 49fa9f3 b378fea
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Jan 4 19:30:52 2016 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 49fa9f3ed2a31f4b1b8bfb7000aac0735e8cb503
Merge: d79d158 68e74a5
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Dec 22 22:46:55 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit d79d158aa4960a849fcf235648b800c29fed78e3
Merge: c060d02 c87f8eb
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Dec 22 21:12:16 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit c060d0261ea6e8ed0ba85e88d080dc01ce12cf60
Merge: 8cdac6d eb65d91
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Dec 21 22:02:04 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 8cdac6d644237f1491623c9fb8520e55833980fa
Merge: d94ac2a dd1c87b
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Dec 20 16:21:00 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit d94ac2a0422d8c83e9fe2eb1eca73497f56c1717
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Dec 19 17:07:37 2015 +0100

    Add ICC version and rendering intent information to color space browser

    Matrix shaper profiles can't use anything but relative colorimetric, but an ICC \
profile can contain  both Matrix and several cLUT profile data, which affects which \
intents are possible.  For now the data is printed into the color space browser. \
We'll do proper disabling later.

    Still have an issue with lists in richtext...

    Ref T429

commit b43600feac454b981b4d8dd88e5e2d8eee3a6647
Merge: 2874c08 60d5223
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Dec 18 14:58:40 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 2874c08e069b829ba792b950121ae6f07861bd09
Merge: 430a544 e7c035c
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Dec 17 19:55:44 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 430a544fd94b40d211859b4ba28b2cf6f14c2e37
Merge: ce83961 2e4082f
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Dec 17 15:25:26 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit ce839615e616c58f95eb913fcdcc7b28e5ef856b
Merge: 28e9fc2 b19a225
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Dec 14 15:02:00 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 28e9fc21449177eb96d287cefd22eb7bd19f7318
Merge: a20d5f4 56634cb
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Dec 14 15:00:43 2015 +0100

    Merge branch 'krita-testing-wolthera' of git://anongit.kde.org/krita into \
krita-testing-wolthera

commit 56634cb4fb8ab99902b2c6ec27205355560668d8
Author: Boudewijn Rempt <boud@valdyas.org>
Date:   Sat Dec 12 16:16:51 2015 +0100

    Cut down on the float/double/qreal confusion a bit

    And do a bit of coding style cleanup (function names start with
    a lower case letter).

    There are some more places where a similar change would be good,
    esp. in the normalise api (and normalise should be renamed to
    normalize).

commit a20d5f4f47c5a82cd38cd2a8ba312729d23b961b
Merge: 5e2a606 af869a5
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Dec 11 14:56:53 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 5e2a60659e343bd9358d10edf594c5da22bbf64a
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Dec 11 14:46:11 2015 +0100

    Disable subpixel precision in the color smudge brush only for smearing mode

    Auditors: rempt, dkazakov, timotheegiet

    Original bug that caused the initial method was 327235, and that was only for
    smearing mode. In dulling mode the lack of subpixel precision is very obvious,
    while in smearing mode it isn't.

    Therefore, I propose we only disable subpixel precision for smearing mode.

commit 7c02c37f7af3635dfb4a1a4e6c619070061c0718
Merge: d619f0b 46bd592
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Dec 10 16:50:25 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit d619f0b23bec9fb56bfbe493feaed71f5b301e73
Merge: 4ed97dd e1c0678
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Dec 7 19:06:55 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 4ed97dd9f9baa1b284b3ea3652440fcdcb4ba938
Merge: be202e5 031cfb1
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Dec 3 19:40:05 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit be202e5bf4a63efee301c9e877b15394fe9bdeb7
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Dec 3 17:47:01 2015 +0100

    Alphabetize PNG importer

    Shouldn't this become a color browser?

commit 5c9c14ef69f92e2c2927a4efc76aaf013b612f48
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Dec 2 16:44:00 2015 +0100

    Tweak colorsmudge algortihms to work better with pure black.

commit d911b722c1c5cd223daa7c013b780e0264aaa4c6
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Dec 2 02:26:42 2015 +0100

    clean up color browser UI by moving things to the tooltips.

commit c82c5b9369bbf725f70a6cfdfcd185e31cb139d1
Merge: db339e7 c1c20d4
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Dec 1 17:08:11 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit db339e79a18fe836bef9e44c3235bc71c6ac83eb
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Dec 1 13:07:36 2015 +0100

    Fix sat maintaining and advanced dulling mode, support blending mode for both

    The mixing itself works now, blendingmodes sorta as well, though different from
    regular dulling. Strange results with orange+black.

    Ref T691

commit c094e8181eac3c20e897f346ed4887c19ac8d9c3
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Nov 29 19:19:51 2015 +0100

    Make sure that CMYK/XYZ get mixed in LAB space

    This prevents crashes, but the results aren't really pretty.

    Ref T691

commit ee6d609c9fb100b3df56b522bd2c8c0b6596c968
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Nov 29 18:35:51 2015 +0100

    Implement basis of advanced color mixing.

    Now we have linearised colormixing+gamma correction :D
    Though the alpha formula isn't quite right, and sat-maintaining
    blending could use work...

    Similarly, this hasn't been properlytested in the non-rgb spaces yet.

    Ref T210
    Ref T691

commit 2ffcca78e26e5967eeb9a1cb62be699ff3ead2a8
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Nov 28 15:58:14 2015 +0100

    Partial fix mixing gradients in the colorspace of the image.

    The remaining problems of course are:
    * No higher than 1.0 floating point.
    * The colorspace of the gradients are STILL in sRGB, meaning colors outside that \
can't be picked.

    Ref T210
    Ref T121

commit b148f84621d6944accbdc08ef35aa2ca4f962d75
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Nov 28 15:22:53 2015 +0100

    Modify and fix floating point for HSI/HSY/YUV adjustments

commit e9a352a0e30c92e6a645e57729300ec184d4e23a
Merge: 5bf45c1 8a971d7
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 27 13:41:06 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 5bf45c1e9b8f7c3988b22262cdad0341afe217f0
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Nov 21 21:57:20 2015 +0100

    Start with preciser color smudge by forcing a 16bit or higher colorspace

    This reduces errors in the mixing, though it's not as smooth as actual 16bit
    needs more investigation, and I also want to make this configurable.

commit 027f33af95e6de05a0fefcbbc3823318dcff5879
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Nov 21 21:54:06 2015 +0100

    Add HSI/HSY/YUV to the hsv adjustment filter.

    Ideally we'd replace the small transform commands with this entirely, but
    I have no idea how to make this filter accept LAB space.
    It also doesn't linearize, something which I need help for.

    However, it does use the luma coefficients of the color profile.

    ref T210

commit e8ae9e9e52c35c65edd5d3dacbd9e3c8d5dd6d41
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 20 22:43:50 2015 +0100

    Fix LCH and R/G/B/Y actions for LAB

    That leaves XYZ to be fixed.

    Ref T210

commit a1d66bfe11bc0250f9a346a873afdaa97c8a0a1a
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 20 20:45:37 2015 +0100

    Fix Redder/Greener/Yellower/Bluer actions for CMYK

    I wanted to do the same thing for HSY, but it seems that
    CMYK has a huge issue with saturation.
    To wit, the convert-from-q-color method of getting saturation
    doesn't seem to work either, even though this should be pretty
    full-proof. Regardless, some hotkeys work, so...

    Ref T220

commit e225166f12b736b57cd12b10d32e1ba8135d21b7
Merge: d1b9f2e 747b18b
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Thu Nov 19 22:40:59 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit d1b9f2e9880d92ec540127b78374aaa9553201a1
Merge: a516116 3434ec6
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Nov 17 18:09:03 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit a516116b91a035db8c3ad5bf9410a993e5e3d93c
Merge: 2b979ef a627798
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sun Nov 15 19:56:27 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 2b979ef74dcf1065f3c6c63ed8989917f448db3a
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Sat Nov 14 17:26:34 2015 +0100

    Change YCbCr to YUV formula, this makes the hotkeys work proper.

    Todo:
    * Fix LAB(inverted) and XYZ(too agressive)
    * Find an alternative for CMYK

    Ref T210

commit 3f42fac080e868009ed9a3cb453c4671cce67517
Merge: 406405a 4c5de2c
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 22:05:19 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 406405a4d25c9c765fd3ab7499db8228aec43930
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 21:44:41 2015 +0100

    First stages YCbCr formula. Not satisfied yet

    There's redder/greener/bluer/yellower actions now, but as long
    as I am not satisfied with the formula they can be considered broken

commit b148b48bad374cdd5e3efb80b0ad3b522f1b9e93
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 15:07:56 2015 +0100

    Crunch the luma of HSY to 2.2 by default.

    This makes it easier to select darker colors while keeping the HSY correct.
    We might want to make this a config option in the future.

    Ref T210

commit 11e791f3c99c222c53cbefa6be7ccf77be0ebae9
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 14:32:45 2015 +0100

    Make faster linearisation functions+linearisize advanced selector

commit 82ee9cf059fc91582a6c7c2794007b10547fc9b6
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 13:04:05 2015 +0100

    Experiment with linearising color selector

    Also doesn't work because linearisation function is too slow

    Ref T210

commit d102f1f168212d0a084306f927081ff76026b3d1
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Fri Nov 13 13:03:02 2015 +0100

    Experiment with HDR Values for the lighter/darker buttons

    This doesn't quite work yet, because HSY only really works in a 0-1.0 sceme

commit cf4c780af6a28ad630ff3b21988d8379273b276b
Merge: bef8552 1fc48d5
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Nov 11 17:28:01 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit bef85521356bdb52e063d956c70d61ada9863a6b
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Nov 11 17:21:35 2015 +0100

    Add basic Gamma crunching to lightness button

    Ref 210

commit 55bffbc4566d0dbcc134f049f6b6a3db54d3b14a
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Wed Nov 11 15:48:19 2015 +0100

    Color manage darker/lighter, add actions for sat/desat/hue

    This still needs a lot of work.

    * It's all linear, we need to crunch the luma.
    * It's not working for XYZ/YCrCb/LAB properly yet. This'll require LCH/xyY
    * Hue-clockwise has issues.
    * QVector <double> needs to become QVector <float> for consistency.

    Ref T210

commit 09404852c6489a38cd2e1fc47a76175cb8884ccd
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Nov 10 18:06:38 2015 +0100

    Some cleanup for the TRC widget and pigment

    Ref T210

commit 5a6874d179032766ac1be8f78366e1277330bf0e
Merge: 0cb7cce 1e70cdc
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Nov 10 15:29:09 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit 0cb7cce7dd7b1a7d1258b20caf6cc98d07cc07c1
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Tue Nov 10 00:09:04 2015 +0100

    Add basic Tone Response Curve widget.

    It is based on receiving QPolygons filled with points, so it's cm agnostic.

    TODO:
    * Document
    * Cleanup
    * Move elements about(rgb to the tooltip of the tongue widget?)
    * Maybe render a grayscale in a given colorspace for the TRC widget?

commit ff8b31a6f4cb34e5f7df30bdcbea10d71e3f7911
Merge: ef0275d 74e7e5a
Author: Wolthera van Hövell <griffinvalley@gmail.com>
Date:   Mon Nov 9 19:08:34 2015 +0100

    Merge branch 'master' into krita-testing-wolthera

commit ef0275d7a082a1bc15cbd5bc0ead95e46543dc4d
Author: Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>
Date:   Sun Nov 8 17:50:34 2015 +0100

    Add basic TRC linearisation functions to the color profiles

M  +88   -0    krita/krita.action
M  +1    -1    libs/pigment/KoChannelInfo.h
M  +1    -1    libs/pigment/KoCmykColorSpaceTraits.h
M  +428  -539  libs/pigment/KoColorConversions.cpp
M  +11   -0    libs/pigment/KoColorConversions.h
M  +18   -1    libs/pigment/KoColorProfile.cpp
M  +52   -5    libs/pigment/KoColorProfile.h
M  +426  -0    libs/pigment/KoColorSpace.cpp
M  +34   -0    libs/pigment/KoColorSpace.h
M  +6    -0    libs/pigment/KoColorSpace_p.h
M  +39   -2    libs/pigment/colorprofiles/KoDummyColorProfile.cpp
M  +10   -0    libs/pigment/colorprofiles/KoDummyColorProfile.h
M  +18   -0    libs/pigment/colorspaces/KoAlphaColorSpace.h
M  +31   -0    libs/pigment/colorspaces/KoLabColorSpace.cpp
M  +5    -0    libs/pigment/colorspaces/KoLabColorSpace.h
M  +28   -0    libs/pigment/colorspaces/KoRgbU16ColorSpace.cpp
M  +5    -0    libs/pigment/colorspaces/KoRgbU16ColorSpace.h
M  +29   -0    libs/pigment/colorspaces/KoRgbU8ColorSpace.cpp
M  +5    -0    libs/pigment/colorspaces/KoRgbU8ColorSpace.h
M  +18   -0    libs/pigment/colorspaces/KoSimpleColorSpace.h
M  +27   -4    libs/pigment/resources/KoSegmentGradient.cpp
M  +28   -7    libs/pigment/resources/KoStopGradient.cpp
M  +1    -0    libs/ui/CMakeLists.txt
M  +27   -24   libs/ui/canvas/kis_display_color_converter.cpp
M  +6    -2    libs/ui/dialogs/kis_dlg_png_import.cpp
M  +9    -57   libs/ui/forms/wdgcolorspaceselectoradvanced.ui
M  +145  -9    libs/ui/kis_canvas_controls_manager.cpp
M  +12   -0    libs/ui/kis_canvas_controls_manager.h
M  +224  -101  libs/ui/widgets/kis_advanced_color_space_selector.cc
M  +55   -1    libs/ui/widgets/kis_cie_tongue_widget.cpp
M  +2    -1    libs/ui/widgets/kis_cie_tongue_widget.h
A  +362  -0    libs/ui/widgets/kis_tone_curve_widget.cpp     [License: GPL (v2+)]
C  +14   -52   libs/ui/widgets/kis_tone_curve_widget.h [from: \
libs/ui/widgets/kis_cie_tongue_widget.h - 051% similarity] M  +208  -58   \
plugins/color/colorspaceextensions/kis_hsv_adjustment.cpp M  +78   -13   \
plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp M  +17   -5    \
plugins/color/lcms2engine/colorprofiles/IccColorProfile.h M  +201  -22   \
plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.cpp M  +16   -1    \
plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.h M  +43   -0    \
plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.h M  +44   -0    \
plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.cpp M  +6    -2    \
plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.h M  +43   -0    \
plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.h M  +25   -0    \
plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.h M  +25   -0    \
plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.h M  +25   -0    \
plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.h M  +25   -0    \
plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.h M  +31   -0    \
plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.cpp M  +7    -3    \
plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.h M  +29   -1    \
plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.h M  +28   -0    \
plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.h M  +28   -0    \
plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp M  +6    -1    \
plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.h M  +30   -0    \
plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h M  +29   -0    \
plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h M  +29   -0    \
plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.cpp M  +5    -1    \
plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h M  +23   -0    \
plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp M  +16   -1    \
plugins/filters/colorsfilters/wdg_hsv_adjustment.ui M  +27   -12   \
plugins/paintops/colorsmudge/kis_colorsmudgeop.cpp M  +1    -1    \
plugins/paintops/colorsmudge/kis_smudge_option_widget.cpp

http://commits.kde.org/krita/290c81bfc240d5b6e06d8c1f244250c5615bd2a9

diff --git a/krita/krita.action b/krita/krita.action
index 5c666d2..086931c 100644
--- a/krita/krita.action
+++ b/krita/krita.action
@@ -273,6 +273,94 @@
       <isCheckable>false</isCheckable>
       <statusTip></statusTip>
     </Action>
+    <Action name="make_brush_color_saturated">
+      <icon></icon>
+      <text>Make brush color more saturated</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more saturated</toolTip>
+      <iconText>Make brush color more saturated</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="make_brush_color_desaturated">
+      <icon></icon>
+      <text>Make brush color more desaturated</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more desaturated</toolTip>
+      <iconText>Make brush color more desaturated</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="shift_brush_color_clockwise">
+      <icon></icon>
+      <text>Shift brush color hue clockwise</text>
+      <whatsThis></whatsThis>
+      <toolTip>Shift brush color hue clockwise</toolTip>
+      <iconText>Shift brush color hue clockwise</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="shift_brush_color_counter_clockwise">
+      <icon></icon>
+      <text>Shift brush color hue counter-clockwise</text>
+      <whatsThis></whatsThis>
+      <toolTip>Shift brush color hue counter-clockwise</toolTip>
+      <iconText>Shift brush color hue counter-clockwise</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="make_brush_color_redder">
+      <icon></icon>
+      <text>Make brush color more red</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more red</toolTip>
+      <iconText>Make brush color more red</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="make_brush_color_greener">
+      <icon></icon>
+      <text>Make brush color more green</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more green</toolTip>
+      <iconText>Make brush color more green</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="make_brush_color_bluer">
+      <icon></icon>
+      <text>Make brush color more blue</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more blue</toolTip>
+      <iconText>Make brush color more blue</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
+    <Action name="make_brush_color_yellower">
+      <icon></icon>
+    <text>Make brush color more yellow</text>
+      <whatsThis></whatsThis>
+      <toolTip>Make brush color more yellow</toolTip>
+      <iconText>Make brush color more yellow</iconText>
+      <shortcut></shortcut>
+      <defaultShortcut></defaultShortcut>
+      <isCheckable>false</isCheckable>
+      <statusTip></statusTip>
+    </Action>
     <Action name="increase_opacity">
       <icon></icon>
       <text>Increase opacity</text>
diff --git a/libs/pigment/KoChannelInfo.h b/libs/pigment/KoChannelInfo.h
index 4b81162..b585455 100644
--- a/libs/pigment/KoChannelInfo.h
+++ b/libs/pigment/KoChannelInfo.h
@@ -44,7 +44,7 @@ public:
             /// creates an invalid range of 0,0
             DoubleRange(void) : minVal(0), maxVal(0) { }
             /// creates
-            DoubleRange(double _minVal, double _maxVal) : minVal(_minVal), \
maxVal(_maxVal) { Q_ASSERT(minVal <= maxVal); } +            DoubleRange(qreal \
_minVal, qreal _maxVal) : minVal(_minVal), maxVal(_maxVal) { Q_ASSERT(minVal <= \
maxVal); }  /// true if this range is usable
             bool isValid(void) const { return minVal < maxVal; }
     };
diff --git a/libs/pigment/KoCmykColorSpaceTraits.h \
b/libs/pigment/KoCmykColorSpaceTraits.h index 23bc8c3..657c501 100644
--- a/libs/pigment/KoCmykColorSpaceTraits.h
+++ b/libs/pigment/KoCmykColorSpaceTraits.h
@@ -34,7 +34,7 @@
 template<typename _channels_type_>
 struct KoCmykTraits : public KoColorSpaceTrait<_channels_type_, 5, 4> {
     typedef _channels_type_ channels_type;
-    typedef KoColorSpaceTrait<_channels_type_, 4, 3> parent;
+    typedef KoColorSpaceTrait<_channels_type_, 5, 4> parent;
 
     static const qint32 c_pos = 0;
     static const qint32 m_pos = 1;
diff --git a/libs/pigment/KoColorConversions.cpp \
b/libs/pigment/KoColorConversions.cpp index 8fa2f5c..0a00c33 100644
--- a/libs/pigment/KoColorConversions.cpp
+++ b/libs/pigment/KoColorConversions.cpp
@@ -423,419 +423,226 @@ void HSLToRGB(float h, float sl, float l, float *r, float *g, \
float *b)  //functions for converting from and back to HSI
 void HSIToRGB(const qreal h,const qreal s, const qreal i, qreal *red, qreal *green, \
qreal *blue)  {//This function takes H, S and I values, which are converted to rgb.
-	qreal hue = 0.0;
-	qreal sat = 0.0;
-	qreal intensity = 0.0;
-	if (h>1.0 || h<0.0){hue=fmod(h, 1.0);} else {hue=h;}
-	if (s>1.0){sat=1.0;}
-	else if (s<0.0){sat=0.0;}
-	else {sat=s;}
-	if (i>1.0){intensity=1.0;}
-	else if (i<0.0){intensity=0.0;}
-	else {intensity=i;}
-	
-	qreal segment = 0.166667;//1/6;
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
-//HSI weights by adding up the components, so in RGB hsi, you would have to divide \
                by 3 to normalise it.
-	qreal onethird=1.0/3.0;
-//The intermediate variables for the weighted HSL forumala, based on the HSL in \
                KoColorConversions.
-	qreal max_sat, m, fract, intensity_a, chroma, x;
-	if (hue >= 0.0 && hue < (segment) )
-	{
-		//need to treat this as a weighted hsl thingy.
-		//so first things first, at which intensity is the maximum saturation for this \
                hue?
-		//between R and G+R (yellow)
-		max_sat = onethird + ( onethird*(hue*6) );	
-		if (intensity<=max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*2*intensity_a;}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-			fract = hue*6.0;
-			x = (1-fabs(fmod(fract,2)-1))*chroma;
-			r = chroma; g=x; b=0;\
-			m = intensity-(onethird*(r+b+g));
-			r += m; g += m; b += m;
-			
-    
-	}	
-	else if (hue >= (segment) && hue < (2.0*segment) )
-	{
-		
-		max_sat = (onethird*2) - (onethird*(hue-segment)*6);
-		if (intensity<max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*(2*intensity_a);}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = x; g=chroma; b=0;
-		m = intensity-(onethird*(r+b+g));
-		r += m; g += m; b += m;
-			
-
-	}	
-	else if (hue >= (2.0*segment) && hue < (3.0*segment) )
-	{
-		max_sat = onethird + (onethird*(hue-2.0*segment)*6);
-		if (intensity<max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*(2*intensity_a);}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = 0; g=chroma; b=x;
-		m = intensity-(onethird*(r+b+g));
-		r += m; g += m; b += m;
-	}	
-	else if (hue >= (3.0*segment) && hue < (4.0*segment) )
-	{	max_sat = (onethird*2) - (onethird*(hue-3.0*segment)*6);	
-		if (intensity<max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*(2*intensity_a);}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = 0; g=x; b=chroma;
-		m = intensity-(onethird*(r+b+g));
-		r += m; g += m; b += m;
-	}
-	else if (hue >= (4.0*segment) && hue < (5*segment) )
-	{
-		max_sat = onethird + (onethird*((hue-4.0*segment)*6));	
-		if (intensity<max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*(2*intensity_a);}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = x; g=0; b=chroma;
-		m = intensity-(onethird*(r+b+g));
-		r += m; g += m; b += m;
-	}
-	else if (hue >= (5.0*segment) && hue <= 1.0)
-	{
-	max_sat = (onethird*2) - (onethird*(hue-5.0*segment)*6);	
-		if (intensity<max_sat){intensity_a = (intensity/max_sat)*0.5; \
                chroma=sat*(2*intensity_a);}
-		else {intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5; \
                chroma=sat*(2-2*intensity_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = chroma; g=0; b=x;
-		m = intensity-(onethird*(r+b+g));
-		r += m; g += m; b += m;
-	}
-	else
-	{
-	r=0.0;
-	g=0.0;
-	b=0.0;
-	}
-
-	//dbgPigment<<"red: "<<r<<", green: "<<g<<", blue: "<<b;
-	if (r>1.0){r=1.0;}
-	if (g>1.0){g=1.0;}
-	if (b>1.0){b=1.0;}
-	if (r<0.0){r=0.0;}
-	if (g<0.0){g=0.0;}
-	if (b<0.0){b=0.0;}
-	
-	*red=r;
-	*green=g;
-	*blue=b;
+    qreal onethird = 1.0/3.0;
+    HSYToRGB(h, s, i, red, green, blue, onethird, onethird, onethird);
 }
 void RGBToHSI(qreal r,qreal g, qreal b, qreal *h, qreal *s, qreal *i)
 {
-//Using these RGB values, we calculate the H, S and I.
-	qreal red; qreal green; qreal blue;
-	if (r>1.0){red=1.0;} else if (r<0.0){red=0.0;} else {red=r;}
-	if (g>1.0){green=1.0;} else if (g<0.0){green=0.0;} else {green=g;}
-	if (b>1.0){blue=1.0;} else if (b<0.0){blue=0.0;} else {blue=b;}
-	qreal minval = qMin(r, qMin(g, b));
-	qreal maxval = qMax(r, qMax(g, b));
-	qreal hue = 0.0;
-	qreal sat = 0.0;
-	qreal intensity = 0.0;
-	qreal onethird=1.0/3.0;
-	intensity=onethird*(red+green+blue);
-	qreal intensity_a;//defined later
-	qreal chroma = maxval-minval;
-	qreal max_sat=0.5;
-	if(chroma==0)
-        {
-            hue = 0.0;
-            sat = 0.0;
-        }
-        else
-        {
-        //the following finds the hue
-
-        if(maxval==r)
-            {
-                
-                //hue = fmod(((g-b)/chroma), 6.0);
-                //above doesn't work so let's try this one:
-                if (minval==b) {hue = (g-b)/chroma;}
-                else {hue = (g-b)/chroma + 6.0;}
-            }
-            else if(maxval==g)
-            {
-                hue = (b-r)/chroma + 2.0;
-            }
-            else if(maxval==b)
-            {
-                hue = (r-g)/chroma + 4.0;
-            }
-            hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
- 			//This HSI formula tries to be a
-			//weighted HSL formula, where instead of 0.5, we search for a Max_Sat value, \
                which is the I
-			//at which the saturation is maximum.
-			//This requires using the hue, and combining the weighting values accordingly.
-			qreal segment = 0.166667; //float for every 60 degrees of a 360 hue wheel.
-			if (hue>1.0 || hue<0.0){hue=fmod(hue, 1.0);}
-			if (hue>=0.0 && hue<segment)
-			{max_sat = onethird + onethird*(hue*6);}
-			else if (hue>=segment && hue<(2.0*segment))
-			{max_sat = (onethird*2) - onethird*((hue-segment)*6) ;}
-			else if (hue>=(2.0*segment) && hue<(3.0*segment))
-			{max_sat = onethird + onethird*((hue-2.0*segment)*6);}
-			else if (hue>=(3.0*segment) && hue<(4.0*segment))
-			{max_sat = (onethird*2) - onethird*((hue-3.0*segment)*6) ;}
-			else if (hue>=(4.0*segment) && hue<(5.0*segment))
-			{max_sat =  (onethird) + onethird*((hue-4.0*segment)*6);}
-			else if (hue>=(5.0*segment) && hue<=1.0)
-			{max_sat = (onethird*2) - onethird*((hue-5.0*segment)*6) ;}
-			else
-			{max_sat=0.5;}
-
-			if(max_sat>1.0 || max_sat<0.0){
-			 //this should not show up during normal use
-			 max_sat=(fmod((max_sat*2.0),2.0))/2.0;} //If it does, it'll try to correct, but \
                it's not good!
-			if (intensity <= max_sat){intensity_a = (intensity/max_sat)*0.5;}
-			else{intensity_a = ((intensity-max_sat)/(1-max_sat)*0.5)+0.5;}//This is weighting \
                the intensity for the saturation.
-			if ((sat = chroma) > 0.0)
-			{sat = (intensity <= max_sat) ? (chroma/ (2*intensity_a) ) \
                :(chroma/(2.0-(2*intensity_a) ) ) ;
-			
-			}
-        }
-
-	//if (hue>1.0){hue=1.0;}
-	if (sat>1.0){sat=1.0;}
-	if (sat<0.0){sat=0.0;}
-	//if (intensity>1.0){intensity=1.0;}
-	//if (intensity<0.0){intensity=0.0;}
-
-	*h=hue;
-	*s=sat;
-	*i=intensity;
-
+    qreal onethird = 1.0/3.0;
+    RGBToHSY(r, g, b, h, s, i, onethird, onethird, onethird);
 
 }
 //functions for converting from and back to hsy'
 void HSYToRGB(const qreal h,const qreal s, const qreal y, qreal *red, qreal *green, \
qreal *blue, qreal R, qreal G, qreal B)  {//This function takes H, S and Y values, \
which are converted to rgb.  //Those are then used to create a qcolor.
-	qreal hue = 0.0;
-	qreal sat = 0.0;
-	qreal luma = 0.0;
-	if (h>1.0 || h<0.0){hue=fmod(h, 1.0);} else {hue=h;}
-	if (s>1.0){sat=1.0;}
-	else if (s<0.0){sat=0.0;}
-	else {sat=s;}
-	if (y>1.0){luma=1.0;}
-	else if (y<0.0){luma=0.0;}
-	else {luma=y;}
-	
-	qreal segment = 0.166667;//1/6;
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
+    qreal hue = 0.0;
+    qreal sat = 0.0;
+    qreal luma = 0.0;
+    if (h>1.0 || h<0.0){hue=fmod(h, 1.0);} else {hue=h;}
+    if (s<0.0){sat=0.0;} else {sat=s;}
+    //if (y>1.0){luma=1.0;}
+    if (y<0.0){luma=0.0;}
+    else {luma=y;}
+    
+    qreal segment = 0.166667;//1/6;
+    qreal r=0.0;
+    qreal g=0.0;
+    qreal b=0.0;
 //weights for rgb to Y'(Luma), these are the same weights used in color space maths \
and the desaturate.  //This is not luminance or luminosity, it just quacks like it.
-	//qreal R=0.299;
-	//qreal G=0.587;
-	//qreal B=0.114;
+    //qreal R=0.299;
+    //qreal G=0.587;
+    //qreal B=0.114;
 //The intermediary variables for the weighted HSL forumala, based on the HSL in \
                KoColorConversions.
-	qreal max_sat, m, fract, luma_a, chroma, x;
-	if (hue >= 0.0 && hue < (segment) )
-	{
-		//need to treat this as a weighted hsl thingy.
-		//so first things first, at which luma is the maximum saturation for this hue?
-		//between R and G+R (yellow)
-		max_sat = R + ( G*(hue*6) );	
-		if (luma<=max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*2*luma_a;}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-			fract = hue*6.0;
-			x = (1-fabs(fmod(fract,2)-1))*chroma;
-			r = chroma; g=x; b=0;
-			m = luma-( (R*r)+(B*b)+(G*g) );
-			r += m; g += m; b += m;
-			
-    
-	}	
-	else if (hue >= (segment) && hue < (2.0*segment) )
-	{
-		
-		max_sat = (G+R) - (R*(hue-segment)*6);
-		if (luma<max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = x; g=chroma; b=0;
-		m = luma-( (R*r)+(B*b)+(G*g) );
-		r += m; g += m; b += m;
-			
-
-	}	
-	else if (hue >= (2.0*segment) && hue < (3.0*segment) )
-	{
-		max_sat = G + (B*(hue-2.0*segment)*6);
-		if (luma<max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = 0; g=chroma; b=x;
-		m = luma-( (R*r)+(B*b)+(G*g) );
-		r += m; g += m; b += m;
-	}	
-	else if (hue >= (3.0*segment) && hue < (4.0*segment) )
-	{	max_sat = (G+B) - (G*(hue-3.0*segment)*6);	
-		if (luma<max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = 0; g=x; b=chroma;
-		m = luma-( (R*r)+(B*b)+(G*g) );
-		r += m; g += m; b += m;
-	}
-	else if (hue >= (4.0*segment) && hue < (5*segment) )
-	{
-		max_sat = B + (R*((hue-4.0*segment)*6));	
-		if (luma<max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = x; g=0; b=chroma;
-		m = luma-( (R*r)+(B*b)+(G*g) );
-		r += m; g += m; b += m;
-	}
-	else if (hue >= (5.0*segment) && hue <= 1.0)
-	{
-	max_sat = (B+R) - (B*(hue-5.0*segment)*6);	
-		if (luma<max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);}
-		else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);}
-		
-		fract = hue*6.0;
-		x = (1-fabs(fmod(fract,2)-1) )*chroma;
-		r = chroma; g=0; b=x;
-		m = luma-( (R*r)+(B*b)+(G*g) );
-		r += m; g += m; b += m;
-	}
-	else
-	{
-	r=0.0;
-	g=0.0;
-	b=0.0;
-	}
-
-	//dbgPigment<<"red: "<<r<<", green: "<<g<<", blue: "<<b;
-	if (r>1.0){r=1.0;}
-	if (g>1.0){g=1.0;}
-	if (b>1.0){b=1.0;}
-	if (r<0.0){r=0.0;}
-	if (g<0.0){g=0.0;}
-	if (b<0.0){b=0.0;}
-	
-	*red=r;
-	*green=g;
-	*blue=b;
+    qreal max_sat, m, fract, luma_a, chroma, x;
+    if (hue >= 0.0 && hue < (segment) ) {
+            //need to treat this as a weighted hsl thingy.
+            //so first things first, at which luma is the maximum saturation for \
this hue? +            //between R and G+R (yellow)
+        max_sat = R + ( G*(hue*6) );	
+        if (luma<=max_sat){luma_a = (luma/max_sat)*0.5; chroma=sat*2*luma_a;}
+        else {luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; \
chroma=sat*(2-2*luma_a);} +
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1))*chroma;
+        r = chroma; g=x; b=0;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else if (hue >= (segment) && hue < (2.0*segment) ) {
+        max_sat = (G+R) - (R*(hue-segment)*6);
+
+        if (luma<max_sat) {
+            luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);
+        } else {
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);
+        }
+
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1) )*chroma;
+        r = x; g=chroma; b=0;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else if (hue >= (2.0*segment) && hue < (3.0*segment) ) {
+        max_sat = G + (B*(hue-2.0*segment)*6);
+        if (luma<max_sat) { 
+            luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);
+        } else {
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);
+        }
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1) )*chroma;
+        r = 0; g=chroma; b=x;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else if (hue >= (3.0*segment) && hue < (4.0*segment) ) {
+        max_sat = (G+B) - (G*(hue-3.0*segment)*6);	
+        if (luma<max_sat){
+            luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);
+        } else {
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);
+        }
+
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1) )*chroma;
+        r = 0; g=x; b=chroma;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else if (hue >= (4.0*segment) && hue < (5*segment) ) {
+        max_sat = B + (R*((hue-4.0*segment)*6));	
+        if (luma<max_sat) {
+            luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);
+        } else {
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);
+        }
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1) )*chroma;
+        r = x; g=0; b=chroma;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else if (hue >= (5.0*segment) && hue <= 1.0) {
+        max_sat = (B+R) - (B*(hue-5.0*segment)*6);	
+        if (luma<max_sat){
+            luma_a = (luma/max_sat)*0.5; chroma=sat*(2*luma_a);
+        } else {
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5; chroma=sat*(2-2*luma_a);
+        }
+        fract = hue*6.0;
+        x = (1-fabs(fmod(fract,2)-1) )*chroma;
+        r = chroma; g=0; b=x;
+        m = luma-( (R*r)+(B*b)+(G*g) );
+        r += m; g += m; b += m;
+    } else {
+        r=0.0;
+        g=0.0;
+        b=0.0;
+    }
+
+    //dbgPigment<<"red: "<<r<<", green: "<<g<<", blue: "<<b;
+    //if (r>1.0){r=1.0;}
+    //if (g>1.0){g=1.0;}
+    //if (b>1.0){b=1.0;}
+    //don't limit upwards due to floating point.
+    if (r<0.0){r=0.0;}
+    if (g<0.0){g=0.0;}
+    if (b<0.0){b=0.0;}
+
+    *red=r;
+    *green=g;
+    *blue=b;
 }
 void RGBToHSY(const qreal r,const qreal g,const qreal b, qreal *h, qreal *s, qreal \
*y, qreal R, qreal G, qreal B)  {
 //This is LUMA btw, not Luminance.
 //Using these RGB values, we calculate the H, S and I.
-	qreal red; qreal green; qreal blue;
-	if (r>1.0){red=1.0;} else if (r<0.0){red=0.0;} else {red=r;}
-	if (g>1.0){green=1.0;} else if (g<0.0){green=0.0;} else {green=g;}
-	if (b>1.0){blue=1.0;} else if (b<0.0){blue=0.0;} else {blue=b;}
-	
-	qreal minval = qMin(r, qMin(g, b));
-	qreal maxval = qMax(r, qMax(g, b));
-	qreal hue = 0.0;
-	qreal sat = 0.0;
-	qreal luma = 0.0;
-	//weights for rgb, these are the same weights used in color space maths and the \
                desaturate.
-	//qreal R=0.299;
-	//qreal G=0.587;
-	//qreal B=0.114;
-	luma=(R*red+G*green+B*blue);
-	qreal luma_a=luma;//defined later
-	qreal chroma = maxval-minval;
-	qreal max_sat=0.5;
-	if(chroma==0)
-        {
-            hue = 0.0;
-            sat = 0.0;
-        }
-        else
-        {
+    qreal red; qreal green; qreal blue;
+    if (r<0.0){red=0.0;} else {red=r;}
+    if (g<0.0){green=0.0;} else {green=g;}
+    if (b<0.0){blue=0.0;} else {blue=b;}
+
+    qreal minval = qMin(r, qMin(g, b));
+    qreal maxval = qMax(r, qMax(g, b));
+    qreal hue = 0.0;
+    qreal sat = 0.0;
+    qreal luma = 0.0;
+    //weights for rgb, these are the same weights used in color space maths and the \
desaturate. +    //qreal R=0.299;
+    //qreal G=0.587;
+    //qreal B=0.114;
+    luma=(R*red+G*green+B*blue);
+    qreal luma_a=luma;//defined later
+    qreal chroma = maxval-minval;
+    qreal max_sat=0.5;
+    if(chroma==0) {
+        hue = 0.0;
+        sat = 0.0;
+    } else {
         //the following finds the hue
 
-        if(maxval==r)
-            {
-                //hue = fmod(((g-b)/chroma), 6.0);
-                //above doesn't work so let's try this one:
-                if (minval==b) {hue = (g-b)/chroma;}
-                else {hue = (g-b)/chroma + 6.0;}
-            }
-            else if(maxval==g)
-            {
-                hue = (b-r)/chroma + 2.0;
+        if(maxval==r) {
+            //hue = fmod(((g-b)/chroma), 6.0);
+            //above doesn't work so let's try this one:
+            if (minval==b) {
+                hue = (g-b)/chroma;
+            } else {
+                hue = (g-b)/chroma + 6.0;
             }
-            else if(maxval==b)
-            {
-                hue = (r-g)/chroma + 4.0;
-            }
-            hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
- 			//Most HSY formula will tell you that Sat=Chroma. However, this HSY' formula \
                tries to be a
-			//weighted HSL formula, where instead of 0.5, we search for a Max_Sat value, \
                which is the Y'
-			//at which the saturation is maximum.
-			//This requires using the hue, and combining the weighting values accordingly.
-			qreal segment = 0.166667;
-			if (hue>1.0 || hue<0.0){hue=fmod(hue, 1.0);}
-			
-			if (hue>=0.0 && hue<segment)
-			{max_sat = R + G*(hue*6);}
-			else if (hue>=segment && hue<(2.0*segment))
-			{max_sat = (G+R) - R*((hue-segment)*6) ;}
-			else if (hue>=(2.0*segment) && hue<(3.0*segment))
-			{max_sat = G + B*((hue-2.0*segment)*6);}
-			else if (hue>=(3.0*segment) && hue<(4.0*segment))
-			{max_sat = (B+G) - G*((hue-3.0*segment)*6) ;}
-			else if (hue>=(4.0*segment) && hue<(5.0*segment))
-			{max_sat =  (B) + R*((hue-4.0*segment)*6);}
-			else if (hue>=(5.0*segment) && hue<=1.0)
-			{max_sat = (R+B) - B*((hue-5.0*segment)*6);}
-			else
-			{max_sat=0.5;}
-
-			if(max_sat>1.0 || max_sat<0.0){ //This debug message should not show up during \
                normal use
-			 max_sat=(fmod(max_sat,1.0));} //If it does, it'll try to correct, but it's not \
                good!
-			if (luma <= max_sat){luma_a = (luma/max_sat)*0.5;}
-			else{luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5;}//This is weighting the luma \
                for the saturation)
-			if ((sat = chroma) > 0.0)
-			{sat = (luma <= max_sat) ? (chroma/ (2*luma_a) ) :(chroma/(2.0-(2*luma_a) ) ) ;}
+        } else if(maxval==g) {
+            hue = (b-r)/chroma + 2.0;
+        } else if(maxval==b) {
+            hue = (r-g)/chroma + 4.0;
+        }
+
+        hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
+        //Most HSY formula will tell you that Sat=Chroma. However, this HSY' formula \
tries to be a +        //weighted HSL formula, where instead of 0.5, we search for a \
Max_Sat value, which is the Y' +        //at which the saturation is maximum.
+        //This requires using the hue, and combining the weighting values \
accordingly. +        qreal segment = 0.166667;
+        if (hue>1.0 || hue<0.0) {
+            hue=fmod(hue, 1.0);
+        }
+
+        if (hue>=0.0 && hue<segment) {
+            max_sat = R + G*(hue*6);
+        } else if (hue>=segment && hue<(2.0*segment)) {
+            max_sat = (G+R) - R*((hue-segment)*6);
+        } else if (hue>=(2.0*segment) && hue<(3.0*segment)) {
+            max_sat = G + B*((hue-2.0*segment)*6);
+        } else if (hue>=(3.0*segment) && hue<(4.0*segment)) {
+            max_sat = (B+G) - G*((hue-3.0*segment)*6);
+        } else if (hue>=(4.0*segment) && hue<(5.0*segment)) {
+            max_sat =  (B) + R*((hue-4.0*segment)*6);
+        } else if (hue>=(5.0*segment) && hue<=1.0) {
+            max_sat = (R+B) - B*((hue-5.0*segment)*6);
+        } else {
+            max_sat=0.5;
         }
 
-	if (sat>1.0){sat=1.0;}
-	if (luma>1.0){luma=1.0;}
-	if (sat<0.0){sat=0.0;}
-	if (luma<0.0){luma=0.0;}
+        if(max_sat>1.0 || max_sat<0.0){ //This should not show up during normal use
+            max_sat=(fmod(max_sat,1.0));
+        } //If it does, it'll try to correct, but it's not good!
 
-	*h=hue;
-	*s=sat;
-	*y=luma;
+            //This is weighting the luma for the saturation)
+        if (luma <= max_sat) {
+            luma_a = (luma/max_sat)*0.5;
+        } else{
+            luma_a = ((luma-max_sat)/(1-max_sat)*0.5)+0.5;
+        }
+            
+        if (chroma > 0.0) {
+            sat = (luma <= max_sat) ? (chroma/ (2*luma_a) ) :(chroma/(2.0-(2*luma_a) \
) ) ; +        }
+    }
+
+    //if (sat>1.0){sat=1.0;}
+    //if (luma>1.0){luma=1.0;}
+    if (sat<0.0){sat=0.0;}
+    if (luma<0.0){luma=0.0;}
+
+    *h=hue;
+    *s=sat;
+    *y=luma;
 
 
 }
@@ -847,174 +654,256 @@ void HCIToRGB(const qreal h, const qreal c, const qreal i, \
qreal *red, qreal *gr  {
 //This function may not be correct, but it's based on the HCY function on the basis \
of seeing HCI as similar  //to the weighted HCY, but assuming that the weights are \
                the same(one-third).
-	qreal hue=0.0;
-	qreal chroma=0.0;
-	qreal intensity=0.0;	
-	if (i>1.0){intensity = 1.0;} else if(i<0.0){intensity = 0.0;} else{intensity = i;}
-	if (h>1.0 || h<0.0){hue=fmod(h, 1.0);} else {hue=h;}
-	if (c>1.0){chroma = 1.0;} else if(c<0.0){chroma = 0.0;} else{chroma = c;}
-	const qreal onethird = 1.0/3.0;
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
+    qreal hue=0.0;
+    qreal chroma=0.0;
+    qreal intensity=0.0;	
+    if(i<0.0){intensity = 0.0;} else{intensity = i;}
+    if (h>1.0 || h<0.0){hue=fmod(h, 1.0);} else {hue=h;}
+    if(c<0.0){chroma = 0.0;} else{chroma = c;}
+    const qreal onethird = 1.0/3.0;
+    qreal r=0.0;
+    qreal g=0.0;
+    qreal b=0.0;
 	
-	int fract = static_cast<int>(hue*6.0);
-	qreal x = (1-fabs(fmod(fract,2)-1) )*chroma;
-	switch (fract) {
-	case 0:r = chroma; g=x; b=0;break;
-	case 1:r = x; g=chroma; b=0;break;
-	case 2:r = 0; g=chroma; b=x;break;
-	case 3:r = 0; g=x; b=chroma;break;
-	case 4:r = x; g=0; b=chroma;break;
-	case 5:r = chroma; g=0; b=x;break;
-	}
-	qreal m = intensity-( onethird*(r+g+b) );
-	r += m; g += m; b += m;
-
-	if (r>1.0){r=1.0;}
-	if (g>1.0){g=1.0;}
-	if (b>1.0){b=1.0;}
-	if (r<0.0){r=0.0;}
-	if (g<0.0){g=0.0;}
-	if (b<0.0){b=0.0;}
-
-	*red=r;
-	*green=g;
-	*blue=b;
+    int fract = static_cast<int>(hue*6.0);
+    qreal x = (1-fabs(fmod(hue*6.0,2)-1) )*chroma;
+    switch (fract) {
+        case 0:r = chroma; g=x; b=0;break;
+        case 1:r = x; g=chroma; b=0;break;
+        case 2:r = 0; g=chroma; b=x;break;
+        case 3:r = 0; g=x; b=chroma;break;
+        case 4:r = x; g=0; b=chroma;break;
+        case 5:r = chroma; g=0; b=x;break;
+    }
+    qreal m = intensity-( onethird*(r+g+b) );
+    r += m; g += m; b += m;
+
+    *red=r;
+    *green=g;
+    *blue=b;
 }
 
 void RGBToHCI(const qreal r,const qreal g,const qreal b, qreal *h, qreal *c, qreal \
*i)  {
-	qreal minval = qMin(r, qMin(g, b));
-	qreal maxval = qMax(r, qMax(g, b));
-	qreal hue = 0.0;
-	qreal sat = 0.0;
-	qreal intensity = 0.0;
-	intensity=(r+g+b)/3.0;
-	qreal chroma = maxval-minval;	
-		if(chroma==0)
-        {
-            hue = 0.0;
-            sat = 0.0;
-        }
-        else
-        {
+    qreal minval = qMin(r, qMin(g, b));
+    qreal maxval = qMax(r, qMax(g, b));
+    qreal hue = 0.0;
+    qreal sat = 0.0;
+    qreal intensity = 0.0;
+    intensity=(r+g+b)/3.0;
+    qreal chroma = maxval-minval;
+    if(chroma==0) {
+        hue = 0.0;
+        sat = 0.0;
+    } else {
         //the following finds the hue
 
-        if(maxval==r)
-            {
-                hue = fmod(((g-b)/chroma), 6.0);
+        if(maxval==r) {
+            if (minval==b) {
+                hue = (g-b)/chroma;
+            } else {
+                hue = (g-b)/chroma + 6.0;
             }
-            else if(maxval==g)
-            {
-                hue = (b-r)/chroma + 2.0;
-            }
-            else if(maxval==b)
-            {
-                hue = (r-g)/chroma + 4.0;
-            }
-            hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
-			sat= 1-(minval/intensity);
-		}
-	if (hue>1.0){hue=1.0;}
-	if (hue<0.0){hue=0.0;}
-	if (sat>1.0){sat=1.0;}
-	if (sat<0.0){sat=0.0;}
-	if (intensity>1.0){intensity=1.0;}
-	if (intensity<0.0){intensity=0.0;}
-
-	*h=hue;
-	*c=sat;
-	*i=intensity;
+        } else if(maxval==g) {
+            hue = (b-r)/chroma + 2.0;
+        } else if(maxval==b) {
+            hue = (r-g)/chroma + 4.0;
+        }
+        hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
+        sat= 1-(minval/intensity);
+    }
+
+    *h=hue;
+    *c=sat;
+    *i=intensity;
 
 }
 void HCYToRGB(const qreal h, const qreal c, const qreal y, qreal *red, qreal *green, \
qreal *blue, qreal R, qreal G, qreal B)  {
-	qreal hue=0.0;
-	qreal chroma=0.0;
-	qreal luma=0.0;
-	if (y>1.0){luma = 1.0;} else if(y<0.0){luma = 0.0;} else{luma = y;}
-	if (h>1.0 || h<0.0){hue=(fmod((h*2.0), 2.0))/2.0;} else {hue=h;}
-	if (c>1.0){chroma = 1.0;} else if(c<0.0){chroma = 0.0;} else{chroma = c;}
-	//const qreal R=0.299;
-	//const qreal G=0.587;
-	//const qreal B=0.114;
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
-	
-	int fract =static_cast<int>(hue*6.0); 
-	qreal x = (1-fabs(fmod(fract,2)-1) )*chroma;
-	switch (fract) {
-	case 0:r = chroma; g=x; b=0;break;
-	case 1:r = x; g=chroma; b=0;break;
-	case 2:r = 0; g=chroma; b=x;break;
-	case 3:r = 0; g=x; b=chroma;break;
-	case 4:r = x; g=0; b=chroma;break;
-	case 5:r = chroma; g=0; b=x;break;
-	}
-	qreal m = luma-( (R*r)+(B*b)+(G*g) );
-	r += m; g += m; b += m;
-
-	if (r>1.0){r=1.0;}
-	if (g>1.0){g=1.0;}
-	if (b>1.0){b=1.0;}
-	if (r<0.0){r=0.0;}
-	if (g<0.0){g=0.0;}
-	if (b<0.0){b=0.0;}
-
-	*red=r;
-	*green=g;
-	*blue=b;
+    qreal hue=0.0;
+    qreal chroma=c;
+    qreal luma=y;
+    if (h>1.0 || h<0.0){hue=(fmod((h*2.0), 2.0))/2.0;} else {hue=h;}
+    //const qreal R=0.299;
+    //const qreal G=0.587;
+    //const qreal B=0.114;
+    qreal r=0.0;
+    qreal g=0.0;
+    qreal b=0.0;
+
+    int fract =static_cast<int>(hue*6.0); 
+    qreal x = (1-fabs(fmod(hue*6.0,2)-1) )*chroma;
+    switch (fract) {
+        case 0:r = chroma; g=x; b=0;break;
+        case 1:r = x; g=chroma; b=0;break;
+        case 2:r = 0; g=chroma; b=x;break;
+        case 3:r = 0; g=x; b=chroma;break;
+        case 4:r = x; g=0; b=chroma;break;
+        case 5:r = chroma; g=0; b=x;break;
+    }
+    qreal m = luma-( (R*r)+(B*b)+(G*g) );
+    r += m; g += m; b += m;
+
+    *red=r;
+    *green=g;
+    *blue=b;
 }
 
 void RGBToHCY(const qreal r,const qreal g,const qreal b, qreal *h, qreal *c, qreal \
*y, qreal R, qreal G, qreal B)  {
-	qreal minval = qMin(r, qMin(g, b));
-	qreal maxval = qMax(r, qMax(g, b));
-	qreal hue = 0.0;
-	qreal chroma = 0.0;
-	qreal luma = 0.0;
-	//weights for rgb, these are the same weights used in color space maths and the \
                desaturate.
-	//qreal R=0.299;
-	//qreal G=0.587;
-	//qreal B=0.114;
-	luma=(R*r+G*g+B*b);
-	chroma = maxval-minval;
-	
-		if(chroma==0)
-        {
-            hue = 0.0;
-        }
-        else
-        {
+    qreal minval = qMin(r, qMin(g, b));
+    qreal maxval = qMax(r, qMax(g, b));
+    qreal hue = 0.0;
+    qreal chroma = 0.0;
+    qreal luma = 0.0;
+    //weights for rgb, these are the same weights used in color space maths and the \
desaturate. +    //qreal R=0.299;
+    //qreal G=0.587;
+    //qreal B=0.114;
+    luma=(R*r+G*g+B*b);
+    chroma = maxval-minval;
+
+    if(chroma==0) {
+        hue = 0.0;
+    }
+    else {
         //the following finds the hue
 
-        if(maxval==r)
-            {
-                hue = fmod(((g-b)/chroma), 6.0);
+        if(maxval==r) {
+            //hue = fmod(((g-b)/chroma), 6.0);
+            //above doesn't work so let's try this one:
+            if (minval==b) {
+                hue = (g-b)/chroma;
+            } else {
+                hue = (g-b)/chroma + 6.0;
             }
-            else if(maxval==g)
-            {
-                hue = (b-r)/chroma + 2.0;
-            }
-            else if(maxval==b)
-            {
-                hue = (r-g)/chroma + 4.0;
-            }
-            hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
-				
-		}
-	if (hue>1.0){hue=1.0;}
-	if (hue<0.0){hue=0.0;}
-	if (chroma>1.0){chroma=1.0;}
-	if (luma>1.0){luma=1.0;}
-	if (chroma<0.0){chroma=0.0;}
-	if (luma<0.0){luma=0.0;}
-
-	*h=hue;
-	*c=chroma;
-	*y=luma;	
+        } else if(maxval==g) {
+            hue = (b-r)/chroma + 2.0;
+        } else if(maxval==b) {
+            hue = (r-g)/chroma + 4.0;
+        }
+        hue /=6.0;//this makes sure that hue is in the 0-1.0 range.
+    }
+    if (chroma<0.0){chroma=0.0;}
+    if (luma<0.0){luma=0.0;}
+
+    *h=qBound(0.0,hue,1.0);
+    *c=chroma;
+    *y=luma;
 
 }
+void RGBToYUV(const qreal r,const qreal g,const qreal b, qreal *y, qreal *u, qreal \
*v, qreal R, qreal G, qreal B) +{
+    qreal uvmax = 0.5;
+    qreal luma = R*r+G*g+B*b;
+    qreal chromaBlue = uvmax*( (b - luma) / (1.0-B) );
+    qreal chromaRed  = uvmax*( (r - luma) / (1.0-R) );
+
+    *y = luma; //qBound(0.0,luma,1.0);
+    *u = chromaBlue+uvmax;//qBound(0.0,chromaBlue+ uvmax,1.0);
+    *v = chromaRed+uvmax;//qBound(0.0,chromaRed + uvmax,1.0);
+}
+void YUVToRGB(const qreal y, const qreal u, const qreal v, qreal *r, qreal *g, qreal \
*b, qreal R, qreal G, qreal B) +{
+    qreal uvmax = 0.5;
+    qreal chromaBlue = u-uvmax;//qBound(0.0,u,1.0)- uvmax;//put into -0.5-+0.5 \
range// +    qreal chromaRed = v-uvmax;//qBound(0.0,v,1.0)- uvmax;
+
+    qreal negB  = 1.0-B;
+    qreal negR  = 1.0-R;
+    qreal red   = y+(chromaRed  * (negR / uvmax) );
+    qreal green = y-(chromaBlue * ((B*negB) / (uvmax*G)) ) - (chromaRed* ((R*negR) / \
(uvmax*G))); +    qreal blue  = y+(chromaBlue * (negB / uvmax) );
+
+    *r=red;//qBound(0.0,red  ,1.0);
+    *g=green;//qBound(0.0,green,1.0);
+    *b=blue;//qBound(0.0,blue ,1.0);
+}
 
+void LabToLCH(const qreal l, const qreal a, const qreal b, qreal *L, qreal *C, qreal \
*H) +{
+    qreal atemp =  (a - 0.5)*10.0;//the multiplication is only so that we get out of \
floating-point maths +    qreal btemp =  (b - 0.5)*10.0;
+    *L=qBound(0.0,l,1.0);
+    *C=sqrt( pow(atemp,2.0) + pow(btemp,2.0) )*0.1;
+    qreal hue = (atan2(btemp,atemp))* 180.0 / M_PI;
+    
+    if (hue<0.0) {
+        hue+=360.0;
+    } else {
+        hue = fmod(hue, 360.0);
+    }
+    *H=hue/360.0;
+}
+
+void LCHToLab(const qreal L, const qreal C, const qreal H, qreal *l, qreal *a, qreal \
*b) +{
+    qreal chroma = qBound(0.0,C,1.0);
+    qreal hue = (qBound(0.0,H,1.0)*360.0)* M_PI / 180.0;
+    *l=qBound(0.0,L,1.0);
+    *a=(chroma * cos(hue) ) + 0.5;
+    *b=(chroma * sin(hue) ) + 0.5;
+}
+
+void XYZToxyY(const qreal X, const qreal Y, const qreal Z, qreal *x, qreal *y, qreal \
*yY) +{
+    qBound(0.0,X,1.0);
+    qBound(0.0,Y,1.0);
+    qBound(0.0,Z,1.0);
+    *x=X/(X+Y+Z);
+    *y=Y/(X+Y+Z);
+    *yY=Y;
+}  
+void xyYToXYZ(const qreal x, const qreal y, const qreal yY, qreal *X, qreal *Y, \
qreal *Z) +{
+    qBound(0.0,x,1.0);
+    qBound(0.0,y,1.0);
+    qBound(0.0,yY,1.0);
+    *X=(x*yY)/y;
+    *Z=((1.0-x-y)/yY)/y;
+    *Y=yY;
+}
+
+void CMYToCMYK(qreal *c, qreal *m, qreal *y, qreal *k)
+{
+    qreal cyan, magenta, yellow, key = 1.0;
+    cyan    = *c;
+    magenta = *m;
+    yellow  = *y;
+    if ( cyan    < key ) {key = cyan;}
+    if ( magenta < key ) {key = magenta;}
+    if ( yellow  < key ) {key = yellow;}
+    
+    if ( key == 1 ) { //Black
+        cyan    = 0;
+        magenta = 0;
+        yellow  = 0;
+    }
+    else {
+        cyan    = ( cyan    - key ) / ( 1.0 - key );
+        magenta = ( magenta - key ) / ( 1.0 - key );
+        yellow  = ( yellow  - key ) / ( 1.0 - key );
+    }
+    
+    *c=qBound(0.0,cyan   ,1.0);
+    *m=qBound(0.0,magenta,1.0);
+    *y=qBound(0.0,yellow ,1.0);
+    *k=qBound(0.0,key    ,1.0);
+}
+
+/*code from easyrgb.com*/
+void CMYKToCMY(qreal *c, qreal *m, qreal *y, qreal *k)
+{
+    qreal key     = *k;
+    qreal cyan    = *c;
+    qreal magenta = *m;
+    qreal yellow  = *y;
+    
+    cyan    = ( cyan    * ( 1.0 - key ) + key );
+    magenta = ( magenta * ( 1.0 - key ) + key );
+    yellow  = ( yellow  * ( 1.0 - key ) + key );
+    
+    *c=qBound(0.0,cyan   ,1.0);
+    *m=qBound(0.0,magenta,1.0);
+    *y=qBound(0.0,yellow ,1.0);
+}
diff --git a/libs/pigment/KoColorConversions.h b/libs/pigment/KoColorConversions.h
index b3d6eb7..852ed40 100644
--- a/libs/pigment/KoColorConversions.h
+++ b/libs/pigment/KoColorConversions.h
@@ -68,6 +68,17 @@ KRITAPIGMENT_EXPORT void RGBToHCI(const qreal r, const qreal g, \
const qreal b, q  KRITAPIGMENT_EXPORT void HCYToRGB(const qreal h, const qreal s, \
const qreal y, qreal *red, qreal *green, qreal *blue,  qreal R=0.299, qreal G=0.587, \
qreal B=0.114);  KRITAPIGMENT_EXPORT void RGBToHCY(const qreal r, const qreal g, \
const qreal b, qreal *h, qreal *c, qreal *y,  qreal R=0.299, qreal G=0.587, qreal \
B=0.114);  
+KRITAPIGMENT_EXPORT void RGBToYUV( qreal r, qreal g, qreal b, qreal *y, qreal *cb, \
qreal *cr, qreal R=0.299, qreal G=0.587, qreal B=0.114); +KRITAPIGMENT_EXPORT void \
YUVToRGB(const qreal y, const qreal cb, const qreal cr, qreal *r, qreal *g, qreal *b, \
qreal R=0.299, qreal G=0.587, qreal B=0.114); +
+KRITAPIGMENT_EXPORT void LabToLCH(const qreal l, const qreal a, const qreal b, qreal \
*L, qreal *C, qreal *H); +KRITAPIGMENT_EXPORT void LCHToLab(const qreal L, const \
qreal C, const qreal H, qreal *l, qreal *a, qreal *b); +
+KRITAPIGMENT_EXPORT void XYZToxyY(const qreal X, const qreal Y, const qreal Z, qreal \
*x, qreal *y, qreal *yY); +KRITAPIGMENT_EXPORT void xyYToXYZ(const qreal x, const \
qreal y, const qreal yY, qreal *X, qreal *Y, qreal *Z); +
+KRITAPIGMENT_EXPORT void CMYToCMYK(qreal *c, qreal *m, qreal *y, qreal *k);
+KRITAPIGMENT_EXPORT void CMYKToCMY(qreal *c, qreal *m, qreal *y, qreal *k);
 
 #endif // _KO_COLORCONVERSIONS_H_
 
diff --git a/libs/pigment/KoColorProfile.cpp b/libs/pigment/KoColorProfile.cpp
index f363a2d..c22aa40 100644
--- a/libs/pigment/KoColorProfile.cpp
+++ b/libs/pigment/KoColorProfile.cpp
@@ -24,6 +24,8 @@ struct Q_DECL_HIDDEN KoColorProfile::Private {
     QString name;
     QString info;
     QString fileName;
+    QString manufacturer;
+    QString copyright;
 };
 
 KoColorProfile::KoColorProfile(const QString &fileName) : d(new Private)
@@ -63,7 +65,14 @@ QString KoColorProfile::info() const
 {
     return d->info;
 }
-
+QString KoColorProfile::manufacturer() const
+{
+    return d->manufacturer;
+}
+QString KoColorProfile::copyright() const
+{
+    return d->copyright;
+}
 QString KoColorProfile::fileName() const
 {
     return d->fileName;
@@ -82,3 +91,11 @@ void KoColorProfile::setInfo(const QString &info)
 {
     d->info = info;
 }
+void KoColorProfile::setManufacturer(const QString &manufacturer)
+{
+    d->manufacturer = manufacturer;
+}
+void KoColorProfile::setCopyright(const QString &copyright)
+{
+    d->copyright = copyright;
+}
\ No newline at end of file
diff --git a/libs/pigment/KoColorProfile.h b/libs/pigment/KoColorProfile.h
index b71af7c..acd45b2 100644
--- a/libs/pigment/KoColorProfile.h
+++ b/libs/pigment/KoColorProfile.h
@@ -85,6 +85,13 @@ public:
      * @return the info of this profile
      */
     QString info() const;
+    /** @return manufacturer of the profile
+     */
+    QString manufacturer() const;
+    /**
+     * @return the copyright of the profile
+     */
+    QString copyright() const;
     /**
      * @return the filename of the profile (it might be empty)
      */
@@ -95,6 +102,10 @@ public:
     void setFileName(const QString &filename);
 
     /**
+     * Return version
+     */
+    virtual float version() const = 0;
+    /**
      * @return true if you can use this profile can be used to convert color from a \
                different
      * profile to this one
      */
@@ -109,30 +120,58 @@ public:
     virtual bool isSuitableForDisplay() const = 0;
 
     /**
+     * @return which rendering intents are supported
+     */
+    virtual bool supportsPerceptual() const = 0;
+    virtual bool supportsSaturation() const = 0;
+    virtual bool supportsAbsolute() const = 0;
+    virtual bool supportsRelative() const = 0;
+    /**
      * @return if the profile has colorants.
      */
     virtual bool hasColorants() const = 0;
     /**
      * @return a qvector <double>(9) with the RGB colorants in XYZ
      */
-    virtual QVector <double> getColorantsXYZ() const = 0;
+    virtual QVector <qreal> getColorantsXYZ() const = 0;
     /**
      * @return a qvector <double>(9) with the RGB colorants in xyY
      */
-    virtual QVector <double> getColorantsxyY() const = 0;
+    virtual QVector <qreal> getColorantsxyY() const = 0;
     /**
      * @return a qvector <double>(3) with the whitepoint in XYZ
      */
-    virtual QVector <double> getWhitePointXYZ() const = 0;
+    virtual QVector <qreal> getWhitePointXYZ() const = 0;
     /**
      * @return a qvector <double>(3) with the whitepoint in xyY
      */
-    virtual QVector <double> getWhitePointxyY() const = 0;
+    virtual QVector <qreal> getWhitePointxyY() const = 0;
     
     /**
      * @return estimated gamma for RGB and Grayscale profiles
      */
-    virtual QVector <double> getEstimatedTRC() const = 0;
+    virtual QVector <qreal> getEstimatedTRC() const = 0;
+
+    /**
+     * @return if the profile has a TRC(required for linearisation).
+     */
+    virtual bool hasTRC() const = 0;
+    /**
+     * Linearizes a QVector of 3 doubles long, if it's possible to Linearize
+     * if not, returns the same QVector
+     */
+    virtual void linearizeFloatValue(QVector <qreal> & Value) const = 0;
+    /**
+     * Delinearizes a QVector of 3 doubles long, if it's possible to delinearize
+     * if not, returns the same QVector. Effectively undoes LinearizeFloatValue.
+     */
+    virtual void delinearizeFloatValue(QVector <qreal> & Value) const = 0;
+    /**
+     * More imprecise versions of the above(limited to 16bit, and can't
+     * delinearize above 1.0.) Use this for filters and images.
+     */
+    virtual void linearizeFloatValueFast(QVector <qreal> & Value) const = 0;
+    virtual void delinearizeFloatValueFast(QVector <qreal> & Value) const = 0;
     
     virtual bool operator==(const KoColorProfile&) const = 0;
 
@@ -152,6 +191,14 @@ protected:
      * Allows to set the information string of that profile.
      */
     void setInfo(const QString &info);
+    /**
+     * Allows to set the manufacturer string of that profile.
+     */
+    void setManufacturer(const QString &manufacturer);
+    /**
+     * Allows to set the copyright string of that profile.
+     */
+    void setCopyright(const QString &copyright);
 
 private:
     struct Private;
diff --git a/libs/pigment/KoColorSpace.cpp b/libs/pigment/KoColorSpace.cpp
index 3ea6b13..8c50f98 100644
--- a/libs/pigment/KoColorSpace.cpp
+++ b/libs/pigment/KoColorSpace.cpp
@@ -40,6 +40,8 @@
 #include <QThreadStorage>
 #include <QByteArray>
 #include <QBitArray>
+#include <QPolygonF>
+#include <QPointF>
 
 
 KoColorSpace::KoColorSpace()
@@ -59,6 +61,10 @@ KoColorSpace::KoColorSpace(const QString &id, const QString &name, \
KoMixColorsOp  d->transfoFromRGBA16 = 0;
     d->transfoToLABA16 = 0;
     d->transfoFromLABA16 = 0;
+    d->gamutXYY = QPolygonF();
+    d->TRCXYY = QPolygonF();
+    d->colorants = QVector <qreal> (0);
+    d->lumaCoefficients = QVector <qreal> (0);
     d->deletability = NotOwnedByRegistry;
 }
 
@@ -102,6 +108,183 @@ QString KoColorSpace::name() const
     return d->name;
 }
 
+//Color space info stuff.
+QPolygonF KoColorSpace::gamutXYY() const
+{
+    if (d->gamutXYY.empty()) {
+        //now, let's decide on the boundary. This is a bit tricky because icc \
profiles can be both matrix-shaper and cLUT at once if the maker so pleases. +        \
//first make a list of colors. +        qreal max = 1.0;
+        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("XYZAF16")->defaultProfile(); +   \
const KoColorSpace* xyzColorSpace = \
KoColorSpaceRegistry::instance()->colorSpace("XYZA", "F16", name); +        quint8 \
data[channelCount()]; +        quint8 data2[4];//xyza is 4.
+        //QVector <qreal> sampleCoordinates(pow(colorChannelCount(),samples));
+        //sampleCoordinates.fill(0.0);
+        QVector <float> channelValuesF(channelCount());//for getting the \
coordinates. +        for(int x=0;x<samples;x++){
+            if (colorChannelCount()==1) {//gray
+                channelValuesF[0]=(max/(samples-1))*(x);
+                channelValuesF[1]=max;
+                fromNormalisedChannelsValue(data, channelValuesF);
+                convertPixelsTo(data, data2, xyzColorSpace, 1, \
KoColorConversionTransformation::IntentAbsoluteColorimetric, \
KoColorConversionTransformation::adjustmentConversionFlags()); +                \
xyzColorSpace->normalisedChannelsValue(data2,channelValuesF); +                qreal \
x = channelValuesF[0]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); +      \
qreal y = channelValuesF[1]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); \
+                d->gamutXYY<< QPointF(x,y); +            } else {
+                for(int y=0;y<samples;y++){
+                    for(int z=0;z<samples;z++){
+                        if (colorChannelCount()==4) {
+                            for(int k=0;k<samples;k++){
+                                channelValuesF[0]=(max/(samples-1))*(x);
+                                channelValuesF[1]=(max/(samples-1))*(y);
+                                channelValuesF[2]=(max/(samples-1))*(z);
+                                channelValuesF[3]=(max/(samples-1))*(k);
+                                channelValuesF[4]=max;
+                                fromNormalisedChannelsValue(data, channelValuesF);
+                                convertPixelsTo(data, data2, xyzColorSpace, 1, \
KoColorConversionTransformation::IntentAbsoluteColorimetric, \
KoColorConversionTransformation::adjustmentConversionFlags()); +                      \
xyzColorSpace->normalisedChannelsValue(data2,channelValuesF); +                       \
qreal x = channelValuesF[0]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); \
+                                qreal y = \
channelValuesF[1]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); +          \
d->gamutXYY<< QPointF(x,y); +                            }
+                        } else {
+                            channelValuesF[0]=(max/(samples-1))*(x);
+                            channelValuesF[1]=(max/(samples-1))*(y);
+                            channelValuesF[2]=(max/(samples-1))*(z);
+                            channelValuesF[3]=max;
+                            if (colorModelId().id()!="XYZA") { //no need for \
conversion when using xyz. +                                \
fromNormalisedChannelsValue(data, channelValuesF); +                                \
convertPixelsTo(data, data2, xyzColorSpace, 1, \
KoColorConversionTransformation::IntentAbsoluteColorimetric,         \
KoColorConversionTransformation::adjustmentConversionFlags()); +                      \
xyzColorSpace->normalisedChannelsValue(data2,channelValuesF); +                       \
} +                            qreal x = \
channelValuesF[0]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); +          \
qreal y = channelValuesF[1]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); \
+                            d->gamutXYY<< QPointF(x,y); +                        }
+                    }
+                }
+                
+            }
+        }
+        //if we ever implement a boundary-checking thing I'd add it here.
+        return d->gamutXYY;
+    } else {
+        return d->gamutXYY;
+    }
+}
+
+QPolygonF KoColorSpace::estimatedTRCXYY() const
+{
+    if (d->TRCXYY.empty()){
+        qreal max = 1.0;
+        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(); +        }
+        QString name = \
KoColorSpaceRegistry::instance()->colorSpaceFactory("XYZAF16")->defaultProfile(); +   \
const KoColorSpace* xyzColorSpace = \
KoColorSpaceRegistry::instance()->colorSpace("XYZA", "F16", name); +        quint8 \
data[channelCount()]; +        quint8 data2[4];//xyza is 4.
+        QVector <float> channelValuesF(channelCount());
+        for (int i=0; i<colorChannelCount(); i++) {
+            qreal colorantY=1.0;
+            if (colorModelId().id()!="CMYKA") {
+                for (int j=5; j>0; j--){
+                    channelValuesF.fill(0.0);
+                    channelValuesF[i] = ((max/4)*(5-j));
+
+                    if (colorModelId().id()!="XYZA") { //no need for conversion when \
using xyz. +                        fromNormalisedChannelsValue(data, \
channelValuesF); +                        convertPixelsTo(data, data2, xyzColorSpace, \
1, KoColorConversionTransformation::IntentAbsoluteColorimetric,         \
KoColorConversionTransformation::adjustmentConversionFlags()); +                      \
xyzColorSpace->normalisedChannelsValue(data2,channelValuesF); +                    }
+
+                    if (j==0) {
+                        colorantY = channelValuesF[1];
+                        if (d->colorants.size()<2){
+                            d->colorants.resize(3*colorChannelCount());
+                            d->colorants[i]  = \
channelValuesF[0]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); +          \
d->colorants[i+1]= channelValuesF[1]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]);
 +                            d->colorants[i+2]= channelValuesF[1];
+                        }
+                    }
+                    d->TRCXYY << QPointF(channelValuesF[1]/colorantY, \
((1.0/4)*(5-j))); +                }
+            } else {
+                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()); +
+                    xyzColorSpace->normalisedChannelsValue(data2,channelValuesF);
+
+                    if (j==0) {
+                        colorantY = channelValuesF[1];
+                        if (d->colorants.size()<2){
+                            d->colorants.resize(3*colorChannelCount());
+                            d->colorants[i]  = \
channelValuesF[0]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]); +          \
d->colorants[i+1]= channelValuesF[1]/(channelValuesF[0]+channelValuesF[1]+channelValuesF[2]);
 +                            d->colorants[i+2]= channelValuesF[1];
+                        }
+                    }
+                    d->TRCXYY << QPointF(channelValuesF[1]/colorantY, \
((1.0/4)*(j))); +                }
+            }
+        }
+        return d->TRCXYY;
+    } else {
+        return d->TRCXYY;
+    }
+}
+
+QVector <qreal> KoColorSpace::colorants() const
+{
+    if (d->colorants.size()>1){
+        return d->colorants;
+    } else if (profile() && profile()->hasColorants()) {
+        d->colorants.resize(3*colorChannelCount());
+        d->colorants = profile()->getColorantsxyY();
+        return d->colorants;
+    } else {
+        estimatedTRCXYY();
+        return d->colorants;
+    }
+}
+QVector <qreal> KoColorSpace::lumaCoefficients() const
+{
+    if (d->lumaCoefficients.size()>1){
+        return d->lumaCoefficients;
+    } else {
+        d->lumaCoefficients.resize(3);
+        if (colorModelId().id()!="RGBA") {
+            d->lumaCoefficients.fill(0.33);
+        } else {
+            colorants();
+            if (d->colorants[2]<0 || d->colorants[5]<0 || d->colorants[8]<0) {
+                d->lumaCoefficients[0]=0.2126;
+                d->lumaCoefficients[1]=0.7152;
+                d->lumaCoefficients[2]=0.0722;
+            } else {
+                d->lumaCoefficients[0]=d->colorants[2];
+                d->lumaCoefficients[1]=d->colorants[5];
+                d->lumaCoefficients[2]=d->colorants[8];
+            }
+        }
+        return d->lumaCoefficients;
+    }
+}
+
 QList<KoChannelInfo *> KoColorSpace::channels() const
 {
     return d->channels;
@@ -336,6 +519,249 @@ KoColorTransformation* \
KoColorSpace::createColorTransformation(const QString & i  }
 }
 
+void KoColorSpace::increaseLuminosity(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    if (profile()->hasTRC()){
+        //only linearise and crunch the luma if there's a TRC
+        profile()->linearizeFloatValue(channelValues);
+        qreal hue, sat, luma = 0.0;
+        toHSY(channelValues, &hue, &sat, &luma);
+        luma = pow(luma, 1/2.2);
+        luma += step;
+        luma = pow(luma, 2.2);
+        channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    } else {
+        qreal hue, sat, luma = 0.0;
+        toHSY(channelValues, &hue, &sat, &luma);
+        luma += step;
+        channelValues = fromHSY(&hue, &sat, &luma);
+    }
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::decreaseLuminosity(quint8 * pixel, qreal step) const {
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    if (profile()->hasTRC()){
+        //only linearise and crunch the luma if there's a TRC
+        profile()->linearizeFloatValue(channelValues);
+        qreal hue, sat, luma = 0.0;
+        toHSY(channelValues, &hue, &sat, &luma);
+        luma = pow(luma, 1/2.2);
+        if (luma-step<0.0) {
+            luma=0.0;
+        } else {
+            luma -= step;
+        }
+        luma = pow(luma, 2.2);
+        channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    } else {
+        qreal hue, sat, luma = 0.0;
+        toHSY(channelValues, &hue, &sat, &luma);
+        if (luma-step<0.0) {
+            luma=0.0;
+        } else {
+            luma -= step;
+        }
+        channelValues = fromHSY(&hue, &sat, &luma);
+    }
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::increaseSaturation(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal hue, sat, luma = 0.0;
+    toHSY(channelValues, &hue, &sat, &luma);
+    sat += step;
+    sat = qBound(0.0, sat, 1.0);
+    channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::decreaseSaturation(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal hue, sat, luma = 0.0;
+    toHSY(channelValues, &hue, &sat, &luma);
+    sat -= step;
+    sat = qBound(0.0, sat, 1.0);
+    channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::increaseHue(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount()); //doesn't work for cmyka...
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal hue, sat, luma = 0.0;
+    toHSY(channelValues, &hue, &sat, &luma);
+    if (hue+step>1.0){
+        hue=(hue+step)- 1.0;
+    } else {
+        hue += step;
+    }
+    channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::decreaseHue(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal hue, sat, luma = 0.0;
+    toHSY(channelValues, &hue, &sat, &luma);
+    if (hue-step<0.0){
+        hue=1.0-(step-hue);
+    } else {
+        hue -= step;
+    }
+    channelValues = fromHSY(&hue, &sat, &luma);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+
+void KoColorSpace::increaseRed(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal y, u, v = 0.0;
+    toYUV(channelValues, &y, &u, &v);
+    u += step;
+    u = qBound(0.0, u, 1.0);
+    channelValues = fromYUV(&y, &u, &v);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::increaseGreen(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal y, u, v = 0.0;
+    toYUV(channelValues, &y, &u, &v);
+    u -= step;
+    u = qBound(0.0, u, 1.0);
+    channelValues = fromYUV(&y, &u, &v);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::increaseBlue(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal y, u, v = 0.0;
+    toYUV(channelValues, &y, &u, &v);
+    v += step;
+    v = qBound(0.0, v, 1.0);
+    channelValues = fromYUV(&y, &u, &v);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
+void KoColorSpace::increaseYellow(quint8 * pixel, qreal step) const{
+    int channelnumber = abs(channelCount());
+    QVector <double> channelValues(channelnumber);
+    QVector <float> channelValuesF(channelnumber);
+    normalisedChannelsValue(pixel, channelValuesF);
+    for (int i=0;i<channelnumber;i++){
+        channelValues[i]=channelValuesF[i];
+    }
+    profile()->linearizeFloatValue(channelValues);
+    qreal y, u, v = 0.0;
+    toYUV(channelValues, &y, &u, &v);
+    v -= step;
+    v = qBound(0.0, v, 1.0);
+    channelValues = fromYUV(&y, &u, &v);
+    profile()->delinearizeFloatValue(channelValues);
+    for (int i=0;i<channelnumber;i++){
+        channelValuesF[i]=channelValues[i];
+    }
+    fromNormalisedChannelsValue(pixel, channelValuesF);
+    setOpacity(pixel, 1.0, 1);
+}
 QImage KoColorSpace::convertToQImage(const quint8 *data, qint32 width, qint32 \
height,  const KoColorProfile *dstProfile,
                                      KoColorConversionTransformation::Intent \
                renderingIntent,
diff --git a/libs/pigment/KoColorSpace.h b/libs/pigment/KoColorSpace.h
index 2968000..5580847 100644
--- a/libs/pigment/KoColorSpace.h
+++ b/libs/pigment/KoColorSpace.h
@@ -101,6 +101,23 @@ protected:
     virtual ~KoColorSpace();
 
 public:
+    //========== Gamut and other basic info ===================================//
+    /*
+     * @returns QPolygonF with 5*channel samples converted to xyY.
+     * 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
@@ -476,6 +493,23 @@ public:
      */
     virtual quint8 intensity8(const quint8 * src) const = 0;
 
+    /*
+     *increase luminosity by step
+     */
+    virtual void increaseLuminosity(quint8 * pixel, qreal step) const;
+    virtual void decreaseLuminosity(quint8 * pixel, qreal step) const;
+    virtual void increaseSaturation(quint8 * pixel, qreal step) const;
+    virtual void decreaseSaturation(quint8 * pixel, qreal step) const;
+    virtual void increaseHue(quint8 * pixel, qreal step) const;
+    virtual void decreaseHue(quint8 * pixel, qreal step) const;
+    virtual void increaseRed(quint8 * pixel, qreal step) const;
+    virtual void increaseGreen(quint8 * pixel, qreal step) const;
+    virtual void increaseBlue(quint8 * pixel, qreal step) const;
+    virtual void increaseYellow(quint8 * pixel, qreal step) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const = 0; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const = 0; +    virtual void toYUV(QVector <double> channelValues, qreal *y, \
qreal *u, qreal *v) const = 0; +    virtual QVector <double> fromYUV(qreal *y, qreal \
*u, qreal *v) const = 0;  /**
      * Compose two arrays of pixels together. If source and target
      * are not the same color model, the source pixels will be
diff --git a/libs/pigment/KoColorSpace_p.h b/libs/pigment/KoColorSpace_p.h
index a78dd61..1a82f24 100644
--- a/libs/pigment/KoColorSpace_p.h
+++ b/libs/pigment/KoColorSpace_p.h
@@ -22,6 +22,7 @@
 
 #include "KoColorSpace.h"
 #include <QThreadStorage>
+#include <QPolygonF>
 
 struct Q_DECL_HIDDEN KoColorSpace::Private {
 
@@ -38,6 +39,11 @@ struct Q_DECL_HIDDEN KoColorSpace::Private {
     mutable KoColorConversionTransformation* transfoFromRGBA16;
     mutable KoColorConversionTransformation* transfoToLABA16;
     mutable KoColorConversionTransformation* transfoFromLABA16;
+    
+    QPolygonF gamutXYY;
+    QPolygonF TRCXYY;
+    QVector <qreal> colorants;
+    QVector <qreal> lumaCoefficients;
 
     Deletability deletability;
 };
diff --git a/libs/pigment/colorprofiles/KoDummyColorProfile.cpp \
b/libs/pigment/colorprofiles/KoDummyColorProfile.cpp index 2f648fe..3db133f 100644
--- a/libs/pigment/colorprofiles/KoDummyColorProfile.cpp
+++ b/libs/pigment/colorprofiles/KoDummyColorProfile.cpp
@@ -37,7 +37,10 @@ bool KoDummyColorProfile::valid() const
 {
     return true;
 }
-
+float KoDummyColorProfile::version() const
+{
+    return 0.0;
+}
 bool KoDummyColorProfile::isSuitableForOutput() const
 {
     return true;
@@ -52,11 +55,30 @@ bool KoDummyColorProfile::isSuitableForDisplay() const
 {
     return true;
 }
+bool KoDummyColorProfile::supportsPerceptual() const
+{
+    return true;
+}
+bool KoDummyColorProfile::supportsSaturation() const
+{
+    return true;
+}
+bool KoDummyColorProfile::supportsAbsolute() const
+{
+    return true;
+}
+bool KoDummyColorProfile::supportsRelative() const
+{
+    return true;
+}
 bool KoDummyColorProfile::hasColorants() const
 {
     return true;
 }
-
+bool KoDummyColorProfile::hasTRC() const
+{
+    return true;
+}
 QVector<double> KoDummyColorProfile::getColorantsXYZ() const
 {
     QVector<double> d50Dummy(3);
@@ -86,12 +108,27 @@ QVector<double> KoDummyColorProfile::getWhitePointxyY() const
 }
 
 QVector <double> KoDummyColorProfile::getEstimatedTRC() const
+
 {
     QVector<double> Dummy(3);
     Dummy.fill(2.2);
     return Dummy;
 }
 
+void KoDummyColorProfile::linearizeFloatValue(QVector <double> & ) const
+{
+}
+
+void KoDummyColorProfile::delinearizeFloatValue(QVector <double> & ) const
+{
+}
+void KoDummyColorProfile::linearizeFloatValueFast(QVector <double> & ) const
+{
+}
+
+void KoDummyColorProfile::delinearizeFloatValueFast(QVector <double> & ) const
+{
+}
 bool KoDummyColorProfile::operator==(const KoColorProfile& rhs) const
 {
     return dynamic_cast<const KoDummyColorProfile*>(&rhs);
diff --git a/libs/pigment/colorprofiles/KoDummyColorProfile.h \
b/libs/pigment/colorprofiles/KoDummyColorProfile.h index 6bcbdee..c8a3f71 100644
--- a/libs/pigment/colorprofiles/KoDummyColorProfile.h
+++ b/libs/pigment/colorprofiles/KoDummyColorProfile.h
@@ -29,15 +29,25 @@ public:
     virtual ~KoDummyColorProfile();
     virtual KoColorProfile* clone() const;
     virtual bool valid() const;
+    virtual float version() const;
     virtual bool isSuitableForOutput() const;
     virtual bool isSuitableForPrinting() const;
     virtual bool isSuitableForDisplay() const;
+    virtual bool supportsPerceptual() const;
+    virtual bool supportsSaturation() const;
+    virtual bool supportsAbsolute() const;
+    virtual bool supportsRelative() const;
     virtual bool hasColorants() const;
+    virtual bool hasTRC() const;
     virtual QVector <double> getColorantsXYZ() const;
     virtual QVector <double> getColorantsxyY() const;
     virtual QVector <double> getWhitePointXYZ() const;
     virtual QVector <double> getWhitePointxyY() const;
     virtual QVector <double> getEstimatedTRC() const;
+    virtual void linearizeFloatValue(QVector <double> & Value) const;
+    virtual void delinearizeFloatValue(QVector <double> & Value) const;
+    virtual void linearizeFloatValueFast(QVector <double> & Value) const;
+    virtual void delinearizeFloatValueFast(QVector <double> & Value) const;
     virtual bool operator==(const KoColorProfile&) const;
 };
 
diff --git a/libs/pigment/colorspaces/KoAlphaColorSpace.h \
b/libs/pigment/colorspaces/KoAlphaColorSpace.h index 0f22014..1bb1826 100644
--- a/libs/pigment/colorspaces/KoAlphaColorSpace.h
+++ b/libs/pigment/colorspaces/KoAlphaColorSpace.h
@@ -158,6 +158,24 @@ public:
     virtual void colorFromXML(quint8* , const QDomElement&) const {
         warnPigment << i18n("Undefined operation in the alpha color space");
     }
+    virtual void toHSY(QVector <double>, qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the alpha color space");
+    }
+    virtual QVector <double> fromHSY(qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the alpha color space");
+        QVector <double> channelValues (1);
+        channelValues.fill(0.0);
+        return channelValues;
+    }
+    virtual void toYUV(QVector <double>, qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the alpha color space");
+    }
+    virtual QVector <double> fromYUV(qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the alpha color space");
+        QVector <double> channelValues (1);
+        channelValues.fill(0.0);
+        return channelValues;
+    }
 
 protected:
     virtual bool preferCompositionInSourceColorSpace() const;
diff --git a/libs/pigment/colorspaces/KoLabColorSpace.cpp \
b/libs/pigment/colorspaces/KoLabColorSpace.cpp index 3574850..61f3c03 100644
--- a/libs/pigment/colorspaces/KoLabColorSpace.cpp
+++ b/libs/pigment/colorspaces/KoLabColorSpace.cpp
@@ -30,6 +30,7 @@
 #include "KoChannelInfo.h"
 #include "KoID.h"
 #include "KoIntegerMaths.h"
+#include "KoColorConversions.h"
 
 #include "../compositeops/KoCompositeOps.h"
 
@@ -163,3 +164,33 @@ void KoLabColorSpace::toQColor(const quint8 * src, QColor *c, \
const KoColorProfi  
     c->setRgba(qRgba(R, G, B, A));
 }
+
+void KoLabColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> KoLabColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const
+{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void KoLabColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *v=channelValues[1];
+    *u=channelValues[2];
+}
+
+QVector <double> KoLabColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*v;
+    channelValues[2]=*u;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/libs/pigment/colorspaces/KoLabColorSpace.h \
b/libs/pigment/colorspaces/KoLabColorSpace.h index 96c1fc6..986ce65 100644
--- a/libs/pigment/colorspaces/KoLabColorSpace.h
+++ b/libs/pigment/colorspaces/KoLabColorSpace.h
@@ -46,6 +46,11 @@ public:
     virtual void fromQColor(const QColor& color, quint8 *dst, const KoColorProfile * \
profile = 0) const;  
     virtual void toQColor(const quint8 *src, QColor *c, const KoColorProfile * \
profile = 0) const; +    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 private:
 
diff --git a/libs/pigment/colorspaces/KoRgbU16ColorSpace.cpp \
b/libs/pigment/colorspaces/KoRgbU16ColorSpace.cpp index e8c4f02..d6f944a 100644
--- a/libs/pigment/colorspaces/KoRgbU16ColorSpace.cpp
+++ b/libs/pigment/colorspaces/KoRgbU16ColorSpace.cpp
@@ -31,6 +31,7 @@
 #include "KoID.h"
 #include "KoIntegerMaths.h"
 
+#include "KoColorConversions.h"
 
 KoRgbU16ColorSpace::KoRgbU16ColorSpace() :
         KoSimpleColorSpace<KoBgrU16Traits>(colorSpaceId(),
@@ -68,3 +69,30 @@ void KoRgbU16ColorSpace::toQColor(const quint8 * src, QColor *c, \
const KoColorPr  normalisedChannelsValue(src, channelValues);
     c->setRgbF(channelValues[2], channelValues[1], channelValues[0], \
channelValues[3]);  }
+void KoRgbU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma);
+}
+
+QVector <double> KoRgbU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+
+}
+
+void KoRgbU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v);
+}
+
+QVector <double> KoRgbU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/libs/pigment/colorspaces/KoRgbU16ColorSpace.h \
b/libs/pigment/colorspaces/KoRgbU16ColorSpace.h index ed1a9c9..d1ddf39 100644
--- a/libs/pigment/colorspaces/KoRgbU16ColorSpace.h
+++ b/libs/pigment/colorspaces/KoRgbU16ColorSpace.h
@@ -46,6 +46,11 @@ public:
     virtual void fromQColor(const QColor& color, quint8 *dst, const KoColorProfile * \
profile = 0) const;  
     virtual void toQColor(const quint8 *src, QColor *c, const KoColorProfile * \
profile = 0) const; +    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/libs/pigment/colorspaces/KoRgbU8ColorSpace.cpp \
b/libs/pigment/colorspaces/KoRgbU8ColorSpace.cpp index 1619d86..9619f70 100644
--- a/libs/pigment/colorspaces/KoRgbU8ColorSpace.cpp
+++ b/libs/pigment/colorspaces/KoRgbU8ColorSpace.cpp
@@ -31,6 +31,8 @@
 #include "KoIntegerMaths.h"
 #include "compositeops/KoCompositeOps.h"
 
+#include "KoColorConversions.h"
+
 
 KoRgbU8ColorSpace::KoRgbU8ColorSpace() :
 
@@ -80,3 +82,30 @@ void KoRgbU8ColorSpace::toQColor(const quint8 * src, QColor *c, \
const KoColorPro  normalisedChannelsValue(src, channelValues);
     c->setRgbF(channelValues[2], channelValues[1], channelValues[0], \
channelValues[3]);  }
+
+void KoRgbU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma);
+}
+
+QVector <double> KoRgbU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void KoRgbU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v);
+}
+
+QVector <double> KoRgbU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/libs/pigment/colorspaces/KoRgbU8ColorSpace.h \
b/libs/pigment/colorspaces/KoRgbU8ColorSpace.h index bb8c681..0957781 100644
--- a/libs/pigment/colorspaces/KoRgbU8ColorSpace.h
+++ b/libs/pigment/colorspaces/KoRgbU8ColorSpace.h
@@ -47,6 +47,11 @@ public:
     virtual void fromQColor(const QColor& color, quint8 *dst, const KoColorProfile * \
profile = 0) const;  
     virtual void toQColor(const quint8 *src, QColor *c, const KoColorProfile * \
profile = 0) const; +    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/libs/pigment/colorspaces/KoSimpleColorSpace.h \
b/libs/pigment/colorspaces/KoSimpleColorSpace.h index 03c9420..34c92b2 100644
--- a/libs/pigment/colorspaces/KoSimpleColorSpace.h
+++ b/libs/pigment/colorspaces/KoSimpleColorSpace.h
@@ -123,6 +123,24 @@ public:
     virtual void colorFromXML(quint8* , const QDomElement&) const {
         warnPigment << i18n("Undefined operation in the %1 color space", m_name);
     }
+    virtual void toHSY(QVector <double>, qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the %1 color space", m_name);
+    }
+    virtual QVector <double> fromHSY(qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the %1 color space", m_name);
+        QVector <double> channelValues (2);
+        channelValues.fill(0.0);
+        return channelValues;
+    }
+    virtual void toYUV(QVector <double>, qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the %1 color space", m_name);
+    }
+    virtual QVector <double> fromYUV(qreal *, qreal *, qreal *) const {
+        warnPigment << i18n("Undefined operation in the %1 color space", m_name);
+        QVector <double> channelValues (2);
+        channelValues.fill(0.0);
+        return channelValues;
+    }
 
     virtual void toLabA16(const quint8* src, quint8* dst, quint32 nPixels) const {
         if (colorDepthId() == Integer16BitsColorDepthID && colorModelId() == \
                LABAColorModelID) {
diff --git a/libs/pigment/resources/KoSegmentGradient.cpp \
b/libs/pigment/resources/KoSegmentGradient.cpp index e44ad22..f41d1a0 100644
--- a/libs/pigment/resources/KoSegmentGradient.cpp
+++ b/libs/pigment/resources/KoSegmentGradient.cpp
@@ -490,18 +490,41 @@ KoGradientSegment::RGBColorInterpolationStrategy \
*KoGradientSegment::RGBColorInt  
 void KoGradientSegment::RGBColorInterpolationStrategy::colorAt(KoColor& dst, qreal \
t, const KoColor& start, const KoColor& end) const  {
+    
+    KoColor startDummy, endDummy;
+    //hack to get a color space with the bitdepth of the gradients(8bit), but with \
the colour profile of the image// +    const KoColorSpace* mixSpace = \
KoColorSpaceRegistry::instance()->rgb8(dst.colorSpace()->profile()); +    //convert \
to the right colorspace for the start and end if we have our mixSpace. +    if \
(mixSpace){ +        startDummy = KoColor(start, mixSpace);
+        endDummy = KoColor(end, mixSpace);
+    } else {
+        startDummy = start;
+        endDummy = end;
+    }
+    
     m_start.fromKoColor(start);
     m_end.fromKoColor(end);
-
+    
     const quint8 *colors[2];
-    colors[0] = start.data();
-    colors[1] = end.data();
+    colors[0] = startDummy.data();
+    colors[1] = endDummy.data();
 
     qint16 colorWeights[2];
     colorWeights[0] = static_cast<quint8>((1.0 - t) * 255 + 0.5);
     colorWeights[1] = 255 - colorWeights[0];
 
-    m_colorSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data());
+    //check if our mixspace exists, it doesn't at startup.
+    if (mixSpace){
+        if ( !(*buffer.colorSpace() == *mixSpace)) {
+            buffer = KoColor(mixSpace);
+            }
+        mixSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data());
+    }
+    else {
+        buffer = KoColor(m_colorSpace);
+        m_colorSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, \
buffer.data()); +    }
 
     dst.fromKoColor(buffer);
 }
diff --git a/libs/pigment/resources/KoStopGradient.cpp \
b/libs/pigment/resources/KoStopGradient.cpp index 19a7ee5..066f785 100644
--- a/libs/pigment/resources/KoStopGradient.cpp
+++ b/libs/pigment/resources/KoStopGradient.cpp
@@ -154,16 +154,26 @@ void KoStopGradient::colorAt(KoColor& dst, qreal t) const
                 break;
         }
 
-        if ( !(*buffer.colorSpace() == *colorSpace())) {
-            buffer = KoColor(colorSpace());
-        }
+        //if ( !(*buffer.colorSpace() == *colorSpace())) {
+        //    buffer = KoColor(colorSpace());
+        //}
+        //hack to get a color space with the bitdepth of the gradients(8bit), but \
with the colour profile of the image// +        const KoColorSpace* mixSpace = \
KoColorSpaceRegistry::instance()->rgb8(dst.colorSpace()->profile());  
         const KoGradientStop& leftStop = *(stop - 1);
         const KoGradientStop& rightStop = *(stop);
-
+        
+        KoColor startDummy, endDummy;
+        if (mixSpace){
+            startDummy = KoColor(leftStop.second, mixSpace);
+            endDummy = KoColor(rightStop.second, mixSpace);
+        } else {
+            startDummy = leftStop.second;
+            endDummy = rightStop.second;
+        }
         const quint8 *colors[2];
-        colors[0] = leftStop.second.data();
-        colors[1] = rightStop.second.data();
+        colors[0] = startDummy.data();
+        colors[1] = endDummy.data();
 
         qreal localT;
         qreal stopDistance = rightStop.first - leftStop.first;
@@ -176,7 +186,18 @@ void KoStopGradient::colorAt(KoColor& dst, qreal t) const
         colorWeights[0] = static_cast<quint8>((1.0 - localT) * 255 + 0.5);
         colorWeights[1] = 255 - colorWeights[0];
 
-        colorSpace()->mixColorsOp()->mixColors(colors, colorWeights, 2, \
buffer.data()); +
+        //check if our mixspace exists, it doesn't at startup.
+        if (mixSpace){
+            if ( !(*buffer.colorSpace() == *mixSpace)) {
+                buffer = KoColor(mixSpace);
+            }
+            mixSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, \
buffer.data()); +        }
+        else {
+            buffer = KoColor(colorSpace());
+            colorSpace()->mixColorsOp()->mixColors(colors, colorWeights, 2, \
buffer.data()); +        }
 
         dst.fromKoColor(buffer);
     }
diff --git a/libs/ui/CMakeLists.txt b/libs/ui/CMakeLists.txt
index 2409347..035dd71 100644
--- a/libs/ui/CMakeLists.txt
+++ b/libs/ui/CMakeLists.txt
@@ -213,6 +213,7 @@ set(kritaui_LIB_SRCS
     widgets/kis_color_space_selector.cc
     widgets/kis_advanced_color_space_selector.cc
     widgets/kis_cie_tongue_widget.cpp
+    widgets/kis_tone_curve_widget.cpp
     widgets/kis_curve_widget.cpp
     widgets/kis_custom_image_widget.cc
     widgets/kis_image_from_clipboard_widget.cpp
diff --git a/libs/ui/canvas/kis_display_color_converter.cpp \
b/libs/ui/canvas/kis_display_color_converter.cpp index c50ae60..9683f3c 100644
--- a/libs/ui/canvas/kis_display_color_converter.cpp
+++ b/libs/ui/canvas/kis_display_color_converter.cpp
@@ -583,47 +583,50 @@ void KisDisplayColorConverter::getHslF(const KoColor &srcColor, \
qreal *h, qreal  KoColor KisDisplayColorConverter::fromHsiF(qreal h, qreal s, qreal \
i)  {
     // generate HSI from sRGB!
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
-	qreal a=1.0;
-	HSIToRGB(h, s, i, &r, &g, &b);
-	QColor qcolor;
-	qcolor.setRgbF(r, g, b, a);
+    qreal r=0.0;
+    qreal g=0.0;
+    qreal b=0.0;
+    qreal a=1.0;
+    HSIToRGB(h, s, i, &r, &g, &b);
+    QColor qcolor;
+    qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
     return m_d->approximateFromQColor(qcolor);
 }
 
 void KisDisplayColorConverter::getHsiF(const KoColor &srcColor, qreal *h, qreal *s, \
qreal *i)  {
     // we are going through sRGB here!
-	QColor color = m_d->approximateToQColor(srcColor);
-	qreal r=color.redF();
-	qreal g=color.greenF();
-	qreal b=color.blueF();
-	RGBToHSI(r, g, b, h, s, i);
+    QColor color = m_d->approximateToQColor(srcColor);
+    qreal r=color.redF();
+    qreal g=color.greenF();
+    qreal b=color.blueF();
+    RGBToHSI(r, g, b, h, s, i);
 }
 
 KoColor KisDisplayColorConverter::fromHsyF(qreal h, qreal s, qreal y, qreal R, qreal \
G, qreal B)  {
     // generate HSL from sRGB!
-	qreal r=0.0;
-	qreal g=0.0;
-	qreal b=0.0;
-	qreal a=1.0;
-	HSYToRGB(h, s, y, &r, &g, &b, R, G, B);
-	QColor qcolor;
-	qcolor.setRgbF(r, g, b, a);
+    QVector <qreal> channelValues(3);
+    y = pow(y, 2.2);
+    HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2], R, G, \
B); +    KoColorSpaceRegistry::instance()->rgb8()->profile()->delinearizeFloatValueFast(channelValues);
 +    QColor qcolor;
+    qcolor.setRgbF(qBound(0.0,channelValues[0],1.0), \
qBound(0.0,channelValues[1],1.0), qBound(0.0,channelValues[2],1.0), 1.0);  return \
m_d->approximateFromQColor(qcolor);  }
 
 void KisDisplayColorConverter::getHsyF(const KoColor &srcColor, qreal *h, qreal *s, \
qreal *y, qreal R, qreal G, qreal B)  {
     // we are going through sRGB here!
-	QColor color = m_d->approximateToQColor(srcColor);
-	qreal r=color.redF();
-	qreal g=color.greenF();
-	qreal b=color.blueF();
-	RGBToHSY(r, g, b, h, s, y, R, G, B);
+    QColor color = m_d->approximateToQColor(srcColor);
+    QVector <qreal> channelValues(3);
+    channelValues[0]=color.redF();
+    channelValues[1]=color.greenF();
+    channelValues[2]=color.blueF();
+    //TODO: if we're going to have KoColor here, remember to check whether the TRC \
of the profile exists... +    \
KoColorSpaceRegistry::instance()->rgb8()->profile()->linearizeFloatValueFast(channelValues);
 +    RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y, R, G, \
B); +    *y = pow(*y, 1/2.2);
 }
 
 #include "moc_kis_display_color_converter.cpp"
diff --git a/libs/ui/dialogs/kis_dlg_png_import.cpp \
b/libs/ui/dialogs/kis_dlg_png_import.cpp index aaa4163..0b9c5de 100644
--- a/libs/ui/dialogs/kis_dlg_png_import.cpp
+++ b/libs/ui/dialogs/kis_dlg_png_import.cpp
@@ -44,9 +44,13 @@ KisDlgPngImport::KisDlgPngImport(const QString &path, const \
                QString &colorModelI
     const KoColorSpaceFactory * csf = \
KoColorSpaceRegistry::instance()->colorSpaceFactory(s);  if (csf) {
         QList<const KoColorProfile *>  profileList = \
                KoColorSpaceRegistry::instance()->profilesFor(csf);
-
+        QStringList profileNames;
         Q_FOREACH (const KoColorProfile *profile, profileList) {
-            dlgWidget.cmbProfile->addSqueezedItem(profile->name());
+            profileNames.append(profile->name());
+        }
+        qSort(profileNames);
+        Q_FOREACH (QString stringName, profileNames) {
+            dlgWidget.cmbProfile->addSqueezedItem(stringName);
         }
         KisConfig cfg;
         QString profile = cfg.readEntry<QString>("pngImportProfile", \
                csf->defaultProfile());
diff --git a/libs/ui/forms/wdgcolorspaceselectoradvanced.ui \
b/libs/ui/forms/wdgcolorspaceselectoradvanced.ui index 59739b7..fdc69bf 100644
--- a/libs/ui/forms/wdgcolorspaceselectoradvanced.ui
+++ b/libs/ui/forms/wdgcolorspaceselectoradvanced.ui
@@ -201,25 +201,13 @@
          <enum>QFormLayout::ExpandingFieldsGrow</enum>
         </property>
         <item row="0" column="0" colspan="2">
-         <widget class="QLabel" name="lbltrc">
+         <widget class="KisToneCurveWidget" name="TRCwidget" native="true">
           <property name="minimumSize">
            <size>
-            <width>240</width>
-            <height>0</height>
+            <width>150</width>
+            <height>150</height>
            </size>
           </property>
-          <property name="maximumSize">
-           <size>
-            <width>240</width>
-            <height>16777215</height>
-           </size>
-          </property>
-          <property name="text">
-           <string notr="true">TRC</string>
-          </property>
-          <property name="wordWrap">
-           <bool>true</bool>
-          </property>
          </widget>
         </item>
         <item row="1" column="0">
@@ -236,48 +224,6 @@
           </property>
          </widget>
         </item>
-        <item row="2" column="0">
-         <widget class="QLabel" name="lblRed">
-          <property name="text">
-           <string>Red:</string>
-          </property>
-         </widget>
-        </item>
-        <item row="2" column="1">
-         <widget class="QLabel" name="lblXYZ_R">
-          <property name="text">
-           <string>xyz</string>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="0">
-         <widget class="QLabel" name="lblGreen">
-          <property name="text">
-           <string>Green:</string>
-          </property>
-         </widget>
-        </item>
-        <item row="3" column="1">
-         <widget class="QLabel" name="lblXYZ_G">
-          <property name="text">
-           <string>xyz</string>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="0">
-         <widget class="QLabel" name="lblBlue">
-          <property name="text">
-           <string>Blue:</string>
-          </property>
-         </widget>
-        </item>
-        <item row="4" column="1">
-         <widget class="QLabel" name="lblXYZ_B">
-          <property name="text">
-           <string>xyz</string>
-          </property>
-         </widget>
-        </item>
        </layout>
       </widget>
      </item>
@@ -319,6 +265,12 @@
    <header>widgets/kis_cie_tongue_widget.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>KisToneCurveWidget</class>
+   <extends>QWidget</extends>
+   <header>widgets/kis_tone_curve_widget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
diff --git a/libs/ui/kis_canvas_controls_manager.cpp \
b/libs/ui/kis_canvas_controls_manager.cpp index fd40998..ef99b6b 100644
--- a/libs/ui/kis_canvas_controls_manager.cpp
+++ b/libs/ui/kis_canvas_controls_manager.cpp
@@ -55,7 +55,30 @@ void KisCanvasControlsManager::setup(KisActionManager \
*actionManager)  
     KisAction *darkerColor = actionManager->createAction("make_brush_color_darker");
     connect(darkerColor, SIGNAL(triggered()), SLOT(makeColorDarker()));
+    KisAction *saturatedColor = \
actionManager->createAction("make_brush_color_saturated"); +    \
connect(saturatedColor, SIGNAL(triggered()), SLOT(makeColorSaturated()));  
+    KisAction *desaturatedColor = \
actionManager->createAction("make_brush_color_desaturated"); +    \
connect(desaturatedColor, SIGNAL(triggered()), SLOT(makeColorDesaturated())); +    
+    KisAction *hueClockwise = \
actionManager->createAction("shift_brush_color_clockwise"); +    \
connect(hueClockwise, SIGNAL(triggered()), SLOT(shiftHueClockWise())); +
+    KisAction *hueCounterClockwise = \
actionManager->createAction("shift_brush_color_counter_clockwise"); +    \
connect(hueCounterClockwise, SIGNAL(triggered()), SLOT(shiftHueCounterClockWise())); \
+     +    KisAction *moreRed = \
actionManager->createAction("make_brush_color_redder"); +    connect(moreRed, \
SIGNAL(triggered()), SLOT(makeColorRed())); +    
+    KisAction *moreGreen = actionManager->createAction("make_brush_color_greener");
+    connect(moreGreen, SIGNAL(triggered()), SLOT(makeColorGreen()));
+    
+    KisAction *moreBlue = actionManager->createAction("make_brush_color_bluer");
+    connect(moreBlue, SIGNAL(triggered()), SLOT(makeColorBlue()));
+
+    KisAction *moreYellow = \
actionManager->createAction("make_brush_color_yellower"); +    connect(moreYellow, \
SIGNAL(triggered()), SLOT(makeColorYellow())); + 
     KisAction *increaseOpacity = actionManager->createAction("increase_opacity");
     connect(increaseOpacity, SIGNAL(triggered()), SLOT(increaseOpacity()));
 
@@ -75,18 +98,96 @@ void KisCanvasControlsManager::transformColor(int step)
     if (!m_view->resourceProvider()->resourceManager()) return;
 
     KoColor color = \
m_view->resourceProvider()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value<KoColor>();
                
-    QColor rgb = color.toQColor();
-    int h = 0, s = 0, v = 0;
-    rgb.getHsv(&h,&s,&v);
-    if ((v < 255) || ((s == 0) || (s == 255))) {
-        v += step;
-        v = qBound(0,v,255);
+    if (color.colorSpace()->colorModelId().id()=="CMYKA" || \
color.colorSpace()->colorModelId().id()=="XYZA"){ +        QColor rgb = \
color.toQColor(); +        int h = 0, s = 0, v = 0;
+        rgb.getHsv(&h,&s,&v);
+        if ((v < 255) || ((s == 0) || (s == 255))) {
+            v += step;
+            v = qBound(0,v,255);
+        } else {
+            s += -step;
+            s = qBound(0,s,255);
+        }
+        rgb.setHsv(h,s,v);
+        color.fromQColor(rgb);
+    } else if (step<0){
+        color.colorSpace()->decreaseLuminosity(color.data(), 0.1);
     } else {
-        s += -step;
+        color.colorSpace()->increaseLuminosity(color.data(), 0.1);
+    }
+    m_view->resourceProvider()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, \
color); +}
+void KisCanvasControlsManager::transformSaturation(int step)
+{
+    if (!m_view) return;
+    if (!m_view->canvasBase()) return;
+    if (!m_view->resourceProvider()->resourceManager()) return;
+
+    KoColor color = \
m_view->resourceProvider()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value<KoColor>();
 +    if (color.colorSpace()->colorModelId().id()=="CMYKA" || \
color.colorSpace()->colorModelId().id()=="XYZA"){ +        QColor rgb = \
color.toQColor(); +        int h = 0, s = 0, v = 0;
+        rgb.getHsl(&h,&s,&v);
+        s += step;
         s = qBound(0,s,255);
+        rgb.setHsl(h,s,v);
+        color.fromQColor(rgb);
+    } else if (step<0){
+        color.colorSpace()->decreaseSaturation(color.data(), 0.1);
+    } else {
+        color.colorSpace()->increaseSaturation(color.data(), 0.1);
+    }
+    m_view->resourceProvider()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, \
color); +}
+void KisCanvasControlsManager::transformHue(int step)
+{
+    if (!m_view) return;
+    if (!m_view->canvasBase()) return;
+    if (!m_view->resourceProvider()->resourceManager()) return;
+
+    KoColor color = \
m_view->resourceProvider()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value<KoColor>();
 +    if (color.colorSpace()->colorModelId().id()=="CMYKA" || \
color.colorSpace()->colorModelId().id()=="XYZA"){ +        QColor rgb = \
color.toQColor(); +        int h = 0, s = 0, v = 0;
+        rgb.getHsl(&h,&s,&v);
+        h += step;
+        if (h>360.0 || h<0.0){h=fmod(h, 360.0);}
+        rgb.setHsl(h,s,v);
+        color.fromQColor(rgb);
+    } else if (step<0){
+        color.colorSpace()->increaseHue(color.data(), 1.0/36.0);
+    } else {
+        color.colorSpace()->decreaseHue(color.data(), 1.0/36.0);
+    }
+    m_view->resourceProvider()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, \
color); +}
+void KisCanvasControlsManager::transformRed(int step)
+{
+    if (!m_view) return;
+    if (!m_view->canvasBase()) return;
+    if (!m_view->resourceProvider()->resourceManager()) return;
+
+    KoColor color = \
m_view->resourceProvider()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value<KoColor>();
 +    if (step<0){
+        color.colorSpace()->increaseGreen(color.data(), 0.05);
+    } else {
+        color.colorSpace()->increaseRed(color.data(), 0.05);
+    }
+    m_view->resourceProvider()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, \
color); +}
+void KisCanvasControlsManager::transformBlue(int step)
+{
+    if (!m_view) return;
+    if (!m_view->canvasBase()) return;
+    if (!m_view->resourceProvider()->resourceManager()) return;
+
+    KoColor color = \
m_view->resourceProvider()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value<KoColor>();
 +    if (step<0){
+        color.colorSpace()->increaseYellow(color.data(), 0.05);
+    } else {
+        color.colorSpace()->increaseBlue(color.data(), 0.05);
     }
-    rgb.setHsv(h,s,v);
-    color.fromQColor(rgb);
     m_view->resourceProvider()->resourceManager()->setResource(KoCanvasResourceManager::ForegroundColor, \
color);  }
 
@@ -101,6 +202,41 @@ void KisCanvasControlsManager::makeColorLighter()
     transformColor(STEP);
 }
 
+void KisCanvasControlsManager::makeColorDesaturated()
+{
+    transformSaturation(-STEP);
+}
+
+void KisCanvasControlsManager::makeColorSaturated()
+{
+    transformSaturation(STEP);
+}
+void KisCanvasControlsManager::shiftHueClockWise()
+{
+    transformHue(STEP);
+}
+
+void KisCanvasControlsManager::shiftHueCounterClockWise()
+{
+    transformHue(-STEP);
+}
+void KisCanvasControlsManager::makeColorRed()
+{
+    transformRed(STEP);
+}
+void KisCanvasControlsManager::makeColorGreen()
+{
+    transformRed(-STEP);
+}
+void KisCanvasControlsManager::makeColorBlue()
+{
+    transformBlue(STEP);
+}
+void KisCanvasControlsManager::makeColorYellow()
+{
+    transformBlue(-STEP);
+}
+
 void KisCanvasControlsManager::stepAlpha(float step)
 {
     if (!m_view) return;
diff --git a/libs/ui/kis_canvas_controls_manager.h \
b/libs/ui/kis_canvas_controls_manager.h index 5dc8d05..26e069b 100644
--- a/libs/ui/kis_canvas_controls_manager.h
+++ b/libs/ui/kis_canvas_controls_manager.h
@@ -43,11 +43,23 @@ public:
 private Q_SLOTS:
     void makeColorLighter();
     void makeColorDarker();
+    void makeColorDesaturated();
+    void makeColorSaturated();
+    void shiftHueClockWise();
+    void shiftHueCounterClockWise();
+    void makeColorRed();
+    void makeColorGreen();
+    void makeColorBlue();
+    void makeColorYellow();
 
     void increaseOpacity();
     void decreaseOpacity();
 private:
     void transformColor(int step);
+    void transformSaturation(int step);
+    void transformHue(int step);
+    void transformRed(int step);
+    void transformBlue(int step);
     void stepAlpha(float step);
 
 private:
diff --git a/libs/ui/widgets/kis_advanced_color_space_selector.cc \
b/libs/ui/widgets/kis_advanced_color_space_selector.cc index f46745e..83dd87e 100644
--- a/libs/ui/widgets/kis_advanced_color_space_selector.cc
+++ b/libs/ui/widgets/kis_advanced_color_space_selector.cc
@@ -77,6 +77,7 @@ KisAdvancedColorSpaceSelector::KisAdvancedColorSpaceSelector(QWidget* \
parent, co  connect(this, SIGNAL(selectionChanged(bool)),
             this, SLOT(fillDescription()));
     connect(this, SIGNAL(selectionChanged(bool)), \
d->colorSpaceSelector->TongueWidget, SLOT(repaint())); +    connect(this, \
SIGNAL(selectionChanged(bool)), d->colorSpaceSelector->TRCwidget, SLOT(repaint()));  
     connect(d->colorSpaceSelector->bnInstallProfile, SIGNAL(clicked()), this, \
SLOT(installProfile()));  
@@ -168,32 +169,20 @@ void KisAdvancedColorSpaceSelector::fillDescription()
             //QString text = currentColorSpace()->profile()->info() + " =" +
             d->colorSpaceSelector->lblXYZ_W->setText(nameWhitePoint(whitepoint));
             d->colorSpaceSelector->lblXYZ_W->setToolTip(QString::number(whitepoint[0], \
'f', 4) + ", " + QString::number(whitepoint[1], 'f', 4) + ", " + \
                QString::number(whitepoint[2], 'f', 4));
-            d->colorSpaceSelector->lblXYZ_R->setText(QString::number(colorants[0], \
'f', 4) + ", " + QString::number(colorants[1], 'f', 4) + ", " + \
                QString::number(colorants[2], 'f', 4));
-            d->colorSpaceSelector->lblXYZ_G->setText(QString::number(colorants[3], \
'f', 4) + ", " + QString::number(colorants[4], 'f', 4) + ", " + \
                QString::number(colorants[5], 'f', 4));
-            d->colorSpaceSelector->lblXYZ_B->setText(QString::number(colorants[6], \
'f', 4) + ", " + QString::number(colorants[7], 'f', 4) + ", " + \
                QString::number(colorants[8], 'f', 4));
-            d->colorSpaceSelector->lblXYZ_R->setToolTip(whatIsColorant);
-            d->colorSpaceSelector->lblXYZ_G->setToolTip(whatIsColorant);
-            d->colorSpaceSelector->lblXYZ_B->setToolTip(whatIsColorant);
+            d->colorSpaceSelector->TongueWidget->setToolTip("<html><head/><body><table><tr><th \
colspan='4'>"+i18nc("@info:tooltip","This profile has the following xyY \
colorants:")+"</th></tr><tr><td>"+ +               i18n("Red:")  \
+"</td><td>"+QString::number(colorants[0], 'f', 4) + "</td><td>" + \
QString::number(colorants[1], 'f', 4) + "</td><td>" + QString::number(colorants[2], \
'f', 4)+"</td></tr><tr><td>"+ +               \
i18n("Green:")+"</td><td>"+QString::number(colorants[3], 'f', 4) + "</td><td>" + \
QString::number(colorants[4], 'f', 4) + "</td><td>" + QString::number(colorants[5], \
'f', 4)+"</th></tr><tr><td>"+ +               i18n("Blue:") \
+"</td><td>"+QString::number(colorants[6], 'f', 4) + "</td><td>" + \
QString::number(colorants[7], 'f', 4) + "</td><td>" + QString::number(colorants[8], \
'f', 4)+"</th></tr></table></body></html>");  } else {
             QVector <double> whitepoint2 = \
                currentColorSpace()->profile()->getWhitePointxyY();
             d->colorSpaceSelector->lblXYZ_W->setText(nameWhitePoint(whitepoint2));
             d->colorSpaceSelector->lblXYZ_W->setToolTip(QString::number(whitepoint2[0], \
'f', 4) + ", " + QString::number(whitepoint2[1], 'f', 4) + ", " + \
                QString::number(whitepoint2[2], 'f', 4));
-            d->colorSpaceSelector->lblXYZ_R->setText(notApplicable);
-            d->colorSpaceSelector->lblXYZ_R->setToolTip(notApplicableTooltip);
-            d->colorSpaceSelector->lblXYZ_G->setText(notApplicable);
-            d->colorSpaceSelector->lblXYZ_G->setToolTip(notApplicableTooltip);
-            d->colorSpaceSelector->lblXYZ_B->setText(notApplicable);
-            d->colorSpaceSelector->lblXYZ_B->setToolTip(notApplicableTooltip);
+            d->colorSpaceSelector->TongueWidget->setToolTip(notApplicableTooltip);
         }
     } else {
         d->colorSpaceSelector->lblXYZ_W->setText(notApplicable);
         d->colorSpaceSelector->lblXYZ_W->setToolTip(notApplicableTooltip);
-        d->colorSpaceSelector->lblXYZ_R->setText(notApplicable);
-        d->colorSpaceSelector->lblXYZ_R->setToolTip(notApplicableTooltip);
-        d->colorSpaceSelector->lblXYZ_G->setText(notApplicable);
-        d->colorSpaceSelector->lblXYZ_G->setToolTip(notApplicableTooltip);
-        d->colorSpaceSelector->lblXYZ_B->setText(notApplicable);
-        d->colorSpaceSelector->lblXYZ_B->setToolTip(notApplicableTooltip);
+        d->colorSpaceSelector->TongueWidget->setToolTip(notApplicableTooltip);
     }
 
     //set TRC
@@ -205,95 +194,213 @@ void KisAdvancedColorSpaceSelector::fillDescription()
 
     if (profileList.isEmpty()) {
         d->colorSpaceSelector->TongueWidget->setProfileDataAvailable(false);
+        d->colorSpaceSelector->TRCwidget->setProfileDataAvailable(false);
     }
     else if (currentModelStr == "RGBA") {
-        QVector <double> colorants = \
                currentColorSpace()->profile()->getColorantsxyY();
-        QVector <double> whitepoint = \
                currentColorSpace()->profile()->getWhitePointxyY();
-        d->colorSpaceSelector->TongueWidget->setRGBData(whitepoint, colorants);
+        QVector <qreal> colorants = \
currentColorSpace()->profile()->getColorantsxyY(); +        QVector <qreal> \
whitepoint = currentColorSpace()->profile()->getWhitePointxyY(); +        if \
(currentColorSpace()->profile()->hasColorants()){ +            \
d->colorSpaceSelector->TongueWidget->setRGBData(whitepoint, colorants); +        } \
else { +            colorants.fill(0.0);
+            d->colorSpaceSelector->TongueWidget->setRGBData(whitepoint, colorants);
+        }
+        d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());
  estimatedTRC = currentColorSpace()->profile()->getEstimatedTRC();
+        QString estimatedCurve = " Estimated curve: ";
+        QPolygonF redcurve;
+        QPolygonF greencurve;
+        QPolygonF bluecurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                redcurve<<tonepoint;
+                tonepoint.setX(linear[1]);
+                greencurve<<tonepoint;
+                tonepoint.setX(linear[2]);
+                bluecurve<<tonepoint;
+            }
+            d->colorSpaceSelector->TRCwidget->setRGBCurve(redcurve, greencurve, \
bluecurve); +        } else {
+            QPolygonF curve = currentColorSpace()->estimatedTRCXYY();
+            redcurve << curve.at(0) << curve.at(1) << curve.at(2) << curve.at(3) << \
curve.at(4); +            greencurve << curve.at(5) << curve.at(6) << curve.at(7) << \
curve.at(8) << curve.at(9); +            bluecurve << curve.at(10) << curve.at(11) << \
curve.at(12) << curve.at(13) << curve.at(14); +            \
d->colorSpaceSelector->TRCwidget->setRGBCurve(redcurve, greencurve, bluecurve); +     \
} +
         if (estimatedTRC[0] == -1) {
-            d->colorSpaceSelector->lbltrc->setToolTip(whatissRGB);
-            d->colorSpaceSelector->lbltrc->setText(estimatedsRGB);
+            d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+whatissRGB+"<br \
/>"+estimatedCurve+"</body></html>");  } else {
-            d->colorSpaceSelector->lbltrc->setToolTip(estimatedGamma + \
QString::number(estimatedTRC[0]) + "," + QString::number(estimatedTRC[1]) + "," + \
                QString::number(estimatedTRC[2]));
-            d->colorSpaceSelector->lbltrc->setText(estimatedGamma + \
QString::number((estimatedTRC[0] + estimatedTRC[1] + estimatedTRC[2])/3)); +          \
d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+estimatedGamma + \
QString::number(estimatedTRC[0]) + "," + QString::number(estimatedTRC[1]) + "," + \
QString::number(estimatedTRC[2])+"<br />"+estimatedCurve+"</body></html>");  }
     }
     else if (currentModelStr == "GRAYA") {
-        QVector <double> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY(); +        QVector <qreal> \
whitepoint = currentColorSpace()->profile()->getWhitePointxyY();  \
d->colorSpaceSelector->TongueWidget->setGrayData(whitepoint); +        \
d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());  \
estimatedTRC = currentColorSpace()->profile()->getEstimatedTRC(); +        QString \
estimatedCurve = " Estimated curve: "; +        QPolygonF tonecurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                tonecurve<<tonepoint;
+            }
+        } else {
+            d->colorSpaceSelector->TRCwidget->setProfileDataAvailable(false);
+        }
+        d->colorSpaceSelector->TRCwidget->setGreyscaleCurve(tonecurve);
         if (estimatedTRC[0] == -1) {
-            d->colorSpaceSelector->lbltrc->setToolTip(whatissRGB);
-            d->colorSpaceSelector->lbltrc->setText(estimatedsRGB);
+            d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+whatissRGB+"<br \
/>"+estimatedCurve+"</body></html>");  } else {
-            d->colorSpaceSelector->lbltrc->setToolTip(estimatedGamma + \
                QString::number(estimatedTRC[0]));
-            d->colorSpaceSelector->lbltrc->setText(estimatedGamma + \
QString::number(estimatedTRC[0])); +            \
d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+estimatedGamma + \
QString::number(estimatedTRC[0])+"<br />"+estimatedCurve+"</body></html>");  }
     }
     else if (currentModelStr == "CMYKA") {
-        QVector <double> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY(); +        QVector <qreal> \
whitepoint = currentColorSpace()->profile()->getWhitePointxyY();  \
                d->colorSpaceSelector->TongueWidget->setCMYKData(whitepoint);
-        d->colorSpaceSelector->lbltrc->setToolTip(i18nc("@info:tooltip","Estimated \
                Gamma cannot be retrieved for CMYK."));
-        d->colorSpaceSelector->lbltrc->setText(estimatedGamma + notApplicable);
+        d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());
 +        QString estimatedCurve = " Estimated curve: ";
+        QPolygonF tonecurve;
+        QPolygonF cyancurve;
+        QPolygonF magentacurve;
+        QPolygonF yellowcurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                tonecurve<<tonepoint;
+            }
+            d->colorSpaceSelector->TRCwidget->setGreyscaleCurve(tonecurve);
+        } else {
+            QPolygonF curve = currentColorSpace()->estimatedTRCXYY();
+            cyancurve << curve.at(0) << curve.at(1) << curve.at(2) << curve.at(3) << \
curve.at(4); +            magentacurve << curve.at(5) << curve.at(6) << curve.at(7) \
<< curve.at(8) << curve.at(9); +            yellowcurve << curve.at(10) << \
curve.at(11) << curve.at(12) << curve.at(13) << curve.at(14); +            tonecurve \
<< curve.at(15) << curve.at(16) << curve.at(17) << curve.at(18) << curve.at(19); +    \
d->colorSpaceSelector->TRCwidget->setCMYKCurve(cyancurve, magentacurve, yellowcurve, \
tonecurve); +        }
+        d->colorSpaceSelector->TRCwidget->setToolTip(i18nc("@info:tooltip","Estimated \
Gamma cannot be retrieved for CMYK."));  }
     else if (currentModelStr == "XYZA") {
-        QVector <double> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY(); +        QString estimatedCurve = \
" Estimated curve: "; +        estimatedTRC = \
currentColorSpace()->profile()->getEstimatedTRC(); +        QPolygonF tonecurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                tonecurve<<tonepoint;
+            }
+            d->colorSpaceSelector->TRCwidget->setGreyscaleCurve(tonecurve);
+        } else {
+            d->colorSpaceSelector->TRCwidget->setProfileDataAvailable(false);
+        }
+        QVector <qreal> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY();  \
                d->colorSpaceSelector->TongueWidget->setXYZData(whitepoint);
-        d->colorSpaceSelector->lbltrc->setToolTip(i18nc("@info:tooltip","XYZ is \
                assumed to be linear Gamma."));
-        d->colorSpaceSelector->lbltrc->setText(estimatedGamma + "1.0");
+        d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());
 +        d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+estimatedGamma \
+ QString::number(estimatedTRC[0])+"< br />"+estimatedCurve+"</body></html>");  }
     else if (currentModelStr == "LABA") {
-        QVector <double> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY(); +        estimatedTRC = \
currentColorSpace()->profile()->getEstimatedTRC(); +        QString estimatedCurve = \
" Estimated curve: "; +        QPolygonF tonecurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                tonecurve<<tonepoint;
+            }
+            d->colorSpaceSelector->TRCwidget->setGreyscaleCurve(tonecurve);
+        } else {
+            d->colorSpaceSelector->TRCwidget->setProfileDataAvailable(false);
+        }
+        QVector <qreal> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY();  \
                d->colorSpaceSelector->TongueWidget->setLABData(whitepoint);
-        d->colorSpaceSelector->lbltrc->setToolTip(i18nc("@info:tooltip","This is \
                assumed to be the L * TRC."));
-        d->colorSpaceSelector->lbltrc->setText(estimatedGamma + "L*");
+        d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());
 +        d->colorSpaceSelector->TRCwidget->setToolTip("<html><head/><body>"+i18nc("@info:tooltip","This \
is assumed to be the L * TRC. ")+"<br />"+estimatedCurve+"</body></html>");  }
     else if (currentModelStr == "YCbCrA") {
-        QVector <double> whitepoint = \
currentColorSpace()->profile()->getWhitePointxyY(); +        QVector <qreal> \
whitepoint = currentColorSpace()->profile()->getWhitePointxyY();  \
                d->colorSpaceSelector->TongueWidget->setYCbCrData(whitepoint);
-        d->colorSpaceSelector->lbltrc->setToolTip(i18nc("@info:tooltip","Estimated \
                Gamma cannot be retrieved for YCrCb."));
-        d->colorSpaceSelector->lbltrc->setText(estimatedGamma + notApplicable);
+        QString estimatedCurve = " Estimated curve: ";
+        QPolygonF tonecurve;
+        if (currentColorSpace()->profile()->hasTRC()){
+            for (int i=0; i<=10; i++) {
+                QVector <qreal> linear(3);
+                linear.fill(i*0.1);            
+                currentColorSpace()->profile()->linearizeFloatValue(linear);
+                estimatedCurve = estimatedCurve + ", " + QString::number(linear[0]);
+                QPointF tonepoint(linear[0],i*0.1);
+                tonecurve<<tonepoint;
+            }
+            d->colorSpaceSelector->TRCwidget->setGreyscaleCurve(tonecurve);
+        } else {
+            d->colorSpaceSelector->TRCwidget->setProfileDataAvailable(false);
+        }
+        d->colorSpaceSelector->TongueWidget->setGamut(currentColorSpace()->gamutXYY());
 +        d->colorSpaceSelector->TRCwidget->setToolTip(i18nc("@info:tooltip","Estimated \
Gamma cannot be retrieved for YCrCb."));  }
 
     d->colorSpaceSelector->textProfileDescription->clear();
     if (profileList.isEmpty()==false) {
         d->colorSpaceSelector->textProfileDescription->append("<h3>"+i18nc("About \
<Profilename>","About ")  +  currentColorSpace()->name()  +  "/"  +  profileName  +  \
"</h3>"); +        d->colorSpaceSelector->textProfileDescription->append("<p>"+ \
i18nc("ICC profile version","ICC Version: ")  + \
QString::number(currentColorSpace()->profile()->version())  +  "</p>"); +        \
//d->colorSpaceSelector->textProfileDescription->append("<p>"+ i18nc("Who made the \
profile?","Manufacturer: ")  + currentColorSpace()->profile()->manufacturer()  +  \
"</p>"); //This would work if people actually wrote the manufacturer into the \
manufacturer fiedl... +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+ i18nc("What is the \
copyright? These are from embedded strings from the icc profile, so they default to \
english.","Copyright: ")  + currentColorSpace()->profile()->copyright()  +  "</p>");  \
                } else {
         d->colorSpaceSelector->textProfileDescription->append("<h3>" + profileName  \
+  "</h3>");  }
 
     if (currentModelStr == "RGBA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is RGB", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
model is RGB",  "<b><a href=\"https://en.wikipedia.org/wiki/RGB_color_space\">RGB \
(Red, Green, Blue)</a></b>, is the color model used by screens and other light-based \
                media.<br/>"
                                                                     "RGB is an \
                additive color model: adding colors together makes them brighter. \
                This color "
                                                                     "model is the \
                most extensive of all color models, and is recommended as a model for \
                painting,"
-                                                                    "that you can \
later convert to other spaces. RGB is also the recommended colorspace for HDR \
editing.")); +                                                                    \
"that you can later convert to other spaces. RGB is also the recommended colorspace \
for HDR editing.")+"</p>");  } else if (currentModelStr == "CMYKA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is CMYK", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
model is CMYK",  "<b><a href=\"https://en.wikipedia.org/wiki/CMYK_color_model\">CMYK \
                (Cyan, Magenta, Yellow, Key)</a></b>, "
-                                                                    "is the model \
used by printers and other ink-based media.<p>" +                                     \
"is the model used by printers and other ink-based media.</br>"  "CMYK is a \
subtractive model, meaning that adding colors together will turn them darker. Because \
of CMYK "  "profiles being very specific per printer, it is recommended to work in \
                RGB space, and then later convert "
                                                                     "to a CMYK \
                profile, preferably one delivered by your printer. <br/>"
                                                                     "CMYK is \
                <b>not</b> recommended for painting."
-                                                                    "Unfortunately, \
Krita cannot retrieve colorants or the TRC for this space.")); +                      \
"Unfortunately, Krita cannot retrieve colorants or the TRC for this space.")+"</p>"); \
                } else if (currentModelStr == "XYZA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is XYZ", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
                model is XYZ",
                                                                     "<b><a \
href=\"https://en.wikipedia.org/wiki/CIE_1931_color_space\">CIE XYZ</a></b>"  "is the \
space determined by the CIE as the space that encompasses all other colors, and used \
to "  "convert colors between profiles. XYZ is an additive color model, meaning that \
adding colors together "  "makes them brighter. XYZ is <b>not</b> recommended for \
                painting, but can be useful to encode in. The Tone Response "
-                                                                    "Curve is \
assumed to be linear.")); +                                                           \
"Curve is assumed to be linear.")+"</p>");  } else if (currentModelStr == "GRAYA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is Grayscale", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
                model is Grayscale",
                                                                     "<b><a \
                href=\"https://en.wikipedia.org/wiki/Grayscale\">Grayscale</a></b> \
                only allows for "
                                                                     "gray values and \
                transparent values. Grayscale images use half "
                                                                     "the memory and \
                disk space compared to an RGB image of the same bit-depth.<br/>"
                                                                     "Grayscale is \
                useful for inking and greyscale images. In "
-                                                                    "Krita, you can \
mix Grayscale and RGB layers in the same image.")); +                                 \
"Krita, you can mix Grayscale and RGB layers in the same image.")+"</p>");  } else if \
                (currentModelStr == "LABA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is LAB", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
model is LAB",  "<b><a \
href=\"https://en.wikipedia.org/wiki/Lab_color_space\">L*a*b</a></b>. <b>L<b> stands \
                for Lightness, "
                                                                     "the <b>a</b> \
and <b>b</b> components represent color channels.<br/>"  "L*a*b is a special model \
for color correction. It is based on human perception, meaning that it " @@ -302,70 \
                +409,86 @@ void KisAdvancedColorSpaceSelector::fillDescription()
                                                                     "modes do \
<b>not</b> work as expected here.<br/>"  "Similarly, Krita does not support HDR in \
                LAB, meaning that HDR images converted to LAB lose color "
                                                                     "information. \
                This colorspace is <b>not</b> recommended for painting, nor for \
                export, "
-                                                                    "but best as a \
space to do post-processing in. The Tone Response Curve is assumed to be the L* \
TRC.")); +                                                                    "but \
best as a space to do post-processing in. The TRC is assumed to be the L* \
TRC.")+"</p>");  } else if (currentModelStr == "YCbCrA") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("If the selected \
model is YCbCr", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("If the selected \
model is YCbCr",  "<b><a href=\"https://en.wikipedia.org/wiki/YCbCr\">YCbCr (Luma, \
                Blue Chroma, Red Chroma)</a></b>, is a "
                                                                     "model designed \
                for video encoding. It is based on human perception, meaning that it \
                tries to "
                                                                     "encode the \
difference in lightness, red-green balance and yellow-blue balance. Chroma in "  \
"this case is then a word indicating a special type of saturation, in these cases the \
                saturation "
                                                                     "of Red and \
Blue, of which the desaturated equivalents are Green and Yellow respectively. It "  \
"is available to open up certain images correctly, but Krita does not currently ship \
                a profile for "
-                                                                    "this due to \
lack of open source ICC profiles for YCrCb.")); +                                     \
"this due to lack of open source ICC profiles for YCrCb.")+"</p>");  }
 
     QString currentDepthStr = \
d->colorSpaceSelector->cmbColorDepth->currentItem().id();  
     if (currentDepthStr == "U8") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("When the \
selected Bitdepth is 8", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("When the selected \
Bitdepth is 8",  "<b>8 bit integer</b>: The default amount of colors per channel. \
Each channel will have 256 values available, "  "leading to a total amount of \
                256*amount of channels. Recommended to use for images intended for \
                the web, "
-                                                                    "or otherwise \
simple images.")); +                                                                  \
"or otherwise simple images.")+"</p>");  }
     else if (currentDepthStr == "U16") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("When the \
selected Bitdepth is 16", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("When the selected \
Bitdepth is 16",  "<b>16 bit integer</b>: Also known as 'deep color'. 16 bit is ideal \
for editing images with a linear TRC, large "  "color space, or just when you need \
more precise color blending. This does take twice as much space on "  "the RAM and \
hard-drive than any given 8 bit image of the same properties, and for some devices it \
"  "takes much more processing power. We recommend watching the RAM usage of the file \
                carefully, or "
                                                                     "otherwise use 8 \
                bit if your computer slows down. Take care to disable conversion \
                optimization "
-                                                                    "when converting \
from 16 bit/channel to 8 bit/channel.")); +                                           \
"when converting from 16 bit/channel to 8 bit/channel.")+"</p>");  }
     else if (currentDepthStr == "F16") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("When the \
selected Bitdepth is 16 bit float", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("When the selected \
Bitdepth is 16 bit float",  "<b>16 bit floating point</b>: Also known as 'Half \
Floating Point', and the standard in VFX industry images. "  "16 bit float is ideal \
for editing images with a linear Tone Response Curve, large color space, or just when \
you need "  "more precise color blending. It being floating point is an absolute \
requirement for Scene Referred "  "(HDR) images. This does take twice as much space \
on the RAM and hard-drive than any given 8 bit image "  "of the same properties, and \
                for some devices it takes much more processing power. We recommend \
                watching "
-                                                                    "the RAM usage \
of the file carefully, or otherwise use 8 bit if your computer slows down.")); +      \
"the RAM usage of the file carefully, or otherwise use 8 bit if your computer slows \
down.")+"</p>");  }
     else if (currentDepthStr == "F32") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("When the \
selected Bitdepth is 32bit float", +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("When the selected \
Bitdepth is 32bit float",  "<b>32 bit float point</b>: Also known as 'Full Floating \
Point'. 32 bit float is ideal for editing images "  "with a linear TRC, large color \
space, or just when you need more precise color blending. It being "  "floating point \
is an absolute requirement for Scene Referred (HDR) images. This does take four times \
"  "as much space on the RAM and hard-drive than any given 8 bit image of the same \
properties, and for "  "some devices it takes much more processing power. We \
                recommend watching the RAM usage of the file "
-                                                                    "carefully, or \
otherwise use 8 bit if your computer slows down.")); +                                \
"carefully, or otherwise use 8 bit if your computer slows down.")+"</p>");  }
     else if (currentDepthStr == "F64") {
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("When the \
selected Bitdepth is 64bit float, but this isn't actually available in Krita at the \
moment.",\ +        d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("When \
the selected Bitdepth is 64bit float, but this isn't actually available in Krita at \
the moment.",\  "<b>64 bit float point</b>: 64 bit float is as precise as it gets in \
current technology, and this depth is used "  "most of the time for images that are \
generated or used as an input for software. It being floating point "  "is an \
absolute requirement for Scene Referred (HDR) images. This does take eight times as \
much space on "  "the RAM and hard-drive than any given 8 bit image of the same \
properties, and for some devices it takes "  "much more processing power. We \
                recommend watching the RAM usage of the file carefully, or otherwise \
                use "
-                                                                    "8 bit if your \
computer slows down.")); +                                                            \
"8 bit if your computer slows down.")+"</p>"); +    }
+    if (profileList.isEmpty()==false) {
+        QString possibleConversionIntents = "<p>"+i18n("The following conversion \
intents are possible: ")+"<ul>"; +        if \
(currentColorSpace()->profile()->supportsPerceptual()){ +            \
possibleConversionIntents += "<li>"+i18n("Perceptual")+"</li>"; +        }
+        if (currentColorSpace()->profile()->supportsRelative()){
+            possibleConversionIntents +=  "<li>"+i18n("Relative \
Colorimetric")+"</li>"; +        }
+        if (currentColorSpace()->profile()->supportsAbsolute()){
+            possibleConversionIntents += "<li>"+i18n("Absolute \
Colorimetric")+"</li>"; +        }
+        if (currentColorSpace()->profile()->supportsSaturation()){
+            possibleConversionIntents += "<li>"+i18n("Saturation")+"</li>";
+        }
+        possibleConversionIntents += "</ul></ul></p>";
+        d->colorSpaceSelector->textProfileDescription->append(possibleConversionIntents);
  }
-
     if (profileName.contains("-elle-")) {
 
-        d->colorSpaceSelector->textProfileDescription->append(i18nc("These are Elle \
                Stone's notes on her profiles that we ship.",
-                                                                    "<p><b>Extra \
notes on profiles by Elle Stone:</b>" +        \
d->colorSpaceSelector->textProfileDescription->append("<p>"+i18nc("These are Elle \
Stone's notes on her profiles that we ship.", +                                       \
                "<p><b>Extra notes on profiles by Elle Stone:</b></p>"
                                                                     "<p><i>Krita \
                comes with a number of high quality profiles created by "
                                                                     "<a \
href=\"http://ninedegreesbelow.com\">Elle Stone</a>. This is a summary. Please check \
                "
-                                                                    "<a \
href=\"http://ninedegreesbelow.com/photography/lcms-make-icc-profiles.html\">the full \
documentation</a> as well.</i>")); +                                                  \
"<a href=\"http://ninedegreesbelow.com/photography/lcms-make-icc-profiles.html\">the \
full documentation</a> as well.</i></p>"));  
                 if (profileName.contains("ACES-")) {
 
@@ -373,69 +496,69 @@ void KisAdvancedColorSpaceSelector::fillDescription()
                                                                         "<p>Quoting \
Wikipedia, 'Academy Color Encoding System (ACES) is a color image "  "encoding system \
proposed by the Academy of Motion Picture Arts and Sciences that will allow for "  "a \
fully encompassing color accurate workflow, with 'seamless interchange of high \
                quality motion "
-                                                                        "picture \
images regardless of source'.")); +                                                   \
"picture images regardless of source'.</p>"));  }
         if (profileName.contains("ACEScg-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>The ACEScg color space is smaller than the ACES color space, but large \
enough to contain the 'Rec-2020 gamut "  "and the DCI-P3 gamut', unlike the ACES \
                color space it has no negative values and contains only few colors "
-                                                                        "that fall \
just barely outside the area of real colors humans can see")); +                      \
"that fall just barely outside the area of real colors humans can see</p>"));  }
         if (profileName.contains("ClayRGB-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "To avoid \
possible copyright infringement issues, I used 'ClayRGB' (following ArgyllCMS) as the \
base name " +                                                                        \
"<p>To avoid possible copyright infringement issues, I used 'ClayRGB' (following \
ArgyllCMS) as the base name "  "for these profiles. As used below, 'Compatible with \
                Adobe RGB 1998' is terminology suggested in the preamble "
-                                                                        "to the \
AdobeRGB 1998 color space specifications.<p>" +                                       \
                "to the AdobeRGB 1998 color space specifications.</p><p>"
                                                                         "The Adobe \
RGB 1998 color gamut covers a higher "  "percentage of real-world cyans, greens, and \
yellow-greens than sRGB, but still doesn't include all printable "  "cyans, greens, \
yellow-greens, especially when printing using today's high-end, wider gamut, ink jet \
printers. "  "BetaRGB (not included in the profile pack) and Rec.2020 are better \
                matches for the color gamuts of today's "
-                                                                        "wide gamut \
printers.<p>" +                                                                       \
                "wide gamut printers.</p><p>"
                                                                         "The Adobe \
                RGB 1998 color gamut is a reasonable approximation to some of today's \
                "
-                                                                        "high-end \
wide gamut monitors.")); +                                                            \
"high-end wide gamut monitors.</p>"));  }
         if (profileName.contains("AllColorsRGB-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "This \
profile's color gamut is roughly the same size and shape as the ACES color space \
gamut, " +                                                                        \
"<p>This profile's color gamut is roughly the same size and shape as the ACES color \
space gamut, "  "and like the ACES color space, AllColorsRGB holds all possible real \
colors. But AllColorsRGB "  "actually has a slightly larger color gamut (to capture \
                some fringe colors that barely qualify "
-                                                                        "as real \
when viewed by the standard observer) and uses the D50 white point.<p>" +             \
"as real when viewed by the standard observer) and uses the D50 white point.</p><p>"  \
"Just like the ACES color space, AllColorsRGB holds a high percentage of imaginary \
                colors. See the Completely "
                                                                         "<a \
href=\"http://ninedegreesbelow.com/photography/xyz-rgb.html\">"  "Painless \
Programmer's Guide to XYZ, RGB, ICC, xyY, and TRCs</a> for more information about \
                imaginary "
-                                                                        "colors.<p>"
+                                                                        \
                "colors.</p><p>"
                                                                         "There is no \
                particular reason why anyone would want to use this profile "
                                                                         "for \
                editing, unless one needs to make sure your color space really does \
                hold all "
-                                                                        "possible \
real colors.")); +                                                                    \
"possible real colors.</p>"));  }
         if (profileName.contains("CIERGB-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "This \
profile is included mostly for its historical significance. " +                       \
                "<p>This profile is included mostly for its historical significance. \
                "
                                                                         "It's the \
                color space that was used in the original color matching experiments \
                "
-                                                                        "that led to \
the creation of the XYZ reference color space.<p>" +                                  \
                "that led to the creation of the XYZ reference color space.</p><p>"
                                                                         "The ASTM E \
                white point "
                                                                         "is probably \
                the right E white point to use when making the CIERGB color space \
                profile. "
                                                                         "It's not \
                clear to me what the correct CIERGB primaries really are. "
                                                                         "Lindbloom \
                gives one set. The LCMS version 1 tutorial gives a different set. "
                                                                         "Experts in \
                the field contend that the real primaries "
-                                                                        "should be \
calculated from the spectral wavelengths, so I did.")); +                             \
"should be calculated from the spectral wavelengths, so I did.</p>"));  }
         if (profileName.contains("IdentityRGB-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "The \
IdentityRGB working space is included in the profile pack because it's a \
mathematically " +                                                                    \
"<p>The IdentityRGB working space is included in the profile pack because it's a \
                mathematically "
                                                                         "obvious way \
to include all possible visible colors, though it has a higher percentage of "  \
"imaginary colors than the ACES and AllColorsRGB color spaces. I cannot think of any \
                reason "
-                                                                        "why you'd \
ever want to actually edit images in the IdentityRGB working space.")); +             \
"why you'd ever want to actually edit images in the IdentityRGB working \
space.</p>"));  }
         if (profileName.contains("LargeRGB-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "To avoid \
possible copyright infringement issues, I used 'LargeRGB' (following RawTherapee) " + \
"<p>To avoid possible copyright infringement issues, I used 'LargeRGB' (following \
                RawTherapee) "
                                                                         "as the base \
                name for these profiles.<p>"
                                                                         "Kodak \
designed the RIMM/ROMM (ProPhotoRGB) color "  "gamut to include all printable and \
most real world colors. It includes some imaginary colors " @@ -446,29 +569,29 @@ \
void KisAdvancedColorSpaceSelector::fillDescription()  "hard-coded into Adobe \
products such as Lightroom and the Dng-DCP camera 'profiles'. However, "  "other than \
being large enough to hold a lot of colors, ProPhotoRGB has no particular merit "  \
"as an RGB working space. Personally and for most editing purposes, I recommend \
                BetaRGB, Rec2020, "
-                                                                        "or the \
ACEScg profiles ProPhotoRGB.")); +                                                    \
"or the ACEScg profiles ProPhotoRGB.</p>"));  }
         if (profileName.contains("Rec2020-")) {
 
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "Rec.2020 is \
the up-and-coming replacement for the thoroughly outdated sRGB color space. As of " + \
"<p>Rec.2020 is the up-and-coming replacement for the thoroughly outdated sRGB color \
space. As of "  "June 2015, very few (if any) display devices (and certainly no \
affordable display devices) can "  "display all of Rec.2020. However, display \
technology is closing in on Rec.2020, movies are "  "already being made for Rec.2020, \
                and various cameras offer support for Rec.2020. And in the "
                                                                         "digital \
                darkroom Rec.2020 is much more suitable as a general RGB working \
                space than the "
-                                                                        "exceedingly \
small sRGB color space.")); +                                                         \
"exceedingly small sRGB color space.</p>"));  }
         if (profileName.contains("sRGB-")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        \
"Hewlett-Packard and Microsoft designed sRGB to match the color gamut of \
consumer-grade CRTs " +                                                               \
"<p>Hewlett-Packard and Microsoft designed sRGB to match the color gamut of \
consumer-grade CRTs "  "from the 1990s. sRGB is the standard color space for the \
                world wide web and is still the best "
-                                                                        "choice for \
exporting images to the internet.<p>" +                                               \
                "choice for exporting images to the internet.</p><p>"
                                                                         "The sRGB \
color gamut was a good match to "  "calibrated decent quality CRTs. But sRGB is not a \
good match to many consumer-grade LCD monitors, "  "which often cannot display the \
                more saturated sRGB blues and magentas (the good news: as technology \
                "
-                                                                        "progresses, \
wider gamuts are trickling down to consumer grade monitors).<p>" +                    \
"progresses, wider gamuts are trickling down to consumer grade monitors).</p><p>"  \
"Printer color gamuts can easily exceed the sRGB color gamut in cyans, greens, and \
                yellow-greens. Colors from interpolated "
-                                                                        "camera raw \
files also often exceed the sRGB color gamut.<p>" +                                   \
                "camera raw files also often exceed the sRGB color gamut.</p><p>"
                                                                         "As a very \
relevant aside, using perceptual "  "intent when converting to sRGB does not \
magically makes otherwise out of gamut colors fit inside the "  "sRGB color gamut! \
The standard sRGB color space (along with all the other the RGB profiles provided " \
@@ -476,11 +599,11 @@ void KisAdvancedColorSpaceSelector::fillDescription()  }
         if (profileName.contains("WideRGB-")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
                notes.",
-                                                                        "To avoid \
possible copyright infringement issues, I used 'WideRGB' as the base name for these \
profiles.<p>" +                                                                       \
"<p>To avoid possible copyright infringement issues, I used 'WideRGB' as the base \
name for these profiles.</p><p>"  "WideGamutRGB was designed by Adobe to be a wide \
gamut color space that uses spectral colors "  "as its primaries. Pascale's primary \
values produce a profile that matches old V2 Widegamut profiles "  "from Adobe and \
                Canon. It is an interesting color space, but shortly after its \
                introduction, Adobe "
-                                                                        "switched \
their emphasis to the ProPhotoRGB color space.")); +                                  \
"switched their emphasis to the ProPhotoRGB color space.</p>"));  }
         if (profileName.contains("Gray-")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.", @@ -488,25 +611,25 @@ void KisAdvancedColorSpaceSelector::fillDescription()
                                                                         "The main \
reason to convert from RGB to Gray is to save the file space needed to encode the \
image. "  "Google places a premium on fast-loading web pages, and images are one of \
the slower-loading elements "  "of a web page. So converting black and white images \
                to Grayscale images does save some kilobytes. "
-                                                                        " For \
grayscale images uploaded to the internet, convert the image to the V2 Gray profile \
with the sRGB TRC.")); +                                                              \
" For grayscale images uploaded to the internet, convert the image to the V2 Gray \
profile with the sRGB TRC.</p>"));  }
         if (profileName.contains("-g10")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>The profiles that end in '-g10.icc' are linear gamma (gamma=1.0, \
'linear light', etc) profiles and "  "should only be used when editing at high bit \
depths (16-bit floating point, 16-bit integer, 32-bit "  "floating point, 32-bit \
                integer). Many editing operations produce better results in linear \
                gamma color "
-                                                                        "spaces."));
+                                                                        \
"spaces.</p>"));  }
         if (profileName.contains("-labl")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>The profiles that end in '-labl.icc' have perceptually uniform TRCs. A \
few editing operations really "  "should be done on perceptually uniform RGB. Make \
                sure you use the V4 versions for editing high bit depth "
-                                                                        "images."));
+                                                                        \
"images.</p>"));  }
         if (profileName.contains("-srgbtrc") || profileName.contains("-g22") || \
                profileName.contains("-g18") || profileName.contains("-bt709")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>The profiles that end in '-srgbtrc.icc', '-g22.icc', and '-bt709.icc' \
                have approximately but not exactly "
-                                                                        \
"perceptually uniform TRCs. ProPhotoRGB's gamma=1.8 TRC is not quite as close to \
being perceptually uniform.")); +                                                     \
"perceptually uniform TRCs. ProPhotoRGB's gamma=1.8 TRC is not quite as close to \
being perceptually uniform.</p>"));  }
         if (d->colorSpaceSelector->cmbColorDepth->currentItem().id()=="U8") {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.", @@ -514,17 +637,17 @@ void KisAdvancedColorSpaceSelector::fillDescription()
                                                                         "exactly \
perceptually uniform TRC. Of the profiles supplied in my profile pack, only the sRGB \
and AdobeRGB1998 "  "(ClayRGB) color spaces are small enough for 8-bit editing. Even \
with the AdobeRGB1998 color space you need to "  "be careful to not cause \
posterization. And of course you cannot use the linear gamma versions of these \
                profiles "
-                                                                        "for 8-bit \
editing.")); +                                                                        \
"for 8-bit editing.</p>"));  }
         if (profileName.contains("-V4-")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>Use V4 profiles for editing images using high bit depth image editors \
                that use LCMS as the Color Management Module. "
-                                                                        "This \
includes Krita, digiKam/showFoto, and GIMP 2.9.")); +                                 \
"This includes Krita, digiKam/showFoto, and GIMP 2.9.</p>"));  }
         if (profileName.contains("-V2-")) {
             d->colorSpaceSelector->textProfileDescription->append(i18nc("From Elle's \
notes.",  "<p>Use V2 profiles for exporting finished images to be uploaded to the web \
                or for use with imaging software that "
-                                                                        "cannot read \
V4 profiles.")); +                                                                    \
"cannot read V4 profiles.</p>"));  }
     }
 
diff --git a/libs/ui/widgets/kis_cie_tongue_widget.cpp \
b/libs/ui/widgets/kis_cie_tongue_widget.cpp index e329066..9afa114 100644
--- a/libs/ui/widgets/kis_cie_tongue_widget.cpp
+++ b/libs/ui/widgets/kis_cie_tongue_widget.cpp
@@ -181,10 +181,12 @@ public:
  
     QPixmap         pixmap;
     QPixmap         cietongue;
+    QPixmap         gamutMap;
     KPixmapSequence progressPix;
  
     QVector <double> Primaries;
     QVector <double> whitePoint;
+    QPolygonF       gamut;
     model colorModel;
 };
 
@@ -198,6 +200,7 @@ KisCIETongueWidget::KisCIETongueWidget(QWidget *parent) :
     d->Primaries.fill(0.0);
     d->whitePoint.resize(3);
     d->whitePoint<<0.34773<<0.35952<<1.0;
+    d->gamut = QPolygonF();
 
     connect(d->progressTimer, SIGNAL(timeout()),
             this, SLOT(slotProgressTimerDone()));
@@ -225,7 +228,10 @@ void KisCIETongueWidget::setProfileData(QVector <double> p, \
QVector <double> w,  return;
     }
 }
-
+void KisCIETongueWidget::setGamut(QPolygonF gamut)
+{
+    d->gamut=gamut;
+}
 void KisCIETongueWidget::setRGBData(QVector <double> whitepoint, QVector <double> \
colorants)  {
     if (colorants.size()==9){
@@ -557,6 +563,52 @@ void KisCIETongueWidget::drawWhitePoint()
     drawSmallElipse(QPointF (d->whitePoint[0],d->whitePoint[1]),  255, 255, 255, 8);
 }
 
+void KisCIETongueWidget::drawGamut()
+{
+    d->gamutMap=QPixmap(size());
+    d->gamutMap.fill(Qt::black);
+    QPainter gamutPaint;
+    gamutPaint.begin(&d->gamutMap);
+    QPainterPath path;
+    //gamutPaint.setCompositionMode(QPainter::CompositionMode_Clear);
+    gamutPaint.setRenderHint(QPainter::Antialiasing);
+    path.setFillRule(Qt::WindingFill);
+    gamutPaint.setBrush(Qt::white);
+    gamutPaint.setPen(Qt::white);
+    int x, y = 0;
+    if (!d->gamut.empty()) {
+        gamutPaint.setOpacity(0.5);
+        if (d->colorModel == KisCIETongueWidget::RGBA) {
+            mapPoint(x, y, (QPointF(d->Primaries[0],d->Primaries[1])) );
+            path.moveTo(QPointF(x + d->xBias,y));
+            mapPoint(x, y, (QPointF(d->Primaries[3],d->Primaries[4])) );
+            path.lineTo(QPointF(x + d->xBias,y));
+            mapPoint(x, y, (QPointF(d->Primaries[6],d->Primaries[7])) );
+            path.lineTo(QPointF(x + d->xBias,y));
+            mapPoint(x, y, (QPointF(d->Primaries[0],d->Primaries[1])) );
+            path.lineTo(QPointF(x + d->xBias,y));
+        }
+        gamutPaint.drawPath(path);
+        gamutPaint.setOpacity(1.0);
+        foreach (QPointF Point, d->gamut) {
+            mapPoint(x, y, Point);
+            gamutPaint.drawEllipse(x + d->xBias- 2, y-2, 4, 4);
+            //Point.setX(x);
+            //Point.setY(y);
+            //path.lineTo(Point);
+        }
+    }
+    
+    gamutPaint.end();
+    d->painter.save();
+    d->painter.setOpacity(0.5);
+    d->painter.setCompositionMode(QPainter::CompositionMode_Multiply);
+    QRect area(d->xBias, 0, d->pxcols, d->pxrows);
+    d->painter.drawPixmap(area,d->gamutMap, area);
+    d->painter.setOpacity(1.0);
+    d->painter.restore();
+}
+
 void KisCIETongueWidget::updatePixmap()
 {
     d->needUpdatePixmap = false;
@@ -605,6 +657,8 @@ void KisCIETongueWidget::updatePixmap()
     {
         drawColorantTriangle();
     }
+    drawGamut();
+
     d->painter.end();
 }
  
diff --git a/libs/ui/widgets/kis_cie_tongue_widget.h \
b/libs/ui/widgets/kis_cie_tongue_widget.h index 3487e8f..8822793 100644
--- a/libs/ui/widgets/kis_cie_tongue_widget.h
+++ b/libs/ui/widgets/kis_cie_tongue_widget.h
@@ -50,7 +50,7 @@ public:
  
     //this expects a qvector <double> (9), qvector <double> (3) and whether or not \
                there's profile data?;
     void setProfileData(QVector <double> p, QVector <double> w, bool profileData = \
                false);
-    
+    void setGamut(QPolygonF gamut);
     void setRGBData(QVector <double> whitepoint, QVector <double> colorants);
     void setCMYKData(QVector <double> whitepoint);
     void setXYZData(QVector <double> whitepoint);
@@ -84,6 +84,7 @@ protected:
 private:
  
     void drawColorantTriangle();
+    void drawGamut();
     void drawWhitePoint();
     void drawPatches();
     void updatePixmap();
diff --git a/libs/ui/widgets/kis_tone_curve_widget.cpp \
b/libs/ui/widgets/kis_tone_curve_widget.cpp new file mode 100644
index 0000000..cc197e8
--- /dev/null
+++ b/libs/ui/widgets/kis_tone_curve_widget.cpp
@@ -0,0 +1,362 @@
+/* 
+ * Copyright (C) 2015 by Wolthera van Hövell tot Westerflier \
<griffinvalley@gmail.com> + *
+ * Based on the Digikam CIE Tongue widget
+ * Copyright (C) 2006-2013 by Gilles Caulier <caulier dot gilles at gmail dot com>
+ *
+ * Any source code are inspired from lprof project and
+ * Copyright (C) 1998-2001 Marti Maria
+ *
+ * This program is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation;
+ * either version 2, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ **/
+#include <QPointF>
+#include <QPolygonF>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QImage>
+#include <cmath>
+#include <klocalizedstring.h>
+
+
+#include "kis_tone_curve_widget.h"
+
+class Q_DECL_HIDDEN KisToneCurveWidget::Private
+{
+public:
+ 
+    Private() :
+        profileDataAvailable(false),
+        needUpdatePixmap(false),
+        TRCGray(true),
+        xBias(0),
+        yBias(0),
+        pxcols(0),
+        pxrows(0),
+        gridside(0)
+        
+    {
+    }
+    
+    bool            profileDataAvailable;
+    bool            needUpdatePixmap;
+    bool            TRCGray;
+    bool            TRCRGB;
+ 
+    int             xBias;
+    int             yBias;
+    int             pxcols;
+    int             pxrows;
+
+    QPolygonF       ToneCurveGray;
+    QPolygonF       ToneCurveRed;
+    QPolygonF       ToneCurveGreen;
+    QPolygonF       ToneCurveBlue;
+ 
+    double          gridside;
+ 
+    QPainter        painter;
+    QPainter        painter2;
+    QPixmap         pixmap;
+    QPixmap         curvemap;
+};
+
+KisToneCurveWidget::KisToneCurveWidget(QWidget *parent) :
+    QWidget(parent), d(new Private)
+{
+    /*this is a tone curve widget*/
+}
+
+KisToneCurveWidget::~KisToneCurveWidget()
+{
+    delete d;
+}
+
+void KisToneCurveWidget::setGreyscaleCurve(QPolygonF poly)
+{
+    d->ToneCurveGray = poly;
+    d->TRCGray = true;
+    d->TRCRGB = false;
+    d->profileDataAvailable = true;
+    d->needUpdatePixmap = true;
+}
+
+void KisToneCurveWidget::setRGBCurve(QPolygonF red, QPolygonF green, QPolygonF blue)
+{
+    d->ToneCurveRed = red;
+    d->ToneCurveGreen = green;
+    d->ToneCurveBlue = blue;
+    d->profileDataAvailable = true;
+    d->TRCGray = false;
+    d->TRCRGB = true;
+    d->needUpdatePixmap = true;
+}
+void KisToneCurveWidget::setCMYKCurve(QPolygonF cyan, QPolygonF magenta, QPolygonF \
yellow, QPolygonF key) +{
+    d->ToneCurveRed = cyan;
+    d->ToneCurveGreen = magenta;
+    d->ToneCurveBlue = yellow;
+    d->ToneCurveGray = key;
+    d->profileDataAvailable = true;
+    d->TRCGray = false;
+    d->TRCRGB = false;
+    d->needUpdatePixmap = true;
+}
+void KisToneCurveWidget::setProfileDataAvailable(bool dataAvailable)
+{
+    d->profileDataAvailable = dataAvailable;
+}
+int KisToneCurveWidget::grids(double val) const
+{
+    return (int) floor(val * d->gridside + 0.5);
+}
+
+void KisToneCurveWidget::mapPoint(QPointF & xy)
+{
+    QPointF dummy = xy;
+    xy.setX( (int) floor((dummy.x() * (d->pxcols - 1)) + .5) + d->xBias);
+    xy.setY( (int) floor(((d->pxrows - 1) - dummy.y() * (d->pxrows - 1)) + .5) );
+}
+
+void KisToneCurveWidget::biasedLine(int x1, int y1, int x2, int y2)
+{
+    d->painter.drawLine(x1 + d->xBias, y1, x2 + d->xBias, y2);
+}
+ 
+void KisToneCurveWidget::biasedText(int x, int y, const QString& txt)
+{
+    d->painter.drawText(QPoint(d->xBias + x, y), txt);
+}
+
+void KisToneCurveWidget::drawGrid()
+{
+    d->painter.setOpacity(1.0);
+    d->painter.setPen(qRgb(255, 255, 255));
+    biasedLine(0, 0,           0,           d->pxrows - 1);
+    biasedLine(0, d->pxrows-1, d->pxcols-1, d->pxrows - 1);
+    
+    QFont font;
+    font.setPointSize(6);
+    d->painter.setFont(font);
+    
+    for (int y = 1; y <= 9; y += 1)
+    {
+        QString s;
+        int xstart = (y * (d->pxcols - 1)) / 10;
+        int ystart = (y * (d->pxrows - 1)) / 10;
+ 
+        s.sprintf("0.%d", y);
+        biasedLine(xstart, d->pxrows - grids(1), xstart,   d->pxrows - grids(4));
+        biasedText(xstart - grids(11), d->pxrows + grids(15), s);
+ 
+        s.sprintf("0.%d", 10 - y);
+        biasedLine(0, ystart, grids(3), ystart);
+        biasedText(grids(-25), ystart + grids(5), s);
+    }
+    
+    d->painter.setPen(qRgb(128, 128, 128));
+    d->painter.setOpacity(0.5);
+ 
+    for (int y = 1; y <= 9; y += 1)
+    {
+        int xstart =  (y * (d->pxcols - 1)) / 10;
+        int ystart =  (y * (d->pxrows - 1)) / 10;
+ 
+        biasedLine(xstart, grids(4), xstart,   d->pxrows - grids(4) - 1);
+        biasedLine(grids(7), ystart, d->pxcols-1-grids(7), ystart);
+    }
+    d->painter.setOpacity(1.0);
+    d->painter.setOpacity(1.0);
+}
+
+void KisToneCurveWidget::updatePixmap()
+{
+    d->needUpdatePixmap = false;
+    d->pixmap = QPixmap(size());
+    d->curvemap = QPixmap(size());
+    d->pixmap.fill(Qt::black);
+    d->curvemap.fill(Qt::transparent);
+
+    d->painter.begin(&d->pixmap);
+    
+
+    int pixcols = d->pixmap.width();
+    int pixrows = d->pixmap.height();
+
+    d->gridside = (qMin(pixcols, pixrows)) / 512.0;
+    d->xBias    = grids(32);
+    d->yBias    = grids(20);
+    d->pxcols   = pixcols - d->xBias;
+    d->pxrows   = pixrows - d->yBias;
+
+    d->painter.setBackground(QBrush(qRgb(0, 0, 0)));
+    QPointF start;
+    drawGrid();
+    d->painter.setRenderHint(QPainter::Antialiasing);
+    if (d->TRCGray && d->ToneCurveGray.size()>0){
+        QPainterPath path;
+        start = d->ToneCurveGray.at(0);
+        mapPoint(start);
+        path.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveGray) {
+            mapPoint(Point);
+            path.lineTo(Point);
+        }
+        d->painter.setPen(qRgb(255, 255, 255));
+        d->painter.drawPath(path);
+    } else if (d->TRCRGB && d->ToneCurveRed.size()>0 && d->ToneCurveGreen.size()>0 \
&& d->ToneCurveBlue.size()>0){ +        d->painter.save();
+        d->painter.setCompositionMode(QPainter::CompositionMode_Screen);
+        QPainterPath path;
+        start = d->ToneCurveRed.at(0);
+        mapPoint(start);
+        path.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveRed) {
+            mapPoint(Point);
+            path.lineTo(Point);
+        }
+        d->painter.setPen(qRgb(255, 0, 0));
+        d->painter.drawPath(path);
+        QPainterPath path2;
+        start = d->ToneCurveGreen.at(0);
+        mapPoint(start);
+        path2.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveGreen) {
+            mapPoint(Point);
+            path2.lineTo(Point);
+        }
+        d->painter.setPen(qRgb(0, 255, 0));
+        d->painter.drawPath(path2);
+        QPainterPath path3;
+        start = d->ToneCurveBlue.at(0);
+        mapPoint(start);
+        path3.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveBlue) {
+            mapPoint(Point);
+            path3.lineTo(Point);
+        }
+        d->painter.setPen(qRgb(0, 0, 255));
+        d->painter.drawPath(path3);
+        d->painter.restore();
+    } else {
+        d->painter2.begin(&d->curvemap);
+        d->painter2.setRenderHint(QPainter::Antialiasing);
+        //d->painter2.setCompositionMode(QPainter::CompositionMode_Multiply);
+        QPainterPath path;
+        start = d->ToneCurveRed.at(0);
+        mapPoint(start);
+        path.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveRed) {
+            mapPoint(Point);
+            path.lineTo(Point);
+        }
+        d->painter2.setPen(qRgb(0, 255, 255));
+        d->painter2.drawPath(path);
+        QPainterPath path2;
+        start = d->ToneCurveGreen.at(0);
+        mapPoint(start);
+        path2.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveGreen) {
+            mapPoint(Point);
+            path2.lineTo(Point);
+        }
+        d->painter2.setPen(qRgb(255, 0, 255));
+        d->painter2.drawPath(path2);
+        QPainterPath path3;
+        start = d->ToneCurveBlue.at(0);
+        mapPoint(start);
+        path3.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveBlue) {
+            mapPoint(Point);
+            path3.lineTo(Point);
+        }
+        d->painter2.setPen(qRgb(255, 255, 0));
+        d->painter2.drawPath(path3);
+        QPainterPath path4;
+        start = d->ToneCurveGray.at(0);
+        mapPoint(start);
+        path4.moveTo(start);
+        foreach (QPointF Point, d->ToneCurveGray) {
+            mapPoint(Point);
+            path4.lineTo(Point);
+        }
+        d->painter2.setPen(qRgb(80, 80, 80));
+        d->painter2.drawPath(path4);
+        d->painter2.end();
+        QRect area(d->xBias, 0, d->pxcols, d->pxrows);
+        d->painter.drawPixmap(area,d->curvemap, area);
+    }
+    d->painter.end();
+
+}
+
+void KisToneCurveWidget::paintEvent(QPaintEvent*)
+{
+    QPainter p(this);
+ 
+    // Widget is disable : drawing grayed frame.
+ 
+    if ( !isEnabled() )
+    {
+        p.fillRect(0, 0, width(), height(),
+                   palette().color(QPalette::Disabled, QPalette::Background));
+ 
+        QPen pen(palette().color(QPalette::Disabled, QPalette::Foreground));
+        pen.setStyle(Qt::SolidLine);
+        pen.setWidth(1);
+ 
+        p.setPen(pen);
+        p.drawRect(0, 0, width(), height());
+ 
+        return;
+    }
+
+ 
+    // No profile data to show, or RAW file
+ 
+    if (!d->profileDataAvailable)
+    {
+        p.fillRect(0, 0, width(), height(), palette().color(QPalette::Active, \
QPalette::Background)); +        QPen pen(palette().color(QPalette::Active, \
QPalette::Text)); +        pen.setStyle(Qt::SolidLine);
+        pen.setWidth(1);
+ 
+        p.setPen(pen);
+        p.drawRect(0, 0, width(), height());
+ 
+        p.setPen(Qt::red);
+        p.drawText(0, 0, width(), height(), Qt::AlignCenter,
+        i18n("No tone curve available..."));
+ 
+        return;
+    }
+ 
+    // Create CIE tongue if needed
+    if (d->needUpdatePixmap)
+    {
+        updatePixmap();
+    }
+ 
+    // draw prerendered tongue
+    p.drawPixmap(0, 0, d->pixmap);
+}
+ 
+void KisToneCurveWidget::resizeEvent(QResizeEvent* event)
+{
+    Q_UNUSED(event);
+    setMinimumWidth(height());
+    setMaximumWidth(height());
+    d->needUpdatePixmap = true;
+}
\ No newline at end of file
diff --git a/libs/ui/widgets/kis_cie_tongue_widget.h \
b/libs/ui/widgets/kis_tone_curve_widget.h similarity index 51%
copy from libs/ui/widgets/kis_cie_tongue_widget.h
copy to libs/ui/widgets/kis_tone_curve_widget.h
index 3487e8f..25fa811 100644
--- a/libs/ui/widgets/kis_cie_tongue_widget.h
+++ b/libs/ui/widgets/kis_tone_curve_widget.h
@@ -22,84 +22,46 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  **/
- 
-#ifndef KIS_CIETONGUEWIDGET_H
-#define KIS_CIETONGUEWIDGET_H
- 
-// Qt includes
+
+#ifndef KIS_TONECURVEWIDGET_H
+#define KIS_TONECURVEWIDGET_H
  
 #include <QWidget>
 #include <QColor>
 #include <QPaintEvent>
- 
-// KDE includes
 
-#include <KoColor.h>
-#include <KoColorSpace.h>
-  
 #include <kritaui_export.h>
  
-class KRITAUI_EXPORT KisCIETongueWidget : public QWidget
+class KRITAUI_EXPORT KisToneCurveWidget : public QWidget
 {
     Q_OBJECT
  
 public:
  
-    KisCIETongueWidget(QWidget *parent=0);
-    ~KisCIETongueWidget();
- 
-    //this expects a qvector <double> (9), qvector <double> (3) and whether or not \
                there's profile data?;
-    void setProfileData(QVector <double> p, QVector <double> w, bool profileData = \
                false);
-    
-    void setRGBData(QVector <double> whitepoint, QVector <double> colorants);
-    void setCMYKData(QVector <double> whitepoint);
-    void setXYZData(QVector <double> whitepoint);
-    void setGrayData(QVector <double> whitepoint);
-    void setLABData(QVector <double> whitepoint);
-    void setYCbCrData(QVector <double> whitepoint);
+    KisToneCurveWidget(QWidget *parent=0);
+    ~KisToneCurveWidget();
+
+    void setGreyscaleCurve(QPolygonF poly);
+    void setRGBCurve(QPolygonF red, QPolygonF green, QPolygonF blue);
+    void setCMYKCurve(QPolygonF cyan, QPolygonF magenta, QPolygonF yellow, QPolygonF \
key);  void setProfileDataAvailable(bool dataAvailable);
- 
-    void loadingStarted();
-    void loadingFailed();
-    void uncalibratedColor();
-    
-    enum model {RGBA, CMYKA, XYZA, LABA, GRAYA, YCbCrA};
- 
 protected:
  
     int  grids(double val) const;
- 
-    void outlineTongue();
-    void fillTongue();
-    void drawTongueAxis();
-    void drawTongueGrid();
-    void drawLabels();
- 
-    QRgb colorByCoord(double x, double y);
-    void drawSmallElipse(QPointF xy, int r, int g, int b, int sz);
- 
+    void drawGrid();
     void resizeEvent(QResizeEvent* event);
     void paintEvent(QPaintEvent*);
  
 private:
  
-    void drawColorantTriangle();
-    void drawWhitePoint();
-    void drawPatches();
     void updatePixmap();
- 
-    void mapPoint(int& icx, int& icy, QPointF xy);
+    void mapPoint(QPointF & xy);
     void biasedLine(int x1, int y1, int x2, int y2);
     void biasedText(int x, int y, const QString& txt);
- 
-private Q_SLOTS:
- 
-    void slotProgressTimerDone();
- 
 private :
  
     class Private;
     Private* const d;
 };
- 
-#endif /* KISCIETONGUEWIDGET_H */
+
+#endif /* KISTONECURVEWIDGET_H */
\ No newline at end of file
diff --git a/plugins/color/colorspaceextensions/kis_hsv_adjustment.cpp \
b/plugins/color/colorspaceextensions/kis_hsv_adjustment.cpp index f6219bc..f9b9e98 \
                100644
--- a/plugins/color/colorspaceextensions/kis_hsv_adjustment.cpp
+++ b/plugins/color/colorspaceextensions/kis_hsv_adjustment.cpp
@@ -92,84 +92,211 @@ public:
     void transform(const quint8 *srcU8, quint8 *dstU8, qint32 nPixels) const
     {
 
-        const RGBPixel* src = reinterpret_cast<const RGBPixel*>(srcU8);
-        RGBPixel* dst = reinterpret_cast<RGBPixel*>(dstU8);
-        float h, s, v, r, g, b;
-        while (nPixels > 0) {
+        //if (m_model="RGBA" || m_colorize) {
+        /*It'd be nice to have LCH automatically selector for LAB in the future, but \
I don't know how to select LAB  +         * */
+            const RGBPixel* src = reinterpret_cast<const RGBPixel*>(srcU8);
+            RGBPixel* dst = reinterpret_cast<RGBPixel*>(dstU8);
+            float h, s, v, r, g, b;
+            qreal lumaR, lumaG, lumaB;
+            //Default to rec 709 when there's no coefficients given//
+            if (m_lumaRed<=0 || m_lumaGreen<=0 || m_lumaBlue<=0) {
+                lumaR   = 0.2126;
+                lumaG   = 0.7152;
+                lumaB   = 0.0722;
+            } else {
+                lumaR   = m_lumaRed;
+                lumaG   = m_lumaGreen;
+                lumaB   = m_lumaBlue;
+            }
+            while (nPixels > 0) {
 
-            if (m_colorize) {
-                h = m_adj_h * 360;
-                if (h >= 360.0) h = 0;
+                if (m_colorize) {
+                    h = m_adj_h * 360;
+                    if (h >= 360.0) h = 0;
 
-                s = m_adj_s;
+                    s = m_adj_s;
 
-                r = SCALE_TO_FLOAT(src->red);
-                g = SCALE_TO_FLOAT(src->green);
-                b = SCALE_TO_FLOAT(src->blue);
+                    r = SCALE_TO_FLOAT(src->red);
+                    g = SCALE_TO_FLOAT(src->green);
+                    b = SCALE_TO_FLOAT(src->blue);
 
-                float luminance = r * 0.2126 + g * 0.7152 + b * 0.0722;
+                    float luminance = r * lumaR + g * lumaG + b * lumaB;
 
-                if (m_adj_v > 0) {
-                    luminance *= (1.0 - m_adj_v);
-                    luminance += 1.0 - (1.0 - m_adj_v);
-                }
-                else if (m_adj_v < 0 ){
-                    luminance *= (m_adj_v + 1.0);
-                }
-                v = luminance;
-                HSLToRGB(h, s, v, &r, &g, &b);
+                    if (m_adj_v > 0) {
+                        luminance *= (1.0 - m_adj_v);
+                        luminance += 1.0 - (1.0 - m_adj_v);
+                    }
+                    else if (m_adj_v < 0 ){
+                        luminance *= (m_adj_v + 1.0);
+                    }
+                    v = luminance;
+                    HSLToRGB(h, s, v, &r, &g, &b);
 
-            }
-            else {
-
-                if (m_type == 0) {
-                    RGBToHSV(SCALE_TO_FLOAT(src->red), SCALE_TO_FLOAT(src->green), \
                SCALE_TO_FLOAT(src->blue), &h, &s, &v);
-                    h += m_adj_h * 180;
-                    if (h > 360) h -= 360;
-                    if (h < 0) h += 360;
-                    s += m_adj_s;
-                    v += m_adj_v;
-                    HSVToRGB(h, s, v, &r, &g, &b);
                 }
                 else {
 
-                    RGBToHSL(SCALE_TO_FLOAT(src->red), SCALE_TO_FLOAT(src->green), \
SCALE_TO_FLOAT(src->blue), &h, &s, &v); +                    if (m_type == 0) {
+                        RGBToHSV(SCALE_TO_FLOAT(src->red), \
SCALE_TO_FLOAT(src->green), SCALE_TO_FLOAT(src->blue), &h, &s, &v); +                 \
h += m_adj_h * 180; +                        if (h > 360) h -= 360;
+                        if (h < 0) h += 360;
+                        s += m_adj_s;
+                        v += m_adj_v;
+                        HSVToRGB(h, s, v, &r, &g, &b);
+                    } else if (abs(m_type) == 1) {
+
+                        RGBToHSL(SCALE_TO_FLOAT(src->red), \
SCALE_TO_FLOAT(src->green), SCALE_TO_FLOAT(src->blue), &h, &s, &v); +
+                        h += m_adj_h * 180;
+                        if (h > 360) h -= 360;
+                        if (h < 0) h += 360;
+
+                        s *= (m_adj_s + 1.0);
+                        if (s < 0.0) s = 0.0;
+                        if (s > 1.0) s = 1.0;
+
+                        if (m_adj_v < 0)
+                            v *= (m_adj_v + 1.0);
+                        else
+                            v += (m_adj_v * (1.0 - v));
+
+
+                        HSLToRGB(h, s, v, &r, &g, &b);
+                    } else if (m_type == 2){
+
+                        qreal red = SCALE_TO_FLOAT(src->red);
+                        qreal green = SCALE_TO_FLOAT(src->green);
+                        qreal blue = SCALE_TO_FLOAT(src->blue);
+                        qreal hue, sat, intensity;
+                        RGBToHCI(red, green, blue, &hue, &sat, &intensity);
+
+                        hue *=360.0;
+                        hue += m_adj_h * 180;
+                        //if (intensity+m_adj_v>1.0){hue+=180.0;}
+                        if (hue < 0) hue += 360;
+                        hue = fmod(hue, 360.0);
+
+                        sat *= (m_adj_s + 1.0);
+                        //sat = qBound(0.0, sat, 1.0);
+                        
+                        intensity += (m_adj_v);
+
+                        HCIToRGB(hue/360.0, sat, intensity, &red, &green, &blue);
+
+                        r = red;
+                        g = green;
+                        b = blue;
+                    } else if (m_type == 3){
+
+                        qreal red = SCALE_TO_FLOAT(src->red);
+                        qreal green = SCALE_TO_FLOAT(src->green);
+                        qreal blue = SCALE_TO_FLOAT(src->blue);
+                        qreal hue, sat, luma;
+                        RGBToHCY(red, green, blue, &hue, &sat, &luma, lumaR, lumaG, \
lumaB); +
+                        hue *=360.0;
+                        hue += m_adj_h * 180;
+                        //if (luma+m_adj_v>1.0){hue+=180.0;}
+                        if (hue < 0) hue += 360;
+                        hue = fmod(hue, 360.0);
+
+                        sat *= (m_adj_s + 1.0);
+                        //sat = qBound(0.0, sat, 1.0);
+
+                        luma += m_adj_v;
+
+
+                        HCYToRGB(hue/360.0, sat, luma, &red, &green, &blue, lumaR, \
lumaG, lumaB); +                        r = red;
+                        g = green;
+                        b = blue;
+                        
+                    } else if (m_type == 4){
+
+                        qreal red = SCALE_TO_FLOAT(src->red);
+                        qreal green = SCALE_TO_FLOAT(src->green);
+                        qreal blue = SCALE_TO_FLOAT(src->blue);
+                        qreal y, cb, cr;
+                        RGBToYUV(red, green, blue, &y, &cb, &cr, lumaR, lumaG, \
lumaB); +
+                        cb *= (m_adj_h + 1.0);
+                        //cb = qBound(0.0, cb, 1.0);
+
+                        cr *= (m_adj_s + 1.0);
+                        //cr = qBound(0.0, cr, 1.0);
+
+                        
+                        
+                        y += (m_adj_v);
+
+
+                        YUVToRGB(y, cb, cr, &red, &green, &blue, lumaR, lumaG, \
lumaB); +                        r = red;
+                        g = green;
+                        b = blue;
+                    }
+                }
 
-                    h += m_adj_h * 180;
-                    if (h > 360) h -= 360;
-                    if (h < 0) h += 360;
+                clamp< _channel_type_ >(&r, &g, &b);
+                dst->red = SCALE_FROM_FLOAT(r);
+                dst->green = SCALE_FROM_FLOAT(g);
+                dst->blue = SCALE_FROM_FLOAT(b);
+                dst->alpha = src->alpha;
 
-                    s *= (m_adj_s + 1.0);
-                    if (s < 0.0) s = 0.0;
-                    if (s > 1.0) s = 1.0;
+                --nPixels;
+                ++src;
+                ++dst;
+            }
+        /*} else if (m_model="LABA"){
+            const LABPixel* src = reinterpret_cast<const LABPixel*>(srcU8);
+            LABPixel* dst = reinterpret_cast<LABPixel*>(dstU8);
+            qreal lightness = SCALE_TO_FLOAT(src->L);
+            qreal a = SCALE_TO_FLOAT(src->a);
+            qreal b = SCALE_TO_FLOAT(src->b);
+            qreal L, C, H;
+            
+            while (nPixels > 0) {
+                if (m_type = 4) {
+                    a *= (m_adj_h + 1.0);
+                    a = qBound(0.0, a, 1.0);
+
+                    b *= (m_adj_s + 1.0);
+                    b = qBound(0.0, b, 1.0);
 
                     if (m_adj_v < 0)
-                        v *= (m_adj_v + 1.0);
+                        lightness *= (m_adj_v + 1.0);
                     else
-                        v += (m_adj_v * (1.0 - v));
-
-
-                    HSLToRGB(h, s, v, &r, &g, &b);
+                        lightness += (m_adj_v * (1.0 - lightness));
+                } else {//lch
+                    LABToLCH(lightness, a, b, &L, &C, &H);
+                    H *=360;
+                    H += m_adj_h * 180;
+                    if (H > 360) h -= 360;
+                    if (H < 0) h += 360;
+                    C += m_adj_s;
+                    C = qBound(0.0,C,1.0);
+                    L += m_adj_v;
+                    L = qBound(0.0,L,1.0);
+                    LCHToLAB(L, C, H/360.0, &lightness, &a, &b);
                 }
-
-            }
-
-            clamp< _channel_type_ >(&r, &g, &b);
-            dst->red = SCALE_FROM_FLOAT(r);
-            dst->green = SCALE_FROM_FLOAT(g);
-            dst->blue = SCALE_FROM_FLOAT(b);
-            dst->alpha = src->alpha;
-
-            --nPixels;
-            ++src;
-            ++dst;
-        }
+                clamp< _channel_type_ >(&lightness, &a, &b);
+                dst->L = SCALE_FROM_FLOAT(lightness);
+                dst->a = SCALE_FROM_FLOAT(a);
+                dst->b = SCALE_FROM_FLOAT(b);
+                dst->alpha = src->alpha;
+
+                --nPixels;
+                ++src;
+                ++dst;
+                }
+        }*/
     }
 
     virtual QList<QString> parameters() const
     {
       QList<QString> list;
-      list << "h" << "s" << "v" << "type" << "colorize";
+      list << "h" << "s" << "v" << "type" << "colorize" << "lumaRed" << \
"lumaGreen"<< "lumaBlue";  return list;
     }
 
@@ -185,6 +312,12 @@ public:
             return 3;
         } else if (name == "colorize") {
             return 4;
+        } else if (name == "lumaRed") {
+            return 5;
+        } else if (name == "lumaGreen") {
+            return 6;
+        } else if (name == "lumaBlue") {
+            return 7;
         }
         return -1;
     }
@@ -194,6 +327,9 @@ public:
     * (h)ue in range <-1.0, 1.0> ( for user, show as -180, 180 or 0, 360 for \
                colorize)
     * (s)aturation in range <-1.0, 1.0> ( for user, show -100, 100, or 0, 100 for \
                colorize)
     * (v)alue in range <-1.0, 1.0> (for user, show -100, 100)
+    * type: 0:HSV, 1:HSL, 2:HSI, 3:HSY, 4:YUV
+    * m_colorize: Use colorize formula instead
+    * luma Red/Green/Blue: Used for luma calculations.
     */
     virtual void setParameter(int id, const QVariant& parameter)
     {
@@ -214,14 +350,28 @@ public:
         case 4:
             m_colorize = parameter.toBool();
             break;
+        case 5:
+            m_lumaRed = parameter.toDouble();
+            break;
+        case 6:
+            m_lumaGreen = parameter.toDouble();
+            break;
+        case 7:
+            m_lumaBlue = parameter.toDouble();
+            break;
         default:
             ;
         }
     }
+    void setLuma(qreal R, qreal G, qreal B){
+        
+    }
 
 private:
 
     double m_adj_h, m_adj_s, m_adj_v;
+    qreal m_lumaRed, m_lumaGreen, m_lumaBlue;
+    QString model;
     int m_type;
     bool m_colorize;
 };
diff --git a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp \
b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp index aa37fe9..b71b033 \
                100644
--- a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp
+++ b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.cpp
@@ -127,7 +127,13 @@ bool IccColorProfile::valid() const
     }
     return false;
 }
-
+float IccColorProfile::version() const
+{
+    if (d->shared->lcmsProfile) {
+        return d->shared->lcmsProfile->version();
+    }
+    return 0.0;
+}
 bool IccColorProfile::isSuitableForOutput() const
 {
     if (d->shared->lcmsProfile) {
@@ -151,6 +157,35 @@ bool IccColorProfile::isSuitableForDisplay() const
     }
     return false;
 }
+
+bool IccColorProfile::supportsPerceptual() const
+{
+    if (d->shared->lcmsProfile) {
+        return d->shared->lcmsProfile->supportsPerceptual();
+    }
+    return false;
+}
+bool IccColorProfile::supportsSaturation() const
+{
+    if (d->shared->lcmsProfile) {
+        return d->shared->lcmsProfile->supportsSaturation();
+    }
+    return false;
+}
+bool IccColorProfile::supportsAbsolute() const
+{
+    if (d->shared->lcmsProfile) {
+        return d->shared->lcmsProfile->supportsAbsolute();
+    }
+    return false;
+}
+bool IccColorProfile::supportsRelative() const
+{
+    if (d->shared->lcmsProfile) {
+        return d->shared->lcmsProfile->supportsRelative();
+    }
+    return false;
+}
 bool IccColorProfile::hasColorants() const
 {
     if (d->shared->lcmsProfile) {
@@ -158,47 +193,75 @@ bool IccColorProfile::hasColorants() const
     }
     return false;
 }
-QVector <double> IccColorProfile::getColorantsXYZ() const
+bool IccColorProfile::hasTRC() const
+{
+    if (d->shared->lcmsProfile)
+        return d->shared->lcmsProfile->hasTRC();
+    return false;
+}
+QVector <qreal> IccColorProfile::getColorantsXYZ() const
 {
     if (d->shared->lcmsProfile) {
         return d->shared->lcmsProfile->getColorantsXYZ();
     }
-    return QVector<double>(9);
+    return QVector<qreal>(9);
 }
-QVector <double> IccColorProfile::getColorantsxyY() const
+QVector <qreal> IccColorProfile::getColorantsxyY() const
 {
     if (d->shared->lcmsProfile) {
         return d->shared->lcmsProfile->getColorantsxyY();
     }
-    return QVector<double>(9);
+    return QVector<qreal>(9);
 }
-QVector <double> IccColorProfile::getWhitePointXYZ() const
+QVector <qreal> IccColorProfile::getWhitePointXYZ() const
 {
-    QVector <double> d50Dummy(3);
+    QVector <qreal> d50Dummy(3);
     d50Dummy << 0.9642 << 1.0000 << 0.8249;
     if (d->shared->lcmsProfile) {
         return d->shared->lcmsProfile->getWhitePointXYZ();
     }
     return d50Dummy;
 }
-QVector <double> IccColorProfile::getWhitePointxyY() const
+QVector <qreal> IccColorProfile::getWhitePointxyY() const
 {
-    QVector <double> d50Dummy(3);
+    QVector <qreal> d50Dummy(3);
     d50Dummy << 0.34773 << 0.35952 << 1.0;
     if (d->shared->lcmsProfile) {
         return d->shared->lcmsProfile->getWhitePointxyY();
     }
     return d50Dummy;
 }
-QVector <double> IccColorProfile::getEstimatedTRC() const
+QVector <qreal> IccColorProfile::getEstimatedTRC() const
 {
-    QVector <double> dummy(3);
+    QVector <qreal> dummy(3);
     dummy.fill(2.2);//estimated sRGB trc.
     if (d->shared->lcmsProfile) {
         return d->shared->lcmsProfile->getEstimatedTRC();
     }
     return dummy;
 }
+
+void IccColorProfile::linearizeFloatValue(QVector <qreal> & Value) const
+{
+    if (d->shared->lcmsProfile)
+        d->shared->lcmsProfile->LinearizeFloatValue(Value);
+}
+void IccColorProfile::delinearizeFloatValue(QVector <qreal> & Value) const
+{
+    if (d->shared->lcmsProfile)
+        d->shared->lcmsProfile->DelinearizeFloatValue(Value);
+}
+void IccColorProfile::linearizeFloatValueFast(QVector <qreal> & Value) const
+{
+    if (d->shared->lcmsProfile)
+        d->shared->lcmsProfile->LinearizeFloatValueFast(Value);
+}
+void IccColorProfile::delinearizeFloatValueFast(QVector<qreal> &Value) const
+{
+    if (d->shared->lcmsProfile)
+        d->shared->lcmsProfile->DelinearizeFloatValueFast(Value);
+}
+
 bool IccColorProfile::load()
 {
     QFile file(fileName());
@@ -226,6 +289,8 @@ bool IccColorProfile::init()
     if (d->shared->lcmsProfile->init()) {
         setName(d->shared->lcmsProfile->name());
         setInfo(d->shared->lcmsProfile->info());
+        setManufacturer(d->shared->lcmsProfile->manufacturer());
+        setCopyright(d->shared->lcmsProfile->copyright());
         if (d->shared->lcmsProfile->valid()) {
             calculateFloatUIMinMax();
         }
@@ -276,8 +341,8 @@ void IccColorProfile::calculateFloatUIMinMax(void)
 
     uint16_t in_min_pixel[4] = {0, 0, 0, 0};
     uint16_t in_max_pixel[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-    double out_min_pixel[4] = {0, 0, 0, 0};
-    double out_max_pixel[4] = {0, 0, 0, 0};
+    qreal out_min_pixel[4] = {0, 0, 0, 0};
+    qreal out_max_pixel[4] = {0, 0, 0, 0};
 
     cmsHTRANSFORM trans = cmsCreateTransform(
                               cprofile,
diff --git a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.h \
b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.h index 884c0fe..5d49822 \
                100644
--- a/plugins/color/lcms2engine/colorprofiles/IccColorProfile.h
+++ b/plugins/color/lcms2engine/colorprofiles/IccColorProfile.h
@@ -62,6 +62,8 @@ public:
     public:
         virtual QString name() const = 0;
         virtual QString info() const = 0;
+        virtual QString manufacturer() const = 0;
+        virtual QString copyright() const = 0;
         virtual bool valid() const = 0;
         virtual bool isSuitableForOutput() const = 0;
         virtual bool isSuitableForPrinting() const = 0;
@@ -90,15 +92,25 @@ public:
     */
     QByteArray rawData() const;
     virtual bool valid() const;
+    virtual float version() const;
     virtual bool isSuitableForOutput() const;
     virtual bool isSuitableForPrinting() const;
     virtual bool isSuitableForDisplay() const;
+    virtual bool supportsPerceptual() const;
+    virtual bool supportsSaturation() const;
+    virtual bool supportsAbsolute() const;
+    virtual bool supportsRelative() const;
     virtual bool hasColorants() const;
-    virtual QVector <double> getColorantsXYZ() const;
-    virtual QVector <double> getColorantsxyY() const;
-    virtual QVector <double> getWhitePointXYZ() const;
-    virtual QVector <double> getWhitePointxyY() const;
-    virtual QVector <double> getEstimatedTRC() const;
+    virtual bool hasTRC() const;
+    virtual QVector <qreal> getColorantsXYZ() const;
+    virtual QVector <qreal> getColorantsxyY() const;
+    virtual QVector <qreal> getWhitePointXYZ() const;
+    virtual QVector <qreal> getWhitePointxyY() const;
+    virtual QVector <qreal> getEstimatedTRC() const;
+    virtual void linearizeFloatValue(QVector <qreal> & Value) const;
+    virtual void delinearizeFloatValue(QVector <qreal> & Value) const;
+    virtual void linearizeFloatValueFast(QVector <qreal> & Value) const;
+    virtual void delinearizeFloatValueFast(QVector <qreal> & Value) const;
     virtual bool operator==(const KoColorProfile &) const;
     virtual QString type() const
     {
diff --git a/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.cpp \
b/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.cpp index \
                4f707a1..223d35a 100644
--- a/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.cpp
+++ b/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.cpp
@@ -43,11 +43,14 @@ public:
     cmsProfileClassSignature deviceClass;
     QString productDescription;
     QString manufacturer;
+    QString copyright;
     QString name;
+    float version;
     IccColorProfile::Data *data;
     bool valid;
     bool suitableForOutput;
     bool hasColorants;
+    bool hasTRC;
     bool adaptedFromD50;
     cmsNAMEDCOLORLIST *namedColorList;
     cmsCIEXYZ mediaWhitePoint;
@@ -57,6 +60,17 @@ public:
     cmsToneCurve *greenTRC;
     cmsToneCurve *blueTRC;
     cmsToneCurve *grayTRC;
+    cmsToneCurve *redTRCReverse;
+    cmsToneCurve *greenTRCReverse;
+    cmsToneCurve *blueTRCReverse;
+    cmsToneCurve *grayTRCReverse;
+    
+    cmsUInt32Number defaultIntent;
+    bool isPerceptualCLUT;
+    bool isRelativeCLUT;
+    bool isAbsoluteCLUT;
+    bool isSaturationCLUT;
+    bool isMatrixShaper;
 };
 
 LcmsColorProfileContainer::LcmsColorProfileContainer()
@@ -125,12 +139,16 @@ bool LcmsColorProfileContainer::init()
         cmsGetProfileInfo(d->profile, cmsInfoDescription, cmsNoLanguage, \
cmsNoCountry, buffer, _BUFFER_SIZE_);  d->name = QString::fromWCharArray(buffer);
 
+        //apparantly this should give us a localised string??? Not sure about this.
         cmsGetProfileInfo(d->profile, cmsInfoModel, cmsNoLanguage, cmsNoCountry, \
buffer, _BUFFER_SIZE_);  d->productDescription = QString::fromWCharArray(buffer);
 
         cmsGetProfileInfo(d->profile, cmsInfoManufacturer, cmsNoLanguage, \
cmsNoCountry, buffer, _BUFFER_SIZE_);  d->manufacturer = \
QString::fromWCharArray(buffer);  
+        cmsGetProfileInfo(d->profile, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, \
buffer, _BUFFER_SIZE_); +        d->copyright = QString::fromWCharArray(buffer);
+
         cmsProfileClassSignature profile_class;
         profile_class = cmsGetDeviceClass(d->profile);
         d->valid = (profile_class != cmsSigNamedColorClass);
@@ -170,22 +188,6 @@ bool LcmsColorProfileContainer::init()
                 cmsXYZ2xyY(&d->whitePoint, &d->mediaWhitePoint);
             }
         }
-
-        //Colorant table tag is for CMYK and other named color profiles. If we use \
                this correctly we can display the full list of named colors
-        //in a named color profile. We retrieve more information elsewhere.
-        if (cmsIsTag(d->profile, cmsSigColorantTableTag)) {
-            d->namedColorList = ((cmsNAMEDCOLORLIST *)cmsReadTag(d->profile, \
                cmsSigColorantTableTag));
-            for (cmsUInt16Number i = 0; i < cmsNamedColorCount(d->namedColorList); \
                i++) {
-                char name;
-                char prefix;
-                char suffix;
-                cmsUInt16Number pcs;
-                cmsUInt16Number col;
-                cmsNamedColorInfo(d->namedColorList, i, &name, &prefix, &suffix, \
                &pcs, &col);
-                //qDebug()<<d->name<<i<<","<< name<<","<< prefix<<","<< suffix;
-                //if (pcs){qDebug()<<pcs;} else {qDebug()<<"no pcs retrieved";}
-            }
-        }
         //This is for RGB profiles, but it only works for matrix profiles. Need to \
design it to work with non-matrix profiles.  if (cmsIsTag(d->profile, \
cmsSigRedColorantTag)) {  cmsCIEXYZTRIPLE tempColorants;
@@ -204,19 +206,36 @@ bool LcmsColorProfileContainer::init()
         }
         //retrieve TRC.
         if (cmsIsTag(d->profile, cmsSigRedTRCTag) && cmsIsTag(d->profile, \
                cmsSigBlueTRCTag) && cmsIsTag(d->profile, cmsSigGreenTRCTag)) {
-
-            d->redTRC = ((cmsToneCurve *)cmsReadTag(d->profile, cmsSigRedTRCTag));
-            d->greenTRC = ((cmsToneCurve *)cmsReadTag(d->profile, \
                cmsSigGreenTRCTag));
-            d->blueTRC = ((cmsToneCurve *)cmsReadTag(d->profile, cmsSigBlueTRCTag));
-
+        
+            d->redTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigRedTRCTag));
+            d->greenTRC = ((cmsToneCurve *)cmsReadTag (d->profile, \
cmsSigGreenTRCTag)); +            d->blueTRC = ((cmsToneCurve *)cmsReadTag \
(d->profile, cmsSigBlueTRCTag)); +            d->redTRCReverse = \
cmsReverseToneCurve(d->redTRC); +            d->greenTRCReverse = \
cmsReverseToneCurve(d->greenTRC); +            d->blueTRCReverse = \
cmsReverseToneCurve(d->blueTRC); +            d->hasTRC = true;
+        
         } else if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) {
-            d->grayTRC = ((cmsToneCurve *)cmsReadTag(d->profile, cmsSigGrayTRCTag));
+            d->grayTRC = ((cmsToneCurve *)cmsReadTag (d->profile, \
cmsSigGrayTRCTag)); +            d->grayTRCReverse = cmsReverseToneCurve(d->grayTRC);
+            d->hasTRC = true;
+        } else {
+            d->hasTRC = false;
         }
 
         // Check if the profile can convert (something->this)
         d->suitableForOutput = cmsIsMatrixShaper(d->profile)
                                || (cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, \
                LCMS_USED_AS_INPUT) &&
                                    cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, \
LCMS_USED_AS_OUTPUT)); +
+        d->version = cmsGetProfileVersion(d->profile);
+        d->defaultIntent = cmsGetHeaderRenderingIntent(d->profile);
+        d->isMatrixShaper = cmsIsMatrixShaper(d->profile);
+        d->isPerceptualCLUT = cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, \
LCMS_USED_AS_INPUT); +        d->isSaturationCLUT = cmsIsCLUT(d->profile, \
INTENT_SATURATION, LCMS_USED_AS_INPUT); +        d->isAbsoluteCLUT = \
cmsIsCLUT(d->profile, INTENT_SATURATION, LCMS_USED_AS_INPUT); +        \
d->isRelativeCLUT = cmsIsCLUT(d->profile, INTENT_RELATIVE_COLORIMETRIC, \
LCMS_USED_AS_INPUT); +
         return true;
     }
 
@@ -243,11 +262,21 @@ QString LcmsColorProfileContainer::manufacturer() const
     return d->manufacturer;
 }
 
+QString LcmsColorProfileContainer::copyright() const
+{
+    return d->copyright;
+}
+
 bool LcmsColorProfileContainer::valid() const
 {
     return d->valid;
 }
 
+float LcmsColorProfileContainer::version() const
+{
+    return d->version;
+}
+
 bool LcmsColorProfileContainer::isSuitableForOutput() const
 {
     return d->suitableForOutput;
@@ -262,10 +291,34 @@ bool LcmsColorProfileContainer::isSuitableForDisplay() const
 {
     return deviceClass() == cmsSigDisplayClass;
 }
+
+bool LcmsColorProfileContainer::supportsPerceptual() const
+{
+    return d->isPerceptualCLUT;
+}
+bool LcmsColorProfileContainer::supportsSaturation() const
+{
+    return d->isSaturationCLUT;
+}
+bool LcmsColorProfileContainer::supportsAbsolute() const
+{
+    return d->isAbsoluteCLUT;//LCMS2 doesn't convert matrix shapers via absolute \
intent, because of V4 workflow. +}
+bool LcmsColorProfileContainer::supportsRelative() const
+{
+    if (d->isRelativeCLUT || d->isMatrixShaper){
+        return true;
+    }
+    return false;
+}
 bool LcmsColorProfileContainer::hasColorants() const
 {
     return d->hasColorants;
 }
+bool LcmsColorProfileContainer::hasTRC() const
+{
+    return d->hasTRC;
+}
 QVector <double> LcmsColorProfileContainer::getColorantsXYZ() const
 {
     QVector <double> colorants(9);
@@ -368,6 +421,132 @@ QVector <double> LcmsColorProfileContainer::getEstimatedTRC() \
const  return TRCtriplet;
 }
 
+void LcmsColorProfileContainer::LinearizeFloatValue(QVector <double> & Value) const
+{
+    QVector <double> TRCtriplet(3);
+    TRCtriplet[0] = Value[0];
+    TRCtriplet[1] = Value[1];
+    TRCtriplet[2] = Value[2];
+    
+
+    if (d->hasColorants) {
+        if (cmsIsToneCurveLinear(d->redTRC)) {
+            TRCtriplet[0] = Value[0];
+        } else {
+            TRCtriplet[0] = cmsEvalToneCurveFloat(d->redTRC, Value[0]);
+        }
+        if (cmsIsToneCurveLinear(d->greenTRC)) {
+            TRCtriplet[1] = Value[1];
+        } else {
+            TRCtriplet[1] = cmsEvalToneCurveFloat(d->greenTRC, Value[1]);
+        }
+        if (cmsIsToneCurveLinear(d->blueTRC)) {
+            TRCtriplet[2] = Value[2];
+        } else {
+            TRCtriplet[2] = cmsEvalToneCurveFloat(d->blueTRC, Value[2]);
+        }
+            
+    } else {
+        if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) {
+            TRCtriplet.fill(cmsEvalToneCurveFloat(d->grayTRC, Value[0]));
+        }
+    }
+    Value = TRCtriplet;
+}
+
+void LcmsColorProfileContainer::DelinearizeFloatValue(QVector <double> & Value) \
const +{
+    QVector <double> TRCtriplet(3);
+    TRCtriplet[0] = Value[0];
+    TRCtriplet[1] = Value[1];
+    TRCtriplet[2] = Value[2];
+    if (cmsIsTag(d->profile, cmsSigRedTRCTag)) {
+        if (cmsIsToneCurveLinear(d->redTRC)) {
+            TRCtriplet[0] = Value[0];
+        } else {
+            TRCtriplet[0] = cmsEvalToneCurveFloat(d->redTRCReverse, Value[0]);
+        }
+        if (cmsIsToneCurveLinear(d->greenTRC)) {
+            TRCtriplet[1] = Value[1];
+        } else {
+            TRCtriplet[1] = cmsEvalToneCurveFloat(d->greenTRCReverse, Value[1]);
+        }
+        if (cmsIsToneCurveLinear(d->blueTRC)) {
+            TRCtriplet[2] = Value[2];
+        } else {
+            TRCtriplet[2] = cmsEvalToneCurveFloat(d->blueTRCReverse, Value[2]);
+        }
+            
+    } else {
+        if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) {
+            TRCtriplet.fill(cmsEvalToneCurveFloat(d->grayTRCReverse, Value[0]));
+        }
+    }
+
+    Value = TRCtriplet;
+}
+
+void LcmsColorProfileContainer::LinearizeFloatValueFast(QVector <double> & Value) \
const +{
+    //we can only reliably delinearise in the 0-1.0 range, outside of that leave the \
value alone. +    QVector <quint16> TRCtriplet(3);
+    TRCtriplet[0] = Value[0]*65535;
+    TRCtriplet[1] = Value[1]*65535;
+    TRCtriplet[2] = Value[2]*65535;
+    
+
+    if (d->hasColorants) {
+        if (!cmsIsToneCurveLinear(d->redTRC) && Value[0]<1.0) {
+            TRCtriplet[0] = cmsEvalToneCurve16(d->redTRC, TRCtriplet[0]);
+            Value[0] = TRCtriplet[0]/65535.0;
+        }
+        if (!cmsIsToneCurveLinear(d->greenTRC) && Value[1]<1.0) {
+            TRCtriplet[1] = cmsEvalToneCurve16(d->greenTRC, TRCtriplet[1]);
+            Value[1] = TRCtriplet[1]/65535.0;
+        }
+        if (!cmsIsToneCurveLinear(d->blueTRC) && Value[2]<1.0) {
+            TRCtriplet[2] = cmsEvalToneCurve16(d->blueTRC, TRCtriplet[2]);
+            Value[2] = TRCtriplet[2]/65535.0;
+        }
+            
+    } else {
+        if (cmsIsTag(d->profile, cmsSigGrayTRCTag) && Value[0]<1.0) {
+            TRCtriplet[0] = (cmsEvalToneCurve16(d->grayTRC, Value[0]*65535));
+            Value.fill(TRCtriplet[0]/65535.0);
+        }
+    }
+}
+void LcmsColorProfileContainer::DelinearizeFloatValueFast(QVector <double> & Value) \
const +{
+    //we can only reliably delinearise in the 0-1.0 range, outside of that leave the \
value alone. +    QVector <quint16> TRCtriplet(3);
+    TRCtriplet[0] = Value[0]*65535;
+    TRCtriplet[1] = Value[1]*65535;
+    TRCtriplet[2] = Value[2]*65535;
+    
+
+    if (d->hasColorants) {
+        if (!cmsIsToneCurveLinear(d->redTRC) && Value[0]<1.0) {
+            TRCtriplet[0] = cmsEvalToneCurve16(d->redTRCReverse, TRCtriplet[0]);
+            Value[0] = TRCtriplet[0]/65535.0;
+        }
+        if (!cmsIsToneCurveLinear(d->greenTRC) && Value[1]<1.0) {
+            TRCtriplet[1] = cmsEvalToneCurve16(d->greenTRCReverse, TRCtriplet[1]);
+            Value[1] = TRCtriplet[1]/65535.0;
+        }
+        if (!cmsIsToneCurveLinear(d->blueTRC) && Value[2]<1.0) {
+            TRCtriplet[2] = cmsEvalToneCurve16(d->blueTRCReverse, TRCtriplet[2]);
+            Value[2] = TRCtriplet[2]/65535.0;
+        }
+            
+    } else {
+        if (cmsIsTag(d->profile, cmsSigGrayTRCTag) && Value[0]<1.0) {
+            TRCtriplet[0] = (cmsEvalToneCurve16(d->grayTRCReverse, Value[0]*65535));
+            Value.fill(TRCtriplet[0]/65535.0);
+        }
+    }
+}
+
 QString LcmsColorProfileContainer::name() const
 {
     return d->name;
diff --git a/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.h \
b/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.h index \
                fa20866..9d851c9 100644
--- a/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.h
+++ b/plugins/color/lcms2engine/colorprofiles/LcmsColorProfileContainer.h
@@ -67,25 +67,40 @@ public:
      * @return the name of the manufacturer
      */
     QString manufacturer() const;
-
+    /**
+     * @return the embedded copyright
+     */
+    QString copyright() const;
     /**
      * @return the structure to use with LCMS functions
      */
     cmsHPROFILE lcmsProfile() const;
 
     virtual bool valid() const;
+    virtual float version() const;
 
     virtual bool isSuitableForOutput() const;
 
     virtual bool isSuitableForPrinting() const;
 
     virtual bool isSuitableForDisplay() const;
+
+    virtual bool supportsPerceptual() const;
+    virtual bool supportsSaturation() const;
+    virtual bool supportsAbsolute() const;
+    virtual bool supportsRelative() const;
+
     virtual bool hasColorants() const;
+    virtual bool hasTRC() const;
     virtual QVector <double> getColorantsXYZ() const;
     virtual QVector <double> getColorantsxyY() const;
     virtual QVector <double> getWhitePointXYZ() const;
     virtual QVector <double> getWhitePointxyY() const;
     virtual QVector <double> getEstimatedTRC() const;
+    virtual void LinearizeFloatValue(QVector <double> & Value) const;
+    virtual void DelinearizeFloatValue(QVector <double> & Value) const;
+    virtual void LinearizeFloatValueFast(QVector <double> & Value) const;
+    virtual void DelinearizeFloatValueFast(QVector <double> & Value) const;
     virtual QString name() const;
     virtual QString info() const;
 
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp index \
                6d5b4d7..b9fd560 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include <KoColorConversions.h>
 
 CmykF32ColorSpace::CmykF32ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoCmykF32Traits>(colorSpaceId(), name,  TYPE_CMYKA_FLT, \
cmsSigCmykData, p) @@ -80,3 +81,45 @@ void CmykF32ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) cons  p->alpha = 1.0;
 }
 
+void CmykF32ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    //we use HSI here because we can't linearise CMYK, and HSY doesn't work right \
with... +    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToHSI(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma);
+}
+
+QVector <double> CmykF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    HSIToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[0] = \
qBound(0.0,1.0-channelValues[0],1.0); +    channelValues[1] = \
qBound(0.0,1.0-channelValues[1],1.0); +    channelValues[2] = \
qBound(0.0,1.0-channelValues[2],1.0); +    \
CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]); + \
return channelValues; +}
+
+void CmykF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, (1.0 - \
0.299),(1.0 - 0.587), (1.0 - 0.114)); +}
+
+QVector <double> CmykF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
0.33, 0.33, 0.33); +    channelValues[0] = qBound(0.0,1.0-channelValues[0],1.0);
+    channelValues[1] = qBound(0.0,1.0-channelValues[1],1.0);
+    channelValues[2] = qBound(0.0,1.0-channelValues[2],1.0);
+    CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    return channelValues;
+}
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.h index \
                4a5fa5a..04e5447 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.h
@@ -49,7 +49,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY( qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.cpp index \
                e62b1f1..6f46733 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include <KoColorConversions.h>
 
 CmykU16ColorSpace::CmykU16ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<CmykU16Traits>(colorSpaceId(), name,  TYPE_CMYKA_16, \
cmsSigCmykData, p) @@ -74,3 +75,46 @@ void CmykU16ColorSpace::colorFromXML(quint8 \
                *pixel, const QDomElement &elt) cons
     p->black = KoColorSpaceMaths< qreal, CmykU16Traits::channels_type \
>::scaleToA(elt.attribute("k").toDouble());  p->alpha = \
> KoColorSpaceMathsTraits<quint16>::max;
 }
+
+void CmykU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    //we use HSI here because we can't linearise CMYK, and HSY doesn't work right \
with... +    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToHSI(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma);
+}
+
+QVector <double> CmykU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    HSIToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[0] = \
qBound(0.0,1.0-channelValues[0],1.0); +    channelValues[1] = \
qBound(0.0,1.0-channelValues[1],1.0); +    channelValues[2] = \
qBound(0.0,1.0-channelValues[2],1.0); +    \
CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]); + \
return channelValues; +}
+
+void CmykU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, 0.33, \
0.33, 0.33); +}
+
+QVector <double> CmykU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
0.33, 0.33, 0.33); +    channelValues[0] = qBound(0.0,1.0-channelValues[0],1.0);
+    channelValues[1] = qBound(0.0,1.0-channelValues[1],1.0);
+    channelValues[2] = qBound(0.0,1.0-channelValues[2],1.0);
+    CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    return channelValues;
+}
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.h index \
                6807f94..c1dec56 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_u16/CmykU16ColorSpace.h
@@ -50,8 +50,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
-
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const; +    
     static QString colorSpaceId()
     {
         return "CMYKAU16";
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.cpp index \
                a3b046a..b4bd724 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.cpp
@@ -25,6 +25,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include <KoColorConversions.h>
 
 CmykU8ColorSpace::CmykU8ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<CmykU8Traits>(colorSpaceId(), name,  TYPE_CMYKA_8, \
cmsSigCmykData, p) @@ -76,3 +77,45 @@ void CmykU8ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) const  p->alpha = \
KoColorSpaceMathsTraits<quint8>::max;  }
 
+void CmykU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    //we use HSI here because we can't linearise CMYK, and HSY doesn't work right \
with... +    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToHSI(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma);
+}
+
+QVector <double> CmykU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    HSIToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[0] = \
qBound(0.0,1.0-channelValues[0],1.0); +    channelValues[1] = \
qBound(0.0,1.0-channelValues[1],1.0); +    channelValues[2] = \
qBound(0.0,1.0-channelValues[2],1.0); +    \
CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]); + \
return channelValues; +}
+
+void CmykU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    CMYKToCMY(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    channelValues[0] = 1.0-channelValues[0];
+    channelValues[1] = 1.0-channelValues[1];
+    channelValues[2] = 1.0-channelValues[2];
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, 0.33, \
0.33, 0.33); +}
+
+QVector <double> CmykU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(5);
+    channelValues.fill(1.0);
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
0.33, 0.33, 0.33); +    channelValues[0] = qBound(0.0,1.0-channelValues[0],1.0);
+    channelValues[1] = qBound(0.0,1.0-channelValues[1],1.0);
+    channelValues[2] = qBound(0.0,1.0-channelValues[2],1.0);
+    CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
 +    return channelValues;
+}
diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.h index \
                721ddd2..e4c8801 100644
--- a/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/cmyk_u8/CmykU8ColorSpace.h
@@ -47,7 +47,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.cpp index \
                709f6a9..bf8ce9f 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.cpp
@@ -62,3 +62,28 @@ void GrayF16ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) cons  p[1] = 1.0;
 }
 
+void GrayF16ColorSpace::toHSY(QVector <double> channelValues, qreal *, qreal *, \
qreal *luma) const +{
+    *luma = channelValues[0];
+}
+
+QVector <double> GrayF16ColorSpace::fromHSY(qreal *, qreal *, qreal *luma) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*luma);
+    channelValues[1]=1.0;
+    return channelValues;
+}
+
+void GrayF16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *, \
qreal *) const +{
+    *y = channelValues[0];
+}
+
+QVector <double> GrayF16ColorSpace::fromYUV(qreal *y, qreal *, qreal *) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*y);
+    channelValues[1]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.h index \
                76864d1..01ad527 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/gray_f16/GrayF16ColorSpace.h
@@ -50,7 +50,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.cpp index \
                df8eb92..41ab593 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.cpp
@@ -65,3 +65,28 @@ void GrayF32ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) cons  p[1] = 1.0;
 }
 
+void GrayF32ColorSpace::toHSY(QVector <double> channelValues, qreal *, qreal *, \
qreal *luma) const +{
+    *luma = channelValues[0];
+}
+
+QVector <double> GrayF32ColorSpace::fromHSY(qreal *, qreal *, qreal *luma) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*luma);
+    channelValues[1]=1.0;
+    return channelValues;
+}
+
+void GrayF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *, \
qreal *) const +{
+    *y = channelValues[0];
+}
+
+QVector <double> GrayF32ColorSpace::fromYUV(qreal *y, qreal *, qreal *) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*y);
+    channelValues[1]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.h index \
                4b4eb59..c28b327 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/gray_f32/GrayF32ColorSpace.h
@@ -50,7 +50,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.cpp index \
                7ad4e08..fd3519d 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.cpp
@@ -60,3 +60,28 @@ void GrayAU16ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) con  p[1] = KoColorSpaceMathsTraits<quint16>::max;
 }
 
+void GrayAU16ColorSpace::toHSY(QVector <double> channelValues, qreal *, qreal *, \
qreal *luma) const +{
+    *luma = channelValues[0];
+}
+
+QVector <double> GrayAU16ColorSpace::fromHSY(qreal *, qreal *, qreal *luma) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*luma);
+    channelValues[1]=1.0;
+    return channelValues;
+}
+
+void GrayAU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *, \
qreal *) const +{
+    *y = channelValues[0];
+}
+
+QVector <double> GrayAU16ColorSpace::fromYUV(qreal *y, qreal *, qreal *) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*y);
+    channelValues[1]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.h index \
                7dd8034..b97e8f5 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/gray_u16/GrayU16ColorSpace.h
@@ -49,7 +49,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.cpp index \
                4d478fc..9d8bb78 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.cpp
@@ -59,3 +59,28 @@ void GrayAU8ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) cons  p[1] = KoColorSpaceMathsTraits<quint8>::max;
 }
 
+void GrayAU8ColorSpace::toHSY(QVector <double> channelValues, qreal *, qreal *, \
qreal *luma) const +{
+    *luma = channelValues[0];
+}
+
+QVector <double> GrayAU8ColorSpace::fromHSY(qreal *, qreal *, qreal *luma) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*luma);
+    channelValues[1]=1.0;
+    return channelValues;
+}
+
+void GrayAU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *, \
qreal *) const +{
+    *y = channelValues[0];
+}
+
+QVector <double> GrayAU8ColorSpace::fromYUV(qreal *y, qreal *, qreal *) const
+{
+    QVector <double> channelValues(2);
+    channelValues.fill(*y);
+    channelValues[1]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.h index \
                0e0cd29..33f68b2 100644
--- a/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/gray_u8/GrayU8ColorSpace.h
@@ -50,7 +50,12 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.cpp index \
                aac1b86..b347a0e 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "../compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 LabF32ColorSpace::LabF32ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoLabF32Traits>(colorSpaceId(), name, TYPE_LabA_FLT, \
cmsSigLabData, p) @@ -76,3 +77,32 @@ void LabF32ColorSpace::colorFromXML(quint8 \
                *pixel, const QDomElement &elt) const
     p->b = KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type \
>::scaleToA(elt.attribute("b").toDouble());  p->alpha = 1.0;
 }
+
+void LabF32ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> LabF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+void LabF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> LabF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.h index \
                f529fb7..f69ec25 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/lab_f32/LabF32ColorSpace.h
@@ -53,7 +53,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     virtual bool hasHighDynamicRange() const
     {
diff --git a/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.cpp index \
                700b8dd..3e56267 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "../compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 LabU16ColorSpace::LabU16ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoLabU16Traits>(colorSpaceId(), name, TYPE_LABA_16, \
cmsSigLabData, p) @@ -92,3 +93,32 @@ void LabU16ColorSpace::colorFromXML(quint8 \
                *pixel, const QDomElement &elt) const
     p->b = KoColorSpaceMaths< qreal, KoLabU16Traits::channels_type \
>::scaleToA(elt.attribute("b").toDouble());  p->alpha = \
> KoColorSpaceMathsTraits<quint16>::max;
 }
+void LabU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> LabU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void LabU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> LabU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.h index \
                a65f01e..b0e4226 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/lab_u16/LabColorSpace.h
@@ -56,7 +56,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 private:
     static const quint32 MAX_CHANNEL_L = 0xff00;
diff --git a/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.cpp index \
                b14ce17..afa6bfe 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "../compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 LabU8ColorSpace::LabU8ColorSpace(const QString &name, KoColorProfile *p) :
     LcmsColorSpace<KoLabU8Traits>(colorSpaceId(), name, TYPE_LABA_8, cmsSigLabData, \
p) @@ -87,3 +88,33 @@ void LabU8ColorSpace::colorFromXML(quint8 *pixel, const \
                QDomElement &elt) const
     p->b = KoColorSpaceMaths< qreal, KoLabU8Traits::channels_type \
>::scaleToA(elt.attribute("b").toDouble());  p->alpha = \
> KoColorSpaceMathsTraits<quint8>::max;
 }
+
+void LabU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> LabU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const
+{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void LabU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> LabU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.h index \
                5ebd97a..52b2afc 100644
--- a/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/lab_u8/LabU8ColorSpace.h
@@ -49,9 +49,13 @@ public:
         return Integer8BitsColorDepthID;
     }
 
-    virtual KoColorSpace *clone() const;
-    virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
                &colorElt) const;
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual KoColorSpace* clone() const;
+    virtual void colorToXML(const quint8* pixel, QDomDocument& doc, QDomElement& \
colorElt) const; +    virtual void colorFromXML(quint8* pixel, const QDomElement& \
elt) const; +    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal \
*sat, qreal *luma) const; +    virtual void toYUV(QVector <double> channelValues, \
qreal *y, qreal *u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, \
qreal *u, qreal *v) const;  
 private:
     static const quint32 MAX_CHANNEL_L = 100;
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.cpp index \
                7e3e814..89c5d7c 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.cpp
@@ -22,7 +22,7 @@
 #include <QDomElement>
 
 #include <klocalizedstring.h>
-
+#include <KoColorConversions.h>
 #include "compositeops/KoCompositeOps.h"
 
 #include "compositeops/RgbCompositeOpIn.h"
@@ -80,3 +80,31 @@ void RgbF16ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) const  p->alpha = 1.0;
 }
 
+void RgbF16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbF16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2], lumaCoefficients()[0], \
lumaCoefficients()[1], lumaCoefficients()[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void RgbF16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+
+    
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbF16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +    \
channelValues[3]=1.0; +    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.h index \
                20a7028..0626ab8 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/rgb_f16/RgbF16ColorSpace.h
@@ -46,7 +46,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.cpp index \
                b84d797..91a900d 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.cpp
@@ -83,3 +83,31 @@ void RgbF32ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) const  p->alpha = 1.0;
 }
 
+void RgbF32ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2], lumaCoefficients()[0], \
lumaCoefficients()[1], lumaCoefficients()[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void RgbF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+
+    
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +    \
channelValues[3]=1.0; +    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.h index \
                c5e2c24..4a6c272 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/rgb_f32/RgbF32ColorSpace.h
@@ -46,7 +46,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.cpp index \
                fc82d34..05eeed5 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.cpp
@@ -76,3 +76,31 @@ void RgbU16ColorSpace::colorFromXML(quint8 *pixel, const \
QDomElement &elt) const  p->alpha = KoColorSpaceMathsTraits<quint16>::max;
 }
 
+void RgbU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2], lumaCoefficients()[0], \
lumaCoefficients()[1], lumaCoefficients()[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void RgbU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+
+    
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +    \
channelValues[3]=1.0; +    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.h index \
                4eb8c5b..fc18aae 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/rgb_u16/RgbU16ColorSpace.h
@@ -46,7 +46,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp index \
                3d2b606..54a0776 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.cpp
@@ -26,6 +26,7 @@
 
 #include <KoIntegerMaths.h>
 #include <KoColorSpaceRegistry.h>
+#include <KoColorConversions.h>
 #include "compositeops/KoCompositeOps.h"
 #include "compositeops/RgbCompositeOps.h"
 
@@ -113,3 +114,32 @@ quint8 RgbU8ColorSpace::intensity8(const quint8 *src) const
     const KoBgrU8Traits::Pixel *p = reinterpret_cast<const KoBgrU8Traits::Pixel \
*>(src);  return (quint8)(p->red * 0.30 + p->green * 0.59 + p->blue * 0.11);
 }
+
+void RgbU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    RGBToHSY(channelValues[0],channelValues[1],channelValues[2], hue, sat, luma, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const
+{
+    QVector <double> channelValues(4);
+    HSYToRGB(*hue, *sat, *luma, \
&channelValues[0],&channelValues[1],&channelValues[2], lumaCoefficients()[0], \
lumaCoefficients()[1], lumaCoefficients()[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void RgbU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+
+    
+    RGBToYUV(channelValues[0],channelValues[1],channelValues[2], y, u, v, \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +}
+
+QVector <double> RgbU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+
+    YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], \
lumaCoefficients()[0], lumaCoefficients()[1], lumaCoefficients()[2]); +    \
channelValues[3]=1.0; +    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h index \
                0d6d9d1..98d461c 100644
--- a/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/rgb_u8/RgbU8ColorSpace.h
@@ -54,7 +54,12 @@ public:
 
     virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
 
-    virtual quint8 intensity8(const quint8 *src) const;
+    virtual quint8 intensity8(const quint8 * src) const;
+    
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.cpp index \
                a463789..a1cfe9d 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 XyzF16ColorSpace::XyzF16ColorSpace(const QString &name, KoColorProfile *p) :
     LcmsColorSpace<KoXyzF16Traits>(colorSpaceId(), name, TYPE_XYZA_HALF_FLT, \
cmsSigXYZData, p) @@ -72,3 +73,32 @@ void XyzF16ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) const  p->alpha = 1.0;
 }
 
+void XyzF16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    qreal xyx, xyy, xyY = 0.0;
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], &xyx, &xyy, &xyY);
+    LabToLCH(xyY,xyx,xyY, hue, sat, luma);
+}
+
+QVector <double> XyzF16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    qreal xyx, xyy, xyY = 0.0;
+    LCHToLab(*luma, *sat, *hue, &xyY,&xyx,&xyy);
+    xyYToXYZ(xyx, xyy, xyY, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void XyzF16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], u, v, y);
+}
+
+QVector <double> XyzF16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    xyYToXYZ(*u, *v, *y, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.h index \
                c3db9ad..b935e78 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/xyz_f16/XyzF16ColorSpace.h
@@ -50,7 +50,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.cpp index \
                83bcbab..695317d 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 XyzF32ColorSpace::XyzF32ColorSpace(const QString &name, KoColorProfile *p) :
     LcmsColorSpace<KoXyzF32Traits>(colorSpaceId(), name, TYPE_XYZA_FLT, \
cmsSigXYZData, p) @@ -76,3 +77,32 @@ void XyzF32ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) const  p->alpha = 1.0;
 }
 
+void XyzF32ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    qreal xyx, xyy, xyY = 0.0;
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], &xyx, &xyy, &xyY);
+    LabToLCH(xyY,xyx,xyY, hue, sat, luma);
+}
+
+QVector <double> XyzF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    qreal xyx, xyy, xyY = 0.0;
+    LCHToLab(*luma, *sat, *hue, &xyY,&xyx,&xyy);
+    xyYToXYZ(xyx, xyy, xyY, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void XyzF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], u, v, y);
+}
+
+QVector <double> XyzF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    xyYToXYZ(*u, *v, *y, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.h index \
                9867c08..20f1007 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/xyz_f32/XyzF32ColorSpace.h
@@ -50,7 +50,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.cpp index \
                7f317fe..f2cde02 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 XyzU16ColorSpace::XyzU16ColorSpace(const QString &name, KoColorProfile *p) :
     LcmsColorSpace<KoXyzU16Traits>(colorSpaceId(), name, TYPE_XYZA_16, \
cmsSigXYZData, p) @@ -72,3 +73,32 @@ void XyzU16ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) const  p->alpha = \
KoColorSpaceMathsTraits<quint16>::max;  }
 
+void XyzU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    qreal xyx, xyy, xyY = 0.0;
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], &xyx, &xyy, &xyY);
+    LabToLCH(xyY,xyx,xyY, hue, sat, luma);
+}
+
+QVector <double> XyzU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    qreal xyx, xyy, xyY = 0.0;
+    LCHToLab(*luma, *sat, *hue, &xyY,&xyx,&xyy);
+    xyYToXYZ(xyx, xyy, xyY, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void XyzU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], u, v, y);
+}
+
+QVector <double> XyzU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    xyYToXYZ(*u, *v, *y, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.h index \
                f8ddc1b..7aa84c7 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/xyz_u16/XyzU16ColorSpace.h
@@ -48,7 +48,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
     static QString colorSpaceId()
     {
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.cpp index \
                de464fa..117684e 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 XyzU8ColorSpace::XyzU8ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoXyzU8Traits>(colorSpaceId(), name, TYPE_XYZA_8, \
cmsSigXYZData, p) @@ -68,3 +69,32 @@ void XyzU8ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) const  p->alpha = \
KoColorSpaceMathsTraits<quint8>::max;  }
 
+void XyzU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, \
qreal *luma) const +{
+    qreal xyx, xyy, xyY = 0.0;
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], &xyx, &xyy, &xyY);
+    LabToLCH(xyY,xyx,xyY, hue, sat, luma);
+}
+
+QVector <double> XyzU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const
+{
+    QVector <double> channelValues(4);
+    qreal xyx, xyy, xyY = 0.0;
+    LCHToLab(*luma, *sat, *hue, &xyY,&xyx,&xyy);
+    xyYToXYZ(xyx, xyy, xyY, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void XyzU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    XYZToxyY(channelValues[0],channelValues[1],channelValues[2], u, v, y);
+}
+
+QVector <double> XyzU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    xyYToXYZ(*u, *v, *y, &channelValues[0],&channelValues[1],&channelValues[2]);
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.h index \
                1c38549..e93ba91 100644
--- a/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/xyz_u8/XyzU8ColorSpace.h
@@ -55,7 +55,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.cpp index \
                a46d0a3..7674fe7 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 YCbCrF32ColorSpace::YCbCrF32ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoYCbCrF32Traits>(colorSpaceId(), name, TYPE_YCbCrA_FLT, \
cmsSigXYZData, p) @@ -78,3 +79,32 @@ void YCbCrF32ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) con  p->alpha = 1.0;
 }
 
+void YCbCrF32ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> YCbCrF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+
+void YCbCrF32ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> YCbCrF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h index \
                39a97b3..b88b669 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_f32/YCbCrF32ColorSpace.h
@@ -60,7 +60,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.cpp index \
                879582b..2c07b12 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 YCbCrU16ColorSpace::YCbCrU16ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoYCbCrU16Traits>(colorSpaceId(), name, TYPE_YCbCrA_16, \
cmsSigXYZData, p) @@ -72,3 +73,31 @@ void YCbCrU16ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) con  p->alpha = \
KoColorSpaceMathsTraits<quint16>::max;  }
 
+void YCbCrU16ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> YCbCrU16ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+void YCbCrU16ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> YCbCrU16ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h index \
                991af18..d29cb55 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_u16/YCbCrU16ColorSpace.h
@@ -55,7 +55,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.cpp \
b/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.cpp index \
                959747a..5703f6f 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.cpp
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.cpp
@@ -24,6 +24,7 @@
 #include <klocalizedstring.h>
 
 #include "compositeops/KoCompositeOps.h"
+#include "KoColorConversions.h"
 
 YCbCrU8ColorSpace::YCbCrU8ColorSpace(const QString &name, KoColorProfile *p)
     : LcmsColorSpace<KoYCbCrU8Traits>(colorSpaceId(), name, TYPE_YCbCrA_8, \
cmsSigXYZData, p) @@ -68,3 +69,31 @@ void YCbCrU8ColorSpace::colorFromXML(quint8 \
*pixel, const QDomElement &elt) cons  p->alpha = \
KoColorSpaceMathsTraits<quint8>::max;  }
 
+void YCbCrU8ColorSpace::toHSY(QVector <double> channelValues, qreal *hue, qreal \
*sat, qreal *luma) const +{
+    LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
+}
+
+QVector <double> YCbCrU8ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) \
const +{
+    QVector <double> channelValues(4);
+    LCHToLab(*luma, *sat, *hue, \
&channelValues[0],&channelValues[1],&channelValues[2]); +    channelValues[3]=1.0;
+    return channelValues;
+}
+void YCbCrU8ColorSpace::toYUV(QVector <double> channelValues, qreal *y, qreal *u, \
qreal *v) const +{
+    *y =channelValues[0];
+    *u=channelValues[1];
+    *v=channelValues[2];
+}
+
+QVector <double> YCbCrU8ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
+{
+    QVector <double> channelValues(4);
+    channelValues[0]=*y;
+    channelValues[1]=*u;
+    channelValues[2]=*v;
+    channelValues[3]=1.0;
+    return channelValues;
+}
\ No newline at end of file
diff --git a/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h \
b/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h index \
                016a77e..c78f26a 100644
--- a/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h
+++ b/plugins/color/lcms2engine/colorspaces/ycbcr_u8/YCbCrU8ColorSpace.h
@@ -55,7 +55,11 @@ public:
 
     virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement \
&colorElt) const;  
-    virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const;
+    virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const;
+    virtual void toHSY(QVector <double> channelValues, qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal \
*luma) const; +    virtual void toYUV(QVector <double> channelValues, qreal *y, qreal \
*u, qreal *v) const; +    virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal \
*v) const;  
 };
 
diff --git a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp \
b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp index cfc9d47..fcac273 \
                100644
--- a/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp
+++ b/plugins/filters/colorsfilters/kis_hsv_adjustment_filter.cpp
@@ -23,6 +23,7 @@
 #include <kis_selection.h>
 #include <kis_paint_device.h>
 #include <kis_processing_information.h>
+#include <KoColorProfile.h>
 
 KisHSVAdjustmentFilter::KisHSVAdjustmentFilter()
         : KisColorTransformationFilter(id(), categoryAdjust(), i18n("&HSV \
Adjustment...")) @@ -53,6 +54,9 @@ KoColorTransformation* \
KisHSVAdjustmentFilter::createTransformation(const KoColo  
         params["type"] = config->getInt("type", 1);
         params["colorize"] = config->getBool("colorize", false);
+        params["lumaRed"]   = cs->lumaCoefficients()[0];
+        params["lumaGreen"] = cs->lumaCoefficients()[1];
+        params["lumaBlue"]  = cs->lumaCoefficients()[2];
     }
     return cs->createColorTransformation("hsv_adjustment", params);
 }
@@ -118,14 +122,33 @@ void KisHSVConfigWidget::setConfiguration(const \
KisPropertiesConfiguration * con  void KisHSVConfigWidget::switchType(int index)
 {
     emit sigConfigurationItemChanged();
+    m_page->label->setText(i18n("Hue:"));
+    m_page->label_2->setText(i18n("Saturation:"));
+    m_page->hue->setMinimum(-180);
+    m_page->hue->setMaximum(180);
     switch(index) {
     case 0:
         m_page->label_3->setText(i18n("Value:"));
         return;
     case 1:
+        m_page->label_3->setText(i18n("Lightness:"));
+        return;
+    case 2:
+        m_page->label_3->setText(i18n("Intensity:"));
+        return;
+    case 3:
+        m_page->label_3->setText(i18n("Luma:"));
+        return;
+    case 4:
+        m_page->label->setText(i18n("Yellow-Blue:"));
+        m_page->label_2->setText(i18n("Green-Red:"));
+        m_page->label_3->setText(i18n("Luma:"));
+        m_page->hue->setRange(-100, 100, 0);
+        m_page->hue->setValue(0);
     default:
         m_page->label_3->setText(i18n("Lightness:"));
     }
+    
 
 }
 
diff --git a/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui \
b/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui index 8e044a1..756587d 100644
--- a/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui
+++ b/plugins/filters/colorsfilters/wdg_hsv_adjustment.ui
@@ -152,7 +152,7 @@
    <item row="0" column="1">
     <widget class="QComboBox" name="cmbType">
      <property name="currentIndex">
-      <number>1</number>
+      <number>0</number>
      </property>
      <item>
       <property name="text">
@@ -164,6 +164,21 @@
        <string>Hue/Saturation/Lightness</string>
       </property>
      </item>
+     <item>
+      <property name="text">
+       <string>Hue/Saturation/Intensity</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Hue/Saturation/Luma</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Blue Chroma/Red Chroma/Luma</string>
+      </property>
+     </item>
     </widget>
    </item>
    <item row="3" column="1">
diff --git a/plugins/paintops/colorsmudge/kis_colorsmudgeop.cpp \
b/plugins/paintops/colorsmudge/kis_colorsmudgeop.cpp index 81bd3d6..01d00cb 100644
--- a/plugins/paintops/colorsmudge/kis_colorsmudgeop.cpp
+++ b/plugins/paintops/colorsmudge/kis_colorsmudgeop.cpp
@@ -24,6 +24,7 @@
 
 #include <KoColorSpaceRegistry.h>
 #include <KoColor.h>
+#include <KoColorProfile.h>
 #include <KoCompositeOpRegistry.h>
 
 #include <kis_brush.h>
@@ -83,16 +84,6 @@ KisColorSmudgeOp::KisColorSmudgeOp(const \
KisBrushBasedPaintOpSettings* settings,  \
m_colorRatePainter->setCompositeOp(painter->compositeOp()->id());  
     m_rotationOption.applyFanCornersInfo(this);
-
-    /**
-     * Disable handling of the subpixel precision. In the smudge op we
-     * should read from the aligned areas of the image, so having
-     * additional internal offsets, created by the subpixel precision,
-     * will worsen the quality (at least because
-     * QRectF(m_dstDabRect).center() will not point to the real center
-     * of the brush anymore).
-     */
-    m_dabCache->disableSubpixelPrecision();
 }
 
 KisColorSmudgeOp::~KisColorSmudgeOp()
@@ -138,6 +129,29 @@ KisSpacingInformation KisColorSmudgeOp::paintAt(const \
KisPaintInformation& info)  return KisSpacingInformation(1.0);
     }
 
+    if (m_smudgeRateOption.getMode() == KisSmudgeOption::SMEARING_MODE) {
+        /**
+        * Disable handling of the subpixel precision. In the smudge op we
+        * should read from the aligned areas of the image, so having
+        * additional internal offsets, created by the subpixel precision,
+        * will worsen the quality (at least because
+        * QRectF(m_dstDabRect).center() will not point to the real center
+        * of the brush anymore).
+        * Of course, this only really matters with smearing_mode (bug:327235),
+        * and you only notice the lack of subpixel precision in the dulling methods.
+        */
+        m_dabCache->disableSubpixelPrecision();
+    }
+    
+    //if precision
+    KoColor colorSpaceChanger = painter()->paintColor();
+    const KoColorSpace* preciseColorSpace = colorSpaceChanger.colorSpace();
+    /*if (colorSpaceChanger.colorSpace()->colorDepthId().id() == "U8") {
+	preciseColorSpace = \
KoColorSpaceRegistry::instance()->colorSpace(colorSpaceChanger.colorSpace()->colorModelId().id(), \
"U16", colorSpaceChanger.profile() ); +        \
colorSpaceChanger.convertTo(preciseColorSpace); +    }
+    painter()->setPaintColor(colorSpaceChanger);*/
+
     // get the scaling factor calculated by the size option
     qreal scale    = m_sizeOption.apply(info);
     scale *= KisLodTransform::lodToScale(painter()->device());
@@ -205,7 +219,7 @@ KisSpacingInformation KisColorSmudgeOp::paintAt(const \
KisPaintInformation& info)  
     if (m_smudgeRateOption.getMode() == KisSmudgeOption::SMEARING_MODE) {
         m_smudgePainter->bitBlt(QPoint(), painter()->device(), srcDabRect);
-    } else {
+    } else if (m_smudgeRateOption.getMode() == KisSmudgeOption::DULLING_MODE) {
         QPoint pt = (srcDabRect.topLeft() + hotSpot).toPoint();
 
         if (m_smudgeRadiusOption.isChecked()) {
@@ -230,7 +244,7 @@ KisSpacingInformation KisColorSmudgeOp::paintAt(const \
KisPaintInformation& info)  
     // if the user selected the color smudge option,
     // we will mix some color into the temporary painting device (m_tempDev)
-    if (m_colorRateOption.isChecked()) {
+    if (m_colorRateOption.isChecked() && m_smudgeRateOption.getMode()) {
         // this will apply the opacity (selected by the user) to copyPainter
         // (but fit the rate inbetween the range 0.0 to (1.0-SmudgeRate))
         qreal maxColorRate = qMax<qreal>(1.0 - m_smudgeRateOption.getRate(), 0.2);
@@ -263,6 +277,7 @@ KisSpacingInformation KisColorSmudgeOp::paintAt(const \
KisPaintInformation& info)  
     // then blit the temporary painting device on the canvas at the current brush \
                position
     // the alpha mask (maskDab) will be used here to only blit the pixels that are \
in the area (shape) of the brush +    
     painter()->setCompositeOp(COMPOSITE_COPY);
     painter()->bitBltWithFixedSelection(m_dstDabRect.x(), m_dstDabRect.y(), \
                m_tempDev, m_maskDab, m_dstDabRect.width(), m_dstDabRect.height());
     painter()->renderMirrorMaskSafe(m_dstDabRect, m_tempDev, 0, 0, m_maskDab, \
                !m_dabCache->needSeparateOriginal());
diff --git a/plugins/paintops/colorsmudge/kis_smudge_option_widget.cpp \
b/plugins/paintops/colorsmudge/kis_smudge_option_widget.cpp index bb380f4..3458f1f \
                100644
--- a/plugins/paintops/colorsmudge/kis_smudge_option_widget.cpp
+++ b/plugins/paintops/colorsmudge/kis_smudge_option_widget.cpp
@@ -37,7 +37,7 @@ KisSmudgeOptionWidget::KisSmudgeOptionWidget()
     mCbSmudgeMode = new QComboBox();
     mCbSmudgeMode->addItem(i18n("Smearing"), KisSmudgeOption::SMEARING_MODE);
     mCbSmudgeMode->addItem("dulling-placeholder" , KisSmudgeOption::DULLING_MODE);
-
+    
     // the text for the second item is initialized here
     updateBrushPierced(false);
 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic