File indexing completed on 2024-05-12 15:59:32

0001 /*
0002  *  SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.1-or-later
0005 */
0006 
0007 #ifndef _KO_COLOR_CONVERSION_TRANSFORMATION_H_
0008 #define _KO_COLOR_CONVERSION_TRANSFORMATION_H_
0009 
0010 #include "KoColorTransformation.h"
0011 
0012 #include "kritapigment_export.h"
0013 
0014 class KoColorSpace;
0015 class KoColorConversionCache;
0016 
0017 /**
0018  * This is the base class of all color transform that convert the color of a pixel
0019  */
0020 class KRITAPIGMENT_EXPORT KoColorConversionTransformation : public KoColorTransformation
0021 {
0022     friend class KoColorConversionCache;
0023     struct Private;
0024 public:
0025 
0026     /**
0027      * Possible value for the intent of a color conversion (useful only for ICC
0028      * transformations)
0029      */
0030     enum Intent {
0031         IntentPerceptual = 0,
0032         IntentRelativeColorimetric = 1,
0033         IntentSaturation = 2,
0034         IntentAbsoluteColorimetric = 3
0035     };
0036 
0037     /**
0038      * Flags for the color conversion, see lcms2 documentation for more information
0039      */
0040     enum ConversionFlag {
0041         Empty                   = 0x0,
0042         NoOptimization          = 0x0100,
0043         GamutCheck              = 0x1000,    // Out of Gamut alarm
0044         SoftProofing            = 0x4000,    // Do softproofing
0045         BlackpointCompensation  = 0x2000,
0046         NoWhiteOnWhiteFixup     = 0x0004,    // Don't fix scum dot
0047         HighQuality             = 0x0400,    // Use more memory to give better accuracy
0048         LowQuality              = 0x0800,    // Use less memory to minimize resources
0049         CopyAlpha               = 0x04000000 //Let LCMS handle the alpha. Should always be on.
0050     };
0051     Q_DECLARE_FLAGS(ConversionFlags, ConversionFlag)
0052 
0053     /**
0054      * We have numerous places where we need to convert color spaces.
0055      *
0056      * In several cases the user asks us about the conversion
0057      * explicitly, e.g. when changing the image type or converting
0058      * pixel data to the monitor profile. Doing this explicitly the
0059      * user can choose what rendering intent and conversion flags to
0060      * use.
0061      *
0062      * But there are also cases when we have to do a conversion
0063      * internally (transparently for the user), for example, when
0064      * merging heterogeneous images, creating thumbnails, converting
0065      * data to/from QImage or while doing some adjustments. We cannot
0066      * ask the user about parameters for every single
0067      * conversion. That's why in all these non-critical cases the
0068      * following default values should be used.
0069      */
0070 
0071     static Intent internalRenderingIntent() { return IntentPerceptual; }
0072     static ConversionFlags internalConversionFlags() { return BlackpointCompensation; }
0073 
0074     static Intent adjustmentRenderingIntent() { return IntentPerceptual; }
0075     static ConversionFlags adjustmentConversionFlags() { return ConversionFlags(BlackpointCompensation | NoWhiteOnWhiteFixup); }
0076 
0077 public:
0078     KoColorConversionTransformation(const KoColorSpace* srcCs,
0079                                     const KoColorSpace* dstCs,
0080                                     Intent renderingIntent,
0081                                     ConversionFlags conversionFlags);
0082     ~KoColorConversionTransformation() override;
0083 public:
0084 
0085     /**
0086      * @return the source color space for this transformation.
0087      */
0088     const KoColorSpace* srcColorSpace() const;
0089 
0090     /**
0091      * @return the destination color space for this transformation.
0092      */
0093     const KoColorSpace* dstColorSpace() const;
0094 
0095     /**
0096      * @return the rendering intent of this transformation (this is only useful
0097      * for ICC transformations)
0098      */
0099     Intent renderingIntent() const;
0100 
0101     /**
0102      * @return the conversion flags
0103      */
0104     ConversionFlags conversionFlags() const;
0105 
0106     /**
0107      * perform the color conversion between two buffers. Make sure that
0108      * \p src is not the same as \p dst!
0109      * @param nPixels the number of pixels in the buffers.
0110      */
0111     void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const override = 0;
0112 
0113     /**
0114      * perform the color conversion between two or one buffer. This is a convenience
0115      * function that allows doing the conversion in-place
0116      * @param nPixels the number of pixels in the buffers.
0117      */
0118     void transformInPlace(const quint8 *src, quint8 *dst, qint32 nPixels) const;
0119 
0120     /**
0121      * @return false if the  transformation is not valid
0122      */
0123     bool isValid() const override { return true; }
0124 
0125 private:
0126 
0127     void setSrcColorSpace(const KoColorSpace*) const;
0128     void setDstColorSpace(const KoColorSpace*) const;
0129 
0130     Private * const d;
0131 };
0132 
0133 Q_DECLARE_OPERATORS_FOR_FLAGS(KoColorConversionTransformation::ConversionFlags)
0134 
0135 #endif