Krita Source Code Documentation
Loading...
Searching...
No Matches
CmykF32ColorSpace.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006 Cyrille Berger <cberger@cberger.net>
3 * SPDX-FileCopyrightText: 2020-2021 L. E. Segovia <amy@amyspark.me>
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8#include "CmykF32ColorSpace.h"
9
10#include <QDomElement>
11#include <QDebug>
12#include <klocalizedstring.h>
13
16#include <KoColorConversions.h>
17#include <kis_dom_utils.h>
18
20 : LcmsColorSpace<KoCmykF32Traits>(colorSpaceId(), name, TYPE_CMYKA_FLT, cmsSigCmykData, p)
21{
22 const IccColorProfile *icc_p = dynamic_cast<const IccColorProfile *>(p);
23 Q_ASSERT(icc_p);
25 Q_ASSERT(uiRanges.size() == 4);
26
27 addChannel(new KoChannelInfo(i18n("Cyan"), 0 * sizeof(float), 0, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::cyan, uiRanges[0]));
28 addChannel(new KoChannelInfo(i18n("Magenta"), 1 * sizeof(float), 1, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::magenta, uiRanges[1]));
29 addChannel(new KoChannelInfo(i18n("Yellow"), 2 * sizeof(float), 2, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::yellow, uiRanges[2]));
30 addChannel(new KoChannelInfo(i18n("Black"), 3 * sizeof(float), 3, KoChannelInfo::COLOR, KoChannelInfo::FLOAT32, sizeof(float), Qt::black, uiRanges[3]));
31 addChannel(new KoChannelInfo(i18n("Alpha"), 4 * sizeof(float), 4, KoChannelInfo::ALPHA, KoChannelInfo::FLOAT32, sizeof(float)));
32
33 init();
34
35 dbgPlugins << "CMYK (float) profile bounds for: " << icc_p->name();
36 dbgPlugins << "C: " << uiRanges[0].minVal << uiRanges[0].maxVal;
37 dbgPlugins << "M: " << uiRanges[1].minVal << uiRanges[1].maxVal;
38 dbgPlugins << "Y: " << uiRanges[2].minVal << uiRanges[2].maxVal;
39 dbgPlugins << "K: " << uiRanges[3].minVal << uiRanges[3].maxVal;
40
41 addStandardCompositeOps<KoCmykF32Traits>(this);
42 addStandardDitherOps<KoCmykF32Traits>(this);
43}
44
46{
47 if (independence == TO_RGBA16) {
48 return true;
49 } else {
50 return false;
51 }
52}
53
58
59void CmykF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement &colorElt) const
60{
61 const KoCmykF32Traits::Pixel *p = reinterpret_cast<const KoCmykF32Traits::Pixel *>(pixel);
62 QDomElement labElt = doc.createElement("CMYK");
63
65
66 // XML expects 0-1, we need 0-100
67 // Get the bounds from the channels and adjust the calculations
68 labElt.setAttribute("c", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA((1.f / channels[0]->getUIUnitValue()) * (p->cyan - channels[0]->getUIMin()))));
69 labElt.setAttribute("m", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA((1.f / channels[1]->getUIUnitValue()) * (p->magenta - channels[1]->getUIMin()))));
70 labElt.setAttribute("y", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA((1.f / channels[2]->getUIUnitValue()) * (p->yellow - channels[2]->getUIMin()))));
71 labElt.setAttribute("k", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA((1.f / channels[3]->getUIUnitValue()) * (p->black - channels[3]->getUIMin()))));
72 labElt.setAttribute("space", profile()->name());
73 colorElt.appendChild(labElt);
74}
75
76void CmykF32ColorSpace::colorFromXML(quint8 *pixel, const QDomElement &elt) const
77{
78 KoCmykF32Traits::Pixel *p = reinterpret_cast<KoCmykF32Traits::Pixel *>(pixel);
80
81 p->cyan = channels[0]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("c"))) * channels[0]->getUIUnitValue();
82 p->magenta = channels[1]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("m"))) * channels[1]->getUIUnitValue();
83 p->yellow = channels[2]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("y"))) * channels[2]->getUIUnitValue();
84 p->black = channels[3]->getUIMin() + KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("k"))) * channels[3]->getUIUnitValue();
85 p->alpha = 1.0;
86}
87
88void CmykF32ColorSpace::toHSY(const QVector<double> &channelValues, qreal *hue, qreal *sat, qreal *luma) const
89{
90 qreal c0 = channelValues[0];
91 qreal c1 = channelValues[1];
92 qreal c2 = channelValues[2];
93 qreal c3 = channelValues[3];
94 //we use HSI here because we can't linearise CMYK, and HSY doesn't work right with...
95 CMYKToCMY(&c0, &c1, &c2, &c3);
96 c0 = 1.0 - c0;
97 c1 = 1.0 - c1;
98 c2 = 1.0 - c2;
99 RGBToHSI(c0, c1, c2, hue, sat, luma);
100}
101
102QVector <double> CmykF32ColorSpace::fromHSY(qreal *hue, qreal *sat, qreal *luma) const
103{
104 QVector <double> channelValues(5);
105 channelValues.fill(1.0);
106 HSIToRGB(*hue, *sat, *luma, &channelValues[0],&channelValues[1],&channelValues[2]);
107 channelValues[0] = qBound(0.0,1.0-channelValues[0],1.0);
108 channelValues[1] = qBound(0.0,1.0-channelValues[1],1.0);
109 channelValues[2] = qBound(0.0,1.0-channelValues[2],1.0);
110 CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
111 return channelValues;
112}
113
114void CmykF32ColorSpace::toYUV(const QVector<double> &channelValues, qreal *y, qreal *u, qreal *v) const
115{
116 qreal c0 = channelValues[0];
117 qreal c1 = channelValues[1];
118 qreal c2 = channelValues[2];
119 qreal c3 = channelValues[3];
120 CMYKToCMY(&c0, &c1, &c2, &c3);
121 c0 = 1.0 - c0;
122 c1 = 1.0 - c1;
123 c2 = 1.0 - c2;
124 RGBToYUV(c0, c1, c2, y, u, v, (1.0 - 0.299),(1.0 - 0.587), (1.0 - 0.114));
125}
126
127QVector <double> CmykF32ColorSpace::fromYUV(qreal *y, qreal *u, qreal *v) const
128{
129 QVector <double> channelValues(5);
130 channelValues.fill(1.0);
131 YUVToRGB(*y, *u, *v, &channelValues[0],&channelValues[1],&channelValues[2], 0.33, 0.33, 0.33);
132 channelValues[0] = qBound(0.0,1.0-channelValues[0],1.0);
133 channelValues[1] = qBound(0.0,1.0-channelValues[1],1.0);
134 channelValues[2] = qBound(0.0,1.0-channelValues[2],1.0);
135 CMYToCMYK(&channelValues[0],&channelValues[1],&channelValues[2],&channelValues[3]);
136 return channelValues;
137}
#define TYPE_CMYKA_FLT
const Params2D p
qreal v
qreal u
void RGBToHSI(qreal r, qreal g, qreal b, qreal *h, qreal *s, qreal *i)
void RGBToYUV(const qreal r, const qreal g, const qreal b, qreal *y, qreal *u, qreal *v, qreal R, qreal G, qreal B)
void HSIToRGB(const qreal h, const qreal s, const qreal i, qreal *red, qreal *green, qreal *blue)
void YUVToRGB(const qreal y, const qreal u, const qreal v, qreal *r, qreal *g, qreal *b, qreal R, qreal G, qreal B)
void CMYToCMYK(qreal *c, qreal *m, qreal *y, qreal *k)
void CMYKToCMY(qreal *c, qreal *m, qreal *y, qreal *k)
ColorSpaceIndependence
@ TO_RGBA16
QVector< double > fromYUV(qreal *y, qreal *u, qreal *v) const override
CmykF32ColorSpace(const QString &name, KoColorProfile *p)
void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement &colorElt) const override
void toHSY(const QVector< double > &channelValues, qreal *hue, qreal *sat, qreal *luma) const override
virtual KoColorSpace * clone() const
void colorFromXML(quint8 *pixel, const QDomElement &elt) const override
QVector< double > fromHSY(qreal *hue, qreal *sat, qreal *luma) const override
void toYUV(const QVector< double > &channelValues, qreal *y, qreal *u, qreal *v) const override
bool willDegrade(ColorSpaceIndependence independence) const override
const QVector< KoChannelInfo::DoubleRange > & getFloatUIMinMax(void) const
@ ALPHA
The channel represents the opacity of a pixel.
@ COLOR
The channel represents a color.
@ FLOAT32
use this for a float 32bits channel
static _Tdst scaleToA(_T a)
QList< KoChannelInfo * > channels
virtual void addChannel(KoChannelInfo *ci)
const KoColorProfile * profile() const override
#define dbgPlugins
Definition kis_debug.h:51
double toDouble(const QString &str, bool *ok=nullptr)
QString toString(const QString &value)