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 RGBCOMPOSITEOPOUT_H 0008 #define RGBCOMPOSITEOPOUT_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 RgbCompositeOpOut : 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 RgbCompositeOpOut(KoColorSpace *cs) 0024 : KoCompositeOp(cs, COMPOSITE_OUT) 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 if (s[_CSTraits::alpha_pos] == NATIVE_OPACITY_TRANSPARENT) { 0057 continue; 0058 } else if (s[_CSTraits::alpha_pos] == NATIVE_OPACITY_OPAQUE) { 0059 d[_CSTraits::alpha_pos] = NATIVE_OPACITY_TRANSPARENT; 0060 continue; 0061 } 0062 if (d[_CSTraits::alpha_pos] == NATIVE_OPACITY_TRANSPARENT) { 0063 continue; 0064 } 0065 0066 alpha = (channels_type)(s[_CSTraits::alpha_pos]) * d[_CSTraits::alpha_pos] / NATIVE_OPACITY_OPAQUE; 0067 if (channelFlags.isEmpty() || channelFlags.testBit(_CSTraits::alpha_pos)) { 0068 d[_CSTraits::alpha_pos] = (channels_type)((d[_CSTraits::alpha_pos] * (NATIVE_OPACITY_OPAQUE - alpha) / NATIVE_OPACITY_OPAQUE) + 0.5); 0069 } 0070 } 0071 dstRowStart += dstRowStride; 0072 srcRowStart += srcRowStride; 0073 } 0074 0075 } 0076 }; 0077 0078 #endif