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->paintingColorSpace = KoColorSpaceRegistry::instance()->rgb8();
241 m_d->setCurrentNode(0);
243}
244
246 : m_d(new Private(this, 0))
247{
249
250 m_d->inputImageProfile = KoColorSpaceRegistry::instance()->p709SRGBProfile();
251 m_d->paintingColorSpace = KoColorSpaceRegistry::instance()->rgb8();
252
253 m_d->setCurrentNode(0);
254}
255
259
261{
262 m_d->inputImageProfile =
264 cs->profile() :
266
267 m_d->notifyDisplayConfigurationChanged();
268}
269
270
275
280
285
287{
288 if (!paintingColorSpace || srcColorSpace == paintingColorSpace || *srcColorSpace == *paintingColorSpace) {
289 return false;
290 }
291 // TODO: ideally, we'd identify color profiles that only differ in transfer curves but
292 // define the same primaries/gamut and return false for them aswell
293 if (srcColorSpace->colorModelId() == paintingColorSpace->colorModelId()) {
294 const KoColorProfile *paintProfile = paintingColorSpace->profile();
295 const KoColorProfile *srcProfile = srcColorSpace->profile();
296 bool matchingProfiles = (paintProfile == srcProfile) ||
297 (paintProfile && srcProfile && *paintProfile == *srcProfile);
298 // unless we go float->int, the color spaces are considered compatible
299 if (matchingProfiles &&
300 (srcColorSpace->colorDepthId() == Integer8BitsColorDepthID ||
301 srcColorSpace->colorDepthId() == Integer16BitsColorDepthID ||
304 return false;
305 }
306 }
307 return true;
308}
309
311{
313
314 KoColor color = srcColor;
315 color.convertTo(intermediateColorSpace());
316 displayFilter->approximateForwardTransformation(color.data(), 1);
317 intermediateFgColor = color;
318}
319
321{
323 KisNodeSP currentNode = v.value<KisNodeWSP>();
324 setCurrentNode(currentNode);
325 } else if (useOcio() && key == KoCanvasResource::ForegroundColor) {
326 updateIntermediateFgColor(v.value<KoColor>());
327 }
328}
329
331{
332 setCurrentNode(connectedNode);
333}
334
336 return node->paintDevice() ? node->paintDevice() : node->original();
337}
338
340{
341 if (connectedNode) {
342 KisPaintDeviceSP device = findValidDevice(connectedNode);
343
344 if (device) {
345 q->disconnect(device, 0);
346 }
347 }
348
349 nodeColorSpace = 0;
350
351 if (node) {
352 KisPaintDeviceSP device = findValidDevice(node);
353
354 nodeColorSpace = device ?
356 node->colorSpace();
357
359
360 if (device) {
361 q->connect(device, SIGNAL(profileChanged(const KoColorProfile*)),
362 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
363 q->connect(device, SIGNAL(colorSpaceChanged(const KoColorSpace*)),
364 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
365 }
366
367 }
368
369 if (!nodeColorSpace) {
371 }
372
373 connectedNode = node;
374 selectPaintingColorSpace();
375}
376
378{
379 KisConfig cfg(true);
381
384 }
385
386 notifyDisplayConfigurationChanged();
387}
388
390{
391 KIS_SAFE_ASSERT_RECOVER(m_d->paintingColorSpace) {
393 }
394
395 return m_d->paintingColorSpace;
396}
397
399{
400 return m_d->nodeColorSpace;
401}
402
404{
405 if (m_d->multiSurfaceDisplayConfig == config) return;
406
407
408
409 m_d->multiSurfaceDisplayConfig = config;
410 m_d->notifyDisplayConfigurationChanged();
411}
412
414{
415 if (m_d->displayFilter && displayFilter &&
416 displayFilter->lockCurrentColorVisualRepresentation()) {
417
418 KoColor color(m_d->intermediateFgColor);
419 displayFilter->approximateInverseTransformation(color.data(), 1);
420 color.convertTo(m_d->paintingColorSpace);
421 m_d->resourceManager->setForegroundColor(color);
422 }
423
424 m_d->displayFilter = displayFilter;
425
426 if (m_d->displayFilter) {
427 m_d->updateIntermediateFgColor(
428 m_d->resourceManager->foregroundColor());
429 }
430
431
432 { // sanity check
433 // KisConfig cfg;
434 // KIS_ASSERT_RECOVER_NOOP(cfg.useOcio() == (bool) m_d->displayFilter);
435 }
436
437 m_d->selectPaintingColorSpace();
438}
439
441{
442 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
443}
444
449
451{
452 return m_d->multiSurfaceDisplayConfig;
453}
454
456{
457 return m_d->multiSurfaceDisplayConfig.options();
458}
459
460QColor KisDisplayColorConverter::toQColor(const KoColor &srcColor, bool proofToPaintColors) const
461{
462 KoColor c(srcColor);
463
464 if (proofToPaintColors && m_d->needsColorProofing(c.colorSpace())) {
465 c.convertTo(m_d->paintingColorSpace, m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
466 }
467
468 if (m_d->useOcio()) {
469 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
470 return QColor(Qt::green);
471 }
472
473 c.convertTo(m_d->ocioInputColorSpace());
474 m_d->displayFilter->filter(c.data(), 1);
475 c.setProfile(m_d->ocioOutputProfile());
476 }
477
478 // we expect the display profile is rgb8, which is BGRA here
479 KIS_ASSERT_RECOVER(m_d->qtWidgetsColorSpace()->pixelSize() == 4) {
480 return QColor(Qt::red);
481 }
482
483 c.convertTo(m_d->qtWidgetsColorSpace(), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
484 const quint8 *p = c.data();
485 return QColor(p[2], p[1], p[0], p[3]);
486}
487
489 const KoID &bitDepthId) const
490{
491 KoColor c(srcColor);
492
493 if (m_d->useOcio()) {
494 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
495 return srcColor;
496 }
497
498 c.convertTo(m_d->ocioInputColorSpace());
499 m_d->displayFilter->filter(c.data(), 1);
500 c.setProfile(m_d->ocioOutputProfile());
501 }
502
503 c.convertTo(m_d->openGLSurfaceColorSpace(bitDepthId), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
504 return c;
505}
506
508{
509 const KoColorProfile *displayProfile = m_d->openGLSurfaceProfile();
510
511 return !m_d->useOcio() &&
513 (!!cs->profile() == !!displayProfile) &&
514 (!cs->profile() ||
515 cs->profile()->uniqueId() == displayProfile->uniqueId());
516}
517
518
520{
521 return m_d->approximateFromQColor(c);
522}
523
524QImage KisDisplayColorConverter::toQImage(KisPaintDeviceSP srcDevice, bool proofPaintColors) const
525{
526 KisPaintDeviceSP device = srcDevice;
527
528 QRect bounds = srcDevice->exactBounds();
529 if (bounds.isEmpty()) return QImage();
530
531 if (proofPaintColors && m_d->needsColorProofing(srcDevice->colorSpace())) {
532 srcDevice->convertTo(paintingColorSpace(), m_d->multiSurfaceDisplayConfig.intent, m_d->multiSurfaceDisplayConfig.conversionFlags);
533 }
534
535 if (m_d->useOcio()) {
536 KIS_ASSERT_RECOVER(m_d->ocioInputColorSpace()->pixelSize() == 16) {
537 return QImage();
538 }
539
540 device = new KisPaintDevice(*srcDevice);
541 device->convertTo(m_d->ocioInputColorSpace());
542
543 KisSequentialIterator it(device, bounds);
544 int numConseqPixels = it.nConseqPixels();
545 while (it.nextPixels(numConseqPixels)) {
546 numConseqPixels = it.nConseqPixels();
547 m_d->displayFilter->filter(it.rawData(), numConseqPixels);
548 }
549
550 device->setProfile(m_d->ocioOutputProfile(), 0);
551 }
552
553 // we expect the display profile is rgb8, which is BGRA here
554 KIS_ASSERT_RECOVER(m_d->qtWidgetsColorSpace()->pixelSize() == 4) {
555 return QImage();
556 }
557
558 return device->convertToQImage(m_d->qtWidgetsProfile(),
559 bounds,
560 m_d->multiSurfaceDisplayConfig.intent,
561 m_d->multiSurfaceDisplayConfig.conversionFlags);
562}
563
564QImage KisDisplayColorConverter::toQImage(const KoColorSpace *srcColorSpace, const quint8 *data, QSize size, bool proofPaintColors) const
565{
566 const int numPixels = size.width() * size.height();
567
568 const KoColorSpace *colorSpace = srcColorSpace;
569 const quint8 *pixels = data;
570
571 QScopedArrayPointer<quint8> proofBuffer;
572
573 if (proofPaintColors && m_d->needsColorProofing(srcColorSpace)) {
574 const int imageSize = numPixels * paintingColorSpace()->pixelSize();
575 proofBuffer.reset(new quint8[imageSize]);
576 colorSpace->convertPixelsTo(pixels, proofBuffer.data(),
578 numPixels,
579 m_d->multiSurfaceDisplayConfig.intent,
580 m_d->multiSurfaceDisplayConfig.conversionFlags);
581 colorSpace = paintingColorSpace();
582 pixels = proofBuffer.data();
583 }
584
585 QScopedArrayPointer<quint8> ocioBuffer;
586 if (m_d->useOcio()) {
587 const int imageSize = numPixels * m_d->ocioInputColorSpace()->pixelSize();
588 ocioBuffer.reset(new quint8[imageSize]);
589 colorSpace->convertPixelsTo(pixels, ocioBuffer.data(),
590 m_d->ocioInputColorSpace(),
591 numPixels,
592 m_d->multiSurfaceDisplayConfig.intent,
593 m_d->multiSurfaceDisplayConfig.conversionFlags);
594 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
595
596 return m_d->ocioOutputColorSpace()->convertToQImage(ocioBuffer.data(), size.width(), size.height(),
597 m_d->qtWidgetsProfile(),
598 m_d->multiSurfaceDisplayConfig.intent,
599 m_d->multiSurfaceDisplayConfig.conversionFlags);
600 }
601
602 return colorSpace->convertToQImage(pixels, size.width(), size.height(),
603 m_d->qtWidgetsProfile(),
604 m_d->multiSurfaceDisplayConfig.intent,
605 m_d->multiSurfaceDisplayConfig.conversionFlags);
606}
607
609 const KoColorSpace *dstColorSpace) const
610{
618 KIS_SAFE_ASSERT_RECOVER_RETURN(device->bounds().isValid());
619
620 if (m_d->useOcio()) {
621 KIS_ASSERT_RECOVER_RETURN(m_d->ocioInputColorSpace()->pixelSize() == 16);
622
623 device->convertTo(m_d->ocioInputColorSpace());
624 m_d->displayFilter->filter(device->data(), device->bounds().width() * device->bounds().height());
625 device->setProfile(m_d->ocioOutputProfile());
626 }
627
628 KIS_SAFE_ASSERT_RECOVER_RETURN(dstColorSpace);
629 device->convertTo(dstColorSpace);
630}
631
633{
634 if (!useOcio()) {
635 return KoColor(qcolor, paintingColorSpace);
636 } else {
637 KoColor color(qcolor, intermediateColorSpace());
638 displayFilter->approximateInverseTransformation(color.data(), 1);
640 return color;
641 }
642
643 qFatal("Must not be reachable");
644 return KoColor();
645}
646
648{
649 KoColor color(srcColor);
650
651 if (useOcio()) {
652 color.convertTo(intermediateColorSpace());
653 displayFilter->approximateForwardTransformation(color.data(), 1);
654 }
655
656 return color.toQColor();
657}
658
659
660KoColor KisDisplayColorConverter::fromHsv(int h, int s, int v, int a) const
661{
662 // generate HSV from sRGB!
663 QColor qcolor(QColor::fromHsv(h, s, v, a));
664 return m_d->approximateFromQColor(qcolor);
665}
666
667void KisDisplayColorConverter::getHsv(const KoColor &srcColor, int *h, int *s, int *v, int *a) const
668{
669 // we are going through sRGB here!
670 QColor color = m_d->approximateToQColor(srcColor);
671 color.getHsv(h, s, v, a);
672}
673
674KoColor KisDisplayColorConverter::fromHsvF(qreal h, qreal s, qreal v, qreal a)
675{
676 // generate HSV from sRGB!
677 QColor qcolor(QColor::fromHsvF(h, s, v, a));
678 return m_d->approximateFromQColor(qcolor);
679}
680
681void KisDisplayColorConverter::getHsvF(const KoColor &srcColor, qreal *h, qreal *s, qreal *v, qreal *a)
682{
683 // we are going through sRGB here!
684 QColor color = m_d->approximateToQColor(srcColor);
685#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
686 color.getHsvF(h, s, v, a);
687#else
688 float fH, fS, fV, fA;
689 fH = *h;
690 fS = *s;
691 fV = *v;
692 if (a) {
693 fA = *a;
694 }
695 color.getHsvF(&fH, &fS, &fV, &fA);
696 *h = fH;
697 *s = fS;
698 *v = fV;
699 if (a) {
700 *a = fA;
701 }
702#endif
703}
704
705KoColor KisDisplayColorConverter::fromHslF(qreal h, qreal s, qreal l, qreal a)
706{
707 // generate HSL from sRGB!
708 QColor qcolor(QColor::fromHslF(h, s, l, a));
709 if (!qcolor.isValid()) {
710 warnKrita << "Could not construct valid color from h" << h << "s" << s << "l" << l << "a" << a;
711 qcolor = Qt::black;
712 }
713 return m_d->approximateFromQColor(qcolor);
714
715}
716
717void KisDisplayColorConverter::getHslF(const KoColor &srcColor, qreal *h, qreal *s, qreal *l, qreal *a)
718{
719 // we are going through sRGB here!
720 QColor color = m_d->approximateToQColor(srcColor);
721#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
722 color.getHslF(h, s, l, a);
723#else
724 float fH, fS, fL, fA;
725 fH = *h;
726 fS = *s;
727 fL = *l;
728 if (a) {
729 fA = *a;
730 }
731 color.getHslF(&fH, &fS, &fL, &fA);
732 *h = fH;
733 *s = fS;
734 *l = fL;
735 if (a) {
736 *a = fA;
737 }
738#endif
739}
740
742{
743 // generate HSI from sRGB!
744 qreal r=0.0;
745 qreal g=0.0;
746 qreal b=0.0;
747 qreal a=1.0;
748 HSIToRGB(h, s, i, &r, &g, &b);
749 QColor qcolor;
750 qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
751 return m_d->approximateFromQColor(qcolor);
752}
753
754void KisDisplayColorConverter::getHsiF(const KoColor &srcColor, qreal *h, qreal *s, qreal *i)
755{
756 // we are going through sRGB here!
757 QColor color = m_d->approximateToQColor(srcColor);
758 qreal r=color.redF();
759 qreal g=color.greenF();
760 qreal b=color.blueF();
761 RGBToHSI(r, g, b, h, s, i);
762}
763
764KoColor KisDisplayColorConverter::fromHsyF(qreal h, qreal s, qreal y, qreal R, qreal G, qreal B, qreal gamma)
765{
766 // generate HSL from sRGB!
767 QVector <qreal> channelValues(3);
768 y = pow(y, gamma);
769 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2], R, G, B);
771 QColor qcolor;
772 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);
773 return m_d->approximateFromQColor(qcolor);
774}
775
776void KisDisplayColorConverter::getHsyF(const KoColor &srcColor, qreal *h, qreal *s, qreal *y, qreal R, qreal G, qreal B, qreal gamma)
777{
778 // we are going through sRGB here!
779 QColor color = m_d->approximateToQColor(srcColor);
780 QVector <qreal> channelValues(3);
781 channelValues[0]=color.redF();
782 channelValues[1]=color.greenF();
783 channelValues[2]=color.blueF();
784 //TODO: if we're going to have KoColor here, remember to check whether the TRC of the profile exists...
786 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y, R, G, B);
787 *y = pow(*y, 1/gamma);
788}
789
790#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"))
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(cond)
Definition kis_assert.h:126
#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