~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to libs/pigment/compositeops/KoCompositeOpAlphaBase.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2010-09-21 15:36:35 UTC
  • mfrom: (1.4.1 upstream) (60.2.11 maverick)
  • Revision ID: james.westby@ubuntu.com-20100921153635-6tejqkiro2u21ydi
Tags: 1:2.2.2-0ubuntu3
Add kubuntu_03_fix-crash-on-closing-sqlite-connection-2.2.2.diff and
kubuntu_04_support-large-memo-values-for-msaccess-2.2.2.diff as
recommended by upstream http://kexi-
project.org/wiki/wikiview/index.php@Kexi2.2_Patches.html#sqlite_stab
ility

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
#include <QBitArray>
24
24
 
25
 
#include "KoColorSpaceMaths.h"
26
 
#include "KoCompositeOp.h"
27
 
 
 
25
#include <KoColorSpaceMaths.h>
 
26
#include <KoCompositeOp.h>
 
27
#include <KoColorSpaceConstants.h>
28
28
 
29
29
#define NATIVE_MIN_VALUE KoColorSpaceMathsTraits<channels_type>::min
30
30
#define NATIVE_MAX_VALUE KoColorSpaceMathsTraits<channels_type>::max
38
38
 * @param _compositeOp this class should define a function with the
39
39
 *        following signature: inline static void composeColorChannels
40
40
 */
41
 
template<class _CSTraits, class _compositeOp>
42
 
class KoCompositeOpAlphaBase : public KoCompositeOp {
 
41
template<class _CSTraits, class _compositeOp, bool _alphaLocked>
 
42
class KoCompositeOpAlphaBase : public KoCompositeOp
 
43
{
43
44
    typedef typename _CSTraits::channels_type channels_type;
44
45
public:
45
46
 
46
 
    KoCompositeOpAlphaBase(const KoColorSpace * cs, const QString& id, const QString& description, const QString& category )
47
 
        : KoCompositeOp(cs, id, description, category )
48
 
        {
49
 
        }
 
47
    KoCompositeOpAlphaBase(const KoColorSpace * cs, const QString& id, const QString& description, const QString& category)
 
48
            : KoCompositeOp(cs, id, description, category) {
 
49
    }
50
50
 
51
51
public:
52
52
    using KoCompositeOp::composite;
60
60
                   qint32 rows,
61
61
                   qint32 cols,
62
62
                   quint8 U8_opacity,
63
 
                   const QBitArray & channelFlags) const
64
 
