Commit 874243cb authored by Amyspark's avatar Amyspark
Browse files

Address Lab/CMYK space subtleties within KoColorSpaceMaths

Summary:
In T4488, two problems were identified with regards to Lab and CMYK when using KoColorSpaceMaths:
 - Palette loading was broken
 - Calculations themselves were broken: KoColorSpaceMaths assumes [0..1] in floating point whereas Lab has [0.100, -128..+127, -128..+127] and CMYK [0..100].

This patch closes T4488 by making LittleCMS-based profiles (CMYKF32ColorSpace, LabF32ColorSpace) request the profile's bounds prior to initializing the channel defaults, and adjusting the same in the Qt controls. I've also changed KoColorSpaceMaths to account for these bounds.

Maniphest Tasks: T4488

Differential Revision: https://phabricator.kde.org/D6589

Closes T4488
parent bbf8fe69
......@@ -52,6 +52,8 @@ set(kritapigment_SRCS
KoColorSpaceEngine.cpp
KoColorSpaceFactory.cpp
KoColorSpaceMaths.cpp
KoCmykColorSpaceMaths.cpp
KoLabColorSpaceMaths.cpp
KoColorSpaceRegistry.cpp
KoColorProfileStorage.cpp
KoColorTransformation.cpp
......
/*
* Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
* Copyright (c) 2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -261,6 +262,15 @@ public:
return m_uiMinMax.maxVal;
}
/**
* @brief getUIUnitValue
* Gets the unit value for this channel.
* This is suitable for converting between representations.
*/
inline double getUIUnitValue(void) const {
return m_uiMinMax.maxVal - m_uiMinMax.minVal;
}
private:
QString m_name;
......
/*
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2017,2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <KoCmykColorSpaceMaths.h>
#include <cfloat>
#include <QtGlobal>
#ifdef HAVE_OPENEXR
const half KoCmykColorSpaceMathsTraits<half>::zeroValueCMYK = 0.0;
const half KoCmykColorSpaceMathsTraits<half>::unitValueCMYK = 100.0;
const half KoCmykColorSpaceMathsTraits<half>::halfValueCMYK = 50.0;
#endif
const float KoCmykColorSpaceMathsTraits<float>::zeroValueCMYK = 0.0;
const float KoCmykColorSpaceMathsTraits<float>::unitValueCMYK = 100.0;
const float KoCmykColorSpaceMathsTraits<float>::halfValueCMYK = 50.0;
const double KoCmykColorSpaceMathsTraits<double>::zeroValueCMYK = 0.0;
const double KoCmykColorSpaceMathsTraits<double>::unitValueCMYK = 100.0;
const double KoCmykColorSpaceMathsTraits<double>::halfValueCMYK = 50.0;
This diff is collapsed.
/*
* Copyright (c) 2006-2007 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2016 L. E. Segovia <amy@amyspark.me>
* Copyright (c) 2016,2017,2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -21,12 +21,7 @@
#ifndef _KO_CMYK_COLORSPACE_TRAITS_H_
#define _KO_CMYK_COLORSPACE_TRAITS_H_
#include <QVector>
#include "KoColorSpaceConstants.h"
#include "KoColorSpaceMaths.h"
#include "DebugPigment.h"
#include <KoCmykColorSpaceMaths.h>
/**
* Base class for CMYK traits, it provides some convenient functions to
......@@ -105,18 +100,49 @@ struct KoCmykU16Traits : public KoCmykTraits<quint16> {
#include <half.h>
struct KoCmykF16Traits : public KoCmykTraits<half> {
static constexpr float MAX_CHANNEL_CMYK = 100;
inline static QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) {
return channelValueText(pixel, channelIndex);
if (channelIndex > parent::channels_nb) return QString("Error");
channels_type c = nativeArray(pixel)[channelIndex];
switch (channelIndex) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK));
case 4:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue));
default:
return QString("Error");
}
}
inline static void normalisedChannelsValue(const quint8 *pixel, QVector<float> &channels) {
Q_ASSERT((int)channels.count() == (int)parent::channels_nb);
channels_type c;
for (uint i = 0; i < parent::channels_nb; i++) {
c = parent::nativeArray(pixel)[i];
channels[i] = (qreal)c;
c = nativeArray(pixel)[i];
switch (i) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
// As per KoChannelInfo alpha channels are [0..1]
case 4:
default:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue);
break;
}
}
}
......@@ -131,13 +157,13 @@ struct KoCmykF16Traits : public KoCmykTraits<half> {
case y_pos:
case k_pos:
b = qBound((float)0,
(float)KoColorSpaceMathsTraits<float>::unitValue * values[i],
(float)MAX_CHANNEL_CMYK);
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
default:
b = qBound((float)KoColorSpaceMathsTraits<float>::min,
(float)KoColorSpaceMathsTraits<float>::unitValue * values[i],
(float)KoColorSpaceMathsTraits<float>::max);
b = qBound((float)KoCmykColorSpaceMathsTraits<channels_type>::min,
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValue * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::max);
break;
}
c = (channels_type)b;
......@@ -149,18 +175,49 @@ struct KoCmykF16Traits : public KoCmykTraits<half> {
#endif
struct KoCmykF32Traits : public KoCmykTraits<float> {
static constexpr float MAX_CHANNEL_CMYK = 100;
inline static QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) {
return channelValueText(pixel, channelIndex);
if (channelIndex > parent::channels_nb) return QString("Error");
channels_type c = nativeArray(pixel)[channelIndex];
switch (channelIndex) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK));
case 4:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue));
default:
return QString("Error");
}
}
inline static void normalisedChannelsValue(const quint8 *pixel, QVector<float> &channels) {
Q_ASSERT((int)channels.count() == (int)parent::channels_nb);
channels_type c;
for (uint i = 0; i < parent::channels_nb; i++) {
c = parent::nativeArray(pixel)[i];
channels[i] = (qreal)c;
c = nativeArray(pixel)[i];
switch (i) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
// As per KoChannelInfo alpha channels are [0..1]
case 4:
default:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue);
break;
}
}
}
......@@ -175,13 +232,13 @@ struct KoCmykF32Traits : public KoCmykTraits<float> {
case y_pos:
case k_pos:
b = qBound((float)0,
(float)KoColorSpaceMathsTraits<float>::unitValue * values[i],
(float)MAX_CHANNEL_CMYK);
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
default:
b = qBound((float)KoColorSpaceMathsTraits<float>::min,
(float)KoColorSpaceMathsTraits<float>::unitValue * values[i],
(float)KoColorSpaceMathsTraits<float>::max);
b = qBound((float)KoCmykColorSpaceMathsTraits<channels_type>::min,
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValue * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::max);
break;
}
c = (channels_type)b;
......@@ -191,18 +248,49 @@ struct KoCmykF32Traits : public KoCmykTraits<float> {
};
struct KoCmykF64Traits : public KoCmykTraits<double> {
static constexpr double MAX_CHANNEL_CMYK = 100;
inline static QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) {
return channelValueText(pixel, channelIndex);
if (channelIndex > parent::channels_nb) return QString("Error");
channels_type c = nativeArray(pixel)[channelIndex];
switch (channelIndex) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK));
case 4:
return QString().setNum(100.0 * qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue));
default:
return QString("Error");
}
}
inline static void normalisedChannelsValue(const quint8 *pixel, QVector<float> &channels) {
Q_ASSERT((int)channels.count() == (int)parent::channels_nb);
channels_type c;
for (uint i = 0; i < parent::channels_nb; i++) {
c = parent::nativeArray(pixel)[i];
channels[i] = (qreal)c;
c = nativeArray(pixel)[i];
switch (i) {
case c_pos:
case m_pos:
case y_pos:
case k_pos:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
// As per KoChannelInfo alpha channels are [0..1]
case 4:
default:
channels[i] = qBound((qreal)0,
((qreal)c) / KoCmykColorSpaceMathsTraits<channels_type>::unitValue,
(qreal)KoCmykColorSpaceMathsTraits<channels_type>::unitValue);
break;
}
}
}
......@@ -216,14 +304,14 @@ struct KoCmykF64Traits : public KoCmykTraits<double> {
case m_pos:
case y_pos:
case k_pos:
b = qBound((double)0,
(double)KoColorSpaceMathsTraits<double>::unitValue * values[i],
(double)MAX_CHANNEL_CMYK);
b = qBound((float)0,
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValueCMYK);
break;
default:
b = qBound((double)KoColorSpaceMathsTraits<double>::min,
(double)KoColorSpaceMathsTraits<double>::unitValue * values[i],
(double)KoColorSpaceMathsTraits<double>::max);
b = qBound((float)KoCmykColorSpaceMathsTraits<channels_type>::min,
(float)KoCmykColorSpaceMathsTraits<channels_type>::unitValue * values[i],
(float)KoCmykColorSpaceMathsTraits<channels_type>::max);
break;
}
c = (channels_type)b;
......
/*
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2017,2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <KoLabColorSpaceMaths.h>
#include <cfloat>
#include <QtGlobal>
#ifdef HAVE_OPENEXR
const half KoLabColorSpaceMathsTraits<half>::zeroValueL = 0.0;
const half KoLabColorSpaceMathsTraits<half>::unitValueL = 100.0;
const half KoLabColorSpaceMathsTraits<half>::halfValueL = 50.0;
const half KoLabColorSpaceMathsTraits<half>::zeroValueAB = -128.0;
const half KoLabColorSpaceMathsTraits<half>::unitValueAB = +127.0;
const half KoLabColorSpaceMathsTraits<half>::halfValueAB = 0.0;
#endif
const float KoLabColorSpaceMathsTraits<float>::zeroValueL = 0.0;
const float KoLabColorSpaceMathsTraits<float>::unitValueL = 100.0;
const float KoLabColorSpaceMathsTraits<float>::halfValueL = 50.0;
const float KoLabColorSpaceMathsTraits<float>::zeroValueAB = -128.0;
const float KoLabColorSpaceMathsTraits<float>::unitValueAB = +127.0;
const float KoLabColorSpaceMathsTraits<float>::halfValueAB = 0.0;
const double KoLabColorSpaceMathsTraits<double>::zeroValueL = 0.0;
const double KoLabColorSpaceMathsTraits<double>::unitValueL = 100.0;
const double KoLabColorSpaceMathsTraits<double>::halfValueL = 50.0;
const double KoLabColorSpaceMathsTraits<double>::zeroValueAB = -128.0;
const double KoLabColorSpaceMathsTraits<double>::unitValueAB = +127.0;
const double KoLabColorSpaceMathsTraits<double>::halfValueAB = 0.0;
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) Wolthera van Hovell tot Westerflier <griffinvalley@gmail.com>, (C) 2016
* Copyright (C) 2020 L. E. Segovia <amy@amyspark.me>
*
* 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
......@@ -69,7 +70,6 @@ void KisSpinboxColorSelector::slotSetColorSpace(const KoColorSpace *cs)
}
m_d->cs = cs;
//remake spinboxes
delete m_d->layout;
m_d->layout = new QFormLayout(this);
......@@ -140,8 +140,8 @@ void KisSpinboxColorSelector::slotSetColorSpace(const KoColorSpace *cs)
#ifdef HAVE_OPENEXR
case KoChannelInfo::FLOAT16: {
KisDoubleParseSpinBox *input = new KisDoubleParseSpinBox(this);
input->setMinimum(0);
input->setMaximum(KoColorSpaceMathsTraits<half>::max);
input->setMinimum(channel->getUIMin());
input->setMaximum(channel->getUIMax());
input->setSingleStep(0.1);
m_d->doubleSpinBoxList.append(input);
m_d->layout->addRow(inlb,input);
......@@ -156,8 +156,8 @@ void KisSpinboxColorSelector::slotSetColorSpace(const KoColorSpace *cs)
#endif
case KoChannelInfo::FLOAT32: {
KisDoubleParseSpinBox *input = new KisDoubleParseSpinBox(this);
input->setMinimum(0);
input->setMaximum(KoColorSpaceMathsTraits<float>::max);
input->setMinimum(channel->getUIMin());
input->setMaximum(channel->getUIMax());
  • Doesn't this limit the ability to input HDR values in RGB to current exposure? I'm not on my PC right now though...

  • It limits it to whatever max/min values LittleCMS's floating-point ICC returns. As far as I tested, only Lab and CMYK profiles yield odd ranges.

Please register or sign in to reply
input->setSingleStep(0.1);
m_d->doubleSpinBoxList.append(input);
m_d->layout->addRow(inlb,input);
......@@ -248,7 +248,8 @@ void KisSpinboxColorSelector::updateSpinboxesWithNewValues()
} else if ((channels.at(i)->channelValueType()==KoChannelInfo::FLOAT16 ||
channels.at(i)->channelValueType()==KoChannelInfo::FLOAT32 ||
channels.at(i)->channelValueType()==KoChannelInfo::FLOAT64) && m_d->doubleSpinBoxList.at(i)) {
m_d->doubleSpinBoxList.at(i)->setValue(channelValues[channelposition]);
float value = channels.at(i)->getUIMin() + channelValues[channelposition] * channels.at(i)->getUIUnitValue();
m_d->doubleSpinBoxList.at(i)->setValue(value);
}
}
......
......@@ -368,7 +368,8 @@ void IccColorProfile::calculateFloatUIMinMax(void)
(COLORSPACE_SH(color_space_mask) | CHANNELS_SH(num_channels) | BYTES_SH(2)),
cprofile,
(COLORSPACE_SH(color_space_mask) | FLOAT_SH(1) | CHANNELS_SH(num_channels) | BYTES_SH(0)), //NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield
INTENT_PERCEPTUAL, 0); // does the intent matter in this case?
INTENT_ABSOLUTE_COLORIMETRIC, 0); // does the intent matter in this case?
// absolute colorimetric gives bigger bounds with cmyk's Chemical Proof
if (trans) {
cmsDoTransform(trans, in_min_pixel, out_min_pixel, 1);
......
/*
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -43,6 +44,12 @@ CmykF32ColorSpace::CmykF32ColorSpace(const QString &name, KoColorProfile *p)
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<KoCmykF32Traits>(this);
}
......@@ -64,10 +71,13 @@ void CmykF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomE
{
const KoCmykF32Traits::Pixel *p = reinterpret_cast<const KoCmykF32Traits::Pixel *>(pixel);
QDomElement labElt = doc.createElement("CMYK");
labElt.setAttribute("c", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(p->cyan)));
labElt.setAttribute("m", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(p->magenta)));
labElt.setAttribute("y", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(p->yellow)));
labElt.setAttribute("k", KisDomUtils::toString(KoColorSpaceMaths< KoCmykF32Traits::channels_type, qreal>::scaleToA(p->black)));
// 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);
}
......@@ -75,10 +85,10 @@ void CmykF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomE
void CmykF32ColorSpace::colorFromXML(quint8 *pixel, const QDomElement &elt) const
{
KoCmykF32Traits::Pixel *p = reinterpret_cast<KoCmykF32Traits::Pixel *>(pixel);
p->cyan = KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("c")));
p->magenta = KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("m")));
p->yellow = KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("y")));
p->black = KoColorSpaceMaths< qreal, KoCmykF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("k")));
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->alpha = 1.0;
}
......
/*
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
* Copyright (c) 2020 L. E. Segovia <amy@amyspark.me>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -43,6 +44,11 @@ LabF32ColorSpace::LabF32ColorSpace(const QString &name, KoColorProfile *p)
init();
addStandardCompositeOps<KoLabF32Traits>(this);
dbgPlugins << "La*b* (float) channel bounds for: " << icc_p->name();
dbgPlugins << "L: " << uiRanges[0].minVal << uiRanges[0].maxVal;
dbgPlugins << "a: " << uiRanges[1].minVal << uiRanges[1].maxVal;
dbgPlugins << "b: " << uiRanges[2].minVal << uiRanges[2].maxVal;
}
bool LabF32ColorSpace::willDegrade(ColorSpaceIndependence independence) const
......@@ -63,9 +69,12 @@ void LabF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomEl
{
const KoLabF32Traits::Pixel *p = reinterpret_cast<const KoLabF32Traits::Pixel *>(pixel);
QDomElement labElt = doc.createElement("Lab");
labElt.setAttribute("L", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(p->L)));
labElt.setAttribute("a", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(p->a)));
labElt.setAttribute("b", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(p->b)));
// XML expects 0-1, we need 0-100, -128-+127
// Get the bounds from the channels and adjust the calculations
labElt.setAttribute("L", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[0]->getUIUnitValue() * (p->L - this->channels()[0]->getUIMin()))));
labElt.setAttribute("a", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[1]->getUIUnitValue() * (p->a - this->channels()[1]->getUIMin()))));
labElt.setAttribute("b", KisDomUtils::toString(KoColorSpaceMaths< KoLabF32Traits::channels_type, qreal>::scaleToA(1.f / this->channels()[2]->getUIUnitValue() * (p->b - this->channels()[2]->getUIMin()))));
labElt.setAttribute("space", profile()->name());
colorElt.appendChild(labElt);
}
......@@ -73,9 +82,9 @@ void LabF32ColorSpace::colorToXML(const quint8 *pixel, QDomDocument &doc, QDomEl
void LabF32ColorSpace::colorFromXML(quint8 *pixel, const QDomElement &elt) const
{
KoLabF32Traits::Pixel *p = reinterpret_cast<KoLabF32Traits::Pixel *>(pixel);
p->L = KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("L")));
p->a = KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("a")));
p->b = KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("b")));
p->L = this->channels()[0]->getUIMin() + KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("L"))) * this->channels()[0]->getUIUnitValue();
p->a = this->channels()[1]->getUIMin() + KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("a"))) * this->channels()[1]->getUIUnitValue();
p->b = this->channels()[2]->getUIMin() + KoColorSpaceMaths< qreal, KoLabF32Traits::channels_type >::scaleToA(KisDomUtils::toDouble(elt.attribute("b"))) * this->channels()[2]->getUIUnitValue();
p->alpha = 1.0;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment