1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
43 #include <QtTest/QtTest>
44 
45 
46 #include <QDebug>
47 #include <QFile>
48 #include <QImage>
49 #include <QImageReader>
50 #include <QImageWriter>
51 #include <QLabel>
52 #include <QPainter>
53 #include <QSet>
54 
55 #if defined(Q_OS_SYMBIAN)
56 # define SRCDIR ""
57 #endif
58 typedef QMap<QString, QString> QStringMap;
59 typedef QList<int> QIntList;
60 Q_DECLARE_METATYPE(QImage)
61 Q_DECLARE_METATYPE(QStringMap)
62 Q_DECLARE_METATYPE(QIntList)
63 Q_DECLARE_METATYPE(QImageWriter::ImageWriterError)
64 Q_DECLARE_METATYPE(QIODevice *)
65 Q_DECLARE_METATYPE(QImage::Format)
66 
67 //TESTED_FILES=
68 
69 class tst_QImageWriter : public QObject
70 {
71     Q_OBJECT
72 
73 public:
74     tst_QImageWriter();
75     virtual ~tst_QImageWriter();
76 
77 public slots:
78     void init();
79     void cleanup();
80 
81 private slots:
82     void getSetCheck();
83     void writeImage_data();
84     void writeImage();
85     void writeImage2_data();
86     void writeImage2();
87     void supportedFormats();
88 
89     void readWriteNonDestructive_data();
90     void readWriteNonDestructive();
91 
92 #if defined QTEST_HAVE_TIFF
93     void largeTiff();
94 #endif
95 
96     void writeToInvalidDevice();
97 
98     void supportsOption_data();
99     void supportsOption();
100 
101     void saveWithNoFormat_data();
102     void saveWithNoFormat();
103 
104     void resolution_data();
105     void resolution();
106 
107     void saveToTemporaryFile();
108 };
109 #ifdef Q_OS_SYMBIAN
110 static const QLatin1String prefix(SRCDIR "images/");
111 #else
112 static const QLatin1String prefix(SRCDIR "/images/");
113 #endif
initializePadding(QImage * image)114 static void initializePadding(QImage *image)
115 {
116     int effectiveBytesPerLine = (image->width() * image->depth() + 7) / 8;
117     int paddingBytes = image->bytesPerLine() - effectiveBytesPerLine;
118     if (paddingBytes == 0)
119         return;
120     for (int y = 0; y < image->height(); ++y) {
121         qMemSet(image->scanLine(y) + effectiveBytesPerLine, 0, paddingBytes);
122     }
123 }
124 
125 // Testing get/set functions
getSetCheck()126 void tst_QImageWriter::getSetCheck()
127 {
128     QImageWriter obj1;
129     // QIODevice * QImageWriter::device()
130     // void QImageWriter::setDevice(QIODevice *)
131     QFile *var1 = new QFile;
132     obj1.setDevice(var1);
133 
134     QCOMPARE((QIODevice *) var1, obj1.device());
135     // The class should possibly handle a 0-pointer as a device, since
136     // there is a default contructor, so it's "handling" a 0 device by default.
137     // For example: QMovie::setDevice(0) works just fine
138     obj1.setDevice((QIODevice *)0);
139     QCOMPARE((QIODevice *) 0, obj1.device());
140     delete var1;
141 
142     // int QImageWriter::quality()
143     // void QImageWriter::setQuality(int)
144     obj1.setQuality(0);
145     QCOMPARE(0, obj1.quality());
146     obj1.setQuality(INT_MIN);
147     QCOMPARE(INT_MIN, obj1.quality());
148     obj1.setQuality(INT_MAX);
149     QCOMPARE(INT_MAX, obj1.quality());
150 
151     // int QImageWriter::compression()
152     // void QImageWriter::setCompression(int)
153     obj1.setCompression(0);
154     QCOMPARE(0, obj1.compression());
155     obj1.setCompression(INT_MIN);
156     QCOMPARE(INT_MIN, obj1.compression());
157     obj1.setCompression(INT_MAX);
158     QCOMPARE(INT_MAX, obj1.compression());
159 
160     // float QImageWriter::gamma()
161     // void QImageWriter::setGamma(float)
162     obj1.setGamma(0.0f);
163     QCOMPARE(0.0f, obj1.gamma());
164     obj1.setGamma(1.1f);
165     QCOMPARE(1.1f, obj1.gamma());
166 }
167 
tst_QImageWriter()168 tst_QImageWriter::tst_QImageWriter()
169 {
170 }
171 
~tst_QImageWriter()172 tst_QImageWriter::~tst_QImageWriter()
173 {
174     QDir dir(prefix);
175     QStringList filesToDelete = dir.entryList(QStringList() << "gen-*" , QDir::NoDotAndDotDot | QDir::Files);
176     foreach( QString file, filesToDelete) {
177         QFile::remove(dir.absoluteFilePath(file));
178     }
179 
180 }
181 
init()182 void tst_QImageWriter::init()
183 {
184 }
185 
cleanup()186 void tst_QImageWriter::cleanup()
187 {
188 }
189 
writeImage_data()190 void tst_QImageWriter::writeImage_data()
191 {
192     QTest::addColumn<QString>("fileName");
193     QTest::addColumn<bool>("lossy");
194     QTest::addColumn<QByteArray>("format");
195 
196     QTest::newRow("BMP: colorful") << QString("colorful.bmp") << false << QByteArray("bmp");
197     QTest::newRow("BMP: font") << QString("font.bmp") << false << QByteArray("bmp");
198     QTest::newRow("XPM: marble") << QString("marble.xpm") << false << QByteArray("xpm");
199     QTest::newRow("PNG: kollada") << QString("kollada.png") << false << QByteArray("png");
200     QTest::newRow("PPM: teapot") << QString("teapot.ppm") << false << QByteArray("ppm");
201     QTest::newRow("PBM: ship63") << QString("ship63.pbm") << true << QByteArray("pbm");
202     QTest::newRow("XBM: gnus") << QString("gnus.xbm") << false << QByteArray("xbm");
203     QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << true << QByteArray("jpeg");
204 #if defined QTEST_HAVE_TIFF
205     QTest::newRow("TIFF: teapot") << QString("teapot.tiff") << false << QByteArray("tiff");
206 #endif
207 }
208 
writeImage()209 void tst_QImageWriter::writeImage()
210 {
211     QFETCH(QString, fileName);
212     QFETCH(bool, lossy);
213     QFETCH(QByteArray, format);
214 
215     QImage image;
216     {
217         QImageReader reader(prefix + fileName);
218         image = reader.read();
219         QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
220     }
221     {
222         QImageWriter writer(prefix + "gen-" + fileName, format);
223         QVERIFY(writer.write(image));
224     }
225 
226     {
227         // Shouldn't be able to write to read-only file
228         QFile sourceFile(prefix + "gen-" + fileName);
229         QFile::Permissions permissions = sourceFile.permissions();
230         QVERIFY(sourceFile.setPermissions(QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther));
231 
232         QImageWriter writer(prefix + "gen-" + fileName, format);
233         QVERIFY(!writer.write(image));
234 
235         QVERIFY(sourceFile.setPermissions(permissions));
236     }
237 
238     QImage image2;
239     {
240         QImageReader reader(prefix + "gen-" + fileName);
241         image2 = reader.read();
242         QVERIFY(!image2.isNull());
243     }
244     if (!lossy) {
245         QCOMPARE(image, image2);
246     } else {
247         QCOMPARE(image.format(), image2.format());
248         QCOMPARE(image.depth(), image2.depth());
249     }
250 }
251 
writeImage2_data()252 void tst_QImageWriter::writeImage2_data()
253 {
254     QTest::addColumn<QString>("fileName");
255     QTest::addColumn<QByteArray>("format");
256     QTest::addColumn<QImage>("image");
257 
258     const QStringList formats = QStringList() << "bmp" << "xpm" << "png"
259                                               << "ppm"; //<< "jpeg";
260     QImage image0(70, 70, QImage::Format_ARGB32);
261     image0.fill(QColor(Qt::red).rgb());
262 
263     QImage::Format imgFormat = QImage::Format_Mono;
264     while (imgFormat != QImage::NImageFormats) {
265         QImage image = image0.convertToFormat(imgFormat);
266         initializePadding(&image);
267         foreach (const QString format, formats) {
268             const QString fileName = QString("solidcolor_%1.%2").arg(imgFormat)
269                                      .arg(format);
270             QTest::newRow(fileName.toLatin1()) << fileName
271                                                << format.toLatin1()
272                                                << image;
273         }
274         imgFormat = QImage::Format(int(imgFormat) + 1);
275     }
276 }
277 
278 #if defined QTEST_HAVE_TIFF
largeTiff()279 void tst_QImageWriter::largeTiff()
280 {
281 #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN)
282     QImage img(4096, 2048, QImage::Format_ARGB32);
283 
284     QPainter p(&img);
285     img.fill(0x0);
286     p.fillRect(0, 0, 4096, 2048, QBrush(Qt::CrossPattern));
287     p.end();
288 
289     QByteArray array;
290     QBuffer writeBuffer(&array);
291     writeBuffer.open(QIODevice::WriteOnly);
292 
293     QImageWriter writer(&writeBuffer, "tiff");
294     QVERIFY(writer.write(img));
295 
296     writeBuffer.close();
297 
298     QBuffer readBuffer(&array);
299     readBuffer.open(QIODevice::ReadOnly);
300 
301     QImageReader reader(&readBuffer, "tiff");
302 
303     QImage img2 = reader.read();
304     QVERIFY(!img2.isNull());
305 
306     QCOMPARE(img, img2);
307 #else
308     QWARN("not tested on Symbian/WinCE");
309 #endif
310 }
311 #endif
312 
313 /*
314     Workaround for the equality operator for indexed formats
315     (which fails if the colortables are different).
316 
317     Images must have the same format and size.
318 */
equalImageContents(const QImage & image1,const QImage & image2)319 static bool equalImageContents(const QImage &image1, const QImage &image2)
320 {
321     switch (image1.format()) {
322     case QImage::Format_Mono:
323     case QImage::Format_Indexed8:
324         for (int y = 0; y < image1.height(); ++y)
325             for (int x = 0; x < image1.width(); ++x)
326                 if (image1.pixel(x, y) != image2.pixel(x, y))
327                     return false;
328         return true;
329     default:
330         return (image1 == image2);
331     }
332 }
333 
writeImage2()334 void tst_QImageWriter::writeImage2()
335 {
336     QFETCH(QString, fileName);
337     QFETCH(QByteArray, format);
338     QFETCH(QImage, image);
339 
340     //we reduce the scope of writer so that it closes the associated file
341     // and QFile::remove can actually work
342     {
343         QImageWriter writer(fileName, format);
344         QVERIFY(writer.write(image));
345     }
346 
347     QImage written;
348 
349     //we reduce the scope of reader so that it closes the associated file
350     // and QFile::remove can actually work
351     {
352         QImageReader reader(fileName, format);
353         QVERIFY(reader.read(&written));
354     }
355 
356     written = written.convertToFormat(image.format());
357     if (!equalImageContents(written, image)) {
358         qDebug() << "image" << image.format() << image.width()
359                  << image.height() << image.depth()
360                  << hex << image.pixel(0, 0);
361         qDebug() << "written" << written.format() << written.width()
362                  << written.height() << written.depth()
363                  << hex << written.pixel(0, 0);
364     }
365     QVERIFY(equalImageContents(written, image));
366 
367     QVERIFY(QFile::remove(fileName));
368 }
369 
supportedFormats()370 void tst_QImageWriter::supportedFormats()
371 {
372     QList<QByteArray> formats = QImageWriter::supportedImageFormats();
373     QList<QByteArray> sortedFormats = formats;
374     qSort(sortedFormats);
375 
376     // check that the list is sorted
377     QCOMPARE(formats, sortedFormats);
378 
379     QSet<QByteArray> formatSet;
380     foreach (QByteArray format, formats)
381         formatSet << format;
382 
383     // check that the list does not contain duplicates
384     QCOMPARE(formatSet.size(), formats.size());
385 }
386 
readWriteNonDestructive_data()387 void tst_QImageWriter::readWriteNonDestructive_data()
388 {
389     QTest::addColumn<QImage::Format>("format");
390     QTest::addColumn<QImage::Format>("expectedFormat");
391     QTest::addColumn<bool>("grayscale");
392     QTest::newRow("tiff mono") << QImage::Format_Mono << QImage::Format_Mono << false;
393     QTest::newRow("tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << false;
394     QTest::newRow("tiff rgb32") << QImage::Format_ARGB32 << QImage::Format_ARGB32 << false;
395     QTest::newRow("tiff grayscale") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << true;
396 }
397 
readWriteNonDestructive()398 void tst_QImageWriter::readWriteNonDestructive()
399 {
400     QFETCH(QImage::Format, format);
401     QFETCH(QImage::Format, expectedFormat);
402     QFETCH(bool, grayscale);
403     QImage image = QImage(prefix + "colorful.bmp").convertToFormat(format);
404 
405     if (grayscale) {
406         QVector<QRgb> colors;
407         for (int i = 0; i < 256; ++i)
408             colors << qRgb(i, i, i);
409         image.setColorTable(colors);
410     }
411 
412     QVERIFY(image.save(prefix + "gen-readWriteNonDestructive.tiff"));
413 
414     QImage image2 = QImage(prefix + "gen-readWriteNonDestructive.tiff");
415     QImage::Format readFormat = image2.format();
416     QCOMPARE(readFormat, expectedFormat);
417     QCOMPARE(image, image2);
418 }
419 
writeToInvalidDevice()420 void tst_QImageWriter::writeToInvalidDevice()
421 {
422     QLatin1String fileName("/these/directories/do/not/exist/001.png");
423     {
424         QImageWriter writer(fileName);
425         QVERIFY(!writer.canWrite());
426         QCOMPARE(writer.error(), QImageWriter::DeviceError);
427     }
428     {
429         QImageWriter writer(fileName);
430         writer.setFormat("png");
431         QVERIFY(!writer.canWrite());
432         QCOMPARE(writer.error(), QImageWriter::DeviceError);
433     }
434     {
435         QImageWriter writer(fileName);
436         QImage im(10, 10, QImage::Format_ARGB32);
437         QVERIFY(!writer.write(im));
438         QCOMPARE(writer.error(), QImageWriter::DeviceError);
439     }
440     {
441         QImageWriter writer(fileName);
442         writer.setFormat("png");
443         QImage im(10, 10, QImage::Format_ARGB32);
444         QVERIFY(!writer.write(im));
445         QCOMPARE(writer.error(), QImageWriter::DeviceError);
446     }
447 }
448 
supportsOption_data()449 void tst_QImageWriter::supportsOption_data()
450 {
451     QTest::addColumn<QString>("fileName");
452     QTest::addColumn<QIntList>("options");
453 
454     QTest::newRow("png") << QString("gen-black.png")
455                          << (QIntList() << QImageIOHandler::Gamma
456                               << QImageIOHandler::Description
457                               << QImageIOHandler::Quality
458                               << QImageIOHandler::Size);
459 #if defined QTEST_HAVE_TIFF
460     QTest::newRow("tiff") << QString("gen-black.tiff")
461                           << (QIntList() << QImageIOHandler::Size
462                               << QImageIOHandler::CompressionRatio);
463 #endif
464 }
465 
supportsOption()466 void tst_QImageWriter::supportsOption()
467 {
468     QFETCH(QString, fileName);
469     QFETCH(QIntList, options);
470 
471     QSet<QImageIOHandler::ImageOption> allOptions;
472     allOptions << QImageIOHandler::Size
473                << QImageIOHandler::ClipRect
474                << QImageIOHandler::Description
475                << QImageIOHandler::ScaledClipRect
476                << QImageIOHandler::ScaledSize
477                << QImageIOHandler::CompressionRatio
478                << QImageIOHandler::Gamma
479                << QImageIOHandler::Quality
480                << QImageIOHandler::Name
481                << QImageIOHandler::SubType
482                << QImageIOHandler::IncrementalReading
483                << QImageIOHandler::Endianness
484                << QImageIOHandler::Animation
485                << QImageIOHandler::BackgroundColor;
486 
487     QImageWriter writer(prefix + fileName);
488     for (int i = 0; i < options.size(); ++i) {
489         QVERIFY(writer.supportsOption(QImageIOHandler::ImageOption(options.at(i))));
490         allOptions.remove(QImageIOHandler::ImageOption(options.at(i)));
491     }
492 
493     foreach (QImageIOHandler::ImageOption option, allOptions)
494         QVERIFY(!writer.supportsOption(option));
495 }
496 
saveWithNoFormat_data()497 void tst_QImageWriter::saveWithNoFormat_data()
498 {
499     QTest::addColumn<QString>("fileName");
500     QTest::addColumn<QByteArray>("format");
501     QTest::addColumn<QImageWriter::ImageWriterError>("error");
502 
503     QTest::newRow("garble") << prefix + QString("gen-out.garble") << QByteArray("jpeg") << QImageWriter::UnsupportedFormatError;
504     QTest::newRow("bmp") << prefix + QString("gen-out.bmp") << QByteArray("bmp") << QImageWriter::ImageWriterError(0);
505     QTest::newRow("xbm") << prefix + QString("gen-out.xbm") << QByteArray("xbm") << QImageWriter::ImageWriterError(0);
506     QTest::newRow("xpm") << prefix + QString("gen-out.xpm") << QByteArray("xpm") << QImageWriter::ImageWriterError(0);
507     QTest::newRow("png") << prefix + QString("gen-out.png") << QByteArray("png") << QImageWriter::ImageWriterError(0);
508     QTest::newRow("ppm") << prefix + QString("gen-out.ppm") << QByteArray("ppm") << QImageWriter::ImageWriterError(0);
509     QTest::newRow("pbm") << prefix + QString("gen-out.pbm") << QByteArray("pbm") << QImageWriter::ImageWriterError(0);
510 #if defined QTEST_HAVE_TIFF
511     QTest::newRow("tiff") << prefix + QString("gen-out.tiff") << QByteArray("tiff") << QImageWriter::ImageWriterError(0);
512 #endif
513 }
514 
saveWithNoFormat()515 void tst_QImageWriter::saveWithNoFormat()
516 {
517     QFETCH(QString, fileName);
518     QFETCH(QByteArray, format);
519     QFETCH(QImageWriter::ImageWriterError, error);
520 
521     QImage niceImage(64, 64, QImage::Format_ARGB32);
522     qMemSet(niceImage.bits(), 0, niceImage.byteCount());
523 
524     QImageWriter writer(fileName /* , 0 - no format! */);
525     if (error != 0) {
526         QVERIFY(!writer.write(niceImage));
527         QCOMPARE(writer.error(), error);
528         return;
529     }
530 
531     QVERIFY2(writer.write(niceImage), qPrintable(writer.errorString()));
532 
533     QImageReader reader(fileName);
534     QCOMPARE(reader.format(), format);
535 
536     QVERIFY(reader.canRead());
537 
538     QImage outImage = reader.read();
539     QVERIFY2(!outImage.isNull(), qPrintable(reader.errorString()));
540 }
541 
resolution_data()542 void tst_QImageWriter::resolution_data()
543 {
544     QTest::addColumn<QString>("filename");
545     QTest::addColumn<int>("expectedDotsPerMeterX");
546     QTest::addColumn<int>("expectedDotsPerMeterY");
547 #if defined QTEST_HAVE_TIFF
548     QTest::newRow("TIFF: 100 dpi") << ("image_100dpi.tif") << qRound(100 * (100 / 2.54)) << qRound(100 * (100 / 2.54));
549     QTest::newRow("TIFF: 50 dpi") << ("image_50dpi.tif") << qRound(50 * (100 / 2.54)) << qRound(50 * (100 / 2.54));
550     QTest::newRow("TIFF: 300 dot per meter") << ("image_300dpm.tif") << 300 << 300;
551 #endif
552 }
553 
resolution()554 void tst_QImageWriter::resolution()
555 {
556     QFETCH(QString, filename);
557     QFETCH(int, expectedDotsPerMeterX);
558     QFETCH(int, expectedDotsPerMeterY);
559 
560     QImage image(prefix + QLatin1String("colorful.bmp"));
561     image.setDotsPerMeterX(expectedDotsPerMeterX);
562     image.setDotsPerMeterY(expectedDotsPerMeterY);
563     const QString generatedFilepath = prefix + "gen-" + filename;
564     {
565         QImageWriter writer(generatedFilepath);
566         QVERIFY(writer.write(image));
567     }
568     QImageReader reader(generatedFilepath);
569     const QImage generatedImage = reader.read();
570 
571     QCOMPARE(expectedDotsPerMeterX, generatedImage.dotsPerMeterX());
572     QCOMPARE(expectedDotsPerMeterY, generatedImage.dotsPerMeterY());
573 }
574 
saveToTemporaryFile()575 void tst_QImageWriter::saveToTemporaryFile()
576 {
577     QImage image(prefix + "kollada.png");
578     QVERIFY(!image.isNull());
579 
580     {
581         // 1) Via QImageWriter's API, with a standard temp file name
582         QTemporaryFile file;
583         QVERIFY(file.open());
584         QImageWriter writer(&file, "PNG");
585         if (writer.canWrite())
586             QVERIFY(writer.write(image));
587         else
588             qWarning() << file.errorString();
589 #if defined(Q_OS_WINCE)
590         file.reset();
591 #endif
592         QCOMPARE(QImage(writer.fileName()), image);
593     }
594     {
595         // 2) Via QImage's API, with a standard temp file name
596         QTemporaryFile file;
597         QVERIFY(file.open());
598         QVERIFY(image.save(&file, "PNG"));
599         file.reset();
600         QImage tmp;
601         QVERIFY(tmp.load(&file, "PNG"));
602         QCOMPARE(tmp, image);
603     }
604     {
605         // 3) Via QImageWriter's API, with a named temp file
606         QTemporaryFile file("tempXXXXXX");
607         QVERIFY(file.open());
608         QImageWriter writer(&file, "PNG");
609         QVERIFY(writer.write(image));
610 #if defined(Q_OS_WINCE)
611         file.reset();
612 #endif
613         QCOMPARE(QImage(writer.fileName()), image);
614     }
615     {
616         // 4) Via QImage's API, with a named temp file
617         QTemporaryFile file("tempXXXXXX");
618         QVERIFY(file.open());
619         QVERIFY(image.save(&file, "PNG"));
620         file.reset();
621         QImage tmp;
622         QVERIFY(tmp.load(&file, "PNG"));
623         QCOMPARE(tmp, image);
624     }
625 }
626 
627 QTEST_MAIN(tst_QImageWriter)
628 #include "tst_qimagewriter.moc"
629