1
/****************************************************************************
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4
** Contact: http://www.qt-project.org/legal
6
** This file is part of the test suite of the Qt Toolkit.
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 Digia. For licensing terms and
14
** conditions see http://qt.digia.com/licensing. For further information
15
** use the contact form at http://qt.digia.com/contact-us.
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 as published by the Free Software
20
** Foundation and appearing in the file LICENSE.LGPL included in the
21
** packaging of this file. Please review the following information to
22
** ensure the GNU Lesser General Public License version 2.1 requirements
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25
** In addition, as a special exception, Digia gives you certain additional
26
** rights. These rights are described in the Digia Qt LGPL Exception
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29
** GNU General Public License Usage
30
** Alternatively, this file may be used under the terms of the GNU
31
** General Public License version 3.0 as published by the Free Software
32
** Foundation and appearing in the file LICENSE.GPL included in the
33
** packaging of this file. Please review the following information to
34
** ensure the GNU General Public License version 3.0 requirements will be
35
** met: http://www.gnu.org/copyleft/gpl.html.
40
****************************************************************************/
43
#include <QtTest/QtTest>
46
#include <qimagereader.h>
52
#include <private/qdrawhelper_p.h>
54
Q_DECLARE_METATYPE(QImage::Format)
55
Q_DECLARE_METATYPE(Qt::GlobalColor)
57
class tst_QImage : public QObject
67
void createInvalidXPM();
68
void createFromUChar();
69
void formatHandlersInput_data();
70
void formatHandlersInput();
72
void setAlphaChannel_data();
73
void setAlphaChannel();
77
void convertToFormat_data();
78
void convertToFormat();
80
void convertToFormatRgb888ToRGB32();
82
void createAlphaMask_data();
83
void createAlphaMask();
84
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
85
void createHeuristicMask();
88
void dotsPerMeterZero();
90
void convertToFormatPreserveDotsPrMeter();
91
void convertToFormatPreserveText();
100
#if !defined(QT_NO_DATASTREAM)
101
void loadFromDataStream();
104
void setPixel_data();
107
void setColorCount();
110
void rasterClipping();
112
void pointOverloads();
120
void smoothScaleBig();
121
void smoothScaleAlpha();
123
void transformed_data();
130
void setAlphaChannelWhilePainting();
132
void smoothScaledSubImage();
134
void nullSize_data();
137
void premultipliedAlphaConsistency();
139
void compareIndexed();
141
void fillColor_data();
144
void fillColorWithAlpha();
148
void rgbSwapped_data();
151
void deepCopyWhenPaintingActive();
152
void scaled_QTBUG19157();
154
void cleanupFunctions();
157
tst_QImage::tst_QImage()
162
void tst_QImage::swap()
164
QImage i1( 16, 16, QImage::Format_RGB32 ), i2( 32, 32, QImage::Format_RGB32 );
165
i1.fill( Qt::white );
166
i2.fill( Qt::black );
167
const qint64 i1k = i1.cacheKey();
168
const qint64 i2k = i2.cacheKey();
170
QCOMPARE(i1.cacheKey(), i2k);
171
QCOMPARE(i1.size(), QSize(32,32));
172
QCOMPARE(i2.cacheKey(), i1k);
173
QCOMPARE(i2.size(), QSize(16,16));
176
// Test if QImage (or any functions called from QImage) throws an
177
// exception when creating an extremely large image.
178
// QImage::create() should return "false" in this case.
179
void tst_QImage::create()
182
#if !defined(Q_OS_WINCE)
185
//QImage image(7000000, 7000000, 8, 256, QImage::IgnoreEndian);
186
QImage image(7000000, 7000000, QImage::Format_Indexed8);
187
image.setColorCount(256);
188
cr = !image.isNull();
189
#if !defined(Q_OS_WINCE)
196
void tst_QImage::createInvalidXPM()
198
QTest::ignoreMessage(QtWarningMsg, "QImage::QImage(), XPM is not supported");
199
const char *xpm[] = {""};
200
QImage invalidXPM(xpm);
201
QVERIFY(invalidXPM.isNull());
204
void tst_QImage::createFromUChar()
207
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
210
1,1,1, 0xFF, 2,2,2, 0xFF, 3,3,3, 0xFF, 4,4,4,
211
#if Q_BYTE_ORDER != Q_BIG_ENDIAN
216
// When the data is const, nothing you do to the image will change the source data.
217
QImage i1((const uchar*)data, 2, 2, 8, QImage::Format_RGB32);
218
QCOMPARE(i1.pixel(0,0), 0xFF010101U);
219
QCOMPARE(i1.pixel(1,0), 0xFF020202U);
220
QCOMPARE(i1.pixel(0,1), 0xFF030303U);
221
QCOMPARE(i1.pixel(1,1), 0xFF040404U);
226
QCOMPARE(i1.pixel(0,0), 0xFF010101U);
227
QCOMPARE(*(QRgb*)data, 0xFF010101U);
228
*((QRgb*)i1.bits()) = 7U;
229
QCOMPARE(i1.pixel(0,0), 7U);
230
QCOMPARE(*(QRgb*)data, 0xFF010101U);
232
// Changing copies should not change the original image or data.
236
QCOMPARE(*(QRgb*)data, 0xFF010101U);
238
QCOMPARE(i1.pixel(0,0), 0xFF000009U);
239
QCOMPARE(i.pixel(0,0), 0xFF000005U);
241
QCOMPARE(i1.pixel(0,0), 0xFF000009U);
243
// When the data is non-const, nothing you do to copies of the image will change the source data,
244
// but changing the image (here via bits()) will change the source data.
245
QImage i2((uchar*)data, 2, 2, 8, QImage::Format_RGB32);
246
QCOMPARE(i2.pixel(0,0), 0xFF010101U);
247
QCOMPARE(i2.pixel(1,0), 0xFF020202U);
248
QCOMPARE(i2.pixel(0,1), 0xFF030303U);
249
QCOMPARE(i2.pixel(1,1), 0xFF040404U);
254
QCOMPARE(i2.pixel(0,0), 0xFF010101U);
255
QCOMPARE(*(QRgb*)data, 0xFF010101U);
256
*((QRgb*)i2.bits()) = 7U;
257
QCOMPARE(i2.pixel(0,0), 7U);
258
QCOMPARE(*(QRgb*)data, 7U);
260
// Changing the data will change the image in either case.
261
QImage i3((uchar*)data, 2, 2, 8, QImage::Format_RGB32);
262
QImage i4((const uchar*)data, 2, 2, 8, QImage::Format_RGB32);
264
QCOMPARE(i3.pixel(0,0), 6U);
265
QCOMPARE(i4.pixel(0,0), 6U);
268
void tst_QImage::formatHandlersInput_data()
270
QTest::addColumn<QString>("testFormat");
271
QTest::addColumn<QString>("testFile");
273
const QString prefix = QFINDTESTDATA("images/");
274
if (prefix.isEmpty())
275
QFAIL("can not find images directory!");
277
// add a new line here when a file is added
278
QTest::newRow("ICO") << "ICO" << prefix + "image.ico";
279
QTest::newRow("PNG") << "PNG" << prefix + "image.png";
280
QTest::newRow("GIF") << "GIF" << prefix + "image.gif";
281
QTest::newRow("BMP") << "BMP" << prefix + "image.bmp";
282
QTest::newRow("JPEG") << "JPEG" << prefix + "image.jpg";
283
QTest::newRow("PBM") << "PBM" << prefix + "image.pbm";
284
QTest::newRow("PGM") << "PGM" << prefix + "image.pgm";
285
QTest::newRow("PPM") << "PPM" << prefix + "image.ppm";
286
QTest::newRow("XBM") << "XBM" << prefix + "image.xbm";
287
QTest::newRow("XPM") << "XPM" << prefix + "image.xpm";
290
void tst_QImage::formatHandlersInput()
292
QFETCH(QString, testFormat);
293
QFETCH(QString, testFile);
294
QList<QByteArray> formats = QImageReader::supportedImageFormats();
295
// qDebug("Image input formats : %s", formats.join(" | ").latin1());
297
bool formatSupported = false;
298
for (QList<QByteArray>::Iterator it = formats.begin(); it != formats.end(); ++it) {
299
if (*it == testFormat.toLower()) {
300
formatSupported = true;
304
if (formatSupported) {
305
// qDebug(QImage::imageFormat(testFile));
306
QCOMPARE(testFormat.toLatin1().toLower(), QImageReader::imageFormat(testFile));
308
QString msg = "Format not supported : ";
309
QSKIP(QString(msg + testFormat).toLatin1());
313
void tst_QImage::setAlphaChannel_data()
315
QTest::addColumn<int>("red");
316
QTest::addColumn<int>("green");
317
QTest::addColumn<int>("blue");
318
QTest::addColumn<int>("alpha");
319
QTest::addColumn<bool>("gray");
321
QTest::newRow("red at 0%, gray") << 255 << 0 << 0 << 0 << true;
322
QTest::newRow("red at 25%, gray") << 255 << 0 << 0 << 63 << true;
323
QTest::newRow("red at 50%, gray") << 255 << 0 << 0 << 127 << true;
324
QTest::newRow("red at 100%, gray") << 255 << 0 << 0 << 191 << true;
325
QTest::newRow("red at 0%, 32bit") << 255 << 0 << 0 << 0 << false;
326
QTest::newRow("red at 25%, 32bit") << 255 << 0 << 0 << 63 << false;
327
QTest::newRow("red at 50%, 32bit") << 255 << 0 << 0 << 127 << false;
328
QTest::newRow("red at 100%, 32bit") << 255 << 0 << 0 << 191 << false;
330
QTest::newRow("green at 0%, gray") << 0 << 255 << 0 << 0 << true;
331
QTest::newRow("green at 25%, gray") << 0 << 255 << 0 << 63 << true;
332
QTest::newRow("green at 50%, gray") << 0 << 255 << 0 << 127 << true;
333
QTest::newRow("green at 100%, gray") << 0 << 255 << 0 << 191 << true;
334
QTest::newRow("green at 0%, 32bit") << 0 << 255 << 0 << 0 << false;
335
QTest::newRow("green at 25%, 32bit") << 0 << 255 << 0 << 63 << false;
336
QTest::newRow("green at 50%, 32bit") << 0 << 255 << 0 << 127 << false;
337
QTest::newRow("green at 100%, 32bit") << 0 << 255 << 0 << 191 << false;
339
QTest::newRow("blue at 0%, gray") << 0 << 0 << 255 << 0 << true;
340
QTest::newRow("blue at 25%, gray") << 0 << 0 << 255 << 63 << true;
341
QTest::newRow("blue at 50%, gray") << 0 << 0 << 255 << 127 << true;
342
QTest::newRow("blue at 100%, gray") << 0 << 0 << 255 << 191 << true;
343
QTest::newRow("blue at 0%, 32bit") << 0 << 0 << 255 << 0 << false;
344
QTest::newRow("blue at 25%, 32bit") << 0 << 0 << 255 << 63 << false;
345
QTest::newRow("blue at 50%, 32bit") << 0 << 0 << 255 << 127 << false;
346
QTest::newRow("blue at 100%, 32bit") << 0 << 0 << 255 << 191 << false;
349
void tst_QImage::setAlphaChannel()
360
QImage image(width, height, QImage::Format_RGB32);
361
image.fill(qRgb(red, green, blue));
363
// Create the alpha channel
366
alphaChannel = QImage(width, height, QImage::Format_Indexed8);
367
alphaChannel.setColorCount(256);
368
for (int i=0; i<256; ++i)
369
alphaChannel.setColor(i, qRgb(i, i, i));
370
alphaChannel.fill(alpha);
372
alphaChannel = QImage(width, height, QImage::Format_ARGB32);
373
alphaChannel.fill(qRgb(alpha, alpha, alpha));
376
image.setAlphaChannel(alphaChannel);
377
image = image.convertToFormat(QImage::Format_ARGB32);
378
QVERIFY(image.format() == QImage::Format_ARGB32);
380
// alpha of 0 becomes black at a=0 due to premultiplication
381
QRgb pixel = alpha == 0 ? 0 : qRgba(red, green, blue, alpha);
382
bool allPixelsOK = true;
383
for (int y=0; y<height; ++y) {
384
for (int x=0; x<width; ++x) {
385
allPixelsOK &= image.pixel(x, y) == pixel;
388
QVERIFY(allPixelsOK);
390
QImage outAlpha = image.alphaChannel();
391
QCOMPARE(outAlpha.size(), image.size());
393
bool allAlphaOk = true;
394
for (int y=0; y<height; ++y) {
395
for (int x=0; x<width; ++x) {
396
allAlphaOk &= outAlpha.pixelIndex(x, y) == alpha;
403
void tst_QImage::alphaChannel()
405
QImage img(10, 10, QImage::Format_Mono);
406
img.setColor(0, Qt::transparent);
407
img.setColor(1, Qt::black);
411
p.fillRect(2, 2, 6, 6, Qt::black);
414
QCOMPARE(img.alphaChannel(), img.convertToFormat(QImage::Format_ARGB32).alphaChannel());
417
void tst_QImage::convertToFormat_data()
419
QTest::addColumn<int>("inFormat");
420
QTest::addColumn<uint>("inPixel");
421
QTest::addColumn<int>("resFormat");
422
QTest::addColumn<uint>("resPixel");
424
QTest::newRow("red rgb32 -> argb32") << int(QImage::Format_RGB32) << 0xffff0000
425
<< int(QImage::Format_ARGB32) << 0xffff0000;
426
QTest::newRow("green rgb32 -> argb32") << int(QImage::Format_RGB32) << 0xff00ff00
427
<< int(QImage::Format_ARGB32) << 0xff00ff00;
428
QTest::newRow("blue rgb32 -> argb32") << int(QImage::Format_RGB32) << 0xff0000ff
429
<< int(QImage::Format_ARGB32) << 0xff0000ff;
431
QTest::newRow("red rgb32 -> rgb16") << int(QImage::Format_RGB32) << 0xffff0000
432
<< int(QImage::Format_RGB16) << 0xffff0000;
433
QTest::newRow("green rgb32 -> rgb16") << int(QImage::Format_RGB32) << 0xff00ff00
434
<< int(QImage::Format_RGB16) << 0xff00ff00;
435
QTest::newRow("blue rgb32 -> rgb16") << int(QImage::Format_RGB32) << 0xff0000ff
436
<< int(QImage::Format_RGB16) << 0xff0000ff;
437
QTest::newRow("funky rgb32 -> rgb16") << int(QImage::Format_RGB32) << 0xfff0c080
438
<< int(QImage::Format_RGB16) << 0xfff7c384;
440
QTest::newRow("red rgb32 -> argb32_pm") << int(QImage::Format_RGB32) << 0xffff0000
441
<< int(QImage::Format_ARGB32_Premultiplied) << 0xffff0000;
442
QTest::newRow("green rgb32 -> argb32_pm") << int(QImage::Format_RGB32) << 0xff00ff00
443
<< int(QImage::Format_ARGB32_Premultiplied) <<0xff00ff00;
444
QTest::newRow("blue rgb32 -> argb32_pm") << int(QImage::Format_RGB32) << 0xff0000ff
445
<< int(QImage::Format_ARGB32_Premultiplied) << 0xff0000ff;
447
QTest::newRow("semired argb32 -> pm") << int(QImage::Format_ARGB32) << 0x7fff0000u
448
<< int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u;
449
QTest::newRow("semigreen argb32 -> pm") << int(QImage::Format_ARGB32) << 0x7f00ff00u
450
<< int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u;
451
QTest::newRow("semiblue argb32 -> pm") << int(QImage::Format_ARGB32) << 0x7f0000ffu
452
<< int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu;
453
QTest::newRow("semiwhite argb32 -> pm") << int(QImage::Format_ARGB32) << 0x7fffffffu
454
<< int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu;
455
QTest::newRow("semiblack argb32 -> pm") << int(QImage::Format_ARGB32) << 0x7f000000u
456
<< int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u;
458
QTest::newRow("semired pm -> argb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
459
<< int(QImage::Format_ARGB32) << 0x7fff0000u;
460
QTest::newRow("semigreen pm -> argb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
461
<< int(QImage::Format_ARGB32) << 0x7f00ff00u;
462
QTest::newRow("semiblue pm -> argb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
463
<< int(QImage::Format_ARGB32) << 0x7f0000ffu;
464
QTest::newRow("semiwhite pm -> argb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
465
<< int(QImage::Format_ARGB32) << 0x7fffffffu;
466
QTest::newRow("semiblack pm -> argb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
467
<< int(QImage::Format_ARGB32) << 0x7f000000u;
469
QTest::newRow("semired pm -> rgb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
470
<< int(QImage::Format_RGB32) << 0xffff0000u;
471
QTest::newRow("semigreen pm -> rgb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
472
<< int(QImage::Format_RGB32) << 0xff00ff00u;
473
QTest::newRow("semiblue pm -> rgb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
474
<< int(QImage::Format_RGB32) << 0xff0000ffu;
475
QTest::newRow("semiwhite pm -> rgb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
476
<< int(QImage::Format_RGB32) << 0xffffffffu;
477
QTest::newRow("semiblack pm -> rgb32") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
478
<< int(QImage::Format_RGB32) << 0xff000000u;
480
QTest::newRow("semired argb32 -> rgb32") << int(QImage::Format_ARGB32) << 0x7fff0000u
481
<< int(QImage::Format_RGB32) << 0xffff0000u;
482
QTest::newRow("semigreen argb32 -> rgb32") << int(QImage::Format_ARGB32) << 0x7f00ff00u
483
<< int(QImage::Format_RGB32) << 0xff00ff00u;
484
QTest::newRow("semiblue argb32 -> rgb32") << int(QImage::Format_ARGB32) << 0x7f0000ffu
485
<< int(QImage::Format_RGB32) << 0xff0000ffu;
486
QTest::newRow("semiwhite argb -> rgb32") << int(QImage::Format_ARGB32) << 0x7fffffffu
487
<< int(QImage::Format_RGB32) << 0xffffffffu;
488
QTest::newRow("semiblack argb -> rgb32") << int(QImage::Format_ARGB32) << 0x7f000000u
489
<< int(QImage::Format_RGB32) << 0xff000000u;
491
QTest::newRow("black mono -> rgb32") << int(QImage::Format_Mono) << 0x00000000u
492
<< int(QImage::Format_RGB32) << 0xff000000u;
494
QTest::newRow("white mono -> rgb32") << int(QImage::Format_Mono) << 0x00000001u
495
<< int(QImage::Format_RGB32) << 0xffffffffu;
496
QTest::newRow("red rgb16 -> argb32") << int(QImage::Format_RGB16) << 0xffff0000
497
<< int(QImage::Format_ARGB32) << 0xffff0000;
498
QTest::newRow("green rgb16 -> argb32") << int(QImage::Format_RGB16) << 0xff00ff00
499
<< int(QImage::Format_ARGB32) << 0xff00ff00;
500
QTest::newRow("blue rgb16 -> argb32") << int(QImage::Format_RGB16) << 0xff0000ff
501
<< int(QImage::Format_ARGB32) << 0xff0000ff;
502
QTest::newRow("red rgb16 -> rgb16") << int(QImage::Format_RGB32) << 0xffff0000
503
<< int(QImage::Format_RGB16) << 0xffff0000;
504
QTest::newRow("green rgb16 -> rgb16") << int(QImage::Format_RGB32) << 0xff00ff00
505
<< int(QImage::Format_RGB16) << 0xff00ff00;
506
QTest::newRow("blue rgb16 -> rgb16") << int(QImage::Format_RGB32) << 0xff0000ff
507
<< int(QImage::Format_RGB16) << 0xff0000ff;
508
QTest::newRow("semired argb32 -> rgb16") << int(QImage::Format_ARGB32) << 0x7fff0000u
509
<< int(QImage::Format_RGB16) << 0xffff0000;
510
QTest::newRow("semigreen argb32 -> rgb16") << int(QImage::Format_ARGB32) << 0x7f00ff00u
511
<< int(QImage::Format_RGB16) << 0xff00ff00;
512
QTest::newRow("semiblue argb32 -> rgb16") << int(QImage::Format_ARGB32) << 0x7f0000ffu
513
<< int(QImage::Format_RGB16) << 0xff0000ff;
514
QTest::newRow("semired pm -> rgb16") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
515
<< int(QImage::Format_RGB16) << 0xffff0000u;
517
QTest::newRow("semigreen pm -> rgb16") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
518
<< int(QImage::Format_RGB16) << 0xff00ff00u;
519
QTest::newRow("semiblue pm -> rgb16") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
520
<< int(QImage::Format_RGB16) << 0xff0000ffu;
521
QTest::newRow("semiwhite pm -> rgb16") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
522
<< int(QImage::Format_RGB16) << 0xffffffffu;
523
QTest::newRow("semiblack pm -> rgb16") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
524
<< int(QImage::Format_RGB16) << 0xff000000u;
526
QTest::newRow("mono -> mono lsb") << int(QImage::Format_Mono) << 1u
527
<< int(QImage::Format_MonoLSB) << 0xffffffffu;
528
QTest::newRow("mono lsb -> mono") << int(QImage::Format_MonoLSB) << 1u
529
<< int(QImage::Format_Mono) << 0xffffffffu;
531
QTest::newRow("red rgb32 -> rgb666") << int(QImage::Format_RGB32) << 0xffff0000
532
<< int(QImage::Format_RGB666) << 0xffff0000;
533
QTest::newRow("green rgb32 -> rgb666") << int(QImage::Format_RGB32) << 0xff00ff00
534
<< int(QImage::Format_RGB666) << 0xff00ff00;
535
QTest::newRow("blue rgb32 -> rgb666") << int(QImage::Format_RGB32) << 0xff0000ff
536
<< int(QImage::Format_RGB666) << 0xff0000ff;
538
QTest::newRow("red rgb16 -> rgb666") << int(QImage::Format_RGB16) << 0xffff0000
539
<< int(QImage::Format_RGB666) << 0xffff0000;
540
QTest::newRow("green rgb16 -> rgb666") << int(QImage::Format_RGB16) << 0xff00ff00
541
<< int(QImage::Format_RGB666) << 0xff00ff00;
542
QTest::newRow("blue rgb16 -> rgb666") << int(QImage::Format_RGB16) << 0xff0000ff
543
<< int(QImage::Format_RGB666) << 0xff0000ff;
545
QTest::newRow("red rgb32 -> rgb15") << int(QImage::Format_RGB32) << 0xffff0000
546
<< int(QImage::Format_RGB555) << 0xffff0000;
547
QTest::newRow("green rgb32 -> rgb15") << int(QImage::Format_RGB32) << 0xff00ff00
548
<< int(QImage::Format_RGB555) << 0xff00ff00;
549
QTest::newRow("blue rgb32 -> rgb15") << int(QImage::Format_RGB32) << 0xff0000ff
550
<< int(QImage::Format_RGB555) << 0xff0000ff;
551
QTest::newRow("funky rgb32 -> rgb15") << int(QImage::Format_RGB32) << 0xfff0c080
552
<< int(QImage::Format_RGB555) << 0xfff7c684;
554
QTest::newRow("red rgb16 -> rgb15") << int(QImage::Format_RGB16) << 0xffff0000
555
<< int(QImage::Format_RGB555) << 0xffff0000;
556
QTest::newRow("green rgb16 -> rgb15") << int(QImage::Format_RGB16) << 0xff00ff00
557
<< int(QImage::Format_RGB555) << 0xff00ff00;
558
QTest::newRow("blue rgb16 -> rgb15") << int(QImage::Format_RGB16) << 0xff0000ff
559
<< int(QImage::Format_RGB555) << 0xff0000ff;
560
QTest::newRow("funky rgb16 -> rgb15") << int(QImage::Format_RGB16) << 0xfff0c080
561
<< int(QImage::Format_RGB555) << 0xfff7c684;
563
QTest::newRow("red rgb32 -> argb8565") << int(QImage::Format_RGB32) << 0xffff0000
564
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xffff0000;
565
QTest::newRow("green rgb32 -> argb8565") << int(QImage::Format_RGB32) << 0xff00ff00
566
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xff00ff00;
567
QTest::newRow("blue rgb32 -> argb8565") << int(QImage::Format_RGB32) << 0xff0000ff
568
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xff0000ff;
570
QTest::newRow("red rgb16 -> argb8565") << int(QImage::Format_RGB16) << 0xffff0000
571
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xffff0000;
572
QTest::newRow("green rgb16 -> argb8565") << int(QImage::Format_RGB16) << 0xff00ff00
573
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xff00ff00;
574
QTest::newRow("blue rgb16 -> argb8565") << int(QImage::Format_RGB16) << 0xff0000ff
575
<< int(QImage::Format_ARGB8565_Premultiplied) << 0xff0000ff;
577
QTest::newRow("red argb8565 -> argb32") << int(QImage::Format_ARGB8565_Premultiplied) << 0xffff0000
578
<< int(QImage::Format_ARGB32) << 0xffff0000;
579
QTest::newRow("green argb8565 -> argb32") << int(QImage::Format_ARGB8565_Premultiplied) << 0xff00ff00
580
<< int(QImage::Format_ARGB32) << 0xff00ff00;
581
QTest::newRow("blue argb8565 -> argb32") << int(QImage::Format_ARGB8565_Premultiplied) << 0xff0000ff
582
<< int(QImage::Format_ARGB32) << 0xff0000ff;
584
QTest::newRow("semired argb32 -> argb8565") << int(QImage::Format_ARGB32) << 0x7fff0000u
585
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f7b0000u;
586
QTest::newRow("semigreen argb32 -> argb8565") << int(QImage::Format_ARGB32) << 0x7f00ff00u
587
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f007d00u;
588
QTest::newRow("semiblue argb32 -> argb8565") << int(QImage::Format_ARGB32) << 0x7f0000ffu
589
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f00007bu;
591
QTest::newRow("semired pm -> argb8565") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
592
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f7b0000u;
593
QTest::newRow("semigreen pm -> argb8565") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
594
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f007d00u;
595
QTest::newRow("semiblue pm -> argb8565") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
596
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f00007bu;
597
QTest::newRow("semiwhite pm -> argb8565") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
598
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f7b7d7bu;
599
QTest::newRow("semiblack pm -> argb8565") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
600
<< int(QImage::Format_ARGB8565_Premultiplied) << 0x7f000000u;
602
QTest::newRow("red rgb666 -> argb32") << int(QImage::Format_RGB666) << 0xffff0000
603
<< int(QImage::Format_ARGB32) << 0xffff0000;
604
QTest::newRow("green rgb666 -> argb32") << int(QImage::Format_RGB666) << 0xff00ff00
605
<< int(QImage::Format_ARGB32) << 0xff00ff00;
606
QTest::newRow("blue rgb666 -> argb32") << int(QImage::Format_RGB666) << 0xff0000ff
607
<< int(QImage::Format_ARGB32) << 0xff0000ff;
609
QTest::newRow("semired argb32 -> rgb666") << int(QImage::Format_ARGB32) << 0x7fff0000u
610
<< int(QImage::Format_RGB666) << 0xffff0000;
611
QTest::newRow("semigreen argb32 -> rgb666") << int(QImage::Format_ARGB32) << 0x7f00ff00u
612
<< int(QImage::Format_RGB666) << 0xff00ff00;
613
QTest::newRow("semiblue argb32 -> rgb666") << int(QImage::Format_ARGB32) << 0x7f0000ffu
614
<< int(QImage::Format_RGB666) << 0xff0000ff;
616
QTest::newRow("semired pm -> rgb666") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
617
<< int(QImage::Format_RGB666) << 0xffff0000u;
618
QTest::newRow("semigreen pm -> rgb666") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
619
<< int(QImage::Format_RGB666) << 0xff00ff00u;
620
QTest::newRow("semiblue pm -> rgb666") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
621
<< int(QImage::Format_RGB666) << 0xff0000ffu;
622
QTest::newRow("semiwhite pm -> rgb666") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
623
<< int(QImage::Format_RGB666) << 0xffffffffu;
624
QTest::newRow("semiblack pm -> rgb666") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
625
<< int(QImage::Format_RGB666) << 0xff000000u;
627
QTest::newRow("red rgb15 -> argb32") << int(QImage::Format_RGB555) << 0xffff0000
628
<< int(QImage::Format_ARGB32) << 0xffff0000;
629
QTest::newRow("green rgb15 -> argb32") << int(QImage::Format_RGB555) << 0xff00ff00
630
<< int(QImage::Format_ARGB32) << 0xff00ff00;
631
QTest::newRow("blue rgb15 -> argb32") << int(QImage::Format_RGB555) << 0xff0000ff
632
<< int(QImage::Format_ARGB32) << 0xff0000ff;
634
QTest::newRow("semired argb32 -> rgb15") << int(QImage::Format_ARGB32) << 0x7fff0000u
635
<< int(QImage::Format_RGB555) << 0xffff0000;
636
QTest::newRow("semigreen argb32 -> rgb15") << int(QImage::Format_ARGB32) << 0x7f00ff00u
637
<< int(QImage::Format_RGB555) << 0xff00ff00;
638
QTest::newRow("semiblue argb32 -> rgb15") << int(QImage::Format_ARGB32) << 0x7f0000ffu
639
<< int(QImage::Format_RGB555) << 0xff0000ff;
641
QTest::newRow("semired pm -> rgb15") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
642
<< int(QImage::Format_RGB555) << 0xffff0000u;
643
QTest::newRow("semigreen pm -> rgb15") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
644
<< int(QImage::Format_RGB555) << 0xff00ff00u;
645
QTest::newRow("semiblue pm -> rgb15") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
646
<< int(QImage::Format_RGB555) << 0xff0000ffu;
647
QTest::newRow("semiwhite pm -> rgb15") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
648
<< int(QImage::Format_RGB555) << 0xffffffffu;
649
QTest::newRow("semiblack pm -> rgb15") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
650
<< int(QImage::Format_RGB555) << 0xff000000u;
653
QTest::newRow("red rgb32 -> argb8555") << int(QImage::Format_RGB32) << 0xffff0000
654
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xffff0000;
655
QTest::newRow("green rgb32 -> argb8555") << int(QImage::Format_RGB32) << 0xff00ff00
656
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xff00ff00;
657
QTest::newRow("blue rgb32 -> argb8555") << int(QImage::Format_RGB32) << 0xff0000ff
658
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xff0000ff;
660
QTest::newRow("red rgb16 -> argb8555") << int(QImage::Format_RGB16) << 0xffff0000
661
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xffff0000;
662
QTest::newRow("green rgb16 -> argb8555") << int(QImage::Format_RGB16) << 0xff00ff00
663
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xff00ff00;
664
QTest::newRow("blue rgb16 -> argb8555") << int(QImage::Format_RGB16) << 0xff0000ff
665
<< int(QImage::Format_ARGB8555_Premultiplied) << 0xff0000ff;
667
QTest::newRow("red argb8555 -> argb32") << int(QImage::Format_ARGB8555_Premultiplied) << 0xffff0000
668
<< int(QImage::Format_ARGB32) << 0xffff0000;
669
QTest::newRow("green argb8555 -> argb32") << int(QImage::Format_ARGB8555_Premultiplied) << 0xff00ff00
670
<< int(QImage::Format_ARGB32) << 0xff00ff00;
671
QTest::newRow("blue argb8555 -> argb32") << int(QImage::Format_ARGB8555_Premultiplied) << 0xff0000ff
672
<< int(QImage::Format_ARGB32) << 0xff0000ff;
674
QTest::newRow("semired argb32 -> argb8555") << int(QImage::Format_ARGB32) << 0x7fff0000u
675
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f7b0000u;
676
QTest::newRow("semigreen argb32 -> argb8555") << int(QImage::Format_ARGB32) << 0x7f00ff00u
677
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f007b00u;
678
QTest::newRow("semiblue argb32 -> argb8555") << int(QImage::Format_ARGB32) << 0x7f0000ffu
679
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f00007bu;
681
QTest::newRow("semired pm -> argb8555") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
682
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f7b0000u;
683
QTest::newRow("semigreen pm -> argb8555") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
684
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f007b00u;
685
QTest::newRow("semiblue pm -> argb8555") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
686
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f00007bu;
687
QTest::newRow("semiwhite pm -> argb8555") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
688
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f7b7b7bu;
689
QTest::newRow("semiblack pm -> argb8555") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
690
<< int(QImage::Format_ARGB8555_Premultiplied) << 0x7f000000u;
692
QTest::newRow("red rgb32 -> rgb888") << int(QImage::Format_RGB32) << 0xffff0000
693
<< int(QImage::Format_RGB888) << 0xffff0000;
694
QTest::newRow("green rgb32 -> rgb888") << int(QImage::Format_RGB32) << 0xff00ff00
695
<< int(QImage::Format_RGB888) << 0xff00ff00;
696
QTest::newRow("blue rgb32 -> rgb888") << int(QImage::Format_RGB32) << 0xff0000ff
697
<< int(QImage::Format_RGB888) << 0xff0000ff;
699
QTest::newRow("red rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xffff0000
700
<< int(QImage::Format_RGB888) << 0xffff0000;
701
QTest::newRow("green rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xff00ff00
702
<< int(QImage::Format_RGB888) << 0xff00ff00;
703
QTest::newRow("blue rgb16 -> rgb888") << int(QImage::Format_RGB16) << 0xff0000ff
704
<< int(QImage::Format_RGB888) << 0xff0000ff;
706
QTest::newRow("red rgb888 -> argb32") << int(QImage::Format_RGB888) << 0xffff0000
707
<< int(QImage::Format_ARGB32) << 0xffff0000;
708
QTest::newRow("green rgb888 -> argb32") << int(QImage::Format_RGB888) << 0xff00ff00
709
<< int(QImage::Format_ARGB32) << 0xff00ff00;
710
QTest::newRow("blue rgb888 -> argb32") << int(QImage::Format_RGB888) << 0xff0000ff
711
<< int(QImage::Format_ARGB32) << 0xff0000ff;
713
QTest::newRow("semired argb32 -> rgb888") << int(QImage::Format_ARGB32) << 0x7fff0000u
714
<< int(QImage::Format_RGB888) << 0xffff0000;
715
QTest::newRow("semigreen argb32 -> rgb888") << int(QImage::Format_ARGB32) << 0x7f00ff00u
716
<< int(QImage::Format_RGB888) << 0xff00ff00;
717
QTest::newRow("semiblue argb32 -> rgb888") << int(QImage::Format_ARGB32) << 0x7f0000ffu
718
<< int(QImage::Format_RGB888) << 0xff0000ff;
720
QTest::newRow("semired pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f0000u
721
<< int(QImage::Format_RGB888) << 0xffff0000u;
722
QTest::newRow("semigreen pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f007f00u
723
<< int(QImage::Format_RGB888) << 0xff00ff00u;
724
QTest::newRow("semiblue pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f00007fu
725
<< int(QImage::Format_RGB888) << 0xff0000ffu;
726
QTest::newRow("semiwhite pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f7f7f7fu
727
<< int(QImage::Format_RGB888) << 0xffffffffu;
728
QTest::newRow("semiblack pm -> rgb888") << int(QImage::Format_ARGB32_Premultiplied) << 0x7f000000u
729
<< int(QImage::Format_RGB888) << 0xff000000u;
733
void tst_QImage::convertToFormat()
735
QFETCH(int, inFormat);
736
QFETCH(uint, inPixel);
737
QFETCH(int, resFormat);
738
QFETCH(uint, resPixel);
740
QImage src(32, 32, QImage::Format(inFormat));
742
if (inFormat == QImage::Format_Mono) {
743
src.setColor(0, qRgba(0,0,0,0xff));
744
src.setColor(1, qRgba(255,255,255,0xff));
747
for (int y=0; y<src.height(); ++y)
748
for (int x=0; x<src.width(); ++x)
749
src.setPixel(x, y, inPixel);
751
QImage result = src.convertToFormat(QImage::Format(resFormat));
753
QCOMPARE(src.width(), result.width());
754
QCOMPARE(src.height(), result.height());
757
for (int y=0; y<result.height(); ++y) {
758
for (int x=0; x<result.width(); ++x) {
759
QRgb pixel = result.pixel(x, y);
760
same &= (pixel == resPixel);
762
printf("expect=%08x, result=%08x\n", resPixel, pixel);
771
// repeat tests converting from an image with nonstandard stride
773
int dp = (src.depth() < 8 || result.depth() < 8) ? 8 : 1;
774
QImage src2(src.bits() + (dp*src.depth())/8,
776
src.height() - 1, src.bytesPerLine(),
779
src2.setColorTable(src.colorTable());
781
const QImage result2 = src2.convertToFormat(QImage::Format(resFormat));
783
QCOMPARE(src2.width(), result2.width());
784
QCOMPARE(src2.height(), result2.height());
786
QImage expected2(result.bits() + (dp*result.depth())/8,
787
result.width() - dp*2,
788
result.height() - 1, result.bytesPerLine(),
790
if (result.depth() < 8)
791
expected2.setColorTable(result.colorTable());
793
result2.save("result2.xpm", "XPM");
794
expected2.save("expected2.xpm", "XPM");
796
QCOMPARE(result2, expected2);
797
QFile::remove(QLatin1String("result2.xpm"));
798
QFile::remove(QLatin1String("expected2.xpm"));
801
void tst_QImage::convertToFormatRgb888ToRGB32()
803
// 545 so width % 4 != 0. This ensure there is padding at the end of the scanlines
804
const int height = 545;
805
const int width = 545;
806
QImage source(width, height, QImage::Format_RGB888);
807
for (int y = 0; y < height; ++y) {
808
uchar *srcPixels = source.scanLine(y);
809
for (int x = 0; x < width * 3; ++x)
813
QImage rgb32Image = source.convertToFormat(QImage::Format_RGB888);
814
QCOMPARE(rgb32Image.format(), QImage::Format_RGB888);
815
for (int x = 0; x < width; ++x) {
816
for (int y = 0; y < height; ++y)
817
QCOMPARE(rgb32Image.pixel(x, y), source.pixel(x, y));
821
void tst_QImage::createAlphaMask_data()
823
QTest::addColumn<int>("x");
824
QTest::addColumn<int>("y");
825
QTest::addColumn<int>("alpha1");
826
QTest::addColumn<int>("alpha2");
828
int alphas[] = { 0, 127, 255 };
830
for (unsigned a1 = 0; a1 < sizeof(alphas) / sizeof(int); ++a1) {
831
for (unsigned a2 = 0; a2 < sizeof(alphas) / sizeof(int); ++a2) {
834
for (int x=10; x<18; x+=3) {
835
for (int y=100; y<108; y+=3) {
836
QTest::newRow(qPrintable(QString::fromLatin1("x=%1, y=%2, a1=%3, a2=%4").arg(x).arg(y).arg(alphas[a1]).arg(alphas[a2])))
837
<< x << y << alphas[a1] << alphas[a2];
844
void tst_QImage::createAlphaMask()
851
QSize size(255, 255);
852
int pixelsInLines = size.width() + size.height() - 1;
853
int pixelsOutofLines = size.width() * size.height() - pixelsInLines;
855
// Generate an white image with two lines, horizontal at y and vertical at x.
856
// Lines have alpha of alpha2, rest has alpha of alpha1
857
QImage image(size, QImage::Format_ARGB32);
858
for (int cy=0; cy<image.height(); ++cy) {
859
for (int cx=0; cx<image.width(); ++cx) {
860
int alpha = (y == cy || x == cx) ? alpha2 : alpha1;
861
image.setPixel(cx, cy, qRgba(255, 255, 255, alpha));
865
QImage mask = image.createAlphaMask(Qt::OrderedAlphaDither);
868
QCOMPARE(mask.width(), image.width());
869
QCOMPARE(mask.height(), image.height());
871
// Sum up the number of pixels set for both lines and other area
874
for (int cy=0; cy<image.height(); ++cy) {
875
for (int cx=0; cx<image.width(); ++cx) {
876
int *alpha = (y == cy || x == cx) ? &sumAlpha2 : &sumAlpha1;
877
*alpha += mask.pixelIndex(cx, cy);
881
// Compare the set bits to whats expected for that alpha.
882
const int threshold = 5;
883
QVERIFY(qAbs(sumAlpha1 * 255 / pixelsOutofLines - alpha1) < threshold);
884
QVERIFY(qAbs(sumAlpha2 * 255 / pixelsInLines - alpha2) < threshold);
887
void tst_QImage::dotsPerMeterZero()
889
QImage img(100, 100, QImage::Format_RGB32);
890
QVERIFY(!img.isNull());
892
int defaultDpmX = img.dotsPerMeterX();
893
int defaultDpmY = img.dotsPerMeterY();
894
QVERIFY(defaultDpmX != 0);
895
QVERIFY(defaultDpmY != 0);
897
img.setDotsPerMeterX(0);
898
img.setDotsPerMeterY(0);
900
QCOMPARE(img.dotsPerMeterX(), defaultDpmX);
901
QCOMPARE(img.dotsPerMeterY(), defaultDpmY);
904
void tst_QImage::rotate_data()
906
QTest::addColumn<QImage::Format>("format");
907
QTest::addColumn<int>("degrees");
909
QVector<int> degrees;
910
degrees << 0 << 90 << 180 << 270;
912
foreach (int d, degrees) {
913
QString title = QString("%1 %2").arg(d);
914
QTest::newRow(qPrintable(title.arg("Format_RGB32")))
915
<< QImage::Format_RGB32 << d;
916
QTest::newRow(qPrintable(title.arg("Format_ARGB32")))
917
<< QImage::Format_ARGB32 << d;
918
QTest::newRow(qPrintable(title.arg("Format_ARGB32_Premultiplied")))
919
<< QImage::Format_ARGB32_Premultiplied << d;
920
QTest::newRow(qPrintable(title.arg("Format_RGB16")))
921
<< QImage::Format_RGB16 << d;
922
QTest::newRow(qPrintable(title.arg("Format_ARGB8565_Premultiplied")))
923
<< QImage::Format_ARGB8565_Premultiplied << d;
924
QTest::newRow(qPrintable(title.arg("Format_RGB666")))
925
<< QImage::Format_RGB666 << d;
926
QTest::newRow(qPrintable(title.arg("Format_RGB555")))
927
<< QImage::Format_RGB555 << d;
928
QTest::newRow(qPrintable(title.arg("Format_ARGB8555_Premultiplied")))
929
<< QImage::Format_ARGB8555_Premultiplied << d;
930
QTest::newRow(qPrintable(title.arg("Format_RGB888")))
931
<< QImage::Format_RGB888 << d;
932
QTest::newRow(qPrintable(title.arg("Format_Indexed8")))
933
<< QImage::Format_Indexed8 << d;
937
void tst_QImage::rotate()
939
QFETCH(QImage::Format, format);
940
QFETCH(int, degrees);
942
// test if rotate90 is lossless
945
QImage original(w, h, format);
946
original.fill(qRgb(255,255,255));
948
if (format == QImage::Format_Indexed8) {
949
original.setColorCount(256);
950
for (int i = 0; i < 255; ++i)
951
original.setColor(i, qRgb(0, i, i));
954
if (original.colorTable().isEmpty()) {
955
for (int x = 0; x < w; ++x) {
956
original.setPixel(x,0, qRgb(x,0,128));
957
original.setPixel(x,h - 1, qRgb(0,255 - x,128));
959
for (int y = 0; y < h; ++y) {
960
original.setPixel(0, y, qRgb(y,0,255));
961
original.setPixel(w - 1, y, qRgb(0,255 - y,255));
964
const int n = original.colorTable().size();
965
for (int x = 0; x < w; ++x) {
966
original.setPixel(x, 0, x % n);
967
original.setPixel(x, h - 1, n - (x % n) - 1);
969
for (int y = 0; y < h; ++y) {
970
original.setPixel(0, y, y % n);
971
original.setPixel(w - 1, y, n - (y % n) - 1);
975
// original.save("rotated90_original.png", "png");
977
// Initialize the matrix manually (do not use rotate) to avoid rounding errors
979
matRotate90.rotate(degrees);
980
QImage dest = original;
981
// And rotate it 4 times, then the image should be identical to the original
982
for (int i = 0; i < 4 ; ++i) {
983
dest = dest.transformed(matRotate90);
986
// Make sure they are similar in format before we compare them.
987
dest = dest.convertToFormat(format);
989
// dest.save("rotated90_result.png","png");
990
QCOMPARE(original, dest);
992
// Test with QMatrix::rotate 90 also, since we trust that now
993
matRotate90.rotate(degrees);
995
// And rotate it 4 times, then the image should be identical to the original
996
for (int i = 0; i < 4 ; ++i) {
997
dest = dest.transformed(matRotate90);
1000
// Make sure they are similar in format before we compare them.
1001
dest = dest.convertToFormat(format);
1003
QCOMPARE(original, dest);
1006
void tst_QImage::copy()
1010
QImage img(16,16,QImage::Format_ARGB32);
1011
img.copy(QRect(1000,1,1,1));
1015
void tst_QImage::load()
1017
const QString prefix = QFINDTESTDATA("images/");
1018
if (prefix.isEmpty())
1019
QFAIL("can not find images directory!");
1020
const QString filePath = prefix + QLatin1String("image.jpg");
1022
QImage dest(filePath);
1023
QVERIFY(!dest.isNull());
1024
QVERIFY(!dest.load("image_that_does_not_exist.png"));
1025
QVERIFY(dest.isNull());
1026
QVERIFY(dest.load(filePath));
1027
QVERIFY(!dest.isNull());
1030
void tst_QImage::loadFromData()
1032
const QString prefix = QFINDTESTDATA("images/");
1033
if (prefix.isEmpty())
1034
QFAIL("can not find images directory!");
1035
const QString filePath = prefix + QLatin1String("image.jpg");
1037
QImage original(filePath);
1038
QVERIFY(!original.isNull());
1043
QVERIFY(buf.open(QIODevice::WriteOnly));
1044
QVERIFY(original.save(&buf, "BMP"));
1046
QVERIFY(!ba.isEmpty());
1049
QVERIFY(dest.loadFromData(ba, "BMP"));
1050
QVERIFY(!dest.isNull());
1052
QCOMPARE(original, dest);
1054
QVERIFY(!dest.loadFromData(QByteArray()));
1055
QVERIFY(dest.isNull());
1058
#if !defined(QT_NO_DATASTREAM)
1059
void tst_QImage::loadFromDataStream()
1061
const QString prefix = QFINDTESTDATA("images/");
1062
if (prefix.isEmpty())
1063
QFAIL("can not find images directory!");
1064
const QString filePath = prefix + QLatin1String("image.jpg");
1066
QImage original(filePath);
1067
QVERIFY(!original.isNull());
1071
QDataStream s(&ba, QIODevice::WriteOnly);
1074
QVERIFY(!ba.isEmpty());
1078
QDataStream s(&ba, QIODevice::ReadOnly);
1081
QVERIFY(!dest.isNull());
1083
QCOMPARE(original, dest);
1087
QDataStream s(&ba, QIODevice::ReadOnly);
1090
QVERIFY(dest.isNull());
1092
#endif // QT_NO_DATASTREAM
1094
void tst_QImage::setPixel_data()
1096
QTest::addColumn<int>("format");
1097
QTest::addColumn<uint>("value");
1098
QTest::addColumn<uint>("expected");
1100
QTest::newRow("ARGB32 red") << int(QImage::Format_ARGB32)
1101
<< 0xffff0000 << 0xffff0000;
1102
QTest::newRow("ARGB32 green") << int(QImage::Format_ARGB32)
1103
<< 0xff00ff00 << 0xff00ff00;
1104
QTest::newRow("ARGB32 blue") << int(QImage::Format_ARGB32)
1105
<< 0xff0000ff << 0xff0000ff;
1106
QTest::newRow("RGB16 red") << int(QImage::Format_RGB16)
1107
<< 0xffff0000 << 0xf800u;
1108
QTest::newRow("RGB16 green") << int(QImage::Format_RGB16)
1109
<< 0xff00ff00 << 0x07e0u;
1110
QTest::newRow("RGB16 blue") << int(QImage::Format_RGB16)
1111
<< 0xff0000ff << 0x001fu;
1112
QTest::newRow("ARGB8565_Premultiplied red") << int(QImage::Format_ARGB8565_Premultiplied)
1113
<< 0xffff0000 << 0xf800ffu;
1114
QTest::newRow("ARGB8565_Premultiplied green") << int(QImage::Format_ARGB8565_Premultiplied)
1115
<< 0xff00ff00 << 0x07e0ffu;
1116
QTest::newRow("ARGB8565_Premultiplied blue") << int(QImage::Format_ARGB8565_Premultiplied)
1117
<< 0xff0000ff << 0x001fffu;
1118
QTest::newRow("RGB666 red") << int(QImage::Format_RGB666)
1119
<< 0xffff0000 << 0x03f000u;
1120
QTest::newRow("RGB666 green") << int(QImage::Format_RGB666)
1121
<< 0xff00ff00 << 0x000fc0u;
1122
QTest::newRow("RGB666 blue") << int(QImage::Format_RGB666)
1123
<< 0xff0000ff << 0x00003fu;
1124
QTest::newRow("RGB555 red") << int(QImage::Format_RGB555)
1125
<< 0xffff0000 << 0x7c00u;
1126
QTest::newRow("RGB555 green") << int(QImage::Format_RGB555)
1127
<< 0xff00ff00 << 0x03e0u;
1128
QTest::newRow("RGB555 blue") << int(QImage::Format_RGB555)
1129
<< 0xff0000ff << 0x001fu;
1130
QTest::newRow("ARGB8555_Premultiplied red") << int(QImage::Format_ARGB8555_Premultiplied)
1131
<< 0xffff0000 << 0x7c00ffu;
1132
QTest::newRow("ARGB8555_Premultiplied green") << int(QImage::Format_ARGB8555_Premultiplied)
1133
<< 0xff00ff00 << 0x03e0ffu;
1134
QTest::newRow("ARGB8555_Premultiplied blue") << int(QImage::Format_ARGB8555_Premultiplied)
1135
<< 0xff0000ff << 0x001fffu;
1136
QTest::newRow("RGB888 red") << int(QImage::Format_RGB888)
1137
<< 0xffff0000 << 0xff0000u;
1138
QTest::newRow("RGB888 green") << int(QImage::Format_RGB888)
1139
<< 0xff00ff00 << 0x00ff00u;
1140
QTest::newRow("RGB888 blue") << int(QImage::Format_RGB888)
1141
<< 0xff0000ff << 0x0000ffu;
1144
void tst_QImage::setPixel()
1146
QFETCH(int, format);
1147
QFETCH(uint, value);
1148
QFETCH(uint, expected);
1153
QImage img(w, h, QImage::Format(format));
1156
for (int y = 0; y < h; ++y)
1157
for (int x = 0; x < w; ++x)
1158
img.setPixel(x, y, value);
1160
// check pixel values
1162
case int(QImage::Format_RGB32):
1163
case int(QImage::Format_ARGB32):
1164
case int(QImage::Format_ARGB32_Premultiplied):
1166
for (int y = 0; y < h; ++y) {
1167
const quint32 *row = (const quint32*)(img.scanLine(y));
1168
for (int x = 0; x < w; ++x) {
1169
quint32 result = row[x];
1170
if (result != expected)
1171
printf("[x,y]: %d,%d, expected=%08x, result=%08x\n",
1172
x, y, expected, result);
1173
QCOMPARE(uint(result), expected);
1178
case int(QImage::Format_RGB555):
1179
case int(QImage::Format_RGB16):
1181
for (int y = 0; y < h; ++y) {
1182
const quint16 *row = (const quint16*)(img.scanLine(y));
1183
for (int x = 0; x < w; ++x) {
1184
quint16 result = row[x];
1185
if (result != expected)
1186
printf("[x,y]: %d,%d, expected=%04x, result=%04x\n",
1187
x, y, expected, result);
1188
QCOMPARE(uint(result), expected);
1193
case int(QImage::Format_RGB666):
1194
case int(QImage::Format_ARGB8565_Premultiplied):
1195
case int(QImage::Format_ARGB8555_Premultiplied):
1196
case int(QImage::Format_RGB888):
1198
for (int y = 0; y < h; ++y) {
1199
const quint24 *row = (const quint24*)(img.scanLine(y));
1200
for (int x = 0; x < w; ++x) {
1201
quint32 result = row[x];
1202
if (result != expected)
1203
printf("[x,y]: %d,%d, expected=%04x, result=%04x\n",
1204
x, y, expected, result);
1205
QCOMPARE(result, expected);
1211
qFatal("Test not implemented for format %d", format);
1215
void tst_QImage::convertToFormatPreserveDotsPrMeter()
1217
QImage img(100, 100, QImage::Format_ARGB32_Premultiplied);
1221
img.setDotsPerMeterX(dpmx);
1222
img.setDotsPerMeterY(dpmy);
1223
img.fill(0x12345678);
1225
img = img.convertToFormat(QImage::Format_RGB32);
1227
QCOMPARE(img.dotsPerMeterX(), dpmx);
1228
QCOMPARE(img.dotsPerMeterY(), dpmy);
1231
void tst_QImage::convertToFormatPreserveText()
1233
QImage img(100, 100, QImage::Format_ARGB32_Premultiplied);
1235
img.setText("foo", "bar");
1236
img.setText("foo2", "bar2");
1237
img.fill(0x12345678);
1239
QStringList listResult;
1240
listResult << "foo" << "foo2";
1241
QString result = "foo: bar\n\nfoo2: bar2";
1243
QImage imgResult1 = img.convertToFormat(QImage::Format_RGB32);
1244
QCOMPARE(imgResult1.text(), result);
1245
QCOMPARE(imgResult1.textKeys(), listResult);
1247
QVector<QRgb> colorTable(4);
1248
for (int i = 0; i < 4; ++i)
1249
colorTable[i] = QRgb(42);
1250
QImage imgResult2 = img.convertToFormat(QImage::Format_MonoLSB,
1252
QCOMPARE(imgResult2.text(), result);
1253
QCOMPARE(imgResult2.textKeys(), listResult);
1256
void tst_QImage::setColorCount()
1258
QImage img(0, 0, QImage::Format_Indexed8);
1259
QTest::ignoreMessage(QtWarningMsg, "QImage::setColorCount: null image");
1260
img.setColorCount(256);
1261
QCOMPARE(img.colorCount(), 0);
1264
void tst_QImage::setColor()
1266
QImage img(0, 0, QImage::Format_Indexed8);
1267
img.setColor(0, qRgba(18, 219, 108, 128));
1268
QCOMPARE(img.colorCount(), 0);
1270
QImage img2(1, 1, QImage::Format_Indexed8);
1271
img2.setColor(0, qRgba(18, 219, 108, 128));
1272
QCOMPARE(img2.colorCount(), 1);
1275
/* Just some sanity checking that we don't draw outside the buffer of
1276
* the image. Hopefully this will create crashes or at least some
1277
* random test fails when broken.
1279
void tst_QImage::rasterClipping()
1281
QImage image(10, 10, QImage::Format_RGB32);
1282
image.fill(0xffffffff);
1286
p.drawLine(-1000, 5, 5, 5);
1287
p.drawLine(-1000, 5, 1000, 5);
1288
p.drawLine(5, 5, 1000, 5);
1290
p.drawLine(5, -1000, 5, 5);
1291
p.drawLine(5, -1000, 5, 1000);
1292
p.drawLine(5, 5, 5, 1000);
1294
p.setBrush(Qt::red);
1296
p.drawEllipse(3, 3, 4, 4);
1297
p.drawEllipse(-100, -100, 210, 210);
1299
p.drawEllipse(-1000, 0, 2010, 2010);
1300
p.drawEllipse(0, -1000, 2010, 2010);
1301
p.drawEllipse(-2010, -1000, 2010, 2010);
1302
p.drawEllipse(-1000, -2010, 2010, 2010);
1306
// Tests the new QPoint overloads in QImage in Qt 4.2
1307
void tst_QImage::pointOverloads()
1309
QImage image(100, 100, QImage::Format_RGB32);
1310
image.fill(0xff00ff00);
1313
QVERIFY(image.valid(QPoint(0, 0)));
1314
QVERIFY(image.valid(QPoint(99, 0)));
1315
QVERIFY(image.valid(QPoint(0, 99)));
1316
QVERIFY(image.valid(QPoint(99, 99)));
1318
QVERIFY(!image.valid(QPoint(50, -1))); // outside on the top
1319
QVERIFY(!image.valid(QPoint(50, 100))); // outside on the bottom
1320
QVERIFY(!image.valid(QPoint(-1, 50))); // outside on the left
1321
QVERIFY(!image.valid(QPoint(100, 50))); // outside on the right
1323
// Test the pixel setter
1324
image.setPixel(QPoint(10, 10), 0xff0000ff);
1325
QCOMPARE(image.pixel(10, 10), 0xff0000ff);
1328
QCOMPARE(image.pixel(QPoint(10, 10)), 0xff0000ff);
1331
QImage indexed = image.convertToFormat(QImage::Format_Indexed8);
1332
QCOMPARE(indexed.pixelIndex(10, 10), indexed.pixelIndex(QPoint(10, 10)));
1335
void tst_QImage::destructor()
1338
poly.setPoint(0,-1455, 1435);
1340
QImage image(100, 100, QImage::Format_RGB32);
1341
QPainter ptPix(&image);
1342
ptPix.setPen(Qt::black);
1343
ptPix.setBrush(Qt::black);
1344
ptPix.drawPolygon(poly, Qt::WindingFill);
1351
static const char *monoPixmap[] = {
1352
/* width height ncolors chars_per_pixel */
1364
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
1365
void tst_QImage::createHeuristicMask()
1367
QImage img(monoPixmap);
1368
img = img.convertToFormat(QImage::Format_MonoLSB);
1369
QImage mask = img.createHeuristicMask();
1370
QImage newMask = mask.convertToFormat(QImage::Format_ARGB32_Premultiplied);
1373
QVERIFY(newMask.pixel(0,1) != newMask.pixel(1,1));
1374
QVERIFY(newMask.pixel(1,1) == newMask.pixel(2,1));
1375
QVERIFY(newMask.pixel(2,1) != newMask.pixel(3,1));
1378
QVERIFY(newMask.pixel(0,2) != newMask.pixel(1,2));
1379
QVERIFY(newMask.pixel(1,2) == newMask.pixel(2,2));
1380
QVERIFY(newMask.pixel(2,2) != newMask.pixel(3,2));
1384
void tst_QImage::cacheKey()
1386
QImage image1(2, 2, QImage::Format_RGB32);
1387
qint64 image1_key = image1.cacheKey();
1388
QImage image2 = image1;
1390
QVERIFY(image2.cacheKey() == image1.cacheKey());
1392
QVERIFY(image2.cacheKey() != image1.cacheKey());
1393
QVERIFY(image1.cacheKey() == image1_key);
1396
void tst_QImage::smoothScale()
1398
unsigned int data[2] = { qRgba(0, 0, 0, 0), qRgba(128, 128, 128, 128) };
1400
QImage imgX((unsigned char *)data, 2, 1, QImage::Format_ARGB32_Premultiplied);
1401
QImage imgY((unsigned char *)data, 1, 2, QImage::Format_ARGB32_Premultiplied);
1403
QImage scaledX = imgX.scaled(QSize(4, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1404
QImage scaledY = imgY.scaled(QSize(1, 4), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1407
(unsigned int *)scaledX.bits(),
1408
(unsigned int *)scaledY.bits()
1411
int expected[4] = { 0, 32, 96, 128 };
1412
for (int image = 0; image < 2; ++image) {
1413
for (int index = 0; index < 4; ++index) {
1414
for (int component = 0; component < 4; ++component) {
1415
int pixel = scaled[image][index];
1416
int val = (pixel >> (component * 8)) & 0xff;
1418
QCOMPARE(val, expected[index]);
1424
// test area sampling
1425
void tst_QImage::smoothScale2()
1427
int sizes[] = { 2, 4, 8, 10, 16, 20, 32, 40, 64, 100, 101, 128, 0 };
1428
QImage::Format formats[] = { QImage::Format_ARGB32, QImage::Format_RGB32, QImage::Format_Invalid };
1429
for (int i = 0; sizes[i] != 0; ++i) {
1430
for (int j = 0; formats[j] != QImage::Format_Invalid; ++j) {
1431
int size = sizes[i];
1433
QRgb expected = formats[j] == QImage::Format_ARGB32 ? qRgba(63, 127, 255, 255) : qRgb(63, 127, 255);
1435
QImage img(size, size, formats[j]);
1438
// scale x down, y down
1439
QImage scaled = img.scaled(QSize(1, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1440
QRgb pixel = scaled.pixel(0, 0);
1441
QCOMPARE(qAlpha(pixel), qAlpha(expected));
1442
QCOMPARE(qRed(pixel), qRed(expected));
1443
QCOMPARE(qGreen(pixel), qGreen(expected));
1444
QCOMPARE(qBlue(pixel), qBlue(expected));
1446
// scale x down, y up
1447
scaled = img.scaled(QSize(1, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1448
for (int y = 0; y < scaled.height(); ++y) {
1449
pixel = scaled.pixel(0, y);
1450
QCOMPARE(qAlpha(pixel), qAlpha(expected));
1451
QCOMPARE(qRed(pixel), qRed(expected));
1452
QCOMPARE(qGreen(pixel), qGreen(expected));
1453
QCOMPARE(qBlue(pixel), qBlue(expected));
1456
// scale x up, y down
1457
scaled = img.scaled(QSize(size * 2, 1), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1458
for (int x = 0; x < scaled.width(); ++x) {
1459
pixel = scaled.pixel(x, 0);
1460
QCOMPARE(qAlpha(pixel), qAlpha(expected));
1461
QCOMPARE(qRed(pixel), qRed(expected));
1462
QCOMPARE(qGreen(pixel), qGreen(expected));
1463
QCOMPARE(qBlue(pixel), qBlue(expected));
1467
scaled = img.scaled(QSize(size * 2, size * 2), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1468
for (int y = 0; y < scaled.height(); ++y) {
1469
for (int x = 0; x < scaled.width(); ++x) {
1470
pixel = scaled.pixel(x, y);
1471
QCOMPARE(qAlpha(pixel), qAlpha(expected));
1472
QCOMPARE(qRed(pixel), qRed(expected));
1473
QCOMPARE(qGreen(pixel), qGreen(expected));
1474
QCOMPARE(qBlue(pixel), qBlue(expected));
1481
static inline int rand8()
1483
return int(256. * (qrand() / (RAND_MAX + 1.0)));
1486
// compares img.scale against the bilinear filtering used by QPainter
1487
void tst_QImage::smoothScale3()
1489
QImage img(128, 128, QImage::Format_RGB32);
1490
for (int y = 0; y < img.height(); ++y) {
1491
for (int x = 0; x < img.width(); ++x) {
1492
const int red = rand8();
1493
const int green = rand8();
1494
const int blue = rand8();
1495
const int alpha = 255;
1497
img.setPixel(x, y, qRgba(red, green, blue, alpha));
1501
qreal scales[2] = { .5, 2 };
1503
for (int i = 0; i < 2; ++i) {
1504
QImage a = img.scaled(img.size() * scales[i], Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1505
QImage b(a.size(), a.format());
1509
p.setRenderHint(QPainter::SmoothPixmapTransform);
1510
p.scale(scales[i], scales[i]);
1511
p.drawImage(0, 0, img);
1515
for (int y = 0; y < a.height(); ++y) {
1516
for (int x = 0; x < a.width(); ++x) {
1517
QRgb ca = a.pixel(x, y);
1518
QRgb cb = b.pixel(x, y);
1520
// tolerate a little bit of rounding errors
1522
r &= qAbs(qRed(ca) - qRed(cb)) <= 18;
1523
r &= qAbs(qGreen(ca) - qGreen(cb)) <= 18;
1524
r &= qAbs(qBlue(ca) - qBlue(cb)) <= 18;
1533
void tst_QImage::smoothScaleBig()
1535
#if defined(Q_OS_WINCE)
1536
int bigValue = 2000;
1538
int bigValue = 200000;
1540
QImage tall(4, bigValue, QImage::Format_ARGB32);
1543
QImage wide(bigValue, 4, QImage::Format_ARGB32);
1546
QImage tallScaled = tall.scaled(4, tall.height() / 4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1547
QImage wideScaled = wide.scaled(wide.width() / 4, 4, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1549
QCOMPARE(tallScaled.pixel(0, 0), QRgb(0x0));
1550
QCOMPARE(wideScaled.pixel(0, 0), QRgb(0x0));
1553
void tst_QImage::smoothScaleAlpha()
1555
QImage src(128, 128, QImage::Format_ARGB32_Premultiplied);
1558
QPainter srcPainter(&src);
1559
srcPainter.setPen(Qt::NoPen);
1560
srcPainter.setBrush(Qt::white);
1561
srcPainter.drawEllipse(QRect(QPoint(), src.size()));
1564
QImage dst(32, 32, QImage::Format_ARGB32_Premultiplied);
1565
dst.fill(0xffffffff);
1566
QImage expected = dst;
1568
QPainter dstPainter(&dst);
1569
dstPainter.drawImage(0, 0, src.scaled(dst.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
1572
QCOMPARE(dst, expected);
1575
static int count(const QImage &img, int x, int y, int dx, int dy, QRgb pixel)
1578
while (x >= 0 && x < img.width() && y >= 0 && y < img.height()) {
1579
i += (img.pixel(x, y) == pixel);
1586
const int transformed_image_width = 128;
1587
const int transformed_image_height = 128;
1589
void tst_QImage::transformed_data()
1591
QTest::addColumn<QTransform>("transform");
1594
QTransform transform;
1595
transform.translate(10.4, 10.4);
1596
QTest::newRow("Translate") << transform;
1599
QTransform transform;
1600
transform.scale(1.5, 1.5);
1601
QTest::newRow("Scale") << transform;
1604
QTransform transform;
1605
transform.rotate(30);
1606
QTest::newRow("Rotate 30") << transform;
1609
QTransform transform;
1610
transform.rotate(90);
1611
QTest::newRow("Rotate 90") << transform;
1614
QTransform transform;
1615
transform.rotate(180);
1616
QTest::newRow("Rotate 180") << transform;
1619
QTransform transform;
1620
transform.rotate(270);
1621
QTest::newRow("Rotate 270") << transform;
1624
QTransform transform;
1625
transform.translate(transformed_image_width/2, transformed_image_height/2);
1626
transform.rotate(155, Qt::XAxis);
1627
transform.translate(-transformed_image_width/2, -transformed_image_height/2);
1628
QTest::newRow("Perspective 1") << transform;
1631
QTransform transform;
1632
transform.rotate(155, Qt::XAxis);
1633
transform.translate(-transformed_image_width/2, -transformed_image_height/2);
1634
QTest::newRow("Perspective 2") << transform;
1638
void tst_QImage::transformed()
1640
QFETCH(QTransform, transform);
1642
QImage img(transformed_image_width, transformed_image_height, QImage::Format_ARGB32_Premultiplied);
1644
p.fillRect(0, 0, img.width(), img.height(), Qt::red);
1645
p.drawRect(0, 0, img.width()-1, img.height()-1);
1648
QImage transformed = img.transformed(transform, Qt::SmoothTransformation);
1650
// all borders should have touched pixels
1652
QVERIFY(count(transformed, 0, 0, 1, 0, 0x0) < transformed.width());
1653
QVERIFY(count(transformed, 0, 0, 0, 1, 0x0) < transformed.height());
1655
QVERIFY(count(transformed, 0, img.height() - 1, 1, 0, 0x0) < transformed.width());
1656
QVERIFY(count(transformed, img.width() - 1, 0, 0, 1, 0x0) < transformed.height());
1658
QImage transformedPadded(transformed.width() + 2, transformed.height() + 2, img.format());
1659
transformedPadded.fill(0x0);
1661
p.begin(&transformedPadded);
1662
p.setRenderHint(QPainter::SmoothPixmapTransform);
1663
p.setRenderHint(QPainter::Antialiasing);
1664
p.setTransform(transformed.trueMatrix(transform, img.width(), img.height()) * QTransform().translate(1, 1));
1665
p.drawImage(0, 0, img);
1668
// no borders should have touched pixels since we have a one-pixel padding
1670
QCOMPARE(count(transformedPadded, 0, 0, 1, 0, 0x0), transformedPadded.width());
1671
QCOMPARE(count(transformedPadded, 0, 0, 0, 1, 0x0), transformedPadded.height());
1673
QCOMPARE(count(transformedPadded, 0, transformedPadded.height() - 1, 1, 0, 0x0), transformedPadded.width());
1674
QCOMPARE(count(transformedPadded, transformedPadded.width() - 1, 0, 0, 1, 0x0), transformedPadded.height());
1677
void tst_QImage::transformed2()
1679
QImage img(3, 3, QImage::Format_Mono);
1681
p.fillRect(0, 0, 3, 3, Qt::white);
1682
p.fillRect(0, 0, 3, 3, Qt::Dense4Pattern);
1685
QTransform transform;
1686
transform.scale(3, 3);
1688
QImage expected(9, 9, QImage::Format_Mono);
1690
p.fillRect(0, 0, 9, 9, Qt::white);
1691
p.setBrush(Qt::black);
1692
p.setPen(Qt::NoPen);
1693
p.drawRect(3, 0, 3, 3);
1694
p.drawRect(0, 3, 3, 3);
1695
p.drawRect(6, 3, 3, 3);
1696
p.drawRect(3, 6, 3, 3);
1700
QImage actual = img.transformed(transform);
1702
QCOMPARE(actual.format(), expected.format());
1703
QCOMPARE(actual.size(), expected.size());
1704
QCOMPARE(actual, expected);
1708
transform.rotate(-90);
1709
QImage actual = img.transformed(transform);
1711
QCOMPARE(actual.convertToFormat(QImage::Format_ARGB32_Premultiplied),
1712
expected.convertToFormat(QImage::Format_ARGB32_Premultiplied));
1716
void tst_QImage::scaled()
1718
QImage img(102, 3, QImage::Format_Mono);
1720
p.fillRect(0, 0, img.width(), img.height(), Qt::white);
1723
QImage scaled = img.scaled(1994, 10);
1725
QImage expected(1994, 10, QImage::Format_Mono);
1727
p.fillRect(0, 0, expected.width(), expected.height(), Qt::white);
1730
QCOMPARE(scaled, expected);
1733
void tst_QImage::paintEngine()
1737
QPaintEngine *engine;
1739
QImage temp(100, 100, QImage::Format_RGB32);
1740
temp.fill(0xff000000);
1743
p.fillRect(80,80,10,10,Qt::blue);
1748
engine = temp.paintEngine();
1754
p.fillRect(80,10,10,10,Qt::yellow);
1758
QImage expected(100, 100, QImage::Format_RGB32);
1759
expected.fill(0xff000000);
1761
QPainter p(&expected);
1762
p.fillRect(80,80,10,10,Qt::blue);
1763
p.fillRect(80,10,10,10,Qt::yellow);
1766
QCOMPARE(engine, img.paintEngine());
1767
QCOMPARE(img, expected);
1770
void tst_QImage::setAlphaChannelWhilePainting()
1772
QImage image(100, 100, QImage::Format_ARGB32);
1773
image.fill(Qt::black);
1776
image.setAlphaChannel(image.createMaskFromColor(QColor(Qt::black).rgb(), Qt::MaskInColor));
1780
// See task 240047 for details
1781
void tst_QImage::smoothScaledSubImage()
1783
QImage original(128, 128, QImage::Format_RGB32);
1784
QPainter p(&original);
1785
p.fillRect(0, 0, 64, 128, Qt::black);
1786
p.fillRect(64, 0, 64, 128, Qt::white);
1789
QImage subimage(((const QImage &) original).bits(), 32, 32, original.bytesPerLine(), QImage::Format_RGB32); // only in the black part of the source...
1791
QImage scaled = subimage.scaled(8, 8, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1793
for (int y=0; y<scaled.height(); ++y)
1794
for (int x=0; x<scaled.width(); ++x)
1795
QCOMPARE(scaled.pixel(x, y), 0xff000000);
1798
void tst_QImage::nullSize_data()
1800
QTest::addColumn<QImage>("image");
1801
QTest::newRow("null image") << QImage();
1802
QTest::newRow("zero-size image") << QImage(0, 0, QImage::Format_RGB32);
1805
void tst_QImage::nullSize()
1807
QFETCH(QImage, image);
1808
QCOMPARE(image.isNull(), true);
1809
QCOMPARE(image.width(), image.size().width());
1810
QCOMPARE(image.height(), image.size().height());
1813
void tst_QImage::premultipliedAlphaConsistency()
1815
QImage img(256, 1, QImage::Format_ARGB32);
1816
for (int x = 0; x < 256; ++x)
1817
img.setPixel(x, 0, (x << 24) | 0xffffff);
1819
QImage converted = img.convertToFormat(QImage::Format_ARGB8565_Premultiplied);
1820
QImage pm32 = converted.convertToFormat(QImage::Format_ARGB32_Premultiplied);
1822
for (int i = 0; i < pm32.width(); ++i) {
1823
QRgb pixel = pm32.pixel(i, 0);
1824
QVERIFY(qRed(pixel) <= qAlpha(pixel));
1825
QVERIFY(qGreen(pixel) <= qAlpha(pixel));
1826
QVERIFY(qBlue(pixel) <= qAlpha(pixel));
1830
void tst_QImage::compareIndexed()
1832
QImage img(256, 1, QImage::Format_Indexed8);
1834
QVector<QRgb> colorTable(256);
1835
for (int i = 0; i < 256; ++i)
1836
colorTable[i] = qRgb(i, i, i);
1837
img.setColorTable(colorTable);
1839
for (int i = 0; i < 256; ++i) {
1840
img.setPixel(i, 0, i);
1843
QImage imgInverted(256, 1, QImage::Format_Indexed8);
1844
QVector<QRgb> invertedColorTable(256);
1845
for (int i = 0; i < 256; ++i)
1846
invertedColorTable[255-i] = qRgb(i, i, i);
1847
imgInverted.setColorTable(invertedColorTable);
1849
for (int i = 0; i < 256; ++i) {
1850
imgInverted.setPixel(i, 0, (255-i));
1853
QCOMPARE(img, imgInverted);
1856
void tst_QImage::fillColor_data()
1858
QTest::addColumn<QImage::Format>("format");
1859
QTest::addColumn<Qt::GlobalColor>("color");
1860
QTest::addColumn<uint>("pixelValue");
1862
QTest::newRow("Mono, color0") << QImage::Format_Mono << Qt::color0 << 0u;
1863
QTest::newRow("Mono, color1") << QImage::Format_Mono << Qt::color1 << 1u;
1865
QTest::newRow("MonoLSB, color0") << QImage::Format_MonoLSB << Qt::color0 << 0u;
1866
QTest::newRow("MonoLSB, color1") << QImage::Format_MonoLSB << Qt::color1 << 1u;
1868
const char *names[] = {
1885
QImage::Format formats[] = {
1886
QImage::Format_Indexed8,
1887
QImage::Format_RGB32,
1888
QImage::Format_ARGB32,
1889
QImage::Format_ARGB32_Premultiplied,
1890
QImage::Format_RGB16,
1891
QImage::Format_ARGB8565_Premultiplied,
1892
QImage::Format_RGB666,
1893
QImage::Format_ARGB6666_Premultiplied,
1894
QImage::Format_RGB555,
1895
QImage::Format_ARGB8555_Premultiplied,
1896
QImage::Format_RGB888,
1897
QImage::Format_RGB444,
1898
QImage::Format_ARGB4444_Premultiplied
1901
for (int i=0; names[i] != 0; ++i) {
1903
name.append(names[i]).append(", ");
1905
QTest::newRow(QByteArray(name).append("black").constData()) << formats[i] << Qt::black << 0xff000000;
1906
QTest::newRow(QByteArray(name).append("white").constData()) << formats[i] << Qt::white << 0xffffffff;
1907
QTest::newRow(QByteArray(name).append("red").constData()) << formats[i] << Qt::red << 0xffff0000;
1908
QTest::newRow(QByteArray(name).append("green").constData()) << formats[i] << Qt::green << 0xff00ff00;
1909
QTest::newRow(QByteArray(name).append("blue").constData()) << formats[i] << Qt::blue << 0xff0000ff;
1912
QTest::newRow("RGB16, transparent") << QImage::Format_RGB16 << Qt::transparent << 0xff000000;
1913
QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << Qt::transparent << 0xff000000;
1914
QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << Qt::transparent << 0x00000000u;
1915
QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << Qt::transparent << 0x00000000u;
1918
void tst_QImage::fillColor()
1920
QFETCH(QImage::Format, format);
1921
QFETCH(Qt::GlobalColor, color);
1922
QFETCH(uint, pixelValue);
1924
QImage image(1, 1, format);
1926
if (image.depth() == 8) {
1927
QVector<QRgb> table;
1928
table << 0xff000000;
1929
table << 0xffffffff;
1930
table << 0xffff0000;
1931
table << 0xff00ff00;
1932
table << 0xff0000ff;
1933
image.setColorTable(table);
1937
if (image.depth() == 1) {
1938
QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue);
1940
QCOMPARE(image.pixel(0, 0), pixelValue);
1943
image.fill(QColor(color));
1944
if (image.depth() == 1) {
1945
QCOMPARE(image.pixelIndex(0, 0), (int) pixelValue);
1947
QCOMPARE(image.pixel(0, 0), pixelValue);
1951
void tst_QImage::fillColorWithAlpha()
1953
QImage argb32(1, 1, QImage::Format_ARGB32);
1954
argb32.fill(QColor(255, 0, 0, 127));
1955
QCOMPARE(argb32.pixel(0, 0), qRgba(255, 0, 0, 127));
1957
QImage argb32pm(1, 1, QImage::Format_ARGB32_Premultiplied);
1958
argb32pm.fill(QColor(255, 0, 0, 127));
1959
QCOMPARE(argb32pm.pixel(0, 0), 0x7f7f0000u);
1962
void tst_QImage::fillRGB888()
1964
QImage expected(1, 1, QImage::Format_RGB888);
1965
QImage actual(1, 1, QImage::Format_RGB888);
1967
for (int c = Qt::black; c < Qt::transparent; ++c) {
1968
QColor color = QColor(Qt::GlobalColor(c));
1970
expected.fill(color);
1971
actual.fill(color.rgba());
1973
QCOMPARE(actual.pixel(0, 0), expected.pixel(0, 0));
1977
void tst_QImage::rgbSwapped_data()
1979
QTest::addColumn<QImage::Format>("format");
1981
QTest::newRow("Format_Indexed8") << QImage::Format_Indexed8;
1982
QTest::newRow("Format_RGB32") << QImage::Format_RGB32;
1983
QTest::newRow("Format_ARGB32") << QImage::Format_ARGB32;
1984
QTest::newRow("Format_ARGB32_Premultiplied") << QImage::Format_ARGB32_Premultiplied;
1985
QTest::newRow("Format_RGB16") << QImage::Format_RGB16;
1986
QTest::newRow("Format_ARGB8565_Premultiplied") << QImage::Format_ARGB8565_Premultiplied;
1987
QTest::newRow("Format_ARGB6666_Premultiplied") << QImage::Format_ARGB6666_Premultiplied;
1988
QTest::newRow("Format_ARGB4444_Premultiplied") << QImage::Format_ARGB4444_Premultiplied;
1989
QTest::newRow("Format_RGB666") << QImage::Format_RGB666;
1990
QTest::newRow("Format_RGB555") << QImage::Format_RGB555;
1991
QTest::newRow("Format_ARGB8555_Premultiplied") << QImage::Format_ARGB8555_Premultiplied;
1992
QTest::newRow("Format_RGB888") << QImage::Format_RGB888;
1993
QTest::newRow("Format_RGB444") << QImage::Format_RGB444;
1996
void tst_QImage::rgbSwapped()
1998
QFETCH(QImage::Format, format);
2000
QImage image(100, 1, format);
2003
QVector<QColor> testColor(image.width());
2005
for (int i = 0; i < image.width(); ++i)
2006
testColor[i] = QColor(i, 10 + i, 20 + i * 2, 30 + i);
2008
if (format != QImage::Format_Indexed8) {
2010
p.setCompositionMode(QPainter::CompositionMode_Source);
2011
for (int i = 0; i < image.width(); ++i)
2012
p.fillRect(QRect(i, 0, 1, 1), testColor[i].rgb());
2014
image.setColorCount(image.width());
2015
for (int i = 0; i < image.width(); ++i) {
2016
image.setColor(0, testColor[i].rgba());
2017
image.setPixel(i, 0, i);
2021
QImage imageSwapped = image.rgbSwapped();
2023
for (int i = 0; i < image.width(); ++i) {
2024
QColor referenceColor = QColor(image.pixel(i, 0));
2025
QColor swappedColor = QColor(imageSwapped.pixel(i, 0));
2027
QCOMPARE(swappedColor.alpha(), referenceColor.alpha());
2028
QCOMPARE(swappedColor.red(), referenceColor.blue());
2029
QCOMPARE(swappedColor.green(), referenceColor.green());
2030
QCOMPARE(swappedColor.blue(), referenceColor.red());
2033
QImage imageSwappedTwice = imageSwapped.rgbSwapped();
2035
QCOMPARE(image, imageSwappedTwice);
2037
QCOMPARE(memcmp(image.constBits(), imageSwappedTwice.constBits(), image.byteCount()), 0);
2040
void tst_QImage::deepCopyWhenPaintingActive()
2042
QImage image(64, 64, QImage::Format_ARGB32_Premultiplied);
2045
QPainter painter(&image);
2046
QImage copy = image;
2048
painter.setBrush(Qt::black);
2049
painter.drawEllipse(image.rect());
2051
QVERIFY(copy != image);
2054
void tst_QImage::scaled_QTBUG19157()
2056
QImage foo(5000, 1, QImage::Format_RGB32);
2057
foo = foo.scaled(1024, 1024, Qt::KeepAspectRatio);
2058
QVERIFY(!foo.isNull());
2061
static void cleanupFunction(void* info)
2063
bool *called = static_cast<bool*>(info);
2067
void tst_QImage::cleanupFunctions()
2069
QImage bufferImage(64, 64, QImage::Format_ARGB32);
2070
bufferImage.fill(0);
2077
QImage image(bufferImage.bits(), bufferImage.width(), bufferImage.height(), bufferImage.format(), cleanupFunction, &called);
2086
QImage image(bufferImage.bits(), bufferImage.width(), bufferImage.height(), bufferImage.format(), cleanupFunction, &called);
2087
copy = new QImage(image);
2096
QTEST_MAIN(tst_QImage)
2097
#include "tst_qimage.moc"