        {
65
 
            qint32 srcInc = (srcstride == 0) ? 0 : _CSTraits::channels_nb;
66
 
            if ( _CSTraits::alpha_pos == -1 ) {
67
 
 
68
 
                qint32 pixelSize = colorSpace()->pixelSize();
69
 
 
70
 
                // XXX: if cols == (dststride/dstPixelSize) == (srcstride/srcPixelSize) == maskstride/maskpixelsize)
71
 
                // then don't loop through rows and cols, but composite everything in one go
72
 
                while (rows > 0) {
73
 
                    const channels_type *srcN = reinterpret_cast<const channels_type *>(srcRowStart);
74
 
                    channels_type *dstN = reinterpret_cast<channels_type *>(dstRowStart);
75
 
                    const quint8 *mask = maskRowStart;
76
 
 
77
 
                    qint32 columns = cols;
78
 
 
79
 
                    while (columns > 0) {
80
 
 
81
 
 
82
 
                        // Don't blend dst with src if the mask is fully
83
 
                        // transparent
84
 
 
85
 
                        if (mask != 0) {
86
 
                            if (*mask == OPACITY_TRANSPARENT) {
87
 
                                mask++;
88
 
                                columns--;
89
 
                                srcN+=_CSTraits::channels_nb;
90
 
                                dstN+=_CSTraits::channels_nb;
91
 
                                continue;
92
 
                            }
93
 
                            mask++;
94
 
                        }
95
 
 
96
 
                        _compositeOp::composeColorChannels( NATIVE_OPACITY_OPAQUE, srcN, dstN, pixelSize, channelFlags );
97
 
 
98
 
                        columns--;
99
 
                        srcN += srcInc;
100
 
                        dstN += _CSTraits::channels_nb;
101
 
                    }
102
 
 
103
 
                    rows--;
104
 
                    srcRowStart += srcstride;
105
 
                    dstRowStart += dststride;
106
 
                    if(maskRowStart) {
107
 
                        maskRowStart += maskstride;
108
 
                    }
109
 
                }
110
 
            }
111
 
            else {
112
 
 
113
 
                channels_type opacity = KoColorSpaceMaths<quint8, channels_type>::scaleToA(U8_opacity);
114
 
                qint32 pixelSize = colorSpace()->pixelSize();
115
 
 
116
 
                while (rows > 0) {
117
 
                    const channels_type *srcN = reinterpret_cast<const channels_type *>(srcRowStart);
118
 
                    channels_type *dstN = reinterpret_cast<channels_type *>(dstRowStart);
119
 
                    const quint8 *mask = maskRowStart;
120
 
 
121
 
                    qint32 columns = cols;
122
 
 
123
 
                    while (columns > 0) {
124
 
 
125
 
                        channels_type srcAlpha = _compositeOp::selectAlpha(srcN[_CSTraits::alpha_pos], dstN[_CSTraits::alpha_pos]);
126
 
 
127
 
                        // apply the alphamask
128
 
                        if (mask != 0) {
129
 
                            if (*mask != OPACITY_OPAQUE) {
130
 
                                srcAlpha = KoColorSpaceMaths<channels_type,quint8>::multiply(srcAlpha, *mask);
131
 
                            }
132
 
                            mask++;
133
 
                        }
134
 
 
135
 
                        if (srcAlpha != NATIVE_OPACITY_TRANSPARENT) {
136
 
 
137
 
                            if (opacity != NATIVE_OPACITY_OPAQUE) {
138
 
                                srcAlpha = KoColorSpaceMaths<channels_type>::multiply(srcAlpha, opacity);
139
 
                            }
140
 
 
141
 
                            channels_type dstAlpha = dstN[_CSTraits::alpha_pos];
142
 
 
143
 
                            channels_type srcBlend;
144
 
 
145
 
                            if (dstAlpha == NATIVE_OPACITY_OPAQUE) {
 
63
                   const QBitArray & channelFlags) const {
 
64
 
 
65
        qint32 srcInc = (srcstride == 0) ? 0 : _CSTraits::channels_nb;
 
66
        bool allChannelFlags = channelFlags.isEmpty();
 
67
        if (_CSTraits::alpha_pos == -1) {
 
68
 
 
69
            qint32 pixelSize = _CSTraits::pixelSize;
 
70
 
 
71
            // XXX: if cols == (dststride/dstPixelSize) == (srcstride/srcPixelSize) == maskstride/maskpixelsize)
 
72
            // then don't loop through rows and cols, but composite everything in one go
 
73
            while (rows > 0) {
 
74
                const channels_type *srcN = reinterpret_cast<const channels_type *>(srcRowStart);
 
75
                channels_type *dstN = reinterpret_cast<channels_type *>(dstRowStart);
 
76
                const quint8 *mask = maskRowStart;
 
77
 
 
78
                qint32 columns = cols;
 
79
 
 
80
                while (columns > 0) {
 
81
 
 
82
 
 
83
                    // Don't blend dst with src if the mask is fully
 
84
                    // transparent
 
85
 
 
86
                    if (mask != 0) {
 
87
                        if (*mask == OPACITY_TRANSPARENT_U8) {
 
88
                            mask++;
 
89
                            columns--;
 
90
                            srcN += _CSTraits::channels_nb;
 
91
                            dstN += _CSTraits::channels_nb;
 
92
                            continue;
 
93
                        }
 
94
                        mask++;
 
95
                    }
 
96
 
 
97
                    _compositeOp::composeColorChannels(NATIVE_OPACITY_OPAQUE, srcN, dstN, pixelSize, allChannelFlags, channelFlags);
 
98
 
 
99
                    columns--;
 
100
                    srcN += srcInc;
 
101
                    dstN += _CSTraits::channels_nb;
 
102
                }
 
103
 
 
104
                rows--;
 
105
                srcRowStart += srcstride;
 
106
                dstRowStart += dststride;
 
107
                if (maskRowStart) {
 
108
                    maskRowStart += maskstride;
 
109
                }
 
110
            }
 
111
        } else {
 
112
            bool alphaLocked = false;
 
113
            if (!channelFlags.isEmpty()) {
 
114
                if (!channelFlags.testBit(_CSTraits::alpha_pos)) {
 
115
                    alphaLocked = true;
 
116
                }
 
117
            }
 
118
 
 
119
            channels_type opacity = KoColorSpaceMaths<quint8, channels_type>::scaleToA(U8_opacity);
 
120
            qint32 pixelSize = _CSTraits::pixelSize;
 
121
 
 
122
            while (rows > 0) {
 
123
                const channels_type *srcN = reinterpret_cast<const channels_type *>(srcRowStart);
 
124
                channels_type *dstN = reinterpret_cast<channels_type *>(dstRowStart);
 
125
                const quint8 *mask = maskRowStart;
 
126
 
 
127
                qint32 columns = cols;
 
128
 
 
129
                while (columns > 0) {
 
130
 
 
131
                    channels_type srcAlpha = _compositeOp::selectAlpha(srcN[_CSTraits::alpha_pos], dstN[_CSTraits::alpha_pos]);
 
132
 
 
133
                    // apply the alphamask
 
134
                    if (mask != 0) {
 
135
                        if (*mask != OPACITY_OPAQUE_U8) {
 
136
                            srcAlpha = KoColorSpaceMaths<channels_type, quint8>::multiply(srcAlpha, *mask);
 
137
                        }
 
138
                        mask++;
 
139
                    }
 
140
 
 
141
                    if (srcAlpha != NATIVE_OPACITY_TRANSPARENT) {
 
142
 
 
143
                        if (opacity != NATIVE_OPACITY_OPAQUE) {
 
144
                            srcAlpha = KoColorSpaceMaths<channels_type>::multiply(srcAlpha, opacity);
 
145
                        }
 
146
 
 
147
                        channels_type dstAlpha = dstN[_CSTraits::alpha_pos];
 
148
 
 
149
                        channels_type srcBlend;
 
150
 
 
151
                        if (dstAlpha == NATIVE_OPACITY_OPAQUE) {
 
152
                            srcBlend = srcAlpha;
 
153
                        } else {
 
154
                            channels_type newAlpha = dstAlpha + KoColorSpaceMaths<channels_type>::multiply(NATIVE_OPACITY_OPAQUE - dstAlpha, srcAlpha);
 
155
                            if (!alphaLocked && !_alphaLocked) {
 
156
                                dstN[_CSTraits::alpha_pos] = newAlpha;
 
157
                            }
 
158
 
 
159
                            if (newAlpha != 0) {
 
160
                                srcBlend = KoColorSpaceMaths<channels_type>::divide(srcAlpha, newAlpha);
 
161
                            } else {
146
162
                                srcBlend = srcAlpha;
147
 
                            } else {
148
 
                                channels_type newAlpha = dstAlpha + KoColorSpaceMaths<channels_type>::multiply(NATIVE_OPACITY_OPAQUE - dstAlpha, srcAlpha);
149
 
                                dstN[_CSTraits::alpha_pos] = newAlpha;
150
 
 
151
 
                                if (newAlpha != 0) {
152
 
                                    srcBlend = KoColorSpaceMaths<channels_type>::divide(srcAlpha, newAlpha);
153
 
                                } else {
154
 
                                    srcBlend = srcAlpha;
155
 
                                }
156
163
                            }
157
 
                            _compositeOp::composeColorChannels( srcBlend, srcN, dstN, pixelSize, channelFlags );
158
 
 
159
164
                        }
160
 
                        columns--;
161
 
                        srcN += srcInc;
162
 
                        dstN+=_CSTraits::channels_nb;
163
 
                    }
164
 
 
165
 
                    rows--;
166
 
                    srcRowStart += srcstride;
167
 
                    dstRowStart += dststride;
168
 
                    if(maskRowStart) {
169
 
                        maskRowStart += maskstride;
170
 
                    }
 
165
                        _compositeOp::composeColorChannels(srcBlend, srcN, dstN, pixelSize, allChannelFlags, channelFlags);
 
166
 
 
167
                    }
 
168
                    columns--;
 
169
                    srcN += srcInc;
 
170
                    dstN += _CSTraits::channels_nb;
 
171
                }
 
172
 
 
173
                rows--;
 
174
                srcRowStart += srcstride;
 
175
                dstRowStart += dststride;
 
176
                if (maskRowStart) {
 
177
                    maskRowStart += maskstride;
171
178
                }
172
179
            }
173
180
        }
 
181
    }
174
182
};
175
183
 
176
184
#endif