1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtAddOn.ImageFormats module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QtTest>
30#include <QtGui/QtGui>
31
32Q_DECLARE_METATYPE(QImage::Format)
33Q_DECLARE_METATYPE(QImageWriter::ImageWriterError)
34Q_DECLARE_METATYPE(QImageIOHandler::Transformation)
35typedef QList<int> QIntList;
36Q_DECLARE_METATYPE(QIntList)
37
38class tst_qtiff: public QObject
39{
40 Q_OBJECT
41private slots:
42 void initTestCase();
43
44 void formatHandler();
45
46 void readImage_data();
47 void readImage();
48
49 void readCorruptImage_data();
50 void readCorruptImage();
51
52 void tiffCompression_data();
53 void tiffCompression();
54 void tiffEndianness();
55
56 void tiffOrientation_data();
57 void tiffOrientation();
58
59 void tiffGrayscale();
60
61 void dotsPerMeter_data();
62 void dotsPerMeter();
63
64 void physicalDpi_data();
65 void physicalDpi();
66
67 void writeImage_data();
68 void writeImage();
69
70 void readWriteNonDestructive_data();
71 void readWriteNonDestructive();
72
73 void largeTiff();
74
75 void supportsOption_data();
76 void supportsOption();
77
78 void resolution_data();
79 void resolution();
80
81 void multipage_data();
82 void multipage();
83
84 void tiled_data();
85 void tiled();
86
87 void readRgba64();
88 void readGray16();
89
90 void colorSpace_data();
91 void colorSpace();
92
93 void bigtiff_data();
94 void bigtiff();
95
96private:
97 QString prefix;
98};
99
100void tst_qtiff::initTestCase()
101{
102 if (!QImageReader::supportedImageFormats().contains(t: "tiff"))
103 QSKIP("The image format handler is not installed.");
104
105 prefix = ":/tiff/";
106}
107
108void tst_qtiff::formatHandler()
109{
110 QString testFormat = "TIFF";
111 QString testFile = prefix + "image.tif";
112 QList<QByteArray> formats = QImageReader::supportedImageFormats();
113
114 bool formatSupported = false;
115 for (QList<QByteArray>::Iterator it = formats.begin(); it != formats.end(); ++it) {
116 if (*it == testFormat.toLower()) {
117 formatSupported = true;
118 break;
119 }
120 }
121 QVERIFY(formatSupported);
122 QCOMPARE(QImageReader::imageFormat(testFile), testFormat.toLatin1().toLower());
123}
124
125void tst_qtiff::readImage_data()
126{
127 QTest::addColumn<QString>(name: "fileName");
128 QTest::addColumn<QSize>(name: "size");
129
130 QTest::newRow(dataTag: "grayscale-ref") << QString("grayscale-ref.tif") << QSize(320, 200);
131 QTest::newRow(dataTag: "grayscale") << QString("grayscale.tif") << QSize(320, 200);
132 QTest::newRow(dataTag: "image_100dpi") << QString("image_100dpi.tif") << QSize(22, 22);
133 QTest::newRow(dataTag: "image") << QString("image.tif") << QSize(22, 22);
134 QTest::newRow(dataTag: "indexed_orientation_1") << QString("indexed_orientation_1.tiff") << QSize(64, 64);
135 QTest::newRow(dataTag: "indexed_orientation_2") << QString("indexed_orientation_2.tiff") << QSize(64, 64);
136 QTest::newRow(dataTag: "indexed_orientation_3") << QString("indexed_orientation_3.tiff") << QSize(64, 64);
137 QTest::newRow(dataTag: "indexed_orientation_4") << QString("indexed_orientation_4.tiff") << QSize(64, 64);
138 QTest::newRow(dataTag: "indexed_orientation_5") << QString("indexed_orientation_5.tiff") << QSize(64, 64);
139 QTest::newRow(dataTag: "indexed_orientation_6") << QString("indexed_orientation_6.tiff") << QSize(64, 64);
140 QTest::newRow(dataTag: "indexed_orientation_7") << QString("indexed_orientation_7.tiff") << QSize(64, 64);
141 QTest::newRow(dataTag: "indexed_orientation_8") << QString("indexed_orientation_8.tiff") << QSize(64, 64);
142 QTest::newRow(dataTag: "mono_orientation_1") << QString("mono_orientation_1.tiff") << QSize(64, 64);
143 QTest::newRow(dataTag: "mono_orientation_2") << QString("mono_orientation_2.tiff") << QSize(64, 64);
144 QTest::newRow(dataTag: "mono_orientation_3") << QString("mono_orientation_3.tiff") << QSize(64, 64);
145 QTest::newRow(dataTag: "mono_orientation_4") << QString("mono_orientation_4.tiff") << QSize(64, 64);
146 QTest::newRow(dataTag: "mono_orientation_5") << QString("mono_orientation_5.tiff") << QSize(64, 64);
147 QTest::newRow(dataTag: "mono_orientation_6") << QString("mono_orientation_6.tiff") << QSize(64, 64);
148 QTest::newRow(dataTag: "mono_orientation_7") << QString("mono_orientation_7.tiff") << QSize(64, 64);
149 QTest::newRow(dataTag: "mono_orientation_8") << QString("mono_orientation_8.tiff") << QSize(64, 64);
150 QTest::newRow(dataTag: "original_indexed") << QString("original_indexed.tiff") << QSize(64, 64);
151 QTest::newRow(dataTag: "original_grayscale") << QString("original_grayscale.tiff") << QSize(64, 64);
152 QTest::newRow(dataTag: "original_mono") << QString("original_mono.tiff") << QSize(64, 64);
153 QTest::newRow(dataTag: "original_rgb") << QString("original_rgb.tiff") << QSize(64, 64);
154 QTest::newRow(dataTag: "rgba_adobedeflate_littleendian") << QString("rgba_adobedeflate_littleendian.tif") << QSize(200, 200);
155 QTest::newRow(dataTag: "rgba_lzw_littleendian") << QString("rgba_lzw_littleendian.tif") << QSize(200, 200);
156 QTest::newRow(dataTag: "rgba_nocompression_bigendian") << QString("rgba_nocompression_bigendian.tif") << QSize(200, 200);
157 QTest::newRow(dataTag: "rgba_nocompression_littleendian") << QString("rgba_nocompression_littleendian.tif") << QSize(200, 200);
158 QTest::newRow(dataTag: "rgba_packbits_littleendian") << QString("rgba_packbits_littleendian.tif") << QSize(200, 200);
159 QTest::newRow(dataTag: "rgba_zipdeflate_littleendian") << QString("rgba_zipdeflate_littleendian.tif") << QSize(200, 200);
160 QTest::newRow(dataTag: "rgb_orientation_1") << QString("rgb_orientation_1.tiff") << QSize(64, 64);
161 QTest::newRow(dataTag: "rgb_orientation_2") << QString("rgb_orientation_2.tiff") << QSize(64, 64);
162 QTest::newRow(dataTag: "rgb_orientation_3") << QString("rgb_orientation_3.tiff") << QSize(64, 64);
163 QTest::newRow(dataTag: "rgb_orientation_4") << QString("rgb_orientation_4.tiff") << QSize(64, 64);
164 QTest::newRow(dataTag: "rgb_orientation_5") << QString("rgb_orientation_5.tiff") << QSize(64, 64);
165 QTest::newRow(dataTag: "rgb_orientation_6") << QString("rgb_orientation_6.tiff") << QSize(64, 64);
166 QTest::newRow(dataTag: "rgb_orientation_7") << QString("rgb_orientation_7.tiff") << QSize(64, 64);
167 QTest::newRow(dataTag: "rgb_orientation_8") << QString("rgb_orientation_8.tiff") << QSize(64, 64);
168 QTest::newRow(dataTag: "teapot") << QString("teapot.tiff") << QSize(256, 256);
169 QTest::newRow(dataTag: "oddsize_grayscale") << QString("oddsize_grayscale.tiff") << QSize(59, 71);
170 QTest::newRow(dataTag: "oddsize_mono") << QString("oddsize_mono.tiff") << QSize(59, 71);
171 QTest::newRow(dataTag: "tiled_rgb") << QString("tiled_rgb.tiff") << QSize(64, 64);
172 QTest::newRow(dataTag: "tiled_indexed") << QString("tiled_indexed.tiff") << QSize(64, 64);
173 QTest::newRow(dataTag: "tiled_grayscale") << QString("tiled_grayscale.tiff") << QSize(64, 64);
174 QTest::newRow(dataTag: "tiled_mono") << QString("tiled_mono.tiff") << QSize(64, 64);
175 QTest::newRow(dataTag: "tiled_oddsize_grayscale") << QString("tiled_oddsize_grayscale.tiff") << QSize(59, 71);
176 QTest::newRow(dataTag: "tiled_oddsize_mono") << QString("tiled_oddsize_mono.tiff") << QSize(59, 71);
177 QTest::newRow(dataTag: "16bpc") << QString("16bpc.tiff") << QSize(64, 46);
178 QTest::newRow(dataTag: "gray16") << QString("gray16.tiff") << QSize(64, 46);
179 QTest::newRow(dataTag: "big_rgb") << QString("big_rgb.tiff") << QSize(64, 64);
180 QTest::newRow(dataTag: "big_rgb_bigendian") << QString("big_rgb_bigendian.tiff") << QSize(64, 64);
181 QTest::newRow(dataTag: "big_grayscale") << QString("big_grayscale.tiff") << QSize(64, 64);
182 QTest::newRow(dataTag: "big_16bpc") << QString("big_16bpc.tiff") << QSize(64, 46);
183}
184
185void tst_qtiff::readImage()
186{
187 QFETCH(QString, fileName);
188 QFETCH(QSize, size);
189
190 QString path = prefix + fileName;
191 QImageReader reader(path);
192 QVERIFY(reader.canRead());
193 QImage::Format headerFormat = reader.imageFormat();
194 QSize headerSize = reader.size();
195 QImage image = reader.read();
196 QVERIFY(!image.isNull());
197 QCOMPARE(image.size(), size);
198 QCOMPARE(image.size(), headerSize);
199 QCOMPARE(image.format(), headerFormat);
200}
201
202void tst_qtiff::readCorruptImage_data()
203{
204 QTest::addColumn<QString>(name: "fileName");
205 QTest::addColumn<QString>(name: "message");
206
207 QTest::newRow(dataTag: "corrupt tiff") << QString("corrupt-data.tif") << QString();
208}
209
210void tst_qtiff::readCorruptImage()
211{
212 QFETCH(QString, fileName);
213 QFETCH(QString, message);
214
215 QString path = prefix + fileName;
216 QImageReader reader(path);
217 if (!message.isEmpty())
218 QTest::ignoreMessage(type: QtWarningMsg, message: message.toLatin1());
219 QVERIFY(reader.canRead());
220 QImage image = reader.read();
221 QVERIFY(image.isNull());
222}
223
224void tst_qtiff::tiffCompression_data()
225{
226 QTest::addColumn<QString>(name: "uncompressedFile");
227 QTest::addColumn<QString>(name: "compressedFile");
228
229 QTest::newRow(dataTag: "TIFF: adobedeflate") << "rgba_nocompression_littleendian.tif"
230 << "rgba_adobedeflate_littleendian.tif";
231 QTest::newRow(dataTag: "TIFF: lzw") << "rgba_nocompression_littleendian.tif"
232 << "rgba_lzw_littleendian.tif";
233 QTest::newRow(dataTag: "TIFF: packbits") << "rgba_nocompression_littleendian.tif"
234 << "rgba_packbits_littleendian.tif";
235 QTest::newRow(dataTag: "TIFF: zipdeflate") << "rgba_nocompression_littleendian.tif"
236 << "rgba_zipdeflate_littleendian.tif";
237}
238
239void tst_qtiff::tiffCompression()
240{
241 QFETCH(QString, uncompressedFile);
242 QFETCH(QString, compressedFile);
243
244 QImage uncompressedImage(prefix + uncompressedFile);
245 QImage compressedImage(prefix + compressedFile);
246
247 QCOMPARE(uncompressedImage, compressedImage);
248}
249
250void tst_qtiff::tiffEndianness()
251{
252 QImage littleEndian(prefix + "rgba_nocompression_littleendian.tif");
253 QImage bigEndian(prefix + "rgba_nocompression_bigendian.tif");
254
255 QCOMPARE(littleEndian, bigEndian);
256}
257
258void tst_qtiff::tiffOrientation_data()
259{
260 QTest::addColumn<QString>(name: "expected");
261 QTest::addColumn<QString>(name: "oriented");
262 QTest::newRow(dataTag: "Indexed TIFF, orientation1") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_1.tiff";
263 QTest::newRow(dataTag: "Indexed TIFF, orientation2") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_2.tiff";
264 QTest::newRow(dataTag: "Indexed TIFF, orientation3") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_3.tiff";
265 QTest::newRow(dataTag: "Indexed TIFF, orientation4") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_4.tiff";
266 QTest::newRow(dataTag: "Indexed TIFF, orientation5") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_5.tiff";
267 QTest::newRow(dataTag: "Indexed TIFF, orientation6") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_6.tiff";
268 QTest::newRow(dataTag: "Indexed TIFF, orientation7") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_7.tiff";
269 QTest::newRow(dataTag: "Indexed TIFF, orientation8") << "tiff_oriented/original_indexed.tiff" << "tiff_oriented/indexed_orientation_8.tiff";
270
271 QTest::newRow(dataTag: "Mono TIFF, orientation1") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_1.tiff";
272 QTest::newRow(dataTag: "Mono TIFF, orientation2") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_2.tiff";
273 QTest::newRow(dataTag: "Mono TIFF, orientation3") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_3.tiff";
274 QTest::newRow(dataTag: "Mono TIFF, orientation4") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_4.tiff";
275 QTest::newRow(dataTag: "Mono TIFF, orientation5") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_5.tiff";
276 QTest::newRow(dataTag: "Mono TIFF, orientation6") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_6.tiff";
277 QTest::newRow(dataTag: "Mono TIFF, orientation7") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_7.tiff";
278 QTest::newRow(dataTag: "Mono TIFF, orientation8") << "tiff_oriented/original_mono.tiff" << "tiff_oriented/mono_orientation_8.tiff";
279
280 QTest::newRow(dataTag: "RGB TIFF, orientation1") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_1.tiff";
281 QTest::newRow(dataTag: "RGB TIFF, orientation2") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_2.tiff";
282 QTest::newRow(dataTag: "RGB TIFF, orientation3") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_3.tiff";
283 QTest::newRow(dataTag: "RGB TIFF, orientation4") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_4.tiff";
284 QTest::newRow(dataTag: "RGB TIFF, orientation5") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_5.tiff";
285 QTest::newRow(dataTag: "RGB TIFF, orientation6") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_6.tiff";
286 QTest::newRow(dataTag: "RGB TIFF, orientation7") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_7.tiff";
287 QTest::newRow(dataTag: "RGB TIFF, orientation8") << "tiff_oriented/original_rgb.tiff" << "tiff_oriented/rgb_orientation_8.tiff";
288}
289
290void tst_qtiff::tiffOrientation()
291{
292 QFETCH(QString, expected);
293 QFETCH(QString, oriented);
294
295 QImage expectedImage(prefix + expected);
296 QImage orientedImage(prefix + oriented);
297 QCOMPARE(expectedImage, orientedImage);
298}
299
300void tst_qtiff::tiffGrayscale()
301{
302 QImage actualImage(prefix + "grayscale.tif");
303 QImage expectedImage(prefix + "grayscale-ref.tif");
304
305 QCOMPARE(expectedImage, actualImage.convertToFormat(expectedImage.format()));
306}
307
308void tst_qtiff::dotsPerMeter_data()
309{
310 QTest::addColumn<QString>(name: "fileName");
311 QTest::addColumn<int>(name: "expectedDotsPerMeterX");
312 QTest::addColumn<int>(name: "expectedDotsPerMeterY");
313 QTest::newRow(dataTag: "TIFF: 72 dpi") << ("rgba_nocompression_littleendian.tif") << qRound(d: 72 * (100 / 2.54)) << qRound(d: 72 * (100 / 2.54));
314 QTest::newRow(dataTag: "TIFF: 100 dpi") << ("image_100dpi.tif") << qRound(d: 100 * (100 / 2.54)) << qRound(d: 100 * (100 / 2.54));
315}
316
317void tst_qtiff::dotsPerMeter()
318{
319 QFETCH(QString, fileName);
320 QFETCH(int, expectedDotsPerMeterX);
321 QFETCH(int, expectedDotsPerMeterY);
322
323 QImage image(prefix + fileName);
324
325 QCOMPARE(image.dotsPerMeterX(), expectedDotsPerMeterX);
326 QCOMPARE(image.dotsPerMeterY(), expectedDotsPerMeterY);
327}
328
329void tst_qtiff::physicalDpi_data()
330{
331 QTest::addColumn<QString>(name: "fileName");
332 QTest::addColumn<int>(name: "expectedPhysicalDpiX");
333 QTest::addColumn<int>(name: "expectedPhysicalDpiY");
334 QTest::newRow(dataTag: "TIFF: 72 dpi") << "rgba_nocompression_littleendian.tif" << 72 << 72;
335 QTest::newRow(dataTag: "TIFF: 100 dpi") << "image_100dpi.tif" << 100 << 100;
336}
337
338void tst_qtiff::physicalDpi()
339{
340 QFETCH(QString, fileName);
341 QFETCH(int, expectedPhysicalDpiX);
342 QFETCH(int, expectedPhysicalDpiY);
343
344 QImage image(prefix + fileName);
345
346 QCOMPARE(image.physicalDpiX(), expectedPhysicalDpiX);
347 QCOMPARE(image.physicalDpiY(), expectedPhysicalDpiY);
348}
349
350void tst_qtiff::writeImage_data()
351{
352 QTest::addColumn<QString>(name: "fileName");
353 QTest::addColumn<bool>(name: "lossy");
354 QTest::addColumn<QByteArray>(name: "format");
355
356 QTest::newRow(dataTag: "TIFF: teapot") << QString("teapot.tiff") << false << QByteArray("tiff");
357}
358
359void tst_qtiff::writeImage()
360{
361 QFETCH(QString, fileName);
362 QFETCH(bool, lossy);
363 QFETCH(QByteArray, format);
364
365 QImage image;
366 {
367 QImageReader reader(prefix + fileName);
368 image = reader.read();
369 QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
370 }
371 QByteArray output;
372 {
373 QBuffer buf(&output);
374 QVERIFY(buf.open(QIODevice::WriteOnly));
375 QImageWriter writer(&buf, format);
376 QVERIFY(writer.write(image));
377 }
378 image = image.convertToFormat(f: QImage::Format_ARGB32_Premultiplied);
379
380 QImage image2;
381 {
382 QBuffer buf(&output);
383 QVERIFY(buf.open(QIODevice::ReadOnly));
384 QImageReader reader(&buf);
385 image2 = reader.read();
386 QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
387 }
388 if (!lossy) {
389 QCOMPARE(image, image2);
390 } else {
391 QCOMPARE(image.format(), image2.format());
392 QCOMPARE(image.depth(), image2.depth());
393 }
394}
395
396void tst_qtiff::readWriteNonDestructive_data()
397{
398 QTest::addColumn<QImage::Format>(name: "format");
399 QTest::addColumn<QImage::Format>(name: "expectedFormat");
400 QTest::addColumn<QImageIOHandler::Transformation>(name: "transformation");
401 QTest::newRow(dataTag: "tiff mono") << QImage::Format_Mono << QImage::Format_Mono << QImageIOHandler::TransformationNone;
402 QTest::newRow(dataTag: "tiff indexed") << QImage::Format_Indexed8 << QImage::Format_Indexed8 << QImageIOHandler::TransformationMirror;
403 QTest::newRow(dataTag: "tiff argb32pm") << QImage::Format_ARGB32_Premultiplied << QImage::Format_ARGB32_Premultiplied << QImageIOHandler::TransformationRotate90;
404 QTest::newRow(dataTag: "tiff rgb32") << QImage::Format_RGB32 << QImage::Format_RGB32 << QImageIOHandler::TransformationRotate270;
405 QTest::newRow(dataTag: "tiff grayscale8") << QImage::Format_Grayscale8 << QImage::Format_Grayscale8 << QImageIOHandler::TransformationFlip;
406 QTest::newRow(dataTag: "tiff grayscale16") << QImage::Format_Grayscale16 << QImage::Format_Grayscale16 << QImageIOHandler::TransformationMirror;
407 QTest::newRow(dataTag: "tiff rgb64") << QImage::Format_RGBX64 << QImage::Format_RGBX64 << QImageIOHandler::TransformationNone;
408 QTest::newRow(dataTag: "tiff rgba64") << QImage::Format_RGBA64 << QImage::Format_RGBA64 << QImageIOHandler::TransformationRotate90;
409 QTest::newRow(dataTag: "tiff rgba64pm") << QImage::Format_RGBA64_Premultiplied << QImage::Format_RGBA64_Premultiplied << QImageIOHandler::TransformationNone;
410}
411
412void tst_qtiff::readWriteNonDestructive()
413{
414 QFETCH(QImage::Format, format);
415 QFETCH(QImage::Format, expectedFormat);
416 QFETCH(QImageIOHandler::Transformation, transformation);
417
418 QImage image = QImage(prefix + "colorful.bmp").convertToFormat(f: format);
419 QVERIFY(!image.isNull());
420
421 QByteArray output;
422 QBuffer buf(&output);
423 QVERIFY(buf.open(QIODevice::WriteOnly));
424 QImageWriter writer(&buf, "tiff");
425 writer.setTransformation(transformation);
426 writer.write(image);
427 buf.close();
428
429 QVERIFY(buf.open(QIODevice::ReadOnly));
430 QImageReader reader(&buf);
431 QCOMPARE(reader.imageFormat(), expectedFormat);
432 QCOMPARE(reader.size(), image.size());
433 QCOMPARE(reader.autoTransform(), true);
434 reader.setAutoTransform(false);
435 QCOMPARE(reader.transformation(), transformation);
436 QImage image2 = reader.read();
437 QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
438
439 QCOMPARE(image2.format(), expectedFormat);
440 QCOMPARE(image2, image);
441}
442
443void tst_qtiff::largeTiff()
444{
445 QImage img(4096, 2048, QImage::Format_ARGB32_Premultiplied);
446
447 QPainter p(&img);
448 img.fill(pixel: 0x0);
449 p.fillRect(x: 0, y: 0, w: 4096, h: 2048, b: QBrush(Qt::CrossPattern));
450 p.end();
451
452 QByteArray array;
453 QBuffer writeBuffer(&array);
454 writeBuffer.open(openMode: QIODevice::WriteOnly);
455
456 QImageWriter writer(&writeBuffer, "tiff");
457 QVERIFY(writer.write(img));
458
459 writeBuffer.close();
460
461 QBuffer readBuffer(&array);
462 readBuffer.open(openMode: QIODevice::ReadOnly);
463
464 QImageReader reader(&readBuffer, "tiff");
465
466 QImage img2 = reader.read();
467 QVERIFY(!img2.isNull());
468
469 QCOMPARE(img, img2);
470}
471
472void tst_qtiff::supportsOption_data()
473{
474 QTest::addColumn<QIntList>(name: "options");
475
476 QTest::newRow(dataTag: "tiff") << (QIntList()
477 << QImageIOHandler::Size
478 << QImageIOHandler::CompressionRatio
479 << QImageIOHandler::ImageTransformation
480 << QImageIOHandler::TransformedByDefault);
481}
482
483void tst_qtiff::supportsOption()
484{
485 QFETCH(QIntList, options);
486
487 QSet<QImageIOHandler::ImageOption> allOptions;
488 allOptions << QImageIOHandler::Size
489 << QImageIOHandler::ClipRect
490 << QImageIOHandler::Description
491 << QImageIOHandler::ScaledClipRect
492 << QImageIOHandler::ScaledSize
493 << QImageIOHandler::CompressionRatio
494 << QImageIOHandler::Gamma
495 << QImageIOHandler::Quality
496 << QImageIOHandler::Name
497 << QImageIOHandler::SubType
498 << QImageIOHandler::IncrementalReading
499 << QImageIOHandler::Endianness
500 << QImageIOHandler::Animation
501 << QImageIOHandler::BackgroundColor
502 << QImageIOHandler::ImageTransformation
503 << QImageIOHandler::TransformedByDefault;
504
505 QImageWriter writer;
506 writer.setFormat("tiff");
507 for (int i = 0; i < options.size(); ++i) {
508 QVERIFY(writer.supportsOption(QImageIOHandler::ImageOption(options.at(i))));
509 allOptions.remove(value: QImageIOHandler::ImageOption(options.at(i)));
510 }
511
512 for (QImageIOHandler::ImageOption option : qAsConst(t&: allOptions))
513 QVERIFY(!writer.supportsOption(option));
514}
515
516void tst_qtiff::resolution_data()
517{
518 QTest::addColumn<QString>(name: "filename");
519 QTest::addColumn<int>(name: "expectedDotsPerMeterX");
520 QTest::addColumn<int>(name: "expectedDotsPerMeterY");
521
522 QTest::newRow(dataTag: "TIFF: 100 dpi") << ("image_100dpi.tif") << qRound(d: 100 * (100 / 2.54)) << qRound(d: 100 * (100 / 2.54));
523 QTest::newRow(dataTag: "TIFF: 50 dpi") << ("image_50dpi.tif") << qRound(d: 50 * (100 / 2.54)) << qRound(d: 50 * (100 / 2.54));
524 QTest::newRow(dataTag: "TIFF: 300 dot per meter") << ("image_300dpm.tif") << 300 << 300;
525}
526
527void tst_qtiff::resolution()
528{
529 QFETCH(QString, filename);
530 QFETCH(int, expectedDotsPerMeterX);
531 QFETCH(int, expectedDotsPerMeterY);
532
533 QImage image(prefix + QLatin1String("colorful.bmp"));
534 image.setDotsPerMeterX(expectedDotsPerMeterX);
535 image.setDotsPerMeterY(expectedDotsPerMeterY);
536
537 QByteArray output;
538 {
539 QBuffer buf(&output);
540 QVERIFY(buf.open(QIODevice::WriteOnly));
541 QImageWriter writer(&buf, "tiff");
542 QVERIFY(writer.write(image));
543 }
544 QBuffer buf(&output);
545 QVERIFY(buf.open(QIODevice::ReadOnly));
546 QImageReader reader(&buf);
547 const QImage generatedImage = reader.read();
548 QVERIFY(!generatedImage.isNull());
549
550 QCOMPARE(expectedDotsPerMeterX, generatedImage.dotsPerMeterX());
551 QCOMPARE(expectedDotsPerMeterY, generatedImage.dotsPerMeterY());
552}
553
554void tst_qtiff::multipage_data()
555{
556 QTest::addColumn<QString>(name: "filename");
557 QTest::addColumn<int>(name: "expectedNumPages");
558 QTest::addColumn<QVector<QSize>>(name: "expectedSizes");
559
560 QVector<QSize> sizes = QVector<QSize>() << QSize(640, 480) << QSize(800, 600) << QSize(320, 240);
561 QTest::newRow(dataTag: "3 page TIFF") << ("multipage.tiff") << 3 << sizes;
562}
563
564void tst_qtiff::multipage()
565{
566 QFETCH(QString, filename);
567 QFETCH(int, expectedNumPages);
568 QFETCH(QVector<QSize>, expectedSizes);
569
570 QImageReader reader(prefix + filename);
571 QCOMPARE(reader.imageCount(), expectedNumPages);
572
573 // Test jumpToImage, currentImageNumber and whether the actual image is correct
574 QCOMPARE(reader.jumpToImage(-1), false);
575 for (int i = 0; i < expectedNumPages; ++i) {
576 reader.jumpToImage(imageNumber: i);
577 QCOMPARE(reader.currentImageNumber(), i);
578 QSize size = reader.size();
579 QCOMPARE(size.width(), expectedSizes[i].width());
580 QCOMPARE(size.height(), expectedSizes[i].height());
581 QImage image = reader.read();
582 QVERIFY2(!image.isNull(), qPrintable(reader.errorString()));
583 }
584 QCOMPARE(reader.jumpToImage(expectedNumPages), false);
585
586 // Test jumpToNextImage
587 reader.jumpToImage(imageNumber: 0);
588 QCOMPARE(reader.currentImageNumber(), 0);
589 for (int i = 0; i < expectedNumPages - 1; ++i) {
590 QCOMPARE(reader.jumpToNextImage(), true);
591 }
592 QCOMPARE(reader.jumpToNextImage(), false);
593}
594
595void tst_qtiff::tiled_data()
596{
597 QTest::addColumn<QString>(name: "expectedFile");
598 QTest::addColumn<QString>(name: "tiledFile");
599 QTest::newRow(dataTag: "RGB") << "original_rgb.tiff" << "tiled_rgb.tiff";
600 QTest::newRow(dataTag: "Indexed") << "original_indexed.tiff" << "tiled_indexed.tiff";
601 QTest::newRow(dataTag: "Grayscale") << "original_grayscale.tiff" << "tiled_grayscale.tiff";
602 QTest::newRow(dataTag: "Mono") << "original_mono.tiff" << "tiled_mono.tiff";
603 QTest::newRow(dataTag: "Oddsize (Grayscale)") << "oddsize_grayscale.tiff" << "tiled_oddsize_grayscale.tiff";
604 QTest::newRow(dataTag: "Oddsize (Mono)") << "oddsize_mono.tiff" << "tiled_oddsize_mono.tiff";
605}
606
607void tst_qtiff::tiled()
608{
609 QFETCH(QString, expectedFile);
610 QFETCH(QString, tiledFile);
611
612 QImage expectedImage(prefix + expectedFile);
613 QImage tiledImage(prefix + tiledFile);
614 QVERIFY(!tiledImage.isNull());
615 QCOMPARE(expectedImage, tiledImage);
616}
617
618void tst_qtiff::readRgba64()
619{
620 QString path = prefix + QString("16bpc.tiff");
621 QImageReader reader(path);
622 QVERIFY(reader.canRead());
623 QCOMPARE(reader.imageFormat(), QImage::Format_RGBX64);
624 QImage image = reader.read();
625 QVERIFY(!image.isNull());
626 QCOMPARE(image.format(), QImage::Format_RGBX64);
627}
628
629void tst_qtiff::readGray16()
630{
631 QString path = prefix + QString("gray16.tiff");
632 QImageReader reader(path);
633 QVERIFY(reader.canRead());
634 QCOMPARE(reader.imageFormat(), QImage::Format_Grayscale16);
635 QImage image = reader.read();
636 QVERIFY(!image.isNull());
637 QCOMPARE(image.format(), QImage::Format_Grayscale16);
638}
639
640void tst_qtiff::colorSpace_data()
641{
642 QTest::addColumn<decltype(QColorSpace::SRgb)>(name: "namedColorSpace");
643
644 QTest::newRow(dataTag: "sRGB") << QColorSpace::SRgb;
645 QTest::newRow(dataTag: "sRGB(linear)") << QColorSpace::SRgbLinear;
646 QTest::newRow(dataTag: "AdobeRGB") << QColorSpace::AdobeRgb;
647 QTest::newRow(dataTag: "DisplayP3") << QColorSpace::DisplayP3;
648 QTest::newRow(dataTag: "ProPhotoRgb") << QColorSpace::ProPhotoRgb;
649}
650
651void tst_qtiff::colorSpace()
652{
653 QFETCH(decltype(QColorSpace::SRgb), namedColorSpace);
654
655 QImage image(prefix + "colorful.bmp");
656 QVERIFY(!image.isNull());
657
658 image.setColorSpace(namedColorSpace);
659
660 QByteArray output;
661 QBuffer buf(&output);
662 QVERIFY(buf.open(QIODevice::WriteOnly));
663 QImageWriter writer(&buf, "tiff");
664 writer.write(image);
665 buf.close();
666
667 QVERIFY(buf.open(QIODevice::ReadOnly));
668 QImageReader reader(&buf);
669 QImage image2 = reader.read();
670
671 QCOMPARE(image2.colorSpace(), namedColorSpace);
672 QCOMPARE(image2, image);
673}
674
675void tst_qtiff::bigtiff_data()
676{
677 QTest::addColumn<QString>(name: "expectedFile");
678 QTest::addColumn<QString>(name: "bigtiffFile");
679
680 QTest::newRow(dataTag: "big_rgb") << QString("original_rgb.tiff") << QString("big_rgb.tiff");
681 QTest::newRow(dataTag: "big_rgb_bigendian") << QString("original_rgb.tiff") << QString("big_rgb_bigendian.tiff");
682 QTest::newRow(dataTag: "big_grayscale") << QString("original_grayscale.tiff") << QString("big_grayscale.tiff");
683 QTest::newRow(dataTag: "big_16bpc") << QString("16bpc.tiff") << QString("big_16bpc.tiff");
684}
685
686void tst_qtiff::bigtiff()
687{
688 QFETCH(QString, expectedFile);
689 QFETCH(QString, bigtiffFile);
690
691 QImage expectedImage(prefix + expectedFile);
692 QImage bigtiffImage(prefix + bigtiffFile);
693 QVERIFY(!bigtiffImage.isNull());
694 QCOMPARE(expectedImage, bigtiffImage);
695}
696
697QTEST_MAIN(tst_qtiff)
698#include "tst_qtiff.moc"
699

source code of qtimageformats/tests/auto/tiff/tst_qtiff.cpp