1 /*
2 * Copyright (c) 2010 Cyrille Berger <cberger@cberger.net>
3 * Copyright (c) 2010 Lukáš Tvrdý <lukast.dev@gmail.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include "TestKoCompositeOps.h"
22
23 #include <QTest>
24
25 #include <KoColorSpace.h>
26
27 #include "../compositeops/KoCompositeOpAlphaDarken.h"
28 #include "../compositeops/KoCompositeOpOver.h"
29
30 #include <KoColorSpaceTraits.h>
31
32 #define FULL_OPACITY KoColorSpaceMathsTraits<quint16>::unitValue
33 #define HALF_OPACITY (FULL_OPACITY/2)
34 #define QUARTER_OPACITY (FULL_OPACITY/4)
35
36 #define QCOMPAREui(a,b) QCOMPARE(a, (quint16)b)
37
38 #include <KoCompositeOpDivide.h>
39 #include <KoCompositeOpDodge.h>
40 #include <KoCompositeOpInversedSubtract.h>
41 #include <KoCompositeOpMultiply.h>
42 #include <KoCompositeOpOverlay.h>
43 #include <KoCompositeOpScreen.h>
44 #include <KoCompositeOpSubtract.h>
45 #include <KoCompositeOpCopy.h>
46 #include <KoCompositeOpCopy2.h>
47
48 #include <KoColorSpaceRegistry.h>
49 #include <KoColor.h>
50
testCompositeOver()51 void TestKoCompositeOps::testCompositeOver()
52 {
53 KoBgrU16Traits::Pixel p16f;
54 KoBgrU16Traits::Pixel p16f1;
55 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
56 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
57
58 KoCompositeOpOver<KoBgrU16Traits> over(0);
59 // Test no mask, full opacity
60 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
61 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
62 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
63 QCOMPAREui(p16f1.red, 10000);
64 QCOMPAREui(p16f1.green, 15000);
65 QCOMPAREui(p16f1.blue, 20000);
66 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
67
68 // Test no mask, half opacity
69 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
70 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
71 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
72 QCOMPAREui(p16f1.red, 12510);
73 QCOMPAREui(p16f1.green, 7972);
74 QCOMPAREui(p16f1.blue, 17992);
75 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
76
77 // Test mask, full opacity
78 quint8 mask; mask = 127;
79 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
80 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
81 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
82 QCOMPAREui(p16f1.red, 12510);
83 QCOMPAREui(p16f1.green, 7972);
84 QCOMPAREui(p16f1.blue, 17992);
85 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
86
87 // Test mask, half opacity
88 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
89 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
90 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
91 QCOMPAREui(p16f1.red, 13760);
92 QCOMPAREui(p16f1.green, 4472);
93 QCOMPAREui(p16f1.blue, 16992);
94 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
95
96 // Test no mask, full opacity, transparent source
97 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
98 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
99 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
100 QCOMPAREui(p16f1.red, 15000);
101 QCOMPAREui(p16f1.green, 1000);
102 QCOMPAREui(p16f1.blue, 16000);
103 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
104
105 // Test no mask, full opacity, transparent dst
106 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
107 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
108 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
109 QCOMPAREui(p16f1.red, 10000);
110 QCOMPAREui(p16f1.green, 15000);
111 QCOMPAREui(p16f1.blue, 20000);
112 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
113
114 // Test no mask, full opacity, half-transparent dst
115 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
116 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
117 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
118 QCOMPAREui(p16f1.red, 10000);
119 QCOMPAREui(p16f1.green, 15000);
120 QCOMPAREui(p16f1.blue, 20000);
121 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
122
123 // Test no mask, full opacity, half-transparent src
124 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
125 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
126 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
127 QCOMPAREui(p16f1.red, 12501);
128 QCOMPAREui(p16f1.green, 7999);
129 QCOMPAREui(p16f1.blue, 17999);
130 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
131
132 // Test no mask, full opacity, half-transparent src, dst
133 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
134 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
135 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
136 QCOMPAREui(p16f1.red, 11667);
137 QCOMPAREui(p16f1.green, 10333);
138 QCOMPAREui(p16f1.blue, 18666);
139 QCOMPAREui(p16f1.alpha, 49151);
140
141 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
142 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
143 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
144 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
145 QCOMPAREui(p16f1.red, 13001);
146 QCOMPAREui(p16f1.green, 6599);
147 QCOMPAREui(p16f1.blue, 17599);
148 QCOMPAREui(p16f1.alpha, 40959);
149
150 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
151 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
152 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
153 over.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
154 QCOMPAREui(p16f1.red, 11000);
155 QCOMPAREui(p16f1.green, 12200);
156 QCOMPAREui(p16f1.blue, 19200);
157 QCOMPAREui(p16f1.alpha, 40959);
158 }
159
testCompositeAlphaDarken()160 void TestKoCompositeOps::testCompositeAlphaDarken()
161 {
162 KoBgrU16Traits::Pixel p16f;
163 KoBgrU16Traits::Pixel p16f1;
164 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
165 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
166
167 KoCompositeOpAlphaDarken<KoBgrU16Traits> alphaDarken(0);
168 // Test no mask, full opacity
169 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
170 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
171 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
172 QCOMPAREui(p16f1.red, 10000);
173 QCOMPAREui(p16f1.green, 15000);
174 QCOMPAREui(p16f1.blue, 20000);
175 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
176
177 // Test no mask, half opacity
178 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
179 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
180 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
181 QCOMPAREui(p16f1.red, 12510);
182 QCOMPAREui(p16f1.green, 7972);
183 QCOMPAREui(p16f1.blue, 17992);
184 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
185
186 // Test mask, full opacity
187 quint8 mask; mask = 127;
188 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
189 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
190 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
191 QCOMPAREui(p16f1.red, 12510);
192 QCOMPAREui(p16f1.green, 7972);
193 QCOMPAREui(p16f1.blue, 17992);
194 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
195
196 // Test mask, half opacity
197 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
198 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
199 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
200 QCOMPAREui(p16f1.red, 13760);
201 QCOMPAREui(p16f1.green, 4472);
202 QCOMPAREui(p16f1.blue, 16992);
203 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
204
205 // Test no mask, full opacity, transparent source
206 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
207 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
208 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
209 QCOMPAREui(p16f1.red, 15000);
210 QCOMPAREui(p16f1.green, 1000);
211 QCOMPAREui(p16f1.blue, 16000);
212 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
213
214 // Test no mask, full opacity, transparent dst
215 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
216 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
217 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
218 QCOMPAREui(p16f1.red, 10000);
219 QCOMPAREui(p16f1.green, 15000);
220 QCOMPAREui(p16f1.blue, 20000);
221 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
222
223 // Test no mask, full opacity, half-transparent dst
224 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
225 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
226 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
227 QCOMPAREui(p16f1.red, 10000);
228 QCOMPAREui(p16f1.green, 15000);
229 QCOMPAREui(p16f1.blue, 20000);
230 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
231
232 // Test no mask, full opacity, half-transparent src
233 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
234 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
235 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
236 QCOMPAREui(p16f1.red, 12501);
237 QCOMPAREui(p16f1.green, 7999);
238 QCOMPAREui(p16f1.blue, 17999);
239 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
240
241 // Test no mask, full opacity, half-transparent src
242 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
243 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
244 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
245 QCOMPAREui(p16f1.red, 12501);
246 QCOMPAREui(p16f1.green, 7999);
247 QCOMPAREui(p16f1.blue, 17999);
248 QCOMPAREui(p16f1.alpha, 49150);
249
250 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
251 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
252 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
253 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
254 QCOMPAREui(p16f1.red, 13751);
255 QCOMPAREui(p16f1.green, 4499);
256 QCOMPAREui(p16f1.blue, 16999);
257 QCOMPAREui(p16f1.alpha, 40958);
258
259 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
260 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
261 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
262 alphaDarken.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
263 QCOMPAREui(p16f1.red, 12501);
264 QCOMPAREui(p16f1.green, 7999);
265 QCOMPAREui(p16f1.blue, 17999);
266 QCOMPAREui(p16f1.alpha, 40958);
267 }
268
testCompositeDivide()269 void TestKoCompositeOps::testCompositeDivide()
270 {
271 KoBgrU16Traits::Pixel p16f;
272 KoBgrU16Traits::Pixel p16f1;
273 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
274 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
275
276 KoCompositeOpDivide<KoBgrU16Traits> divide(0);
277 // Test no mask, full opacity
278 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
279 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
280 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
281 QCOMPAREui(p16f1.red, 65535);
282 QCOMPAREui(p16f1.green, 4369);
283 QCOMPAREui(p16f1.blue, 52426);
284 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
285
286 // Test no mask, half opacity
287 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
288 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
289 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
290 QCOMPAREui(p16f1.red, 40168);
291 QCOMPAREui(p16f1.green, 2677);
292 QCOMPAREui(p16f1.blue, 34141);
293 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
294
295 // Test mask, full opacity
296 quint8 mask; mask = 127;
297 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
298 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
299 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
300 QCOMPAREui(p16f1.red, 40168);
301 QCOMPAREui(p16f1.green, 2677);
302 QCOMPAREui(p16f1.blue, 34141);
303 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
304
305 // Test mask, half opacity
306 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
307 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
308 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
309 QCOMPAREui(p16f1.red, 27534);
310 QCOMPAREui(p16f1.green, 1835);
311 QCOMPAREui(p16f1.blue, 25034);
312 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
313
314 // Test no mask, full opacity, transparent source
315 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
316 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
317 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
318 QCOMPAREui(p16f1.red, 15000);
319 QCOMPAREui(p16f1.green, 1000);
320 QCOMPAREui(p16f1.blue, 16000);
321 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
322
323 // Test no mask, full opacity, transparent dst
324 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
325 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
326 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
327 QCOMPAREui(p16f1.red, 15000);
328 QCOMPAREui(p16f1.green, 1000);
329 QCOMPAREui(p16f1.blue, 16000);
330 QCOMPAREui(p16f1.alpha, 0);
331
332 // Test no mask, full opacity, half-transparent dst
333 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
334 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
335 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
336 QCOMPAREui(p16f1.red, 48690);
337 QCOMPAREui(p16f1.green, 3246);
338 QCOMPAREui(p16f1.blue, 40284);
339 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
340
341 // Test no mask, full opacity, half-transparent src
342 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
343 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
344 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
345 QCOMPAREui(p16f1.red, 40267);
346 QCOMPAREui(p16f1.green, 2684);
347 QCOMPAREui(p16f1.blue, 34212);
348 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
349
350 // Test no mask, full opacity, half-transparent src
351 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
352 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
353 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
354 QCOMPAREui(p16f1.red, 48690);
355 QCOMPAREui(p16f1.green, 3246);
356 QCOMPAREui(p16f1.blue, 40284);
357 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
358
359 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
360 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
361 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
362 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
363 QCOMPAREui(p16f1.red, 35213);
364 QCOMPAREui(p16f1.green, 2347);
365 QCOMPAREui(p16f1.blue, 30569);
366 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
367
368 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
369 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
370 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
371 divide.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
372 QCOMPAREui(p16f1.red, 43877);
373 QCOMPAREui(p16f1.green, 2925);
374 QCOMPAREui(p16f1.blue, 36815);
375 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
376 }
377
testCompositeDodge()378 void TestKoCompositeOps::testCompositeDodge()
379 {
380 KoBgrU16Traits::Pixel p16f;
381 KoBgrU16Traits::Pixel p16f1;
382 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
383 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
384
385 KoCompositeOpDodge<KoBgrU16Traits> dodge(0);
386 // Test no mask, full opacity
387 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
388 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
389 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
390 QCOMPAREui(p16f1.red, 17700);
391 QCOMPAREui(p16f1.green, 1296);
392 QCOMPAREui(p16f1.blue, 23027);
393 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
394
395 // Test no mask, half opacity
396 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
397 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
398 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
399 QCOMPAREui(p16f1.red, 16344);
400 QCOMPAREui(p16f1.green, 1147);
401 QCOMPAREui(p16f1.blue, 19499);
402 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
403
404 // Test mask, full opacity
405 quint8 mask; mask = 127;
406 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
407 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
408 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
409 QCOMPAREui(p16f1.red, 16344);
410 QCOMPAREui(p16f1.green, 1147);
411 QCOMPAREui(p16f1.blue, 19499);
412 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
413
414 // Test mask, half opacity
415 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
416 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
417 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
418 QCOMPAREui(p16f1.red, 15669);
419 QCOMPAREui(p16f1.green, 1073);
420 QCOMPAREui(p16f1.blue, 17742);
421 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
422
423 // Test no mask, full opacity, transparent source
424 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
425 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
426 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
427 QCOMPAREui(p16f1.red, 15000);
428 QCOMPAREui(p16f1.green, 1000);
429 QCOMPAREui(p16f1.blue, 16000);
430 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
431
432 // Test no mask, full opacity, transparent dst
433 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
434 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
435 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
436 QCOMPAREui(p16f1.red, 15000);
437 QCOMPAREui(p16f1.green, 1000);
438 QCOMPAREui(p16f1.blue, 16000);
439 QCOMPAREui(p16f1.alpha, 0);
440
441 // Test no mask, full opacity, half-transparent dst
442 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
443 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
444 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
445 QCOMPAREui(p16f1.red, 16800);
446 QCOMPAREui(p16f1.green, 1197);
447 QCOMPAREui(p16f1.blue, 20684);
448 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
449
450 // Test no mask, full opacity, half-transparent src
451 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
452 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
453 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
454 QCOMPAREui(p16f1.red, 16349);
455 QCOMPAREui(p16f1.green, 1147);
456 QCOMPAREui(p16f1.blue, 19513);
457 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
458
459 // Test no mask, full opacity, half-transparent src
460 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
461 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
462 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
463 QCOMPAREui(p16f1.red, 16800);
464 QCOMPAREui(p16f1.green, 1197);
465 QCOMPAREui(p16f1.blue, 20684);
466 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
467
468 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
469 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
470 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
471 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
472 QCOMPAREui(p16f1.red, 16079);
473 QCOMPAREui(p16f1.green, 1118);
474 QCOMPAREui(p16f1.blue, 18810);
475 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
476
477 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
478 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
479 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
480 dodge.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
481 QCOMPAREui(p16f1.red, 16542);
482 QCOMPAREui(p16f1.green, 1169);
483 QCOMPAREui(p16f1.blue, 20015);
484 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
485 }
486
testCompositeInversedSubtract()487 void TestKoCompositeOps::testCompositeInversedSubtract()
488 {
489 KoBgrU16Traits::Pixel p16f;
490 KoBgrU16Traits::Pixel p16f1;
491 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
492 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
493
494 KoCompositeOpInversedSubtract<KoBgrU16Traits> inversedSubtract(0);
495 // Test no mask, full opacity
496 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
497 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
498 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
499 QCOMPAREui(p16f1.red, 0);
500 QCOMPAREui(p16f1.green, 14000);
501 QCOMPAREui(p16f1.blue, 4000);
502 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
503
504 // Test no mask, half opacity
505 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
506 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
507 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
508 QCOMPAREui(p16f1.red, 7530);
509 QCOMPAREui(p16f1.green, 7474);
510 QCOMPAREui(p16f1.blue, 10024);
511 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
512
513 // Test mask, full opacity
514 quint8 mask; mask = 127;
515 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
516 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
517 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
518 QCOMPAREui(p16f1.red, 7530);
519 QCOMPAREui(p16f1.green, 7474);
520 QCOMPAREui(p16f1.blue, 10024);
521 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
522
523 // Test mask, half opacity
524 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
525 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
526 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
527 QCOMPAREui(p16f1.red, 11280);
528 QCOMPAREui(p16f1.green, 4224);
529 QCOMPAREui(p16f1.blue, 13024);
530 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
531
532 // Test no mask, full opacity, transparent source
533 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
534 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
535 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
536 QCOMPAREui(p16f1.red, 15000);
537 QCOMPAREui(p16f1.green, 1000);
538 QCOMPAREui(p16f1.blue, 16000);
539 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
540
541 // Test no mask, full opacity, transparent dst
542 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
543 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
544 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
545 QCOMPAREui(p16f1.red, 15000);
546 QCOMPAREui(p16f1.green, 1000);
547 QCOMPAREui(p16f1.blue, 16000);
548 QCOMPAREui(p16f1.alpha, 0);
549
550 // Test no mask, full opacity, half-transparent dst
551 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
552 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
553 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
554 QCOMPAREui(p16f1.red, 5000);
555 QCOMPAREui(p16f1.green, 9666);
556 QCOMPAREui(p16f1.blue, 8000);
557 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
558
559 // Test no mask, full opacity, half-transparent src
560 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
561 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
562 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
563 QCOMPAREui(p16f1.red, 7501);
564 QCOMPAREui(p16f1.green, 7499);
565 QCOMPAREui(p16f1.blue, 10001);
566 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
567
568 // Test no mask, full opacity, half-transparent src
569 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
570 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
571 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
572 QCOMPAREui(p16f1.red, 5000);
573 QCOMPAREui(p16f1.green, 9666);
574 QCOMPAREui(p16f1.blue, 8000);
575 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
576
577 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
578 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
579 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
580 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
581 QCOMPAREui(p16f1.red, 9001);
582 QCOMPAREui(p16f1.green, 6199);
583 QCOMPAREui(p16f1.blue, 11201);
584 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
585
586 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
587 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
588 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
589 inversedSubtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
590 QCOMPAREui(p16f1.red, 6429);
591 QCOMPAREui(p16f1.green, 8428);
592 QCOMPAREui(p16f1.blue, 9143);
593 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
594 }
595
testCompositeMulitply()596 void TestKoCompositeOps::testCompositeMulitply()
597 {
598 KoBgrU16Traits::Pixel p16f;
599 KoBgrU16Traits::Pixel p16f1;
600 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
601 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
602
603 KoCompositeOpMultiply<KoBgrU16Traits> mulitply(0);
604 // Test no mask, full opacity
605 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
606 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
607 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
608 QCOMPAREui(p16f1.red, 2289);
609 QCOMPAREui(p16f1.green, 229);
610 QCOMPAREui(p16f1.blue, 4883);
611 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
612
613 // Test no mask, half opacity
614 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
615 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
616 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
617 QCOMPAREui(p16f1.red, 8670);
618 QCOMPAREui(p16f1.green, 617);
619 QCOMPAREui(p16f1.blue, 10464);
620 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
621
622 // Test mask, full opacity
623 quint8 mask; mask = 127;
624 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
625 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
626 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
627 QCOMPAREui(p16f1.red, 8670);
628 QCOMPAREui(p16f1.green, 617);
629 QCOMPAREui(p16f1.blue, 10464);
630 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
631
632 // Test mask, half opacity
633 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
634 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
635 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
636 QCOMPAREui(p16f1.red, 11848);
637 QCOMPAREui(p16f1.green, 809);
638 QCOMPAREui(p16f1.blue, 13243);
639 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
640
641 // Test no mask, full opacity, transparent source
642 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
643 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
644 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
645 QCOMPAREui(p16f1.red, 15000);
646 QCOMPAREui(p16f1.green, 1000);
647 QCOMPAREui(p16f1.blue, 16000);
648 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
649
650 // Test no mask, full opacity, transparent dst
651 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
652 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
653 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
654 QCOMPAREui(p16f1.red, 15000);
655 QCOMPAREui(p16f1.green, 1000);
656 QCOMPAREui(p16f1.blue, 16000);
657 QCOMPAREui(p16f1.alpha, 0);
658
659 // Test no mask, full opacity, half-transparent dst
660 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
661 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
662 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
663 QCOMPAREui(p16f1.red, 6526);
664 QCOMPAREui(p16f1.green, 486);
665 QCOMPAREui(p16f1.blue, 8589);
666 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
667
668 // Test no mask, full opacity, half-transparent src
669 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
670 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
671 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
672 QCOMPAREui(p16f1.red, 8645);
673 QCOMPAREui(p16f1.green, 615);
674 QCOMPAREui(p16f1.blue, 10442);
675 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
676
677 // Test no mask, full opacity, half-transparent src
678 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
679 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
680 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
681 QCOMPAREui(p16f1.red, 6526);
682 QCOMPAREui(p16f1.green, 486);
683 QCOMPAREui(p16f1.blue, 8589);
684 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
685
686 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
687 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
688 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
689 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
690 QCOMPAREui(p16f1.red, 9916);
691 QCOMPAREui(p16f1.green, 692);
692 QCOMPAREui(p16f1.blue, 11554);
693 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
694
695 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
696 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
697 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
698 mulitply.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
699 QCOMPAREui(p16f1.red, 7737);
700 QCOMPAREui(p16f1.green, 560);
701 QCOMPAREui(p16f1.blue, 9648);
702 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
703 }
704
testCompositeOverlay()705 void TestKoCompositeOps::testCompositeOverlay()
706 {
707 KoBgrU16Traits::Pixel p16f;
708 KoBgrU16Traits::Pixel p16f1;
709 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
710 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
711
712 KoCompositeOpOverlay<KoBgrU16Traits> overlay(0);
713 // Test no mask, full opacity
714 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
715 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
716 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
717 QCOMPAREui(p16f1.red, 6963);
718 QCOMPAREui(p16f1.green, 466);
719 QCOMPAREui(p16f1.blue, 11288);
720 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
721
722 // Test no mask, half opacity
723 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
724 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
725 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
726 QCOMPAREui(p16f1.red, 10998);
727 QCOMPAREui(p16f1.green, 735);
728 QCOMPAREui(p16f1.blue, 13654);
729 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
730
731 // Test mask, full opacity
732 quint8 mask; mask = 127;
733 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
734 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
735 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
736 QCOMPAREui(p16f1.red, 10998);
737 QCOMPAREui(p16f1.green, 735);
738 QCOMPAREui(p16f1.blue, 13654);
739 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
740
741 // Test mask, half opacity
742 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
743 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
744 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
745 QCOMPAREui(p16f1.red, 13007);
746 QCOMPAREui(p16f1.green, 868);
747 QCOMPAREui(p16f1.blue, 14832);
748 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
749
750 // Test no mask, full opacity, transparent source
751 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
752 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
753 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
754 QCOMPAREui(p16f1.red, 15000);
755 QCOMPAREui(p16f1.green, 1000);
756 QCOMPAREui(p16f1.blue, 16000);
757 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
758
759 // Test no mask, full opacity, transparent dst
760 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
761 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
762 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
763 QCOMPAREui(p16f1.red, 15000);
764 QCOMPAREui(p16f1.green, 1000);
765 QCOMPAREui(p16f1.blue, 16000);
766 QCOMPAREui(p16f1.alpha, 0);
767
768 // Test no mask, full opacity, half-transparent dst
769 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
770 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
771 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
772 QCOMPAREui(p16f1.red, 9642);
773 QCOMPAREui(p16f1.green, 644);
774 QCOMPAREui(p16f1.blue, 12859);
775 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
776
777 // Test no mask, full opacity, half-transparent src
778 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
779 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
780 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
781 QCOMPAREui(p16f1.red, 10982);
782 QCOMPAREui(p16f1.green, 734);
783 QCOMPAREui(p16f1.blue, 13645);
784 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
785
786 // Test no mask, full opacity, half-transparent src
787 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
788 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
789 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
790 QCOMPAREui(p16f1.red, 9642);
791 QCOMPAREui(p16f1.green, 644);
792 QCOMPAREui(p16f1.blue, 12859);
793 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
794
795 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
796 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
797 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
798 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
799 QCOMPAREui(p16f1.red, 11786);
800 QCOMPAREui(p16f1.green, 787);
801 QCOMPAREui(p16f1.blue, 14116);
802 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
803
804 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
805 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
806 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
807 overlay.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
808 QCOMPAREui(p16f1.red, 10408);
809 QCOMPAREui(p16f1.green, 695);
810 QCOMPAREui(p16f1.blue, 13308);
811 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
812 }
813
testCompositeScreen()814 void TestKoCompositeOps::testCompositeScreen()
815 {
816 KoBgrU16Traits::Pixel p16f;
817 KoBgrU16Traits::Pixel p16f1;
818 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
819 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
820
821 KoCompositeOpScreen<KoBgrU16Traits> screen(0);
822 // Test no mask, full opacity
823 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
824 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
825 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
826 QCOMPAREui(p16f1.red, 22711);
827 QCOMPAREui(p16f1.green, 15771);
828 QCOMPAREui(p16f1.blue, 31117);
829 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
830
831 // Test no mask, half opacity
832 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
833 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
834 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
835 QCOMPAREui(p16f1.red, 18840);
836 QCOMPAREui(p16f1.green, 8356);
837 QCOMPAREui(p16f1.blue, 23528);
838 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
839
840 // Test mask, full opacity
841 quint8 mask; mask = 127;
842 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
843 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
844 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
845 QCOMPAREui(p16f1.red, 18840);
846 QCOMPAREui(p16f1.green, 8356);
847 QCOMPAREui(p16f1.blue, 23528);
848 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
849
850 // Test mask, half opacity
851 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
852 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
853 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
854 QCOMPAREui(p16f1.red, 16912);
855 QCOMPAREui(p16f1.green, 4663);
856 QCOMPAREui(p16f1.blue, 19749);
857 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
858
859 // Test no mask, full opacity, transparent source
860 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
861 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
862 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
863 QCOMPAREui(p16f1.red, 15000);
864 QCOMPAREui(p16f1.green, 1000);
865 QCOMPAREui(p16f1.blue, 16000);
866 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
867
868 // Test no mask, full opacity, transparent dst
869 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
870 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
871 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
872 QCOMPAREui(p16f1.red, 15000);
873 QCOMPAREui(p16f1.green, 1000);
874 QCOMPAREui(p16f1.blue, 16000);
875 QCOMPAREui(p16f1.alpha, 0);
876
877 // Test no mask, full opacity, half-transparent dst
878 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
879 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
880 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
881 QCOMPAREui(p16f1.red, 20140);
882 QCOMPAREui(p16f1.green, 10847);
883 QCOMPAREui(p16f1.blue, 26078);
884 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
885
886 // Test no mask, full opacity, half-transparent src
887 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
888 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
889 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
890 QCOMPAREui(p16f1.red, 18855);
891 QCOMPAREui(p16f1.green, 8385);
892 QCOMPAREui(p16f1.blue, 23558);
893 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
894
895 // Test no mask, full opacity, half-transparent src
896 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
897 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
898 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
899 QCOMPAREui(p16f1.red, 20140);
900 QCOMPAREui(p16f1.green, 10847);
901 QCOMPAREui(p16f1.blue, 26078);
902 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
903
904 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
905 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
906 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
907 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
908 QCOMPAREui(p16f1.red, 18084);
909 QCOMPAREui(p16f1.green, 6908);
910 QCOMPAREui(p16f1.blue, 22046);
911 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
912
913 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
914 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
915 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
916 screen.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
917 QCOMPAREui(p16f1.red, 19406);
918 QCOMPAREui(p16f1.green, 9440);
919 QCOMPAREui(p16f1.blue, 24638);
920 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
921 }
922
testCompositeSubtract()923 void TestKoCompositeOps::testCompositeSubtract()
924 {
925 KoBgrU16Traits::Pixel p16f;
926 KoBgrU16Traits::Pixel p16f1;
927 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
928 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
929
930 KoCompositeOpSubtract<KoBgrU16Traits> subtract(0);
931 // Test no mask, full opacity
932 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
933 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
934 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
935 QCOMPAREui(p16f1.red, 5000);
936 QCOMPAREui(p16f1.green, 0);
937 QCOMPAREui(p16f1.blue, 0);
938 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
939
940 // Test no mask, half opacity
941 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
942 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
943 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
944 QCOMPAREui(p16f1.red, 10020);
945 QCOMPAREui(p16f1.green, 502);
946 QCOMPAREui(p16f1.blue, 8032);
947 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
948
949 // Test mask, full opacity
950 quint8 mask; mask = 127;
951 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
952 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
953 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
954 QCOMPAREui(p16f1.red, 10020);
955 QCOMPAREui(p16f1.green, 502);
956 QCOMPAREui(p16f1.blue, 8032);
957 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
958
959 // Test mask, half opacity
960 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
961 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
962 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
963 QCOMPAREui(p16f1.red, 12520);
964 QCOMPAREui(p16f1.green, 752);
965 QCOMPAREui(p16f1.blue, 12032);
966 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
967
968 // Test no mask, full opacity, transparent source
969 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
970 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
971 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
972 QCOMPAREui(p16f1.red, 15000);
973 QCOMPAREui(p16f1.green, 1000);
974 QCOMPAREui(p16f1.blue, 16000);
975 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
976
977 // Test no mask, full opacity, transparent dst
978 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
979 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
980 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
981 QCOMPAREui(p16f1.red, 15000);
982 QCOMPAREui(p16f1.green, 1000);
983 QCOMPAREui(p16f1.blue, 16000);
984 QCOMPAREui(p16f1.alpha, 0);
985
986 // Test no mask, full opacity, half-transparent dst
987 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
988 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
989 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
990 QCOMPAREui(p16f1.red, 8334);
991 QCOMPAREui(p16f1.green, 334);
992 QCOMPAREui(p16f1.blue, 5334);
993 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
994
995 // Test no mask, full opacity, half-transparent src
996 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
997 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
998 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
999 QCOMPAREui(p16f1.red, 10001);
1000 QCOMPAREui(p16f1.green, 501);
1001 QCOMPAREui(p16f1.blue, 8001);
1002 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1003
1004 // Test no mask, full opacity, half-transparent src
1005 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1006 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
1007 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1008 QCOMPAREui(p16f1.red, 8334);
1009 QCOMPAREui(p16f1.green, 334);
1010 QCOMPAREui(p16f1.blue, 5334);
1011 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
1012
1013 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
1014 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
1015 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
1016 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1017 QCOMPAREui(p16f1.red, 11001);
1018 QCOMPAREui(p16f1.green, 601);
1019 QCOMPAREui(p16f1.blue, 9601);
1020 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
1021
1022 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
1023 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1024 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
1025 subtract.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1026 QCOMPAREui(p16f1.red, 9286);
1027 QCOMPAREui(p16f1.green, 429);
1028 QCOMPAREui(p16f1.blue, 6858);
1029 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
1030 }
1031
testCompositeCopy2()1032 void TestKoCompositeOps::testCompositeCopy2()
1033 {
1034 KoBgrU16Traits::Pixel p16f;
1035 KoBgrU16Traits::Pixel p16f1;
1036 quint8 *p16fPtr = reinterpret_cast<quint8 *>(&p16f);
1037 quint8 *p16fPtr1 = reinterpret_cast<quint8 *>(&p16f1);
1038
1039 KoCompositeOpCopy2<KoBgrU16Traits> copy(0);
1040 // Test no mask, full opacity
1041 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1042 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1043 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1044 QCOMPAREui(p16f1.red, 10000);
1045 QCOMPAREui(p16f1.green, 15000);
1046 QCOMPAREui(p16f1.blue, 20000);
1047 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1048
1049 // Test no mask, half opacity
1050 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1051 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1052 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
1053 QCOMPAREui(p16f1.red, 12510);
1054 QCOMPAREui(p16f1.green, 7972);
1055 QCOMPAREui(p16f1.blue, 17992);
1056 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1057
1058 // Test mask, full opacity
1059 quint8 mask; mask = 127;
1060 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1061 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1062 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 255);
1063 QCOMPAREui(p16f1.red, 12510);
1064 QCOMPAREui(p16f1.green, 7972);
1065 QCOMPAREui(p16f1.blue, 17992);
1066 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1067
1068 // Test mask, half opacity
1069 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1070 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1071 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 1, 1, 1, 127);
1072 QCOMPAREui(p16f1.red, 13760);
1073 QCOMPAREui(p16f1.green, 4472);
1074 QCOMPAREui(p16f1.blue, 16992);
1075 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1076
1077 // Test no mask, full opacity, transparent source
1078 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = 0;
1079 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1080 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1081 QCOMPAREui(p16f1.red, 10000);
1082 QCOMPAREui(p16f1.green, 15000);
1083 QCOMPAREui(p16f1.blue, 20000);
1084 QCOMPAREui(p16f1.alpha, 0);
1085
1086 // Test no mask, full opacity, transparent dst
1087 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1088 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = 0;
1089 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1090 QCOMPAREui(p16f1.red, 10000);
1091 QCOMPAREui(p16f1.green, 15000);
1092 QCOMPAREui(p16f1.blue, 20000);
1093 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1094
1095 // Test no mask, full opacity, half-transparent dst
1096 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = FULL_OPACITY;
1097 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
1098 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1099 QCOMPAREui(p16f1.red, 10000);
1100 QCOMPAREui(p16f1.green, 15000);
1101 QCOMPAREui(p16f1.blue, 20000);
1102 QCOMPAREui(p16f1.alpha, FULL_OPACITY);
1103
1104 // Test no mask, full opacity, half-transparent src
1105 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1106 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = FULL_OPACITY;
1107 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1108 QCOMPAREui(p16f1.red, 10000);
1109 QCOMPAREui(p16f1.green, 15000);
1110 QCOMPAREui(p16f1.blue, 20000);
1111 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
1112
1113 // Test no mask, full opacity, half-transparent src
1114 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1115 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
1116 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1117 QCOMPAREui(p16f1.red, 10000);
1118 QCOMPAREui(p16f1.green, 15000);
1119 QCOMPAREui(p16f1.blue, 20000);
1120 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
1121
1122 // Test no mask, full opacity, quarter-transparent src, half-transparent dst
1123 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = QUARTER_OPACITY;
1124 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = HALF_OPACITY;
1125 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1126 QCOMPAREui(p16f1.red, 10000);
1127 QCOMPAREui(p16f1.green, 15000);
1128 QCOMPAREui(p16f1.blue, 20000);
1129 QCOMPAREui(p16f1.alpha, QUARTER_OPACITY);
1130
1131 // Test no mask, full opacity, quarter-transparent dst, half-transparent src
1132 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1133 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
1134 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 255);
1135 QCOMPAREui(p16f1.red, 10000);
1136 QCOMPAREui(p16f1.green, 15000);
1137 QCOMPAREui(p16f1.blue, 20000);
1138 QCOMPAREui(p16f1.alpha, HALF_OPACITY);
1139
1140 // Test no mask, half opacity, quarter-transparent dst, half-transparent src
1141 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1142 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
1143 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, 0, 0, 1, 1, 127);
1144 QCOMPAREui(p16f1.red, 12510);
1145 QCOMPAREui(p16f1.green, 7972);
1146 QCOMPAREui(p16f1.blue, 17992);
1147 QCOMPAREui(p16f1.alpha, 24542);
1148
1149 // Test mask, half opacity, quarter-transparent dst, half-transparent src
1150 p16f.red = 10000; p16f.green = 15000; p16f.blue = 20000; p16f.alpha = HALF_OPACITY;
1151 p16f1.red = 15000; p16f1.green = 1000; p16f1.blue = 16000; p16f1.alpha = QUARTER_OPACITY;
1152 copy.composite(p16fPtr1, KoBgrU16Traits::pixelSize, p16fPtr, KoBgrU16Traits::pixelSize, &mask, 0, 1, 1, 127);
1153 QCOMPAREui(p16f1.red, 13760);
1154 QCOMPAREui(p16f1.green, 4472);
1155 QCOMPAREui(p16f1.blue, 16992);
1156 QCOMPAREui(p16f1.alpha, 20447);
1157 }
1158
testCompositeCopy()1159 void TestKoCompositeOps::testCompositeCopy()
1160 {
1161 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
1162 const KoCompositeOp *copy = cs->compositeOp(COMPOSITE_COPY);
1163
1164 KoColor black(Qt::black, cs);
1165 KoColor white(Qt::white, cs);
1166 KoColor opaque(QColor(0, 0, 0, 0), cs);
1167
1168 int w = 512;
1169 int h = 512;
1170
1171 int pixelCount = w * h;
1172 quint32 pixelSize = cs->pixelSize();
1173 // dst
1174 quint8 *layer = new quint8[pixelCount * pixelSize];
1175 quint8 *iter = layer;
1176 for (int i = 0; i < pixelCount; i++) {
1177 memcpy(iter, white.data(), pixelSize);
1178 iter += pixelSize;
1179 }
1180
1181 // full white image
1182 //cs->convertToQImage(layer, w, h, 0,KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()).save("0dst.png");
1183
1184 // src
1185 quint8 *dab = new quint8[pixelCount * pixelSize];
1186 iter = dab;
1187 for (int i = 0; i < pixelCount; i++) {
1188 memcpy(iter, black.data(), pixelSize);
1189 iter += pixelSize;
1190 }
1191
1192 // full black image
1193 //cs->convertToQImage(dab, w, h, 0,KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()).save("1src.png");
1194
1195 // selection
1196 quint32 selectionPixelSize = KoColorSpaceRegistry::instance()->alpha8()->pixelSize();
1197 quint8 *selection = new quint8[pixelCount * selectionPixelSize];
1198 iter = selection;
1199 for (int height = 0; height < h; height++) {
1200 for (int width = 0; width < w; width++) {
1201 if ((height > 128) && (height < 256) && (width > 128) && (width < 256)) {
1202 *iter = 255;
1203 } else {
1204 *iter = 0;
1205 }
1206 iter += selectionPixelSize;
1207 }
1208 }
1209
1210 // white rectangle at 128,128
1211 //KoColorSpaceRegistry::instance()->alpha8()->convertToQImage(selection, w, h, 0, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()).save("1mask.png");
1212
1213 copy->composite(layer, w * pixelSize,
1214 dab, w * pixelSize,
1215 0, 0,
1216 h, w,
1217 255,
1218 QBitArray());
1219
1220 // full black image
1221 //cs->convertToQImage(layer, w, h, 0,KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()).save("2result.png");
1222
1223 copy->composite(layer, w * pixelSize,
1224 opaque.data(), 0,
1225 0, 0,
1226 h, w,
1227 255,
1228 QBitArray()
1229 );
1230
1231 // full opaque image
1232 //cs->convertToQImage(layer, w, h, 0,KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()).save("3result.png");
1233
1234 copy->composite(layer, w * pixelSize,
1235 dab, w * pixelSize,
1236 selection, w * selectionPixelSize,
1237 h, w,
1238 255,
1239 QBitArray()
1240 );
1241
1242 // black rectangle on opaque background
1243 QImage result = cs->convertToQImage(layer, w, h, 0, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
1244 QImage expectedResult(QString(FILES_DATA_DIR) + QDir::separator() + "CopyWithSelectionExpectedResult.png");
1245
1246 bool testOk = (result == expectedResult);
1247 if (!testOk) {
1248 qDebug() << "Saving the result";
1249 result.save("CopyWithSelection.png");
1250 }
1251
1252 QVERIFY2(testOk, "Images are not equal");
1253
1254 copy->composite(layer, w * pixelSize,
1255 white.data(), 0,
1256 selection, w * selectionPixelSize,
1257 h, w,
1258 255,
1259 QBitArray());
1260
1261 result = cs->convertToQImage(layer, w, h, 0, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags());
1262 expectedResult = QImage(QString(FILES_DATA_DIR) + QDir::separator() + "CopySingleWithSelectionExpectedResult.png");
1263
1264 testOk = (result == expectedResult);
1265 if (!testOk) {
1266 qDebug() << expectedResult.size() << result.size();
1267 for (int row = 0; row < expectedResult.size().height(); ++row) {
1268 for (int col = 0; col < expectedResult.size().width(); ++ col) {
1269 QRgb res = result.pixel(col, row);
1270 QRgb exp = expectedResult.pixel(col, row);
1271 if (res != exp) {
1272 qDebug() << "wrong pixel:" << col << "," << row
1273 << "result:" << qRed(res) << qGreen(res) << qBlue(res) << qAlpha(res)
1274 << "expected" << qRed(exp) << qGreen(exp) << qBlue(exp) << qAlpha(exp);
1275 }
1276 }
1277 }
1278 expectedResult.save("expected result.png");
1279 result.save("CopySingleWithSelection.png");
1280 QFAIL("Images with single pixel and selection are not equal");
1281
1282 }
1283
1284 }
1285
1286 QTEST_GUILESS_MAIN(TestKoCompositeOps)
1287