Warning, file /office/calligra/libs/pigment/KoColorSpace.h was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
0003  *  Copyright (c) 2006-2007 Cyrille Berger <cberger@cberger.net>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2.1 of the License, or (at your option) any later version.
0009  *
0010  * This library is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013  * Lesser General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU Lesser General Public License
0016  * along with this library; see the file COPYING.LIB.  If not, write to
0017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018  * Boston, MA 02110-1301, USA.
0019  */
0020 #ifndef KOCOLORSPACE_H
0021 #define KOCOLORSPACE_H
0022 
0023 #include <limits.h>
0024 
0025 #include <QImage>
0026 #include <QHash>
0027 #include <QVector>
0028 #include <QList>
0029 
0030 #include "KoColorSpaceConstants.h"
0031 #include "KoColorConversionTransformation.h"
0032 #include "KoCompositeOp.h"
0033 #include <KoID.h>
0034 #include "pigment_export.h"
0035 
0036 class QDomDocument;
0037 class QDomElement;
0038 class KoChannelInfo;
0039 class KoColorProfile;
0040 class KoColorTransformation;
0041 class QBitArray;
0042 
0043 enum Deletability {
0044     OwnedByRegistryDoNotDelete,
0045     OwnedByRegistryRegistryDeletes,
0046     NotOwnedByRegistry
0047 };
0048 
0049 enum ColorSpaceIndependence {
0050     FULLY_INDEPENDENT,
0051     TO_LAB16,
0052     TO_RGBA8,
0053     TO_RGBA16
0054 };
0055 
0056 class KoMixColorsOp;
0057 class KoConvolutionOp;
0058 
0059 /**
0060  * A KoColorSpace is the definition of a certain color space.
0061  *
0062  * A color model and a color space are two related concepts. A color
0063  * model is more general in that it describes the channels involved and
0064  * how they in broad terms combine to describe a color. Examples are
0065  * RGB, HSV, CMYK.
0066  *
0067  * A color space is more specific in that it also describes exactly how
0068  * the channels are combined. So for each color model there can be a
0069  * number of specific color spaces. So RGB is the model and sRGB,
0070  * adobeRGB, etc are colorspaces.
0071  *
0072  * In Pigment KoColorSpace acts as both a color model and a color space.
0073  * You can think of the class definition as the color model, but the
0074  * instance of the class as representing a colorspace.
0075  *
0076  * A third concept is the profile represented by KoColorProfile. It
0077  * represents the info needed to specialize a color model into a color
0078  * space.
0079  *
0080  * KoColorSpace is an abstract class serving as an interface.
0081  *
0082  * Subclasses implement actual color spaces
0083  * Some subclasses implement only some parts and are named Traits
0084  *
0085  */
0086 class PIGMENTCMS_EXPORT KoColorSpace
0087 {
0088     friend class KoColorSpaceRegistry;
0089     friend class KoColorSpaceFactory;
0090 protected:
0091     /// Only for use by classes that serve as baseclass for real color spaces
0092     KoColorSpace();
0093 
0094 public:
0095 
0096     /// Should be called by real color spaces
0097     KoColorSpace(const QString &id, const QString &name, KoMixColorsOp* mixColorsOp, KoConvolutionOp* convolutionOp);
0098 
0099     virtual bool operator==(const KoColorSpace& rhs) const;
0100 protected:
0101     virtual ~KoColorSpace();
0102 
0103 public:
0104     //========== Gamut and other basic info ===================================//
0105     /*
0106      * @returns QPolygonF with 5*channel samples converted to xyY.
0107      * maybe convert to 3d space in future?
0108      */
0109     QPolygonF gamutXYY() const;
0110     
0111     /*
0112      * @returns a polygon with 5 samples per channel converted to xyY, but unlike
0113      * gamutxyY it focuses on the luminance. This then can be used to visualise
0114      * the approximate trc of a given colorspace.
0115      */
0116     QPolygonF estimatedTRCXYY() const;
0117     
0118     QVector <qreal> colorants() const;
0119     QVector <qreal> lumaCoefficients() const;
0120     
0121     //========== Channels =====================================================//
0122 
0123     /// Return a list describing all the channels this color model has. The order
0124     /// of the channels in the list is the order of channels in the pixel. To find
0125     /// out the preferred display position, use KoChannelInfo::displayPosition.
0126     virtual QList<KoChannelInfo *> channels() const;
0127 
0128     /**
0129      * The total number of channels for a single pixel in this color model
0130      */
0131     virtual quint32 channelCount() const = 0;
0132 
0133     /**
0134      * The total number of color channels (excludes alpha) for a single
0135      * pixel in this color model.
0136      */
0137     virtual quint32 colorChannelCount() const = 0;
0138 
0139     /**
0140      * returns a QBitArray that contains true for the specified
0141      * channel types:
0142      *
0143      * @param color if true, set all color channels to true
0144      * @param alpha if true, set all alpha channels to true
0145      *
0146      * The order of channels is the colorspace descriptive order,
0147      * not the pixel order.
0148      */
0149     QBitArray channelFlags(bool color = true, bool alpha = false) const;
0150 
0151     /**
0152      * The size in bytes of a single pixel in this color model
0153      */
0154     virtual quint32 pixelSize() const = 0;
0155 
0156     /**
0157      * Return a string with the channel's value suitable for display in the gui.
0158      */
0159     virtual QString channelValueText(const quint8 *pixel, quint32 channelIndex) const = 0;
0160 
0161     /**
0162      * Return a string with the channel's value with integer
0163      * channels normalised to the floating point range 0 to 1, if
0164      * appropriate.
0165      */
0166     virtual QString normalisedChannelValueText(const quint8 *pixel, quint32 channelIndex) const = 0;
0167 
0168     /**
0169      * Return a QVector of floats with channels' values normalized
0170      * to floating point range 0 to 1.
0171      */
0172     virtual void normalisedChannelsValue(const quint8 *pixel, QVector<qreal> &channels) const = 0;
0173 
0174     /**
0175      * Write in the pixel the value from the normalized vector.
0176      */
0177     virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector<qreal> &values) const = 0;
0178 
0179     /**
0180      * Convert the value of the channel at the specified position into
0181      * an 8-bit value. The position is not the number of bytes, but
0182      * the position of the channel as defined in the channel info list.
0183      */
0184     virtual quint8 scaleToU8(const quint8 * srcPixel, qint32 channelPos) const = 0;
0185 
0186     /**
0187      * Set dstPixel to the pixel containing only the given channel of srcPixel. The remaining channels
0188      * should be set to whatever makes sense for 'empty' channels of this color space,
0189      * with the intent being that the pixel should look like it only has the given channel.
0190      */
0191     virtual void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) const = 0;
0192 
0193     //========== Identification ===============================================//
0194 
0195     /**
0196      * ID for use in files and internally: unchanging name. As the id must be unique
0197      * it is usually the concatenation of the id of the color model and of the color
0198      * depth, for instance "RGBA8" or "CMYKA16" or "XYZA32f".
0199      */
0200     virtual QString id() const;
0201 
0202     /**
0203      * User visible name which contains the name of the color model and of the color depth.
0204      * For intance "RGBA (8-bits)" or "CMYKA (16-bits)".
0205      */
0206     virtual QString name() const;
0207 
0208     /**
0209      * @return a string that identify the color model (for instance "RGB" or "CMYK" ...)
0210      * @see KoColorModelStandardIds.h
0211      */
0212     virtual KoID colorModelId() const = 0;
0213     /**
0214      * @return a string that identify the bit depth (for instance "U8" or "F16" ...)
0215      * @see KoColorModelStandardIds.h
0216      */
0217     virtual KoID colorDepthId() const = 0;
0218 
0219     /**
0220      * @return true if the profile given in argument can be used by this color space
0221      */
0222     virtual bool profileIsCompatible(const KoColorProfile* profile) const = 0;
0223 
0224     /**
0225      * If false, images in this colorspace will degrade considerably by
0226      * functions, tools and filters that have the given measure of colorspace
0227      * independence.
0228      *
0229      * @param independence the measure to which this colorspace will suffer
0230      *                     from the manipulations of the tool or filter asking
0231      * @return false if no degradation will take place, true if degradation will
0232      *         take place
0233      */
0234     virtual bool willDegrade(ColorSpaceIndependence independence) const = 0;
0235 
0236     //========== Capabilities =================================================//
0237 
0238     /**
0239      * Tests if the colorspace offers the specific composite op.
0240      */
0241     virtual bool hasCompositeOp(const QString & id) const;
0242 
0243     /**
0244      * Returns the list of user-visible composite ops supported by this colorspace.
0245      */
0246     virtual QList<KoCompositeOp*> compositeOps() const;
0247 
0248     /**
0249      * Retrieve a single composite op from the ones this colorspace offers.
0250      * If the requested composite op does not exist, COMPOSITE_OVER is returned.
0251      */
0252     virtual const KoCompositeOp * compositeOp(const QString & id) const;
0253 
0254     /**
0255      * add a composite op to this colorspace.
0256      */
0257     virtual void addCompositeOp(const KoCompositeOp * op);
0258 
0259     /**
0260      * Returns true if the colorspace supports channel values outside the
0261      * (normalised) range 0 to 1.
0262      */
0263     virtual bool hasHighDynamicRange() const = 0;
0264 
0265 
0266 //========== Display profiles =============================================//
0267 
0268     /**
0269      * Return the profile of this color space.
0270      */
0271     virtual const KoColorProfile * profile() const = 0;
0272 
0273 
0274 //================= Conversion functions ==================================//
0275 
0276 
0277     /**
0278      * The fromQColor methods take a given color defined as an RGB QColor
0279      * and fills a byte array with the corresponding color in the
0280      * the colorspace managed by this strategy.
0281      *
0282      * @param color the QColor that will be used to fill dst
0283      * @param dst a pointer to a pixel
0284      * @param profile the optional profile that describes the color values of QColor
0285      */
0286     virtual void fromQColor(const QColor& color, quint8 *dst, const KoColorProfile * profile = 0) const = 0;
0287 
0288     /**
0289      * The toQColor methods take a byte array that is at least pixelSize() long
0290      * and converts the contents to a QColor, using the given profile as a source
0291      * profile and the optional profile as a destination profile.
0292      *
0293      * @param src a pointer to the source pixel
0294      * @param c the QColor that will be filled with the color at src
0295      * @param profile the optional profile that describes the color in c, for instance the monitor profile
0296      */
0297     virtual void toQColor(const quint8 *src, QColor *c, const KoColorProfile * profile = 0) const = 0;
0298 
0299     /**
0300      * Convert the pixels in data to (8-bit BGRA) QImage using the specified profiles.
0301      *
0302      * @param data A pointer to a contiguous memory region containing width * height pixels
0303      * @param width in pixels
0304      * @param height in pixels
0305      * @param dstProfile destination profile
0306      * @param renderingIntent the rendering intent
0307      * @param conversionFlags the conversion flags
0308      */
0309     virtual QImage convertToQImage(const quint8 *data, qint32 width, qint32 height,
0310                                    const KoColorProfile *  dstProfile,
0311                                    KoColorConversionTransformation::Intent renderingIntent,
0312                                    KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0313 
0314     /**
0315      * Convert the specified data to Lab (D50). All colorspaces are guaranteed to support this
0316      *
0317      * @param src the source data
0318      * @param dst the destination data
0319      * @param nPixels the number of source pixels
0320      */
0321     virtual void toLabA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
0322 
0323     /**
0324      * Convert the specified data from Lab (D50). to this colorspace. All colorspaces are
0325      * guaranteed to support this.
0326      *
0327      * @param src the pixels in 16 bit lab format
0328      * @param dst the destination data
0329      * @param nPixels the number of pixels in the array
0330      */
0331     virtual void fromLabA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
0332 
0333     /**
0334      * Convert the specified data to sRGB 16 bits. All colorspaces are guaranteed to support this
0335      *
0336      * @param src the source data
0337      * @param dst the destination data
0338      * @param nPixels the number of source pixels
0339      */
0340     virtual void toRgbA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
0341 
0342     /**
0343      * Convert the specified data from sRGB 16 bits. to this colorspace. All colorspaces are
0344      * guaranteed to support this.
0345      *
0346      * @param src the pixels in 16 bit rgb format
0347      * @param dst the destination data
0348      * @param nPixels the number of pixels in the array
0349      */
0350     virtual void fromRgbA16(const quint8 * src, quint8 * dst, quint32 nPixels) const;
0351 
0352     /**
0353      * Create a color conversion transformation.
0354      */
0355     virtual KoColorConversionTransformation* createColorConverter(const KoColorSpace * dstColorSpace,
0356                                                                   KoColorConversionTransformation::Intent renderingIntent,
0357                                                                   KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0358 
0359     /**
0360      * Convert a byte array of srcLen pixels *src to the specified color space
0361      * and put the converted bytes into the prepared byte array *dst.
0362      *
0363      * Returns false if the conversion failed, true if it succeeded
0364      *
0365      * This function is not thread-safe. If you want to apply multiple conversion
0366      * in different threads at the same time, you need to create one color converter
0367      * per-thread using createColorConverter.
0368      */
0369     virtual bool convertPixelsTo(const quint8 * src,
0370                                  quint8 * dst, const KoColorSpace * dstColorSpace,
0371                                  quint32 numPixels,
0372                                  KoColorConversionTransformation::Intent renderingIntent,
0373                                  KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0374 
0375 //============================== Manipulation functions ==========================//
0376 
0377 
0378 //
0379 // The manipulation functions have default implementations that _convert_ the pixel
0380 // to a QColor and back. Reimplement these methods in your color strategy!
0381 //
0382 
0383     /**
0384      * Get the alpha value of the given pixel, downscaled to an 8-bit value.
0385      */
0386     virtual quint8 opacityU8(const quint8 * pixel) const = 0;
0387     virtual qreal opacityF(const quint8 * pixel) const = 0;
0388 
0389     /**
0390      * Set the alpha channel of the given run of pixels to the given value.
0391      *
0392      * pixels -- a pointer to the pixels that will have their alpha set to this value
0393      * alpha --  a downscaled 8-bit value for opacity
0394      * nPixels -- the number of pixels
0395      *
0396      */
0397     virtual void setOpacity(quint8 * pixels, quint8 alpha, qint32 nPixels) const = 0;
0398     virtual void setOpacity(quint8 * pixels, qreal alpha, qint32 nPixels) const = 0;
0399 
0400     /**
0401      * Multiply the alpha channel of the given run of pixels by the given value.
0402      *
0403      * pixels -- a pointer to the pixels that will have their alpha set to this value
0404      * alpha --  a downscaled 8-bit value for opacity
0405      * nPixels -- the number of pixels
0406      *
0407      */
0408     virtual void multiplyAlpha(quint8 * pixels, quint8 alpha, qint32 nPixels) const = 0;
0409 
0410     /**
0411      * Applies the specified 8-bit alpha mask to the pixels. We assume that there are just
0412      * as many alpha values as pixels but we do not check this; the alpha values
0413      * are assumed to be 8-bits.
0414      */
0415     virtual void applyAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const = 0;
0416 
0417     /**
0418      * Applies the inverted 8-bit alpha mask to the pixels. We assume that there are just
0419      * as many alpha values as pixels but we do not check this; the alpha values
0420      * are assumed to be 8-bits.
0421      */
0422     virtual void applyInverseAlphaU8Mask(quint8 * pixels, const quint8 * alpha, qint32 nPixels) const = 0;
0423 
0424     /**
0425      * Applies the specified float alpha mask to the pixels. We assume that there are just
0426      * as many alpha values as pixels but we do not check this; alpha values have to be between 0.0 and 1.0
0427      */
0428     virtual void applyAlphaNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const = 0;
0429 
0430     /**
0431      * Applies the inverted specified float alpha mask to the pixels. We assume that there are just
0432      * as many alpha values as pixels but we do not check this; alpha values have to be between 0.0 and 1.0
0433      */
0434     virtual void applyInverseNormedFloatMask(quint8 * pixels, const float * alpha, qint32 nPixels) const = 0;
0435 
0436     /**
0437      * Create an adjustment object for adjusting the brightness and contrast
0438      * transferValues is a 256 bins array with values from 0 to 0xFFFF
0439      * This function is thread-safe, but you need to create one KoColorTransformation per thread.
0440      */
0441     virtual KoColorTransformation *createBrightnessContrastAdjustment(const quint16 *transferValues) const = 0;
0442 
0443     /**
0444      * Create an adjustment object for adjusting individual channels
0445      * transferValues is an array of colorChannelCount number of 256 bins array with values from 0 to 0xFFFF
0446      * This function is thread-safe, but you need to create one KoColorTransformation per thread.
0447      *
0448      * The layout of the channels must be the following:
0449      *
0450      * 0..N-2 - color channels of the pixel;
0451      * N-1 - alpha channel of the pixel (if exists)
0452      */
0453     virtual KoColorTransformation *createPerChannelAdjustment(const quint16 * const* transferValues) const = 0;
0454 
0455     /**
0456      * Darken all color channels with the given amount. If compensate is true,
0457      * the compensation factor will be used to limit the darkening.
0458      *
0459      */
0460     virtual KoColorTransformation *createDarkenAdjustment(qint32 shade, bool compensate, qreal compensation) const = 0;
0461 
0462     /**
0463      * Invert color channels of the given pixels
0464      * This function is thread-safe, but you need to create one KoColorTransformation per thread.
0465      */
0466     virtual KoColorTransformation *createInvertTransformation() const = 0;
0467 
0468     /**
0469      * Get the difference between 2 colors, normalized in the range (0,255). Only completely
0470      * opaque and completely transparent are taken into account when computing the different;
0471      * other transparency levels are not regarded when finding the difference.
0472      */
0473     virtual quint8 difference(const quint8* src1, const quint8* src2) const = 0;
0474 
0475     /**
0476      * Get the difference between 2 colors, normalized in the range (0,255). This function
0477      * takes the Alpha channel of the pixel into account. Alpha channel has the same
0478      * weight as Lightness channel.
0479      */
0480     virtual quint8 differenceA(const quint8* src1, const quint8* src2) const = 0;
0481 
0482     /**
0483      * @return the mix color operation of this colorspace (do not delete it locally, it's deleted by the colorspace).
0484      */
0485     virtual KoMixColorsOp* mixColorsOp() const;
0486 
0487     /**
0488      * @return the convolution operation of this colorspace (do not delete it locally, it's deleted by the colorspace).
0489      */
0490     virtual KoConvolutionOp* convolutionOp() const;
0491 
0492     /**
0493      * Calculate the intensity of the given pixel, scaled down to the range 0-255. XXX: Maybe this should be more flexible
0494      */
0495     virtual quint8 intensity8(const quint8 * src) const = 0;
0496 
0497     /*
0498      *increase luminosity by step
0499      */
0500     virtual void increaseLuminosity(quint8 * pixel, qreal step) const;
0501     virtual void decreaseLuminosity(quint8 * pixel, qreal step) const;
0502     virtual void increaseSaturation(quint8 * pixel, qreal step) const;
0503     virtual void decreaseSaturation(quint8 * pixel, qreal step) const;
0504     virtual void increaseHue(quint8 * pixel, qreal step) const;
0505     virtual void decreaseHue(quint8 * pixel, qreal step) const;
0506     virtual void increaseRed(quint8 * pixel, qreal step) const;
0507     virtual void increaseGreen(quint8 * pixel, qreal step) const;
0508     virtual void increaseBlue(quint8 * pixel, qreal step) const;
0509     virtual void increaseYellow(quint8 * pixel, qreal step) const;
0510     virtual void toHSY(const QVector<qreal> &channelValues, qreal *hue, qreal *sat, qreal *luma) const = 0;
0511     virtual QVector <qreal> fromHSY(qreal *hue, qreal *sat, qreal *luma) const = 0;
0512     virtual void toYUV(const QVector<qreal> &channelValues, qreal *y, qreal *u, qreal *v) const = 0;
0513     virtual QVector <qreal> fromYUV(qreal *y, qreal *u, qreal *v) const = 0;
0514     /**
0515      * Compose two arrays of pixels together. If source and target
0516      * are not the same color model, the source pixels will be
0517      * converted to the target model. We're "dst" -- "dst" pixels are always in _this_
0518      * colorspace.
0519      *
0520      * @param srcSpace the colorspace of the source pixels that will be composited onto "us"
0521      * @param params the information needed for blitting e.g. the source and destination pixel data,
0522      *        the opacity and flow, ...
0523      * @param op the composition operator to use, e.g. COPY_OVER
0524      * @param renderingIntent the rendering intent
0525      * @param conversionFlags the conversion flags
0526      *
0527      */
0528     virtual void bitBlt(const KoColorSpace* srcSpace, const KoCompositeOp::ParameterInfo& params, const KoCompositeOp* op,
0529                         KoColorConversionTransformation::Intent renderingIntent,
0530                         KoColorConversionTransformation::ConversionFlags conversionFlags) const;
0531 
0532     /**
0533      * Serialize this color following Create's swatch color specification available
0534      * at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
0535      *
0536      * This function doesn't create the \<color /\> element but rather the \<CMYK /\>,
0537      * \<sRGB /\>, \<RGB /\> ... elements. It is assumed that @p colorElt is the \<color /\>
0538      * element.
0539      *
0540      * @param pixel buffer to serialized
0541      * @param colorElt root element for the serialization, it is assumed that this
0542      *                 element is \<color /\>
0543      * @param doc is the document containing colorElt
0544      */
0545     virtual void colorToXML(const quint8* pixel, QDomDocument& doc, QDomElement& colorElt) const = 0;
0546 
0547     /**
0548      * Unserialize a color following Create's swatch color specification available
0549      * at http://create.freedesktop.org/wiki/index.php/Swatches_-_colour_file_format
0550      *
0551      * @param pixel buffer where the color will be unserialized
0552      * @param elt the element to unserialize (\<CMYK /\>, \<sRGB /\>, \<RGB /\>)
0553      * @return the unserialize color, or an empty color object if the function failed
0554      *         to unserialize the color
0555      */
0556     virtual void colorFromXML(quint8* pixel, const QDomElement& elt) const = 0;
0557 
0558     KoColorTransformation* createColorTransformation(const QString & id, const QHash<QString, QVariant> & parameters) const;
0559 
0560 protected:
0561 
0562     /**
0563      * Use this function in the constructor of your colorspace to add the information about a channel.
0564      * @param ci a pointer to the information about a channel
0565      */
0566     virtual void addChannel(KoChannelInfo * ci);
0567     const KoColorConversionTransformation* toLabA16Converter() const;
0568     const KoColorConversionTransformation* fromLabA16Converter() const;
0569     const KoColorConversionTransformation* toRgbA16Converter() const;
0570     const KoColorConversionTransformation* fromRgbA16Converter() const;
0571 
0572     /**
0573      * Returns the thread-local conversion cache. If it doesn't exist
0574      * yet, it is created. If it is currently too small, it is resized.
0575      */
0576     QVector<quint8> * threadLocalConversionCache(quint32 size) const;
0577 
0578     /**
0579      * This function defines the behavior of the bitBlt function
0580      * when the composition of pixels in different colorspaces is
0581      * requested, that is in case:
0582      *
0583      * srcCS == any
0584      * dstCS == this
0585      *
0586      * 1) preferCompositionInSourceColorSpace() == false,
0587      *
0588      *    the source pixels are first converted to *this color space
0589      *    and then composition is performed.
0590      *
0591      * 2)  preferCompositionInSourceColorSpace() == true,
0592      *
0593      *    the destination pixels are first converted into *srcCS color
0594      *    space, then the composition is done, and the result is finally
0595      *    converted into *this colorspace.
0596      *
0597      *    This is used by alpha8() color space mostly, because it has
0598      *    weaker representation of the color, so the composition
0599      *    should be done in CS with richer functionality.
0600      */
0601     virtual bool preferCompositionInSourceColorSpace() const;
0602 
0603 
0604     struct Private;
0605     Private * const d;
0606 
0607 };
0608 
0609 inline QDebug operator<<(QDebug dbg, const KoColorSpace *cs)
0610 {
0611     dbg.nospace() << cs->name() << " (" << cs->colorModelId().id() << "," << cs->colorDepthId().id() << " )";
0612 
0613     return dbg.space();
0614 }
0615 
0616 
0617 #endif // KOCOLORSPACE_H