9#include <QGlobalStatic>
41 resourceManager(_resourceManager),
43 paintingColorSpace(0),
67 cachedOcioInputColorSpace = 0;
68 cachedOcioOutputColorSpace = 0;
69 cachedQtWidgetsColorSpace = 0;
70 cachedOpenGLSurfaceColorSpace = 0;
76 return multiSurfaceDisplayConfig.uiProfile;
80 return multiSurfaceDisplayConfig.canvasProfile;
84 return displayFilter && displayFilter->useInternalColorManagement() ?
85 openGLSurfaceProfile() : inputImageProfile;
89 return openGLSurfaceProfile();
93 return cachedOcioInputColorSpace
94 ? cachedOcioInputColorSpace
95 : (cachedOcioInputColorSpace =
100 ocioInputProfile()));
104 return cachedOcioOutputColorSpace
105 ? cachedOcioOutputColorSpace
106 : (cachedOcioOutputColorSpace =
111 ocioOutputProfile()));
116 return cachedQtWidgetsColorSpace
117 ? cachedQtWidgetsColorSpace
118 : (cachedQtWidgetsColorSpace =
123 qtWidgetsProfile()));
128 return cachedOpenGLSurfaceColorSpace
129 ? cachedOpenGLSurfaceColorSpace
130 : (cachedOpenGLSurfaceColorSpace =
135 openGLSurfaceProfile()));
141 return cachedIntermediateColorSpace
142 ? cachedIntermediateColorSpace
143 : (cachedIntermediateColorSpace =
159 inline KoColor approximateFromQColor(
const QColor &qcolor);
160 inline QColor approximateToQColor(
const KoColor &color);
162 void slotCanvasResourceChanged(
int key,
const QVariant &
v);
163 void slotUpdateCurrentNodeColorSpace();
164 void selectPaintingColorSpace();
166 void updateIntermediateFgColor(
const KoColor &color);
168 bool useOcio()
const;
169 bool needsColorProofing(
const KoColorSpace *srcColorSpace)
const;
174 : m_displayColorConverter(displayColorConverter),
175 m_resourceManager(resourceManager)
177 displayColorConverter->connect(displayColorConverter, SIGNAL(displayConfigurationChanged()),
178 this, SIGNAL(displayConfigurationChanged()), Qt::UniqueConnection);
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);
187 return m_displayColorConverter->toQColor(c, proofToPaintColors);
191 return m_displayColorConverter->approximateFromRenderedQColor(c);
195 return m_displayColorConverter->fromHsv(h, s,
v, a);
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);
207 qreal maxValue = chaninfo->
getUIMax();
209 if (m_resourceManager) {
212 maxValue *= std::pow(2.0, -exposure);
219 return m_displayColorConverter->paintingColorSpace();
232 m_d(new
Private(this, resourceManager))
234 connect(
m_d->resourceManager, SIGNAL(canvasResourceChanged(
int,QVariant)),
235 SLOT(slotCanvasResourceChanged(
int,QVariant)));
237 SLOT(selectPaintingColorSpace()));
240 m_d->setCurrentNode(0);
252 m_d->setCurrentNode(0);
261 m_d->inputImageProfile =
266 m_d->notifyDisplayConfigurationChanged();
277 return m_d->displayRenderer.data();
295 bool matchingProfiles = (paintProfile == srcProfile) ||
296 (paintProfile && srcProfile && *paintProfile == *srcProfile);
298 if (matchingProfiles &&
314 color.
convertTo(intermediateColorSpace());
316 intermediateFgColor = color;
323 setCurrentNode(currentNode);
325 updateIntermediateFgColor(
v.value<
KoColor>());
331 setCurrentNode(connectedNode);
344 q->disconnect(device, 0);
361 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
362 q->connect(device, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
363 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
372 connectedNode = node;
373 selectPaintingColorSpace();
385 notifyDisplayConfigurationChanged();
394 return m_d->paintingColorSpace;
399 return m_d->nodeColorSpace;
404 if (
m_d->multiSurfaceDisplayConfig == config)
return;
408 m_d->multiSurfaceDisplayConfig = config;
409 m_d->notifyDisplayConfigurationChanged();
420 m_d->resourceManager->setForegroundColor(color);
425 if (
m_d->displayFilter) {
426 m_d->updateIntermediateFgColor(
427 m_d->resourceManager->foregroundColor());
436 m_d->selectPaintingColorSpace();
441 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
446 return m_d->displayFilter;
451 return m_d->multiSurfaceDisplayConfig;
456 return m_d->multiSurfaceDisplayConfig.options();
463 if (proofToPaintColors &&
m_d->needsColorProofing(c.
colorSpace())) {
464 c.
convertTo(
m_d->paintingColorSpace,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
467 if (
m_d->useOcio()) {
469 return QColor(Qt::green);
473 m_d->displayFilter->filter(c.
data(), 1);
479 return QColor(Qt::red);
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]);
488 const KoID &bitDepthId)
const
492 if (
m_d->useOcio()) {
498 m_d->displayFilter->filter(c.
data(), 1);
502 c.
convertTo(
m_d->openGLSurfaceColorSpace(bitDepthId),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
510 return !
m_d->useOcio() &&
512 (!!cs->
profile() == !!displayProfile) &&
520 return m_d->approximateFromQColor(c);
528 if (
bounds.isEmpty())
return QImage();
530 if (proofPaintColors &&
m_d->needsColorProofing(srcDevice->
colorSpace())) {
534 if (
m_d->useOcio()) {
546 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
559 m_d->multiSurfaceDisplayConfig.intent,
560 m_d->multiSurfaceDisplayConfig.conversionFlags);
565 const int numPixels = size.width() * size.height();
568 const quint8 *pixels = data;
570 QScopedArrayPointer<quint8> proofBuffer;
572 if (proofPaintColors &&
m_d->needsColorProofing(srcColorSpace)) {
574 proofBuffer.reset(
new quint8[imageSize]);
578 m_d->multiSurfaceDisplayConfig.intent,
579 m_d->multiSurfaceDisplayConfig.conversionFlags);
581 pixels = proofBuffer.data();
584 QScopedArrayPointer<quint8> ocioBuffer;
585 if (
m_d->useOcio()) {
586 const int imageSize = numPixels *
m_d->ocioInputColorSpace()->pixelSize();
587 ocioBuffer.reset(
new quint8[imageSize]);
589 m_d->ocioInputColorSpace(),
591 m_d->multiSurfaceDisplayConfig.intent,
592 m_d->multiSurfaceDisplayConfig.conversionFlags);
593 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
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);
601 return colorSpace->
convertToQImage(pixels, size.width(), size.height(),
602 m_d->qtWidgetsProfile(),
603 m_d->multiSurfaceDisplayConfig.intent,
604 m_d->multiSurfaceDisplayConfig.conversionFlags);
619 if (
m_d->useOcio()) {
623 m_d->displayFilter->filter(device->
data(), device->
bounds().width() * device->
bounds().height());
636 KoColor color(qcolor, intermediateColorSpace());
642 qFatal(
"Must not be reachable");
651 color.
convertTo(intermediateColorSpace());
662 QColor qcolor(QColor::fromHsv(h, s,
v, a));
663 return m_d->approximateFromQColor(qcolor);
669 QColor color =
m_d->approximateToQColor(srcColor);
670 color.getHsv(h, s,
v, a);
676 QColor qcolor(QColor::fromHsvF(h, s,
v, a));
677 return m_d->approximateFromQColor(qcolor);
683 QColor color =
m_d->approximateToQColor(srcColor);
684#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
685 color.getHsvF(h, s,
v, a);
687 float fH, fS, fV, fA;
694 color.getHsvF(&fH, &fS, &fV, &fA);
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;
712 return m_d->approximateFromQColor(qcolor);
719 QColor color =
m_d->approximateToQColor(srcColor);
720#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
721 color.getHslF(h, s, l, a);
723 float fH, fS, fL, fA;
730 color.getHslF(&fH, &fS, &fL, &fA);
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);
756 QColor color =
m_d->approximateToQColor(srcColor);
757 qreal r=color.redF();
758 qreal g=color.greenF();
759 qreal b=color.blueF();
766 QVector <qreal> channelValues(3);
768 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2],
R,
G,
B);
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);
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();
785 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y,
R,
G,
B);
786 *y = pow(*y, 1/gamma);
789#include "moc_kis_display_color_converter.cpp"
Eigen::Matrix< double, 4, 2 > R
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
KisDisplayColorConverter * m_displayColorConverter
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
QPointer< KoCanvasResourceProvider > m_resourceManager
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
KisDisplayColorConverter()
KoColor fromHsiF(qreal h, qreal s, qreal i)
KoColorDisplayRendererInterface * displayRendererInterface() const
const KoColorSpace * paintingColorSpace() const
void displayConfigurationChanged()
KisDisplayConfig displayConfig() 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)
~KisDisplayColorConverter() override
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)
bool nextPixels(int numPixels)
ALWAYS_INLINE quint8 * rawData()
int nConseqPixels() const
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)
const KoColorSpace * colorSpace() const
return the current colorSpace
void toQColor(QColor *c) const
a convenience method for the above.
void setProfile(const KoColorProfile *profile)
assign new profile without converting pixel data
#define KIS_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
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
void slotUpdateCurrentNodeColorSpace()
KoColor intermediateFgColor
void setCurrentNode(KisNodeSP node)
QColor approximateToQColor(const KoColor &color)
const KoColorProfile * ocioOutputProfile() const
void notifyDisplayConfigurationChanged()
KisDisplayColorConverter *const q
KoCanvasResourceProvider * resourceManager
KisMultiSurfaceDisplayConfig multiSurfaceDisplayConfig
const KoColorProfile * openGLSurfaceProfile() const
QScopedPointer< KoColorDisplayRendererInterface > displayRenderer
const KoColorSpace * nodeColorSpace
const KoColorSpace * qtWidgetsColorSpace() const
const KoColorSpace * ocioOutputColorSpace() const
const KoColorSpace * ocioInputColorSpace() const
KoColor approximateFromQColor(const QColor &qcolor)
const KoColorSpace * paintingColorSpace
void selectPaintingColorSpace()
const KoColorSpace * intermediateColorSpace() const
const KoColorSpace * openGLSurfaceColorSpace(const KoID &bitDepthId) const
void updateIntermediateFgColor(const KoColor &color)
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