Change bugreports.qt.nokia.com -> bugreports.qt-project.org
[profile/ivi/qtbase.git] / tests / auto / gui / image / qimagereader / tst_qimagereader.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44
45 #include <QBuffer>
46 #include <QDebug>
47 #include <QFile>
48 #include <QImage>
49 #include <QImageReader>
50 #include <QImageWriter>
51 #include <QLabel>
52 #include <QPixmap>
53 #include <QSet>
54 #include <QTcpSocket>
55 #include <QTcpServer>
56 #include <QTimer>
57 #include <QTemporaryDir>
58
59 typedef QMap<QString, QString> QStringMap;
60 typedef QList<int> QIntList;
61 Q_DECLARE_METATYPE(QImage)
62 Q_DECLARE_METATYPE(QRect)
63 Q_DECLARE_METATYPE(QSize)
64 Q_DECLARE_METATYPE(QColor)
65 Q_DECLARE_METATYPE(QStringMap)
66 Q_DECLARE_METATYPE(QIntList)
67 Q_DECLARE_METATYPE(QIODevice *)
68 Q_DECLARE_METATYPE(QImage::Format)
69
70 class tst_QImageReader : public QObject
71 {
72     Q_OBJECT
73
74 public:
75     tst_QImageReader();
76     virtual ~tst_QImageReader();
77
78 public slots:
79     void init();
80     void cleanup();
81
82 private slots:
83     void getSetCheck();
84     void readImage_data();
85     void readImage();
86     void jpegRgbCmyk();
87
88     void setScaledSize_data();
89     void setScaledSize();
90
91     void setClipRect_data();
92     void setClipRect();
93
94     void setScaledClipRect_data();
95     void setScaledClipRect();
96
97     void imageFormat_data();
98     void imageFormat();
99
100     void blackXPM();
101     void transparentXPM();
102     void multiWordNamedColorXPM();
103
104     void supportedFormats();
105
106     void readFromDevice_data();
107     void readFromDevice();
108
109     void readFromFileAfterJunk_data();
110     void readFromFileAfterJunk();
111
112     void devicePosition_data();
113     void devicePosition();
114
115     void setBackgroundColor_data();
116     void setBackgroundColor();
117
118     void supportsAnimation_data();
119     void supportsAnimation();
120
121     void readFromResources_data();
122     void readFromResources();
123
124     void sizeBeforeRead_data();
125     void sizeBeforeRead();
126
127     void sizeBeforeFormat_data();
128     void sizeBeforeFormat();
129
130     void imageFormatBeforeRead_data();
131     void imageFormatBeforeRead();
132
133     void gifHandlerBugs();
134     void animatedGif();
135     void gifImageCount();
136     void gifLoopCount();
137
138     void readCorruptImage_data();
139     void readCorruptImage();
140     void readCorruptBmp();
141
142     void supportsOption_data();
143     void supportsOption();
144
145     void autoDetectImageFormat();
146     void fileNameProbing();
147
148     void pixelCompareWithBaseline_data();
149     void pixelCompareWithBaseline();
150
151     void task255627_setNullScaledSize_data();
152     void task255627_setNullScaledSize();
153
154     void testIgnoresFormatAndExtension_data();
155     void testIgnoresFormatAndExtension();
156
157     void saveFormat_data();
158     void saveFormat();
159
160     void readText_data();
161     void readText();
162
163     void preserveTexts_data();
164     void preserveTexts();
165
166 private:
167     QString prefix;
168     QTemporaryDir m_temporaryDir;
169 };
170
171 // helper to skip an autotest when the given image format is not supported
172 #define SKIP_IF_UNSUPPORTED(format) do {                                                          \
173     if (!QByteArray(format).isEmpty() && !QImageReader::supportedImageFormats().contains(format)) \
174         QSKIP("\"" + QByteArray(format) + "\" images are not supported");             \
175 } while (0)
176
177 // Testing get/set functions
178 void tst_QImageReader::getSetCheck()
179 {
180     QImageReader obj1;
181     // QIODevice * QImageReader::device()
182     // void QImageReader::setDevice(QIODevice *)
183     QFile *var1 = new QFile;
184     obj1.setDevice(var1);
185
186     //A bit strange but that's the only way to compile under windows.
187     QCOMPARE((QIODevice *) var1, obj1.device());
188     obj1.setDevice((QIODevice *)0);
189     QCOMPARE((QIODevice *) 0,
190              obj1.device());
191     delete var1;
192 }
193
194 tst_QImageReader::tst_QImageReader() :
195     m_temporaryDir(QStringLiteral("tst_qimagereaderXXXXXX"))
196 {
197     m_temporaryDir.setAutoRemove(true);
198 }
199
200 tst_QImageReader::~tst_QImageReader()
201 {
202
203 }
204
205 void tst_QImageReader::init()
206 {
207     prefix = QFINDTESTDATA("images/");
208    QVERIFY(m_temporaryDir.isValid());
209 }
210
211 void tst_QImageReader::cleanup()
212 {
213 }
214
215 void tst_QImageReader::readImage_data()
216 {
217     QTest::addColumn<QString>("fileName");
218     QTest::addColumn<bool>("success");
219     QTest::addColumn<QByteArray>("format");
220
221     QTest::newRow("empty") << QString() << false << QByteArray();
222     QTest::newRow("BMP: colorful") << QString("colorful.bmp") << true << QByteArray("bmp");
223     QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << true << QByteArray("bmp");
224     QTest::newRow("BMP: test32v5") << QString("test32v5.bmp") << true << QByteArray("bmp");
225     QTest::newRow("BMP: font") << QString("font.bmp") << true << QByteArray("bmp");
226     QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << true << QByteArray("bmp");
227     QTest::newRow("BMP: 4bpp RLE") << QString("4bpp-rle.bmp") << true << QByteArray("bmp");
228     QTest::newRow("BMP: 4bpp uncompressed") << QString("tst7.bmp") << true << QByteArray("bmp");
229     QTest::newRow("BMP: 16bpp") << QString("16bpp.bmp") << true << QByteArray("bmp");
230     QTest::newRow("BMP: negative height") << QString("negativeheight.bmp") << true << QByteArray("bmp");
231     QTest::newRow("XPM: marble") << QString("marble.xpm") << true << QByteArray("xpm");
232     QTest::newRow("PNG: kollada") << QString("kollada.png") << true << QByteArray("png");
233     QTest::newRow("PPM: teapot") << QString("teapot.ppm") << true << QByteArray("ppm");
234     QTest::newRow("PPM: runners") << QString("runners.ppm") << true << QByteArray("ppm");
235     QTest::newRow("PPM: test") << QString("test.ppm") << true << QByteArray("ppm");
236     QTest::newRow("XBM: gnus") << QString("gnus.xbm") << true << QByteArray("xbm");
237
238     QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << true << QByteArray("jpeg");
239     QTest::newRow("JPEG: qtbug13653") << QString("qtbug13653-no_eoi.jpg") << true << QByteArray("jpeg");
240
241     QTest::newRow("GIF: earth") << QString("earth.gif") << true << QByteArray("gif");
242     QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << true << QByteArray("gif");
243
244     QTest::newRow("SVG: rect") << QString("rect.svg") << true << QByteArray("svg");
245     QTest::newRow("SVGZ: rect") << QString("rect.svgz") << true << QByteArray("svgz");
246 }
247
248 void tst_QImageReader::readImage()
249 {
250     QFETCH(QString, fileName);
251     QFETCH(bool, success);
252     QFETCH(QByteArray, format);
253
254     SKIP_IF_UNSUPPORTED(format);
255
256     for (int i = 0; i < 2; ++i) {
257         QImageReader io(prefix + fileName, i ? QByteArray() : format);
258         if (success) {
259             if (!io.supportsAnimation())
260                 QVERIFY(io.imageCount() > 0);
261         } else {
262             QCOMPARE(io.imageCount(), -1);
263         }
264         QImage image = io.read();
265         if (!success) {
266             QVERIFY(image.isNull());
267             return;
268         }
269
270         QVERIFY2(!image.isNull(), io.errorString().toLatin1().constData());
271
272         // No format
273         QImageReader io2(prefix + fileName);
274         QVERIFY2(!io2.read().isNull(), io.errorString().toLatin1().constData());
275
276         // No extension, no format
277         QImageReader io3(prefix + fileName.left(fileName.lastIndexOf(QLatin1Char('.'))));
278         QVERIFY2(!io3.read().isNull(), io.errorString().toLatin1().constData());
279
280         // Read into \a image2
281         QImage image2;
282         QImageReader image2Reader(prefix + fileName, i ? QByteArray() : format);
283         QCOMPARE(image2Reader.format(), format);
284         QVERIFY(image2Reader.read(&image2));
285         if (image2Reader.canRead()) {
286             if (i)
287                 QVERIFY(!image2Reader.format().isEmpty());
288             else
289                 QCOMPARE(image2Reader.format(), format);
290         } else {
291             if (i)
292                 QVERIFY(image2Reader.format().isEmpty());
293             else
294                 QVERIFY(!image2Reader.format().isEmpty());
295         }
296         QCOMPARE(image, image2);
297         do {
298             QVERIFY2(!image.isNull(), io.errorString().toLatin1().constData());
299         } while (!(image = io.read()).isNull());
300     }
301 }
302
303 void tst_QImageReader::jpegRgbCmyk()
304 {
305     QImage image1(prefix + QLatin1String("YCbCr_cmyk.jpg"));
306     QImage image2(prefix + QLatin1String("YCbCr_cmyk.png"));
307
308     if (image1 != image2) {
309         // first, do some obvious tests
310         QCOMPARE(image1.height(), image2.height());
311         QCOMPARE(image1.width(), image2.width());
312         QCOMPARE(image1.format(), image2.format());
313         QCOMPARE(image1.format(), QImage::Format_RGB32);
314
315         // compare all the pixels with a slack of 3. This ignores rounding errors
316         // in libjpeg/libpng, where some versions sacrifice accuracy for speed.
317         for (int h = 0; h < image1.height(); ++h) {
318             const uchar *s1 = image1.constScanLine(h);
319             const uchar *s2 = image2.constScanLine(h);
320             for (int w = 0; w < image1.width() * 4; ++w) {
321                 if (*s1 != *s2) {
322                     QVERIFY2(qAbs(*s1 - *s2) <= 3, qPrintable(QString("images differ in line %1, col %2 (image1: %3, image2: %4)").arg(h).arg(w).arg(*s1, 0, 16).arg(*s2, 0, 16)));
323                 }
324                 s1++;
325                 s2++;
326             }
327         }
328     }
329 }
330
331 void tst_QImageReader::setScaledSize_data()
332 {
333     QTest::addColumn<QString>("fileName");
334     QTest::addColumn<QSize>("newSize");
335     QTest::addColumn<QByteArray>("format");
336
337     QTest::newRow("BMP: colorful") << "colorful" << QSize(200, 200) << QByteArray("bmp");
338     QTest::newRow("BMP: font") << "font" << QSize(200, 200) << QByteArray("bmp");
339     QTest::newRow("XPM: marble") << "marble" << QSize(200, 200) << QByteArray("xpm");
340     QTest::newRow("PNG: kollada") << "kollada" << QSize(200, 200) << QByteArray("png");
341     QTest::newRow("PPM: teapot") << "teapot" << QSize(200, 200) << QByteArray("ppm");
342     QTest::newRow("PPM: runners") << "runners.ppm" << QSize(400, 400) << QByteArray("ppm");
343     QTest::newRow("PPM: test") << "test.ppm" << QSize(10, 10) << QByteArray("ppm");
344     QTest::newRow("XBM: gnus") << "gnus" << QSize(200, 200) << QByteArray("xbm");
345
346     QTest::newRow("JPEG: beavis A") << "beavis" << QSize(200, 200) << QByteArray("jpeg");
347     QTest::newRow("JPEG: beavis B") << "beavis" << QSize(175, 175) << QByteArray("jpeg");
348     QTest::newRow("JPEG: beavis C") << "beavis" << QSize(100, 100) << QByteArray("jpeg");
349     QTest::newRow("JPEG: beavis D") << "beavis" << QSize(100, 200) << QByteArray("jpeg");
350     QTest::newRow("JPEG: beavis E") << "beavis" << QSize(200, 100) << QByteArray("jpeg");
351     QTest::newRow("JPEG: beavis F") << "beavis" << QSize(87, 87) << QByteArray("jpeg");
352     QTest::newRow("JPEG: beavis G") << "beavis" << QSize(50, 45) << QByteArray("jpeg");
353     QTest::newRow("JPEG: beavis H") << "beavis" << QSize(43, 43) << QByteArray("jpeg");
354     QTest::newRow("JPEG: beavis I") << "beavis" << QSize(25, 25) << QByteArray("jpeg");
355
356     QTest::newRow("GIF: earth") << "earth" << QSize(200, 200) << QByteArray("gif");
357     QTest::newRow("GIF: trolltech") << "trolltech" << QSize(200, 200) << QByteArray("gif");
358
359     QTest::newRow("SVG: rect") << "rect" << QSize(200, 200) << QByteArray("svg");
360     QTest::newRow("SVGZ: rect") << "rect" << QSize(200, 200) << QByteArray("svgz");
361 }
362
363 void tst_QImageReader::setScaledSize()
364 {
365     QFETCH(QString, fileName);
366     QFETCH(QSize, newSize);
367     QFETCH(QByteArray, format);
368
369     SKIP_IF_UNSUPPORTED(format);
370
371     QImageReader reader(prefix + fileName);
372     reader.setScaledSize(newSize);
373     QImage image = reader.read();
374     QVERIFY(!image.isNull());
375
376     QCOMPARE(image.size(), newSize);
377 }
378
379 void tst_QImageReader::task255627_setNullScaledSize_data()
380 {
381     setScaledSize_data();
382 }
383
384 void tst_QImageReader::task255627_setNullScaledSize()
385 {
386     QFETCH(QString, fileName);
387     QFETCH(QByteArray, format);
388
389     SKIP_IF_UNSUPPORTED(format);
390
391     QImageReader reader(prefix + fileName);
392
393     // set a null size
394     reader.setScaledSize(QSize(0, 0));
395     reader.setQuality(0);
396     QImage image = reader.read();
397     QVERIFY(image.isNull());
398     QCOMPARE(image.size(), QSize(0, 0));
399 }
400
401 void tst_QImageReader::setClipRect_data()
402 {
403     QTest::addColumn<QString>("fileName");
404     QTest::addColumn<QRect>("newRect");
405     QTest::addColumn<QByteArray>("format");
406     QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
407     QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
408     QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
409     QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
410     QTest::newRow("BMP: 4bpp uncompressed") << "tst7.bmp" << QRect(0, 0, 31, 31) << QByteArray("bmp");
411     QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
412     QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png");
413     QTest::newRow("PPM: teapot") << "teapot" << QRect(0, 0, 50, 50) << QByteArray("ppm");
414     QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
415     QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
416     QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
417
418     QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
419
420     QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
421     QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
422
423     QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
424     QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
425 }
426
427 void tst_QImageReader::setClipRect()
428 {
429     QFETCH(QString, fileName);
430     QFETCH(QRect, newRect);
431     QFETCH(QByteArray, format);
432
433     SKIP_IF_UNSUPPORTED(format);
434
435     QImageReader reader(prefix + fileName);
436     reader.setClipRect(newRect);
437     QImage image = reader.read();
438     QVERIFY(!image.isNull());
439     QCOMPARE(image.rect(), newRect);
440
441     QImageReader originalReader(prefix + fileName);
442     QImage originalImage = originalReader.read();
443     QCOMPARE(originalImage.copy(newRect), image);
444 }
445
446 void tst_QImageReader::setScaledClipRect_data()
447 {
448     QTest::addColumn<QString>("fileName");
449     QTest::addColumn<QRect>("newRect");
450     QTest::addColumn<QByteArray>("format");
451
452     QTest::newRow("BMP: colorful") << "colorful" << QRect(0, 0, 50, 50) << QByteArray("bmp");
453     QTest::newRow("BMP: test32bfv4") << "test32bfv4" << QRect(0, 0, 50, 50) << QByteArray("bmp");
454     QTest::newRow("BMP: test32v5") << "test32v5" << QRect(0, 0, 50, 50) << QByteArray("bmp");
455     QTest::newRow("BMP: font") << "font" << QRect(0, 0, 50, 50) << QByteArray("bmp");
456     QTest::newRow("XPM: marble") << "marble" << QRect(0, 0, 50, 50) << QByteArray("xpm");
457     QTest::newRow("PNG: kollada") << "kollada" << QRect(0, 0, 50, 50) << QByteArray("png");
458     QTest::newRow("PPM: teapot") << "teapot" << QRect(0, 0, 50, 50) << QByteArray("ppm");
459     QTest::newRow("PPM: runners") << "runners.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
460     QTest::newRow("PPM: test") << "test.ppm" << QRect(0, 0, 50, 50) << QByteArray("ppm");
461     QTest::newRow("XBM: gnus") << "gnus" << QRect(0, 0, 50, 50) << QByteArray("xbm");
462
463     QTest::newRow("JPEG: beavis") << "beavis" << QRect(0, 0, 50, 50) << QByteArray("jpeg");
464
465     QTest::newRow("GIF: earth") << "earth" << QRect(0, 0, 50, 50) << QByteArray("gif");
466     QTest::newRow("GIF: trolltech") << "trolltech" << QRect(0, 0, 50, 50) << QByteArray("gif");
467
468     QTest::newRow("SVG: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svg");
469     QTest::newRow("SVGZ: rect") << "rect" << QRect(0, 0, 50, 50) << QByteArray("svgz");
470 }
471
472 void tst_QImageReader::setScaledClipRect()
473 {
474     QFETCH(QString, fileName);
475     QFETCH(QRect, newRect);
476     QFETCH(QByteArray, format);
477
478     SKIP_IF_UNSUPPORTED(format);
479
480     QImageReader reader(prefix + fileName);
481     reader.setScaledSize(QSize(300, 300));
482     reader.setScaledClipRect(newRect);
483     QImage image = reader.read();
484     QVERIFY(!image.isNull());
485     QCOMPARE(image.rect(), newRect);
486
487     QImageReader originalReader(prefix + fileName);
488     originalReader.setScaledSize(QSize(300, 300));
489     QImage originalImage = originalReader.read();
490     QCOMPARE(originalImage.copy(newRect), image);
491 }
492
493 void tst_QImageReader::imageFormat_data()
494 {
495     QTest::addColumn<QString>("fileName");
496     QTest::addColumn<QByteArray>("format");
497     QTest::addColumn<QImage::Format>("imageFormat");
498
499     QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm") << QImage::Format_Mono;
500     QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm") << QImage::Format_Indexed8;
501     QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
502     QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
503     QTest::newRow("ppm-3") << QString("runners.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
504     QTest::newRow("ppm-4") << QString("test.ppm") << QByteArray("ppm") << QImage::Format_RGB32;
505
506     QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg") << QImage::Format_Indexed8;
507     QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
508     QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg") << QImage::Format_RGB32;
509
510     QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif") << QImage::Format_Invalid;
511     QTest::newRow("gif-2") << QString("trolltech.gif") << QByteArray("gif") << QImage::Format_Invalid;
512
513     QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm") << QImage::Format_MonoLSB;
514     QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm") << QImage::Format_Indexed8;
515     QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp") << QImage::Format_Indexed8;
516     QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp") << QImage::Format_Indexed8;
517     QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp") << QImage::Format_RGB32;
518     QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp") << QImage::Format_RGB32;
519     QTest::newRow("png") << QString("kollada.png") << QByteArray("png") << QImage::Format_ARGB32;
520     QTest::newRow("png-2") << QString("YCbCr_cmyk.png") << QByteArray("png") << QImage::Format_RGB32;
521     QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg") << QImage::Format_ARGB32_Premultiplied;
522     QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz") << QImage::Format_ARGB32_Premultiplied;
523 }
524
525 void tst_QImageReader::imageFormat()
526 {
527     QFETCH(QString, fileName);
528     QFETCH(QByteArray, format);
529     QFETCH(QImage::Format, imageFormat);
530
531     SKIP_IF_UNSUPPORTED(format);
532
533     QCOMPARE(QImageReader::imageFormat(prefix + fileName), format);
534     QImageReader reader(prefix + fileName);
535     QCOMPARE(reader.imageFormat(), imageFormat);
536 }
537
538 void tst_QImageReader::blackXPM()
539 {
540     QImage image(prefix + QLatin1String("black.xpm"));
541     QImage image2(prefix + QLatin1String("black.png"));
542     QCOMPARE(image.pixel(25, 25), qRgb(190, 190, 190));
543     QCOMPARE(image.pixel(25, 25), image2.pixel(25, 25));
544 }
545
546 void tst_QImageReader::transparentXPM()
547 {
548     QImage image(prefix + QLatin1String("nontransparent.xpm"));
549     QImage image2(prefix + QLatin1String("transparent.xpm"));
550     QCOMPARE(image.format(), QImage::Format_RGB32);
551     QCOMPARE(image2.format(), QImage::Format_ARGB32);
552 }
553
554 void tst_QImageReader::multiWordNamedColorXPM()
555 {
556     QImage image(prefix + QLatin1String("namedcolors.xpm"));
557     QCOMPARE(image.pixel(0, 0), qRgb(102, 139, 139)); // pale turquoise 4
558     QCOMPARE(image.pixel(0, 1), qRgb(250, 250, 210)); // light golden rod yellow
559     QCOMPARE(image.pixel(0, 2), qRgb(255, 250, 205)); // lemon chiffon
560 }
561
562 void tst_QImageReader::supportedFormats()
563 {
564     QList<QByteArray> formats = QImageReader::supportedImageFormats();
565     QList<QByteArray> sortedFormats = formats;
566     qSort(sortedFormats);
567
568     // check that the list is sorted
569     QCOMPARE(formats, sortedFormats);
570
571     QSet<QByteArray> formatSet;
572     foreach (QByteArray format, formats)
573         formatSet << format;
574
575     // check that the list does not contain duplicates
576     QCOMPARE(formatSet.size(), formats.size());
577 }
578
579 void tst_QImageReader::setBackgroundColor_data()
580 {
581     QTest::addColumn<QString>("fileName");
582     QTest::addColumn<QColor>("color");
583
584     QTest::newRow("BMP: colorful") << QString("colorful.bmp") << QColor(Qt::white);
585     QTest::newRow("BMP: font") << QString("font.bmp") << QColor(Qt::black);
586     QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << QColor(Qt::red);
587     QTest::newRow("XPM: marble") << QString("marble.xpm") << QColor(Qt::darkRed);
588     QTest::newRow("PNG: kollada") << QString("kollada.png") << QColor(Qt::green);
589     QTest::newRow("PPM: teapot") << QString("teapot.ppm") << QColor(Qt::darkGreen);
590     QTest::newRow("PPM: runners") << QString("runners.ppm") << QColor(Qt::red);
591     QTest::newRow("PPM: test") << QString("test.ppm") << QColor(Qt::white);
592     QTest::newRow("XBM: gnus") << QString("gnus.xbm") << QColor(Qt::blue);
593
594     QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << QColor(Qt::darkBlue);
595
596     QTest::newRow("GIF: earth") << QString("earth.gif") << QColor(Qt::cyan);
597     QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << QColor(Qt::magenta);
598
599     QTest::newRow("SVG: rect") << QString("rect.svg") << QColor(Qt::darkGreen);
600     QTest::newRow("SVGZ: rect") << QString("rect.svgz") << QColor(Qt::darkGreen);
601 }
602
603 void tst_QImageReader::setBackgroundColor()
604 {
605     QFETCH(QString, fileName);
606     QFETCH(QColor, color);
607     QImageReader io("images/" + fileName);
608     io.setBackgroundColor(color);
609     if (io.backgroundColor().isValid())
610         QCOMPARE(io.backgroundColor(), color);
611 }
612
613 void tst_QImageReader::supportsAnimation_data()
614 {
615     QTest::addColumn<QString>("fileName");
616     QTest::addColumn<bool>("success");
617
618     QTest::newRow("BMP: colorful") << QString("colorful.bmp") << false;
619     QTest::newRow("BMP: font") << QString("font.bmp") << false;
620     QTest::newRow("BMP: signed char") << QString("crash-signed-char.bmp") << false;
621     QTest::newRow("BMP: test32bfv4") << QString("test32bfv4.bmp") << false;;
622     QTest::newRow("BMP: test32v5") << QString("test32v5.bmp") << false;
623     QTest::newRow("XPM: marble") << QString("marble.xpm") << false;
624     QTest::newRow("PNG: kollada") << QString("kollada.png") << false;
625     QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false;
626     QTest::newRow("PPM: runners") << QString("runners.ppm") << false;
627     QTest::newRow("XBM: gnus") << QString("gnus.xbm") << false;
628
629     QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << false;
630
631     QTest::newRow("GIF: earth") << QString("earth.gif") << true;
632     QTest::newRow("GIF: trolltech") << QString("trolltech.gif") << true;
633
634     QTest::newRow("SVG: rect") << QString("rect.svg") << false;
635     QTest::newRow("SVGZ: rect") << QString("rect.svgz") << false;
636 }
637
638 void tst_QImageReader::supportsAnimation()
639 {
640     QFETCH(QString, fileName);
641     QFETCH(bool, success);
642     QImageReader io(prefix + fileName);
643     QCOMPARE(io.supportsAnimation(), success);
644 }
645
646 void tst_QImageReader::sizeBeforeRead_data()
647 {
648     imageFormat_data();
649 }
650
651 void tst_QImageReader::sizeBeforeRead()
652 {
653     QFETCH(QString, fileName);
654     QFETCH(QByteArray, format);
655
656     SKIP_IF_UNSUPPORTED(format);
657
658     QImageReader reader(prefix + fileName);
659     QVERIFY(reader.canRead());
660
661     QSize size = reader.size();
662     QVERIFY(reader.canRead());
663     QImage image = reader.read();
664     QVERIFY(!image.isNull());
665     QCOMPARE(size, image.size());
666 }
667
668 void tst_QImageReader::sizeBeforeFormat_data()
669 {
670     imageFormat_data();
671 }
672
673 void tst_QImageReader::sizeBeforeFormat()
674 {
675     QFETCH(QString, fileName);
676
677     QByteArray formatA, formatB;
678
679     {
680         QImageReader reader(prefix + fileName);
681         formatA = reader.format();
682     }
683
684     {
685         QImageReader reader(prefix + fileName);
686         reader.size();
687         formatB = reader.format();
688     }
689
690     QCOMPARE(formatA, formatB);
691 }
692
693 void tst_QImageReader::imageFormatBeforeRead_data()
694 {
695     imageFormat_data();
696 }
697
698 void tst_QImageReader::imageFormatBeforeRead()
699 {
700     QFETCH(QString, fileName);
701     QFETCH(QByteArray, format);
702     QFETCH(QImage::Format, imageFormat);
703
704     SKIP_IF_UNSUPPORTED(format);
705
706     QImageReader reader(fileName);
707     if (reader.supportsOption(QImageIOHandler::ImageFormat)) {
708         QImage::Format fileFormat = reader.imageFormat();
709         QCOMPARE(fileFormat, imageFormat);
710         QSize size = reader.size();
711         QImage image(size, fileFormat);
712         QVERIFY(reader.read(&image));
713         QCOMPARE(image.format(), fileFormat);
714     }
715 }
716
717 void tst_QImageReader::gifHandlerBugs()
718 {
719     SKIP_IF_UNSUPPORTED("gif");
720
721     {
722         QImageReader io(prefix + "trolltech.gif");
723         QVERIFY(io.loopCount() != 1);
724         int count=0;
725         for (; io.canRead(); io.read(), ++count) ;
726         QVERIFY(count == 34);
727     }
728
729     // Task 95166
730     {
731         QImageReader io1(prefix + "bat1.gif");
732         QImageReader io2(prefix + "bat2.gif");
733         QVERIFY(io1.canRead());
734         QVERIFY(io2.canRead());
735         QImage im1 = io1.read();
736         QImage im2 = io2.read();
737         QVERIFY(!im1.isNull());
738         QVERIFY(!im2.isNull());
739         QCOMPARE(im1, im2);
740     }
741
742     // Task 9994
743     {
744         QImageReader io1(prefix + "noclearcode.gif");
745         QImageReader io2(prefix + "noclearcode.bmp");
746         QVERIFY(io1.canRead());  QVERIFY(io2.canRead());
747         QImage im1 = io1.read(); QImage im2 = io2.read();
748         QVERIFY(!im1.isNull());  QVERIFY(!im2.isNull());
749         QCOMPARE(im1.convertToFormat(QImage::Format_ARGB32), im2.convertToFormat(QImage::Format_ARGB32));
750     }
751
752     // Check the undocumented feature.
753     {
754         QImageReader io(prefix + "endless-anim.gif");
755         QVERIFY(io.canRead());
756         QCOMPARE(io.loopCount(), -1);
757     }
758 }
759
760 void tst_QImageReader::animatedGif()
761 {
762     SKIP_IF_UNSUPPORTED("gif");
763
764     QImageReader io(":images/qt.gif");
765     QImage image = io.read();
766     QVERIFY(!image.isNull());
767     int i = 0;
768     while(!image.isNull()){
769         QString frameName = QString(":images/qt%1.gif").arg(++i);
770         QCOMPARE(image, QImage(frameName));
771         image = io.read();
772     }
773 }
774
775 // http://bugreports.qt-project.org/browse/QTBUG-6696
776 // Check the count of images in various call orders...
777 void tst_QImageReader::gifImageCount()
778 {
779     SKIP_IF_UNSUPPORTED("gif");
780
781     // just read every frame... and see how much we got..
782     {
783         QImageReader io(":images/four-frames.gif");
784
785         QVERIFY(io.canRead());
786         QImage blackFrame = io.read();
787
788         QVERIFY(io.canRead());
789         QImage whiteFrame = io.read();
790
791         QVERIFY(io.canRead());
792         QImage greenFrame = io.read();
793
794         QVERIFY(io.imageCount() == 4);
795
796         QVERIFY(io.canRead());
797         QImage blueFrame = io.read();
798
799         QVERIFY(!io.canRead());
800         QImage emptyFrame = io.read();
801
802         QVERIFY(!io.canRead());
803         QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0));
804         QCOMPARE(blackFrame.size(), QSize(64,64));
805
806         QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff));
807         QCOMPARE(whiteFrame.size(), QSize(64,64));
808
809         QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0));
810         QCOMPARE(greenFrame.size(), QSize(64,64));
811
812         QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff));
813         QCOMPARE(blueFrame.size(), QSize(64,64));
814         QVERIFY(emptyFrame.isNull());
815     }
816
817     // Read and get the size
818     {
819         QImageReader io(":images/four-frames.gif");
820
821         QVERIFY(io.canRead());
822         QCOMPARE(io.size(), QSize(64,64));
823
824         QVERIFY(io.canRead());
825         QCOMPARE(io.size(), QSize(64,64));
826         QCOMPARE(io.size(), QSize(64,64));
827         QVERIFY(io.canRead());
828         QImage blackFrame = io.read();
829
830         QVERIFY(io.canRead());
831         QCOMPARE(io.size(), QSize(64,64));
832         QCOMPARE(io.size(), QSize(64,64));
833         QVERIFY(io.canRead());
834         QImage whiteFrame = io.read();
835
836         QVERIFY(io.canRead());
837         QCOMPARE(io.size(), QSize(64,64));
838         QCOMPARE(io.size(), QSize(64,64));
839         QVERIFY(io.canRead());
840         QImage greenFrame = io.read();
841
842         QVERIFY(io.canRead());
843         QCOMPARE(io.size(), QSize(64,64));
844         QCOMPARE(io.size(), QSize(64,64));
845         QVERIFY(io.canRead());
846         QImage blueFrame = io.read();
847
848         QVERIFY(!io.canRead());
849         QCOMPARE(io.size(), QSize());
850         QCOMPARE(io.size(), QSize());
851         QVERIFY(!io.canRead());
852         QImage emptyFrame = io.read();
853
854         QVERIFY(!io.canRead());
855         QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0));
856         QCOMPARE(blackFrame.size(), QSize(64,64));
857
858         QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff));
859         QCOMPARE(whiteFrame.size(), QSize(64,64));
860
861         QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0));
862         QCOMPARE(greenFrame.size(), QSize(64,64));
863
864         QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff));
865         QCOMPARE(blueFrame.size(), QSize(64,64));
866         QVERIFY(emptyFrame.isNull());
867     }
868
869     // Do a Size query as substitute for canRead
870     {
871         QImageReader io(":images/four-frames.gif");
872
873         QCOMPARE(io.size(), QSize(64,64));
874         QCOMPARE(io.size(), QSize(64,64));
875         QImage blackFrame = io.read();
876
877         QCOMPARE(io.size(), QSize(64,64));
878         QCOMPARE(io.size(), QSize(64,64));
879         QImage whiteFrame = io.read();
880
881         QCOMPARE(io.size(), QSize(64,64));
882         QCOMPARE(io.size(), QSize(64,64));
883         QImage greenFrame = io.read();
884
885         QCOMPARE(io.size(), QSize(64,64));
886         QCOMPARE(io.size(), QSize(64,64));
887         QImage blueFrame = io.read();
888
889         QCOMPARE(io.size(), QSize());
890         QVERIFY(!io.canRead());
891         QImage emptyFrame = io.read();
892
893         QVERIFY(!io.canRead());
894         QCOMPARE(blackFrame.pixel(0,0), qRgb(0, 0, 0));
895         QCOMPARE(blackFrame.size(), QSize(64,64));
896
897         QCOMPARE(whiteFrame.pixel(0,0), qRgb(0xff, 0xff, 0xff));
898         QCOMPARE(whiteFrame.size(), QSize(64,64));
899
900         QCOMPARE(greenFrame.pixel(0,0), qRgb(0x0, 0xff, 0x0));
901         QCOMPARE(greenFrame.size(), QSize(64,64));
902
903         QCOMPARE(blueFrame.pixel(0,0), qRgb(0x0, 0x0, 0xff));
904         QCOMPARE(blueFrame.size(), QSize(64,64));
905         QVERIFY(emptyFrame.isNull());
906     }
907     {
908         QImageReader io(":images/trolltech.gif");
909         QVERIFY(io.imageCount() == 34);
910         QVERIFY(io.size() == QSize(128,64));
911     }
912 }
913
914 void tst_QImageReader::gifLoopCount()
915 {
916     SKIP_IF_UNSUPPORTED("gif");
917
918     {
919         QImageReader io(":images/qt-gif-anim.gif");
920         QCOMPARE(io.loopCount(), -1); // infinite loop
921     }
922     {
923         QImageReader io(":images/qt-gif-noanim.gif");
924         QCOMPARE(io.loopCount(), 0); // no loop
925     }
926 }
927
928 class Server : public QObject
929 {
930     Q_OBJECT
931 public:
932     Server(const QByteArray &data) :serverSocket(0)
933     {
934         connect(&server, SIGNAL(newConnection()), this, SLOT(acceptNewConnection()));
935         server.listen();
936         this->data = data;
937     }
938
939 public slots:
940     void runTest()
941     {
942         connect(&clientSocket, SIGNAL(connected()), this, SLOT(connected()));
943         clientSocket.connectToHost(QHostAddress::LocalHost, server.serverPort());
944     }
945
946 public:
947     inline QTcpSocket *socket() const { return serverSocket; }
948
949 signals:
950     void ready();
951
952 private slots:
953     void acceptNewConnection()
954     {
955         serverSocket = server.nextPendingConnection();
956         connect(serverSocket, SIGNAL(error(QAbstractSocket::SocketError)),
957                 this, SLOT(remoteHostClosed()));
958     }
959
960     void connected()
961     {
962         clientSocket.write(data);
963         clientSocket.disconnectFromHost();
964     }
965
966     void remoteHostClosed()
967     {
968         emit ready();
969     }
970
971 private:
972     QTcpServer server;
973     QTcpSocket clientSocket;
974     QTcpSocket *serverSocket;
975     QByteArray data;
976 };
977
978 void tst_QImageReader::readFromDevice_data()
979 {
980     QTest::addColumn<QString>("fileName");
981     QTest::addColumn<QByteArray>("format");
982
983     QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm");
984     QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm");
985     QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm");
986     QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm");
987     QTest::newRow("ppm-3") << QString("teapot.ppm") << QByteArray("ppm");
988     QTest::newRow("ppm-4") << QString("runners.ppm") << QByteArray("ppm");
989
990     QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
991     QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
992     QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
993     QTest::newRow("jpeg-4") << QString("qtbug13653-no_eoi.jpg") << QByteArray("jpeg");
994
995     QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif");
996     QTest::newRow("gif-2") << QString("trolltech.gif") << QByteArray("gif");
997
998     QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
999     QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
1000     QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
1001     QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
1002     QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
1003     QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
1004     QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
1005
1006     QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
1007     QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
1008 #if defined QTEST_HAVE_TGA
1009     QTest::newRow("tga") << QString("test-flag.tga") << QByteArray("tga");
1010 #endif
1011 }
1012
1013 static QByteArray msgReadFromDeviceFail(const QString &sourceFileName,
1014                                         const QByteArray &detectedFormat)
1015 {
1016     QByteArray result = "Failure for '";
1017     result += sourceFileName.toLocal8Bit();
1018     result += "', detected as: '";
1019     result += detectedFormat;
1020     result += '\'';
1021     return result;
1022 }
1023
1024 void tst_QImageReader::readFromDevice()
1025 {
1026     QFETCH(QString, fileName);
1027     QFETCH(QByteArray, format);
1028
1029     SKIP_IF_UNSUPPORTED(format);
1030
1031     const QString imageFileName = prefix + fileName;
1032     QImage expectedImage(imageFileName, format);
1033     QFile file(imageFileName);
1034     QVERIFY(file.open(QFile::ReadOnly));
1035     QByteArray imageData = file.readAll();
1036     QVERIFY(!imageData.isEmpty());
1037     {
1038         QBuffer buffer;
1039         buffer.setData(imageData);
1040         QVERIFY(buffer.open(QBuffer::ReadOnly));
1041
1042         QImageReader reader(&buffer);
1043         QVERIFY(reader.canRead());
1044         QImage imageReaderImage = reader.read();
1045
1046         QVERIFY2(!imageReaderImage.isNull(), msgReadFromDeviceFail(imageFileName, reader.format()).constData());
1047         QCOMPARE(imageReaderImage, expectedImage);
1048
1049         buffer.seek(0);
1050
1051         QImage image1;
1052         QVERIFY(image1.loadFromData((const uchar *)buffer.data().data(),
1053                                     buffer.data().size(), format.data()));
1054         QCOMPARE(image1, expectedImage);
1055
1056         QByteArray throughBase64 = QByteArray::fromBase64(imageData.toBase64());
1057         QVERIFY(image1.loadFromData((const uchar *)throughBase64.data(),
1058                                     throughBase64.size(), format.data()));
1059         QCOMPARE(image1, expectedImage);
1060     }
1061
1062     Server server(imageData);
1063     QEventLoop loop;
1064     connect(&server, SIGNAL(ready()), &loop, SLOT(quit()));
1065     QTimer::singleShot(0, &server, SLOT(runTest()));
1066     QTimer::singleShot(5000, &loop, SLOT(quit()));
1067     loop.exec();
1068
1069     QImageReader reader(server.socket(), format == "xbm" ? "xbm" : "");
1070     if (format == "xbm")
1071         QVERIFY(!reader.canRead());
1072     else
1073         QVERIFY(reader.canRead());
1074     QImage imageReaderImage = reader.read();
1075     QCOMPARE(imageReaderImage, expectedImage);
1076 }
1077
1078 void tst_QImageReader::readFromFileAfterJunk_data()
1079 {
1080     QTest::addColumn<QString>("fileName");
1081     QTest::addColumn<QByteArray>("format");
1082
1083     QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm");
1084     QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm");
1085     QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm");
1086     QTest::newRow("ppm-2") << QString("teapot.ppm") << QByteArray("ppm");
1087     QTest::newRow("ppm-3") << QString("teapot.ppm") << QByteArray("ppm");
1088     QTest::newRow("ppm-4") << QString("runners.ppm") << QByteArray("ppm");
1089
1090     QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
1091     QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
1092     QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
1093
1094     QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
1095     QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
1096     QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
1097     QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
1098     QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
1099     QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
1100     QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
1101     QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
1102     QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
1103 }
1104
1105 void tst_QImageReader::readFromFileAfterJunk()
1106 {
1107     QFETCH(QString, fileName);
1108     QFETCH(QByteArray, format);
1109
1110     SKIP_IF_UNSUPPORTED(format);
1111
1112     QFile::remove("junk");
1113     QFile junkFile("junk");
1114     QVERIFY(junkFile.open(QFile::WriteOnly));
1115
1116     QFile imageFile(prefix + fileName);
1117     QVERIFY(imageFile.open(QFile::ReadOnly));
1118     QByteArray imageData = imageFile.readAll();
1119     QVERIFY(!imageData.isNull());
1120
1121     int iterations = 3;
1122     if (format == "ppm" || format == "pbm" || format == "pgm" || format == "svg" || format == "svgz")
1123         iterations = 1;
1124
1125     if (!QImageWriter::supportedImageFormats().contains(format)) {
1126         for (int i = 0; i < iterations; ++i) {
1127             junkFile.write("deadbeef", 9);
1128             QCOMPARE(junkFile.write(imageData), qint64(imageData.size()));
1129         }
1130     } else {
1131         for (int i = 0; i < iterations; ++i) {
1132             QImageWriter writer(&junkFile, format);
1133             junkFile.write("deadbeef", 9);
1134             QVERIFY(writer.write(QImage(prefix + fileName)));
1135         }
1136     }
1137     junkFile.close();
1138     junkFile.open(QFile::ReadOnly);
1139
1140     for (int i = 0; i < iterations; ++i) {
1141         QByteArray ole = junkFile.read(9);
1142         junkFile.ungetChar(ole[ole.size() - 1]);
1143         char c;
1144         junkFile.getChar(&c);
1145         QImageReader reader(&junkFile);
1146         QVERIFY(reader.canRead());
1147         QVERIFY(!reader.read().isNull());
1148     }
1149 }
1150
1151 void tst_QImageReader::devicePosition_data()
1152 {
1153     QTest::addColumn<QString>("fileName");
1154     QTest::addColumn<QByteArray>("format");
1155
1156     QTest::newRow("pbm") << QString("image.pbm") << QByteArray("pbm");
1157     QTest::newRow("pgm") << QString("image.pgm") << QByteArray("pgm");
1158     QTest::newRow("ppm-1") << QString("image.ppm") << QByteArray("ppm");
1159
1160     QTest::newRow("jpeg-1") << QString("beavis.jpg") << QByteArray("jpeg");
1161     QTest::newRow("jpeg-2") << QString("YCbCr_cmyk.jpg") << QByteArray("jpeg");
1162     QTest::newRow("jpeg-3") << QString("YCbCr_rgb.jpg") << QByteArray("jpeg");
1163
1164     QTest::newRow("gif-1") << QString("earth.gif") << QByteArray("gif");
1165
1166     QTest::newRow("xbm") << QString("gnus.xbm") << QByteArray("xbm");
1167     QTest::newRow("xpm") << QString("marble.xpm") << QByteArray("xpm");
1168     QTest::newRow("bmp-1") << QString("colorful.bmp") << QByteArray("bmp");
1169     QTest::newRow("bmp-2") << QString("font.bmp") << QByteArray("bmp");
1170     QTest::newRow("bmp-3") << QString("test32bfv4.bmp") << QByteArray("bmp");
1171     QTest::newRow("bmp-4") << QString("test32v5.bmp") << QByteArray("bmp");
1172     QTest::newRow("png") << QString("kollada.png") << QByteArray("png");
1173     QTest::newRow("svg") << QString("rect.svg") << QByteArray("svg");
1174     QTest::newRow("svgz") << QString("rect.svgz") << QByteArray("svgz");
1175 }
1176
1177 void tst_QImageReader::devicePosition()
1178 {
1179     QFETCH(QString, fileName);
1180     QFETCH(QByteArray, format);
1181
1182     SKIP_IF_UNSUPPORTED(format);
1183
1184     QImage expected(prefix + fileName);
1185     QVERIFY(!expected.isNull());
1186
1187     QFile imageFile(prefix + fileName);
1188     QVERIFY(imageFile.open(QFile::ReadOnly));
1189     QByteArray imageData = imageFile.readAll();
1190     QVERIFY(!imageData.isNull());
1191     int imageDataSize = imageData.size();
1192
1193     const char *preStr = "prebeef\n";
1194     int preLen = qstrlen(preStr);
1195     imageData.prepend(preStr);
1196     if (format != "svg" && format != "svgz") // Doesn't handle trailing data
1197         imageData.append("\npostbeef");
1198     QBuffer buf(&imageData);
1199     buf.open(QIODevice::ReadOnly);
1200     buf.seek(preLen);
1201     QImageReader reader(&buf, format);
1202     QCOMPARE(expected, reader.read());
1203     if (format != "ppm" &&
1204         format != "pgm" &&
1205         format != "pbm" &&
1206         format != "gif")  // Known not to work
1207         QCOMPARE(buf.pos(), qint64(preLen+imageDataSize));
1208 }
1209
1210
1211 void tst_QImageReader::readFromResources_data()
1212 {
1213     QTest::addColumn<QString>("fileName");
1214     QTest::addColumn<QByteArray>("format");
1215     QTest::addColumn<QSize>("size");
1216     QTest::addColumn<QString>("message");
1217
1218     QTest::newRow("corrupt.bmp") << QString("corrupt.bmp")
1219                                         << QByteArray("bmp") << QSize(0, 0)
1220                                         << QString("");
1221     QTest::newRow("negativeheight.bmp") << QString("negativeheight.bmp")
1222                                                << QByteArray("bmp") << QSize(127, 64)
1223                                                << QString("");
1224     QTest::newRow("font.bmp") << QString("font.bmp")
1225                                      << QByteArray("bmp") << QSize(240, 8)
1226                                      << QString("");
1227     QTest::newRow("noclearcode.bmp") << QString("noclearcode.bmp")
1228                                             << QByteArray("bmp") << QSize(29, 18)
1229                                             << QString("");
1230     QTest::newRow("colorful.bmp") << QString("colorful.bmp")
1231                                          << QByteArray("bmp") << QSize(320, 200)
1232                                          << QString("");
1233     QTest::newRow("16bpp.bmp") << QString("16bpp.bmp")
1234                                       << QByteArray("bmp") << QSize(320, 240)
1235                                       << QString("");
1236     QTest::newRow("crash-signed-char.bmp") << QString("crash-signed-char.bmp")
1237                                                   << QByteArray("bmp") << QSize(360, 280)
1238                                                   << QString("");
1239     QTest::newRow("4bpp-rle.bmp") << QString("4bpp-rle.bmp")
1240                                          << QByteArray("bmp") << QSize(640, 480)
1241                                          << QString("");
1242     QTest::newRow("test32bfv4.bmp") << QString("test32bfv4.bmp")
1243                                          << QByteArray("bmp") << QSize(373, 156)
1244                                          << QString("");
1245     QTest::newRow("test32v5.bmp") << QString("test32v5.bmp")
1246                                          << QByteArray("bmp") << QSize(373, 156)
1247                                          << QString("");
1248     QTest::newRow("corrupt.gif") << QString("corrupt.gif")
1249                                         << QByteArray("gif") << QSize(0, 0)
1250                                         << QString("");
1251     QTest::newRow("trolltech.gif") << QString("trolltech.gif")
1252                                           << QByteArray("gif") << QSize(128, 64)
1253                                           << QString("");
1254     QTest::newRow("noclearcode.gif") << QString("noclearcode.gif")
1255                                             << QByteArray("gif") << QSize(29, 18)
1256                                             << QString("");
1257     QTest::newRow("earth.gif") << QString("earth.gif")
1258                                       << QByteArray("gif") << QSize(320, 200)
1259                                       << QString("");
1260     QTest::newRow("bat1.gif") << QString("bat1.gif")
1261                                      << QByteArray("gif") << QSize(32, 32)
1262                                      << QString("");
1263     QTest::newRow("bat2.gif") << QString("bat2.gif")
1264                                      << QByteArray("gif") << QSize(32, 32)
1265                                      << QString("");
1266     QTest::newRow("corrupt.jpg") << QString("corrupt.jpg")
1267                                         << QByteArray("jpg") << QSize(0, 0)
1268                                         << QString("JPEG datastream contains no image");
1269     QTest::newRow("beavis.jpg") << QString("beavis.jpg")
1270                                        << QByteArray("jpg") << QSize(350, 350)
1271                                        << QString("");
1272     QTest::newRow("YCbCr_cmyk.jpg") << QString("YCbCr_cmyk.jpg")
1273                                            << QByteArray("jpg") << QSize(75, 50)
1274                                            << QString("");
1275     QTest::newRow("YCbCr_rgb.jpg") << QString("YCbCr_rgb.jpg")
1276                                           << QByteArray("jpg") << QSize(75, 50)
1277                                           << QString("");
1278     QTest::newRow("qtbug13653-no_eoi.jpg") << QString("qtbug13653-no_eoi.jpg")
1279                                         << QByteArray("jpg") << QSize(240, 180)
1280                                         << QString("");
1281     QTest::newRow("rect.svg") << QString("rect.svg")
1282                                      << QByteArray("svg") << QSize(105, 137)
1283                                      << QString("");
1284     QTest::newRow("rect.svgz") << QString("rect.svgz")
1285                                      << QByteArray("svgz") << QSize(105, 137)
1286                                      << QString("");
1287     QTest::newRow("corrupt.svg") << QString("corrupt.svg")
1288                                      << QByteArray("svg") << QSize(0, 0)
1289                                      << QString("");
1290     QTest::newRow("corrupt.svgz") << QString("corrupt.svgz")
1291                                      << QByteArray("svgz") << QSize(0, 0)
1292                                      << QString("");
1293     QTest::newRow("image.pbm") << QString("image.pbm")
1294                                       << QByteArray("pbm") << QSize(16, 6)
1295                                       << QString("");
1296     QTest::newRow("image.pgm") << QString("image.pgm")
1297                                       << QByteArray("pgm") << QSize(24, 7)
1298                                       << QString("");
1299     QTest::newRow("corrupt.png") << QString("corrupt.png")
1300                                         << QByteArray("png") << QSize(0, 0)
1301                                         << QString("");
1302     QTest::newRow("away.png") << QString("away.png")
1303                                      << QByteArray("png") << QSize(16, 16)
1304                                      << QString("");
1305     QTest::newRow("image.png") << QString("image.png")
1306                                       << QByteArray("png") << QSize(22, 22)
1307                                       << QString("");
1308     QTest::newRow("kollada.png") << QString("kollada.png")
1309                                         << QByteArray("png") << QSize(436, 160)
1310                                         << QString("");
1311     QTest::newRow("black.png") << QString("black.png")
1312                                       << QByteArray("png") << QSize(48, 48)
1313                                       << QString("");
1314     QTest::newRow("YCbCr_cmyk.png") << QString("YCbCr_cmyk.png")
1315                                            << QByteArray("png") << QSize(75, 50)
1316                                            << QString("");
1317     QTest::newRow("teapot.ppm") << QString("teapot.ppm")
1318                                        << QByteArray("ppm") << QSize(256, 256)
1319                                        << QString("");
1320     QTest::newRow("image.ppm") << QString("image.ppm")
1321                                       << QByteArray("ppm") << QSize(4, 4)
1322                                       << QString("");
1323     QTest::newRow("runners.ppm") << QString("runners.ppm")
1324                                         << QByteArray("ppm") << QSize(400, 400)
1325                                         << QString("");
1326     QTest::newRow("test.ppm") << QString("test.ppm")
1327                                      << QByteArray("ppm") << QSize(10, 10)
1328                                      << QString("");
1329     QTest::newRow("gnus.xbm") << QString("gnus.xbm")
1330                                      << QByteArray("xbm") << QSize(271, 273)
1331                                      << QString("");
1332     QTest::newRow("corrupt-colors.xpm") << QString("corrupt-colors.xpm")
1333                                                << QByteArray("xpm") << QSize(0, 0)
1334                                                << QString("QImage: XPM color specification is missing: bla9an.n#x");
1335     QTest::newRow("corrupt-pixels.xpm") << QString("corrupt-pixels.xpm")
1336                                                << QByteArray("xpm") << QSize(0, 0)
1337                                                << QString("QImage: XPM pixels missing on image line 3");
1338     QTest::newRow("corrupt-pixel-count.xpm") << QString("corrupt-pixel-count.xpm")
1339                                              << QByteArray("xpm") << QSize(0, 0)
1340                                              << QString("");
1341     QTest::newRow("marble.xpm") << QString("marble.xpm")
1342                                        << QByteArray("xpm") << QSize(240, 240)
1343                                        << QString("");
1344     QTest::newRow("test.xpm") << QString("test.xpm")
1345                                      << QByteArray("xpm") << QSize(256, 256)
1346                                      << QString("");
1347     QTest::newRow("black.xpm") << QString("black.xpm")
1348                                       << QByteArray("xpm") << QSize(48, 48)
1349                                       << QString("");
1350     QTest::newRow("namedcolors.xpm") << QString("namedcolors.xpm")
1351                                             << QByteArray("xpm") << QSize(8, 8)
1352                                             << QString("");
1353     QTest::newRow("nontransparent.xpm") << QString("nontransparent.xpm")
1354                                                << QByteArray("xpm") << QSize(8, 8)
1355                                                << QString("");
1356     QTest::newRow("transparent.xpm") << QString("transparent.xpm")
1357                                             << QByteArray("xpm") << QSize(8, 8)
1358                                             << QString("");
1359 }
1360
1361 void tst_QImageReader::readFromResources()
1362 {
1363     QFETCH(QString, fileName);
1364     QFETCH(QByteArray, format);
1365     QFETCH(QSize, size);
1366     QFETCH(QString, message);
1367
1368     SKIP_IF_UNSUPPORTED(format);
1369
1370     for (int i = 0; i < 2; ++i) {
1371         QString file = i ? QString(QStringLiteral(":/images/") + fileName) : QString(prefix + fileName);
1372         {
1373             // suppress warnings if we expect them
1374             if (!message.isEmpty()) {
1375                 for (int j = 0; j < 5; ++j)
1376                     QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
1377             }
1378
1379             // 1) full filename, no format
1380             QImageReader reader(file);
1381             QImage image = reader.read();
1382             if (size.isNull())
1383                 QVERIFY(image.isNull());
1384             else
1385                 QVERIFY(!image.isNull());
1386             QCOMPARE(image.size(), size);
1387         }
1388         {
1389             // 2) full filename, with format
1390             QImageReader reader(file, format);
1391             QImage image = reader.read();
1392             if (size.isNull())
1393                 QVERIFY(image.isNull());
1394             else
1395                 QVERIFY(!image.isNull());
1396             QCOMPARE(image.size(), size);
1397         }
1398         {
1399             // 3) full filename, with uppercase format
1400             QImageReader reader(file, format.toUpper());
1401             QImage image = reader.read();
1402             if (size.isNull())
1403                 QVERIFY(image.isNull());
1404             else
1405                 QVERIFY(!image.isNull());
1406             QCOMPARE(image.size(), size);
1407         }
1408         {
1409             // 4) chopped filename, with format
1410             QImageReader reader(file.left(file.lastIndexOf(QLatin1Char('.'))), format);
1411             QImage image = reader.read();
1412             if (size.isNull())
1413                 QVERIFY(image.isNull());
1414             else
1415                 QVERIFY(!image.isNull());
1416             QCOMPARE(image.size(), size);
1417         }
1418         {
1419             // 5) chopped filename, with uppercase format
1420             QImageReader reader(file.left(file.lastIndexOf(QLatin1Char('.'))), format.toUpper());
1421             QImage image = reader.read();
1422             if (size.isNull())
1423                 QVERIFY(image.isNull());
1424             else
1425                 QVERIFY(!image.isNull());
1426             QCOMPARE(image.size(), size);
1427         }
1428     }
1429
1430     // Check that the results are identical
1431     if (!message.isEmpty()) {
1432         QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
1433         QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
1434     }
1435     QCOMPARE(QImageReader(prefix + fileName).read(), QImageReader(":/images/" + fileName).read());
1436 }
1437
1438 void tst_QImageReader::readCorruptImage_data()
1439 {
1440     QTest::addColumn<QString>("fileName");
1441     QTest::addColumn<bool>("shouldFail");
1442     QTest::addColumn<QString>("message");
1443     QTest::addColumn<QByteArray>("format");
1444     QTest::newRow("corrupt jpeg") << QString("corrupt.jpg") << true
1445                                   << QString("JPEG datastream contains no image")
1446                                   << QByteArray("jpeg");
1447     QTest::newRow("corrupt gif") << QString("corrupt.gif") << true << QString("") << QByteArray("gif");
1448     QTest::newRow("corrupt png") << QString("corrupt.png") << true << QString("") << QByteArray("png");
1449     QTest::newRow("corrupt bmp") << QString("corrupt.bmp") << true << QString("") << QByteArray("bmp");
1450     QTest::newRow("corrupt xpm (colors)") << QString("corrupt-colors.xpm") << true
1451                                           << QString("QImage: XPM color specification is missing: bla9an.n#x")
1452                                           << QByteArray("xpm");
1453     QTest::newRow("corrupt xpm (pixels)") << QString("corrupt-pixels.xpm") << true
1454                                           << QString("QImage: XPM pixels missing on image line 3")
1455                                           << QByteArray("xpm");
1456     QTest::newRow("corrupt xbm") << QString("corrupt.xbm") << false << QString("") << QByteArray("xbm");
1457     QTest::newRow("corrupt svg") << QString("corrupt.svg") << true << QString("") << QByteArray("svg");
1458     QTest::newRow("corrupt svgz") << QString("corrupt.svgz") << true << QString("") << QByteArray("svgz");
1459 }
1460
1461 void tst_QImageReader::readCorruptImage()
1462 {
1463     QFETCH(QString, fileName);
1464     QFETCH(bool, shouldFail);
1465     QFETCH(QString, message);
1466     QFETCH(QByteArray, format);
1467
1468     SKIP_IF_UNSUPPORTED(format);
1469
1470     if (!message.isEmpty())
1471         QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
1472     QImageReader reader(prefix + fileName);
1473     QVERIFY(reader.canRead());
1474     QCOMPARE(reader.read().isNull(), shouldFail);
1475 }
1476
1477 void tst_QImageReader::readCorruptBmp()
1478 {
1479     QCOMPARE(QImage(prefix + "tst7.bmp").convertToFormat(QImage::Format_ARGB32_Premultiplied), QImage(prefix + "tst7.png").convertToFormat(QImage::Format_ARGB32_Premultiplied));
1480 }
1481
1482 void tst_QImageReader::supportsOption_data()
1483 {
1484     QTest::addColumn<QString>("fileName");
1485     QTest::addColumn<QIntList>("options");
1486
1487     QTest::newRow("png") << QString("black.png")
1488                          << (QIntList() << QImageIOHandler::Gamma
1489                               << QImageIOHandler::Description
1490                               << QImageIOHandler::Quality
1491                               << QImageIOHandler::Size);
1492 }
1493
1494 void tst_QImageReader::supportsOption()
1495 {
1496     QFETCH(QString, fileName);
1497     QFETCH(QIntList, options);
1498
1499     QSet<QImageIOHandler::ImageOption> allOptions;
1500     allOptions << QImageIOHandler::Size
1501                << QImageIOHandler::ClipRect
1502                << QImageIOHandler::Description
1503                << QImageIOHandler::ScaledClipRect
1504                << QImageIOHandler::ScaledSize
1505                << QImageIOHandler::CompressionRatio
1506                << QImageIOHandler::Gamma
1507                << QImageIOHandler::Quality
1508                << QImageIOHandler::Name
1509                << QImageIOHandler::SubType
1510                << QImageIOHandler::IncrementalReading
1511                << QImageIOHandler::Endianness
1512                << QImageIOHandler::Animation
1513                << QImageIOHandler::BackgroundColor;
1514
1515     QImageReader reader(prefix + fileName);
1516     for (int i = 0; i < options.size(); ++i) {
1517         QVERIFY(reader.supportsOption(QImageIOHandler::ImageOption(options.at(i))));
1518         allOptions.remove(QImageIOHandler::ImageOption(options.at(i)));
1519     }
1520
1521     foreach (QImageIOHandler::ImageOption option, allOptions)
1522         QVERIFY(!reader.supportsOption(option));
1523 }
1524
1525 void tst_QImageReader::autoDetectImageFormat()
1526 {
1527     // Assume PNG is supported :-)
1528     {
1529         // Disables file name extension probing
1530         QImageReader reader(prefix + "kollada");
1531         reader.setAutoDetectImageFormat(false);
1532         QVERIFY(!reader.canRead());
1533         QVERIFY(reader.read().isNull());
1534         reader.setAutoDetectImageFormat(true);
1535         QVERIFY(reader.canRead());
1536         QVERIFY(!reader.read().isNull());
1537     }
1538     {
1539         // Disables detection based on suffix
1540         QImageReader reader(prefix + "kollada.png");
1541         reader.setAutoDetectImageFormat(false);
1542         QVERIFY(!reader.canRead());
1543         QVERIFY(reader.read().isNull());
1544         reader.setAutoDetectImageFormat(true);
1545         QVERIFY(reader.canRead());
1546         QVERIFY(!reader.read().isNull());
1547     }
1548     {
1549         // Disables detection based on content
1550         QImageReader reader(prefix + "kollada-noext");
1551         reader.setAutoDetectImageFormat(false);
1552         QVERIFY(!reader.canRead());
1553         QVERIFY(reader.read().isNull());
1554         reader.setAutoDetectImageFormat(true);
1555         QVERIFY(reader.canRead());
1556         QVERIFY(!reader.read().isNull());
1557     }
1558
1559     if (QImageReader::supportedImageFormats().contains("jpeg")) {
1560         QImageReader io(prefix + "YCbCr_rgb.jpg");
1561         io.setAutoDetectImageFormat(false);
1562         // This should fail since no format string is given
1563         QImage image;
1564         QVERIFY(!io.read(&image));
1565     }
1566     if (QImageReader::supportedImageFormats().contains("jpeg")) {
1567         QImageReader io(prefix + "YCbCr_rgb.jpg", "jpg");
1568         io.setAutoDetectImageFormat(false);
1569         QImage image;
1570         QVERIFY(io.read(&image));
1571     }
1572     {
1573         QImageReader io(prefix + "tst7.png");
1574         io.setAutoDetectImageFormat(false);
1575         // This should fail since no format string is given
1576         QImage image;
1577         QVERIFY(!io.read(&image));
1578     }
1579     {
1580         QImageReader io(prefix + "tst7.png", "png");
1581         io.setAutoDetectImageFormat(false);
1582         QImage image;
1583         QVERIFY(io.read(&image));
1584     }
1585 }
1586
1587 void tst_QImageReader::fileNameProbing()
1588 {
1589     QString name("doesnotexist.png");
1590     QImageReader r;
1591     r.setFileName(name); // non-existing / non-readable file
1592     QCOMPARE(r.fileName(), name);
1593
1594     r.size();
1595     QCOMPARE(r.fileName(), name);
1596     r.read();
1597     QCOMPARE(r.fileName(), name);
1598 }
1599
1600 void tst_QImageReader::pixelCompareWithBaseline_data()
1601 {
1602     QTest::addColumn<QString>("fileName");
1603
1604     QTest::newRow("floppy (16px,32px - 16 colors)") << "35floppy.ico";
1605     QTest::newRow("semitransparent") << "semitransparent.ico";
1606     QTest::newRow("slightlybrokenBMPHeader") << "kde_favicon.ico";
1607     QTest::newRow("sightlybrokenIconHeader") << "connect.ico";
1608 }
1609
1610 void tst_QImageReader::pixelCompareWithBaseline()
1611 {
1612     QFETCH(QString, fileName);
1613
1614     static int enteredCount = 0;    // Used for better error diagnostics if something fails. We
1615     static int loadFailCount = 0;   // don't know if the reason load() fails is that the plugin
1616                                     // does not exist or because of a bug in the plugin. But if at
1617                                     // least one file succeeded we know that the plugin was built.
1618                                     // The other failures are then real failures.
1619     QImage icoImg;
1620     const QString inputFileName(QString::fromAscii("images/%1").arg(fileName));
1621     QFileInfo fi(inputFileName);
1622
1623     ++enteredCount;
1624     // might fail if the plugin does not exist, which is ok.
1625     if (icoImg.load(inputFileName)) {
1626         icoImg = icoImg.convertToFormat(QImage::Format_ARGB32_Premultiplied);
1627         const QString baselineFileName(QString::fromAscii("baseline/%1.png").arg(fi.baseName()));
1628 #if 0
1629         icoImg.save(baselineFileName);
1630 #else
1631         QImage baseImg;
1632         QVERIFY(baseImg.load(baselineFileName));
1633         baseImg = baseImg.convertToFormat(QImage::Format_ARGB32_Premultiplied);
1634         QCOMPARE(int(baseImg.format()), int(icoImg.format()));
1635         QCOMPARE(baseImg, icoImg);
1636 #endif
1637     } else {
1638         ++loadFailCount;
1639         if (enteredCount != loadFailCount) {
1640             QFAIL("Plugin is built, but some did not load properly");
1641         } else {
1642             qWarning("loading failed, check if ico plugin is built");
1643         }
1644     }
1645 }
1646
1647
1648 void tst_QImageReader::testIgnoresFormatAndExtension_data()
1649 {
1650     QTest::addColumn<QString>("name");
1651     QTest::addColumn<QString>("extension");
1652     QTest::addColumn<QString>("expected");
1653
1654     QTest::newRow("black.png") << "black" << "png" << "png";
1655     QTest::newRow("black.xpm") << "black" << "xpm" << "xpm";
1656     QTest::newRow("colorful.bmp") << "colorful" << "bmp" << "bmp";
1657     QTest::newRow("image.ppm") << "image" << "ppm" << "ppm";
1658     QTest::newRow("image.pbm") << "image" << "pbm" << "pbm";
1659     QTest::newRow("image.pgm") << "image" << "pgm" << "pgm";
1660
1661     QTest::newRow("bat1.gif") << "bat1" << "gif" << "gif";
1662
1663     QTest::newRow("beavis.jpg") << "beavis" << "jpg" << "jpeg";
1664
1665     QTest::newRow("rect.svg") << "rect" << "svg" << "svg";
1666     QTest::newRow("rect.svgz") << "rect" << "svgz" << "svgz";
1667 }
1668
1669 static QByteArray msgIgnoreFormatAndExtensionFail(const QString &sourceFileName,
1670                                                   const QString &targetFileName,
1671                                                   const QString &detectedFormat)
1672 {
1673     QByteArray result = "Failure for '";
1674     result += sourceFileName.toLocal8Bit();
1675     result += "' as '";
1676     result += targetFileName;
1677     result += "', detected as: '";
1678     result += detectedFormat.toLocal8Bit();
1679     result += '\'';
1680     return result;
1681 }
1682
1683 void tst_QImageReader::testIgnoresFormatAndExtension()
1684 {
1685     QFETCH(QString, name);
1686     QFETCH(QString, extension);
1687     QFETCH(QString, expected);
1688
1689     SKIP_IF_UNSUPPORTED(expected.toLatin1());
1690
1691     QList<QByteArray> formats = QImageReader::supportedImageFormats();
1692     QString fileNameBase = prefix + name + QLatin1Char('.');
1693     QString tempPath = m_temporaryDir.path();
1694     if (!tempPath.endsWith(QLatin1Char('/')))
1695         tempPath += QLatin1Char('/');
1696
1697     foreach (const QByteArray &f, formats) {
1698         if (f == extension)
1699             continue;
1700
1701         QFile tmp(tempPath + name + QLatin1Char('_') + expected + QLatin1Char('.') + f);
1702         const QString sourceFileName = fileNameBase + extension;
1703         const QString tempFileName = QFileInfo(tmp).absoluteFilePath();
1704         QVERIFY(QFile::copy(sourceFileName, tempFileName));
1705
1706         QString format;
1707         QImage image;
1708         {
1709             // image reader needs to be scoped for the remove() to work..
1710             QImageReader r;
1711             r.setFileName(tempFileName);
1712             r.setDecideFormatFromContent(true);
1713             format = r.format();
1714             r.read(&image);
1715         }
1716
1717         tmp.remove();
1718
1719         QVERIFY2(!image.isNull(), msgIgnoreFormatAndExtensionFail(sourceFileName, tempFileName, format).constData());
1720         QCOMPARE(format, expected);
1721     }
1722 }
1723
1724
1725 void tst_QImageReader::saveFormat_data()
1726 {
1727     QTest::addColumn<QImage::Format>("format");
1728
1729     QTest::newRow("Format_Mono") << QImage::Format_Mono;
1730     QTest::newRow("Format_MonoLSB") << QImage::Format_MonoLSB;
1731     QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
1732     QTest::newRow("Format_RGB32") << QImage::Format_RGB32;
1733     QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32;
1734     QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
1735     QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
1736     QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied;
1737     QTest::newRow("Format_RGB666") << QImage::Format_RGB666;
1738     QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied;
1739     QTest::newRow("Format_RGB555") << QImage::Format_RGB555;
1740     QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
1741     QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
1742     QTest::newRow("Format_RGB444") << QImage::Format_RGB444;
1743     QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied;
1744 }
1745
1746 void tst_QImageReader::saveFormat()
1747 {
1748     QFETCH(QImage::Format, format);
1749
1750     QImage orig(":/images/kollada.png");
1751
1752     QImage converted = orig.convertToFormat(format);
1753     QBuffer buf;
1754     buf.open(QIODevice::WriteOnly);
1755     QVERIFY(converted.save(&buf, "png"));
1756     buf.close();
1757     QImage stored = QImage::fromData(buf.buffer(), "png");
1758
1759     stored = stored.convertToFormat(QImage::Format_ARGB32);
1760     converted = converted.convertToFormat(QImage::Format_ARGB32);
1761     QCOMPARE(stored, converted);
1762 }
1763
1764
1765 void tst_QImageReader::readText_data()
1766 {
1767     QTest::addColumn<QString>("fileName");
1768     QTest::addColumn<QString>("key");
1769     QTest::addColumn<QString>("text");
1770
1771     QTest::newRow("png, tEXt before img") << "txts.png" << "Title" << "PNG";
1772     QTest::newRow("png, zTXt before img") << "txts.png" << "Comment" << "Some compressed text.";
1773     QTest::newRow("png, tEXt after img") << "txts.png" << "Disclaimer" << "For testing only.";
1774     QTest::newRow("png, zTXt after img") << "txts.png" << "Description" << "Rendered by Persistence of Vision (tm) Ray Tracer";
1775 }
1776
1777
1778 void tst_QImageReader::readText()
1779 {
1780     QFETCH(QString, fileName);
1781     QFETCH(QString, key);
1782     QFETCH(QString, text);
1783
1784     QImage img(prefix + fileName);
1785     QVERIFY(img.textKeys().contains(key));
1786     QCOMPARE(img.text(key), text);
1787 }
1788
1789
1790 void tst_QImageReader::preserveTexts_data()
1791 {
1792     QTest::addColumn<QString>("text");
1793
1794     QTest::newRow("Simple") << "simpletext";
1795     QTest::newRow("Whitespace") << " A text  with whitespace ";
1796     QTest::newRow("Newline") << "A text\nwith newlines\n";
1797     QTest::newRow("Double newlines") << "A text\n\nwith double newlines\n\n";
1798     QTest::newRow("Long") << QString("A rather long text, at least after many repetitions. ").repeated(100);
1799     QString latin1set;
1800     int c;
1801     for(c = 0x20; c <= 0x7e; c++)
1802         latin1set.append(QLatin1Char(c));
1803     for(c = 0xa0; c <= 0xff; c++)
1804         latin1set.append(QLatin1Char(c));
1805     QTest::newRow("All Latin1 chars") << latin1set;
1806
1807 #if 0
1808     // Depends on iTXt support in libpng
1809     QTest::newRow("Multibyte string") << QString::fromUtf8("\341\233\222\341\233\226\341\232\251\341\232\271\341\232\242\341\233\232\341\232\240");
1810 #endif
1811 }
1812
1813
1814 void tst_QImageReader::preserveTexts()
1815 {
1816     QFETCH(QString, text);
1817     QString key("testkey");
1818     QString key2("testkey2");
1819     QString text2("Some other text.");
1820     QString key3("testkey3");
1821     QString text3("Some more other text.");
1822
1823     QImage img(":/images/kollada.png");
1824     img.setText(key, text);
1825     img.setText(key2, text2);
1826     QBuffer buf;
1827     buf.open(QIODevice::WriteOnly);
1828     QVERIFY(img.save(&buf, "png"));
1829     buf.close();
1830     QImage stored = QImage::fromData(buf.buffer(), "png");
1831     QCOMPARE(stored.text(key), text);
1832     QCOMPARE(stored.text(key2), text2);
1833
1834     QImage img2(":/images/kollada.png");
1835     img2.setText(key3, text3);
1836     QBuffer buf2;
1837     QImageWriter w(&buf2, "png");
1838     w.setText(key, text);
1839     w.setText(key2, text2);
1840     QVERIFY(w.write(img2));
1841     buf2.close();
1842     QImageReader r(&buf2, "png");
1843     QCOMPARE(r.text(key), text.simplified());
1844     QCOMPARE(r.text(key2), text2.simplified());
1845     QCOMPARE(r.text(key3), text3.simplified());
1846 }
1847
1848
1849 QTEST_MAIN(tst_QImageReader)
1850 #include "tst_qimagereader.moc"