Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_display_color_converter.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2014 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QGlobalStatic>
10#include <QPointer>
11
12#include <KoColor.h>
14#include <KoColorSpaceMaths.h>
17#include <KoColorConversions.h>
18
20#include "kis_config_notifier.h"
22#include "kis_canvas2.h"
23#include "KisViewManager.h"
24#include "kis_image.h"
25#include "kis_node.h"
26
27#include "kundo2command.h"
28#include "kis_config.h"
29#include "kis_paint_device.h"
30#include "kis_iterator_ng.h"
32#include "KisDisplayConfig.h"
33
35
36
38{
40 : q(_q),
41 resourceManager(_resourceManager),
42 nodeColorSpace(0),
43 paintingColorSpace(0),
44 displayFilter(0),
45 displayRenderer(new DisplayRenderer(_q, _resourceManager))
46 {
47 }
48
50
52
55
56 const KoColorProfile* inputImageProfile = 0;
57
58 mutable const KoColorSpace *cachedOcioInputColorSpace = 0;
59 mutable const KoColorSpace *cachedOcioOutputColorSpace = 0;
60 mutable const KoColorSpace *cachedQtWidgetsColorSpace = 0;
61 mutable const KoColorSpace *cachedOpenGLSurfaceColorSpace = 0;
62
63 // this color space will never change during the run of Krita
64 mutable const KoColorSpace *cachedIntermediateColorSpace = 0;
65
67 cachedOcioInputColorSpace = 0;
68 cachedOcioOutputColorSpace = 0;
69 cachedQtWidgetsColorSpace = 0;
70 cachedOpenGLSurfaceColorSpace = 0;
71
73 }
74
76 return multiSurfaceDisplayConfig.uiProfile;
77 }
78
80 return multiSurfaceDisplayConfig.canvasProfile;
81 }
82
84 return displayFilter && displayFilter->useInternalColorManagement() ?
85 openGLSurfaceProfile() : inputImageProfile;
86 }
87
89 return openGLSurfaceProfile();
90 }
91
93 return cachedOcioInputColorSpace
94 ? cachedOcioInputColorSpace
95 : (cachedOcioInputColorSpace =
97 colorSpace(
100 ocioInputProfile()));
101 }
102
104 return cachedOcioOutputColorSpace
105 ? cachedOcioOutputColorSpace
106 : (cachedOcioOutputColorSpace =
108 colorSpace(
111 ocioOutputProfile()));
112
113 }
114
116 return cachedQtWidgetsColorSpace
117 ? cachedQtWidgetsColorSpace
118 : (cachedQtWidgetsColorSpace =
120 colorSpace(
123 qtWidgetsProfile()));
124
125 }
126
127 const KoColorSpace* openGLSurfaceColorSpace(const KoID &bitDepthId) const {
128 return cachedOpenGLSurfaceColorSpace
129 ? cachedOpenGLSurfaceColorSpace
130 : (cachedOpenGLSurfaceColorSpace =
132 colorSpace(
134 bitDepthId.id(),
135 openGLSurfaceProfile()));
136 }
137
139 // the color space where we apply exposure and
140 // gamma should always be linear
141 return cachedIntermediateColorSpace
142 ? cachedIntermediateColorSpace
143 : (cachedIntermediateColorSpace =
145 colorSpace(
149 }
150
152
154
158
159 inline KoColor approximateFromQColor(const QColor &qcolor);
160 inline QColor approximateToQColor(const KoColor &color);
161
162 void slotCanvasResourceChanged(int key, const QVariant &v);
163 void slotUpdateCurrentNodeColorSpace();
164 void selectPaintingColorSpace();
165
166 void updateIntermediateFgColor(const KoColor &color);
167 void setCurrentNode(KisNodeSP node);
168 bool useOcio() const;
169 bool needsColorProofing(const KoColorSpace *srcColorSpace) const;
170
172 public:
173 DisplayRenderer(KisDisplayColorConverter *displayColorConverter, KoCanvasResourceProvider *resourceManager)
174 : m_displayColorConverter(displayColorConverter),
175 m_resourceManager(resourceManager)
176 {
177 displayColorConverter->connect(displayColorConverter, SIGNAL(displayConfigurationChanged()),
178 this, SIGNAL(displayConfigurationChanged()), Qt::UniqueConnection);
179 }
180
181 QImage toQImage(const KoColorSpace *srcColorSpace, const quint8 *data, QSize size, bool proofPaintColors = false) const override {
182 QImage result = m_displayColorConverter->toQImage(srcColorSpace, data, size, proofPaintColors);
183 return result;
184 }
185
186 QColor toQColor(const KoColor &c, bool proofToPaintColors = false) const override {
187 return m_displayColorConverter->toQColor(c, proofToPaintColors);
188 }
189
190 KoColor approximateFromRenderedQColor(const QColor &c) const override {
191 return m_displayColorConverter->approximateFromRenderedQColor(c);
192 }
193
194 KoColor fromHsv(int h, int s, int v, int a) const override {
195 return m_displayColorConverter->fromHsv(h, s, v, a);
196 }
197
198 void getHsv(const KoColor &srcColor, int *h, int *s, int *v, int *a) const override {
199 m_displayColorConverter->getHsv(srcColor, h, s, v, a);
200 }
201
202 qreal minVisibleFloatValue(const KoChannelInfo *chaninfo) const override {
203 return chaninfo->getUIMin();
204 }
205
206 qreal maxVisibleFloatValue(const KoChannelInfo *chaninfo) const override {
207 qreal maxValue = chaninfo->getUIMax();
208
209 if (m_resourceManager) {
210 qreal exposure = m_resourceManager->resource(KoCanvasResource::HdrExposure).value<qreal>();
211 // not sure if *= is what we want
212 maxValue *= std::pow(2.0, -exposure);
213 }
214
215 return maxValue;
216 }
217
218 const KoColorSpace* getPaintingColorSpace() const override {
219 return m_displayColorConverter->paintingColorSpace();
220 }
221
222 private:
225 };
226
227 QScopedPointer<KoColorDisplayRendererInterface> displayRenderer;
228};
229
231 : QObject(parent),
232 m_d(new Private(this, resourceManager))
233{
234 connect(m_d->resourceManager, SIGNAL(canvasResourceChanged(int,QVariant)),
235 SLOT(slotCanvasResourceChanged(int,QVariant)));
236 connect(KisConfigNotifier::instance(), SIGNAL(configChanged()),
237 SLOT(selectPaintingColorSpace()));
238
239 m_d->inputImageProfile = KoColorSpaceRegistry::instance()->p709SRGBProfile();
240 m_d->setCurrentNode(0);
242}
243
245 : m_d(new Private(this, 0))
246{
248
249 m_d->inputImageProfile = KoColorSpaceRegistry::instance()->p709SRGBProfile();
250 m_d->paintingColorSpace = KoColorSpaceRegistry::instance()->rgb8();
251
252 m_d->setCurrentNode(0);
253}
254
258
260{
261 m_d->inputImageProfile =
263 cs->profile() :
265
266 m_d->notifyDisplayConfigurationChanged();
267}
268
269
274
279
284
286{
287 if (!paintingColorSpace || srcColorSpace == paintingColorSpace || *srcColorSpace == *paintingColorSpace) {
288 return false;
289 }
290 // TODO: ideally, we'd identify color profiles that only differ in transfer curves but
291 // define the same primaries/gamut and return false for them aswell
292 if (srcColorSpace->colorModelId() == paintingColorSpace->colorModelId()) {
293 const KoColorProfile *paintProfile = paintingColorSpace->profile();
294 const KoColorProfile *srcProfile = srcColorSpace->profile();
295 bool matchingProfiles = (paintProfile == srcProfile) ||
296 (paintProfile && srcProfile && *paintProfile == *srcProfile);
297 // unless we go float->int, the color spaces are considered compatible
298 if (matchingProfiles &&
299 (srcColorSpace->colorDepthId() == Integer8BitsColorDepthID ||
300 srcColorSpace->colorDepthId() == Integer16BitsColorDepthID ||
303 return false;
304 }
305 }
306 return true;
307}
308
310{
312
313 KoColor color = srcColor;
314 color.convertTo(intermediateColorSpace());
315 displayFilter->approximateForwardTransformation(color.data(), 1);
316 intermediateFgColor = color;
317}
318
320{
322 KisNodeSP currentNode = v.value<KisNodeWSP>();
323 setCurrentNode(currentNode);
324 } else if (useOcio() && key == KoCanvasResource::ForegroundColor) {
325 updateIntermediateFgColor(v.value<KoColor>());
326 }
327}
328
330{
331 setCurrentNode(connectedNode);
332}
333
335 return node->paintDevice() ? node->paintDevice() : node->original();
336}
337
339{
340 if (connectedNode) {
341 KisPaintDeviceSP device = findValidDevice(connectedNode);
342
343 if (device) {
344 q->disconnect(device, 0);
345 }
346 }
347
348 nodeColorSpace = 0;
349
350 if (node) {
351 KisPaintDeviceSP device = findValidDevice(node);
352
353 nodeColorSpace = device ?
355 node->colorSpace();
356
358
359 if (device) {
360 q->connect(device, SIGNAL(profileChanged(const KoColorProfile*)),
361 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
362 q->connect(device, SIGNAL(colorSpaceChanged(const KoColorSpace*)),
363 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
364 }
365
366 }
367
368 if (!nodeColorSpace) {
370 }
371
372 connectedNode = node;
373 selectPaintingColorSpace();
374}
375
377{
378 KisConfig cfg(true);
380
383 }
384
385 notifyDisplayConfigurationChanged();
386}
387
389{
390 KIS_ASSERT_RECOVER(m_d->paintingColorSpace) {
392 }
393
394 return m_d->paintingColorSpace;
395}
396
398{
399 return m_d->nodeColorSpace;
400}
401
403{
404 if (m_d->multiSurfaceDisplayConfig == config) return;
405
406
407
408 m_d->multiSurfaceDisplayConfig = config;
409 m_d->notifyDisplayConfigurationChanged();
410}
411
413{
414 if (m_d->displayFilter && displayFilter &&
415 displayFilter->lockCurrentColorVisualRepresentation()) {
416
417 KoColor color(m_d->intermediateFgColor);
418 displayFilter->approximateInverseTransformation(color.data(), 1);
419 color.convertTo(m_d->paintingColorSpace);
420 m_d->resourceManager->setForegroundColor(color);
421 }
422
423 m_d->displayFilter = displayFilter;
424
425 if (m_d->displayFilter) {
426 m_d->updateIntermediateFgColor(
427 m_d->resourceManager->foregroundColor());
428 }
429
430
431 { // sanity check
432 // KisConfig cfg;
433 // KIS_ASSERT_RECOVER_NOOP(cfg.useOcio() == (bool) m_d->displayFilter);
434 }
435
436 m_d->selectPaintingColorSpace();
437}
438
440{
441 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
442}
443
448
450{
451 return m_d->multiSurfaceDisplayConfig;
452}
453
455{
456 return m_d->multiSurfaceDisplayConfig.options();
457}
458
459QColor KisDisplayColorConverter::toQColor(const KoColor &srcColor, bool proofToPaintColors) const
460{
461 KoColor c(srcColor);
462
463 if (proofToPaintColors && m_d->needsColorProofing(c.colorSpace())) {
464 c.convertTo(m_d->paintingColorSpace, m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
465 }
466
467 if (m_d->useOcio()) {
468 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
469 return QColor(Qt::green);
470 }
471
472 c.convertTo(m_d->ocioInputColorSpace());
473 m_d->displayFilter->filter(c.data(), 1);
474 c.setProfile(m_d->ocioOutputProfile());
475 }
476
477 // we expect the display profile is rgb8, which is BGRA here
478 KIS_ASSERT_RECOVER(m_d->qtWidgetsColorSpace()->pixelSize() == 4) {
479 return QColor(Qt::red);
480 }
481
482 c.convertTo(m_d->qtWidgetsColorSpace(), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
483 const quint8 *p = c.data();
484 return QColor(p[2], p[1], p[0], p[3]);
485}
486
488 const KoID &bitDepthId) const
489{
490 KoColor c(srcColor);
491
492 if (m_d->useOcio()) {
493 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
494 return srcColor;
495 }
496
497 c.convertTo(m_d->ocioInputColorSpace());
498 m_d->displayFilter->filter(c.data(), 1);
499 c.setProfile(m_d->ocioOutputProfile());
500 }
501
502 c.convertTo(m_d->openGLSurfaceColorSpace(bitDepthId), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
503 return c;
504}
505
507{
508 const KoColorProfile *displayProfile = m_d->openGLSurfaceProfile();
509
510 return !m_d->useOcio() &&
512 (!!cs->profile() == !!displayProfile) &&
513 (!cs->profile() ||
514 cs->profile()->uniqueId() == displayProfile->uniqueId());
515}
516
517
519{
520 return m_d->approximateFromQColor(c);
521}
522
523QImage KisDisplayColorConverter::toQImage(KisPaintDeviceSP srcDevice, bool proofPaintColors) const
524{
525 KisPaintDeviceSP device = srcDevice;
526
527 QRect bounds = srcDevice->exactBounds();
528 if (bounds.isEmpty()) return QImage();
529
530 if (proofPaintColors && m_d->needsColorProofing(srcDevice->colorSpace())) {
531 srcDevice->convertTo(paintingColorSpace(), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
532 }
533
534 if (m_d->useOcio()) {
535 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
536 return QImage();
537 }
538
539 device = new KisPaintDevice(*srcDevice);
540 device->convertTo(m_d->ocioInputColorSpace());
541
542 KisSequentialIterator it(device, bounds);
543 int numConseqPixels = it.nConseqPixels();
544 while (it.nextPixels(numConseqPixels)) {
545 numConseqPixels = it.nConseqPixels();
546 m_d->displayFilter->filter(it.rawData(), numConseqPixels);
547 }
548
549 device->setProfile(m_d->ocioOutputProfile(), 0);
550 }
551
552 // we expect the display profile is rgb8, which is BGRA here
553 KIS_ASSERT_RECOVER(m_d->qtWidgetsColorSpace()->pixelSize() == 4) {
554 return QImage();
555 }
556
557 return device->convertToQImage(m_d->qtWidgetsProfile(),
558 bounds,
559 m_d->multiSurfaceDisplayConfig.intent,
560 m_d->multiSurfaceDisplayConfig.conversionFlags);
561}
562
563QImage KisDisplayColorConverter::toQImage(const KoColorSpace *srcColorSpace, const quint8 *data, QSize size, bool proofPaintColors) const
564{
565 const int numPixels = size.width() * size.height();
566
567 const KoColorSpace *colorSpace = srcColorSpace;
568 const quint8 *pixels = data;
569
570 QScopedArrayPointer<quint8> proofBuffer;
571
572 if (proofPaintColors && m_d->needsColorProofing(srcColorSpace)) {
573 const int imageSize = numPixels * paintingColorSpace()->pixelSize();
574 proofBuffer.reset(new quint8[imageSize]);
575 colorSpace->convertPixelsTo(pixels, proofBuffer.data(),
577 numPixels,
578 m_d->multiSurfaceDisplayConfig.intent,
579 m_d->multiSurfaceDisplayConfig.conversionFlags);
580 colorSpace = paintingColorSpace();
581 pixels = proofBuffer.data();
582 }
583
584 QScopedArrayPointer<quint8> ocioBuffer;
585 if (m_d->useOcio()) {
586 const int imageSize = numPixels * m_d->ocioInputColorSpace()->pixelSize();
587 ocioBuffer.reset(new quint8[imageSize]);
588 colorSpace->convertPixelsTo(pixels, ocioBuffer.data(),
589 m_d->ocioInputColorSpace(),
590 numPixels,
591 m_d->multiSurfaceDisplayConfig.intent,
592 m_d->multiSurfaceDisplayConfig.conversionFlags);
593 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
594
595 return m_d->ocioOutputColorSpace()->convertToQImage(ocioBuffer.data(), size.width(), size.height(),
596 m_d->qtWidgetsProfile(),
597 m_d->multiSurfaceDisplayConfig.intent,
598 m_d->multiSurfaceDisplayConfig.conversionFlags);
599 }
600
601 return colorSpace->convertToQImage(pixels, size.width(), size.height(),
602 m_d->qtWidgetsProfile(),
603 m_d->multiSurfaceDisplayConfig.intent,
604 m_d->multiSurfaceDisplayConfig.conversionFlags);
605}
606
608 const KoColorSpace *dstColorSpace) const
609{
617 KIS_SAFE_ASSERT_RECOVER_RETURN(device->bounds().isValid());
618
619 if (m_d->useOcio()) {
620 KIS_ASSERT_RECOVER_RETURN(m_d->ocioInputColorSpace()->pixelSize() == 16);
621
622 device->convertTo(m_d->ocioInputColorSpace());
623 m_d->displayFilter->filter(device->data(), device->bounds().width() * device->bounds().height());
624 device->setProfile(m_d->ocioOutputProfile());
625 }
626
627 KIS_SAFE_ASSERT_RECOVER_RETURN(dstColorSpace);
628 device->convertTo(dstColorSpace);
629}
630
632{
633 if (!useOcio()) {
634 return KoColor(qcolor, paintingColorSpace);
635 } else {
636 KoColor color(qcolor, intermediateColorSpace());
637 displayFilter->approximateInverseTransformation(color.data(), 1);
639 return color;
640 }
641
642 qFatal("Must not be reachable");
643 return KoColor();
644}
645
647{
648 KoColor color(srcColor);
649
650 if (useOcio()) {
651 color.convertTo(intermediateColorSpace());
652 displayFilter->approximateForwardTransformation(color.data(), 1);
653 }
654
655 return color.toQColor();
656}
657
658
659KoColor KisDisplayColorConverter::fromHsv(int h, int s, int v, int a) const
660{
661 // generate HSV from sRGB!
662 QColor qcolor(QColor::fromHsv(h, s, v, a));
663 return m_d->approximateFromQColor(qcolor);
664}
665
666void KisDisplayColorConverter::getHsv(const KoColor &srcColor, int *h, int *s, int *v, int *a) const
667{
668 // we are going through sRGB here!
669 QColor color = m_d->approximateToQColor(srcColor);
670 color.getHsv(h, s, v, a);
671}
672
673KoColor KisDisplayColorConverter::fromHsvF(qreal h, qreal s, qreal v, qreal a)
674{
675 // generate HSV from sRGB!
676 QColor qcolor(QColor::fromHsvF(h, s, v, a));
677 return m_d->approximateFromQColor(qcolor);
678}
679
680void KisDisplayColorConverter::getHsvF(const KoColor &srcColor, qreal *h, qreal *s, qreal *v, qreal *a)
681{
682 // we are going through sRGB here!
683 QColor color = m_d->approximateToQColor(srcColor);
684#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
685 color.getHsvF(h, s, v, a);
686#else
687 float fH, fS, fV, fA;
688 fH = *h;
689 fS = *s;
690 fV = *v;
691 if (a) {
692 fA = *a;
693 }
694 color.getHsvF(&fH, &fS, &fV, &fA);
695 *h = fH;
696 *s = fS;
697 *v = fV;
698 if (a) {
699 *a = fA;
700 }
701#endif
702}
703
704KoColor KisDisplayColorConverter::fromHslF(qreal h, qreal s, qreal l, qreal a)
705{
706 // generate HSL from sRGB!
707 QColor qcolor(QColor::fromHslF(h, s, l, a));
708 if (!qcolor.isValid()) {
709 warnKrita << "Could not construct valid color from h" << h << "s" << s << "l" << l << "a" << a;
710 qcolor = Qt::black;
711 }
712 return m_d->approximateFromQColor(qcolor);
713
714}
715
716void KisDisplayColorConverter::getHslF(const KoColor &srcColor, qreal *h, qreal *s, qreal *l, qreal *a)
717{
718 // we are going through sRGB here!
719 QColor color = m_d->approximateToQColor(srcColor);
720#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
721 color.getHslF(h, s, l, a);
722#else
723 float fH, fS, fL, fA;
724 fH = *h;
725 fS = *s;
726 fL = *l;
727 if (a) {
728 fA = *a;
729 }
730 color.getHslF(&fH, &fS, &fL, &fA);
731 *h = fH;
732 *s = fS;
733 *l = fL;
734 if (a) {
735 *a = fA;
736 }
737#endif
738}
739
741{
742 // generate HSI from sRGB!
743 qreal r=0.0;
744 qreal g=0.0;
745 qreal b=0.0;
746 qreal a=1.0;
747 HSIToRGB(h, s, i, &r, &g, &b);
748 QColor qcolor;
749 qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
750 return m_d->approximateFromQColor(qcolor);
751}
752
753void KisDisplayColorConverter::getHsiF(const KoColor &srcColor, qreal *h, qreal *s, qreal *i)
754{
755 // we are going through sRGB here!
756 QColor color = m_d->approximateToQColor(srcColor);
757 qreal r=color.redF();
758 qreal g=color.greenF();
759 qreal b=color.blueF();
760 RGBToHSI(r, g, b, h, s, i);
761}
762
763KoColor KisDisplayColorConverter::fromHsyF(qreal h, qreal s, qreal y, qreal R, qreal G, qreal B, qreal gamma)
764{
765 // generate HSL from sRGB!
766 QVector <qreal> channelValues(3);
767 y = pow(y, gamma);
768 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2], R, G, B);
770 QColor qcolor;
771 qcolor.setRgbF(qBound(0.0,channelValues[0],1.0), qBound(0.0,channelValues[1],1.0), qBound(0.0,channelValues[2],1.0), 1.0);
772 return m_d->approximateFromQColor(qcolor);
773}
774
775void KisDisplayColorConverter::getHsyF(const KoColor &srcColor, qreal *h, qreal *s, qreal *y, qreal R, qreal G, qreal B, qreal gamma)
776{
777 // we are going through sRGB here!
778 QColor color = m_d->approximateToQColor(srcColor);
779 QVector <qreal> channelValues(3);
780 channelValues[0]=color.redF();
781 channelValues[1]=color.greenF();
782 channelValues[2]=color.blueF();
783 //TODO: if we're going to have KoColor here, remember to check whether the TRC of the profile exists...
785 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y, R, G, B);
786 *y = pow(*y, 1/gamma);
787}
788
789#include "moc_kis_display_color_converter.cpp"
const Params2D p
Eigen::Matrix< double, 4, 2 > R
qreal v
Q_GLOBAL_STATIC(KisStoragePluginRegistry, s_instance)
void HSYToRGB(const qreal h, const qreal s, const qreal y, qreal *red, qreal *green, qreal *blue, qreal R, qreal G, qreal B)
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 RGBToHSY(const qreal r, const qreal g, const qreal b, qreal *h, qreal *s, qreal *y, qreal R, qreal G, qreal B)
const KoID Float32BitsColorDepthID("F32", ki18n("32-bit float/channel"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisConfigNotifier * instance()
const KoColorSpace * customColorSelectorColorSpace(bool defaultValue=false) const
qreal minVisibleFloatValue(const KoChannelInfo *chaninfo) const override
DisplayRenderer(KisDisplayColorConverter *displayColorConverter, KoCanvasResourceProvider *resourceManager)
QColor toQColor(const KoColor &c, bool proofToPaintColors=false) const override
KoColor approximateFromRenderedQColor(const QColor &c) const override
KoColor fromHsv(int h, int s, int v, int a) const override
const KoColorSpace * getPaintingColorSpace() const override
getColorSpace
QImage toQImage(const KoColorSpace *srcColorSpace, const quint8 *data, QSize size, bool proofPaintColors=false) const override
Convert a consecutive block of pixel data to an ARGB32 QImage.
void getHsv(const KoColor &srcColor, int *h, int *s, int *v, int *a) const override
qreal maxVisibleFloatValue(const KoChannelInfo *chaninfo) const override
void getHslF(const KoColor &srcColor, qreal *h, qreal *s, qreal *l, qreal *a=0)
std::pair< KoColorConversionTransformation::Intent, KoColorConversionTransformation::ConversionFlags > ConversionOptions
KisMultiSurfaceDisplayConfig multiSurfaceDisplayConfig() const
KoColor fromHsiF(qreal h, qreal s, qreal i)
KoColorDisplayRendererInterface * displayRendererInterface() const
const KoColorSpace * paintingColorSpace() const
QSharedPointer< KisDisplayFilter > displayFilter() const
void getHsiF(const KoColor &srcColor, qreal *h, qreal *s, qreal *i)
const QScopedPointer< Private > m_d
QImage toQImage(KisPaintDeviceSP srcDevice, bool proofPaintColors=false) const
KoColor applyDisplayFiltering(const KoColor &srcColor, const KoID &bitDepthId) const
void getHsyF(const KoColor &srcColor, qreal *h, qreal *s, qreal *y, qreal R=0.2126, qreal G=0.7152, qreal B=0.0722, qreal gamma=2.2)
KoColor fromHslF(qreal h, qreal s, qreal l, qreal a=1.0)
void getHsvF(const KoColor &srcColor, qreal *h, qreal *s, qreal *v, qreal *a=0)
static KisDisplayColorConverter * dumbConverterInstance()
void setImageColorSpace(const KoColorSpace *cs)
void getHsv(const KoColor &srcColor, int *h, int *s, int *v, int *a=0) const
bool canSkipDisplayConversion(const KoColorSpace *cs) const
void applyDisplayFilteringF32(KisFixedPaintDeviceSP device, const KoColorSpace *dstColorSpace) const
void setMultiSurfaceDisplayConfig(const KisMultiSurfaceDisplayConfig &config)
void setDisplayFilter(QSharedPointer< KisDisplayFilter > displayFilter)
QColor toQColor(const KoColor &c, bool proofToPaintColors=false) const
KoColor approximateFromRenderedQColor(const QColor &c) const
KoColor fromHsv(int h, int s, int v, int a=255) const
KoColor fromHsyF(qreal h, qreal s, qreal y, qreal R=0.2126, qreal G=0.7152, qreal B=0.0722, qreal gamma=2.2)
const KoColorSpace * nodeColorSpace() const
ConversionOptions conversionOptions() const
KoColor fromHsvF(qreal h, qreal s, qreal v, qreal a=1.0)
KisDisplayConfig This class keeps track of the color management configuration for image to display....
void setProfile(const KoColorProfile *profile)
void convertTo(const KoColorSpace *dstColorSpace=0, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags())
const KoColorSpace * colorSpace() const
virtual const KoColorSpace * compositionSourceColorSpace() const
QRect exactBounds() const
const KoColorSpace * colorSpace() const
QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags()) const
bool setProfile(const KoColorProfile *profile, KUndo2Command *parentCommand)
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
ALWAYS_INLINE quint8 * rawData()
double getUIMin(void) const
double getUIMax(void) const
virtual quint32 pixelSize() const =0
virtual QImage convertToQImage(const quint8 *data, qint32 width, qint32 height, const KoColorProfile *dstProfile, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
virtual KoID colorModelId() const =0
virtual KoID colorDepthId() const =0
virtual bool convertPixelsTo(const quint8 *src, quint8 *dst, const KoColorSpace *dstColorSpace, quint32 numPixels, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
virtual const KoColorProfile * profile() const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
Definition KoColor.cpp:136
quint8 * data()
Definition KoColor.h:144
const KoColorSpace * colorSpace() const
return the current colorSpace
Definition KoColor.h:82
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
void setProfile(const KoColorProfile *profile)
assign new profile without converting pixel data
Definition KoColor.cpp:177
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
#define KIS_ASSERT_RECOVER(cond)
Definition kis_assert.h:55
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:75
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
#define bounds(x, a, b)
#define warnKrita
Definition kis_debug.h:87
KisPaintDeviceSP findValidDevice(KisNodeSP node)
@ ForegroundColor
The active foreground color selected for this canvas.
virtual KisPaintDeviceSP original() const =0
virtual const KoColorSpace * colorSpace() const =0
virtual KisPaintDeviceSP paintDevice() const =0
Private(KisDisplayColorConverter *_q, KoCanvasResourceProvider *_resourceManager)
bool needsColorProofing(const KoColorSpace *srcColorSpace) const
void slotCanvasResourceChanged(int key, const QVariant &v)
QSharedPointer< KisDisplayFilter > displayFilter
const KoColorProfile * ocioInputProfile() const
const KoColorProfile * ocioOutputProfile() const
KisMultiSurfaceDisplayConfig multiSurfaceDisplayConfig
const KoColorProfile * openGLSurfaceProfile() const
QScopedPointer< KoColorDisplayRendererInterface > displayRenderer
const KoColorSpace * ocioOutputColorSpace() const
const KoColorSpace * ocioInputColorSpace() const
KoColor approximateFromQColor(const QColor &qcolor)
const KoColorSpace * intermediateColorSpace() const
const KoColorSpace * openGLSurfaceColorSpace(const KoID &bitDepthId) const
const KoColorProfile * qtWidgetsProfile() const
virtual void linearizeFloatValueFast(QVector< qreal > &Value) const =0
virtual QByteArray uniqueId() const =0
virtual void delinearizeFloatValueFast(QVector< qreal > &Value) const =0
static KoColorSpaceRegistry * instance()
const KoColorProfile * p709SRGBProfile() const
const KoColorSpace * rgb8(const QString &profileName=QString())
const KoColorProfile * p2020G10Profile() const