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()));
241 m_d->setCurrentNode(0);
253 m_d->setCurrentNode(0);
262 m_d->inputImageProfile =
267 m_d->notifyDisplayConfigurationChanged();
278 return m_d->displayRenderer.data();
296 bool matchingProfiles = (paintProfile == srcProfile) ||
297 (paintProfile && srcProfile && *paintProfile == *srcProfile);
299 if (matchingProfiles &&
315 color.
convertTo(intermediateColorSpace());
317 intermediateFgColor = color;
324 setCurrentNode(currentNode);
326 updateIntermediateFgColor(
v.value<
KoColor>());
332 setCurrentNode(connectedNode);
345 q->disconnect(device, 0);
362 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
363 q->connect(device, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
364 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
373 connectedNode = node;
374 selectPaintingColorSpace();
386 notifyDisplayConfigurationChanged();
395 return m_d->paintingColorSpace;
400 return m_d->nodeColorSpace;
405 if (
m_d->multiSurfaceDisplayConfig == config)
return;
409 m_d->multiSurfaceDisplayConfig = config;
410 m_d->notifyDisplayConfigurationChanged();
421 m_d->resourceManager->setForegroundColor(color);
426 if (
m_d->displayFilter) {
427 m_d->updateIntermediateFgColor(
428 m_d->resourceManager->foregroundColor());
437 m_d->selectPaintingColorSpace();
442 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
447 return m_d->displayFilter;
452 return m_d->multiSurfaceDisplayConfig;
457 return m_d->multiSurfaceDisplayConfig.options();
464 if (proofToPaintColors &&
m_d->needsColorProofing(c.
colorSpace())) {
465 c.
convertTo(
m_d->paintingColorSpace,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
468 if (
m_d->useOcio()) {
470 return QColor(Qt::green);
474 m_d->displayFilter->filter(c.
data(), 1);
480 return QColor(Qt::red);
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]);
489 const KoID &bitDepthId)
const
493 if (
m_d->useOcio()) {
499 m_d->displayFilter->filter(c.
data(), 1);
503 c.
convertTo(
m_d->openGLSurfaceColorSpace(bitDepthId),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
511 return !
m_d->useOcio() &&
513 (!!cs->
profile() == !!displayProfile) &&
521 return m_d->approximateFromQColor(c);
529 if (
bounds.isEmpty())
return QImage();
531 if (proofPaintColors &&
m_d->needsColorProofing(srcDevice->
colorSpace())) {
535 if (
m_d->useOcio()) {
547 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
560 m_d->multiSurfaceDisplayConfig.intent,
561 m_d->multiSurfaceDisplayConfig.conversionFlags);
566 const int numPixels = size.width() * size.height();
569 const quint8 *pixels = data;
571 QScopedArrayPointer<quint8> proofBuffer;
573 if (proofPaintColors &&
m_d->needsColorProofing(srcColorSpace)) {
575 proofBuffer.reset(
new quint8[imageSize]);
579 m_d->multiSurfaceDisplayConfig.intent,
580 m_d->multiSurfaceDisplayConfig.conversionFlags);
582 pixels = proofBuffer.data();
585 QScopedArrayPointer<quint8> ocioBuffer;
586 if (
m_d->useOcio()) {
587 const int imageSize = numPixels *
m_d->ocioInputColorSpace()->pixelSize();
588 ocioBuffer.reset(
new quint8[imageSize]);
590 m_d->ocioInputColorSpace(),
592 m_d->multiSurfaceDisplayConfig.intent,
593 m_d->multiSurfaceDisplayConfig.conversionFlags);
594 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
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);
602 return colorSpace->
convertToQImage(pixels, size.width(), size.height(),
603 m_d->qtWidgetsProfile(),
604 m_d->multiSurfaceDisplayConfig.intent,
605 m_d->multiSurfaceDisplayConfig.conversionFlags);
620 if (
m_d->useOcio()) {
624 m_d->displayFilter->filter(device->
data(), device->
bounds().width() * device->
bounds().height());
637 KoColor color(qcolor, intermediateColorSpace());
643 qFatal(
"Must not be reachable");
652 color.
convertTo(intermediateColorSpace());
663 QColor qcolor(QColor::fromHsv(h, s,
v, a));
664 return m_d->approximateFromQColor(qcolor);
670 QColor color =
m_d->approximateToQColor(srcColor);
671 color.getHsv(h, s,
v, a);
677 QColor qcolor(QColor::fromHsvF(h, s,
v, a));
678 return m_d->approximateFromQColor(qcolor);
684 QColor color =
m_d->approximateToQColor(srcColor);
685#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
686 color.getHsvF(h, s,
v, a);
688 float fH, fS, fV, fA;
695 color.getHsvF(&fH, &fS, &fV, &fA);
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;
713 return m_d->approximateFromQColor(qcolor);
720 QColor color =
m_d->approximateToQColor(srcColor);
721#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
722 color.getHslF(h, s, l, a);
724 float fH, fS, fL, fA;
731 color.getHslF(&fH, &fS, &fL, &fA);
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);
757 QColor color =
m_d->approximateToQColor(srcColor);
758 qreal r=color.redF();
759 qreal g=color.greenF();
760 qreal b=color.blueF();
767 QVector <qreal> channelValues(3);
769 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2],
R,
G,
B);
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);
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();
786 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y,
R,
G,
B);
787 *y = pow(*y, 1/gamma);
790#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"))
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(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