1 /*
2     SPDX-FileCopyrightText: 2020 Kai Uwe Broulik <kde@broulik.de>
3 
4     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5 */
6 
7 #include <QImage>
8 #include <QImageReader>
9 #include <QTest>
10 
imgEquals(const QImage & im1,const QImage & im2)11 static bool imgEquals(const QImage &im1, const QImage &im2)
12 {
13     const int height = im1.height();
14     const int width = im1.width();
15     for (int i = 0; i < height; ++i) {
16         const auto *line1 = reinterpret_cast<const quint8 *>(im1.scanLine(i));
17         const auto *line2 = reinterpret_cast<const quint8 *>(im2.scanLine(i));
18         for (int j = 0; j < width; ++j) {
19             if (line1[j] - line2[j] != 0) {
20                 return false;
21             }
22         }
23     }
24     return true;
25 }
26 
27 class AniTests : public QObject
28 {
29     Q_OBJECT
30 
31 private Q_SLOTS:
initTestCase()32     void initTestCase()
33     {
34         QCoreApplication::addLibraryPath(QStringLiteral(PLUGIN_DIR));
35     }
36 
testReadMetadata()37     void testReadMetadata()
38     {
39         QImageReader reader(QFINDTESTDATA("ani/test.ani"));
40 
41         QVERIFY(reader.canRead());
42 
43         QCOMPARE(reader.imageCount(), 4);
44 
45         QCOMPARE(reader.size(), QSize(32, 32));
46 
47         QCOMPARE(reader.text(QStringLiteral("Title")), QStringLiteral("ANI Test"));
48         QCOMPARE(reader.text(QStringLiteral("Author")), QStringLiteral("KDE Community"));
49     }
50 
textRead()51     void textRead()
52     {
53         QImageReader reader(QFINDTESTDATA("ani/test.ani"));
54         QVERIFY(reader.canRead());
55         QCOMPARE(reader.currentImageNumber(), 0);
56 
57         QImage aniFrame;
58         QVERIFY(reader.read(&aniFrame));
59 
60         QImage img1(QFINDTESTDATA("ani/test_1.png"));
61         img1.convertTo(aniFrame.format());
62 
63         QVERIFY(imgEquals(aniFrame, img1));
64 
65         QCOMPARE(reader.nextImageDelay(), 166); // 10 "jiffies"
66 
67         QVERIFY(reader.canRead());
68         // that read() above should have advanced us to the next frame
69         QCOMPARE(reader.currentImageNumber(), 1);
70 
71         QVERIFY(reader.read(&aniFrame));
72         QImage img2(QFINDTESTDATA("ani/test_2.png"));
73         img2.convertTo(aniFrame.format());
74 
75         QVERIFY(imgEquals(aniFrame, img2));
76 
77         // The "middle" frame has a longer delay than the others
78         QCOMPARE(reader.nextImageDelay(), 333); // 20 "jiffies"
79 
80         QVERIFY(reader.canRead());
81         QCOMPARE(reader.currentImageNumber(), 2);
82 
83         QVERIFY(reader.read(&aniFrame));
84         QImage img3(QFINDTESTDATA("ani/test_3.png"));
85         img3.convertTo(aniFrame.format());
86 
87         QVERIFY(imgEquals(aniFrame, img3));
88 
89         QCOMPARE(reader.nextImageDelay(), 166);
90 
91         QVERIFY(reader.canRead());
92         QCOMPARE(reader.currentImageNumber(), 3);
93 
94         QVERIFY(reader.read(&aniFrame));
95         // custom sequence in the ANI file should get us back to img2
96         QVERIFY(imgEquals(aniFrame, img2));
97 
98         QCOMPARE(reader.nextImageDelay(), 166);
99 
100         // We should have reached the end now
101         QVERIFY(!reader.canRead());
102         QVERIFY(!reader.read(&aniFrame));
103 
104         // Jump back to the start
105         QVERIFY(reader.jumpToImage(0));
106 
107         QVERIFY(reader.canRead());
108         QCOMPARE(reader.currentImageNumber(), 0);
109 
110         QCOMPARE(reader.nextImageDelay(), 166);
111 
112         QVERIFY(reader.read(&aniFrame));
113         QVERIFY(imgEquals(aniFrame, img1));
114     }
115 };
116 
117 QTEST_MAIN(AniTests)
118 
119 #include "anitest.moc"
120