1 /*
2 * Copyright (c) 2012 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #include "kis_filter_weights_applicator_test.h"
20
21 #include <QTest>
22
23 #include <KoColor.h>
24 #include <KoColorSpace.h>
25 #include <KoColorSpaceRegistry.h>
26 #include "kis_paint_device.h"
27 #include "kistest.h"
28
29 #include <sstream>
30
31 //#define DEBUG_ENABLED
32 #include "kis_filter_weights_applicator.h"
33
debugSpan(const KisFilterWeightsApplicator::BlendSpan & span)34 void debugSpan(const KisFilterWeightsApplicator::BlendSpan &span)
35 {
36 qDebug() << ppVar(span.weights->centerIndex);
37 for (int i = 0; i < span.weights->span; i++) {
38 qDebug() << "Weights" << i << span.weights->weight[i];
39 }
40
41 qDebug() << ppVar(span.firstBlendPixel);
42 qDebug() << ppVar(span.offset);
43 qDebug() << ppVar(span.offsetInc);
44 }
45
testSpan(qreal scale,qreal dx,int dst_l,int expectedFirstPixel,qreal expectedOffset,qreal expectedOffsetInc)46 void testSpan(qreal scale, qreal dx, int dst_l,
47 int expectedFirstPixel,
48 qreal expectedOffset,
49 qreal expectedOffsetInc)
50 {
51 KisFilterStrategy *filter = new KisBilinearFilterStrategy();
52
53 KisFilterWeightsBuffer buf(filter, qAbs(scale));
54 KisFilterWeightsApplicator applicator(0, 0, scale, 0.0, dx, false);
55 KisFilterWeightsApplicator::BlendSpan span;
56 span = applicator.calculateBlendSpan(dst_l, 0, &buf);
57
58 //debugSpan(span);
59
60 if (span.firstBlendPixel != expectedFirstPixel ||
61 span.offset != KisFixedPoint(expectedOffset) ||
62 span.offsetInc != KisFixedPoint(expectedOffsetInc)) {
63
64 qDebug() << "Failed to generate a span:";
65 qDebug() << ppVar(scale) << ppVar(dx) << ppVar(dst_l);
66 qDebug() << ppVar(span.firstBlendPixel) << ppVar(expectedFirstPixel);
67 qDebug() << ppVar(span.offset) << ppVar(KisFixedPoint(expectedOffset));
68 qDebug() << ppVar(span.offsetInc) << ppVar(KisFixedPoint(expectedOffsetInc));
69 QFAIL("fail");
70 }
71 }
72
testSpan_Scale_2_0_Aligned()73 void KisFilterWeightsApplicatorTest::testSpan_Scale_2_0_Aligned()
74 {
75 testSpan(2.0, 0.0, 0, -1, 0.25, 1.0);
76 testSpan(2.0, 0.0, 1, 0, 0.75, 1.0);
77 testSpan(2.0, 0.0, -1, -1, 0.75, 1.0);
78 testSpan(2.0, 0.0, -2, -2, 0.25, 1.0);
79 }
80
testSpan_Scale_2_0_Shift_0_5()81 void KisFilterWeightsApplicatorTest::testSpan_Scale_2_0_Shift_0_5()
82 {
83 testSpan(2.0, 0.5, 0, -1, 0.5, 1.0);
84 testSpan(2.0, 0.5, 1, -1, 0.0, 1.0);
85 testSpan(2.0, 0.5, -1, -2, 0.0, 1.0);
86 testSpan(2.0, 0.5, -2, -2, 0.5, 1.0);
87 }
88
testSpan_Scale_2_0_Shift_0_75()89 void KisFilterWeightsApplicatorTest::testSpan_Scale_2_0_Shift_0_75()
90 {
91 testSpan(2.0, 0.75, 0, -1, 0.625, 1.0);
92 testSpan(2.0, 0.75, 1, -1, 0.125, 1.0);
93 testSpan(2.0, 0.75, -1, -2, 0.125, 1.0);
94 testSpan(2.0, 0.75, -2, -2, 0.625, 1.0);
95 }
96
testSpan_Scale_0_5_Aligned()97 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Aligned()
98 {
99 testSpan(0.5, 0.0, 0, -1, 0.25, 0.5);
100 testSpan(0.5, 0.0, 1, 1, 0.25, 0.5);
101 testSpan(0.5, 0.0, -1, -3, 0.25, 0.5);
102 }
103
testSpan_Scale_0_5_Shift_0_5()104 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_0_5()
105 {
106 testSpan(0.5, 0.5, 0, -2, 0.25, 0.5);
107 testSpan(0.5, 0.5, 1, 0, 0.25, 0.5);
108 testSpan(0.5, 0.5, -1, -4, 0.25, 0.5);
109 }
110
testSpan_Scale_0_5_Shift_0_25()111 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_0_25()
112 {
113 testSpan(0.5, 0.25, 0, -2, 0.0, 0.5);
114 testSpan(0.5, 0.25, 1, 0, 0.0, 0.5);
115 testSpan(0.5, 0.25, -1, -4, 0.0, 0.5);
116 }
117
testSpan_Scale_0_5_Shift_0_375()118 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_0_375()
119 {
120 testSpan(0.5, 0.375, 0, -2, 0.125, 0.5);
121 testSpan(0.5, 0.375, 1, 0, 0.125, 0.5);
122 testSpan(0.5, 0.375, -1, -4, 0.125, 0.5);
123 }
124
testSpan_Scale_0_5_Shift_m0_5()125 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_m0_5()
126 {
127 testSpan(0.5, -0.5, 0, 0, 0.25, 0.5);
128 testSpan(0.5, -0.5, 1, 2, 0.25, 0.5);
129 testSpan(0.5, -0.5, -1, -2, 0.25, 0.5);
130 }
131
testSpan_Scale_0_5_Shift_m0_25()132 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_m0_25()
133 {
134 testSpan(0.5, -0.25, 0, -1, 0.0, 0.5);
135 testSpan(0.5, -0.25, 1, 1, 0.0, 0.5);
136 testSpan(0.5, -0.25, -1, -3, 0.0, 0.5);
137 }
138
testSpan_Scale_0_5_Shift_m0_375()139 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_m0_375()
140 {
141 testSpan(0.5, -0.375, 0, 0, 0.375, 0.5);
142 testSpan(0.5, -0.375, 1, 2, 0.375, 0.5);
143 testSpan(0.5, -0.375, -1, -2, 0.375, 0.5);
144 }
145
testSpan_Scale_1_0_Aligned_Mirrored()146 void KisFilterWeightsApplicatorTest::testSpan_Scale_1_0_Aligned_Mirrored()
147 {
148 testSpan(-1.0, 0.0, 0, -2, 0.0, 1.0);
149 testSpan(-1.0, 0.0, 1, -3, 0.0, 1.0);
150 testSpan(-1.0, 0.0, -1, -1, 0.0, 1.0);
151 testSpan(-1.0, 0.0, -2, 0, 0.0, 1.0);
152 }
153
testSpan_Scale_0_5_Aligned_Mirrored()154 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Aligned_Mirrored()
155 {
156 testSpan(-0.5, 0.0, 0, -3, 0.25, 0.5);
157 testSpan(-0.5, 0.0, 1, -5, 0.25, 0.5);
158 testSpan(-0.5, 0.0, -1, -1, 0.25, 0.5);
159 testSpan(-0.5, 0.0, -2, 1, 0.25, 0.5);
160 }
161
testSpan_Scale_0_5_Shift_0_125_Mirrored()162 void KisFilterWeightsApplicatorTest::testSpan_Scale_0_5_Shift_0_125_Mirrored()
163 {
164 testSpan(-0.5, 0.125, 0, -3, 0.125, 0.5);
165 testSpan(-0.5, 0.125, 1, -5, 0.125, 0.5);
166 testSpan(-0.5, 0.125, -1, -1, 0.125, 0.5);
167 testSpan(-0.5, 0.125, -2, 1, 0.125, 0.5);
168 }
169
printPixels(KisPaintDeviceSP dev,int x0,int len,bool horizontal,bool dense=false)170 void printPixels(KisPaintDeviceSP dev, int x0, int len, bool horizontal, bool dense = false)
171 {
172 std::stringstream ss;
173 for (int i = x0; i < x0 + len; i++) {
174 QColor c;
175
176 int x = horizontal ? i : 0;
177 int y = horizontal ? 0 : i;
178
179 dev->pixel(x, y, &c);
180 if (dense){
181 ss << c.red() << " , " << c.alpha() << " | ";
182 } else {
183 qDebug() << "px" << x << y << "|" << c.red() << c.green() << c.blue() << c.alpha();
184 }
185 }
186
187 if (dense) {
188 qDebug() << ss.str().c_str();
189 }
190 }
191
checkRA(KisPaintDeviceSP dev,int x0,int len,quint8 r[],quint8 a[],bool horizontal)192 void checkRA(KisPaintDeviceSP dev, int x0, int len, quint8 r[], quint8 a[], bool horizontal)
193 {
194 bool failed = false;
195 for (int i = 0; i < len; i++) {
196 QColor c;
197
198 int x = horizontal ? x0 + i : 0;
199 int y = horizontal ? 0 : x0 + i;
200
201 dev->pixel(x, y, &c);
202
203 if (c.red() != r[i] ||
204 c.alpha() != a[i]) {
205
206 qDebug() << "Failed to compare RA channels:" << ppVar(x0 + i);
207 qDebug() << "Red:" << c.red() << "Expected:" << r[i];
208 qDebug() << "Alpha:" << c.alpha() << "Expected:" << a[i];
209 failed = true;
210 }
211 }
212
213 if (failed) {
214 QFAIL("failed");
215 }
216 }
217
testLineImpl(qreal scale,qreal dx,quint8 expR[],quint8 expA[],int x0,int len,bool clampToEdge,bool horizontal,KisFilterStrategy * filter=0,KisPaintDeviceSP dev=0)218 void testLineImpl(qreal scale, qreal dx, quint8 expR[], quint8 expA[], int x0, int len, bool clampToEdge, bool horizontal, KisFilterStrategy *filter = 0, KisPaintDeviceSP dev = 0)
219 {
220 int startPos = 0;
221 int endPos = 4;
222 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
223 if (!filter) {
224 filter = new KisBilinearFilterStrategy();
225 }
226 if (!dev) {
227 dev = new KisPaintDevice(cs);
228
229 for (int i = 0; i < 4; i++) {
230 int x = horizontal ? i : 0;
231 int y = horizontal ? 0 : i;
232 dev->setPixel(x,y,QColor(10 + i * 10, 20 + i * 10, 40 + i * 10));
233 }
234
235 {
236 quint8 r[] = { 0, 10, 20, 30, 40, 0, 0};
237 quint8 a[] = { 0,255,255,255,255, 0, 0};
238 checkRA(dev, -1, 6, r, a, horizontal);
239 }
240
241 startPos = 0;
242 endPos = 4;
243
244 } else {
245 QRect rc = dev->exactBounds();
246 if (horizontal) {
247 startPos = rc.left();
248 endPos = rc.left() + rc.width();
249 } else {
250 startPos = rc.top();
251 endPos = rc.top() + rc.height();
252 }
253 }
254
255 KisFilterWeightsBuffer buf(filter, qAbs(scale));
256 KisFilterWeightsApplicator applicator(dev, dev, scale, 0.0, dx, clampToEdge);
257
258
259 KisFilterWeightsApplicator::LinePos srcPos(startPos, endPos);
260 KisFilterWeightsApplicator::LinePos dstPos;
261
262 if (horizontal) {
263 dstPos = applicator.processLine<KisHLineIteratorSP>(srcPos,0,&buf, filter->support(buf.weightsPositionScale().toFloat()));
264 } else {
265 dstPos = applicator.processLine<KisVLineIteratorSP>(srcPos,0,&buf, filter->support(buf.weightsPositionScale().toFloat()));
266 }
267
268 QRect rc = dev->exactBounds();
269
270 if (horizontal) {
271 QVERIFY(rc.left() >= dstPos.start());
272 QVERIFY(rc.left() + rc.width() <= dstPos.end());
273 } else {
274 QVERIFY(rc.top() >= dstPos.start());
275 QVERIFY(rc.top() + rc.height() <= dstPos.end());
276 }
277
278 //printPixels(dev, x0, len, horizontal, true);
279 checkRA(dev, x0, len, expR, expA, horizontal);
280 }
281
testLine(qreal scale,qreal dx,quint8 expR[],quint8 expA[],int x0,int len,bool clampToEdge=false,KisFilterStrategy * filter=0,KisPaintDeviceSP dev=0)282 void testLine(qreal scale, qreal dx, quint8 expR[], quint8 expA[], int x0, int len, bool clampToEdge = false, KisFilterStrategy* filter = 0, KisPaintDeviceSP dev = 0)
283 {
284 testLineImpl(scale, dx, expR, expA, x0, len, clampToEdge, true, filter, dev);
285 testLineImpl(scale, dx, expR, expA, x0, len, clampToEdge, false, filter, dev);
286 }
287
testProcessLine_Scale_1_0_Aligned()288 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Aligned()
289 {
290 qreal scale = 1.0;
291 qreal dx = 0.0;
292
293 quint8 r[] = { 0, 10, 20, 30, 40, 0, 0};
294 quint8 a[] = { 0,255,255,255,255, 0, 0};
295
296 testLine(scale, dx, r, a, -1, 7);
297 }
298
testProcessLine_Scale_1_0_Shift_0_5()299 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Shift_0_5()
300 {
301 qreal scale = 1.0;
302 qreal dx = 0.5;
303
304 quint8 r[] = { 0, 10, 15, 25, 35, 40, 0};
305 quint8 a[] = { 0,128,255,255,255,127, 0};
306
307 testLine(scale, dx, r, a, -1, 7);
308 }
309
testProcessLine_Scale_1_0_Shift_m0_5()310 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Shift_m0_5()
311 {
312 qreal scale = 1.0;
313 qreal dx = -0.5;
314
315 quint8 r[] = { 10, 15, 25, 35, 40, 0, 0};
316 quint8 a[] = {128,255,255,255,127, 0, 0};
317
318 testLine(scale, dx, r, a, -1, 7);
319 }
320
testProcessLine_Scale_1_0_Shift_0_25()321 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Shift_0_25()
322 {
323 qreal scale = 1.0;
324 qreal dx = 0.25;
325
326 quint8 r[] = { 0, 10, 17, 27, 37, 40, 0};
327 quint8 a[] = { 0,191,255,255,255, 64, 0};
328
329 testLine(scale, dx, r, a, -1, 7);
330 }
331
testProcessLine_Scale_1_0_Shift_m0_25()332 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Shift_m0_25()
333 {
334 qreal scale = 1.0;
335 qreal dx = -0.25;
336
337 quint8 r[] = { 10, 13, 23, 33, 40, 0, 0};
338 quint8 a[] = { 64,255,255,255,191, 0, 0};
339
340 testLine(scale, dx, r, a, -1, 7);
341 }
342
testProcessLine_Scale_0_5_Aligned()343 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_0_5_Aligned()
344 {
345 qreal scale = 0.5;
346 qreal dx = 0.0;
347
348 quint8 r[] = { 10, 17, 33, 40, 0, 0, 0};
349 quint8 a[] = { 32,223,223, 32, 0, 0, 0};
350
351 testLine(scale, dx, r, a, -1, 7);
352 }
353
testProcessLine_Scale_0_5_Shift_0_25()354 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_0_5_Shift_0_25()
355 {
356 qreal scale = 0.5;
357 qreal dx = 0.25;
358
359 quint8 r[] = { 0, 13, 30, 40, 0, 0, 0};
360 quint8 a[] = { 0,191,255, 64, 0, 0, 0};
361
362 testLine(scale, dx, r, a, -1, 7);
363 }
364
testProcessLine_Scale_2_0_Aligned()365 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_2_0_Aligned()
366 {
367 qreal scale = 2.0;
368 qreal dx = 0.0;
369
370 quint8 r[] = { 0, 10, 10, 13, 17, 23, 27, 33, 37, 40, 40, 0};
371 quint8 a[] = { 0, 64,191,255,255,255,255,255,255,191, 64, 0};
372
373 testLine(scale, dx, r, a, -2, 12);
374 }
375
testProcessLine_Scale_2_0_Shift_0_25()376 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_2_0_Shift_0_25()
377 {
378 qreal scale = 2.0;
379 qreal dx = 0.25;
380
381 quint8 r[] = { 0, 10, 10, 11, 16, 21, 26, 31, 36, 40, 40, 0};
382 quint8 a[] = { 0, 32,159,255,255,255,255,255,255,223, 96, 0};
383
384 testLine(scale, dx, r, a, -2, 12);
385 }
386
testProcessLine_Scale_2_0_Shift_0_5()387 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_2_0_Shift_0_5()
388 {
389 qreal scale = 2.0;
390 qreal dx = 0.5;
391
392 quint8 r[] = { 0, 0, 10, 10, 15, 20, 25, 30, 35, 40, 40, 0};
393 quint8 a[] = { 0, 0,128,255,255,255,255,255,255,255,127, 0};
394
395 testLine(scale, dx, r, a, -2, 12);
396 }
397
testProcessLine_Scale_1_0_Aligned_Clamped()398 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Aligned_Clamped()
399 {
400 qreal scale = 1.0;
401 qreal dx = 0.0;
402
403 quint8 r[] = { 0, 10, 20, 30, 40, 0, 0};
404 quint8 a[] = { 0,255,255,255,255, 0, 0};
405
406 testLine(scale, dx, r, a, -1, 7, true);
407 }
408
testProcessLine_Scale_0_5_Aligned_Clamped()409 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_0_5_Aligned_Clamped()
410 {
411 qreal scale = 0.5;
412 qreal dx = 0.0;
413
414 quint8 r[] = { 0, 16, 34, 0, 0, 0, 0};
415 quint8 a[] = { 0,255,255, 0, 0, 0, 0};
416
417 testLine(scale, dx, r, a, -1, 7, true);
418 }
419
testProcessLine_Scale_2_0_Aligned_Clamped()420 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_2_0_Aligned_Clamped()
421 {
422 qreal scale = 2.0;
423 qreal dx = 0.0;
424
425 quint8 r[] = { 0, 0, 10, 13, 17, 23, 27, 33, 37, 40, 0, 0};
426 quint8 a[] = { 0, 0,255,255,255,255,255,255,255,255, 0, 0};
427
428 testLine(scale, dx, r, a, -2, 12, true);
429 }
430
testProcessLine_Scale_1_0_Aligned_Mirrored()431 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Aligned_Mirrored()
432 {
433 qreal scale = -1.0;
434 qreal dx = 0.0;
435
436 quint8 r[] = { 0, 0, 40, 30, 20, 10, 0, 0, 0, 0};
437 quint8 a[] = { 0, 0,255,255,255,255, 0, 0, 0, 0};
438
439 testLine(scale, dx, r, a, -6, 10);
440 }
441
testProcessLine_Scale_1_0_Shift_0_25_Mirrored()442 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_1_0_Shift_0_25_Mirrored()
443 {
444 qreal scale = -1.0;
445 qreal dx = 0.25;
446
447 quint8 r[] = { 0, 0, 40, 33, 23, 13, 10, 0, 0, 0};
448 quint8 a[] = { 0, 0,191,255,255,255, 64, 0, 0, 0};
449
450 testLine(scale, dx, r, a, -6, 10);
451 }
452
testProcessLine_Scale_0_5_Aligned_Mirrored_Clamped()453 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_0_5_Aligned_Mirrored_Clamped()
454 {
455 qreal scale = -0.5;
456 qreal dx = 0.0;
457
458 quint8 r[] = { 0, 0, 0, 0, 34, 16, 0, 0, 0, 0};
459 quint8 a[] = { 0, 0, 0, 0,255,255, 0, 0, 0, 0};
460
461 testLine(scale, dx, r, a, -6, 10, true);
462 }
463
testProcessLine_Scale_0_5_Shift_0_125_Mirrored()464 void KisFilterWeightsApplicatorTest::testProcessLine_Scale_0_5_Shift_0_125_Mirrored()
465 {
466 qreal scale = -0.5;
467 qreal dx = 0.125;
468
469 quint8 r[] = { 0, 0, 0, 40, 35, 19, 10, 0, 0, 0};
470 quint8 a[] = { 0, 0, 0, 16,207,239, 48, 0, 0, 0};
471
472 testLine(scale, dx, r, a, -6, 10);
473 }
474
testProcessLine_NearestNeighbourFilter_2x()475 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_2x()
476 {
477 qreal scale = 2.0;
478 qreal dx = 0;
479
480 quint8 r[] = {0, 10, 10, 20, 20, 30, 30, 40, 40, 0, 0};
481 quint8 a[] = {0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0};
482
483 KisFilterStrategy* filter = new KisBoxFilterStrategy();
484 testLine(scale, dx, r, a, -1, 11, true, filter);
485 }
486
testProcessLine_NearestNeighbourFilter_1x()487 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_1x()
488 {
489
490 qreal scale = 1.0;
491 qreal dx = 0;
492
493 quint8 r[] = { 0, 10, 20, 30, 40, 0, 0};
494 quint8 a[] = { 0,255,255,255,255, 0, 0};
495
496 KisFilterStrategy* filter = new KisBoxFilterStrategy();
497 testLine(scale, dx, r, a, -1, 7, false, filter);
498 }
499
testProcessLine_NearestNeighbourFilter_05x()500 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_05x()
501 {
502
503 qreal scale = 0.5;
504 qreal dx = 0;
505
506 quint8 r[] = { 0, 10, 30, 0, 0, 0, 0};
507 quint8 a[] = { 0,255,255, 0, 0, 0, 0};
508
509 KisFilterStrategy* filter = new KisBoxFilterStrategy();
510 testLine(scale, dx, r, a, -1, 7, false, filter);
511 }
512
513
testProcessLine_NearestNeighbourFilter_077x()514 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_077x()
515 {
516
517 qreal scale = 0.77;
518 qreal dx = 0;
519
520 quint8 r[] = { 0, 10, 20, 40, 0, 0, 0};
521 quint8 a[] = { 0,255,255, 255, 0, 0, 0};
522
523 KisFilterStrategy* filter = new KisBoxFilterStrategy();
524 testLine(scale, dx, r, a, -1, 7, false, filter);
525 }
526
testProcessLine_NearestNeighbourFilter_074x()527 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_074x()
528 {
529
530 qreal scale = 0.74;
531 qreal dx = 0;
532
533 quint8 r[] = { 0, 10, 30, 40, 0, 0, 0};
534 quint8 a[] = { 0,255,255, 255, 0, 0, 0};
535
536 KisFilterStrategy* filter = new KisBoxFilterStrategy();
537 testLine(scale, dx, r, a, -1, 7, false, filter);
538 }
539
testProcessLine_NearestNeighbourFilter_075x()540 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_075x()
541 {
542
543 qreal scale = 0.75;
544 qreal dx = 0;
545
546 quint8 r[] = { 0, 10, 20, 40, 0, 0, 0};
547 quint8 a[] = { 0,255,255, 255, 0, 0, 0};
548
549 KisFilterStrategy* filter = new KisBoxFilterStrategy();
550 testLine(scale, dx, r, a, -1, 7, false, filter);
551 }
552
testProcessLine_NearestNeighbourFilter_051x()553 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_051x()
554 {
555
556 qreal scale = 0.51;
557 qreal dx = 0;
558
559 quint8 r[] = { 0, 10, 30, 0, 0, 0, 0};
560 quint8 a[] = { 0,255,255, 0, 0, 0, 0};
561
562 KisFilterStrategy* filter = new KisBoxFilterStrategy();
563 testLine(scale, dx, r, a, -1, 7, false, filter);
564 }
565
566
567
testProcessLine_NearestNeighbourFilter_15x()568 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_15x()
569 {
570
571 qreal scale = 1.5;
572 qreal dx = 0;
573
574 quint8 r[] = { 0, 10, 10, 20, 30, 30, 40};
575 quint8 a[] = { 0,255,255, 255, 255, 255, 255};
576
577 KisFilterStrategy* filter = new KisBoxFilterStrategy();
578 testLine(scale, dx, r, a, -1, 7, false, filter);
579 }
580
581
preparePixelData(quint8 * r,quint8 * a,int i)582 void preparePixelData(quint8* r, quint8* a, int i)
583 {
584 for (int j = 0; j < 7; j ++) {
585 r[j] = 0;
586 a[j] = 0;
587 }
588
589 if (i < 13) {
590 // nothing to do
591 } else if (i < 17) {
592 r[1] = 40;
593 a[1] = 255;
594 } else if (i < 25) {
595 r[1] = 30;
596 a[1] = 255;
597 } else if (i < 38) {
598 r[1] = 20;
599 a[1] = 255;
600 } else if (i < 50) {
601 r[1] = 20;
602 r[2] = 40;
603 a[1] = 255;
604 a[2] = 255;
605 } else if (i < 63) {
606 r[1] = 10;
607 r[2] = 30;
608 a[1] = 255;
609 a[2] = 255;
610 } else if (i < 75) {
611 r[1] = 10;
612 r[2] = 30;
613 r[3] = 40;
614
615 a[1] = 255;
616 a[2] = 255;
617 a[3] = 255;
618
619 } else if (i < 84) {
620 r[1] = 10;
621 r[2] = 20;
622 r[3] = 40;
623
624 a[1] = 255;
625 a[2] = 255;
626 a[3] = 255;
627
628 } else if (i < 88) {
629 r[1] = 10;
630 r[2] = 20;
631 r[3] = 30;
632
633 a[1] = 255;
634 a[2] = 255;
635 a[3] = 255;
636 } else {
637
638 r[1] = 10;
639 r[2] = 20;
640 r[3] = 30;
641 r[4] = 40;
642
643 a[1] = 255;
644 a[2] = 255;
645 a[3] = 255;
646 a[4] = 255;
647 }
648
649 }
650
651
testProcessLine_NearestNeighbourFilter_all()652 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_all()
653 {
654
655 KisFilterStrategy* filter = new KisBoxFilterStrategy();
656
657 for (int i = 1; i < 100; i++) {
658
659 qreal scale = i/100.0;
660 qreal dx = 0;
661
662 quint8 r[7];
663 quint8 a[7];
664
665 preparePixelData(r, a, i);
666 testLine(scale, dx, r, a, -1, 7, false, filter);
667
668 }
669 }
670
671
672
673
prepareUniformPaintDevice(int pixelsNumber,bool horizontal)674 KisPaintDeviceSP prepareUniformPaintDevice(int pixelsNumber, bool horizontal)
675 {
676 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
677 KisPaintDeviceSP dev = new KisPaintDevice(cs);
678 for (int i = 0; i < pixelsNumber; i++) {
679 int x = horizontal ? i : 0;
680 int y = horizontal ? 0 : i;
681
682 QColor c = QColor(10, 0, 0, 255);
683 dev->setPixel(x, y, c);
684 }
685
686 return dev;
687 }
688
prepareUniformPixels(quint8 r[],quint8 a[],int pixelsNumber,bool)689 void prepareUniformPixels(quint8 r[], quint8 a[], int pixelsNumber, bool /*horizontal*/)
690 {
691 for (int i = 0; i < pixelsNumber; i++) {
692
693 QColor c = QColor(10, 0, 0, 255);
694 r[i] = c.red();
695 a[i] = c.alpha();
696 }
697
698 }
699
700
701
testProcessLine_NearestNeighbourFilter_0098x_horizontal()702 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_0098x_horizontal()
703 {
704 int before = 5075;
705 int after = 500;
706
707 qreal scale = before/after;
708 qreal dx = 0;
709
710 bool horizontal = true;
711
712 KisPaintDeviceSP dev = prepareUniformPaintDevice(before, horizontal);
713
714 quint8 *r = new quint8[after];
715 quint8 *a = new quint8[after];
716
717 prepareUniformPixels(r, a, after, horizontal);
718
719 KisFilterStrategy* filter = new KisBoxFilterStrategy();
720 testLineImpl(scale, dx, r, a, 0, after, false, horizontal, filter, dev);
721
722 }
723
testProcessLine_NearestNeighbourFilter_0098x_vertical()724 void KisFilterWeightsApplicatorTest::testProcessLine_NearestNeighbourFilter_0098x_vertical()
725 {
726 int before = 4725;
727 int after = 466;
728
729 qreal scale = before/after;
730 qreal dx = 0;
731
732 bool horizontal = false;
733
734 KisPaintDeviceSP dev = prepareUniformPaintDevice(before, horizontal);
735
736 quint8 *r = new quint8[after];
737 quint8 *a = new quint8[after];
738
739 prepareUniformPixels(r, a, after, horizontal);
740
741 KisFilterStrategy* filter = new KisBoxFilterStrategy();
742 testLineImpl(scale, dx, r, a, 0, after, false, horizontal, filter, dev);
743
744 }
745
746
benchmarkProcesssLine()747 void KisFilterWeightsApplicatorTest::benchmarkProcesssLine()
748 {
749 const KoColorSpace *cs = KoColorSpaceRegistry::instance()->rgb8();
750 KisPaintDeviceSP dev = new KisPaintDevice(cs);
751 KisFilterStrategy *filter = new KisBilinearFilterStrategy();
752
753 const qreal scale = 0.873;
754 const qreal dx = 0.0387;
755
756 KisFilterWeightsBuffer buf(filter, qAbs(scale));
757 KisFilterWeightsApplicator applicator(dev, dev, scale, 0.0, dx, false);
758
759 for (int i = 0; i < 32767; i++) {
760 dev->setPixel(i,0,QColor(10 + i%240,20,40));
761 }
762
763 KisFilterWeightsApplicator::LinePos linePos(0,32767);
764
765 QBENCHMARK {
766 applicator.processLine<KisHLineIteratorSP>(linePos,0,&buf, filter->support(buf.weightsPositionScale().toFloat()));
767 }
768 }
769
770 KISTEST_MAIN(KisFilterWeightsApplicatorTest)
771