16#include <klocalizedstring.h>
28 i18n(
"L*a*b* (16-bit integer/channel, unmanaged)"),
38 addStandardCompositeOps<KoLabU16Traits>(
this);
39 addStandardDitherOps<KoLabU16Traits>(
this);
49 return QStringLiteral(
"LABA");
65 c.getRgb(&
R, &
G, &
B, &
A);
67 double X, Y, Z, fX, fY, fZ;
69 X = 0.412453 *
R + 0.357580 *
G + 0.180423 *
B;
70 Y = 0.212671 *
R + 0.715160 *
G + 0.072169 *
B;
71 Z = 0.019334 *
R + 0.119193 *
G + 0.950227 *
B;
73 X /= (255 * 0.950456);
75 Z /= (255 * 1.088754);
80 fY = pow(Y, 1.0 / 3.0);
81 L =
static_cast<int>(116.0 * fY - 16.0 + 0.5);
83 fY = 7.787 * Y + 16.0 / 116.0;
84 L =
static_cast<int>(903.3 * Y + 0.5);
88 fX = pow(X, 1.0 / 3.0);
90 fX = 7.787 * X + 16.0 / 116.0;
93 fZ = pow(Z, 1.0 / 3.0);
95 fZ = 7.787 * Z + 16.0 / 116.0;
97 a =
static_cast<int>(500.0 * (fX - fY) + 0.5);
98 b =
static_cast<int>(200.0 * (fY - fZ) + 0.5);
117 double X, Y, Z, fX, fY, fZ;
120 fY = pow((L + 16.0) / 116.0, 3.0);
126 fY = pow(fY, 1.0 / 3.0);
128 fY = 7.787 * fY + 16.0 / 116.0;
134 X = (fX - 16.0 / 116.0) / 7.787;
140 Z = (fZ - 16.0 / 116.0) / 7.787;
146 RR =
static_cast<int>(3.240479 * X - 1.537150 * Y - 0.498535 * Z + 0.5);
147 GG =
static_cast<int>(-0.969256 * X + 1.875992 * Y + 0.041556 * Z + 0.5);
148 BB =
static_cast<int>(0.055648 * X - 0.204043 * Y + 1.057311 * Z + 0.5);
150 quint8
R = RR < 0 ? 0 : RR > 255 ? 255 : RR;
151 quint8
G = GG < 0 ? 0 : GG > 255 ? 255 : GG;
152 quint8
B = BB < 0 ? 0 : BB > 255 ? 255 : BB;
154 c->setRgba(qRgba(
R,
G,
B,
A));
159 LabToLCH(channelValues[0],channelValues[1],channelValues[2], luma, sat, hue);
164 QVector <double> channelValues(4);
165 LCHToLab(*luma, *sat, *hue, &channelValues[0],&channelValues[1],&channelValues[2]);
166 channelValues[3]=1.0;
167 return channelValues;
172 *y =channelValues[0];
179 QVector <double> channelValues(4);
183 channelValues[3]=1.0;
184 return channelValues;
189 typename ColorSpaceTraits::channels_type c = ColorSpaceTraits::nativeArray(srcPixel)[channelIndex];
191 switch (channelIndex) {
192 case ColorSpaceTraits::L_pos:
193 b = ((qreal)c) / ColorSpaceTraits::math_trait::unitValueL;
195 case ColorSpaceTraits::a_pos:
196 case ColorSpaceTraits::b_pos:
197 if (c <= ColorSpaceTraits::math_trait::halfValueAB) {
198 b = ((qreal)c - ColorSpaceTraits::math_trait::zeroValueAB) / (2.0 * (ColorSpaceTraits::math_trait::halfValueAB - ColorSpaceTraits::math_trait::zeroValueAB));
200 b = 0.5 + ((qreal)c - ColorSpaceTraits::math_trait::halfValueAB) / (2.0 * (ColorSpaceTraits::math_trait::unitValueAB - ColorSpaceTraits::math_trait::halfValueAB));
204 b = ((qreal)c) / ColorSpaceTraits::math_trait::unitValue;
213 for (
uint pixelIndex = 0; pixelIndex < nPixels; ++pixelIndex) {
214 for (
uint channelIndex = 0; channelIndex < ColorSpaceTraits::channels_nb; ++channelIndex) {
215 if (channelIndex != ColorSpaceTraits::alpha_pos) {
216 if (channelIndex == ColorSpaceTraits::L_pos) {
217 ColorSpaceTraits::channels_type c = ColorSpaceTraits::nativeArray((src + (pixelIndex * ColorSpaceTraits::pixelSize)))[selectedChannelIndex];
218 switch (selectedChannelIndex) {
219 case ColorSpaceTraits::L_pos:
221 case ColorSpaceTraits::a_pos:
222 case ColorSpaceTraits::b_pos:
223 if (c <= ColorSpaceTraits::math_trait::halfValueAB) {
224 c = ColorSpaceTraits::math_trait::unitValueL * (((qreal)c - ColorSpaceTraits::math_trait::zeroValueAB) / (2.0 * (ColorSpaceTraits::math_trait::halfValueAB - ColorSpaceTraits::math_trait::zeroValueAB)));
226 c = ColorSpaceTraits::math_trait::unitValueL * (0.5 + ((qreal)c - ColorSpaceTraits::math_trait::halfValueAB) / (2.0 * (ColorSpaceTraits::math_trait::unitValueAB - ColorSpaceTraits::math_trait::halfValueAB)));
231 c = ColorSpaceTraits::math_trait::unitValueL * (qreal)c / ColorSpaceTraits::math_trait::unitValue;
234 ColorSpaceTraits::nativeArray(dst + (pixelIndex * ColorSpaceTraits::pixelSize))[channelIndex] = c;
236 ColorSpaceTraits::nativeArray(dst + (pixelIndex * ColorSpaceTraits::pixelSize))[channelIndex] = ColorSpaceTraits::math_trait::halfValueAB;
239 ColorSpaceTraits::nativeArray((dst + (pixelIndex * ColorSpaceTraits::pixelSize)))[channelIndex] =
240 ColorSpaceTraits::nativeArray((src + (pixelIndex * ColorSpaceTraits::pixelSize)))[channelIndex];
248 for (
uint pixelIndex = 0; pixelIndex < nPixels; ++pixelIndex) {
249 for (
uint channelIndex = 0; channelIndex < ColorSpaceTraits::channels_nb; ++channelIndex) {
251 if (selectedChannels.testBit(channelIndex)) {
252 ColorSpaceTraits::nativeArray((dst + (pixelIndex * ColorSpaceTraits::pixelSize)))[channelIndex] =
253 ColorSpaceTraits::nativeArray((src + (pixelIndex * ColorSpaceTraits::pixelSize)))[channelIndex];
255 ColorSpaceTraits::channels_type
v;
256 switch (channelIndex) {
257 case ColorSpaceTraits::L_pos:
258 v = ColorSpaceTraits::math_trait::halfValueL;
260 case ColorSpaceTraits::a_pos:
261 case ColorSpaceTraits::b_pos:
262 v = ColorSpaceTraits::math_trait::halfValueAB;
265 v = ColorSpaceTraits::math_trait::zeroValue;
268 ColorSpaceTraits::nativeArray((dst + (pixelIndex * ColorSpaceTraits::pixelSize)))[channelIndex] =
v;
Eigen::Matrix< double, 4, 2 > R
void LabToLCH(const qreal l, const qreal a, const qreal b, qreal *L, qreal *C, qreal *H)
void LCHToLab(const qreal L, const qreal C, const qreal H, qreal *l, qreal *a, qreal *b)
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
uint UINT8_TO_UINT16(uint c)
uint UINT16_TO_UINT8(uint c)
@ ALPHA
The channel represents the opacity of a pixel.
@ COLOR
The channel represents a color.
@ UINT16
use this for an integer 16bits channel
static _Tdst scaleToA(_T a)
virtual void addChannel(KoChannelInfo *ci)
void toQColor(const quint8 *src, QColor *c) const override
void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const qint32 selectedChannelIndex) const override
static const quint32 CHANNEL_ALPHA
QVector< double > fromHSY(qreal *hue, qreal *sat, qreal *luma) const override
QVector< double > fromYUV(qreal *y, qreal *u, qreal *v) const override
static const quint32 CHANNEL_A
~KoLabColorSpace() override
static const quint32 CHANNEL_L
static const quint32 CHANNEL_B
virtual KoColorSpace * clone() const
void toYUV(const QVector< double > &channelValues, qreal *y, qreal *u, qreal *v) const override
static QString colorSpaceId()
void fromQColor(const QColor &color, quint8 *dst) const override
void toHSY(const QVector< double > &channelValues, qreal *hue, qreal *sat, qreal *luma) const override
quint8 scaleToU8(const quint8 *srcPixel, qint32 channelIndex) const override