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);
287 m_d->setCurrentNode(0);
296 m_d->inputImageProfile =
301 m_d->notifyDisplayConfigurationChanged();
312 return m_d->displayRenderer.data();
330 bool matchingProfiles = (paintProfile == srcProfile) ||
331 (paintProfile && srcProfile && *paintProfile == *srcProfile);
333 if (matchingProfiles &&
349 color.
convertTo(intermediateColorSpace());
351 intermediateFgColor = color;
358 setCurrentNode(currentNode);
360 updateIntermediateFgColor(
v.value<
KoColor>());
366 setCurrentNode(connectedNode);
397 QPalette pal = qApp->palette();
398 for (
int r = 0; r < QPalette::NColorRoles; r++) {
399 for (
int cg = 0; cg < QPalette::NColorGroups; cg++) {
400 c.
fromQColor(pal.brush(QPalette::ColorGroup(cg), QPalette::ColorRole(r)).color());
406 m_d->systemPalette = pal;
419 q->disconnect(device, 0);
436 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
437 q->connect(device, SIGNAL(colorSpaceChanged(
const KoColorSpace*)),
438 SLOT(slotUpdateCurrentNodeColorSpace()), Qt::UniqueConnection);
447 connectedNode = node;
448 selectPaintingColorSpace();
460 notifyDisplayConfigurationChanged();
469 return m_d->paintingColorSpace;
474 return m_d->nodeColorSpace;
479 if (
m_d->multiSurfaceDisplayConfig == config)
return;
483 m_d->multiSurfaceDisplayConfig = config;
484 m_d->notifyDisplayConfigurationChanged();
495 m_d->resourceManager->setForegroundColor(color);
500 if (
m_d->displayFilter) {
501 m_d->updateIntermediateFgColor(
502 m_d->resourceManager->foregroundColor());
511 m_d->selectPaintingColorSpace();
516 return m_d->multiSurfaceDisplayConfig.uiDisplayConfig();
521 return m_d->displayFilter;
526 return m_d->multiSurfaceDisplayConfig;
531 return m_d->multiSurfaceDisplayConfig.options();
538 if (proofToPaintColors &&
m_d->needsColorProofing(c.
colorSpace())) {
539 c.
convertTo(
m_d->paintingColorSpace,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
542 if (
m_d->useOcio()) {
544 return QColor(Qt::green);
548 m_d->displayFilter->filter(c.
data(), 1);
554 return QColor(Qt::red);
557 c.
convertTo(
m_d->qtWidgetsColorSpace(),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
558 const quint8 *
p = c.
data();
559 return QColor(
p[2],
p[1],
p[0],
p[3]);
563 const KoID &bitDepthId)
const
567 if (
m_d->useOcio()) {
573 m_d->displayFilter->filter(c.
data(), 1);
577 c.
convertTo(
m_d->openGLSurfaceColorSpace(bitDepthId),
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
585 return !
m_d->useOcio() &&
587 (!!cs->
profile() == !!displayProfile) &&
595 return m_d->approximateFromQColor(c);
603 if (
bounds.isEmpty())
return QImage();
605 if (proofPaintColors &&
m_d->needsColorProofing(srcDevice->
colorSpace())) {
609 if (
m_d->useOcio()) {
621 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
634 m_d->multiSurfaceDisplayConfig.intent,
635 m_d->multiSurfaceDisplayConfig.conversionFlags);
640 const int numPixels = size.width() * size.height();
643 const quint8 *pixels = data;
645 QScopedArrayPointer<quint8> proofBuffer;
647 if (proofPaintColors &&
m_d->needsColorProofing(srcColorSpace)) {
649 proofBuffer.reset(
new quint8[imageSize]);
653 m_d->multiSurfaceDisplayConfig.intent,
654 m_d->multiSurfaceDisplayConfig.conversionFlags);
656 pixels = proofBuffer.data();
659 QScopedArrayPointer<quint8> ocioBuffer;
660 if (
m_d->useOcio()) {
661 const int imageSize = numPixels *
m_d->ocioInputColorSpace()->pixelSize();
662 ocioBuffer.reset(
new quint8[imageSize]);
664 m_d->ocioInputColorSpace(),
666 m_d->multiSurfaceDisplayConfig.intent,
667 m_d->multiSurfaceDisplayConfig.conversionFlags);
668 m_d->displayFilter->filter(ocioBuffer.data(), numPixels);
670 return m_d->ocioOutputColorSpace()->convertToQImage(ocioBuffer.data(), size.width(), size.height(),
671 m_d->qtWidgetsProfile(),
672 m_d->multiSurfaceDisplayConfig.intent,
673 m_d->multiSurfaceDisplayConfig.conversionFlags);
676 return colorSpace->
convertToQImage(pixels, size.width(), size.height(),
677 m_d->qtWidgetsProfile(),
678 m_d->multiSurfaceDisplayConfig.intent,
679 m_d->multiSurfaceDisplayConfig.conversionFlags);
694 if (
m_d->useOcio()) {
698 m_d->displayFilter->filter(device->
data(), device->
bounds().width() * device->
bounds().height());
724 for (
int ch = 0; ch < norm.size(); ch++) {
732 return QColor::fromRgbF(sorted[0], sorted[1], sorted[2], sorted[3]);
740 if (
m_d->useOcio() && applyOcio) {
745 conversionDevice->
convertTo(
m_d->ocioInputColorSpace());
750 m_d->displayFilter->filter(it.
rawData(), numConseqPixels);
756 return conversionDevice->
convertToQImage(
m_d->openGLSurfaceProfile(), s,
m_d->multiSurfaceDisplayConfig.intent,
m_d->multiSurfaceDisplayConfig.conversionFlags);
761 return m_d->handlePalette;
766 return m_d->systemPalette;
774 KoColor color(qcolor, intermediateColorSpace());
780 qFatal(
"Must not be reachable");
789 color.
convertTo(intermediateColorSpace());
800 QColor qcolor(QColor::fromHsv(h, s,
v, a));
801 return m_d->approximateFromQColor(qcolor);
807 QColor color =
m_d->approximateToQColor(srcColor);
808 color.getHsv(h, s,
v, a);
814 QColor qcolor(QColor::fromHsvF(h, s,
v, a));
815 return m_d->approximateFromQColor(qcolor);
821 QColor color =
m_d->approximateToQColor(srcColor);
822#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
823 color.getHsvF(h, s,
v, a);
825 float fH, fS, fV, fA;
832 color.getHsvF(&fH, &fS, &fV, &fA);
845 QColor qcolor(QColor::fromHslF(h, s, l, a));
846 if (!qcolor.isValid()) {
847 warnKrita <<
"Could not construct valid color from h" << h <<
"s" << s <<
"l" << l <<
"a" << a;
850 return m_d->approximateFromQColor(qcolor);
857 QColor color =
m_d->approximateToQColor(srcColor);
858#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
859 color.getHslF(h, s, l, a);
861 float fH, fS, fL, fA;
868 color.getHslF(&fH, &fS, &fL, &fA);
887 qcolor.setRgbF(qBound(0.0,r,1.0), qBound(0.0,g,1.0), qBound(0.0,b,1.0), a);
888 return m_d->approximateFromQColor(qcolor);
894 QColor color =
m_d->approximateToQColor(srcColor);
895 qreal r=color.redF();
896 qreal g=color.greenF();
897 qreal b=color.blueF();
904 QVector <qreal> channelValues(3);
906 HSYToRGB(h, s, y, &channelValues[0], &channelValues[1], &channelValues[2],
R,
G,
B);
909 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);
910 return m_d->approximateFromQColor(qcolor);
916 QColor color =
m_d->approximateToQColor(srcColor);
917 QVector <qreal> channelValues(3);
918 channelValues[0]=color.redF();
919 channelValues[1]=color.greenF();
920 channelValues[2]=color.blueF();
923 RGBToHSY(channelValues[0], channelValues[1], channelValues[2], h, s, y,
R,
G,
B);
924 *y = pow(*y, 1/gamma);
927#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.
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