File indexing completed on 2025-03-09 04:08:37

0001 /*
0002  *  SPDX-FileCopyrightText: 2006 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 
0007 #ifndef RGBCOMPOSITEOPIN_H
0008 #define RGBCOMPOSITEOPIN_H
0009 
0010 #include <KoCompositeOp.h>
0011 
0012 #define SCALE_TO_FLOAT( v ) KoColorSpaceMaths< channels_type, float>::scaleToA( v )
0013 #define SCALE_FROM_FLOAT( v ) KoColorSpaceMaths< float, channels_type>::scaleToA( v )
0014 
0015 template<class _CSTraits>
0016 class RgbCompositeOpIn : public KoCompositeOp
0017 {
0018     typedef typename _CSTraits::channels_type channels_type;
0019     typedef typename KoColorSpaceMathsTraits<typename _CSTraits::channels_type>::compositetype compositetype;
0020 
0021 public:
0022 
0023     RgbCompositeOpIn(KoColorSpace *cs)
0024         : KoCompositeOp(cs, COMPOSITE_IN, "")
0025     {
0026     }
0027 
0028     using KoCompositeOp::composite;
0029 
0030     void composite(quint8 *dstRowStart, qint32 dstRowStride,
0031                    const quint8 *srcRowStart, qint32 srcRowStride,
0032                    const quint8 *maskRowStart, qint32 maskRowStride,
0033                    qint32 rows, qint32 numColumns,
0034                    quint8 opacity,
0035                    const QBitArray &channelFlags) const override
0036     {
0037         Q_UNUSED(maskRowStart);
0038         Q_UNUSED(maskRowStride);
0039 
0040         if (opacity == OPACITY_TRANSPARENT_U8) {
0041             return;
0042         }
0043 
0044         channels_type *d;
0045         const channels_type *s;
0046 
0047         qint32 i;
0048 
0049         //qreal sAlpha, dAlpha;
0050         qreal alpha;
0051 
0052         while (rows-- > 0) {
0053             d = reinterpret_cast<channels_type *>(dstRowStart);
0054             s = reinterpret_cast<const channels_type *>(srcRowStart);
0055             for (i = numColumns; i > 0; i--, d += _CSTraits::channels_nb, s += _CSTraits::channels_nb) {
0056 
0057                 if (s[_CSTraits::alpha_pos] == NATIVE_OPACITY_TRANSPARENT) {
0058                     d[_CSTraits::alpha_pos] = NATIVE_OPACITY_TRANSPARENT;
0059                     continue;
0060                 } else if (s[_CSTraits::alpha_pos] == NATIVE_OPACITY_OPAQUE) {
0061                     continue;
0062                 }
0063                 if (d[_CSTraits::alpha_pos] == NATIVE_OPACITY_TRANSPARENT) {
0064                     continue;
0065                 }
0066 
0067                 alpha = (qreal)(s[_CSTraits::alpha_pos]) * d[_CSTraits::alpha_pos] / NATIVE_OPACITY_OPAQUE;
0068 
0069                 if (channelFlags.isEmpty() || channelFlags.testBit(_CSTraits::alpha_pos)) {
0070                     d[_CSTraits::alpha_pos] = (channels_type)((d[_CSTraits::alpha_pos] * alpha / NATIVE_OPACITY_OPAQUE) + 0.5);
0071                 }
0072 
0073             }
0074             dstRowStart += dstRowStride;
0075             srcRowStart += srcRowStride;
0076         }
0077     }
0078 };
0079 
0080 #endif