9#include <QGlobalStatic>
37#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
38#include <QGuiApplication>
48 resourceManager(_resourceManager),
50 paintingColorSpace(0),
74 cachedOcioInputColorSpace = 0;
75 cachedOcioOutputColorSpace = 0;
76 cachedQtWidgetsColorSpace = 0;
77 cachedOpenGLSurfaceColorSpace = 0;
83 return multiSurfaceDisplayConfig.uiProfile;
87 return multiSurfaceDisplayConfig.canvasProfile;
91 return displayFilter && displayFilter->useInternalColorManagement() ?
92 openGLSurfaceProfile() : inputImageProfile;
96 return openGLSurfaceProfile();
100 return cachedOcioInputColorSpace
101 ? cachedOcioInputColorSpace
102 : (cachedOcioInputColorSpace =
107 ocioInputProfile()));
111 return cachedOcioOutputColorSpace
112 ? cachedOcioOutputColorSpace
113 : (cachedOcioOutputColorSpace =
118 ocioOutputProfile()));
123 return cachedQtWidgetsColorSpace
124 ? cachedQtWidgetsColorSpace
125 : (cachedQtWidgetsColorSpace =
130 qtWidgetsProfile()));
135 return cachedOpenGLSurfaceColorSpace
136 ? cachedOpenGLSurfaceColorSpace
137 : (cachedOpenGLSurfaceColorSpace =
142 openGLSurfaceProfile()));
148 return cachedIntermediateColorSpace
149 ? cachedIntermediateColorSpace
150 : (cachedIntermediateColorSpace =
169 inline KoColor approximateFromQColor(
const QColor &qcolor);
170 inline QColor approximateToQColor(
const KoColor &color);
172 void slotCanvasResourceChanged(
int key,
const QVariant &
v);
173 void slotUpdateCurrentNodeColorSpace();
174 void selectPaintingColorSpace();
176 void updateIntermediateFgColor(
const KoColor &color);
178 bool useOcio()
const;
179 bool needsColorProofing(
const KoColorSpace *srcColorSpace)
const;
184 : m_displayColorConverter(displayColorConverter),
185 m_resourceManager(resourceManager)
187 displayColorConverter->connect(displayColorConverter, SIGNAL(displayConfigurationChanged()),
188 this, SIGNAL(displayConfigurationChanged()), Qt::UniqueConnection);
191 QImage
toQImage(
const KoColorSpace *srcColorSpace,
const quint8 *data, QSize size,
bool proofPaintColors =
false)
const override {
192 QImage result = m_displayColorConverter->toQImage(srcColorSpace, data, size, proofPaintColors);
197 return m_displayColorConverter->toQColor(c, proofToPaintColors);
201 return m_displayColorConverter->approximateFromRenderedQColor(c);
205 return m_displayColorConverter->fromHsv(h, s,
v, a);
208 void getHsv(
const KoColor &srcColor,
int *h,
int *s,
int *
v,
int *a)
const override {
209 m_displayColorConverter->getHsv(srcColor, h, s,
v, a);
217 qreal maxValue = chaninfo->
getUIMax();
219 if (m_resourceManager) {
222 maxValue *= std::pow(2.0, -exposure);
229 return m_displayColorConverter->paintingColorSpace();
233 return m_displayColorConverter->convertColorToDisplayColorSpace(c);
240 QImage destination = m_displayColorConverter->convertImageToDisplayColorSpace(srcDevice);
241 destination.setDevicePixelRatio(
source.devicePixelRatio());
246 return m_displayColorConverter->handlePaletteForDisplayColorSpace();
250 return m_displayColorConverter->systemPaletteForDisplayColorSpace();
263 m_d(new
Private(this, resourceManager))
265 connect(
m_d->resourceManager, SIGNAL(canvasResourceChanged(
int,QVariant)),
266 SLOT(slotCanvasResourceChanged(
int,QVariant)));
268 SLOT(selectPaintingColorSpace()));
272 m_d->setCurrentNode(0);
277 if(reactOnThemeChange)
289 m_d->setCurrentNode(0);
298 m_d->inputImageProfile =
303 m_d->notifyDisplayConfigurationChanged();
314 return m_d->displayRenderer.data();
332 bool matchingProfiles = (paintProfile == srcProfile) ||
333 (paintProfile && srcProfile && *paintProfile == *srcProfile);
335 if (matchingProfiles &&
351 color.
convertTo(intermediateColorSpace());
353 intermediateFgColor = color;
360 setCurrentNode(currentNode);
362 updateIntermediateFgColor(
v.value<
KoColor>());
368 setCurrentNode(connectedNode);
399 QPalette pal = qApp->palette();
400 for (
int r = 0; r < QPalette::NColorRoles; r++) {
401 for (
int cg = 0; cg < QPalette::NColorGroups; cg++) {
402 c.
fromQColor(pal.brush(QPalette::ColorGroup(cg), QPalette::ColorRole(r)).color());
407 m_d->handlePalette = palette;
408 m_d->systemPalette = pal;
421 q->disconnect(device, 0);
438 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
439 q->connect(device, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
440 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
449 connectedNode = node;
450 selectPaintingColorSpace();
462 notifyDisplayConfigurationChanged();
471 return m_d->paintingColorSpace;
476 return m_d->nodeColorSpace;
481 if (
m_d->multiSurfaceDisplayConfig == config)
return;
485 m_d->multiSurfaceDisplayConfig = config;
486 m_d->notifyDisplayConfigurationChanged();
497 m_d->resourceManager->setForegroundColor(color);
502 if (
m_d->displayFilter) {
503 m_d->updateIntermediateFgColor(
504 m_d->resourceManager->foregroundColor());
513 m_d->selectPaintingColorSpace();
518 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
523 return m_d->displayFilter;
528 return m_d->multiSurfaceDisplayConfig;
533 return m_d->multiSurfaceDisplayConfig.options();
540 if (proofToPaintColors &&
m_d->needsColorProofing(c.
colorSpace())) {
541 c.
convertTo(
m_d->paintingColorSpace,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
544 if (
m_d->useOcio()) {
546 return QColor(Qt::green);
550 m_d->displayFilter->filter(c.
data(), 1);
556 return QColor(Qt::red);
559 c.
convertTo(
m_d->qtWidgetsColorSpace(),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
560 const quint8 *
p = c.
data();
561 return QColor(
p[2],
p[1],
p[0],
p[3]);
565 const KoID &bitDepthId)
const
569 if (
m_d->useOcio()) {
575 m_d->displayFilter->filter(c.
data(), 1);
579 c.
convertTo(
m_d->openGLSurfaceColorSpace(bitDepthId),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
587 return !
m_d->useOcio() &&
589 (!!cs->
profile() == !!displayProfile) &&
597 return m_d->approximateFromQColor(c);
605 if (
bounds.isEmpty())
return QImage();
607 if (proofPaintColors &&
m_d->needsColorProofing(srcDevice->
colorSpace())) {
611 if (
m_d->useOcio()) {
623 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
636 m_d->multiSurfaceDisplayConfig.intent,
637 m_d->multiSurfaceDisplayConfig.conversionFlags);
642 const int numPixels = size.width() * size.height();
645 const quint8 *pixels = data;
647 QScopedArrayPointer<quint8> proofBuffer;
649 if (proofPaintColors &&
m_d->needsColorProofing(srcColorSpace)) {
651 proofBuffer.reset(
new quint8[imageSize]);
655 m_d->multiSurfaceDisplayConfig.intent,
656 m_d->multiSurfaceDisplayConfig.conversionFlags);
658 pixels = proofBuffer.data();
661 QScopedArrayPointer<quint8> ocioBuffer;
662 if (
m_d->useOcio()) {
663 const int imageSize = numPixels *
m_d->ocioInputColorSpace()->pixelSize();
664 ocioBuffer.reset(
new quint8[imageSize]);
666 m_d->ocioInputColorSpace(),
668 m_d->multiSurfaceDisplayConfig.intent,
669 m_d->multiSurfaceDisplayConfig.conversionFlags);
670 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
672 return m_d->ocioOutputColorSpace()->convertToQImage(ocioBuffer.data(), size.width(), size.height(),
673 m_d->qtWidgetsProfile(),
674 m_d->multiSurfaceDisplayConfig.intent,
675 m_d->multiSurfaceDisplayConfig.conversionFlags);
678 return colorSpace->
convertToQImage(pixels, size.width(), size.height(),
679 m_d->qtWidgetsProfile(),
680 m_d->multiSurfaceDisplayConfig.intent,
681 m_d->multiSurfaceDisplayConfig.conversionFlags);
696 if (
m_d->useOcio()) {
700 m_d->displayFilter->filter(device->
data(), device->
bounds().width() * device->
bounds().height());
726 for (
int ch = 0; ch < norm.size(); ch++) {
734 return QColor::fromRgbF(sorted[0], sorted[1], sorted[2], sorted[3]);
742 if (
m_d->useOcio() && applyOcio) {
747 conversionDevice->
convertTo(
m_d->ocioInputColorSpace());
752 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
758 return conversionDevice->
convertToQImage(
m_d->openGLSurfaceProfile(), s,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
763 return m_d->handlePalette;
768 return m_d->systemPalette;
776 KoColor color(qcolor, intermediateColorSpace());
782 qFatal(
"Must not be reachable");
791 color.
convertTo(intermediateColorSpace());
802 QColor qcolor(QColor::fromHsv(h, s,
v, a));
803 return m_d->approximateFromQColor(qcolor);
809 QColor color =
m_d->approximateToQColor(srcColor);
810 color.getHsv(h, s,
v, a);
816 QColor qcolor(QColor::fromHsvF(h, s,
v, a));
817 return m_d->approximateFromQColor(qcolor);
823 QColor color =
m_d->approximateToQColor(srcColor);
824#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
825 color.getHsvF(h, s,
v, a);
827 float fH, fS, fV, fA;
834 color.getHsvF(&fH, &fS, &fV, &fA);
847 QColor qcolor(QColor::fromHslF(h, s, l, a));
848 if (!qcolor.isValid()) {
849 warnKrita <<
"Could not construct valid color from h" << h <<
"s" << s <<
"l" << l <<
"a" << a;
852 return m_d->approximateFromQColor(qcolor);
859 QColor color =
m_d->approximateToQColor(srcColor);
860#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
861 color.getHslF(h, s, l, a);
863 float fH, fS, fL, fA;
870 color.getHslF(&fH, &fS, &fL, &fA);
889 qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
890 return m_d->approximateFromQColor(qcolor);
896 QColor color =
m_d->approximateToQColor(srcColor);
897 qreal r=color.redF();
898 qreal g=color.greenF();
899 qreal b=color.blueF();
906 QVector <qreal> channelValues(3);
908 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2],
R,
G,
B);
911 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);
912 return m_d->approximateFromQColor(qcolor);
918 QColor color =
m_d->approximateToQColor(srcColor);
919 QVector <qreal> channelValues(3);
920 channelValues[0]=color.redF();
921 channelValues[1]=color.greenF();
922 channelValues[2]=color.blueF();
925 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y,
R,
G,
B);
926 *y = pow(*y, 1/gamma);
929#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)
static KisPart * instance()
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.
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
QColor highlightOutlineColor
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