Krita Source Code Documentation
Loading...
Searching...
No Matches
KoColorSpace.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2005 Boudewijn Rempt <boud@valdyas.org>
3 * SPDX-FileCopyrightText: 2006-2007 Cyrille Berger <cberger@cberger.net>
4 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me>
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8#ifndef KOCOLORSPACE_H
9#define KOCOLORSPACE_H
10
11#include <climits>
12
13#include <QImage>
14#include <QHash>
15#include <QVector>
16#include <QList>
17
18#include <boost/operators.hpp>
22#include "KoCompositeOp.h"
23#include "KisDitherOp.h"
24#include <KoID.h>
25#include "kritapigment_export.h"
26
27class QDomDocument;
28class QDomElement;
29class KoChannelInfo;
30class KoColorProfile;
32class QBitArray;
33
39
46
47class KoMixColorsOp;
48class KoConvolutionOp;
49
77class KRITAPIGMENT_EXPORT KoColorSpace : public boost::equality_comparable<KoColorSpace>
78{
80 friend class KoColorSpaceFactory;
81protected:
84
85public:
86
88 KoColorSpace(const QString &id, const QString &name, KoMixColorsOp *mixColorsOp, KoConvolutionOp *convolutionOp);
89
90 virtual bool operator==(const KoColorSpace& rhs) const;
91protected:
92 virtual ~KoColorSpace();
93
94public:
95 //========== Gamut and other basic info ===================================//
96 /*
97 * @returns QPolygonF with 5*channel samples converted to xyY.
98 * maybe convert to 3d space in future?
99 */
100 QPolygonF gamutXYY() const;
101
102 /*
103 * @returns a polygon with 5 samples per channel converted to xyY, but unlike
104 * gamutxyY it focuses on the luminance. This then can be used to visualise
105 * the approximate trc of a given colorspace.
106 */
107 QPolygonF estimatedTRCXYY() const;
108
109 QVector <qreal> lumaCoefficients() const;
110
111 //========== Channels =====================================================//
112
117
121 virtual quint32 channelCount() const = 0;
122
126 virtual quint32 alphaPos() const = 0;
127
132 virtual quint32 colorChannelCount() const = 0;
133
144 QBitArray channelFlags(bool color = true, bool alpha = false) const;
145
149 virtual quint32 pixelSize() const = 0;
150
154 virtual QString channelValueText(const quint8 *pixel, quint32 channelIndex) const = 0;
155
161 virtual QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) const = 0;
162
167 virtual void normalisedChannelsValue(const quint8 *pixel, QVector<float> &channels) const = 0;
168
172 virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector<float> &values) const = 0;
173
179 virtual quint8 scaleToU8(const quint8 * srcPixel, qint32 channelPos) const = 0;
180
186 virtual void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) const = 0;
187
188 //========== Identification ===============================================//
189
195 QString id() const;
196
201 QString name() const;
202
207 virtual KoID colorModelId() const = 0;
212 virtual KoID colorDepthId() const = 0;
213
217 virtual bool profileIsCompatible(const KoColorProfile* profile) const = 0;
218
229 virtual bool willDegrade(ColorSpaceIndependence independence) const = 0;
230
231 //========== Capabilities =================================================//
232
238 virtual bool hasCompositeOp(const QString & id, const KoColorSpace *srcSpace = nullptr) const;
239
244
252 const KoCompositeOp * compositeOp(const QString & id, const KoColorSpace *srcSpace = nullptr) const;
253
257 virtual void addCompositeOp(const KoCompositeOp * op);
258
263 virtual bool hasHighDynamicRange() const = 0;
264
265//========== Display profiles =============================================//
266
270 virtual const KoColorProfile * profile() const = 0;
271
272
273//================= Conversion functions ==================================//
274
282 virtual void transparentColor(quint8 *dst, quint32 nPixels) const;
283
292 virtual void fromQColor(const QColor& color, quint8 *dst) const = 0;
293
302 virtual void toQColor(const quint8 *src, QColor *c) const = 0;
303
312 virtual void toQColor16(const quint8 *src, QColor *c) const = 0;
313
324 virtual QImage convertToQImage(const quint8 *data, qint32 width, qint32 height,
325 const KoColorProfile * dstProfile,
327 KoColorConversionTransformation::ConversionFlags conversionFlags) const;
328
336 virtual void toLabA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
337
346 virtual void fromLabA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
347
355 virtual void toRgbA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
356
365 virtual void fromRgbA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
366
370 virtual KoColorConversionTransformation* createColorConverter(const KoColorSpace * dstColorSpace,
372 KoColorConversionTransformation::ConversionFlags conversionFlags) const;
373
377 virtual const KisDitherOp *ditherOp(const QString &depth, DitherType type) const;
378
379 virtual void addDitherOp(KisDitherOp *op);
380
391 virtual bool convertPixelsTo(const quint8 * src,
392 quint8 * dst, const KoColorSpace * dstColorSpace,
393 quint32 numPixels,
395 KoColorConversionTransformation::ConversionFlags conversionFlags) const;
396
412 virtual KoColorConversionTransformation *createProofingTransform(const KoColorSpace * dstColorSpace,
413 const KoColorSpace * proofingSpace,
416 bool bpcFirstTransform,
417 quint8 *gamutWarning,
418 KoColorConversionTransformation::ConversionFlags displayConversionFlags) const;
427 virtual bool proofPixelsTo(const quint8 * src,
428 quint8 * dst,
429 quint32 numPixels,
430 KoColorConversionTransformation *proofingTransform) const;
431
444 virtual void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const qint32 selectedChannelIndex) const = 0;
445
458 virtual void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const QBitArray selectedChannels) const = 0;
459
460//============================== Manipulation functions ==========================//
461
462
463//
464// The manipulation functions have default implementations that _convert_ the pixel
465// to a QColor and back. Reimplement these methods in your color strategy!
466//
467
471 virtual quint8 opacityU8(const quint8 * pixel) const = 0;
472 virtual qreal opacityF(const quint8 * pixel) const = 0;
473
482 virtual void setOpacity(quint8 * pixels, quint8 alpha, qint32 nPixels) const = 0;
483 virtual void setOpacity(quint8 * pixels, qreal alpha, qint32 nPixels) const = 0;
484
485
494 virtual void copyOpacityU8(quint8* src, quint8* dst, qint32 nPixels) const = 0;
495
504 virtual void multiplyAlpha(quint8 * pixels, quint8 alpha, qint32 nPixels) const = 0;
505
511 virtual void applyAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const = 0;
512
518 virtual void applyInverseAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const = 0;
519
524 virtual void applyAlphaNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const = 0;
525
530 virtual void applyInverseNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const = 0;
531
536 virtual void fillInverseAlphaNormedFloatMaskWithColor(quint8 * pixels, const float * alpha, const quint8 *brushColor, qint32 nPixels) const = 0;
537
548 virtual void fillGrayBrushWithColor(quint8 *dst, const QRgb *brush, quint8 *brushColor, qint32 nPixels) const = 0;
549
564 virtual void fillGrayBrushWithColorAndLightnessOverlay(quint8 *dst, const QRgb *brush, quint8 *brushColor, qint32 nPixels) const;
565 // Same as above, but with contrast adjusted by strength. Strength == 1 -> full contrast. Allows softer lightness adjustments.
566 virtual void fillGrayBrushWithColorAndLightnessWithStrength(quint8* dst, const QRgb* brush, quint8* brushColor, qreal strength, qint32 nPixels) const;
567 // Same as above, but applies lightness adjustment to \p dst in-place
568 virtual void modulateLightnessByGrayBrush(quint8* dst, const QRgb *brush, qreal strength, qint32 nPixels) const;
569
575 virtual KoColorTransformation *createBrightnessContrastAdjustment(const quint16 *transferValues) const = 0;
576
587 virtual KoColorTransformation *createPerChannelAdjustment(const quint16 * const* transferValues) const = 0;
588
594 virtual KoColorTransformation *createDarkenAdjustment(qint32 shade, bool compensate, qreal compensation) const = 0;
595
601
610 virtual quint8 difference(const quint8* src1, const quint8* src2) const = 0;
611
621 virtual quint8 differenceA(const quint8* src1, const quint8* src2) const = 0;
622
626 virtual KoMixColorsOp* mixColorsOp() const;
627
632
636 virtual quint8 intensity8(const quint8 * src) const = 0;
637
641 virtual qreal intensityF(const quint8 * src) const = 0;
642
643 /*
644 *increase luminosity by step
645 */
646 virtual void increaseLuminosity(quint8 * pixel, qreal step) const;
647 virtual void decreaseLuminosity(quint8 * pixel, qreal step) const;
648 virtual void increaseSaturation(quint8 * pixel, qreal step) const;
649 virtual void decreaseSaturation(quint8 * pixel, qreal step) const;
650 virtual void increaseHue(quint8 * pixel, qreal step) const;
651 virtual void decreaseHue(quint8 * pixel, qreal step) const;
652 virtual void increaseRed(quint8 * pixel, qreal step) const;
653 virtual void increaseGreen(quint8 * pixel, qreal step) const;
654 virtual void increaseBlue(quint8 * pixel, qreal step) const;
655 virtual void increaseYellow(quint8 * pixel, qreal step) const;
656 virtual void toHSY(const QVector<double> &channelValues, qreal *hue, qreal *sat, qreal *luma) const = 0;
657 virtual QVector <double> fromHSY(qreal *hue, qreal *sat, qreal *luma) const = 0;
658 virtual void toYUV(const QVector<double> &channelValues, qreal *y, qreal *u, qreal *v) const = 0;
659 virtual QVector <double> fromYUV(qreal *y, qreal *u, qreal *v) const = 0;
680 virtual void bitBlt(const KoColorSpace* srcSpace, const KoCompositeOp::ParameterInfo& params, const KoCompositeOp* op,
682 KoColorConversionTransformation::ConversionFlags conversionFlags) const;
683
697 virtual void colorToXML(const quint8* pixel, QDomDocument& doc, QDomElement& colorElt) const = 0;
698
708 virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const = 0;
709
710 KoColorTransformation* createColorTransformation(const QString & id, const QHash<QString, QVariant> & parameters) const;
711
712protected:
713
718 virtual void addChannel(KoChannelInfo * ci);
719 const KoColorConversionTransformation* toLabA16Converter() const;
720 const KoColorConversionTransformation* fromLabA16Converter() const;
721 const KoColorConversionTransformation* toRgbA16Converter() const;
722 const KoColorConversionTransformation* fromRgbA16Converter() const;
723
747 virtual bool preferCompositionInSourceColorSpace() const;
748
749
750 struct Private;
751 Private * const d;
752
753};
754
755inline QDebug operator<<(QDebug dbg, const KoColorSpace *cs)
756{
757 if (cs) {
758 dbg.nospace() << cs->name() << " (" << cs->colorModelId().id() << "," << cs->colorDepthId().id() << " )";
759 } else {
760 dbg.nospace() << "0x0";
761 }
762
763 return dbg.space();
764}
765
766
767#endif // KOCOLORSPACE_H
qreal v
qreal u
DitherType
Definition KisDitherOp.h:21
bool operator==(const KisRegion &lhs, const KisRegion &rhs)
QDebug operator<<(QDebug dbg, const KoColorSpace *cs)
Deletability
@ NotOwnedByRegistry
@ OwnedByRegistryDoNotDelete
@ OwnedByRegistryRegistryDeletes
ColorSpaceIndependence
@ TO_RGBA16
@ TO_LAB16
@ FULLY_INDEPENDENT
@ TO_RGBA8
virtual quint32 alphaPos() const =0
virtual quint8 intensity8(const quint8 *src) const =0
virtual qreal intensityF(const quint8 *src) const =0
QList< KoChannelInfo * > channels() const
QVector< qreal > lumaCoefficients() const
virtual quint32 pixelSize() const =0
virtual void applyAlphaU8Mask(quint8 *pixels, const quint8 *alpha, qint32 nPixels) const =0
virtual void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const qint32 selectedChannelIndex) const =0
virtual quint8 difference(const quint8 *src1, const quint8 *src2) const =0
virtual QList< KoCompositeOp * > compositeOps() const
virtual void toQColor(const quint8 *src, QColor *c) const =0
virtual QString channelValueText(const quint8 *pixel, quint32 channelIndex) const =0
QString name() const
virtual KoColorTransformation * createInvertTransformation() const =0
virtual void copyOpacityU8(quint8 *src, quint8 *dst, qint32 nPixels) const =0
QString id() const
virtual void setOpacity(quint8 *pixels, qreal alpha, qint32 nPixels) const =0
virtual void multiplyAlpha(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual bool profileIsCompatible(const KoColorProfile *profile) const =0
virtual void fillInverseAlphaNormedFloatMaskWithColor(quint8 *pixels, const float *alpha, const quint8 *brushColor, qint32 nPixels) const =0
virtual qreal opacityF(const quint8 *pixel) const =0
virtual void applyInverseAlphaU8Mask(quint8 *pixels, const quint8 *alpha, qint32 nPixels) const =0
virtual void toHSY(const QVector< double > &channelValues, qreal *hue, qreal *sat, qreal *luma) const =0
virtual void applyInverseNormedFloatMask(quint8 *pixels, const float *alpha, qint32 nPixels) const =0
virtual KoMixColorsOp * mixColorsOp() const
virtual void toYUV(const QVector< double > &channelValues, qreal *y, qreal *u, qreal *v) const =0
virtual bool hasHighDynamicRange() const =0
virtual KoColorTransformation * createBrightnessContrastAdjustment(const quint16 *transferValues) const =0
virtual KoColorTransformation * createPerChannelAdjustment(const quint16 *const *transferValues) const =0
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
virtual void convertChannelToVisualRepresentation(const quint8 *src, quint8 *dst, quint32 nPixels, const QBitArray selectedChannels) const =0
virtual QVector< double > fromYUV(qreal *y, qreal *u, qreal *v) const =0
virtual quint8 scaleToU8(const quint8 *srcPixel, qint32 channelPos) const =0
virtual void fromQColor(const QColor &color, quint8 *dst) const =0
virtual void applyAlphaNormedFloatMask(quint8 *pixels, const float *alpha, qint32 nPixels) const =0
Private *const d
virtual KoID colorModelId() const =0
virtual void toQColor16(const quint8 *src, QColor *c) const =0
virtual void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) const =0
virtual KoConvolutionOp * convolutionOp() const
QPolygonF gamutXYY() const
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual quint8 differenceA(const quint8 *src1, const quint8 *src2) const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) const =0
virtual void fillGrayBrushWithColor(quint8 *dst, const QRgb *brush, quint8 *brushColor, qint32 nPixels) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
virtual quint32 colorChannelCount() const =0
virtual void colorToXML(const quint8 *pixel, QDomDocument &doc, QDomElement &colorElt) const =0
virtual QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) const =0
virtual bool willDegrade(ColorSpaceIndependence independence) const =0
virtual KoColorTransformation * createDarkenAdjustment(qint32 shade, bool compensate, qreal compensation) const =0
virtual void colorFromXML(quint8 *pixel, const QDomElement &elt) const =0
virtual QVector< double > fromHSY(qreal *hue, qreal *sat, qreal *luma) const =0
virtual const KoColorProfile * profile() const =0
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
static QImage convertToQImage(char *buffer, qint32 width, qint32 height)
save the QImages as png files to directory image_tests
unsigned int QRgb