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