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

0001 /*
0002  *  SPDX-FileCopyrightText: 2005 Boudewijn Rempt <boud@valdyas.org>
0003  *  SPDX-FileCopyrightText: 2006-2007 Cyrille Berger <cberger@cberger.net>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.1-or-later
0006  */
0007 #ifndef KO_MIX_COLORS_OP_H
0008 #define KO_MIX_COLORS_OP_H
0009 
0010 #include <limits.h>
0011 
0012 /**
0013  * Base class of the mix color operation. It's defined by
0014  * sum(colors[i] * weights[i]) / weightSum. You access the KoMixColorsOp
0015  * of a colorspace by calling KoColorSpace::mixColorsOp.
0016  */
0017 class KoMixColorsOp
0018 {
0019 public:
0020 
0021     /**
0022      * An accumulator-like object for mixing color without copying and allocations
0023      */
0024     class Mixer
0025     {
0026     public:
0027         virtual ~Mixer() {}
0028         /**
0029          * Add \p nPixels pixels pointed by \p data to the mixing sum. The
0030          * passed pixels are weighted by coefficients in \p weights.
0031          */
0032         virtual void accumulate(const quint8 *data, const qint16 *weights, int weightSum, int nPixels) = 0;
0033 
0034         /**
0035          * Add \p nPixels pixels pointed by \p data to the mixing sum. The
0036          * passed pixels are weighted uniformly, that is, each pixel has
0037          * implicit weight of 1.
0038          */
0039         virtual void accumulateAverage(const quint8 *data, int nPixels) = 0;
0040 
0041         /**
0042          * Calculate the final mixed color. This function may be called
0043          * as many times as needed on any stage of the mixing.
0044          */
0045         virtual void computeMixedColor(quint8 *data) = 0;
0046 
0047         /**
0048          * Return the current sum of the weights of the averaging
0049          * algorithm. That might be needed to make a decision whether
0050          * we had a meaningful amount of data passed.
0051          */
0052         virtual qint64 currentWeightsSum() const = 0;
0053     };
0054 
0055     virtual Mixer* createMixer() const = 0;
0056 
0057 public:
0058     virtual ~KoMixColorsOp() { }
0059     /**
0060      * Mix the colors.
0061      * @param colors a pointer toward the source pixels
0062      * @param weights the coefficient of the source pixels
0063      * @param nColors the number of pixels in the colors array
0064      * @param dst the destination pixel
0065      * @param weightSum an integer representing the sum of the coefficients.
0066      *                  by default 255. If for some reason you do not want a
0067      *                  perfect average, make this anything but the sum. Try
0068      *                  to keep this below 255 for division-related performance.
0069      *
0070      * @code
0071      * quint8* colors[nColors];
0072      * colors[0] = ptrToFirstPixel;
0073      * colors[1] = ptrToSecondPixel;
0074      * ...
0075      * colors[nColors-1] = ptrToLastPixel;
0076      * qint16 weights[nColors];
0077      * weights[0] = firstWeight;
0078      * weights[1] = secondWeight;
0079      * ...
0080      * weights[nColors-1] = lastWeight;
0081      *
0082      * mixColors(colors, weights, nColors, ptrToDestinationPixel);
0083      * @endcode
0084      */
0085     virtual void mixColors(const quint8 * const*colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum = 255) const = 0;
0086     virtual void mixColors(const quint8 *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum = 255) const = 0;
0087 
0088 
0089     /**
0090      * Mix the colors uniformly, without weightening
0091      * @param colors a pointer toward the source pixels
0092      * @param nColors the number of pixels in the colors array
0093      * @param dst the destination pixel
0094      *
0095      * @code
0096      * quint8* colors[nColors];
0097      * colors[0] = ptrToFirstPixel;
0098      * colors[1] = ptrToSecondPixel;
0099      * ...
0100      * colors[nColors-1] = ptrToLastPixel;
0101      *
0102      * mixColors(colors, nColors, ptrToDestinationPixel);
0103      * @endcode
0104      */
0105     virtual void mixColors(const quint8 * const*colors, int nColors, quint8 *dst) const = 0;
0106     virtual void mixColors(const quint8 *colors, int nColors, quint8 *dst) const = 0;
0107 
0108     /**
0109      *   Convenience function to mix two color arrays with one weight.  Mixes colorsA[x] with colorsB[x] with 
0110      *   weight as the percentage of B vs A (0.0 -> 100% A, 1.0 -> 100% B), for all x = [0 .. nColors-1].
0111      *
0112      *
0113     */
0114     virtual void mixTwoColorArrays(const quint8* colorsA, const quint8* colorsB, int nColors, qreal weight, quint8* dst) const = 0;
0115 
0116     /**
0117      *   Convenience function to mix one color array with one color with a specific weight.  Mixes colorArray[x] with color with
0118      *   weight as the percentage of B vs A (0.0 -> 100% A, 1.0 -> 100% B), for all x = [0 .. nColors-1].
0119      *
0120      *
0121     */
0122     virtual void mixArrayWithColor(const quint8* colorArray, const quint8* color, int nColors, qreal weight, quint8* dst) const = 0;
0123 };
0124 
0125 #endif