diff --git a/libs/pigment/KoCmykColorSpaceMaths.h b/libs/pigment/KoCmykColorSpaceMaths.h index 46c3a89d5d..0e63940ac6 100644 --- a/libs/pigment/KoCmykColorSpaceMaths.h +++ b/libs/pigment/KoCmykColorSpaceMaths.h @@ -1,740 +1,115 @@ /* * Copyright (c) 2006,2007,2010 Cyrille Berger * Copyright (c) 2017,2020 L. E. Segovia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KOCMYKCOLORSPACEMATHS_H_ #define KOCMYKCOLORSPACEMATHS_H_ #include #include #include "kritapigment_export.h" #include #include "KoChannelInfo.h" #include "KoLut.h" #include #undef _T /** * This is an empty mainWindow that needs to be "specialized" for each possible * numerical type (quint8, quint16...). * * It needs to defines some static constant fields : * - zeroValue : the zero for this numerical type * - unitValue : the maximum value of the normal dynamic range * - max : the maximum value * - min : the minimum value * - epsilon : a value close to zero but different of zero * - bits : the bit depth * * And some types : * - compositetype the type used for composite operations (usually one with * a higher bit depth) * * This class is specialized to handle the floating point bounds of the CMYK color space. */ template class KoCmykColorSpaceMathsTraits { public: }; /** * No changes for integer color spaces. */ template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { }; template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { }; template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { }; template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { }; #include #ifdef HAVE_OPENEXR #include template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { public: static const half zeroValueCMYK; static const half unitValueCMYK; static const half halfValueCMYK; }; #endif template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { public: static const float zeroValueCMYK; static const float unitValueCMYK; static const float halfValueCMYK; }; template<> class KRITAPIGMENT_EXPORT KoCmykColorSpaceMathsTraits : public KoColorSpaceMathsTraits { public: static const double zeroValueCMYK; static const double unitValueCMYK; static const double halfValueCMYK; }; -//template -//struct KoIntegerToFloat { -// inline float operator()(_T_ f) const -// { -// return f / float(KoColorSpaceMathsTraits<_T_>::max); -// } -//}; - -//struct KoLuts { - -// static KRITAPIGMENT_EXPORT const Ko::FullLut< KoIntegerToFloat, float, quint16> Uint16ToFloat; -// static KRITAPIGMENT_EXPORT const Ko::FullLut< KoIntegerToFloat, float, quint8> Uint8ToFloat; -//}; - -///** -// * This class defines some elementary operations used by various color -// * space. It's intended to be generic, but some specialization exists -// * either for optimization or just for being buildable. -// * -// * @param _T some numerical type with an existing trait -// * @param _Tdst some other numerical type with an existing trait, it is -// * only needed if different of _T -// */ -//template < typename _T, typename _Tdst = _T > -//class KoColorSpaceMaths -//{ -// typedef KoColorSpaceMathsTraits<_T> traits; -// typedef typename traits::compositetype src_compositetype; -// typedef typename KoColorSpaceMathsTraits<_Tdst>::compositetype dst_compositetype; - -//public: -// inline static _Tdst multiply(_T a, _Tdst b) { -// return (dst_compositetype(a)*b) / KoColorSpaceMathsTraits<_Tdst>::unitValue; -// } - -// inline static _Tdst multiply(_T a, _Tdst b, _Tdst c) { -// return (dst_compositetype(a)*b*c) / (dst_compositetype(KoColorSpaceMathsTraits<_Tdst>::unitValue) * KoColorSpaceMathsTraits<_T>::unitValue); -// } - -// /** -// * Division : (a * MAX ) / b -// * @param a -// * @param b -// */ -// inline static dst_compositetype divide(_T a, _Tdst b) { -// return (dst_compositetype(a) * KoColorSpaceMathsTraits<_Tdst>::unitValue) / b; -// } - -// /** -// * Inversion : unitValue - a -// * @param a -// */ -// inline static _T invert(_T a) { -// return traits::unitValue - a; -// } - -// /** -// * Blending : (a * alpha) + b * (1 - alpha) -// * @param a -// * @param b -// * @param alpha -// */ -// inline static _T blend(_T a, _T b, _T alpha) { -// src_compositetype c = ((src_compositetype(a) - b) * alpha) / traits::unitValue; -// return c + b; -// } - -// /** -// * This function will scale a value of type _T to fit into a _Tdst. -// */ -// inline static _Tdst scaleToA(_T a) { -// return _Tdst(dst_compositetype(a) * KoColorSpaceMathsTraits<_Tdst>::unitValue / KoColorSpaceMathsTraits<_T>::unitValue); -// } - -// inline static dst_compositetype clamp(dst_compositetype val) { -// return qBound(KoColorSpaceMathsTraits<_Tdst>::min, val, KoColorSpaceMathsTraits<_Tdst>::max); -// } - -// /** -// * Clamps the composite type on higher border only. That is a fast path -// * for scale-only transformations -// */ -// inline static _Tdst clampAfterScale(dst_compositetype val) { -// return qMin(val, KoColorSpaceMathsTraits<_Tdst>::max); -// } -//}; - -////------------------------------ double specialization ------------------------------// -//template<> -//inline quint8 KoColorSpaceMaths::scaleToA(double a) -//{ -// double v = a * 255; -// return float2int(CLAMP(v, 0, 255)); -//} - -//template<> -//inline double KoColorSpaceMaths::scaleToA(quint8 a) -//{ -// return KoLuts::Uint8ToFloat(a); -//} - -//template<> -//inline quint16 KoColorSpaceMaths::scaleToA(double a) -//{ -// double v = a * 0xFFFF; -// return float2int(CLAMP(v, 0, 0xFFFF)); -//} - -//template<> -//inline double KoColorSpaceMaths::scaleToA(quint16 a) -//{ -// return KoLuts::Uint16ToFloat(a); -//} - -//template<> -//inline double KoColorSpaceMaths::clamp(double a) -//{ -// return a; -//} - -////------------------------------ float specialization ------------------------------// - -//template<> -//inline float KoColorSpaceMaths::scaleToA(double a) -//{ -// return (float)a; -//} - -//template<> -//inline double KoColorSpaceMaths::scaleToA(float a) -//{ -// return a; -//} - -//template<> -//inline quint16 KoColorSpaceMaths::scaleToA(float a) -//{ -// float v = a * 0xFFFF; -// return (quint16)float2int(CLAMP(v, 0, 0xFFFF)); -//} - -//template<> -//inline float KoColorSpaceMaths::scaleToA(quint16 a) -//{ -// return KoLuts::Uint16ToFloat(a); -//} - -//template<> -//inline quint8 KoColorSpaceMaths::scaleToA(float a) -//{ -// float v = a * 255; -// return (quint8)float2int(CLAMP(v, 0, 255)); -//} - -//template<> -//inline float KoColorSpaceMaths::scaleToA(quint8 a) -//{ -// return KoLuts::Uint8ToFloat(a); -//} - -//template<> -//inline float KoColorSpaceMaths::blend(float a, float b, float alpha) -//{ -// return (a - b) * alpha + b; -//} - -//template<> -//inline double KoColorSpaceMaths::clamp(double a) -//{ -// return a; -//} - -////------------------------------ half specialization ------------------------------// - -//#ifdef HAVE_OPENEXR - -//template<> -//inline half KoColorSpaceMaths::scaleToA(double a) -//{ -// return (half)a; -//} - -//template<> -//inline double KoColorSpaceMaths::scaleToA(half a) -//{ -// return a; -//} - -//template<> -//inline float KoColorSpaceMaths::scaleToA(half a) -//{ -// return a; -//} - -//template<> -//inline half KoColorSpaceMaths::scaleToA(float a) -//{ -// return (half) a; -//} - -//template<> -//inline quint8 KoColorSpaceMaths::scaleToA(half a) -//{ -// half v = a * 255; -// return (quint8)(CLAMP(v, 0, 255)); -//} - -//template<> -//inline half KoColorSpaceMaths::scaleToA(quint8 a) -//{ -// return a *(1.0 / 255.0); -//} -//template<> -//inline quint16 KoColorSpaceMaths::scaleToA(half a) -//{ -// double v = a * 0xFFFF; -// return (quint16)(CLAMP(v, 0, 0xFFFF)); -//} - -//template<> -//inline half KoColorSpaceMaths::scaleToA(quint16 a) -//{ -// return a *(1.0 / 0xFFFF); -//} - -//template<> -//inline half KoColorSpaceMaths::scaleToA(half a) -//{ -// return a; -//} - -//template<> -//inline half KoColorSpaceMaths::blend(half a, half b, half alpha) -//{ -// return (a - b) * alpha + b; -//} - -//template<> -//inline double KoColorSpaceMaths::clamp(double a) -//{ -// return a; -//} - - -//#endif - -////------------------------------ quint8 specialization ------------------------------// - -//template<> -//inline quint8 KoColorSpaceMaths::multiply(quint8 a, quint8 b) -//{ -// return (quint8)UINT8_MULT(a, b); -//} - - -//template<> -//inline quint8 KoColorSpaceMaths::multiply(quint8 a, quint8 b, quint8 c) -//{ -// return (quint8)UINT8_MULT3(a, b, c); -//} - -//template<> -//inline KoColorSpaceMathsTraits::compositetype -//KoColorSpaceMaths::divide(quint8 a, quint8 b) -//{ -// return UINT8_DIVIDE(a, b); -//} - -//template<> -//inline quint8 KoColorSpaceMaths::invert(quint8 a) -//{ -// return ~a; -//} - -//template<> -//inline quint8 KoColorSpaceMaths::blend(quint8 a, quint8 b, quint8 c) -//{ -// return UINT8_BLEND(a, b, c); -//} - -////------------------------------ quint16 specialization ------------------------------// - -//template<> -//inline quint16 KoColorSpaceMaths::multiply(quint16 a, quint16 b) -//{ -// return (quint16)UINT16_MULT(a, b); -//} - -//template<> -//inline KoColorSpaceMathsTraits::compositetype -//KoColorSpaceMaths::divide(quint16 a, quint16 b) -//{ -// return UINT16_DIVIDE(a, b); -//} - -//template<> -//inline quint16 KoColorSpaceMaths::invert(quint16 a) -//{ -// return ~a; -//} - -////------------------------------ various specialization ------------------------------// - - -//// TODO: use more functions from KoIntegersMaths to do the computation - -///// This specialization is needed because the default implementation won't work when scaling up -//template<> -//inline quint16 KoColorSpaceMaths::scaleToA(quint8 a) -//{ -// return UINT8_TO_UINT16(a); -//} - -//template<> -//inline quint8 KoColorSpaceMaths::scaleToA(quint16 a) -//{ -// return UINT16_TO_UINT8(a); -//} - - -//// Due to once again a bug in gcc, there is the need for those specialized functions: - -//template<> -//inline quint8 KoColorSpaceMaths::scaleToA(quint8 a) -//{ -// return a; -//} - -//template<> -//inline quint16 KoColorSpaceMaths::scaleToA(quint16 a) -//{ -// return a; -//} - -//template<> -//inline float KoColorSpaceMaths::scaleToA(float a) -//{ -// return a; -//} - -//namespace Arithmetic -//{ -// const static qreal pi = 3.14159265358979323846; - -// template -// inline T mul(T a, T b) { return KoColorSpaceMaths::multiply(a, b); } - -// template -// inline T mul(T a, T b, T c) { return KoColorSpaceMaths::multiply(a, b, c); } - -//// template -//// inline T mul(T a, T b) { -//// typedef typename KoColorSpaceMathsTraits::compositetype composite_type; -//// return T(composite_type(a) * b / KoColorSpaceMathsTraits::unitValue); -//// } -//// -//// template -//// inline T mul(T a, T b, T c) { -//// typedef typename KoColorSpaceMathsTraits::compositetype composite_type; -//// return T((composite_type(a) * b * c) / (composite_type(KoColorSpaceMathsTraits::unitValue) * KoColorSpaceMathsTraits::unitValue)); -//// } - -// template -// inline T inv(T a) { return KoColorSpaceMaths::invert(a); } - -// template -// inline T lerp(T a, T b, T alpha) { return KoColorSpaceMaths::blend(b, a, alpha); } - -// template -// inline TRet scale(T a) { return KoColorSpaceMaths::scaleToA(a); } - -// template -// inline typename KoColorSpaceMathsTraits::compositetype -// div(T a, T b) { return KoColorSpaceMaths::divide(a, b); } - -// template -// inline T clamp(typename KoColorSpaceMathsTraits::compositetype a) { -// return KoColorSpaceMaths::clamp(a); -// } - -// template -// inline T min(T a, T b, T c) { -// b = (a < b) ? a : b; -// return (b < c) ? b : c; -// } - -// template -// inline T max(T a, T b, T c) { -// b = (a > b) ? a : b; -// return (b > c) ? b : c; -// } - -// template -// inline T zeroValue() { return KoColorSpaceMathsTraits::zeroValue; } - -// template -// inline T halfValue() { return KoColorSpaceMathsTraits::halfValue; } - -// template -// inline T unitValue() { return KoColorSpaceMathsTraits::unitValue; } - -// template -// inline T unionShapeOpacity(T a, T b) { -// typedef typename KoColorSpaceMathsTraits::compositetype composite_type; -// return T(composite_type(a) + b - mul(a,b)); -// } - -// template -// inline T blend(T src, T srcAlpha, T dst, T dstAlpha, T cfValue) { -// return mul(inv(srcAlpha), dstAlpha, dst) + mul(inv(dstAlpha), srcAlpha, src) + mul(dstAlpha, srcAlpha, cfValue); -// } -//} - -//struct HSYType -//{ -// template -// inline static TReal getLightness(TReal r, TReal g, TReal b) { -// return TReal(0.299)*r + TReal(0.587)*g + TReal(0.114)*b; -// } - -// template -// inline static TReal getSaturation(TReal r, TReal g, TReal b) { -// return Arithmetic::max(r,g,b) - Arithmetic::min(r,g,b); -// } -//}; - -//struct HSIType -//{ -// template -// inline static TReal getLightness(TReal r, TReal g, TReal b) { -// return (r + g + b) * TReal(0.33333333333333333333); // (r + g + b) / 3.0 -// } - -// template -// inline static TReal getSaturation(TReal r, TReal g, TReal b) { -// TReal max = Arithmetic::max(r, g, b); -// TReal min = Arithmetic::min(r, g, b); -// TReal chroma = max - min; - -// return (chroma > std::numeric_limits::epsilon()) ? -// (TReal(1.0) - min / getLightness(r, g, b)) : TReal(0.0); -// } -//}; - -//struct HSLType -//{ -// template -// inline static TReal getLightness(TReal r, TReal g, TReal b) { -// TReal max = Arithmetic::max(r, g, b); -// TReal min = Arithmetic::min(r, g, b); -// return (max + min) * TReal(0.5); -// } - -// template -// inline static TReal getSaturation(TReal r, TReal g, TReal b) { -// TReal max = Arithmetic::max(r, g, b); -// TReal min = Arithmetic::min(r, g, b); -// TReal chroma = max - min; -// TReal light = (max + min) * TReal(0.5); -// TReal div = TReal(1.0) - std::abs(TReal(2.0)*light - TReal(1.0)); - -// if(div > std::numeric_limits::epsilon()) -// return chroma / div; - -// return TReal(1.0); -// } -//}; - -//struct HSVType -//{ -// template -// inline static TReal getLightness(TReal r, TReal g, TReal b) { -// return Arithmetic::max(r,g,b); -// } - -// template -// inline static TReal getSaturation(TReal r, TReal g, TReal b) { -// TReal max = Arithmetic::max(r, g, b); -// TReal min = Arithmetic::min(r, g, b); -// return (max == TReal(0.0)) ? TReal(0.0) : (max - min) / max; -// } -//}; - -//template -//TReal getHue(TReal r, TReal g, TReal b) { -// TReal min = Arithmetic::min(r, g, b); -// TReal max = Arithmetic::max(r, g, b); -// TReal chroma = max - min; - -// TReal hue = TReal(-1.0); - -// if(chroma > std::numeric_limits::epsilon()) { - -//// return atan2(TReal(2.0)*r - g - b, TReal(1.73205080756887729353)*(g - b)); - -// if(max == r) // between yellow and magenta -// hue = (g - b) / chroma; -// else if(max == g) // between cyan and yellow -// hue = TReal(2.0) + (b - r) / chroma; -// else if(max == b) // between magenta and cyan -// hue = TReal(4.0) + (r - g) / chroma; - -// if(hue < -std::numeric_limits::epsilon()) -// hue += TReal(6.0); - -// hue /= TReal(6.0); -// } - -//// hue = (r == max) ? (b-g) : (g == max) ? TReal(2.0)+(r-b) : TReal(4.0)+(g-r); - -// return hue; -//} - -//template -//void getRGB(TReal& r, TReal& g, TReal& b, TReal hue) { -// // 0 red -> (1,0,0) -// // 1 yellow -> (1,1,0) -// // 2 green -> (0,1,0) -// // 3 cyan -> (0,1,1) -// // 4 blue -> (0,0,1) -// // 5 maenta -> (1,0,1) -// // 6 red -> (1,0,0) - -// if(hue < -std::numeric_limits::epsilon()) { -// r = g = b = TReal(0.0); -// return; -// } - -// int i = int(hue * TReal(6.0)); -// TReal x = hue * TReal(6.0) - i; -// TReal y = TReal(1.0) - x; - -// switch(i % 6){ -// case 0: { r=TReal(1.0), g=x , b=TReal(0.0); } break; -// case 1: { r=y , g=TReal(1.0), b=TReal(0.0); } break; -// case 2: { r=TReal(0.0), g=TReal(1.0), b=x ; } break; -// case 3: { r=TReal(0.0), g=y , b=TReal(1.0); } break; -// case 4: { r=x , g=TReal(0.0), b=TReal(1.0); } break; -// case 5: { r=TReal(1.0), g=TReal(0.0), b=y ; } break; -// } -//} - -//template -//inline static TReal getLightness(TReal r, TReal g, TReal b) { -// return HSXType::getLightness(r, g, b); -//} - -//template -//inline void addLightness(TReal& r, TReal& g, TReal& b, TReal light) -//{ -// using namespace Arithmetic; - -// r += light; -// g += light; -// b += light; - -// TReal l = HSXType::getLightness(r, g, b); -// TReal n = min(r, g, b); -// TReal x = max(r, g, b); - -// if(n < TReal(0.0)) { -// TReal iln = TReal(1.0) / (l-n); -// r = l + ((r-l) * l) * iln; -// g = l + ((g-l) * l) * iln; -// b = l + ((b-l) * l) * iln; -// } - -// if(x > TReal(1.0) && (x-l) > std::numeric_limits::epsilon()) { -// TReal il = TReal(1.0) - l; -// TReal ixl = TReal(1.0) / (x - l); -// r = l + ((r-l) * il) * ixl; -// g = l + ((g-l) * il) * ixl; -// b = l + ((b-l) * il) * ixl; -// } -//} - -//template -//inline void setLightness(TReal& r, TReal& g, TReal& b, TReal light) -//{ -// addLightness(r,g,b, light - HSXType::getLightness(r,g,b)); -//} - -//template -//inline static TReal getSaturation(TReal r, TReal g, TReal b) { -// return HSXType::getSaturation(r, g, b); -//} - -//template -//inline void setSaturation(TReal& r, TReal& g, TReal& b, TReal sat) -//{ -// int min = 0; -// int mid = 1; -// int max = 2; -// TReal rgb[3] = {r, g, b}; - -// if(rgb[mid] < rgb[min]) { -// int tmp = min; -// min = mid; -// mid = tmp; -// } - -// if(rgb[max] < rgb[mid]) { -// int tmp = mid; -// mid = max; -// max = tmp; -// } - -// if(rgb[mid] < rgb[min]) { -// int tmp = min; -// min = mid; -// mid = tmp; -// } - -// if((rgb[max] - rgb[min]) > TReal(0.0)) { -// rgb[mid] = ((rgb[mid]-rgb[min]) * sat) / (rgb[max]-rgb[min]); -// rgb[max] = sat; -// rgb[min] = TReal(0.0); - -// r = rgb[0]; -// g = rgb[1]; -// b = rgb[2]; -// } -// else r = g = b = TReal(0.0); -//} - #endif diff --git a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp index 6a55982afe..8f51bf9c02 100644 --- a/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp +++ b/plugins/color/lcms2engine/colorspaces/cmyk_f32/CmykF32ColorSpace.cpp @@ -1,144 +1,144 @@ /* * Copyright (c) 2006 Cyrille Berger * Copyright (c) 2020 L. E. Segovia * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "CmykF32ColorSpace.h" #include #include #include #include "compositeops/KoCompositeOps.h" #include #include CmykF32ColorSpace::CmykF32ColorSpace(const QString &name, KoColorProfile *p) : LcmsColorSpace(colorSpaceId(), name, TYPE_CMYKA_FLT, cmsSigCmykData, p) { const IccColorProfile *icc_p = dynamic_cast(p); Q_ASSERT(icc_p); QVector uiRanges(icc_p->getFloatUIMinMax()); Q_ASSERT(uiRanges.size() == 4); addChannel(new KoChannelInfo(i18n("Cyan"), 0 * sizeof(float), 0, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::cyan, uiRanges[0])); addChannel(new KoChannelInfo(i18n("Magenta"), 1 * sizeof(float), 1, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::magenta, uiRanges[1])); addChannel(new KoChannelInfo(i18n("Yellow"), 2 * sizeof(float), 2, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::yellow, uiRanges[2])); addChannel(new KoChannelInfo(i18n("Black"), 3 * sizeof(float), 3, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::black, uiRanges[3])); addChannel(new KoChannelInfo(i18n("Alpha"), 4 * sizeof(float), 4, KoChannelInfo::ALPHA, KoChannelInfo::FLOAT32, sizeof(float))); init(); dbgPlugins << "CMYK (float) profile bounds for: " << icc_p->name(); dbgPlugins << "C: " << uiRanges[0].minVal << uiRanges[0].maxVal; dbgPlugins << "M: " << uiRanges[1].minVal << uiRanges[1].maxVal; dbgPlugins << "Y: " << uiRanges[2].minVal << uiRanges[2].maxVal; dbgPlugins << "K: " << uiRanges[3].minVal << uiRanges[3].maxVal; addStandardCompositeOps(this); } bool CmykF32ColorSpace::willDegrade(ColorSpaceIndependence independence) const { if (independence == TO_RGBA16) { return true; } else { return false; } } KoColorSpace *CmykF32ColorSpace::clone() const { return new CmykF32ColorSpace(name(), profile()->clone()); } void CmykF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement &colorElt) const { const KoCmykF32Traits::Pixel *p = reinterpret_cast(pixel); QDomElement labElt = doc.createElement("CMYK"); // XML expects 0-1, we need 0-100 // Get the bounds from the channels and adjust the calculations labElt.setAttribute("c", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[0]->getUIUnitValue() * (p->cyan - this->channels()[0]->getUIMin())))); labElt.setAttribute("m", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[1]->getUIUnitValue() * (p->magenta - this->channels()[1]->getUIMin())))); labElt.setAttribute("y", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[2]->getUIUnitValue() * (p->yellow - this->channels()[2]->getUIMin())))); labElt.setAttribute("k", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[3]->getUIUnitValue() * (p->black - this->channels()[3]->getUIMin())))); labElt.setAttribute("space", profile()->name()); colorElt.appendChild(labElt); } void CmykF32ColorSpace::colorFromXML(quint8 *pixel, const QDomElement &elt) const { KoCmykF32Traits::Pixel *p = reinterpret_cast(pixel); p->cyan = this->channels()[0]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("c"))) * this->channels()[0]->getUIUnitValue(); p->magenta = this->channels()[1]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("m"))) * this->channels()[1]->getUIUnitValue(); p->yellow = this->channels()[2]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("y"))) * this->channels()[2]->getUIUnitValue(); - p->black = this->channels()[2]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("k"))) * this->channels()[2]->getUIUnitValue(); + p->black = this->channels()[3]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("k"))) * this->channels()[3]->getUIUnitValue(); p->alpha = 1.0; } void CmykF32ColorSpace::toHSY(const QVector &channelValues, qreal *hue, qreal *sat, qreal *luma) const { qreal c0 = channelValues[0]; qreal c1 = channelValues[1]; qreal c2 = channelValues[2]; qreal c3 = channelValues[3]; //we use HSI here because we can't linearise CMYK, and HSY doesn't work right with... CMYKToCMY(&c0, &c1, &c2, &c3); c0 = 1.0 - c0; c1 = 1.0 - c1; c2 = 1.0 - c2; RGBToHSI(c0, c1, c2, hue, sat, luma); } QVector CmykF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const { QVector 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(const QVector &channelValues, qreal *y, qreal *u, qreal *v) const { qreal c0 = channelValues[0]; qreal c1 = channelValues[1]; qreal c2 = channelValues[2]; qreal c3 = channelValues[3]; CMYKToCMY(&c0, &c1, &c2, &c3); c0 = 1.0 - c0; c1 = 1.0 - c1; c2 = 1.0 - c2; RGBToYUV(c0, c1, c2, y, u, v, (1.0 - 0.299),(1.0 - 0.587), (1.0 - 0.114)); } QVector CmykF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const { QVector 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; }