1 /*
2 * Copyright (c) 2008 Boudewijn Rempt <boud@valdyas.org>
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_all_filter_test.h"
20 #include <QTest>
21 #include "filter/kis_filter_configuration.h"
22 #include "filter/kis_filter_registry.h"
23 #include "kis_selection.h"
24 #include "kis_processing_information.h"
25 #include "filter/kis_filter.h"
26 #include "kis_pixel_selection.h"
27 #include "kis_transaction.h"
28 #include <KoColorSpaceRegistry.h>
29 #include <sdk/tests/qimage_test_util.h>
30 #include <sdk/tests/testing_timed_default_bounds.h>
31
testFilterSrcNotIsDev(KisFilterSP f)32 bool testFilterSrcNotIsDev(KisFilterSP f)
33 {
34 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
35
36 QImage qimage(QString(FILES_DATA_DIR) + '/' + "carrot.png");
37 QImage result(QString(FILES_DATA_DIR) + '/' + "carrot_" + f->id() + ".png");
38 KisPaintDeviceSP dev = new KisPaintDevice(cs);
39 dev->setDefaultBounds(new TestUtil::TestingTimedDefaultBounds(qimage.rect()));
40
41 KisPaintDeviceSP dstdev = new KisPaintDevice(cs);
42 dstdev->setDefaultBounds(new TestUtil::TestingTimedDefaultBounds(qimage.rect()));
43
44 dev->convertFromQImage(qimage, 0, 0, 0);
45
46 // Get the predefined configuration from a file
47 KisFilterConfigurationSP kfc = f->defaultConfiguration();
48
49 QFile file(QString(FILES_DATA_DIR) + '/' + f->id() + ".cfg");
50 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
51 //qDebug() << "creating new file for " << f->id();
52 file.open(QIODevice::WriteOnly | QIODevice::Text);
53 QTextStream out(&file);
54 out.setCodec("UTF-8");
55 out << kfc->toXML();
56 } else {
57 QString s;
58 QTextStream in(&file);
59 in.setCodec("UTF-8");
60 s = in.readAll();
61 //qDebug() << "Read for " << f->id() << "\n" << s;
62 kfc->fromXML(s);
63 }
64 dbgKrita << f->id();// << "\n" << kfc->toXML() << "\n";
65
66 f->process(dev, dstdev, 0, QRect(QPoint(0,0), qimage.size()), kfc);
67
68 QPoint errpoint;
69
70 QImage actualResult = dstdev->convertToQImage(0, 0, 0, qimage.width(), qimage.height());
71
72 if (!TestUtil::compareQImages(errpoint, result, actualResult, 1, 1)) {
73 qDebug() << "Failed compare result images for: " << f->id();
74 qDebug() << errpoint;
75 actualResult.save(QString("carrot_%1.png").arg(f->id()));
76 result.save(QString("carrot_%1_expected.png").arg(f->id()));
77 return false;
78 }
79 return true;
80 }
81
testFilter(KisFilterSP f)82 bool testFilter(KisFilterSP f)
83 {
84 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
85
86 QImage qimage(QString(FILES_DATA_DIR) + '/' + "carrot.png");
87 QString resultFileName = QString(FILES_DATA_DIR) + '/' + "carrot_" + f->id() + ".png";
88 QImage result(resultFileName);
89
90 //if (!f->id().contains("hsv")) return true;
91
92 KisPaintDeviceSP dev = new KisPaintDevice(cs);
93 dev->setDefaultBounds(new TestUtil::TestingTimedDefaultBounds(qimage.rect()));
94 dev->convertFromQImage(qimage, 0, 0, 0);
95 KisTransaction * cmd = new KisTransaction(kundo2_noi18n(f->name()), dev);
96
97 // Get the predefined configuration from a file
98 KisFilterConfigurationSP kfc = f->defaultConfiguration();
99
100 QFile file(QString(FILES_DATA_DIR) + '/' + f->id() + ".cfg");
101 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
102 //qDebug() << "creating new file for " << f->id();
103 file.open(QIODevice::WriteOnly | QIODevice::Text);
104 QTextStream out(&file);
105 out.setCodec("UTF-8");
106 out << kfc->toXML();
107 } else {
108 QString s;
109 QTextStream in(&file);
110 in.setCodec("UTF-8");
111 s = in.readAll();
112 //qDebug() << "Read for " << f->id() << "\n" << s;
113 const bool validConfig = kfc->fromXML(s);
114
115
116 if (!validConfig) {
117 qDebug() << QString("Couldn't parse XML settings for filter %1").arg(f->id()).toLatin1();
118 return false;
119 }
120 }
121 dbgKrita << f->id();// << "\n" << kfc->toXML() << "\n";
122
123 f->process(dev, QRect(QPoint(0,0), qimage.size()), kfc);
124
125 QPoint errpoint;
126
127 delete cmd;
128
129 QImage actualResult = dev->convertToQImage(0, 0, 0, qimage.width(), qimage.height());
130
131 if (!TestUtil::compareQImages(errpoint, result, actualResult, 1, 1)) {
132 qDebug() << "Failed compare result images for: " << f->id();
133 qDebug() << errpoint;
134 actualResult.save(QString("carrot_%1.png").arg(f->id()));
135 result.save(QString("carrot_%1_expected.png").arg(f->id()));
136 return false;
137 }
138 return true;
139 }
140
141
testFilterWithSelections(KisFilterSP f)142 bool testFilterWithSelections(KisFilterSP f)
143 {
144 const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
145
146 QImage qimage(QString(FILES_DATA_DIR) + '/' + "carrot.png");
147 QImage result(QString(FILES_DATA_DIR) + '/' + "carrot_" + f->id() + ".png");
148 KisPaintDeviceSP dev = new KisPaintDevice(cs);
149 dev->setDefaultBounds(new TestUtil::TestingTimedDefaultBounds(qimage.rect()));
150 dev->convertFromQImage(qimage, 0, 0, 0);
151
152 // Get the predefined configuration from a file
153 KisFilterConfigurationSP kfc = f->defaultConfiguration();
154
155 QFile file(QString(FILES_DATA_DIR) + '/' + f->id() + ".cfg");
156 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
157 //qDebug() << "creating new file for " << f->id();
158 file.open(QIODevice::WriteOnly | QIODevice::Text);
159 QTextStream out(&file);
160 out.setCodec("UTF-8");
161 out << kfc->toXML();
162 } else {
163 QString s;
164 QTextStream in(&file);
165 in.setCodec("UTF-8");
166 s = in.readAll();
167 //qDebug() << "Read for " << f->id() << "\n" << s;
168 kfc->fromXML(s);
169 }
170 dbgKrita << f->id();// << "\n"; << kfc->toXML() << "\n";
171
172 KisSelectionSP sel1 = new KisSelection(new KisSelectionDefaultBounds(dev));
173 sel1->pixelSelection()->select(qimage.rect());
174
175 f->process(dev, dev, sel1, QRect(QPoint(0,0), qimage.size()), kfc);
176
177 QPoint errpoint;
178
179 QImage actualResult = dev->convertToQImage(0, 0, 0, qimage.width(), qimage.height());
180
181 if (!TestUtil::compareQImages(errpoint, result, actualResult, 1, 1)) {
182 qDebug() << "Failed compare result images for: " << f->id();
183 qDebug() << errpoint;
184 actualResult.save(QString("carrot_%1.png").arg(f->id()));
185 result.save(QString("carrot_%1_expected.png").arg(f->id()));
186 return false;
187 }
188
189 return true;
190 }
191
testAllFilters()192 void KisAllFilterTest::testAllFilters()
193 {
194 QStringList excludeFilters;
195 excludeFilters << "colortransfer";
196 excludeFilters << "gradientmap";
197 excludeFilters << "phongbumpmap";
198 excludeFilters << "raindrops";
199
200 // halftone has some bezier curve painting drifts, so
201 // let's just exclude it
202 excludeFilters << "halftone";
203
204 QStringList failures;
205 QStringList successes;
206
207 QList<QString> filterList = KisFilterRegistry::instance()->keys();
208 std::sort(filterList.begin(), filterList.end());
209 for (QList<QString>::Iterator it = filterList.begin(); it != filterList.end(); ++it) {
210 if (excludeFilters.contains(*it)) continue;
211
212 if (testFilter(KisFilterRegistry::instance()->value(*it)))
213 successes << *it;
214 else
215 failures << *it;
216 }
217 dbgKrita << "Success: " << successes;
218 if (failures.size() > 0) {
219 QFAIL(QString("Failed filters:\n\t %1").arg(failures.join("\n\t")).toLatin1());
220 }
221 }
222
testAllFiltersSrcNotIsDev()223 void KisAllFilterTest::testAllFiltersSrcNotIsDev()
224 {
225 QStringList excludeFilters;
226 excludeFilters << "colortransfer";
227 excludeFilters << "gradientmap";
228 excludeFilters << "phongbumpmap";
229 excludeFilters << "raindrops";
230
231 // halftone has some bezier curve painting drifts, so
232 // let's just exclude it
233 excludeFilters << "halftone";
234
235 QStringList failures;
236 QStringList successes;
237
238 QList<QString> filterList = KisFilterRegistry::instance()->keys();
239 std::sort(filterList.begin(), filterList.end());
240 for (QList<QString>::Iterator it = filterList.begin(); it != filterList.end(); ++it) {
241 if (excludeFilters.contains(*it)) continue;
242
243 if (testFilterSrcNotIsDev(KisFilterRegistry::instance()->value(*it)))
244 successes << *it;
245 else
246 failures << *it;
247 }
248 dbgKrita << "Src!=Dev Success: " << successes;
249 if (failures.size() > 0) {
250 QFAIL(QString("Src!=Dev Failed filters:\n\t %1").arg(failures.join("\n\t")).toLatin1());
251 }
252
253 }
254
testAllFiltersWithSelections()255 void KisAllFilterTest::testAllFiltersWithSelections()
256 {
257 QStringList excludeFilters;
258 excludeFilters << "colortransfer";
259 excludeFilters << "gradientmap";
260 excludeFilters << "phongbumpmap";
261 excludeFilters << "raindrops";
262
263 // halftone has some bezier curve painting drifts, so
264 // let's just exclude it
265 excludeFilters << "halftone";
266
267 QStringList failures;
268 QStringList successes;
269
270 QList<QString> filterList = KisFilterRegistry::instance()->keys();
271 std::sort(filterList.begin(), filterList.end());
272 for (QList<QString>::Iterator it = filterList.begin(); it != filterList.end(); ++it) {
273 if (excludeFilters.contains(*it)) continue;
274
275 if (testFilterWithSelections(KisFilterRegistry::instance()->value(*it)))
276 successes << *it;
277 else
278 failures << *it;
279 }
280 dbgKrita << "Success: " << successes;
281 if (failures.size() > 0) {
282 QFAIL(QString("Failed filters with selections:\n\t %1").arg(failures.join("\n\t")).toLatin1());
283 }
284 }
285
286
287
288 QTEST_MAIN(KisAllFilterTest)
289