16#include <KSharedConfig>
17#include <KConfigGroup>
40 qreal
lumaRGB[3] {0.2126, 0.7152, 0.0722};
52 KConfigGroup cfg = KSharedConfig::openConfig()->group(
"advancedColorSelector");
63 if (!
m_d->allowUpdates) {
67 if (!
m_d->currentCS) {
68 m_d->currentcolor = c;
80 if (!
m_d->currentCS || *
m_d->currentCS != *cs) {
104 if (!
m_d->allowUpdates) {
108 quint32 changeFlags = 0;
109 QVector4D newValues(0, 0, 0, 0);
110 for (
int i = 0; i <
m_d->colorChannelCount; i++) {
111 newValues[i] = values[i];
112 changeFlags |= quint32(values[i] !=
m_d->channelValues[i]) << i;
114 if (changeFlags != 0) {
115 m_d->allowUpdates =
false;
116 m_d->channelValues = newValues;
120 m_d->allowUpdates =
true;
126 return m_d->currentcolor;
131 return m_d->channelValues;
136 return m_d->colorChannelCount;
146 return m_d->channelMaxValues;
151 if (maxValues ==
m_d->channelMaxValues) {
154 m_d->channelMaxValues = maxValues;
155 if (
m_d->exposureSupported) {
164 m_d->channelMaxValues = other.
m_d->channelMaxValues;
174 if (model ==
m_d->modelRGB) {
178 m_d->modelRGB = model;
191 return m_d->currentCS;
201 return (
m_d->exposureSupported);
207 QVector4D baseValues(values);
209 channelVec.fill(1.0);
214 HSVToRGB(values.x()*360, values.y(), values.z(), &baseValues[0], &baseValues[1], &baseValues[2]);
217 HSLToRGB(values.x()*360, values.y(), values.z(), &baseValues[0], &baseValues[1], &baseValues[2]);
222 HSIToRGB(values.x(), values.y(), values.z(), &temp[0], &temp[1], &temp[2]);
223 baseValues.setX(temp[0]);
224 baseValues.setY(temp[1]);
225 baseValues.setZ(temp[2]);
229 qreal Y = pow(values.z(),
m_d->gamma);
230 HSYToRGB(values.x(), values.y(), Y, &temp[0], &temp[1], &temp[2],
231 m_d->lumaRGB[0],
m_d->lumaRGB[1],
m_d->lumaRGB[2]);
232 baseValues.setX(temp[0]);
233 baseValues.setY(temp[1]);
234 baseValues.setZ(temp[2]);
235 if (!
m_d->isLinear) {
238 QVector<qreal> tempVec({baseValues[0], baseValues[1], baseValues[2]});
239 if (
m_d->exposureSupported) {
240 m_d->currentCS->profile()->delinearizeFloatValue(tempVec);
243 m_d->currentCS->profile()->delinearizeFloatValueFast(tempVec);
245 baseValues = QVector4D(tempVec[0], tempVec[1], tempVec[2], 0);
248 if (
m_d->applyGamma) {
249 for (
int i=0; i<3; i++) {
250 baseValues[i] = pow(baseValues[i], 2.2);
255 if (
m_d->exposureSupported) {
256 for (
int i = 0; i <
m_d->colorChannelCount; i++) {
257 baseValues[i] *=
m_d->channelMaxValues[i];
261 for (
int i=0; i<
m_d->colorChannelCount; i++) {
262 channelVec[
m_d->logicalToMemoryPosition[i]] = baseValues[i];
277 channelVec.fill(1.0);
278 m_d->currentCS->normalisedChannelsValue(c.
data(), channelVec);
279 QVector4D channelValuesDisplay(0, 0, 0, 0), coordinates(0, 0, 0, 0);
281 for (
int i =0; i<
m_d->colorChannelCount; i++) {
282 channelValuesDisplay[i] = channelVec[
m_d->logicalToMemoryPosition[i]];
285 if (
m_d->exposureSupported) {
286 for (
int i = 0; i <
m_d->colorChannelCount; i++) {
287 channelValuesDisplay[i] /=
m_d->channelMaxValues[i];
291 if (
m_d->applyGamma) {
292 for (
int i=0; i<3; i++) {
293 channelValuesDisplay[i] = pow(channelValuesDisplay[i], 1/2.2);
298 RGBToHSV(channelValuesDisplay[0], channelValuesDisplay[1], channelValuesDisplay[2], &hsv[0], &hsv[1], &hsv[2]);
300 coordinates = QVector4D(hsv, 0.f);
303 RGBToHSL(channelValuesDisplay[0], channelValuesDisplay[1], channelValuesDisplay[2], &hsl[0], &hsl[1], &hsl[2]);
305 coordinates = QVector4D(hsl, 0.f);
308 RGBToHSI(channelValuesDisplay[0], channelValuesDisplay[1], channelValuesDisplay[2], &hsi[0], &hsi[1], &hsi[2]);
309 coordinates = QVector4D(hsi[0], hsi[1], hsi[2], 0.f);
311 if (!
m_d->isLinear) {
314 QVector<qreal> temp({channelValuesDisplay[0], channelValuesDisplay[1], channelValuesDisplay[2]});
315 m_d->currentCS->profile()->linearizeFloatValue(temp);
316 channelValuesDisplay = QVector4D(temp[0], temp[1], temp[2], 0);
319 RGBToHSY(channelValuesDisplay[0], channelValuesDisplay[1], channelValuesDisplay[2], &hsy[0], &hsy[1], &hsy[2],
320 m_d->lumaRGB[0],
m_d->lumaRGB[1],
m_d->lumaRGB[2]);
321 hsy[2] = pow(hsy[2], 1/
m_d->gamma);
322 coordinates = QVector4D(hsy[0], hsy[1], hsy[2], 0.f);
325 if (coordinates[0] < 0) {
326 coordinates[0] =
m_d->channelValues[0];
328 for (
int i=0; i<3; i++) {
329 coordinates[i] = qBound(0.f, coordinates[i], 1.f);
332 for (
int i=0; i<4; i++) {
333 coordinates[i] = qBound(0.f, channelValuesDisplay[i], 1.f);
341 KConfigGroup cfg = KSharedConfig::openConfig()->group(
"advancedColorSelector");
344 m_d->gamma = cfg.readEntry(
"gamma", 2.2);
348 switch(
m_d->acs_config.mainTypeParameter) {
391 for (
int i = 0; i < channelList.size(); i++) {
398 m_d->logicalToMemoryPosition[logical] = i;
399 m_d->channelMaxValues[logical] = channel->
getUIMax();
403 KIS_ASSERT_X(cCount < 5,
"",
"unsupported channel count!");
405 m_d->colorChannelCount = cCount;
412 m_d->exposureSupported =
true;
414 m_d->exposureSupported =
false;
426 memcpy(
m_d->lumaRGB, luma.constData(), 3*
sizeof(qreal));
427 m_d->model =
m_d->modelRGB;
442 bool updatesAllowed =
m_d->allowUpdates;
443 m_d->allowUpdates =
false;
445 m_d->allowUpdates = updatesAllowed;
void HSYToRGB(const qreal h, const qreal s, const qreal y, qreal *red, qreal *green, qreal *blue, qreal R, qreal G, qreal B)
void RGBToHSV(float r, float g, float b, float *h, float *s, float *v)
void RGBToHSI(qreal r, qreal g, qreal b, qreal *h, qreal *s, qreal *i)
void HSIToRGB(const qreal h, const qreal s, const qreal i, qreal *red, qreal *green, qreal *blue)
void RGBToHSL(float r, float g, float b, float *h, float *s, float *l)
void RGBToHSY(const qreal r, const qreal g, const qreal b, qreal *h, qreal *s, qreal *y, qreal R, qreal G, qreal B)
void HSVToRGB(float h, float s, float v, float *r, float *g, float *b)
void HSLToRGB(float h, float sl, float l, float *r, float *g, float *b)
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID Float64BitsColorDepthID("F64", ki18n("64-bit float/channel"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
static KisColorSelectorConfiguration fromString(QString string)
The KisVisualColorModel class allows manipulating a KoColor using various color models.
void setMaxChannelValues(const QVector4D &maxValues)
void sigColorModelChanged()
sigColorModelChanged is emitted whenever the color model changes.
const KoColorSpace * colorSpace() const
void copyState(const KisVisualColorModel &other)
Copy the internal state of another KisVisualColorModel.
int colorChannelCount() const
KoColor currentColor() const
void slotSetColorSpace(const KoColorSpace *cs)
void slotLoadACSConfig()
slotLoadACSConfig loads supported settings from Advanced Color Selector
QVector4D convertKoColorToChannelValues(KoColor c) const
QVector4D channelValues() const
QVector4D maxChannelValues() const
bool supportsExposure() const
void loadColorSpace(const KoColorSpace *cs)
KoColor convertChannelValuesToKoColor(const QVector4D &values) const
void slotSetChannelValues(const QVector4D &values)
void setRGBColorModel(ColorModel model)
Set the HSX color model used for RGB color spaces.
~KisVisualColorModel() override
void sigNewColor(const KoColor &c)
const QScopedPointer< Private > m_d
ColorModel colorModel() const
void slotSetColor(const KoColor &c)
void sigChannelValuesChanged(const QVector4D &values, quint32 channelFlags)
void sigColorSpaceChanged()
sigColorSpaceChanged notifies that the color space from which the channel values are derived changed,...
@ ALPHA
The channel represents the opacity of a pixel.
enumChannelType channelType() const
qint32 displayPosition() const
double getUIMax(void) const
virtual quint32 alphaPos() const =0
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
QVector< qreal > lumaCoefficients
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
virtual const KoColorProfile * profile() const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
const KoColorSpace * colorSpace() const
return the current colorSpace
#define KIS_ASSERT_X(cond, where, what)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QVector4D channelMaxValues
const KoColorSpace * currentCS
KisColorSelectorConfiguration acs_config
int logicalToMemoryPosition[4]
virtual QByteArray uniqueId() const =0
virtual bool isLinear() const =0
static KoColorSpaceRegistry * instance()
const KoColorProfile * p2020PQProfile() const
const KoColorProfile * p2020G10Profile() const