9#include <QGlobalStatic>
35#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
36#include <QGuiApplication>
46 resourceManager(_resourceManager),
48 paintingColorSpace(0),
72 cachedOcioInputColorSpace = 0;
73 cachedOcioOutputColorSpace = 0;
74 cachedQtWidgetsColorSpace = 0;
75 cachedOpenGLSurfaceColorSpace = 0;
81 return multiSurfaceDisplayConfig.uiProfile;
85 return multiSurfaceDisplayConfig.canvasProfile;
89 return displayFilter && displayFilter->useInternalColorManagement() ?
90 openGLSurfaceProfile() : inputImageProfile;
94 return openGLSurfaceProfile();
98 return cachedOcioInputColorSpace
99 ? cachedOcioInputColorSpace
100 : (cachedOcioInputColorSpace =
105 ocioInputProfile()));
109 return cachedOcioOutputColorSpace
110 ? cachedOcioOutputColorSpace
111 : (cachedOcioOutputColorSpace =
116 ocioOutputProfile()));
121 return cachedQtWidgetsColorSpace
122 ? cachedQtWidgetsColorSpace
123 : (cachedQtWidgetsColorSpace =
128 qtWidgetsProfile()));
133 return cachedOpenGLSurfaceColorSpace
134 ? cachedOpenGLSurfaceColorSpace
135 : (cachedOpenGLSurfaceColorSpace =
140 openGLSurfaceProfile()));
146 return cachedIntermediateColorSpace
147 ? cachedIntermediateColorSpace
148 : (cachedIntermediateColorSpace =
167 inline KoColor approximateFromQColor(
const QColor &qcolor);
168 inline QColor approximateToQColor(
const KoColor &color);
170 void slotCanvasResourceChanged(
int key,
const QVariant &
v);
171 void slotUpdateCurrentNodeColorSpace();
172 void selectPaintingColorSpace();
174 void updateIntermediateFgColor(
const KoColor &color);
176 bool useOcio()
const;
177 bool needsColorProofing(
const KoColorSpace *srcColorSpace)
const;
182 : m_displayColorConverter(displayColorConverter),
183 m_resourceManager(resourceManager)
185 displayColorConverter->connect(displayColorConverter, SIGNAL(displayConfigurationChanged()),
186 this, SIGNAL(displayConfigurationChanged()), Qt::UniqueConnection);
189 QImage
toQImage(
const KoColorSpace *srcColorSpace,
const quint8 *data, QSize size,
bool proofPaintColors =
false)
const override {
190 QImage result = m_displayColorConverter->toQImage(srcColorSpace, data, size, proofPaintColors);
195 return m_displayColorConverter->toQColor(c, proofToPaintColors);
199 return m_displayColorConverter->approximateFromRenderedQColor(c);
203 return m_displayColorConverter->fromHsv(h, s,
v, a);
206 void getHsv(
const KoColor &srcColor,
int *h,
int *s,
int *
v,
int *a)
const override {
207 m_displayColorConverter->getHsv(srcColor, h, s,
v, a);
215 qreal maxValue = chaninfo->
getUIMax();
217 if (m_resourceManager) {
220 maxValue *= std::pow(2.0, -exposure);
227 return m_displayColorConverter->paintingColorSpace();
231 return m_displayColorConverter->convertColorToDisplayColorSpace(c);
238 QImage destination = m_displayColorConverter->convertImageToDisplayColorSpace(srcDevice);
239 destination.setDevicePixelRatio(
source.devicePixelRatio());
244 return m_displayColorConverter->handlePaletteForDisplayColorSpace();
248 return m_displayColorConverter->systemPaletteForDisplayColorSpace();
261 m_d(new
Private(this, resourceManager))
263 connect(
m_d->resourceManager, SIGNAL(canvasResourceChanged(
int,QVariant)),
264 SLOT(slotCanvasResourceChanged(
int,QVariant)));
266 SLOT(selectPaintingColorSpace()));
270 m_d->setCurrentNode(0);
284 m_d->setCurrentNode(0);
293 m_d->inputImageProfile =
298 m_d->notifyDisplayConfigurationChanged();
309 return m_d->displayRenderer.data();
327 bool matchingProfiles = (paintProfile == srcProfile) ||
328 (paintProfile && srcProfile && *paintProfile == *srcProfile);
330 if (matchingProfiles &&
346 color.
convertTo(intermediateColorSpace());
348 intermediateFgColor = color;
355 setCurrentNode(currentNode);
357 updateIntermediateFgColor(
v.value<
KoColor>());
363 setCurrentNode(connectedNode);
394 QPalette pal = qApp->palette();
395 for (
int r = 0; r < QPalette::NColorRoles; r++) {
396 for (
int cg = 0; cg < QPalette::NColorGroups; cg++) {
397 c.
fromQColor(pal.brush(QPalette::ColorGroup(cg), QPalette::ColorRole(r)).color());
403 m_d->systemPalette = pal;
416 q->disconnect(device, 0);
433 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
434 q->connect(device, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
435 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
444 connectedNode = node;
445 selectPaintingColorSpace();
457 notifyDisplayConfigurationChanged();
466 return m_d->paintingColorSpace;
471 return m_d->nodeColorSpace;
476 if (
m_d->multiSurfaceDisplayConfig == config)
return;
480 m_d->multiSurfaceDisplayConfig = config;
481 m_d->notifyDisplayConfigurationChanged();
492 m_d->resourceManager->setForegroundColor(color);
497 if (
m_d->displayFilter) {
498 m_d->updateIntermediateFgColor(
499 m_d->resourceManager->foregroundColor());
508 m_d->selectPaintingColorSpace();
513 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
518 return m_d->displayFilter;
523 return m_d->multiSurfaceDisplayConfig;
528 return m_d->multiSurfaceDisplayConfig.options();
535 if (proofToPaintColors &&
m_d->needsColorProofing(c.
colorSpace())) {
536 c.
convertTo(
m_d->paintingColorSpace,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
539 if (
m_d->useOcio()) {
541 return QColor(Qt::green);
545 m_d->displayFilter->filter(c.
data(), 1);
551 return QColor(Qt::red);
554 c.
convertTo(
m_d->qtWidgetsColorSpace(),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
555 const quint8 *
p = c.
data();
556 return QColor(
p[2],
p[1],
p[0],
p[3]);
560 const KoID &bitDepthId)
const
564 if (
m_d->useOcio()) {
570 m_d->displayFilter->filter(c.
data(), 1);
574 c.
convertTo(
m_d->openGLSurfaceColorSpace(bitDepthId),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
582 return !
m_d->useOcio() &&
584 (!!cs->
profile() == !!displayProfile) &&
592 return m_d->approximateFromQColor(c);
600 if (
bounds.isEmpty())
return QImage();
602 if (proofPaintColors &&
m_d->needsColorProofing(srcDevice->
colorSpace())) {
606 if (
m_d->useOcio()) {
618 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
631 m_d->multiSurfaceDisplayConfig.intent,
632 m_d->multiSurfaceDisplayConfig.conversionFlags);
637 const int numPixels = size.width() * size.height();
640 const quint8 *pixels = data;
642 QScopedArrayPointer<quint8> proofBuffer;
644 if (proofPaintColors &&
m_d->needsColorProofing(srcColorSpace)) {
646 proofBuffer.reset(
new quint8[imageSize]);
650 m_d->multiSurfaceDisplayConfig.intent,
651 m_d->multiSurfaceDisplayConfig.conversionFlags);
653 pixels = proofBuffer.data();
656 QScopedArrayPointer<quint8> ocioBuffer;
657 if (
m_d->useOcio()) {
658 const int imageSize = numPixels *
m_d->ocioInputColorSpace()->pixelSize();
659 ocioBuffer.reset(
new quint8[imageSize]);
661 m_d->ocioInputColorSpace(),
663 m_d->multiSurfaceDisplayConfig.intent,
664 m_d->multiSurfaceDisplayConfig.conversionFlags);
665 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
667 return m_d->ocioOutputColorSpace()->convertToQImage(ocioBuffer.data(), size.width(), size.height(),
668 m_d->qtWidgetsProfile(),
669 m_d->multiSurfaceDisplayConfig.intent,
670 m_d->multiSurfaceDisplayConfig.conversionFlags);
673 return colorSpace->
convertToQImage(pixels, size.width(), size.height(),
674 m_d->qtWidgetsProfile(),
675 m_d->multiSurfaceDisplayConfig.intent,
676 m_d->multiSurfaceDisplayConfig.conversionFlags);
691 if (
m_d->useOcio()) {
695 m_d->displayFilter->filter(device->
data(), device->
bounds().width() * device->
bounds().height());
721 for (
int ch = 0; ch < norm.size(); ch++) {
729 return QColor::fromRgbF(sorted[0], sorted[1], sorted[2], sorted[3]);
737 if (
m_d->useOcio() && applyOcio) {
742 conversionDevice->
convertTo(
m_d->ocioInputColorSpace());
747 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
753 return conversionDevice->
convertToQImage(
m_d->openGLSurfaceProfile(), s,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
758 return m_d->handlePalette;
763 return m_d->systemPalette;
771 KoColor color(qcolor, intermediateColorSpace());
777 qFatal(
"Must not be reachable");
786 color.
convertTo(intermediateColorSpace());
797 QColor qcolor(QColor::fromHsv(h, s,
v, a));
798 return m_d->approximateFromQColor(qcolor);
804 QColor color =
m_d->approximateToQColor(srcColor);
805 color.getHsv(h, s,
v, a);
811 QColor qcolor(QColor::fromHsvF(h, s,
v, a));
812 return m_d->approximateFromQColor(qcolor);
818 QColor color =
m_d->approximateToQColor(srcColor);
819#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
820 color.getHsvF(h, s,
v, a);
822 float fH, fS, fV, fA;
829 color.getHsvF(&fH, &fS, &fV, &fA);
842 QColor qcolor(QColor::fromHslF(h, s, l, a));
843 if (!qcolor.isValid()) {
844 warnKrita <<
"Could not construct valid color from h" << h <<
"s" << s <<
"l" << l <<
"a" << a;
847 return m_d->approximateFromQColor(qcolor);
854 QColor color =
m_d->approximateToQColor(srcColor);
855#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
856 color.getHslF(h, s, l, a);
858 float fH, fS, fL, fA;
865 color.getHslF(&fH, &fS, &fL, &fA);
884 qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
885 return m_d->approximateFromQColor(qcolor);
891 QColor color =
m_d->approximateToQColor(srcColor);
892 qreal r=color.redF();
893 qreal g=color.greenF();
894 qreal b=color.blueF();
901 QVector <qreal> channelValues(3);
903 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2],
R,
G,
B);
906 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);
907 return m_d->approximateFromQColor(qcolor);
913 QColor color =
m_d->approximateToQColor(srcColor);
914 QVector <qreal> channelValues(3);
915 channelValues[0]=color.redF();
916 channelValues[1]=color.greenF();
917 channelValues[2]=color.blueF();
920 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y,
R,
G,
B);
921 *y = pow(*y, 1/gamma);
924#include "moc_kis_display_color_converter.cpp"
Eigen::Matrix< double, 4, 2 > R
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
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.
KisHandlePalette handlePaletteForDisplayColorSpace() const override
handlePaletteForDisplayColorSpace
QImage convertImageToDisplayColorSpace(const QImage source) const override
convertImageToDisplayColorSpace
QPalette systemPaletteForDisplayColorSpace() const override
systemPaletteForDisplayColorSpace
QColor convertColorToDisplayColorSpace(KoColor c) const override
convertColorToDisplayColorSpace
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)
KisHandlePalette handlePaletteForDisplayColorSpace() const
handlePaletteForDisplayColorSpace
std::pair< KoColorConversionTransformation::Intent, KoColorConversionTransformation::ConversionFlags > ConversionOptions
KisMultiSurfaceDisplayConfig multiSurfaceDisplayConfig() const
KisDisplayColorConverter()
KoColor fromHsiF(qreal h, qreal s, qreal i)
KoColorDisplayRendererInterface * displayRendererInterface() const
QColor convertColorToDisplayColorSpace(const KoColor color, bool applyOcio=false) const
convertColorToDisplayColorSpace This applies displayfiltering to the given KoColor,...
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
QPalette systemPaletteForDisplayColorSpace() const
systemPaletteForDisplayColorSpace
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)
Q_SLOT void updatePalettes()
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
QImage convertImageToDisplayColorSpace(KisPaintDeviceSP srcDevice, QRect source=QRect(), bool applyOcio=false) const
convertImageToDisplayColorSpace Same as convertColorToDisplayColorSpace, but then for a KisPaintDevic...
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
void convertFromQImage(const QImage &image, const KoColorProfile *profile, qint32 offsetX=0, qint32 offsetY=0)
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
qint32 displayPosition() 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
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) 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)
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
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_VALUE(cond, val)
#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.
rgba palette[MAX_PALETTE]
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
KisHandlePalette handlePalette
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