1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qimage.h"
41
42#include "qbuffer.h"
43#include "qdatastream.h"
44#include "qcolortransform.h"
45#include "qmap.h"
46#include "qtransform.h"
47#include "qimagereader.h"
48#include "qimagewriter.h"
49#include "qstringlist.h"
50#include "qvariant.h"
51#include "qimagepixmapcleanuphooks_p.h"
52#include <qpa/qplatformintegration.h>
53#include <private/qguiapplication_p.h>
54#include <ctype.h>
55#include <stdlib.h>
56#include <limits.h>
57#include <qpa/qplatformpixmap.h>
58#include <private/qcolortransform_p.h>
59#include <private/qmemrotate_p.h>
60#include <private/qimagescale_p.h>
61#include <private/qpixellayout_p.h>
62#include <private/qsimd_p.h>
63
64#include <qhash.h>
65
66#include <private/qpaintengine_raster_p.h>
67
68#include <private/qimage_p.h>
69#include <private/qfont_p.h>
70
71#if QT_CONFIG(thread)
72#include "qsemaphore.h"
73#include "qthreadpool.h"
74#endif
75
76#include <qtgui_tracepoints_p.h>
77
78QT_BEGIN_NAMESPACE
79
80static inline bool isLocked(QImageData *data)
81{
82 return data != nullptr && data->is_locked;
83}
84
85#if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
86#pragma message disable narrowptr
87#endif
88
89
90#define QIMAGE_SANITYCHECK_MEMORY(image) \
91 if ((image).isNull()) { \
92 qWarning("QImage: out of memory, returning null image"); \
93 return QImage(); \
94 }
95
96
97static QImage rotated90(const QImage &src);
98static QImage rotated180(const QImage &src);
99static QImage rotated270(const QImage &src);
100
101static int next_qimage_serial_number()
102{
103 static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0);
104 return 1 + serial.fetchAndAddRelaxed(1);
105}
106
107QImageData::QImageData()
108 : ref(0), width(0), height(0), depth(0), nbytes(0), devicePixelRatio(1.0), data(nullptr),
109 format(QImage::Format_ARGB32), bytes_per_line(0),
110 ser_no(next_qimage_serial_number()),
111 detach_no(0),
112 dpmx(qt_defaultDpiX() * 100 / qreal(2.54)),
113 dpmy(qt_defaultDpiY() * 100 / qreal(2.54)),
114 offset(0, 0), own_data(true), ro_data(false), has_alpha_clut(false),
115 is_cached(false), is_locked(false), cleanupFunction(nullptr), cleanupInfo(nullptr),
116 paintEngine(nullptr)
117{
118}
119
120/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format)
121
122 \internal
123
124 Creates a new image data.
125 Returns \nullptr if invalid parameters are give or anything else failed.
126*/
127QImageData * QImageData::create(const QSize &size, QImage::Format format)
128{
129 if (size.isEmpty() || format == QImage::Format_Invalid)
130 return nullptr; // invalid parameter(s)
131
132 Q_TRACE_SCOPE(QImageData_create, size, format);
133
134 int width = size.width();
135 int height = size.height();
136 int depth = qt_depthForFormat(format);
137 auto params = calculateImageParameters(width, height, depth);
138 if (!params.isValid())
139 return nullptr;
140
141 QScopedPointer<QImageData> d(new QImageData);
142
143 switch (format) {
144 case QImage::Format_Mono:
145 case QImage::Format_MonoLSB:
146 d->colortable.resize(2);
147 d->colortable[0] = QColor(Qt::black).rgba();
148 d->colortable[1] = QColor(Qt::white).rgba();
149 break;
150 default:
151 break;
152 }
153
154 d->width = width;
155 d->height = height;
156 d->depth = depth;
157 d->format = format;
158 d->has_alpha_clut = false;
159 d->is_cached = false;
160
161 d->bytes_per_line = params.bytesPerLine;
162 d->nbytes = params.totalSize;
163 d->data = (uchar *)malloc(d->nbytes);
164
165 if (!d->data)
166 return nullptr;
167
168 d->ref.ref();
169 return d.take();
170}
171
172QImageData::~QImageData()
173{
174 if (cleanupFunction)
175 cleanupFunction(cleanupInfo);
176 if (is_cached)
177 QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no));
178 delete paintEngine;
179 if (data && own_data)
180 free(data);
181 data = nullptr;
182}
183
184#if defined(_M_ARM)
185#pragma optimize("", off)
186#endif
187
188bool QImageData::checkForAlphaPixels() const
189{
190 bool has_alpha_pixels = false;
191
192 switch (format) {
193
194 case QImage::Format_Mono:
195 case QImage::Format_MonoLSB:
196 case QImage::Format_Indexed8:
197 has_alpha_pixels = has_alpha_clut;
198 break;
199 case QImage::Format_Alpha8:
200 has_alpha_pixels = true;
201 break;
202 case QImage::Format_ARGB32:
203 case QImage::Format_ARGB32_Premultiplied: {
204 const uchar *bits = data;
205 for (int y=0; y<height && !has_alpha_pixels; ++y) {
206 uint alphaAnd = 0xff000000;
207 for (int x=0; x<width; ++x)
208 alphaAnd &= reinterpret_cast<const uint*>(bits)[x];
209 has_alpha_pixels = (alphaAnd != 0xff000000);
210 bits += bytes_per_line;
211 }
212 } break;
213
214 case QImage::Format_RGBA8888:
215 case QImage::Format_RGBA8888_Premultiplied: {
216 const uchar *bits = data;
217 for (int y=0; y<height && !has_alpha_pixels; ++y) {
218 uchar alphaAnd = 0xff;
219 for (int x=0; x<width; ++x)
220 alphaAnd &= bits[x * 4+ 3];
221 has_alpha_pixels = (alphaAnd != 0xff);
222 bits += bytes_per_line;
223 }
224 } break;
225
226 case QImage::Format_A2BGR30_Premultiplied:
227 case QImage::Format_A2RGB30_Premultiplied: {
228 const uchar *bits = data;
229 for (int y=0; y<height && !has_alpha_pixels; ++y) {
230 uint alphaAnd = 0xc0000000;
231 for (int x=0; x<width; ++x)
232 alphaAnd &= reinterpret_cast<const uint*>(bits)[x];
233 has_alpha_pixels = (alphaAnd != 0xc0000000);
234 bits += bytes_per_line;
235 }
236 } break;
237
238 case QImage::Format_ARGB8555_Premultiplied:
239 case QImage::Format_ARGB8565_Premultiplied: {
240 const uchar *bits = data;
241 const uchar *end_bits = data + bytes_per_line;
242
243 for (int y=0; y<height && !has_alpha_pixels; ++y) {
244 uchar alphaAnd = 0xff;
245 while (bits < end_bits) {
246 alphaAnd &= bits[0];
247 bits += 3;
248 }
249 has_alpha_pixels = (alphaAnd != 0xff);
250 bits = end_bits;
251 end_bits += bytes_per_line;
252 }
253 } break;
254
255 case QImage::Format_ARGB6666_Premultiplied: {
256 const uchar *bits = data;
257 const uchar *end_bits = data + bytes_per_line;
258
259 for (int y=0; y<height && !has_alpha_pixels; ++y) {
260 uchar alphaAnd = 0xfc;
261 while (bits < end_bits) {
262 alphaAnd &= bits[0];
263 bits += 3;
264 }
265 has_alpha_pixels = (alphaAnd != 0xfc);
266 bits = end_bits;
267 end_bits += bytes_per_line;
268 }
269 } break;
270
271 case QImage::Format_ARGB4444_Premultiplied: {
272 const uchar *bits = data;
273 for (int y=0; y<height && !has_alpha_pixels; ++y) {
274 ushort alphaAnd = 0xf000;
275 for (int x=0; x<width; ++x)
276 alphaAnd &= reinterpret_cast<const ushort*>(bits)[x];
277 has_alpha_pixels = (alphaAnd != 0xf000);
278 bits += bytes_per_line;
279 }
280 } break;
281 case QImage::Format_RGBA64:
282 case QImage::Format_RGBA64_Premultiplied: {
283 uchar *bits = data;
284 for (int y=0; y<height && !has_alpha_pixels; ++y) {
285 for (int x=0; x<width; ++x) {
286 has_alpha_pixels |= !(((QRgba64 *)bits)[x].isOpaque());
287 }
288 bits += bytes_per_line;
289 }
290 } break;
291
292 case QImage::Format_RGB32:
293 case QImage::Format_RGB16:
294 case QImage::Format_RGB444:
295 case QImage::Format_RGB555:
296 case QImage::Format_RGB666:
297 case QImage::Format_RGB888:
298 case QImage::Format_BGR888:
299 case QImage::Format_RGBX8888:
300 case QImage::Format_BGR30:
301 case QImage::Format_RGB30:
302 case QImage::Format_Grayscale8:
303 case QImage::Format_Grayscale16:
304 case QImage::Format_RGBX64:
305 break;
306 case QImage::Format_Invalid:
307 case QImage::NImageFormats:
308 Q_UNREACHABLE();
309 break;
310 }
311
312 return has_alpha_pixels;
313}
314#if defined(_M_ARM)
315#pragma optimize("", on)
316#endif
317
318/*!
319 \class QImage
320
321 \inmodule QtGui
322 \ingroup painting
323 \ingroup shared
324
325 \reentrant
326
327 \brief The QImage class provides a hardware-independent image
328 representation that allows direct access to the pixel data, and
329 can be used as a paint device.
330
331 Qt provides four classes for handling image data: QImage, QPixmap,
332 QBitmap and QPicture. QImage is designed and optimized for I/O,
333 and for direct pixel access and manipulation, while QPixmap is
334 designed and optimized for showing images on screen. QBitmap is
335 only a convenience class that inherits QPixmap, ensuring a
336 depth of 1. Finally, the QPicture class is a paint device that
337 records and replays QPainter commands.
338
339 Because QImage is a QPaintDevice subclass, QPainter can be used to
340 draw directly onto images. When using QPainter on a QImage, the
341 painting can be performed in another thread than the current GUI
342 thread.
343
344 The QImage class supports several image formats described by the
345 \l Format enum. These include monochrome, 8-bit, 32-bit and
346 alpha-blended images which are available in all versions of Qt
347 4.x.
348
349 QImage provides a collection of functions that can be used to
350 obtain a variety of information about the image. There are also
351 several functions that enables transformation of the image.
352
353 QImage objects can be passed around by value since the QImage
354 class uses \l{Implicit Data Sharing}{implicit data
355 sharing}. QImage objects can also be streamed and compared.
356
357 \note If you would like to load QImage objects in a static build of Qt,
358 refer to the \l{How to Create Qt Plugins}{Plugin HowTo}.
359
360 \warning Painting on a QImage with the format
361 QImage::Format_Indexed8 is not supported.
362
363 \tableofcontents
364
365 \section1 Reading and Writing Image Files
366
367 QImage provides several ways of loading an image file: The file
368 can be loaded when constructing the QImage object, or by using the
369 load() or loadFromData() functions later on. QImage also provides
370 the static fromData() function, constructing a QImage from the
371 given data. When loading an image, the file name can either refer
372 to an actual file on disk or to one of the application's embedded
373 resources. See \l{The Qt Resource System} overview for details
374 on how to embed images and other resource files in the
375 application's executable.
376
377 Simply call the save() function to save a QImage object.
378
379 The complete list of supported file formats are available through
380 the QImageReader::supportedImageFormats() and
381 QImageWriter::supportedImageFormats() functions. New file formats
382 can be added as plugins. By default, Qt supports the following
383 formats:
384
385 \table
386 \header \li Format \li Description \li Qt's support
387 \row \li BMP \li Windows Bitmap \li Read/write
388 \row \li GIF \li Graphic Interchange Format (optional) \li Read
389 \row \li JPG \li Joint Photographic Experts Group \li Read/write
390 \row \li JPEG \li Joint Photographic Experts Group \li Read/write
391 \row \li PNG \li Portable Network Graphics \li Read/write
392 \row \li PBM \li Portable Bitmap \li Read
393 \row \li PGM \li Portable Graymap \li Read
394 \row \li PPM \li Portable Pixmap \li Read/write
395 \row \li XBM \li X11 Bitmap \li Read/write
396 \row \li XPM \li X11 Pixmap \li Read/write
397 \endtable
398
399 \section1 Image Information
400
401 QImage provides a collection of functions that can be used to
402 obtain a variety of information about the image:
403
404 \table
405 \header
406 \li \li Available Functions
407
408 \row
409 \li Geometry
410 \li
411
412 The size(), width(), height(), dotsPerMeterX(), and
413 dotsPerMeterY() functions provide information about the image size
414 and aspect ratio.
415
416 The rect() function returns the image's enclosing rectangle. The
417 valid() function tells if a given pair of coordinates is within
418 this rectangle. The offset() function returns the number of pixels
419 by which the image is intended to be offset by when positioned
420 relative to other images, which also can be manipulated using the
421 setOffset() function.
422
423 \row
424 \li Colors
425 \li
426
427 The color of a pixel can be retrieved by passing its coordinates
428 to the pixel() function. The pixel() function returns the color
429 as a QRgb value indepedent of the image's format.
430
431 In case of monochrome and 8-bit images, the colorCount() and
432 colorTable() functions provide information about the color
433 components used to store the image data: The colorTable() function
434 returns the image's entire color table. To obtain a single entry,
435 use the pixelIndex() function to retrieve the pixel index for a
436 given pair of coordinates, then use the color() function to
437 retrieve the color. Note that if you create an 8-bit image
438 manually, you have to set a valid color table on the image as
439 well.
440
441 The hasAlphaChannel() function tells if the image's format
442 respects the alpha channel, or not. The allGray() and
443 isGrayscale() functions tell whether an image's colors are all
444 shades of gray.
445
446 See also the \l {QImage#Pixel Manipulation}{Pixel Manipulation}
447 and \l {QImage#Image Transformations}{Image Transformations}
448 sections.
449
450 \row
451 \li Text
452 \li
453
454 The text() function returns the image text associated with the
455 given text key. An image's text keys can be retrieved using the
456 textKeys() function. Use the setText() function to alter an
457 image's text.
458
459 \row
460 \li Low-level information
461 \li
462
463 The depth() function returns the depth of the image. The supported
464 depths are 1 (monochrome), 8, 16, 24 and 32 bits. The
465 bitPlaneCount() function tells how many of those bits that are
466 used. For more information see the
467 \l {QImage#Image Formats}{Image Formats} section.
468
469 The format(), bytesPerLine(), and sizeInBytes() functions provide
470 low-level information about the data stored in the image.
471
472 The cacheKey() function returns a number that uniquely
473 identifies the contents of this QImage object.
474 \endtable
475
476 \section1 Pixel Manipulation
477
478 The functions used to manipulate an image's pixels depend on the
479 image format. The reason is that monochrome and 8-bit images are
480 index-based and use a color lookup table, while 32-bit images
481 store ARGB values directly. For more information on image formats,
482 see the \l {Image Formats} section.
483
484 In case of a 32-bit image, the setPixel() function can be used to
485 alter the color of the pixel at the given coordinates to any other
486 color specified as an ARGB quadruplet. To make a suitable QRgb
487 value, use the qRgb() (adding a default alpha component to the
488 given RGB values, i.e. creating an opaque color) or qRgba()
489 function. For example:
490
491 \table
492 \header
493 \li {2,1}32-bit
494 \row
495 \li \inlineimage qimage-32bit_scaled.png
496 \li
497 \snippet code/src_gui_image_qimage.cpp 0
498 \endtable
499
500 In case of a 8-bit and monchrome images, the pixel value is only
501 an index from the image's color table. So the setPixel() function
502 can only be used to alter the color of the pixel at the given
503 coordinates to a predefined color from the image's color table,
504 i.e. it can only change the pixel's index value. To alter or add a
505 color to an image's color table, use the setColor() function.
506
507 An entry in the color table is an ARGB quadruplet encoded as an
508 QRgb value. Use the qRgb() and qRgba() functions to make a
509 suitable QRgb value for use with the setColor() function. For
510 example:
511
512 \table
513 \header
514 \li {2,1} 8-bit
515 \row
516 \li \inlineimage qimage-8bit_scaled.png
517 \li
518 \snippet code/src_gui_image_qimage.cpp 1
519 \endtable
520
521 For images with more than 8-bit per color-channel. The methods
522 setPixelColor() and pixelColor() can be used to set and get
523 with QColor values.
524
525 QImage also provide the scanLine() function which returns a
526 pointer to the pixel data at the scanline with the given index,
527 and the bits() function which returns a pointer to the first pixel
528 data (this is equivalent to \c scanLine(0)).
529
530 \section1 Image Formats
531
532 Each pixel stored in a QImage is represented by an integer. The
533 size of the integer varies depending on the format. QImage
534 supports several image formats described by the \l Format
535 enum.
536
537 Monochrome images are stored using 1-bit indexes into a color table
538 with at most two colors. There are two different types of
539 monochrome images: big endian (MSB first) or little endian (LSB
540 first) bit order.
541
542 8-bit images are stored using 8-bit indexes into a color table,
543 i.e. they have a single byte per pixel. The color table is a
544 QList<QRgb>, and the QRgb typedef is equivalent to an unsigned
545 int containing an ARGB quadruplet on the format 0xAARRGGBB.
546
547 32-bit images have no color table; instead, each pixel contains an
548 QRgb value. There are three different types of 32-bit images
549 storing RGB (i.e. 0xffRRGGBB), ARGB and premultiplied ARGB
550 values respectively. In the premultiplied format the red, green,
551 and blue channels are multiplied by the alpha component divided by
552 255.
553
554 An image's format can be retrieved using the format()
555 function. Use the convertToFormat() functions to convert an image
556 into another format. The allGray() and isGrayscale() functions
557 tell whether a color image can safely be converted to a grayscale
558 image.
559
560 \section1 Image Transformations
561
562 QImage supports a number of functions for creating a new image
563 that is a transformed version of the original: The
564 createAlphaMask() function builds and returns a 1-bpp mask from
565 the alpha buffer in this image, and the createHeuristicMask()
566 function creates and returns a 1-bpp heuristic mask for this
567 image. The latter function works by selecting a color from one of
568 the corners, then chipping away pixels of that color starting at
569 all the edges.
570
571 The mirrored() function returns a mirror of the image in the
572 desired direction, the scaled() returns a copy of the image scaled
573 to a rectangle of the desired measures, and the rgbSwapped() function
574 constructs a BGR image from a RGB image.
575
576 The scaledToWidth() and scaledToHeight() functions return scaled
577 copies of the image.
578
579 The transformed() function returns a copy of the image that is
580 transformed with the given transformation matrix and
581 transformation mode: Internally, the transformation matrix is
582 adjusted to compensate for unwanted translation,
583 i.e. transformed() returns the smallest image containing all
584 transformed points of the original image. The static trueMatrix()
585 function returns the actual matrix used for transforming the
586 image.
587
588 There are also functions for changing attributes of an image
589 in-place:
590
591 \table
592 \header \li Function \li Description
593 \row
594 \li setDotsPerMeterX()
595 \li Defines the aspect ratio by setting the number of pixels that fit
596 horizontally in a physical meter.
597 \row
598 \li setDotsPerMeterY()
599 \li Defines the aspect ratio by setting the number of pixels that fit
600 vertically in a physical meter.
601 \row
602 \li fill()
603 \li Fills the entire image with the given pixel value.
604 \row
605 \li invertPixels()
606 \li Inverts all pixel values in the image using the given InvertMode value.
607 \row
608 \li setColorTable()
609 \li Sets the color table used to translate color indexes. Only
610 monochrome and 8-bit formats.
611 \row
612 \li setColorCount()
613 \li Resizes the color table. Only monochrome and 8-bit formats.
614
615 \endtable
616
617 \sa QImageReader, QImageWriter, QPixmap, QSvgRenderer, {Image Composition Example},
618 {Image Viewer Example}, {Scribble Example}, {Pixelator Example}
619*/
620
621/*!
622 \fn QImage::QImage(QImage &&other)
623
624 Move-constructs a QImage instance, making it point at the same
625 object that \a other was pointing to.
626
627 \since 5.2
628*/
629
630/*!
631 \fn QImage &QImage::operator=(QImage &&other)
632
633 Move-assigns \a other to this QImage instance.
634
635 \since 5.2
636*/
637
638/*!
639 \typedef QImageCleanupFunction
640 \relates QImage
641 \since 5.0
642
643 A function with the following signature that can be used to
644 implement basic image memory management:
645
646 \code
647 void myImageCleanupHandler(void *info);
648 \endcode
649*/
650
651/*!
652 \enum QImage::InvertMode
653
654 This enum type is used to describe how pixel values should be
655 inverted in the invertPixels() function.
656
657 \value InvertRgb Invert only the RGB values and leave the alpha
658 channel unchanged.
659
660 \value InvertRgba Invert all channels, including the alpha channel.
661
662 \sa invertPixels()
663*/
664
665/*!
666 \enum QImage::Format
667
668 The following image formats are available in Qt.
669 See the notes after the table.
670
671 \value Format_Invalid The image is invalid.
672 \value Format_Mono The image is stored using 1-bit per pixel. Bytes are
673 packed with the most significant bit (MSB) first.
674 \value Format_MonoLSB The image is stored using 1-bit per pixel. Bytes are
675 packed with the less significant bit (LSB) first.
676
677 \value Format_Indexed8 The image is stored using 8-bit indexes
678 into a colormap.
679
680 \value Format_RGB32 The image is stored using a 32-bit RGB format (0xffRRGGBB).
681
682 \value Format_ARGB32 The image is stored using a 32-bit ARGB
683 format (0xAARRGGBB).
684
685 \value Format_ARGB32_Premultiplied The image is stored using a premultiplied 32-bit
686 ARGB format (0xAARRGGBB), i.e. the red,
687 green, and blue channels are multiplied
688 by the alpha component divided by 255. (If RR, GG, or BB
689 has a higher value than the alpha channel, the results are
690 undefined.) Certain operations (such as image composition
691 using alpha blending) are faster using premultiplied ARGB32
692 than with plain ARGB32.
693
694 \value Format_RGB16 The image is stored using a 16-bit RGB format (5-6-5).
695
696 \value Format_ARGB8565_Premultiplied The image is stored using a
697 premultiplied 24-bit ARGB format (8-5-6-5).
698 \value Format_RGB666 The image is stored using a 24-bit RGB format (6-6-6).
699 The unused most significant bits is always zero.
700 \value Format_ARGB6666_Premultiplied The image is stored using a
701 premultiplied 24-bit ARGB format (6-6-6-6).
702 \value Format_RGB555 The image is stored using a 16-bit RGB format (5-5-5).
703 The unused most significant bit is always zero.
704 \value Format_ARGB8555_Premultiplied The image is stored using a
705 premultiplied 24-bit ARGB format (8-5-5-5).
706 \value Format_RGB888 The image is stored using a 24-bit RGB format (8-8-8).
707 \value Format_RGB444 The image is stored using a 16-bit RGB format (4-4-4).
708 The unused bits are always zero.
709 \value Format_ARGB4444_Premultiplied The image is stored using a
710 premultiplied 16-bit ARGB format (4-4-4-4).
711 \value Format_RGBX8888 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8).
712 This is the same as the Format_RGBA8888 except alpha must always be 255. (added in Qt 5.2)
713 \value Format_RGBA8888 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8).
714 Unlike ARGB32 this is a byte-ordered format, which means the 32bit
715 encoding differs between big endian and little endian architectures,
716 being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors
717 is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA. (added in Qt 5.2)
718 \value Format_RGBA8888_Premultiplied The image is stored using a
719 premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). (added in Qt 5.2)
720 \value Format_BGR30 The image is stored using a 32-bit BGR format (x-10-10-10). (added in Qt 5.4)
721 \value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). (added in Qt 5.4)
722 \value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10). (added in Qt 5.4)
723 \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). (added in Qt 5.4)
724 \value Format_Alpha8 The image is stored using an 8-bit alpha only format. (added in Qt 5.5)
725 \value Format_Grayscale8 The image is stored using an 8-bit grayscale format. (added in Qt 5.5)
726 \value Format_Grayscale16 The image is stored using an 16-bit grayscale format. (added in Qt 5.13)
727 \value Format_RGBX64 The image is stored using a 64-bit halfword-ordered RGB(x) format (16-16-16-16).
728 This is the same as the Format_RGBA64 except alpha must always be 65535. (added in Qt 5.12)
729 \value Format_RGBA64 The image is stored using a 64-bit halfword-ordered RGBA format (16-16-16-16). (added in Qt 5.12)
730 \value Format_RGBA64_Premultiplied The image is stored using a premultiplied 64-bit halfword-ordered
731 RGBA format (16-16-16-16). (added in Qt 5.12)
732 \value Format_BGR888 The image is stored using a 24-bit BGR format. (added in Qt 5.14)
733
734 \note Drawing into a QImage with QImage::Format_Indexed8 is not
735 supported.
736
737 \note Avoid most rendering directly to most of these formats using QPainter. Rendering
738 is best optimized to the \c Format_RGB32 and \c Format_ARGB32_Premultiplied formats, and secondarily for rendering to the
739 \c Format_RGB16, \c Format_RGBX8888, \c Format_RGBA8888_Premultiplied, \c Format_RGBX64 and \c Format_RGBA64_Premultiplied formats
740
741 \sa format(), convertToFormat()
742*/
743
744/*****************************************************************************
745 QImage member functions
746 *****************************************************************************/
747
748/*!
749 Constructs a null image.
750
751 \sa isNull()
752*/
753
754QImage::QImage() noexcept
755 : QPaintDevice()
756{
757 d = nullptr;
758}
759
760/*!
761 Constructs an image with the given \a width, \a height and \a
762 format.
763
764 A \l{isNull()}{null} image will be returned if memory cannot be allocated.
765
766 \warning This will create a QImage with uninitialized data. Call
767 fill() to fill the image with an appropriate pixel value before
768 drawing onto it with QPainter.
769*/
770QImage::QImage(int width, int height, Format format)
771 : QImage(QSize(width, height), format)
772{
773}
774
775/*!
776 Constructs an image with the given \a size and \a format.
777
778 A \l{isNull()}{null} image is returned if memory cannot be allocated.
779
780 \warning This will create a QImage with uninitialized data. Call
781 fill() to fill the image with an appropriate pixel value before
782 drawing onto it with QPainter.
783*/
784QImage::QImage(const QSize &size, Format format)
785 : QPaintDevice()
786{
787 d = QImageData::create(size, format);
788}
789
790
791
792QImageData *QImageData::create(uchar *data, int width, int height, qsizetype bpl, QImage::Format format, bool readOnly, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
793{
794 if (width <= 0 || height <= 0 || !data || format == QImage::Format_Invalid)
795 return nullptr;
796
797 const int depth = qt_depthForFormat(format);
798 auto params = calculateImageParameters(width, height, depth);
799 if (!params.isValid())
800 return nullptr;
801
802 if (bpl > 0) {
803 // can't overflow, because has calculateImageParameters already done this multiplication
804 const qsizetype min_bytes_per_line = (qsizetype(width) * depth + 7)/8;
805 if (bpl < min_bytes_per_line)
806 return nullptr;
807
808 // recalculate the total with this value
809 params.bytesPerLine = bpl;
810 if (mul_overflow<qsizetype>(bpl, height, &params.totalSize))
811 return nullptr;
812 }
813
814 QImageData *d = new QImageData;
815 d->ref.ref();
816
817 d->own_data = false;
818 d->ro_data = readOnly;
819 d->data = data;
820 d->width = width;
821 d->height = height;
822 d->depth = depth;
823 d->format = format;
824
825 d->bytes_per_line = params.bytesPerLine;
826 d->nbytes = params.totalSize;
827
828 d->cleanupFunction = cleanupFunction;
829 d->cleanupInfo = cleanupInfo;
830
831 return d;
832}
833
834/*!
835 Constructs an image with the given \a width, \a height and \a
836 format, that uses an existing memory buffer, \a data. The \a width
837 and \a height must be specified in pixels, \a data must be 32-bit aligned,
838 and each scanline of data in the image must also be 32-bit aligned.
839
840 The buffer must remain valid throughout the life of the QImage and
841 all copies that have not been modified or otherwise detached from
842 the original buffer. The image does not delete the buffer at destruction.
843 You can provide a function pointer \a cleanupFunction along with an
844 extra pointer \a cleanupInfo that will be called when the last copy
845 is destroyed.
846
847 If \a format is an indexed color format, the image color table is
848 initially empty and must be sufficiently expanded with
849 setColorCount() or setColorTable() before the image is used.
850*/
851QImage::QImage(uchar* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
852 : QPaintDevice()
853{
854 d = QImageData::create(data, width, height, 0, format, false, cleanupFunction, cleanupInfo);
855}
856
857/*!
858 Constructs an image with the given \a width, \a height and \a
859 format, that uses an existing read-only memory buffer, \a
860 data. The \a width and \a height must be specified in pixels, \a
861 data must be 32-bit aligned, and each scanline of data in the
862 image must also be 32-bit aligned.
863
864 The buffer must remain valid throughout the life of the QImage and
865 all copies that have not been modified or otherwise detached from
866 the original buffer. The image does not delete the buffer at destruction.
867 You can provide a function pointer \a cleanupFunction along with an
868 extra pointer \a cleanupInfo that will be called when the last copy
869 is destroyed.
870
871 If \a format is an indexed color format, the image color table is
872 initially empty and must be sufficiently expanded with
873 setColorCount() or setColorTable() before the image is used.
874
875 Unlike the similar QImage constructor that takes a non-const data buffer,
876 this version will never alter the contents of the buffer. For example,
877 calling QImage::bits() will return a deep copy of the image, rather than
878 the buffer passed to the constructor. This allows for the efficiency of
879 constructing a QImage from raw data, without the possibility of the raw
880 data being changed.
881*/
882QImage::QImage(const uchar* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
883 : QPaintDevice()
884{
885 d = QImageData::create(const_cast<uchar*>(data), width, height, 0, format, true, cleanupFunction, cleanupInfo);
886}
887
888/*!
889 Constructs an image with the given \a width, \a height and \a
890 format, that uses an existing memory buffer, \a data. The \a width
891 and \a height must be specified in pixels. \a bytesPerLine
892 specifies the number of bytes per line (stride).
893
894 The buffer must remain valid throughout the life of the QImage and
895 all copies that have not been modified or otherwise detached from
896 the original buffer. The image does not delete the buffer at destruction.
897 You can provide a function pointer \a cleanupFunction along with an
898 extra pointer \a cleanupInfo that will be called when the last copy
899 is destroyed.
900
901 If \a format is an indexed color format, the image color table is
902 initially empty and must be sufficiently expanded with
903 setColorCount() or setColorTable() before the image is used.
904*/
905
906QImage::QImage(uchar *data, int width, int height, qsizetype bytesPerLine, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
907 :QPaintDevice()
908{
909 d = QImageData::create(data, width, height, bytesPerLine, format, false, cleanupFunction, cleanupInfo);
910}
911
912/*!
913 Constructs an image with the given \a width, \a height and \a
914 format, that uses an existing memory buffer, \a data. The \a width
915 and \a height must be specified in pixels. \a bytesPerLine
916 specifies the number of bytes per line (stride).
917
918 The buffer must remain valid throughout the life of the QImage and
919 all copies that have not been modified or otherwise detached from
920 the original buffer. The image does not delete the buffer at destruction.
921 You can provide a function pointer \a cleanupFunction along with an
922 extra pointer \a cleanupInfo that will be called when the last copy
923 is destroyed.
924
925 If \a format is an indexed color format, the image color table is
926 initially empty and must be sufficiently expanded with
927 setColorCount() or setColorTable() before the image is used.
928
929 Unlike the similar QImage constructor that takes a non-const data buffer,
930 this version will never alter the contents of the buffer. For example,
931 calling QImage::bits() will return a deep copy of the image, rather than
932 the buffer passed to the constructor. This allows for the efficiency of
933 constructing a QImage from raw data, without the possibility of the raw
934 data being changed.
935*/
936
937QImage::QImage(const uchar *data, int width, int height, qsizetype bytesPerLine, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
938 :QPaintDevice()
939{
940 d = QImageData::create(const_cast<uchar*>(data), width, height, bytesPerLine, format, true, cleanupFunction, cleanupInfo);
941}
942
943/*!
944 Constructs an image and tries to load the image from the file with
945 the given \a fileName.
946
947 The loader attempts to read the image using the specified \a
948 format. If the \a format is not specified (which is the default),
949 it is auto-detected based on the file's suffix and header. For
950 details, see {QImageReader::setAutoDetectImageFormat()}{QImageReader}.
951
952 If the loading of the image failed, this object is a null image.
953
954 The file name can either refer to an actual file on disk or to one
955 of the application's embedded resources. See the
956 \l{resources.html}{Resource System} overview for details on how to
957 embed images and other resource files in the application's
958 executable.
959
960 \sa isNull(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
961*/
962
963QImage::QImage(const QString &fileName, const char *format)
964 : QPaintDevice()
965{
966 d = nullptr;
967 load(fileName, format);
968}
969
970#ifndef QT_NO_IMAGEFORMAT_XPM
971extern bool qt_read_xpm_image_or_array(QIODevice *device, const char * const *source, QImage &image);
972
973/*!
974 Constructs an image from the given \a xpm image.
975
976 Make sure that the image is a valid XPM image. Errors are silently
977 ignored.
978
979 Note that it's possible to squeeze the XPM variable a little bit
980 by using an unusual declaration:
981
982 \snippet code/src_gui_image_qimage.cpp 2
983
984 The extra \c const makes the entire definition read-only, which is
985 slightly more efficient (e.g., when the code is in a shared
986 library) and able to be stored in ROM with the application.
987*/
988
989QImage::QImage(const char * const xpm[])
990 : QPaintDevice()
991{
992 d = nullptr;
993 if (!xpm)
994 return;
995 if (!qt_read_xpm_image_or_array(nullptr, xpm, *this))
996 // Issue: Warning because the constructor may be ambigious
997 qWarning("QImage::QImage(), XPM is not supported");
998}
999#endif // QT_NO_IMAGEFORMAT_XPM
1000
1001/*!
1002 Constructs a shallow copy of the given \a image.
1003
1004 For more information about shallow copies, see the \l {Implicit
1005 Data Sharing} documentation.
1006
1007 \sa copy()
1008*/
1009
1010QImage::QImage(const QImage &image)
1011 : QPaintDevice()
1012{
1013 if (image.paintingActive() || isLocked(image.d)) {
1014 d = nullptr;
1015 image.copy().swap(*this);
1016 } else {
1017 d = image.d;
1018 if (d)
1019 d->ref.ref();
1020 }
1021}
1022
1023/*!
1024 Destroys the image and cleans up.
1025*/
1026
1027QImage::~QImage()
1028{
1029 if (d && !d->ref.deref())
1030 delete d;
1031}
1032
1033/*!
1034 Assigns a shallow copy of the given \a image to this image and
1035 returns a reference to this image.
1036
1037 For more information about shallow copies, see the \l {Implicit
1038 Data Sharing} documentation.
1039
1040 \sa copy(), QImage()
1041*/
1042
1043QImage &QImage::operator=(const QImage &image)
1044{
1045 if (image.paintingActive() || isLocked(image.d)) {
1046 operator=(image.copy());
1047 } else {
1048 if (image.d)
1049 image.d->ref.ref();
1050 if (d && !d->ref.deref())
1051 delete d;
1052 d = image.d;
1053 }
1054 return *this;
1055}
1056
1057/*!
1058 \fn void QImage::swap(QImage &other)
1059 \since 4.8
1060
1061 Swaps image \a other with this image. This operation is very
1062 fast and never fails.
1063*/
1064
1065/*!
1066 \internal
1067*/
1068int QImage::devType() const
1069{
1070 return QInternal::Image;
1071}
1072
1073/*!
1074 Returns the image as a QVariant.
1075*/
1076QImage::operator QVariant() const
1077{
1078 return QVariant::fromValue(*this);
1079}
1080
1081/*!
1082 \internal
1083
1084 If multiple images share common data, this image makes a copy of
1085 the data and detaches itself from the sharing mechanism, making
1086 sure that this image is the only one referring to the data.
1087
1088 Nothing is done if there is just a single reference.
1089
1090 \sa copy(), {QImage::isDetached()}{isDetached()}, {Implicit Data Sharing}
1091*/
1092void QImage::detach()
1093{
1094 if (d) {
1095 if (d->is_cached && d->ref.loadRelaxed() == 1)
1096 QImagePixmapCleanupHooks::executeImageHooks(cacheKey());
1097
1098 if (d->ref.loadRelaxed() != 1 || d->ro_data)
1099 *this = copy();
1100
1101 if (d)
1102 ++d->detach_no;
1103 }
1104}
1105
1106
1107static void copyPhysicalMetadata(QImageData *dst, const QImageData *src)
1108{
1109 dst->dpmx = src->dpmx;
1110 dst->dpmy = src->dpmy;
1111 dst->devicePixelRatio = src->devicePixelRatio;
1112}
1113
1114static void copyMetadata(QImageData *dst, const QImageData *src)
1115{
1116 // Doesn't copy colortable and alpha_clut, or offset.
1117 copyPhysicalMetadata(dst, src);
1118 dst->text = src->text;
1119 dst->colorSpace = src->colorSpace;
1120}
1121
1122static void copyMetadata(QImage *dst, const QImage &src)
1123{
1124 dst->setDotsPerMeterX(src.dotsPerMeterX());
1125 dst->setDotsPerMeterY(src.dotsPerMeterY());
1126 dst->setDevicePixelRatio(src.devicePixelRatio());
1127 const auto textKeys = src.textKeys();
1128 for (const auto &key: textKeys)
1129 dst->setText(key, src.text(key));
1130
1131}
1132
1133/*!
1134 \fn QImage QImage::copy(int x, int y, int width, int height) const
1135 \overload
1136
1137 The returned image is copied from the position (\a x, \a y) in
1138 this image, and will always have the given \a width and \a height.
1139 In areas beyond this image, pixels are set to 0.
1140
1141*/
1142
1143/*!
1144 \fn QImage QImage::copy(const QRect& rectangle) const
1145
1146 Returns a sub-area of the image as a new image.
1147
1148 The returned image is copied from the position (\a
1149 {rectangle}.x(), \a{rectangle}.y()) in this image, and will always
1150 have the size of the given \a rectangle.
1151
1152 In areas beyond this image, pixels are set to 0. For 32-bit RGB
1153 images, this means black; for 32-bit ARGB images, this means
1154 transparent black; for 8-bit images, this means the color with
1155 index 0 in the color table which can be anything; for 1-bit
1156 images, this means Qt::color0.
1157
1158 If the given \a rectangle is a null rectangle the entire image is
1159 copied.
1160
1161 \sa QImage()
1162*/
1163QImage QImage::copy(const QRect& r) const
1164{
1165 Q_TRACE_SCOPE(QImage_copy, r);
1166 if (!d)
1167 return QImage();
1168
1169 if (r.isNull()) {
1170 QImage image(d->width, d->height, d->format);
1171 if (image.isNull())
1172 return image;
1173
1174 // Qt for Embedded Linux can create images with non-default bpl
1175 // make sure we don't crash.
1176 if (image.d->nbytes != d->nbytes) {
1177 qsizetype bpl = qMin(bytesPerLine(), image.bytesPerLine());
1178 for (int i = 0; i < height(); i++)
1179 memcpy(image.scanLine(i), scanLine(i), bpl);
1180 } else
1181 memcpy(image.bits(), bits(), d->nbytes);
1182 image.d->colortable = d->colortable;
1183 image.d->offset = d->offset;
1184 image.d->has_alpha_clut = d->has_alpha_clut;
1185 copyMetadata(image.d, d);
1186 return image;
1187 }
1188
1189 int x = r.x();
1190 int y = r.y();
1191 int w = r.width();
1192 int h = r.height();
1193
1194 int dx = 0;
1195 int dy = 0;
1196 if (w <= 0 || h <= 0)
1197 return QImage();
1198
1199 QImage image(w, h, d->format);
1200 if (image.isNull())
1201 return image;
1202
1203 if (x < 0 || y < 0 || x + w > d->width || y + h > d->height) {
1204 // bitBlt will not cover entire image - clear it.
1205 image.fill(0);
1206 if (x < 0) {
1207 dx = -x;
1208 x = 0;
1209 }
1210 if (y < 0) {
1211 dy = -y;
1212 y = 0;
1213 }
1214 }
1215
1216 image.d->colortable = d->colortable;
1217
1218 int pixels_to_copy = qMax(w - dx, 0);
1219 if (x > d->width)
1220 pixels_to_copy = 0;
1221 else if (pixels_to_copy > d->width - x)
1222 pixels_to_copy = d->width - x;
1223 int lines_to_copy = qMax(h - dy, 0);
1224 if (y > d->height)
1225 lines_to_copy = 0;
1226 else if (lines_to_copy > d->height - y)
1227 lines_to_copy = d->height - y;
1228
1229 bool byteAligned = true;
1230 if (d->format == Format_Mono || d->format == Format_MonoLSB)
1231 byteAligned = !(dx & 7) && !(x & 7) && !(pixels_to_copy & 7);
1232
1233 if (byteAligned) {
1234 const uchar *src = d->data + ((x * d->depth) >> 3) + y * d->bytes_per_line;
1235 uchar *dest = image.d->data + ((dx * d->depth) >> 3) + dy * image.d->bytes_per_line;
1236 const qsizetype bytes_to_copy = (qsizetype(pixels_to_copy) * d->depth) >> 3;
1237 for (int i = 0; i < lines_to_copy; ++i) {
1238 memcpy(dest, src, bytes_to_copy);
1239 src += d->bytes_per_line;
1240 dest += image.d->bytes_per_line;
1241 }
1242 } else if (d->format == Format_Mono) {
1243 const uchar *src = d->data + y * d->bytes_per_line;
1244 uchar *dest = image.d->data + dy * image.d->bytes_per_line;
1245 for (int i = 0; i < lines_to_copy; ++i) {
1246 for (int j = 0; j < pixels_to_copy; ++j) {
1247 if (src[(x + j) >> 3] & (0x80 >> ((x + j) & 7)))
1248 dest[(dx + j) >> 3] |= (0x80 >> ((dx + j) & 7));
1249 else
1250 dest[(dx + j) >> 3] &= ~(0x80 >> ((dx + j) & 7));
1251 }
1252 src += d->bytes_per_line;
1253 dest += image.d->bytes_per_line;
1254 }
1255 } else { // Format_MonoLSB
1256 Q_ASSERT(d->format == Format_MonoLSB);
1257 const uchar *src = d->data + y * d->bytes_per_line;
1258 uchar *dest = image.d->data + dy * image.d->bytes_per_line;
1259 for (int i = 0; i < lines_to_copy; ++i) {
1260 for (int j = 0; j < pixels_to_copy; ++j) {
1261 if (src[(x + j) >> 3] & (0x1 << ((x + j) & 7)))
1262 dest[(dx + j) >> 3] |= (0x1 << ((dx + j) & 7));
1263 else
1264 dest[(dx + j) >> 3] &= ~(0x1 << ((dx + j) & 7));
1265 }
1266 src += d->bytes_per_line;
1267 dest += image.d->bytes_per_line;
1268 }
1269 }
1270
1271 copyMetadata(image.d, d);
1272 image.d->offset = offset();
1273 image.d->has_alpha_clut = d->has_alpha_clut;
1274 return image;
1275}
1276
1277
1278/*!
1279 \fn bool QImage::isNull() const
1280
1281 Returns \c true if it is a null image, otherwise returns \c false.
1282
1283 A null image has all parameters set to zero and no allocated data.
1284*/
1285bool QImage::isNull() const
1286{
1287 return !d;
1288}
1289
1290/*!
1291 \fn int QImage::width() const
1292
1293 Returns the width of the image.
1294
1295 \sa {QImage#Image Information}{Image Information}
1296*/
1297int QImage::width() const
1298{
1299 return d ? d->width : 0;
1300}
1301
1302/*!
1303 \fn int QImage::height() const
1304
1305 Returns the height of the image.
1306
1307 \sa {QImage#Image Information}{Image Information}
1308*/
1309int QImage::height() const
1310{
1311 return d ? d->height : 0;
1312}
1313
1314/*!
1315 \fn QSize QImage::size() const
1316
1317 Returns the size of the image, i.e. its width() and height().
1318
1319 \sa {QImage#Image Information}{Image Information}
1320*/
1321QSize QImage::size() const
1322{
1323 return d ? QSize(d->width, d->height) : QSize(0, 0);
1324}
1325
1326/*!
1327 \fn QRect QImage::rect() const
1328
1329 Returns the enclosing rectangle (0, 0, width(), height()) of the
1330 image.
1331
1332 \sa {QImage#Image Information}{Image Information}
1333*/
1334QRect QImage::rect() const
1335{
1336 return d ? QRect(0, 0, d->width, d->height) : QRect();
1337}
1338
1339/*!
1340 Returns the depth of the image.
1341
1342 The image depth is the number of bits used to store a single
1343 pixel, also called bits per pixel (bpp).
1344
1345 The supported depths are 1, 8, 16, 24, 32 and 64.
1346
1347 \sa bitPlaneCount(), convertToFormat(), {QImage#Image Formats}{Image Formats},
1348 {QImage#Image Information}{Image Information}
1349
1350*/
1351int QImage::depth() const
1352{
1353 return d ? d->depth : 0;
1354}
1355
1356/*!
1357 \since 4.6
1358 \fn int QImage::colorCount() const
1359
1360 Returns the size of the color table for the image.
1361
1362 Notice that colorCount() returns 0 for 32-bpp images because these
1363 images do not use color tables, but instead encode pixel values as
1364 ARGB quadruplets.
1365
1366 \sa setColorCount(), {QImage#Image Information}{Image Information}
1367*/
1368int QImage::colorCount() const
1369{
1370 return d ? d->colortable.size() : 0;
1371}
1372
1373/*!
1374 Sets the color table used to translate color indexes to QRgb
1375 values, to the specified \a colors.
1376
1377 When the image is used, the color table must be large enough to
1378 have entries for all the pixel/index values present in the image,
1379 otherwise the results are undefined.
1380
1381 \sa colorTable(), setColor(), {QImage#Image Transformations}{Image
1382 Transformations}
1383*/
1384void QImage::setColorTable(const QList<QRgb> &colors)
1385{
1386 if (!d)
1387 return;
1388 detach();
1389
1390 // In case detach() ran out of memory
1391 if (!d)
1392 return;
1393
1394 d->colortable = colors;
1395 d->has_alpha_clut = false;
1396 for (int i = 0; i < d->colortable.size(); ++i) {
1397 if (qAlpha(d->colortable.at(i)) != 255) {
1398 d->has_alpha_clut = true;
1399 break;
1400 }
1401 }
1402}
1403
1404/*!
1405 Returns a list of the colors contained in the image's color table,
1406 or an empty list if the image does not have a color table
1407
1408 \sa setColorTable(), colorCount(), color()
1409*/
1410QList<QRgb> QImage::colorTable() const
1411{
1412 return d ? d->colortable : QList<QRgb>();
1413}
1414
1415/*!
1416 Returns the device pixel ratio for the image. This is the
1417 ratio between \e{device pixels} and \e{device independent pixels}.
1418
1419 Use this function when calculating layout geometry based on
1420 the image size: QSize layoutSize = image.size() / image.devicePixelRatio()
1421
1422 The default value is 1.0.
1423
1424 \sa setDevicePixelRatio(), QImageReader
1425*/
1426qreal QImage::devicePixelRatio() const
1427{
1428 if (!d)
1429 return 1.0;
1430 return d->devicePixelRatio;
1431}
1432
1433/*!
1434 Sets the device pixel ratio for the image. This is the
1435 ratio between image pixels and device-independent pixels.
1436
1437 The default \a scaleFactor is 1.0. Setting it to something else has
1438 two effects:
1439
1440 QPainters that are opened on the image will be scaled. For
1441 example, painting on a 200x200 image if with a ratio of 2.0
1442 will result in effective (device-independent) painting bounds
1443 of 100x100.
1444
1445 Code paths in Qt that calculate layout geometry based on the
1446 image size will take the ratio into account:
1447 QSize layoutSize = image.size() / image.devicePixelRatio()
1448 The net effect of this is that the image is displayed as
1449 high-DPI image rather than a large image
1450 (see \l{Drawing High Resolution Versions of Pixmaps and Images}).
1451
1452 \sa devicePixelRatio()
1453*/
1454void QImage::setDevicePixelRatio(qreal scaleFactor)
1455{
1456 if (!d)
1457 return;
1458
1459 if (scaleFactor == d->devicePixelRatio)
1460 return;
1461
1462 detach();
1463 if (d)
1464 d->devicePixelRatio = scaleFactor;
1465}
1466
1467/*!
1468 \since 5.10
1469 Returns the image data size in bytes.
1470
1471 \sa bytesPerLine(), bits(), {QImage#Image Information}{Image
1472 Information}
1473*/
1474qsizetype QImage::sizeInBytes() const
1475{
1476 return d ? d->nbytes : 0;
1477}
1478
1479/*!
1480 Returns the number of bytes per image scanline.
1481
1482 This is equivalent to sizeInBytes() / height() if height() is non-zero.
1483
1484 \sa scanLine()
1485*/
1486qsizetype QImage::bytesPerLine() const
1487{
1488 return d ? d->bytes_per_line : 0;
1489}
1490
1491
1492/*!
1493 Returns the color in the color table at index \a i. The first
1494 color is at index 0.
1495
1496 The colors in an image's color table are specified as ARGB
1497 quadruplets (QRgb). Use the qAlpha(), qRed(), qGreen(), and
1498 qBlue() functions to get the color value components.
1499
1500 \sa setColor(), pixelIndex(), {QImage#Pixel Manipulation}{Pixel
1501 Manipulation}
1502*/
1503QRgb QImage::color(int i) const
1504{
1505 Q_ASSERT(i < colorCount());
1506 return d ? d->colortable.at(i) : QRgb(uint(-1));
1507}
1508
1509/*!
1510 \fn void QImage::setColor(int index, QRgb colorValue)
1511
1512 Sets the color at the given \a index in the color table, to the
1513 given to \a colorValue. The color value is an ARGB quadruplet.
1514
1515 If \a index is outside the current size of the color table, it is
1516 expanded with setColorCount().
1517
1518 \sa color(), colorCount(), setColorTable(), {QImage#Pixel Manipulation}{Pixel
1519 Manipulation}
1520*/
1521void QImage::setColor(int i, QRgb c)
1522{
1523 if (!d)
1524 return;
1525 if (i < 0 || d->depth > 8 || i >= 1<<d->depth) {
1526 qWarning("QImage::setColor: Index out of bound %d", i);
1527 return;
1528 }
1529 detach();
1530
1531 // In case detach() run out of memory
1532 if (!d)
1533 return;
1534
1535 if (i >= d->colortable.size())
1536 setColorCount(i+1);
1537 d->colortable[i] = c;
1538 d->has_alpha_clut |= (qAlpha(c) != 255);
1539}
1540
1541/*!
1542 Returns a pointer to the pixel data at the scanline with index \a
1543 i. The first scanline is at index 0.
1544
1545 The scanline data is as minimum 32-bit aligned. For 64-bit formats
1546 it follows the native alignment of 64-bit integers (64-bit for most
1547 platforms, but notably 32-bit on i386).
1548
1549 For example, to remove the green component of each pixel in an image:
1550
1551 \snippet code/src_gui_image_qimage.cpp scanLine
1552
1553 \warning If you are accessing 32-bpp image data, cast the returned
1554 pointer to \c{QRgb*} (QRgb has a 32-bit size) and use it to
1555 read/write the pixel value. You cannot use the \c{uchar*} pointer
1556 directly, because the pixel format depends on the byte order on
1557 the underlying platform. Use qRed(), qGreen(), qBlue(), and
1558 qAlpha() to access the pixels.
1559
1560 \sa bytesPerLine(), bits(), {QImage#Pixel Manipulation}{Pixel
1561 Manipulation}, constScanLine()
1562*/
1563uchar *QImage::scanLine(int i)
1564{
1565 if (!d)
1566 return nullptr;
1567
1568 detach();
1569
1570 // In case detach() ran out of memory
1571 if (!d)
1572 return nullptr;
1573
1574 return d->data + i * d->bytes_per_line;
1575}
1576
1577/*!
1578 \overload
1579*/
1580const uchar *QImage::scanLine(int i) const
1581{
1582 if (!d)
1583 return nullptr;
1584
1585 Q_ASSERT(i >= 0 && i < height());
1586 return d->data + i * d->bytes_per_line;
1587}
1588
1589
1590/*!
1591 Returns a pointer to the pixel data at the scanline with index \a
1592 i. The first scanline is at index 0.
1593
1594 The scanline data is as minimum 32-bit aligned. For 64-bit formats
1595 it follows the native alignment of 64-bit integers (64-bit for most
1596 platforms, but notably 32-bit on i386).
1597
1598 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1599 sharing}, but this function does \e not perform a deep copy of the
1600 shared pixel data, because the returned data is const.
1601
1602 \sa scanLine(), constBits()
1603 \since 4.7
1604*/
1605const uchar *QImage::constScanLine(int i) const
1606{
1607 if (!d)
1608 return nullptr;
1609
1610 Q_ASSERT(i >= 0 && i < height());
1611 return d->data + i * d->bytes_per_line;
1612}
1613
1614/*!
1615 Returns a pointer to the first pixel data. This is equivalent to
1616 scanLine(0).
1617
1618 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1619 sharing}. This function performs a deep copy of the shared pixel
1620 data, thus ensuring that this QImage is the only one using the
1621 current return value.
1622
1623 \sa scanLine(), sizeInBytes(), constBits()
1624*/
1625uchar *QImage::bits()
1626{
1627 if (!d)
1628 return nullptr;
1629 detach();
1630
1631 // In case detach ran out of memory...
1632 if (!d)
1633 return nullptr;
1634
1635 return d->data;
1636}
1637
1638/*!
1639 \overload
1640
1641 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1642 sharing}, but this function does \e not perform a deep copy of the
1643 shared pixel data, because the returned data is const.
1644*/
1645const uchar *QImage::bits() const
1646{
1647 return d ? d->data : nullptr;
1648}
1649
1650
1651/*!
1652 Returns a pointer to the first pixel data.
1653
1654 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1655 sharing}, but this function does \e not perform a deep copy of the
1656 shared pixel data, because the returned data is const.
1657
1658 \sa bits(), constScanLine()
1659 \since 4.7
1660*/
1661const uchar *QImage::constBits() const
1662{
1663 return d ? d->data : nullptr;
1664}
1665
1666/*!
1667 \fn void QImage::fill(uint pixelValue)
1668
1669 Fills the entire image with the given \a pixelValue.
1670
1671 If the depth of this image is 1, only the lowest bit is used. If
1672 you say fill(0), fill(2), etc., the image is filled with 0s. If
1673 you say fill(1), fill(3), etc., the image is filled with 1s. If
1674 the depth is 8, the lowest 8 bits are used and if the depth is 16
1675 the lowest 16 bits are used.
1676
1677 Note: QImage::pixel() returns the color of the pixel at the given
1678 coordinates while QColor::pixel() returns the pixel value of the
1679 underlying window system (essentially an index value), so normally
1680 you will want to use QImage::pixel() to use a color from an
1681 existing image or QColor::rgb() to use a specific color.
1682
1683 \sa depth(), {QImage#Image Transformations}{Image Transformations}
1684*/
1685
1686void QImage::fill(uint pixel)
1687{
1688 if (!d)
1689 return;
1690
1691 detach();
1692
1693 // In case detach() ran out of memory
1694 if (!d)
1695 return;
1696
1697 if (d->depth == 1 || d->depth == 8) {
1698 int w = d->width;
1699 if (d->depth == 1) {
1700 if (pixel & 1)
1701 pixel = 0xffffffff;
1702 else
1703 pixel = 0;
1704 w = (w + 7) / 8;
1705 } else {
1706 pixel &= 0xff;
1707 }
1708 qt_rectfill<quint8>(d->data, pixel, 0, 0,
1709 w, d->height, d->bytes_per_line);
1710 return;
1711 } else if (d->depth == 16) {
1712 qt_rectfill<quint16>(reinterpret_cast<quint16*>(d->data), pixel,
1713 0, 0, d->width, d->height, d->bytes_per_line);
1714 return;
1715 } else if (d->depth == 24) {
1716 qt_rectfill<quint24>(reinterpret_cast<quint24*>(d->data), pixel,
1717 0, 0, d->width, d->height, d->bytes_per_line);
1718 return;
1719 } else if (d->depth == 64) {
1720 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), QRgba64::fromArgb32(pixel),
1721 0, 0, d->width, d->height, d->bytes_per_line);
1722 return;
1723 }
1724
1725 if (d->format == Format_RGB32)
1726 pixel |= 0xff000000;
1727 if (d->format == Format_RGBX8888)
1728#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
1729 pixel |= 0xff000000;
1730#else
1731 pixel |= 0x000000ff;
1732#endif
1733 if (d->format == Format_BGR30 || d->format == Format_RGB30)
1734 pixel |= 0xc0000000;
1735
1736 qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
1737 0, 0, d->width, d->height, d->bytes_per_line);
1738}
1739
1740
1741/*!
1742 \fn void QImage::fill(Qt::GlobalColor color)
1743 \overload
1744 \since 4.8
1745
1746 Fills the image with the given \a color, described as a standard global
1747 color.
1748 */
1749
1750void QImage::fill(Qt::GlobalColor color)
1751{
1752 fill(QColor(color));
1753}
1754
1755
1756
1757/*!
1758 \fn void QImage::fill(const QColor &color)
1759
1760 \overload
1761
1762 Fills the entire image with the given \a color.
1763
1764 If the depth of the image is 1, the image will be filled with 1 if
1765 \a color equals Qt::color1; it will otherwise be filled with 0.
1766
1767 If the depth of the image is 8, the image will be filled with the
1768 index corresponding the \a color in the color table if present; it
1769 will otherwise be filled with 0.
1770
1771 \since 4.8
1772*/
1773
1774void QImage::fill(const QColor &color)
1775{
1776 if (!d)
1777 return;
1778 detach();
1779
1780 // In case we run out of memory
1781 if (!d)
1782 return;
1783
1784 switch (d->format) {
1785 case QImage::Format_RGB32:
1786 case QImage::Format_ARGB32:
1787 fill(color.rgba());
1788 break;
1789 case QImage::Format_ARGB32_Premultiplied:
1790 fill(qPremultiply(color.rgba()));
1791 break;
1792 case QImage::Format_RGBX8888:
1793 fill(ARGB2RGBA(color.rgba() | 0xff000000));
1794 break;
1795 case QImage::Format_RGBA8888:
1796 fill(ARGB2RGBA(color.rgba()));
1797 break;
1798 case QImage::Format_RGBA8888_Premultiplied:
1799 fill(ARGB2RGBA(qPremultiply(color.rgba())));
1800 break;
1801 case QImage::Format_BGR30:
1802 case QImage::Format_A2BGR30_Premultiplied:
1803 fill(qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64()));
1804 break;
1805 case QImage::Format_RGB30:
1806 case QImage::Format_A2RGB30_Premultiplied:
1807 fill(qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()));
1808 break;
1809 case QImage::Format_RGB16:
1810 fill((uint) qConvertRgb32To16(color.rgba()));
1811 break;
1812 case QImage::Format_Indexed8: {
1813 uint pixel = 0;
1814 for (int i=0; i<d->colortable.size(); ++i) {
1815 if (color.rgba() == d->colortable.at(i)) {
1816 pixel = i;
1817 break;
1818 }
1819 }
1820 fill(pixel);
1821 break;
1822 }
1823 case QImage::Format_Mono:
1824 case QImage::Format_MonoLSB:
1825 if (color == Qt::color1)
1826 fill((uint) 1);
1827 else
1828 fill((uint) 0);
1829 break;
1830 case QImage::Format_RGBX64: {
1831 QRgba64 c = color.rgba64();
1832 c.setAlpha(65535);
1833 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), c,
1834 0, 0, d->width, d->height, d->bytes_per_line);
1835 break;
1836
1837 }
1838 case QImage::Format_RGBA64:
1839 case QImage::Format_RGBA64_Premultiplied:
1840 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(),
1841 0, 0, d->width, d->height, d->bytes_per_line);
1842 break;
1843 default: {
1844 QPainter p(this);
1845 p.setCompositionMode(QPainter::CompositionMode_Source);
1846 p.fillRect(rect(), color);
1847 }}
1848}
1849
1850
1851
1852/*!
1853 Inverts all pixel values in the image.
1854
1855 The given invert \a mode only have a meaning when the image's
1856 depth is 32. The default \a mode is InvertRgb, which leaves the
1857 alpha channel unchanged. If the \a mode is InvertRgba, the alpha
1858 bits are also inverted.
1859
1860 Inverting an 8-bit image means to replace all pixels using color
1861 index \e i with a pixel using color index 255 minus \e i. The same
1862 is the case for a 1-bit image. Note that the color table is \e not
1863 changed.
1864
1865 If the image has a premultiplied alpha channel, the image is first
1866 converted to an unpremultiplied image format to be inverted and
1867 then converted back.
1868
1869 \sa {QImage#Image Transformations}{Image Transformations}
1870*/
1871
1872void QImage::invertPixels(InvertMode mode)
1873{
1874 if (!d)
1875 return;
1876
1877 detach();
1878
1879 // In case detach() ran out of memory
1880 if (!d)
1881 return;
1882
1883 QImage::Format originalFormat = d->format;
1884 // Inverting premultiplied pixels would produce invalid image data.
1885 if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied) {
1886 if (depth() > 32) {
1887 if (!d->convertInPlace(QImage::Format_RGBA64, { }))
1888 *this = convertToFormat(QImage::Format_RGBA64);
1889 } else {
1890 if (!d->convertInPlace(QImage::Format_ARGB32, { }))
1891 *this = convertToFormat(QImage::Format_ARGB32);
1892 }
1893 }
1894
1895 if (depth() < 32) {
1896 // This assumes no alpha-channel as the only formats with non-premultipled alpha are 32bit.
1897 qsizetype bpl = (qsizetype(d->width) * d->depth + 7) / 8;
1898 int pad = d->bytes_per_line - bpl;
1899 uchar *sl = d->data;
1900 for (int y=0; y<d->height; ++y) {
1901 for (qsizetype x=0; x<bpl; ++x)
1902 *sl++ ^= 0xff;
1903 sl += pad;
1904 }
1905 }
1906 else if (depth() == 64) {
1907 quint16 *p = (quint16*)d->data;
1908 quint16 *end = (quint16*)(d->data + d->nbytes);
1909 quint16 xorbits = 0xffff;
1910 while (p < end) {
1911 *p++ ^= xorbits;
1912 *p++ ^= xorbits;
1913 *p++ ^= xorbits;
1914 if (mode == InvertRgba)
1915 *p++ ^= xorbits;
1916 else
1917 p++;
1918 }
1919 } else {
1920 quint32 *p = (quint32*)d->data;
1921 quint32 *end = (quint32*)(d->data + d->nbytes);
1922 quint32 xorbits = 0xffffffff;
1923 switch (d->format) {
1924 case QImage::Format_RGBA8888:
1925 if (mode == InvertRgba)
1926 break;
1927 Q_FALLTHROUGH();
1928 case QImage::Format_RGBX8888:
1929#if Q_BYTE_ORDER == Q_BIG_ENDIAN
1930 xorbits = 0xffffff00;
1931 break;
1932#else
1933 xorbits = 0x00ffffff;
1934 break;
1935#endif
1936 case QImage::Format_ARGB32:
1937 if (mode == InvertRgba)
1938 break;
1939 Q_FALLTHROUGH();
1940 case QImage::Format_RGB32:
1941 xorbits = 0x00ffffff;
1942 break;
1943 case QImage::Format_BGR30:
1944 case QImage::Format_RGB30:
1945 xorbits = 0x3fffffff;
1946 break;
1947 default:
1948 Q_UNREACHABLE();
1949 xorbits = 0;
1950 break;
1951 }
1952 while (p < end)
1953 *p++ ^= xorbits;
1954 }
1955
1956 if (originalFormat != d->format) {
1957 if (!d->convertInPlace(originalFormat, { }))
1958 *this = convertToFormat(originalFormat);
1959 }
1960}
1961
1962// Windows defines these
1963#if defined(write)
1964# undef write
1965#endif
1966#if defined(close)
1967# undef close
1968#endif
1969#if defined(read)
1970# undef read
1971#endif
1972
1973/*!
1974 \since 4.6
1975 Resizes the color table to contain \a colorCount entries.
1976
1977 If the color table is expanded, all the extra colors will be set to
1978 transparent (i.e qRgba(0, 0, 0, 0)).
1979
1980 When the image is used, the color table must be large enough to
1981 have entries for all the pixel/index values present in the image,
1982 otherwise the results are undefined.
1983
1984 \sa colorCount(), colorTable(), setColor(), {QImage#Image
1985 Transformations}{Image Transformations}
1986*/
1987
1988void QImage::setColorCount(int colorCount)
1989{
1990 if (!d) {
1991 qWarning("QImage::setColorCount: null image");
1992 return;
1993 }
1994
1995 detach();
1996
1997 // In case detach() ran out of memory
1998 if (!d)
1999 return;
2000
2001 if (colorCount == d->colortable.size())
2002 return;
2003 if (colorCount <= 0) { // use no color table
2004 d->colortable.clear();
2005 return;
2006 }
2007 int nc = d->colortable.size();
2008 d->colortable.resize(colorCount);
2009 for (int i = nc; i < colorCount; ++i)
2010 d->colortable[i] = 0;
2011}
2012
2013/*!
2014 Returns the format of the image.
2015
2016 \sa {QImage#Image Formats}{Image Formats}
2017*/
2018QImage::Format QImage::format() const
2019{
2020 return d ? d->format : Format_Invalid;
2021}
2022
2023/*!
2024 \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const &
2025 \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) &&
2026
2027 Returns a copy of the image in the given \a format.
2028
2029 The specified image conversion \a flags control how the image data
2030 is handled during the conversion process.
2031
2032 \sa convertTo(), {Image Formats}
2033*/
2034
2035/*!
2036 \fn QImage QImage::convertedTo(Format format, Qt::ImageConversionFlags flags) const &
2037 \fn QImage QImage::convertedTo(Format format, Qt::ImageConversionFlags flags) &&
2038 \since 6.0
2039
2040 Returns a copy of the image in the given \a format.
2041
2042 The specified image conversion \a flags control how the image data
2043 is handled during the conversion process.
2044
2045 \sa convertTo(), {Image Formats}
2046*/
2047
2048/*!
2049 \internal
2050*/
2051QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const
2052{
2053 if (!d || d->format == format)
2054 return *this;
2055
2056 if (format == Format_Invalid || d->format == Format_Invalid)
2057 return QImage();
2058
2059 const QPixelLayout *destLayout = &qPixelLayouts[format];
2060 Image_Converter converter = qimage_converter_map[d->format][format];
2061 if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) {
2062 if (qt_highColorPrecision(d->format, !destLayout->hasAlphaChannel)
2063 && qt_highColorPrecision(format, !hasAlphaChannel())) {
2064 converter = convert_generic_over_rgb64;
2065 } else
2066 converter = convert_generic;
2067 }
2068 if (converter) {
2069 QImage image(d->width, d->height, format);
2070
2071 QIMAGE_SANITYCHECK_MEMORY(image);
2072
2073 image.d->offset = offset();
2074 copyMetadata(image.d, d);
2075
2076 converter(image.d, d, flags);
2077 return image;
2078 }
2079
2080 // Convert indexed formats over ARGB32 or RGB32 to the final format.
2081 Q_ASSERT(format != QImage::Format_ARGB32 && format != QImage::Format_RGB32);
2082 Q_ASSERT(d->format != QImage::Format_ARGB32 && d->format != QImage::Format_RGB32);
2083
2084 if (!hasAlphaChannel())
2085 return convertToFormat(Format_RGB32, flags).convertToFormat(format, flags);
2086
2087 return convertToFormat(Format_ARGB32, flags).convertToFormat(format, flags);
2088}
2089
2090/*!
2091 \internal
2092*/
2093bool QImage::convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags)
2094{
2095 return d && d->convertInPlace(format, flags);
2096}
2097
2098static inline int pixel_distance(QRgb p1, QRgb p2) {
2099 int r1 = qRed(p1);
2100 int g1 = qGreen(p1);
2101 int b1 = qBlue(p1);
2102 int a1 = qAlpha(p1);
2103
2104 int r2 = qRed(p2);
2105 int g2 = qGreen(p2);
2106 int b2 = qBlue(p2);
2107 int a2 = qAlpha(p2);
2108
2109 return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) + abs(a1 - a2);
2110}
2111
2112static inline int closestMatch(QRgb pixel, const QList<QRgb> &clut) {
2113 int idx = 0;
2114 int current_distance = INT_MAX;
2115 for (int i=0; i<clut.size(); ++i) {
2116 int dist = pixel_distance(pixel, clut.at(i));
2117 if (dist < current_distance) {
2118 current_distance = dist;
2119 idx = i;
2120 }
2121 }
2122 return idx;
2123}
2124
2125static QImage convertWithPalette(const QImage &src, QImage::Format format,
2126 const QList<QRgb> &clut) {
2127 QImage dest(src.size(), format);
2128 dest.setColorTable(clut);
2129
2130 QImageData::get(dest)->text = QImageData::get(src)->text;
2131
2132 int h = src.height();
2133 int w = src.width();
2134
2135 QHash<QRgb, int> cache;
2136
2137 if (format == QImage::Format_Indexed8) {
2138 for (int y=0; y<h; ++y) {
2139 const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
2140 uchar *dest_pixels = (uchar *) dest.scanLine(y);
2141 for (int x=0; x<w; ++x) {
2142 int src_pixel = src_pixels[x];
2143 int value = cache.value(src_pixel, -1);
2144 if (value == -1) {
2145 value = closestMatch(src_pixel, clut);
2146 cache.insert(src_pixel, value);
2147 }
2148 dest_pixels[x] = (uchar) value;
2149 }
2150 }
2151 } else {
2152 QList<QRgb> table = clut;
2153 table.resize(2);
2154 for (int y=0; y<h; ++y) {
2155 const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
2156 for (int x=0; x<w; ++x) {
2157 int src_pixel = src_pixels[x];
2158 int value = cache.value(src_pixel, -1);
2159 if (value == -1) {
2160 value = closestMatch(src_pixel, table);
2161 cache.insert(src_pixel, value);
2162 }
2163 dest.setPixel(x, y, value);
2164 }
2165 }
2166 }
2167
2168 return dest;
2169}
2170
2171/*!
2172 \overload
2173
2174 Returns a copy of the image converted to the given \a format,
2175 using the specified \a colorTable.
2176
2177 Conversion from RGB formats to indexed formats is a slow operation
2178 and will use a straightforward nearest color approach, with no
2179 dithering.
2180*/
2181QImage QImage::convertToFormat(Format format, const QList<QRgb> &colorTable, Qt::ImageConversionFlags flags) const
2182{
2183 if (!d || d->format == format)
2184 return *this;
2185
2186 if (format == QImage::Format_Invalid)
2187 return QImage();
2188 if (format <= QImage::Format_Indexed8)
2189 return convertWithPalette(convertToFormat(QImage::Format_ARGB32, flags), format, colorTable);
2190
2191 return convertToFormat(format, flags);
2192}
2193
2194/*!
2195 \since 5.9
2196
2197 Changes the format of the image to \a format without changing the
2198 data. Only works between formats of the same depth.
2199
2200 Returns \c true if successful.
2201
2202 This function can be used to change images with alpha-channels to
2203 their corresponding opaque formats if the data is known to be opaque-only,
2204 or to change the format of a given image buffer before overwriting
2205 it with new data.
2206
2207 \warning The function does not check if the image data is valid in the
2208 new format and will still return \c true if the depths are compatible.
2209 Operations on an image with invalid data are undefined.
2210
2211 \warning If the image is not detached, this will cause the data to be
2212 copied.
2213
2214 \sa hasAlphaChannel(), convertToFormat()
2215*/
2216
2217bool QImage::reinterpretAsFormat(Format format)
2218{
2219 if (!d)
2220 return false;
2221 if (d->format == format)
2222 return true;
2223 if (qt_depthForFormat(format) != qt_depthForFormat(d->format))
2224 return false;
2225 if (!isDetached()) { // Detach only if shared, not for read-only data.
2226 QImageData *oldD = d;
2227 detach();
2228 // In case detach() ran out of memory
2229 if (!d) {
2230 d = oldD;
2231 return false;
2232 }
2233 }
2234
2235 d->format = format;
2236 return true;
2237}
2238
2239/*!
2240 \since 5.13
2241
2242 Detach and convert the image to the given \a format in place.
2243
2244 The specified image conversion \a flags control how the image data
2245 is handled during the conversion process.
2246
2247 \sa convertedTo()
2248*/
2249
2250void QImage::convertTo(Format format, Qt::ImageConversionFlags flags)
2251{
2252 if (!d || format == QImage::Format_Invalid)
2253 return;
2254
2255 detach();
2256 if (convertToFormat_inplace(format, flags))
2257 return;
2258
2259 *this = convertToFormat_helper(format, flags);
2260}
2261
2262/*!
2263 \fn bool QImage::valid(const QPoint &pos) const
2264
2265 Returns \c true if \a pos is a valid coordinate pair within the
2266 image; otherwise returns \c false.
2267
2268 \sa rect(), QRect::contains()
2269*/
2270
2271/*!
2272 \overload
2273
2274 Returns \c true if QPoint(\a x, \a y) is a valid coordinate pair
2275 within the image; otherwise returns \c false.
2276*/
2277bool QImage::valid(int x, int y) const
2278{
2279 return d
2280 && x >= 0 && x < d->width
2281 && y >= 0 && y < d->height;
2282}
2283
2284/*!
2285 \fn int QImage::pixelIndex(const QPoint &position) const
2286
2287 Returns the pixel index at the given \a position.
2288
2289 If \a position is not valid, or if the image is not a paletted
2290 image (depth() > 8), the results are undefined.
2291
2292 \sa valid(), depth(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2293*/
2294
2295/*!
2296 \overload
2297
2298 Returns the pixel index at (\a x, \a y).
2299*/
2300int QImage::pixelIndex(int x, int y) const
2301{
2302 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
2303 qWarning("QImage::pixelIndex: coordinate (%d,%d) out of range", x, y);
2304 return -12345;
2305 }
2306 const uchar * s = scanLine(y);
2307 switch(d->format) {
2308 case Format_Mono:
2309 return (*(s + (x >> 3)) >> (7- (x & 7))) & 1;
2310 case Format_MonoLSB:
2311 return (*(s + (x >> 3)) >> (x & 7)) & 1;
2312 case Format_Indexed8:
2313 return (int)s[x];
2314 default:
2315 qWarning("QImage::pixelIndex: Not applicable for %d-bpp images (no palette)", d->depth);
2316 }
2317 return 0;
2318}
2319
2320
2321/*!
2322 \fn QRgb QImage::pixel(const QPoint &position) const
2323
2324 Returns the color of the pixel at the given \a position.
2325
2326 If the \a position is not valid, the results are undefined.
2327
2328 \warning This function is expensive when used for massive pixel
2329 manipulations. Use constBits() or constScanLine() when many
2330 pixels needs to be read.
2331
2332 \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
2333 Manipulation}
2334*/
2335
2336/*!
2337 \overload
2338
2339 Returns the color of the pixel at coordinates (\a x, \a y).
2340*/
2341QRgb QImage::pixel(int x, int y) const
2342{
2343 if (!d || x < 0 || x >= d->width || y < 0 || y >= d->height) {
2344 qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
2345 return 12345;
2346 }
2347
2348 const uchar *s = d->data + y * d->bytes_per_line;
2349
2350 int index = -1;
2351 switch (d->format) {
2352 case Format_Mono:
2353 index = (*(s + (x >> 3)) >> (~x & 7)) & 1;
2354 break;
2355 case Format_MonoLSB:
2356 index = (*(s + (x >> 3)) >> (x & 7)) & 1;
2357 break;
2358 case Format_Indexed8:
2359 index = s[x];
2360 break;
2361 default:
2362 break;
2363 }
2364 if (index >= 0) { // Indexed format
2365 if (index >= d->colortable.size()) {
2366 qWarning("QImage::pixel: color table index %d out of range.", index);
2367 return 0;
2368 }
2369 return d->colortable.at(index);
2370 }
2371
2372 switch (d->format) {
2373 case Format_RGB32:
2374 return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
2375 case Format_ARGB32: // Keep old behaviour.
2376 case Format_ARGB32_Premultiplied:
2377 return reinterpret_cast<const QRgb *>(s)[x];
2378 case Format_RGBX8888:
2379 case Format_RGBA8888: // Match ARGB32 behavior.
2380 case Format_RGBA8888_Premultiplied:
2381 return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]);
2382 case Format_BGR30:
2383 case Format_A2BGR30_Premultiplied:
2384 return qConvertA2rgb30ToArgb32<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
2385 case Format_RGB30:
2386 case Format_A2RGB30_Premultiplied:
2387 return qConvertA2rgb30ToArgb32<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
2388 case Format_RGB16:
2389 return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
2390 case Format_RGBX64:
2391 case Format_RGBA64: // Match ARGB32 behavior.
2392 case Format_RGBA64_Premultiplied:
2393 return reinterpret_cast<const QRgba64 *>(s)[x].toArgb32();
2394 default:
2395 break;
2396 }
2397 const QPixelLayout *layout = &qPixelLayouts[d->format];
2398 uint result;
2399 return *layout->fetchToARGB32PM(&result, s, x, 1, nullptr, nullptr);
2400}
2401
2402/*!
2403 \fn void QImage::setPixel(const QPoint &position, uint index_or_rgb)
2404
2405 Sets the pixel index or color at the given \a position to \a
2406 index_or_rgb.
2407
2408 If the image's format is either monochrome or paletted, the given \a
2409 index_or_rgb value must be an index in the image's color table,
2410 otherwise the parameter must be a QRgb value.
2411
2412 If \a position is not a valid coordinate pair in the image, or if
2413 \a index_or_rgb >= colorCount() in the case of monochrome and
2414 paletted images, the result is undefined.
2415
2416 \warning This function is expensive due to the call of the internal
2417 \c{detach()} function called within; if performance is a concern, we
2418 recommend the use of scanLine() or bits() to access pixel data directly.
2419
2420 \sa pixel(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2421*/
2422
2423/*!
2424 \overload
2425
2426 Sets the pixel index or color at (\a x, \a y) to \a index_or_rgb.
2427*/
2428void QImage::setPixel(int x, int y, uint index_or_rgb)
2429{
2430 if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
2431 qWarning("QImage::setPixel: coordinate (%d,%d) out of range", x, y);
2432 return;
2433 }
2434 // detach is called from within scanLine
2435 uchar * s = scanLine(y);
2436 switch(d->format) {
2437 case Format_Mono:
2438 case Format_MonoLSB:
2439 if (index_or_rgb > 1) {
2440 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
2441 } else if (format() == Format_MonoLSB) {
2442 if (index_or_rgb==0)
2443 *(s + (x >> 3)) &= ~(1 << (x & 7));
2444 else
2445 *(s + (x >> 3)) |= (1 << (x & 7));
2446 } else {
2447 if (index_or_rgb==0)
2448 *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
2449 else
2450 *(s + (x >> 3)) |= (1 << (7-(x & 7)));
2451 }
2452 return;
2453 case Format_Indexed8:
2454 if (index_or_rgb >= (uint)d->colortable.size()) {
2455 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
2456 return;
2457 }
2458 s[x] = index_or_rgb;
2459 return;
2460 case Format_RGB32:
2461 //make sure alpha is 255, we depend on it in qdrawhelper for cases
2462 // when image is set as a texture pattern on a qbrush
2463 ((uint *)s)[x] = 0xff000000 | index_or_rgb;
2464 return;
2465 case Format_ARGB32:
2466 case Format_ARGB32_Premultiplied:
2467 ((uint *)s)[x] = index_or_rgb;
2468 return;
2469 case Format_RGB16:
2470 ((quint16 *)s)[x] = qConvertRgb32To16(qUnpremultiply(index_or_rgb));
2471 return;
2472 case Format_RGBX8888:
2473 ((uint *)s)[x] = ARGB2RGBA(0xff000000 | index_or_rgb);
2474 return;
2475 case Format_RGBA8888:
2476 case Format_RGBA8888_Premultiplied:
2477 ((uint *)s)[x] = ARGB2RGBA(index_or_rgb);
2478 return;
2479 case Format_BGR30:
2480 ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderBGR>(index_or_rgb);
2481 return;
2482 case Format_A2BGR30_Premultiplied:
2483 ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderBGR>(index_or_rgb);
2484 return;
2485 case Format_RGB30:
2486 ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderRGB>(index_or_rgb);
2487 return;
2488 case Format_A2RGB30_Premultiplied:
2489 ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderRGB>(index_or_rgb);
2490 return;
2491 case Format_Invalid:
2492 case NImageFormats:
2493 Q_ASSERT(false);
2494 return;
2495 default:
2496 break;
2497 }
2498
2499 const QPixelLayout *layout = &qPixelLayouts[d->format];
2500 layout->storeFromARGB32PM(s, &index_or_rgb, x, 1, nullptr, nullptr);
2501}
2502
2503/*!
2504 \fn QColor QImage::pixelColor(const QPoint &position) const
2505 \since 5.6
2506
2507 Returns the color of the pixel at the given \a position as a QColor.
2508
2509 If the \a position is not valid, an invalid QColor is returned.
2510
2511 \warning This function is expensive when used for massive pixel
2512 manipulations. Use constBits() or constScanLine() when many
2513 pixels needs to be read.
2514
2515 \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
2516 Manipulation}
2517*/
2518
2519/*!
2520 \overload
2521 \since 5.6
2522
2523 Returns the color of the pixel at coordinates (\a x, \a y) as a QColor.
2524*/
2525QColor QImage::pixelColor(int x, int y) const
2526{
2527 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
2528 qWarning("QImage::pixelColor: coordinate (%d,%d) out of range", x, y);
2529 return QColor();
2530 }
2531
2532 QRgba64 c;
2533 const uchar * s = constScanLine(y);
2534 switch (d->format) {
2535 case Format_BGR30:
2536 case Format_A2BGR30_Premultiplied:
2537 c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
2538 break;
2539 case Format_RGB30:
2540 case Format_A2RGB30_Premultiplied:
2541 c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
2542 break;
2543 case Format_RGBX64:
2544 case Format_RGBA64:
2545 case Format_RGBA64_Premultiplied:
2546 c = reinterpret_cast<const QRgba64 *>(s)[x];
2547 break;
2548 case Format_Grayscale16: {
2549 quint16 v = reinterpret_cast<const quint16 *>(s)[x];
2550 return QColor(qRgba64(v, v, v, 0xffff));
2551 }
2552 default:
2553 c = QRgba64::fromArgb32(pixel(x, y));
2554 break;
2555 }
2556 // QColor is always unpremultiplied
2557 if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
2558 c = c.unpremultiplied();
2559 return QColor(c);
2560}
2561
2562/*!
2563 \fn void QImage::setPixelColor(const QPoint &position, const QColor &color)
2564 \since 5.6
2565
2566 Sets the color at the given \a position to \a color.
2567
2568 If \a position is not a valid coordinate pair in the image, or
2569 the image's format is either monochrome or paletted, the result is undefined.
2570
2571 \warning This function is expensive due to the call of the internal
2572 \c{detach()} function called within; if performance is a concern, we
2573 recommend the use of scanLine() or bits() to access pixel data directly.
2574
2575 \sa pixel(), bits(), scanLine(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2576*/
2577
2578/*!
2579 \overload
2580 \since 5.6
2581
2582 Sets the pixel color at (\a x, \a y) to \a color.
2583*/
2584void QImage::setPixelColor(int x, int y, const QColor &color)
2585{
2586 if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
2587 qWarning("QImage::setPixelColor: coordinate (%d,%d) out of range", x, y);
2588 return;
2589 }
2590
2591 if (!color.isValid()) {
2592 qWarning("QImage::setPixelColor: color is invalid");
2593 return;
2594 }
2595
2596 // QColor is always unpremultiplied
2597 QRgba64 c = color.rgba64();
2598 if (!hasAlphaChannel())
2599 c.setAlpha(65535);
2600 else if (qPixelLayouts[d->format].premultiplied)
2601 c = c.premultiplied();
2602 // detach is called from within scanLine
2603 uchar * s = scanLine(y);
2604 switch (d->format) {
2605 case Format_Mono:
2606 case Format_MonoLSB:
2607 case Format_Indexed8:
2608 qWarning("QImage::setPixelColor: called on monochrome or indexed format");
2609 return;
2610 case Format_BGR30:
2611 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
2612 return;
2613 case Format_A2BGR30_Premultiplied:
2614 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
2615 return;
2616 case Format_RGB30:
2617 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
2618 return;
2619 case Format_A2RGB30_Premultiplied:
2620 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
2621 return;
2622 case Format_RGBX64:
2623 ((QRgba64 *)s)[x] = color.rgba64();
2624 ((QRgba64 *)s)[x].setAlpha(65535);
2625 return;
2626 case Format_RGBA64:
2627 case Format_RGBA64_Premultiplied:
2628 ((QRgba64 *)s)[x] = color.rgba64();
2629 return;
2630 default:
2631 setPixel(x, y, c.toArgb32());
2632 return;
2633 }
2634}
2635
2636/*!
2637 Returns \c true if all the colors in the image are shades of gray
2638 (i.e. their red, green and blue components are equal); otherwise
2639 false.
2640
2641 Note that this function is slow for images without color table.
2642
2643 \sa isGrayscale()
2644*/
2645bool QImage::allGray() const
2646{
2647 if (!d)
2648 return true;
2649
2650 switch (d->format) {
2651 case Format_Mono:
2652 case Format_MonoLSB:
2653 case Format_Indexed8:
2654 for (int i = 0; i < d->colortable.size(); ++i) {
2655 if (!qIsGray(d->colortable.at(i)))
2656 return false;
2657 }
2658 return true;
2659 case Format_Alpha8:
2660 return false;
2661 case Format_Grayscale8:
2662 case Format_Grayscale16:
2663 return true;
2664 case Format_RGB32:
2665 case Format_ARGB32:
2666 case Format_ARGB32_Premultiplied:
2667#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
2668 case Format_RGBX8888:
2669 case Format_RGBA8888:
2670 case Format_RGBA8888_Premultiplied:
2671#endif
2672 for (int j = 0; j < d->height; ++j) {
2673 const QRgb *b = (const QRgb *)constScanLine(j);
2674 for (int i = 0; i < d->width; ++i) {
2675 if (!qIsGray(b[i]))
2676 return false;
2677 }
2678 }
2679 return true;
2680 case Format_RGB16:
2681 for (int j = 0; j < d->height; ++j) {
2682 const quint16 *b = (const quint16 *)constScanLine(j);
2683 for (int i = 0; i < d->width; ++i) {
2684 if (!qIsGray(qConvertRgb16To32(b[i])))
2685 return false;
2686 }
2687 }
2688 return true;
2689 default:
2690 break;
2691 }
2692
2693 uint buffer[BufferSize];
2694 const QPixelLayout *layout = &qPixelLayouts[d->format];
2695 const auto fetch = layout->fetchToARGB32PM;
2696 for (int j = 0; j < d->height; ++j) {
2697 const uchar *b = constScanLine(j);
2698 int x = 0;
2699 while (x < d->width) {
2700 int l = qMin(d->width - x, BufferSize);
2701 const uint *ptr = fetch(buffer, b, x, l, nullptr, nullptr);
2702 for (int i = 0; i < l; ++i) {
2703 if (!qIsGray(ptr[i]))
2704 return false;
2705 }
2706 x += l;
2707 }
2708 }
2709 return true;
2710}
2711
2712/*!
2713 For 32-bit images, this function is equivalent to allGray().
2714
2715 For color indexed images, this function returns \c true if
2716 color(i) is QRgb(i, i, i) for all indexes of the color table;
2717 otherwise returns \c false.
2718
2719 \sa allGray(), {QImage#Image Formats}{Image Formats}
2720*/
2721bool QImage::isGrayscale() const
2722{
2723 if (!d)
2724 return false;
2725
2726 if (d->format == QImage::Format_Alpha8)
2727 return false;
2728
2729 if (d->format == QImage::Format_Grayscale8 || d->format == QImage::Format_Grayscale16)
2730 return true;
2731
2732 switch (depth()) {
2733 case 32:
2734 case 24:
2735 case 16:
2736 return allGray();
2737 case 8: {
2738 Q_ASSERT(d->format == QImage::Format_Indexed8);
2739 for (int i = 0; i < colorCount(); i++)
2740 if (d->colortable.at(i) != qRgb(i,i,i))
2741 return false;
2742 return true;
2743 }
2744 }
2745 return false;
2746}
2747
2748/*!
2749 \fn QImage QImage::scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode,
2750 Qt::TransformationMode transformMode) const
2751 \overload
2752
2753 Returns a copy of the image scaled to a rectangle with the given
2754 \a width and \a height according to the given \a aspectRatioMode
2755 and \a transformMode.
2756
2757 If either the \a width or the \a height is zero or negative, this
2758 function returns a null image.
2759*/
2760
2761/*!
2762 \fn QImage QImage::scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode,
2763 Qt::TransformationMode transformMode) const
2764
2765 Returns a copy of the image scaled to a rectangle defined by the
2766 given \a size according to the given \a aspectRatioMode and \a
2767 transformMode.
2768
2769 \image qimage-scaling.png
2770
2771 \list
2772 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the image
2773 is scaled to \a size.
2774 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the image is
2775 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
2776 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
2777 the image is scaled to a rectangle as small as possible
2778 outside \a size, preserving the aspect ratio.
2779 \endlist
2780
2781 If the given \a size is empty, this function returns a null image.
2782
2783 \sa isNull(), {QImage#Image Transformations}{Image
2784 Transformations}
2785*/
2786QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
2787{
2788 if (!d) {
2789 qWarning("QImage::scaled: Image is a null image");
2790 return QImage();
2791 }
2792 if (s.isEmpty())
2793 return QImage();
2794
2795 QSize newSize = size();
2796 newSize.scale(s, aspectMode);
2797 newSize.rwidth() = qMax(newSize.width(), 1);
2798 newSize.rheight() = qMax(newSize.height(), 1);
2799 if (newSize == size())
2800 return *this;
2801
2802 Q_TRACE_SCOPE(QImage_scaled, s, aspectMode, mode);
2803
2804 QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());
2805 QImage img = transformed(wm, mode);
2806 return img;
2807}
2808
2809/*!
2810 \fn QImage QImage::scaledToWidth(int width, Qt::TransformationMode mode) const
2811
2812 Returns a scaled copy of the image. The returned image is scaled
2813 to the given \a width using the specified transformation \a
2814 mode.
2815
2816 This function automatically calculates the height of the image so
2817 that its aspect ratio is preserved.
2818
2819 If the given \a width is 0 or negative, a null image is returned.
2820
2821 \sa {QImage#Image Transformations}{Image Transformations}
2822*/
2823QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const
2824{
2825 if (!d) {
2826 qWarning("QImage::scaleWidth: Image is a null image");
2827 return QImage();
2828 }
2829 if (w <= 0)
2830 return QImage();
2831
2832 Q_TRACE_SCOPE(QImage_scaledToWidth, w, mode);
2833
2834 qreal factor = (qreal) w / width();
2835 QTransform wm = QTransform::fromScale(factor, factor);
2836 return transformed(wm, mode);
2837}
2838
2839/*!
2840 \fn QImage QImage::scaledToHeight(int height, Qt::TransformationMode mode) const
2841
2842 Returns a scaled copy of the image. The returned image is scaled
2843 to the given \a height using the specified transformation \a
2844 mode.
2845
2846 This function automatically calculates the width of the image so that
2847 the ratio of the image is preserved.
2848
2849 If the given \a height is 0 or negative, a null image is returned.
2850
2851 \sa {QImage#Image Transformations}{Image Transformations}
2852*/
2853QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const
2854{
2855 if (!d) {
2856 qWarning("QImage::scaleHeight: Image is a null image");
2857 return QImage();
2858 }
2859 if (h <= 0)
2860 return QImage();
2861
2862 Q_TRACE_SCOPE(QImage_scaledToHeight, h, mode);
2863
2864 qreal factor = (qreal) h / height();
2865 QTransform wm = QTransform::fromScale(factor, factor);
2866 return transformed(wm, mode);
2867}
2868
2869/*!
2870 Builds and returns a 1-bpp mask from the alpha buffer in this
2871 image. Returns a null image if the image's format is
2872 QImage::Format_RGB32.
2873
2874 The \a flags argument is a bitwise-OR of the
2875 Qt::ImageConversionFlags, and controls the conversion
2876 process. Passing 0 for flags sets all the default options.
2877
2878 The returned image has little-endian bit order (i.e. the image's
2879 format is QImage::Format_MonoLSB), which you can convert to
2880 big-endian (QImage::Format_Mono) using the convertToFormat()
2881 function.
2882
2883 \sa createHeuristicMask(), {QImage#Image Transformations}{Image
2884 Transformations}
2885*/
2886QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
2887{
2888 if (!d || d->format == QImage::Format_RGB32)
2889 return QImage();
2890
2891 if (d->depth == 1) {
2892 // A monochrome pixmap, with alpha channels on those two colors.
2893 // Pretty unlikely, so use less efficient solution.
2894 return convertToFormat(Format_Indexed8, flags).createAlphaMask(flags);
2895 }
2896
2897 QImage mask(d->width, d->height, Format_MonoLSB);
2898 if (!mask.isNull()) {
2899 dither_to_Mono(mask.d, d, flags, true);
2900 copyPhysicalMetadata(mask.d, d);
2901 }
2902 return mask;
2903}
2904
2905#ifndef QT_NO_IMAGE_HEURISTIC_MASK
2906/*!
2907 Creates and returns a 1-bpp heuristic mask for this image.
2908
2909 The function works by selecting a color from one of the corners,
2910 then chipping away pixels of that color starting at all the edges.
2911 The four corners vote for which color is to be masked away. In
2912 case of a draw (this generally means that this function is not
2913 applicable to the image), the result is arbitrary.
2914
2915 The returned image has little-endian bit order (i.e. the image's
2916 format is QImage::Format_MonoLSB), which you can convert to
2917 big-endian (QImage::Format_Mono) using the convertToFormat()
2918 function.
2919
2920 If \a clipTight is true (the default) the mask is just large
2921 enough to cover the pixels; otherwise, the mask is larger than the
2922 data pixels.
2923
2924 Note that this function disregards the alpha buffer.
2925
2926 \sa createAlphaMask(), {QImage#Image Transformations}{Image
2927 Transformations}
2928*/
2929
2930QImage QImage::createHeuristicMask(bool clipTight) const
2931{
2932 if (!d)
2933 return QImage();
2934
2935 if (d->depth != 32) {
2936 QImage img32 = convertToFormat(Format_RGB32);
2937 return img32.createHeuristicMask(clipTight);
2938 }
2939
2940#define PIX(x,y) (*((const QRgb*)scanLine(y)+x) & 0x00ffffff)
2941
2942 int w = width();
2943 int h = height();
2944 QImage m(w, h, Format_MonoLSB);
2945 QIMAGE_SANITYCHECK_MEMORY(m);
2946 m.setColorCount(2);
2947 m.setColor(0, QColor(Qt::color0).rgba());
2948 m.setColor(1, QColor(Qt::color1).rgba());
2949 m.fill(0xff);
2950
2951 QRgb background = PIX(0,0);
2952 if (background != PIX(w-1,0) &&
2953 background != PIX(0,h-1) &&
2954 background != PIX(w-1,h-1)) {
2955 background = PIX(w-1,0);
2956 if (background != PIX(w-1,h-1) &&
2957 background != PIX(0,h-1) &&
2958 PIX(0,h-1) == PIX(w-1,h-1)) {
2959 background = PIX(w-1,h-1);
2960 }
2961 }
2962
2963 int x,y;
2964 bool done = false;
2965 uchar *ypp, *ypc, *ypn;
2966 while(!done) {
2967 done = true;
2968 ypn = m.scanLine(0);
2969 ypc = nullptr;
2970 for (y = 0; y < h; y++) {
2971 ypp = ypc;
2972 ypc = ypn;
2973 ypn = (y == h-1) ? nullptr : m.scanLine(y+1);
2974 const QRgb *p = (const QRgb *)scanLine(y);
2975 for (x = 0; x < w; x++) {
2976 // slowness here - it's possible to do six of these tests
2977 // together in one go. oh well.
2978 if ((x == 0 || y == 0 || x == w-1 || y == h-1 ||
2979 !(*(ypc + ((x-1) >> 3)) & (1 << ((x-1) & 7))) ||
2980 !(*(ypc + ((x+1) >> 3)) & (1 << ((x+1) & 7))) ||
2981 !(*(ypp + (x >> 3)) & (1 << (x & 7))) ||
2982 !(*(ypn + (x >> 3)) & (1 << (x & 7)))) &&
2983 ( (*(ypc + (x >> 3)) & (1 << (x & 7)))) &&
2984 ((*p & 0x00ffffff) == background)) {
2985 done = false;
2986 *(ypc + (x >> 3)) &= ~(1 << (x & 7));
2987 }
2988 p++;
2989 }
2990 }
2991 }
2992
2993 if (!clipTight) {
2994 ypn = m.scanLine(0);
2995 ypc = nullptr;
2996 for (y = 0; y < h; y++) {
2997 ypp = ypc;
2998 ypc = ypn;
2999 ypn = (y == h-1) ? nullptr : m.scanLine(y+1);
3000 const QRgb *p = (const QRgb *)scanLine(y);
3001 for (x = 0; x < w; x++) {
3002 if ((*p & 0x00ffffff) != background) {
3003 if (x > 0)
3004 *(ypc + ((x-1) >> 3)) |= (1 << ((x-1) & 7));
3005 if (x < w-1)
3006 *(ypc + ((x+1) >> 3)) |= (1 << ((x+1) & 7));
3007 if (y > 0)
3008 *(ypp + (x >> 3)) |= (1 << (x & 7));
3009 if (y < h-1)
3010 *(ypn + (x >> 3)) |= (1 << (x & 7));
3011 }
3012 p++;
3013 }
3014 }
3015 }
3016
3017#undef PIX
3018
3019 copyPhysicalMetadata(m.d, d);
3020 return m;
3021}
3022#endif //QT_NO_IMAGE_HEURISTIC_MASK
3023
3024/*!
3025 Creates and returns a mask for this image based on the given \a
3026 color value. If the \a mode is MaskInColor (the default value),
3027 all pixels matching \a color will be opaque pixels in the mask. If
3028 \a mode is MaskOutColor, all pixels matching the given color will
3029 be transparent.
3030
3031 \sa createAlphaMask(), createHeuristicMask()
3032*/
3033
3034QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
3035{
3036 if (!d)
3037 return QImage();
3038 QImage maskImage(size(), QImage::Format_MonoLSB);
3039 QIMAGE_SANITYCHECK_MEMORY(maskImage);
3040 maskImage.fill(0);
3041 uchar *s = maskImage.bits();
3042
3043 if (depth() == 32) {
3044 for (int h = 0; h < d->height; h++) {
3045 const uint *sl = (const uint *) scanLine(h);
3046 for (int w = 0; w < d->width; w++) {
3047 if (sl[w] == color)
3048 *(s + (w >> 3)) |= (1 << (w & 7));
3049 }
3050 s += maskImage.bytesPerLine();
3051 }
3052 } else {
3053 for (int h = 0; h < d->height; h++) {
3054 for (int w = 0; w < d->width; w++) {
3055 if ((uint) pixel(w, h) == color)
3056 *(s + (w >> 3)) |= (1 << (w & 7));
3057 }
3058 s += maskImage.bytesPerLine();
3059 }
3060 }
3061 if (mode == Qt::MaskOutColor)
3062 maskImage.invertPixels();
3063
3064 copyPhysicalMetadata(maskImage.d, d);
3065 return maskImage;
3066}
3067
3068/*!
3069 \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const &
3070 \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) &&
3071
3072 Returns a mirror of the image, mirrored in the horizontal and/or
3073 the vertical direction depending on whether \a horizontal and \a
3074 vertical are set to true or false.
3075
3076 Note that the original image is not changed.
3077
3078 \sa mirror(), {QImage#Image Transformations}{Image Transformations}
3079*/
3080
3081/*!
3082 \fn void QImage::mirror(bool horizontal = false, bool vertical = true)
3083 \since 6.0
3084
3085 Mirrors of the image in the horizontal and/or the vertical direction depending
3086 on whether \a horizontal and \a vertical are set to true or false.
3087
3088 \sa mirrored(), {QImage#Image Transformations}{Image Transformations}
3089*/
3090
3091template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
3092 int dstX0, int dstY0,
3093 int dstXIncr, int dstYIncr,
3094 int w, int h)
3095{
3096 if (dst == src) {
3097 // When mirroring in-place, stop in the middle for one of the directions, since we
3098 // are swapping the bytes instead of merely copying.
3099 const int srcXEnd = (dstX0 && !dstY0) ? w / 2 : w;
3100 const int srcYEnd = dstY0 ? h / 2 : h;
3101 for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) {
3102 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3103 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
3104 for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr)
3105 std::swap(srcPtr[srcX], dstPtr[dstX]);
3106 }
3107 // If mirroring both ways, the middle line needs to be mirrored horizontally only.
3108 if (dstX0 && dstY0 && (h & 1)) {
3109 int srcY = h / 2;
3110 int srcXEnd2 = w / 2;
3111 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3112 for (int srcX = 0, dstX = dstX0; srcX < srcXEnd2; ++srcX, dstX += dstXIncr)
3113 std::swap(srcPtr[srcX], srcPtr[dstX]);
3114 }
3115 } else {
3116 for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) {
3117 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3118 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
3119 for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr)
3120 dstPtr[dstX] = srcPtr[srcX];
3121 }
3122 }
3123}
3124
3125inline void do_flip(QImageData *dst, QImageData *src, int w, int h, int depth)
3126{
3127 const int data_bytes_per_line = w * (depth / 8);
3128 if (dst == src) {
3129 uint *srcPtr = reinterpret_cast<uint *>(src->data);
3130 uint *dstPtr = reinterpret_cast<uint *>(dst->data + (h - 1) * dst->bytes_per_line);
3131 h = h / 2;
3132 const int uint_per_line = (data_bytes_per_line + 3) >> 2; // bytes per line must be a multiple of 4
3133 for (int y = 0; y < h; ++y) {
3134 // This is auto-vectorized, no need for SSE2 or NEON versions:
3135 for (int x = 0; x < uint_per_line; x++) {
3136 const uint d = dstPtr[x];
3137 const uint s = srcPtr[x];
3138 dstPtr[x] = s;
3139 srcPtr[x] = d;
3140 }
3141 srcPtr += src->bytes_per_line >> 2;
3142 dstPtr -= dst->bytes_per_line >> 2;
3143 }
3144
3145 } else {
3146 const uchar *srcPtr = src->data;
3147 uchar *dstPtr = dst->data + (h - 1) * dst->bytes_per_line;
3148 for (int y = 0; y < h; ++y) {
3149 memcpy(dstPtr, srcPtr, data_bytes_per_line);
3150 srcPtr += src->bytes_per_line;
3151 dstPtr -= dst->bytes_per_line;
3152 }
3153 }
3154}
3155
3156inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
3157{
3158 Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
3159 int w = src->width;
3160 int h = src->height;
3161 int depth = src->depth;
3162
3163 if (src->depth == 1) {
3164 w = (w + 7) / 8; // byte aligned width
3165 depth = 8;
3166 }
3167
3168 if (vertical && !horizontal) {
3169 // This one is simple and common, so do it a little more optimized
3170 do_flip(dst, src, w, h, depth);
3171 return;
3172 }
3173
3174 int dstX0 = 0, dstXIncr = 1;
3175 int dstY0 = 0, dstYIncr = 1;
3176 if (horizontal) {
3177 // 0 -> w-1, 1 -> w-2, 2 -> w-3, ...
3178 dstX0 = w - 1;
3179 dstXIncr = -1;
3180 }
3181 if (vertical) {
3182 // 0 -> h-1, 1 -> h-2, 2 -> h-3, ...
3183 dstY0 = h - 1;
3184 dstYIncr = -1;
3185 }
3186
3187 switch (depth) {
3188 case 64:
3189 do_mirror_data<quint64>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3190 break;
3191 case 32:
3192 do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3193 break;
3194 case 24:
3195 do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3196 break;
3197 case 16:
3198 do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3199 break;
3200 case 8:
3201 do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3202 break;
3203 default:
3204 Q_ASSERT(false);
3205 break;
3206 }
3207
3208 // The bytes are now all in the correct place. In addition, the bits in the individual
3209 // bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image.
3210 if (horizontal && dst->depth == 1) {
3211 Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
3212 const int shift = 8 - (dst->width % 8);
3213 const uchar *bitflip = qt_get_bitflip_array();
3214 for (int y = 0; y < h; ++y) {
3215 uchar *begin = dst->data + y * dst->bytes_per_line;
3216 uchar *end = begin + dst->bytes_per_line;
3217 for (uchar *p = begin; p < end; ++p) {
3218 *p = bitflip[*p];
3219 // When the data is non-byte aligned, an extra bit shift (of the number of
3220 // unused bits at the end) is needed for the entire scanline.
3221 if (shift != 8 && p != begin) {
3222 if (dst->format == QImage::Format_Mono) {
3223 for (int i = 0; i < shift; ++i) {
3224 p[-1] <<= 1;
3225 p[-1] |= (*p & (128 >> i)) >> (7 - i);
3226 }
3227 } else {
3228 for (int i = 0; i < shift; ++i) {
3229 p[-1] >>= 1;
3230 p[-1] |= (*p & (1 << i)) << (7 - i);
3231 }
3232 }
3233 }
3234 }
3235 if (shift != 8) {
3236 if (dst->format == QImage::Format_Mono)
3237 end[-1] <<= shift;
3238 else
3239 end[-1] >>= shift;
3240 }
3241 }
3242 }
3243}
3244
3245/*!
3246 \internal
3247*/
3248QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
3249{
3250 if (!d)
3251 return QImage();
3252
3253 if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
3254 return *this;
3255
3256 // Create result image, copy colormap
3257 QImage result(d->width, d->height, d->format);
3258 QIMAGE_SANITYCHECK_MEMORY(result);
3259
3260 // check if we ran out of of memory..
3261 if (!result.d)
3262 return QImage();
3263
3264 result.d->colortable = d->colortable;
3265 result.d->has_alpha_clut = d->has_alpha_clut;
3266 copyMetadata(result.d, d);
3267
3268 do_mirror(result.d, d, horizontal, vertical);
3269
3270 return result;
3271}
3272
3273/*!
3274 \internal
3275*/
3276void QImage::mirrored_inplace(bool horizontal, bool vertical)
3277{
3278 if (!d || (d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
3279 return;
3280
3281 detach();
3282 if (!d)
3283 return;
3284 if (!d->own_data)
3285 *this = copy();
3286
3287 do_mirror(d, d, horizontal, vertical);
3288}
3289
3290/*!
3291 \fn QImage QImage::rgbSwapped() const &
3292 \fn QImage QImage::rgbSwapped() &&
3293
3294 Returns a QImage in which the values of the red and blue
3295 components of all pixels have been swapped, effectively converting
3296 an RGB image to an BGR image.
3297
3298 The original QImage is not changed.
3299
3300 \sa rgbSwap(), {QImage#Image Transformations}{Image Transformations}
3301*/
3302
3303/*!
3304 \fn void QImage::rgbSwap()
3305 \since 6.0
3306
3307 Swaps the values of the red and blue components of all pixels, effectively converting
3308 an RGB image to an BGR image.
3309
3310 \sa rgbSwapped(), {QImage#Image Transformations}{Image Transformations}
3311*/
3312
3313static inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
3314{
3315 const RbSwapFunc func = layout->rbSwap;
3316 if (!func) {
3317 qWarning("Trying to rb-swap an image format where it doesn't make sense");
3318 if (src != dst)
3319 *dst = *src;
3320 return;
3321 }
3322
3323 for (int i = 0; i < height; ++i) {
3324 uchar *q = dst->scanLine(i);
3325 const uchar *p = src->constScanLine(i);
3326 func(q, p, width);
3327 }
3328}
3329
3330/*!
3331 \internal
3332*/
3333QImage QImage::rgbSwapped_helper() const
3334{
3335 if (isNull())
3336 return *this;
3337
3338 Q_TRACE_SCOPE(QImage_rgbSwapped_helper);
3339
3340 QImage res;
3341
3342 switch (d->format) {
3343 case Format_Invalid:
3344 case NImageFormats:
3345 Q_ASSERT(false);
3346 break;
3347 case Format_Alpha8:
3348 case Format_Grayscale8:
3349 case Format_Grayscale16:
3350 return *this;
3351 case Format_Mono:
3352 case Format_MonoLSB:
3353 case Format_Indexed8:
3354 res = copy();
3355 for (int i = 0; i < res.d->colortable.size(); i++) {
3356 QRgb c = res.d->colortable.at(i);
3357 res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
3358 }
3359 break;
3360 case Format_RGBX8888:
3361 case Format_RGBA8888:
3362 case Format_RGBA8888_Premultiplied:
3363#if Q_BYTE_ORDER == Q_BIG_ENDIAN
3364 res = QImage(d->width, d->height, d->format);
3365 QIMAGE_SANITYCHECK_MEMORY(res);
3366 for (int i = 0; i < d->height; i++) {
3367 uint *q = (uint*)res.scanLine(i);
3368 const uint *p = (const uint*)constScanLine(i);
3369 const uint *end = p + d->width;
3370 while (p < end) {
3371 uint c = *p;
3372 *q = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff);
3373 p++;
3374 q++;
3375 }
3376 }
3377 break;
3378#else
3379 // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32
3380 Q_FALLTHROUGH();
3381#endif
3382 case Format_RGB32:
3383 case Format_ARGB32:
3384 case Format_ARGB32_Premultiplied:
3385 res = QImage(d->width, d->height, d->format);
3386 QIMAGE_SANITYCHECK_MEMORY(res);
3387 for (int i = 0; i < d->height; i++) {
3388 uint *q = (uint*)res.scanLine(i);
3389 const uint *p = (const uint*)constScanLine(i);
3390 const uint *end = p + d->width;
3391 while (p < end) {
3392 uint c = *p;
3393 *q = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
3394 p++;
3395 q++;
3396 }
3397 }
3398 break;
3399 case Format_RGB16:
3400 res = QImage(d->width, d->height, d->format);
3401 QIMAGE_SANITYCHECK_MEMORY(res);
3402 for (int i = 0; i < d->height; i++) {
3403 ushort *q = (ushort*)res.scanLine(i);
3404 const ushort *p = (const ushort*)constScanLine(i);
3405 const ushort *end = p + d->width;
3406 while (p < end) {
3407 ushort c = *p;
3408 *q = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
3409 p++;
3410 q++;
3411 }
3412 }
3413 break;
3414 case Format_RGBX64:
3415 case Format_RGBA64:
3416 case Format_RGBA64_Premultiplied:
3417 res = QImage(d->width, d->height, d->format);
3418 QIMAGE_SANITYCHECK_MEMORY(res);
3419 for (int i = 0; i < d->height; i++) {
3420 QRgba64 *q = reinterpret_cast<QRgba64 *>(res.scanLine(i));
3421 const QRgba64 *p = reinterpret_cast<const QRgba64 *>(constScanLine(i));
3422 const QRgba64 *end = p + d->width;
3423 while (p < end) {
3424 QRgba64 c = *p;
3425 *q = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
3426 p++;
3427 q++;
3428 }
3429 }
3430 break;
3431 default:
3432 res = QImage(d->width, d->height, d->format);
3433 rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]);
3434 break;
3435 }
3436 copyMetadata(res.d, d);
3437 return res;
3438}
3439
3440/*!
3441 \internal
3442*/
3443void QImage::rgbSwapped_inplace()
3444{
3445 if (isNull())
3446 return;
3447
3448 detach();
3449 if (!d)
3450 return;
3451 if (!d->own_data)
3452 *this = copy();
3453
3454 switch (d->format) {
3455 case Format_Invalid:
3456 case NImageFormats:
3457 Q_ASSERT(false);
3458 break;
3459 case Format_Alpha8:
3460 case Format_Grayscale8:
3461 case Format_Grayscale16:
3462 return;
3463 case Format_Mono:
3464 case Format_MonoLSB:
3465 case Format_Indexed8:
3466 for (int i = 0; i < d->colortable.size(); i++) {
3467 QRgb c = d->colortable.at(i);
3468 d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
3469 }
3470 break;
3471 case Format_RGBX8888:
3472 case Format_RGBA8888:
3473 case Format_RGBA8888_Premultiplied:
3474#if Q_BYTE_ORDER == Q_BIG_ENDIAN
3475 for (int i = 0; i < d->height; i++) {
3476 uint *p = (uint*)scanLine(i);
3477 uint *end = p + d->width;
3478 while (p < end) {
3479 uint c = *p;
3480 *p = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff);
3481 p++;
3482 }
3483 }
3484 break;
3485#else
3486 // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32
3487 Q_FALLTHROUGH();
3488#endif
3489 case Format_RGB32:
3490 case Format_ARGB32:
3491 case Format_ARGB32_Premultiplied:
3492 for (int i = 0; i < d->height; i++) {
3493 uint *p = (uint*)scanLine(i);
3494 uint *end = p + d->width;
3495 while (p < end) {
3496 uint c = *p;
3497 *p = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
3498 p++;
3499 }
3500 }
3501 break;
3502 case Format_RGB16:
3503 for (int i = 0; i < d->height; i++) {
3504 ushort *p = (ushort*)scanLine(i);
3505 ushort *end = p + d->width;
3506 while (p < end) {
3507 ushort c = *p;
3508 *p = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
3509 p++;
3510 }
3511 }
3512 break;
3513 case Format_BGR30:
3514 case Format_A2BGR30_Premultiplied:
3515 case Format_RGB30:
3516 case Format_A2RGB30_Premultiplied:
3517 for (int i = 0; i < d->height; i++) {
3518 uint *p = (uint*)scanLine(i);
3519 uint *end = p + d->width;
3520 while (p < end) {
3521 *p = qRgbSwapRgb30(*p);
3522 p++;
3523 }
3524 }
3525 break;
3526 case Format_RGBX64:
3527 case Format_RGBA64:
3528 case Format_RGBA64_Premultiplied:
3529 for (int i = 0; i < d->height; i++) {
3530 QRgba64 *p = reinterpret_cast<QRgba64 *>(scanLine(i));
3531 QRgba64 *end = p + d->width;
3532 while (p < end) {
3533 QRgba64 c = *p;
3534 *p = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
3535 p++;
3536 }
3537 }
3538 break;
3539 default:
3540 rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]);
3541 break;
3542 }
3543}
3544
3545/*!
3546 Loads an image from the file with the given \a fileName. Returns \c true if
3547 the image was successfully loaded; otherwise invalidates the image
3548 and returns \c false.
3549
3550 The loader attempts to read the image using the specified \a format, e.g.,
3551 PNG or JPG. If \a format is not specified (which is the default), it is
3552 auto-detected based on the file's suffix and header. For details, see
3553 QImageReader::setAutoDetectImageFormat().
3554
3555 The file name can either refer to an actual file on disk or to one
3556 of the application's embedded resources. See the
3557 \l{resources.html}{Resource System} overview for details on how to
3558 embed images and other resource files in the application's
3559 executable.
3560
3561 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3562*/
3563
3564bool QImage::load(const QString &fileName, const char* format)
3565{
3566 *this = QImageReader(fileName, format).read();
3567 return !isNull();
3568}
3569
3570/*!
3571 \overload
3572
3573 This function reads a QImage from the given \a device. This can,
3574 for example, be used to load an image directly into a QByteArray.
3575*/
3576
3577bool QImage::load(QIODevice* device, const char* format)
3578{
3579 *this = QImageReader(device, format).read();
3580 return !isNull();
3581}
3582
3583/*!
3584 \fn bool QImage::loadFromData(const uchar *data, int len, const char *format)
3585
3586 Loads an image from the first \a len bytes of the given binary \a
3587 data. Returns \c true if the image was successfully loaded; otherwise
3588 invalidates the image and returns \c false.
3589
3590 The loader attempts to read the image using the specified \a format, e.g.,
3591 PNG or JPG. If \a format is not specified (which is the default), the
3592 loader probes the file for a header to guess the file format.
3593
3594 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3595*/
3596
3597bool QImage::loadFromData(const uchar *data, int len, const char *format)
3598{
3599 *this = fromData(data, len, format);
3600 return !isNull();
3601}
3602
3603/*!
3604 \fn bool QImage::loadFromData(const QByteArray &data, const char *format)
3605
3606 \overload
3607
3608 Loads an image from the given QByteArray \a data.
3609*/
3610
3611/*!
3612 \fn QImage QImage::fromData(const uchar *data, int size, const char *format)
3613
3614 Constructs a QImage from the first \a size bytes of the given
3615 binary \a data. The loader attempts to read the image using the
3616 specified \a format. If \a format is not specified (which is the default),
3617 the loader probes the data for a header to guess the file format.
3618
3619 If \a format is specified, it must be one of the values returned by
3620 QImageReader::supportedImageFormats().
3621
3622 If the loading of the image fails, the image returned will be a null image.
3623
3624 \sa load(), save(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3625 */
3626
3627QImage QImage::fromData(const uchar *data, int size, const char *format)
3628{
3629 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(data), size);
3630 QBuffer b;
3631 b.setData(a);
3632 b.open(QIODevice::ReadOnly);
3633 return QImageReader(&b, format).read();
3634}
3635
3636/*!
3637 \fn QImage QImage::fromData(const QByteArray &data, const char *format)
3638
3639 \overload
3640
3641 Loads an image from the given QByteArray \a data.
3642*/
3643
3644/*!
3645 Saves the image to the file with the given \a fileName, using the
3646 given image file \a format and \a quality factor. If \a format is
3647 \nullptr, QImage will attempt to guess the format by looking at
3648 \a fileName's suffix.
3649
3650 The \a quality factor must be in the range 0 to 100 or -1. Specify
3651 0 to obtain small compressed files, 100 for large uncompressed
3652 files, and -1 (the default) to use the default settings.
3653
3654 Returns \c true if the image was successfully saved; otherwise
3655 returns \c false.
3656
3657 \sa {QImage#Reading and Writing Image Files}{Reading and Writing
3658 Image Files}
3659*/
3660bool QImage::save(const QString &fileName, const char *format, int quality) const
3661{
3662 if (isNull())
3663 return false;
3664 QImageWriter writer(fileName, format);
3665 return d->doImageIO(this, &writer, quality);
3666}
3667
3668/*!
3669 \overload
3670
3671 This function writes a QImage to the given \a device.
3672
3673 This can, for example, be used to save an image directly into a
3674 QByteArray:
3675
3676 \snippet image/image.cpp 0
3677*/
3678
3679bool QImage::save(QIODevice* device, const char* format, int quality) const
3680{
3681 if (isNull())
3682 return false; // nothing to save
3683 QImageWriter writer(device, format);
3684 return d->doImageIO(this, &writer, quality);
3685}
3686
3687/* \internal
3688*/
3689
3690bool QImageData::doImageIO(const QImage *image, QImageWriter *writer, int quality) const
3691{
3692 if (quality > 100 || quality < -1)
3693 qWarning("QPixmap::save: Quality out of range [-1, 100]");
3694 if (quality >= 0)
3695 writer->setQuality(qMin(quality,100));
3696 return writer->write(*image);
3697}
3698
3699/*****************************************************************************
3700 QImage stream functions
3701 *****************************************************************************/
3702#if !defined(QT_NO_DATASTREAM)
3703/*!
3704 \fn QDataStream &operator<<(QDataStream &stream, const QImage &image)
3705 \relates QImage
3706
3707 Writes the given \a image to the given \a stream as a PNG image,
3708 or as a BMP image if the stream's version is 1. Note that writing
3709 the stream to a file will not produce a valid image file.
3710
3711 \sa QImage::save(), {Serializing Qt Data Types}
3712*/
3713
3714QDataStream &operator<<(QDataStream &s, const QImage &image)
3715{
3716 if (s.version() >= 5) {
3717 if (image.isNull()) {
3718 s << (qint32) 0; // null image marker
3719 return s;
3720 } else {
3721 s << (qint32) 1;
3722 // continue ...
3723 }
3724 }
3725 QImageWriter writer(s.device(), s.version() == 1 ? "bmp" : "png");
3726 writer.write(image);
3727 return s;
3728}
3729
3730/*!
3731 \fn QDataStream &operator>>(QDataStream &stream, QImage &image)
3732 \relates QImage
3733
3734 Reads an image from the given \a stream and stores it in the given
3735 \a image.
3736
3737 \sa QImage::load(), {Serializing Qt Data Types}
3738*/
3739
3740QDataStream &operator>>(QDataStream &s, QImage &image)
3741{
3742 if (s.version() >= 5) {
3743 qint32 nullMarker;
3744 s >> nullMarker;
3745 if (!nullMarker) {
3746 image = QImage(); // null image
3747 return s;
3748 }
3749 }
3750 image = QImageReader(s.device(), s.version() == 1 ? "bmp" : "png").read();
3751 if (image.isNull() && s.version() >= 5)
3752 s.setStatus(QDataStream::ReadPastEnd);
3753 return s;
3754}
3755#endif // QT_NO_DATASTREAM
3756
3757
3758
3759/*!
3760 \fn bool QImage::operator==(const QImage & image) const
3761
3762 Returns \c true if this image and the given \a image have the same
3763 contents; otherwise returns \c false.
3764
3765 The comparison can be slow, unless there is some obvious
3766 difference (e.g. different size or format), in which case the
3767 function will return quickly.
3768
3769 \sa operator=()
3770*/
3771
3772bool QImage::operator==(const QImage & i) const
3773{
3774 // same object, or shared?
3775 if (i.d == d)
3776 return true;
3777 if (!i.d || !d)
3778 return false;
3779
3780 // obviously different stuff?
3781 if (i.d->height != d->height || i.d->width != d->width || i.d->format != d->format)
3782 return false;
3783
3784 if (d->format != Format_RGB32) {
3785 if (d->format >= Format_ARGB32) { // all bits defined
3786 const int n = d->width * d->depth / 8;
3787 if (n == d->bytes_per_line && n == i.d->bytes_per_line) {
3788 if (memcmp(bits(), i.bits(), d->nbytes))
3789 return false;
3790 } else {
3791 for (int y = 0; y < d->height; ++y) {
3792 if (memcmp(scanLine(y), i.scanLine(y), n))
3793 return false;
3794 }
3795 }
3796 } else {
3797 const int w = width();
3798 const int h = height();
3799 const QList<QRgb> &colortable = d->colortable;
3800 const QList<QRgb> &icolortable = i.d->colortable;
3801 for (int y=0; y<h; ++y) {
3802 for (int x=0; x<w; ++x) {
3803 if (colortable[pixelIndex(x, y)] != icolortable[i.pixelIndex(x, y)])
3804 return false;
3805 }
3806 }
3807 }
3808 } else {
3809 //alpha channel undefined, so we must mask it out
3810 for(int l = 0; l < d->height; l++) {
3811 int w = d->width;
3812 const uint *p1 = reinterpret_cast<const uint*>(scanLine(l));
3813 const uint *p2 = reinterpret_cast<const uint*>(i.scanLine(l));
3814 while (w--) {
3815 if ((*p1++ & 0x00ffffff) != (*p2++ & 0x00ffffff))
3816 return false;
3817 }
3818 }
3819 }
3820 return true;
3821}
3822
3823
3824/*!
3825 \fn bool QImage::operator!=(const QImage & image) const
3826
3827 Returns \c true if this image and the given \a image have different
3828 contents; otherwise returns \c false.
3829
3830 The comparison can be slow, unless there is some obvious
3831 difference, such as different widths, in which case the function
3832 will return quickly.
3833
3834 \sa operator=()
3835*/
3836
3837bool QImage::operator!=(const QImage & i) const
3838{
3839 return !(*this == i);
3840}
3841
3842
3843
3844
3845/*!
3846 Returns the number of pixels that fit horizontally in a physical
3847 meter. Together with dotsPerMeterY(), this number defines the
3848 intended scale and aspect ratio of the image.
3849
3850 \sa setDotsPerMeterX(), {QImage#Image Information}{Image
3851 Information}
3852*/
3853int QImage::dotsPerMeterX() const
3854{
3855 return d ? qRound(d->dpmx) : 0;
3856}
3857
3858/*!
3859 Returns the number of pixels that fit vertically in a physical
3860 meter. Together with dotsPerMeterX(), this number defines the
3861 intended scale and aspect ratio of the image.
3862
3863 \sa setDotsPerMeterY(), {QImage#Image Information}{Image
3864 Information}
3865*/
3866int QImage::dotsPerMeterY() const
3867{
3868 return d ? qRound(d->dpmy) : 0;
3869}
3870
3871/*!
3872 Sets the number of pixels that fit horizontally in a physical
3873 meter, to \a x.
3874
3875 Together with dotsPerMeterY(), this number defines the intended
3876 scale and aspect ratio of the image, and determines the scale
3877 at which QPainter will draw graphics on the image. It does not
3878 change the scale or aspect ratio of the image when it is rendered
3879 on other paint devices.
3880
3881 \sa dotsPerMeterX(), {QImage#Image Information}{Image Information}
3882*/
3883void QImage::setDotsPerMeterX(int x)
3884{
3885 if (!d || !x)
3886 return;
3887 detach();
3888
3889 if (d)
3890 d->dpmx = x;
3891}
3892
3893/*!
3894 Sets the number of pixels that fit vertically in a physical meter,
3895 to \a y.
3896
3897 Together with dotsPerMeterX(), this number defines the intended
3898 scale and aspect ratio of the image, and determines the scale
3899 at which QPainter will draw graphics on the image. It does not
3900 change the scale or aspect ratio of the image when it is rendered
3901 on other paint devices.
3902
3903 \sa dotsPerMeterY(), {QImage#Image Information}{Image Information}
3904*/
3905void QImage::setDotsPerMeterY(int y)
3906{
3907 if (!d || !y)
3908 return;
3909 detach();
3910
3911 if (d)
3912 d->dpmy = y;
3913}
3914
3915/*!
3916 \fn QPoint QImage::offset() const
3917
3918 Returns the number of pixels by which the image is intended to be
3919 offset by when positioning relative to other images.
3920
3921 \sa setOffset(), {QImage#Image Information}{Image Information}
3922*/
3923QPoint QImage::offset() const
3924{
3925 return d ? d->offset : QPoint();
3926}
3927
3928
3929/*!
3930 \fn void QImage::setOffset(const QPoint& offset)
3931
3932 Sets the number of pixels by which the image is intended to be
3933 offset by when positioning relative to other images, to \a offset.
3934
3935 \sa offset(), {QImage#Image Information}{Image Information}
3936*/
3937void QImage::setOffset(const QPoint& p)
3938{
3939 if (!d)
3940 return;
3941 detach();
3942
3943 if (d)
3944 d->offset = p;
3945}
3946
3947/*!
3948 Returns the text keys for this image.
3949
3950 You can use these keys with text() to list the image text for a
3951 certain key.
3952
3953 \sa text()
3954*/
3955QStringList QImage::textKeys() const
3956{
3957 return d ? QStringList(d->text.keys()) : QStringList();
3958}
3959
3960/*!
3961 Returns the image text associated with the given \a key. If the
3962 specified \a key is an empty string, the whole image text is
3963 returned, with each key-text pair separated by a newline.
3964
3965 \sa setText(), textKeys()
3966*/
3967QString QImage::text(const QString &key) const
3968{
3969 if (!d)
3970 return QString();
3971
3972 if (!key.isEmpty())
3973 return d->text.value(key);
3974
3975 QString tmp;
3976 for (auto it = d->text.begin(), end = d->text.end(); it != end; ++it)
3977 tmp += it.key() + QLatin1String(": ") + it.value().simplified() + QLatin1String("\n\n");
3978 if (!tmp.isEmpty())
3979 tmp.chop(2); // remove final \n\n
3980 return tmp;
3981}
3982
3983/*!
3984 \fn void QImage::setText(const QString &key, const QString &text)
3985
3986 Sets the image text to the given \a text and associate it with the
3987 given \a key.
3988
3989 If you just want to store a single text block (i.e., a "comment"
3990 or just a description), you can either pass an empty key, or use a
3991 generic key like "Description".
3992
3993 The image text is embedded into the image data when you
3994 call save() or QImageWriter::write().
3995
3996 Not all image formats support embedded text. You can find out
3997 if a specific image or format supports embedding text
3998 by using QImageWriter::supportsOption(). We give an example:
3999
4000 \snippet image/supportedformat.cpp 0
4001
4002 You can use QImageWriter::supportedImageFormats() to find out
4003 which image formats are available to you.
4004
4005 \sa text(), textKeys()
4006*/
4007void QImage::setText(const QString &key, const QString &value)
4008{
4009 if (!d)
4010 return;
4011 detach();
4012
4013 if (d)
4014 d->text.insert(key, value);
4015}
4016
4017/*!
4018 \internal
4019
4020 Used by QPainter to retrieve a paint engine for the image.
4021*/
4022QPaintEngine *QImage::paintEngine() const
4023{
4024 if (!d)
4025 return nullptr;
4026
4027 if (!d->paintEngine) {
4028 QPaintDevice *paintDevice = const_cast<QImage *>(this);
4029 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
4030 if (platformIntegration)
4031 d->paintEngine = platformIntegration->createImagePaintEngine(paintDevice);
4032 if (!d->paintEngine)
4033 d->paintEngine = new QRasterPaintEngine(paintDevice);
4034 }
4035
4036 return d->paintEngine;
4037}
4038
4039
4040/*!
4041 \internal
4042
4043 Returns the size for the specified \a metric on the device.
4044*/
4045int QImage::metric(PaintDeviceMetric metric) const
4046{
4047 if (!d)
4048 return 0;
4049
4050 switch (metric) {
4051 case PdmWidth:
4052 return d->width;
4053
4054 case PdmHeight:
4055 return d->height;
4056
4057 case PdmWidthMM:
4058 return qRound(d->width * 1000 / d->dpmx);
4059
4060 case PdmHeightMM:
4061 return qRound(d->height * 1000 / d->dpmy);
4062
4063 case PdmNumColors:
4064 return d->colortable.size();
4065
4066 case PdmDepth:
4067 return d->depth;
4068
4069 case PdmDpiX:
4070 return qRound(d->dpmx * 0.0254);
4071 break;
4072
4073 case PdmDpiY:
4074 return qRound(d->dpmy * 0.0254);
4075 break;
4076
4077 case PdmPhysicalDpiX:
4078 return qRound(d->dpmx * 0.0254);
4079 break;
4080
4081 case PdmPhysicalDpiY:
4082 return qRound(d->dpmy * 0.0254);
4083 break;
4084
4085 case PdmDevicePixelRatio:
4086 return d->devicePixelRatio;
4087 break;
4088
4089 case PdmDevicePixelRatioScaled:
4090 return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale();
4091 break;
4092
4093 default:
4094 qWarning("QImage::metric(): Unhandled metric type %d", metric);
4095 break;
4096 }
4097 return 0;
4098}
4099
4100
4101
4102/*****************************************************************************
4103 QPixmap (and QImage) helper functions
4104 *****************************************************************************/
4105/*
4106 This internal function contains the common (i.e. platform independent) code
4107 to do a transformation of pixel data. It is used by QPixmap::transform() and by
4108 QImage::transform().
4109
4110 \a trueMat is the true transformation matrix (see QPixmap::trueMatrix()) and
4111 \a xoffset is an offset to the matrix.
4112
4113 \a msbfirst specifies for 1bpp images, if the MSB or LSB comes first and \a
4114 depth specifies the colordepth of the data.
4115
4116 \a dptr is a pointer to the destination data, \a dbpl specifies the bits per
4117 line for the destination data, \a p_inc is the offset that we advance for
4118 every scanline and \a dHeight is the height of the destination image.
4119
4120 \a sprt is the pointer to the source data, \a sbpl specifies the bits per
4121 line of the source data, \a sWidth and \a sHeight are the width and height of
4122 the source data.
4123*/
4124
4125#undef IWX_MSB
4126#define IWX_MSB(b) if (trigx < maxws && trigy < maxhs) { \
4127 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4128 (1 << (7-((trigx>>12)&7)))) \
4129 *dptr |= b; \
4130 } \
4131 trigx += m11; \
4132 trigy += m12;
4133 // END OF MACRO
4134#undef IWX_LSB
4135#define IWX_LSB(b) if (trigx < maxws && trigy < maxhs) { \
4136 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4137 (1 << ((trigx>>12)&7))) \
4138 *dptr |= b; \
4139 } \
4140 trigx += m11; \
4141 trigy += m12;
4142 // END OF MACRO
4143#undef IWX_PIX
4144#define IWX_PIX(b) if (trigx < maxws && trigy < maxhs) { \
4145 if ((*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4146 (1 << (7-((trigx>>12)&7)))) == 0) \
4147 *dptr &= ~b; \
4148 } \
4149 trigx += m11; \
4150 trigy += m12;
4151 // END OF MACRO
4152bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth,
4153 uchar *dptr, qsizetype dbpl, int p_inc, int dHeight,
4154 const uchar *sptr, qsizetype sbpl, int sWidth, int sHeight)
4155{
4156 int m11 = int(trueMat.m11()*4096.0);
4157 int m12 = int(trueMat.m12()*4096.0);
4158 int m21 = int(trueMat.m21()*4096.0);
4159 int m22 = int(trueMat.m22()*4096.0);
4160 int dx = qRound(trueMat.dx()*4096.0);
4161 int dy = qRound(trueMat.dy()*4096.0);
4162
4163 int m21ydx = dx + (xoffset<<16) + (m11 + m21) / 2;
4164 int m22ydy = dy + (m12 + m22) / 2;
4165 uint trigx;
4166 uint trigy;
4167 uint maxws = sWidth<<12;
4168 uint maxhs = sHeight<<12;
4169
4170 for (int y=0; y<dHeight; y++) { // for each target scanline
4171 trigx = m21ydx;
4172 trigy = m22ydy;
4173 uchar *maxp = dptr + dbpl;
4174 if (depth != 1) {
4175 switch (depth) {
4176 case 8: // 8 bpp transform
4177 while (dptr < maxp) {
4178 if (trigx < maxws && trigy < maxhs)
4179 *dptr = *(sptr+sbpl*(trigy>>12)+(trigx>>12));
4180 trigx += m11;
4181 trigy += m12;
4182 dptr++;
4183 }
4184 break;
4185
4186 case 16: // 16 bpp transform
4187 while (dptr < maxp) {
4188 if (trigx < maxws && trigy < maxhs)
4189 *((ushort*)dptr) = *((const ushort *)(sptr+sbpl*(trigy>>12) +
4190 ((trigx>>12)<<1)));
4191 trigx += m11;
4192 trigy += m12;
4193 dptr++;
4194 dptr++;
4195 }
4196 break;
4197
4198 case 24: // 24 bpp transform
4199 while (dptr < maxp) {
4200 if (trigx < maxws && trigy < maxhs) {
4201 const uchar *p2 = sptr+sbpl*(trigy>>12) + ((trigx>>12)*3);
4202 dptr[0] = p2[0];
4203 dptr[1] = p2[1];
4204 dptr[2] = p2[2];
4205 }
4206 trigx += m11;
4207 trigy += m12;
4208 dptr += 3;
4209 }
4210 break;
4211
4212 case 32: // 32 bpp transform
4213 while (dptr < maxp) {
4214 if (trigx < maxws && trigy < maxhs)
4215 *((uint*)dptr) = *((const uint *)(sptr+sbpl*(trigy>>12) +
4216 ((trigx>>12)<<2)));
4217 trigx += m11;
4218 trigy += m12;
4219 dptr += 4;
4220 }
4221 break;
4222
4223 default: {
4224 return false;
4225 }
4226 }
4227 } else {
4228 switch (type) {
4229 case QT_XFORM_TYPE_MSBFIRST:
4230 while (dptr < maxp) {
4231 IWX_MSB(128);
4232 IWX_MSB(64);
4233 IWX_MSB(32);
4234 IWX_MSB(16);
4235 IWX_MSB(8);
4236 IWX_MSB(4);
4237 IWX_MSB(2);
4238 IWX_MSB(1);
4239 dptr++;
4240 }
4241 break;
4242 case QT_XFORM_TYPE_LSBFIRST:
4243 while (dptr < maxp) {
4244 IWX_LSB(1);
4245 IWX_LSB(2);
4246 IWX_LSB(4);
4247 IWX_LSB(8);
4248 IWX_LSB(16);
4249 IWX_LSB(32);
4250 IWX_LSB(64);
4251 IWX_LSB(128);
4252 dptr++;
4253 }
4254 break;
4255 }
4256 }
4257 m21ydx += m21;
4258 m22ydy += m22;
4259 dptr += p_inc;
4260 }
4261 return true;
4262}
4263#undef IWX_MSB
4264#undef IWX_LSB
4265#undef IWX_PIX
4266
4267/*!
4268 Returns a number that identifies the contents of this QImage
4269 object. Distinct QImage objects can only have the same key if they
4270 refer to the same contents.
4271
4272 The key will change when the image is altered.
4273*/
4274qint64 QImage::cacheKey() const
4275{
4276 if (!d)
4277 return 0;
4278 else
4279 return (((qint64) d->ser_no) << 32) | ((qint64) d->detach_no);
4280}
4281
4282/*!
4283 \internal
4284
4285 Returns \c true if the image is detached; otherwise returns \c false.
4286
4287 \sa detach(), {Implicit Data Sharing}
4288*/
4289
4290bool QImage::isDetached() const
4291{
4292 return d && d->ref.loadRelaxed() == 1;
4293}
4294
4295
4296/*!
4297 Sets the alpha channel of this image to the given \a alphaChannel.
4298
4299 If \a alphaChannel is an 8 bit alpha image, the alpha values are
4300 used directly. Otherwise, \a alphaChannel is converted to 8 bit
4301 grayscale and the intensity of the pixel values is used.
4302
4303 If the image already has an alpha channel, the existing alpha channel
4304 is multiplied with the new one. If the image doesn't have an alpha
4305 channel it will be converted to a format that does.
4306
4307 The operation is similar to painting \a alphaChannel as an alpha image
4308 over this image using \c QPainter::CompositionMode_DestinationIn.
4309
4310 \sa hasAlphaChannel(),
4311 {QImage#Image Transformations}{Image Transformations},
4312 {QImage#Image Formats}{Image Formats}
4313*/
4314
4315void QImage::setAlphaChannel(const QImage &alphaChannel)
4316{
4317 if (!d || alphaChannel.isNull())
4318 return;
4319
4320 if (d->paintEngine && d->paintEngine->isActive()) {
4321 qWarning("QImage::setAlphaChannel: "
4322 "Unable to set alpha channel while image is being painted on");
4323 return;
4324 }
4325
4326 const Format alphaFormat = qt_alphaVersionForPainting(d->format);
4327 if (d->format == alphaFormat)
4328 detach();
4329 else
4330 convertTo(alphaFormat);
4331
4332 if (isNull())
4333 return;
4334
4335 QImage sourceImage;
4336 if (alphaChannel.format() == QImage::Format_Alpha8 || (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()))
4337 sourceImage = alphaChannel;
4338 else
4339 sourceImage = alphaChannel.convertToFormat(QImage::Format_Grayscale8);
4340 if (!sourceImage.reinterpretAsFormat(QImage::Format_Alpha8))
4341 return;
4342
4343 QPainter painter(this);
4344 if (sourceImage.size() != size())
4345 painter.setRenderHint(QPainter::SmoothPixmapTransform);
4346 painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
4347 painter.drawImage(rect(), sourceImage);
4348}
4349
4350/*!
4351 Returns \c true if the image has a format that respects the alpha
4352 channel, otherwise returns \c false.
4353
4354 \sa {QImage#Image Information}{Image Information}
4355*/
4356bool QImage::hasAlphaChannel() const
4357{
4358 if (!d)
4359 return false;
4360 const QPixelFormat format = pixelFormat();
4361 if (format.alphaUsage() == QPixelFormat::UsesAlpha)
4362 return true;
4363 if (format.colorModel() == QPixelFormat::Indexed)
4364 return d->has_alpha_clut;
4365 return false;
4366}
4367
4368/*!
4369 \since 4.7
4370 Returns the number of bit planes in the image.
4371
4372 The number of bit planes is the number of bits of color and
4373 transparency information for each pixel. This is different from
4374 (i.e. smaller than) the depth when the image format contains
4375 unused bits.
4376
4377 \sa depth(), format(), {QImage#Image Formats}{Image Formats}
4378*/
4379int QImage::bitPlaneCount() const
4380{
4381 if (!d)
4382 return 0;
4383 int bpc = 0;
4384 switch (d->format) {
4385 case QImage::Format_Invalid:
4386 break;
4387 case QImage::Format_BGR30:
4388 case QImage::Format_RGB30:
4389 bpc = 30;
4390 break;
4391 case QImage::Format_RGB32:
4392 case QImage::Format_RGBX8888:
4393 bpc = 24;
4394 break;
4395 case QImage::Format_RGB666:
4396 bpc = 18;
4397 break;
4398 case QImage::Format_RGB555:
4399 bpc = 15;
4400 break;
4401 case QImage::Format_ARGB8555_Premultiplied:
4402 bpc = 23;
4403 break;
4404 case QImage::Format_RGB444:
4405 bpc = 12;
4406 break;
4407 case QImage::Format_RGBX64:
4408 bpc = 48;
4409 break;
4410 default:
4411 bpc = qt_depthForFormat(d->format);
4412 break;
4413 }
4414 return bpc;
4415}
4416
4417/*!
4418 \internal
4419 Returns a smoothly scaled copy of the image. The returned image has a size
4420 of width \a w by height \a h pixels.
4421
4422 The function operates internally on \c Format_RGB32, \c Format_ARGB32_Premultiplied,
4423 \c Format_RGBX8888, \c Format_RGBA8888_Premultiplied, \c Format_RGBX64,
4424 or \c Format_RGBA64_Premultiplied and will convert to those formats
4425 if necessary. To avoid unnecessary conversion the result is returned in the format
4426 internally used, and not in the original format.
4427*/
4428QImage QImage::smoothScaled(int w, int h) const {
4429 QImage src = *this;
4430 switch (src.format()) {
4431 case QImage::Format_RGB32:
4432 case QImage::Format_ARGB32_Premultiplied:
4433#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4434 case QImage::Format_RGBX8888:
4435#endif
4436 case QImage::Format_RGBA8888_Premultiplied:
4437#if QT_CONFIG(raster_64bit)
4438 case QImage::Format_RGBX64:
4439 case QImage::Format_RGBA64_Premultiplied:
4440 break;
4441 case QImage::Format_RGBA64:
4442 src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);
4443 break;
4444#endif
4445 default:
4446 if (src.hasAlphaChannel())
4447 src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
4448 else
4449 src = src.convertToFormat(QImage::Format_RGB32);
4450 }
4451 src = qSmoothScaleImage(src, w, h);
4452 if (!src.isNull())
4453 copyMetadata(src.d, d);
4454 return src;
4455}
4456
4457static QImage rotated90(const QImage &image)
4458{
4459 QImage out(image.height(), image.width(), image.format());
4460 copyMetadata(&out, image);
4461 if (image.colorCount() > 0)
4462 out.setColorTable(image.colorTable());
4463 int w = image.width();
4464 int h = image.height();
4465 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][2];
4466 if (memrotate) {
4467 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4468 } else {
4469 for (int y=0; y<h; ++y) {
4470 if (image.colorCount())
4471 for (int x=0; x<w; ++x)
4472 out.setPixel(h-y-1, x, image.pixelIndex(x, y));
4473 else
4474 for (int x=0; x<w; ++x)
4475 out.setPixel(h-y-1, x, image.pixel(x, y));
4476 }
4477 }
4478 return out;
4479}
4480
4481static QImage rotated180(const QImage &image)
4482{
4483 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][1];
4484 if (!memrotate)
4485 return image.mirrored(true, true);
4486
4487 QImage out(image.width(), image.height(), image.format());
4488 copyMetadata(&out, image);
4489 if (image.colorCount() > 0)
4490 out.setColorTable(image.colorTable());
4491 int w = image.width();
4492 int h = image.height();
4493 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4494 return out;
4495}
4496
4497static QImage rotated270(const QImage &image)
4498{
4499 QImage out(image.height(), image.width(), image.format());
4500 copyMetadata(&out, image);
4501 if (image.colorCount() > 0)
4502 out.setColorTable(image.colorTable());
4503 int w = image.width();
4504 int h = image.height();
4505 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][0];
4506 if (memrotate) {
4507 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4508 } else {
4509 for (int y=0; y<h; ++y) {
4510 if (image.colorCount())
4511 for (int x=0; x<w; ++x)
4512 out.setPixel(y, w-x-1, image.pixelIndex(x, y));
4513 else
4514 for (int x=0; x<w; ++x)
4515 out.setPixel(y, w-x-1, image.pixel(x, y));
4516 }
4517 }
4518 return out;
4519}
4520
4521/*!
4522 Returns a copy of the image that is transformed using the given
4523 transformation \a matrix and transformation \a mode.
4524
4525 The returned image will normally have the same {Image Formats}{format} as
4526 the original image. However, a complex transformation may result in an
4527 image where not all pixels are covered by the transformed pixels of the
4528 original image. In such cases, those background pixels will be assigned a
4529 transparent color value, and the transformed image will be given a format
4530 with an alpha channel, even if the orginal image did not have that.
4531
4532 The transformation \a matrix is internally adjusted to compensate
4533 for unwanted translation; i.e. the image produced is the smallest
4534 image that contains all the transformed points of the original
4535 image. Use the trueMatrix() function to retrieve the actual matrix
4536 used for transforming an image.
4537
4538 Unlike the other overload, this function can be used to perform perspective
4539 transformations on images.
4540
4541 \sa trueMatrix(), {QImage#Image Transformations}{Image
4542 Transformations}
4543*/
4544
4545QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
4546{
4547 if (!d)
4548 return QImage();
4549
4550 Q_TRACE_SCOPE(QImage_transformed, matrix, mode);
4551
4552 // source image data
4553 const int ws = width();
4554 const int hs = height();
4555
4556 // target image data
4557 int wd;
4558 int hd;
4559
4560 // compute size of target image
4561 QTransform mat = trueMatrix(matrix, ws, hs);
4562 bool complex_xform = false;
4563 bool scale_xform = false;
4564 bool nonpaintable_scale_xform = false;
4565 if (mat.type() <= QTransform::TxScale) {
4566 if (mat.type() == QTransform::TxNone) // identity matrix
4567 return *this;
4568 else if (mat.m11() == -1. && mat.m22() == -1.)
4569 return rotated180(*this);
4570
4571 if (mode == Qt::FastTransformation) {
4572 hd = qRound(qAbs(mat.m22()) * hs);
4573 wd = qRound(qAbs(mat.m11()) * ws);
4574 } else {
4575 hd = int(qAbs(mat.m22()) * hs + 0.9999);
4576 wd = int(qAbs(mat.m11()) * ws + 0.9999);
4577 }
4578 scale_xform = true;
4579 // The paint-based scaling is only bilinear, and has problems
4580 // with scaling smoothly more than 2x down.
4581 if (hd * 2 < hs || wd * 2 < ws)
4582 nonpaintable_scale_xform = true;
4583 } else {
4584 if (mat.type() <= QTransform::TxRotate && mat.m11() == 0 && mat.m22() == 0) {
4585 if (mat.m12() == 1. && mat.m21() == -1.)
4586 return rotated90(*this);
4587 else if (mat.m12() == -1. && mat.m21() == 1.)
4588 return rotated270(*this);
4589 }
4590
4591 QPolygonF a(QRectF(0, 0, ws, hs));
4592 a = mat.map(a);
4593 QRect r = a.boundingRect().toAlignedRect();
4594 wd = r.width();
4595 hd = r.height();
4596 complex_xform = true;
4597 }
4598
4599 if (wd == 0 || hd == 0)
4600 return QImage();
4601
4602 if (scale_xform && mode == Qt::SmoothTransformation) {
4603 switch (format()) {
4604 case QImage::Format_RGB32:
4605 case QImage::Format_ARGB32_Premultiplied:
4606#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4607 case QImage::Format_RGBX8888:
4608#endif
4609 case QImage::Format_RGBA8888_Premultiplied:
4610#if QT_CONFIG(raster_64bit)
4611 case QImage::Format_RGBX64:
4612 case QImage::Format_RGBA64_Premultiplied:
4613#endif
4614 // Use smoothScaled for scaling when we can do so without conversion.
4615 if (mat.m11() > 0.0F && mat.m22() > 0.0F)
4616 return smoothScaled(wd, hd);
4617 break;
4618 default:
4619 break;
4620 }
4621 // Otherwise only use it when the scaling factor demands it, or the image is large enough to scale multi-threaded
4622 if (nonpaintable_scale_xform
4623#if QT_CONFIG(thread) && !defined(Q_OS_WASM)
4624 || (ws * hs) >= (1<<20)
4625#endif
4626 ) {
4627 if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip
4628 return smoothScaled(wd, hd).mirrored(true, true).convertToFormat(format());
4629 } else if (mat.m11() < 0.0F) { // horizontal flip
4630 return smoothScaled(wd, hd).mirrored(true, false).convertToFormat(format());
4631 } else if (mat.m22() < 0.0F) { // vertical flip
4632 return smoothScaled(wd, hd).mirrored(false, true).convertToFormat(format());
4633 } else { // no flipping
4634 return smoothScaled(wd, hd).convertToFormat(format());
4635 }
4636 }
4637 }
4638
4639 int bpp = depth();
4640
4641 qsizetype sbpl = bytesPerLine();
4642 const uchar *sptr = bits();
4643
4644 QImage::Format target_format = d->format;
4645
4646 if (complex_xform || mode == Qt::SmoothTransformation) {
4647 if (d->format < QImage::Format_RGB32 || (!hasAlphaChannel() && complex_xform)) {
4648 target_format = qt_alphaVersion(d->format);
4649 }
4650 }
4651
4652 QImage dImage(wd, hd, target_format);
4653 QIMAGE_SANITYCHECK_MEMORY(dImage);
4654
4655 if (target_format == QImage::Format_MonoLSB
4656 || target_format == QImage::Format_Mono
4657 || target_format == QImage::Format_Indexed8) {
4658 dImage.d->colortable = d->colortable;
4659 dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform;
4660 }
4661
4662 // initizialize the data
4663 if (target_format == QImage::Format_Indexed8) {
4664 if (dImage.d->colortable.size() < 256) {
4665 // colors are left in the color table, so pick that one as transparent
4666 dImage.d->colortable.append(0x0);
4667 memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.d->nbytes);
4668 } else {
4669 memset(dImage.bits(), 0, dImage.d->nbytes);
4670 }
4671 } else
4672 memset(dImage.bits(), 0x00, dImage.d->nbytes);
4673
4674 if (target_format >= QImage::Format_RGB32) {
4675 // Prevent QPainter from applying devicePixelRatio corrections
4676 const QImage sImage = (devicePixelRatio() != 1) ? QImage(constBits(), width(), height(), format()) : *this;
4677
4678 Q_ASSERT(sImage.devicePixelRatio() == 1);
4679 Q_ASSERT(sImage.devicePixelRatio() == dImage.devicePixelRatio());
4680
4681 QPainter p(&dImage);
4682 if (mode == Qt::SmoothTransformation) {
4683 p.setRenderHint(QPainter::Antialiasing);
4684 p.setRenderHint(QPainter::SmoothPixmapTransform);
4685 }
4686 p.setTransform(mat);
4687 p.drawImage(QPoint(0, 0), sImage);
4688 } else {
4689 bool invertible;
4690 mat = mat.inverted(&invertible); // invert matrix
4691 if (!invertible) // error, return null image
4692 return QImage();
4693
4694 // create target image (some of the code is from QImage::copy())
4695 int type = format() == Format_Mono ? QT_XFORM_TYPE_MSBFIRST : QT_XFORM_TYPE_LSBFIRST;
4696 qsizetype dbpl = dImage.bytesPerLine();
4697 qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs);
4698 }
4699 copyMetadata(dImage.d, d);
4700
4701 return dImage;
4702}
4703
4704/*!
4705 \fn QTransform QImage::trueMatrix(const QTransform &matrix, int width, int height)
4706
4707 Returns the actual matrix used for transforming an image with the
4708 given \a width, \a height and \a matrix.
4709
4710 When transforming an image using the transformed() function, the
4711 transformation matrix is internally adjusted to compensate for
4712 unwanted translation, i.e. transformed() returns the smallest
4713 image containing all transformed points of the original image.
4714 This function returns the modified matrix, which maps points
4715 correctly from the original image into the new image.
4716
4717 Unlike the other overload, this function creates transformation
4718 matrices that can be used to perform perspective
4719 transformations on images.
4720
4721 \sa transformed(), {QImage#Image Transformations}{Image
4722 Transformations}
4723*/
4724
4725QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h)
4726{
4727 const QRectF rect(0, 0, w, h);
4728 const QRect mapped = matrix.mapRect(rect).toAlignedRect();
4729 const QPoint delta = mapped.topLeft();
4730 return matrix * QTransform().translate(-delta.x(), -delta.y());
4731}
4732
4733/*!
4734 \since 5.14
4735
4736 Sets the image color space to \a colorSpace without performing any conversions on image data.
4737
4738 \sa colorSpace()
4739*/
4740void QImage::setColorSpace(const QColorSpace &colorSpace)
4741{
4742 if (!d)
4743 return;
4744 if (d->colorSpace == colorSpace)
4745 return;
4746 if (!isDetached()) // Detach only if shared, not for read-only data.
4747 detach();
4748 d->colorSpace = colorSpace;
4749}
4750
4751/*!
4752 \since 5.14
4753
4754 Converts the image to \a colorSpace.
4755
4756 If the image has no valid color space, the method does nothing.
4757
4758 \sa convertedToColorSpace(), setColorSpace()
4759*/
4760void QImage::convertToColorSpace(const QColorSpace &colorSpace)
4761{
4762 if (!d)
4763 return;
4764 if (!d->colorSpace.isValid())
4765 return;
4766 if (!colorSpace.isValid()) {
4767 qWarning() << "QImage::convertToColorSpace: Output colorspace is not valid";
4768 return;
4769 }
4770 detach();
4771 applyColorTransform(d->colorSpace.transformationToColorSpace(colorSpace));
4772 d->colorSpace = colorSpace;
4773}
4774
4775/*!
4776 \since 5.14
4777
4778 Returns the image converted to \a colorSpace.
4779
4780 If the image has no valid color space, a null QImage is returned.
4781
4782 \sa convertToColorSpace()
4783*/
4784QImage QImage::convertedToColorSpace(const QColorSpace &colorSpace) const
4785{
4786 if (!d || !d->colorSpace.isValid() || !colorSpace.isValid())
4787 return QImage();
4788 QImage image = copy();
4789 image.convertToColorSpace(colorSpace);
4790 return image;
4791}
4792
4793/*!
4794 \since 5.14
4795
4796 Returns the color space of the image if a color space is defined.
4797*/
4798QColorSpace QImage::colorSpace() const
4799{
4800 if (!d)
4801 return QColorSpace();
4802 return d->colorSpace;
4803}
4804
4805/*!
4806 \since 5.14
4807
4808 Applies the color transformation \a transform to all pixels in the image.
4809*/
4810void QImage::applyColorTransform(const QColorTransform &transform)
4811{
4812 QImage::Format oldFormat = format();
4813 if (depth() > 32) {
4814 if (format() != QImage::Format_RGBX64 && format() != QImage::Format_RGBA64
4815 && format() != QImage::Format_RGBA64_Premultiplied)
4816 *this = std::move(*this).convertToFormat(QImage::Format_RGBA64);
4817 } else if (format() != QImage::Format_ARGB32 && format() != QImage::Format_RGB32
4818 && format() != QImage::Format_ARGB32_Premultiplied) {
4819 if (hasAlphaChannel())
4820 *this = std::move(*this).convertToFormat(QImage::Format_ARGB32);
4821 else
4822 *this = std::move(*this).convertToFormat(QImage::Format_RGB32);
4823 }
4824
4825 QColorTransformPrivate::TransformFlags flags = QColorTransformPrivate::Unpremultiplied;
4826 switch (format()) {
4827 case Format_ARGB32_Premultiplied:
4828 case Format_RGBA64_Premultiplied:
4829 flags = QColorTransformPrivate::Premultiplied;
4830 break;
4831 case Format_RGB32:
4832 case Format_RGBX64:
4833 flags = QColorTransformPrivate::InputOpaque;
4834 break;
4835 case Format_ARGB32:
4836 case Format_RGBA64:
4837 break;
4838 default:
4839 Q_UNREACHABLE();
4840 }
4841
4842 std::function<void(int,int)> transformSegment;
4843
4844 if (depth() > 32) {
4845 transformSegment = [&](int yStart, int yEnd) {
4846 for (int y = yStart; y < yEnd; ++y) {
4847 QRgba64 *scanline = reinterpret_cast<QRgba64 *>(scanLine(y));
4848 transform.d->apply(scanline, scanline, width(), flags);
4849 }
4850 };
4851 } else {
4852 transformSegment = [&](int yStart, int yEnd) {
4853 for (int y = yStart; y < yEnd; ++y) {
4854 QRgb *scanline = reinterpret_cast<QRgb *>(scanLine(y));
4855 transform.d->apply(scanline, scanline, width(), flags);
4856 }
4857 };
4858 }
4859
4860#if QT_CONFIG(thread) && !defined(Q_OS_WASM)
4861 int segments = sizeInBytes() / (1<<16);
4862 segments = std::min(segments, height());
4863 QThreadPool *threadPool = QThreadPool::globalInstance();
4864 if (segments > 1 && !threadPool->contains(QThread::currentThread())) {
4865 QSemaphore semaphore;
4866 int y = 0;
4867 for (int i = 0; i < segments; ++i) {
4868 int yn = (height() - y) / (segments - i);
4869 threadPool->start([&, y, yn]() {
4870 transformSegment(y, y + yn);
4871 semaphore.release(1);
4872 });
4873 y += yn;
4874 }
4875 semaphore.acquire(segments);
4876 } else
4877#endif
4878 transformSegment(0, height());
4879
4880 if (oldFormat != format())
4881 *this = std::move(*this).convertToFormat(oldFormat);
4882}
4883
4884
4885bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags)
4886{
4887 if (format == newFormat)
4888 return true;
4889
4890 // No in-place conversion if we have to detach
4891 if (ref.loadRelaxed() > 1 || !own_data)
4892 return false;
4893
4894 InPlace_Image_Converter converter = qimage_inplace_converter_map[format][newFormat];
4895 if (converter)
4896 return converter(this, flags);
4897 if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8 && !qimage_converter_map[format][newFormat]) {
4898 // Convert inplace generic, but only if there are no direct converters,
4899 // any direct ones are probably better even if not inplace.
4900 if (qt_highColorPrecision(newFormat, !qPixelLayouts[newFormat].hasAlphaChannel)
4901 && qt_highColorPrecision(format, !qPixelLayouts[format].hasAlphaChannel)) {
4902 return convert_generic_inplace_over_rgb64(this, newFormat, flags);
4903 }
4904 return convert_generic_inplace(this, newFormat, flags);
4905 }
4906 return false;
4907}
4908
4909/*!
4910 \typedef QImage::DataPtr
4911 \internal
4912*/
4913
4914/*!
4915 \fn DataPtr & QImage::data_ptr()
4916 \internal
4917*/
4918
4919#ifndef QT_NO_DEBUG_STREAM
4920QDebug operator<<(QDebug dbg, const QImage &i)
4921{
4922 QDebugStateSaver saver(dbg);
4923 dbg.nospace();
4924 dbg.noquote();
4925 dbg << "QImage(";
4926 if (i.isNull()) {
4927 dbg << "null";
4928 } else {
4929 dbg << i.size() << ",format=" << i.format() << ",depth=" << i.depth();
4930 if (i.colorCount())
4931 dbg << ",colorCount=" << i.colorCount();
4932 const int bytesPerLine = i.bytesPerLine();
4933 dbg << ",devicePixelRatio=" << i.devicePixelRatio()
4934 << ",bytesPerLine=" << bytesPerLine << ",sizeInBytes=" << i.sizeInBytes();
4935 if (dbg.verbosity() > 2 && i.height() > 0) {
4936 const int outputLength = qMin(bytesPerLine, 24);
4937 dbg << ",line0="
4938 << QByteArray(reinterpret_cast<const char *>(i.scanLine(0)), outputLength).toHex()
4939 << "...";
4940 }
4941 }
4942 dbg << ')';
4943 return dbg;
4944}
4945#endif
4946
4947static constexpr QPixelFormat pixelformats[] = {
4948 //QImage::Format_Invalid:
4949 QPixelFormat(),
4950 //QImage::Format_Mono:
4951 QPixelFormat(QPixelFormat::Indexed,
4952 /*RED*/ 1,
4953 /*GREEN*/ 0,
4954 /*BLUE*/ 0,
4955 /*FOURTH*/ 0,
4956 /*FIFTH*/ 0,
4957 /*ALPHA*/ 0,
4958 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
4959 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
4960 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
4961 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
4962 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
4963 //QImage::Format_MonoLSB:
4964 QPixelFormat(QPixelFormat::Indexed,
4965 /*RED*/ 1,
4966 /*GREEN*/ 0,
4967 /*BLUE*/ 0,
4968 /*FOURTH*/ 0,
4969 /*FIFTH*/ 0,
4970 /*ALPHA*/ 0,
4971 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
4972 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
4973 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
4974 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
4975 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
4976 //QImage::Format_Indexed8:
4977 QPixelFormat(QPixelFormat::Indexed,
4978 /*RED*/ 8,
4979 /*GREEN*/ 0,
4980 /*BLUE*/ 0,
4981 /*FOURTH*/ 0,
4982 /*FIFTH*/ 0,
4983 /*ALPHA*/ 0,
4984 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
4985 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
4986 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
4987 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
4988 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
4989 //QImage::Format_RGB32:
4990 QPixelFormat(QPixelFormat::RGB,
4991 /*RED*/ 8,
4992 /*GREEN*/ 8,
4993 /*BLUE*/ 8,
4994 /*FOURTH*/ 0,
4995 /*FIFTH*/ 0,
4996 /*ALPHA*/ 8,
4997 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
4998 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
4999 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5000 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5001 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5002 //QImage::Format_ARGB32:
5003 QPixelFormat(QPixelFormat::RGB,
5004 /*RED*/ 8,
5005 /*GREEN*/ 8,
5006 /*BLUE*/ 8,
5007 /*FOURTH*/ 0,
5008 /*FIFTH*/ 0,
5009 /*ALPHA*/ 8,
5010 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5011 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5012 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5013 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5014 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5015 //QImage::Format_ARGB32_Premultiplied:
5016 QPixelFormat(QPixelFormat::RGB,
5017 /*RED*/ 8,
5018 /*GREEN*/ 8,
5019 /*BLUE*/ 8,
5020 /*FOURTH*/ 0,
5021 /*FIFTH*/ 0,
5022 /*ALPHA*/ 8,
5023 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5024 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5025 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5026 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5027 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5028 //QImage::Format_RGB16:
5029 QPixelFormat(QPixelFormat::RGB,
5030 /*RED*/ 5,
5031 /*GREEN*/ 6,
5032 /*BLUE*/ 5,
5033 /*FOURTH*/ 0,
5034 /*FIFTH*/ 0,
5035 /*ALPHA*/ 0,
5036 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5037 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5038 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5039 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5040 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5041 //QImage::Format_ARGB8565_Premultiplied:
5042 QPixelFormat(QPixelFormat::RGB,
5043 /*RED*/ 5,
5044 /*GREEN*/ 6,
5045 /*BLUE*/ 5,
5046 /*FOURTH*/ 0,
5047 /*FIFTH*/ 0,
5048 /*ALPHA*/ 8,
5049 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5050 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5051 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5052 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5053 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5054 //QImage::Format_RGB666:
5055 QPixelFormat(QPixelFormat::RGB,
5056 /*RED*/ 6,
5057 /*GREEN*/ 6,
5058 /*BLUE*/ 6,
5059 /*FOURTH*/ 0,
5060 /*FIFTH*/ 0,
5061 /*ALPHA*/ 0,
5062 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5063 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5064 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5065 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5066 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5067 //QImage::Format_ARGB6666_Premultiplied:
5068 QPixelFormat(QPixelFormat::RGB,
5069 /*RED*/ 6,
5070 /*GREEN*/ 6,
5071 /*BLUE*/ 6,
5072 /*FOURTH*/ 0,
5073 /*FIFTH*/ 0,
5074 /*ALPHA*/ 6,
5075 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5076 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5077 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5078 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5079 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5080 //QImage::Format_RGB555:
5081 QPixelFormat(QPixelFormat::RGB,
5082 /*RED*/ 5,
5083 /*GREEN*/ 5,
5084 /*BLUE*/ 5,
5085 /*FOURTH*/ 0,
5086 /*FIFTH*/ 0,
5087 /*ALPHA*/ 0,
5088 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5089 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5090 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5091 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5092 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5093 //QImage::Format_ARGB8555_Premultiplied:
5094 QPixelFormat(QPixelFormat::RGB,
5095 /*RED*/ 5,
5096 /*GREEN*/ 5,
5097 /*BLUE*/ 5,
5098 /*FOURTH*/ 0,
5099 /*FIFTH*/ 0,
5100 /*ALPHA*/ 8,
5101 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5102 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5103 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5104 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5105 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5106 //QImage::Format_RGB888:
5107 QPixelFormat(QPixelFormat::RGB,
5108 /*RED*/ 8,
5109 /*GREEN*/ 8,
5110 /*BLUE*/ 8,
5111 /*FOURTH*/ 0,
5112 /*FIFTH*/ 0,
5113 /*ALPHA*/ 0,
5114 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5115 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5116 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5117 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5118 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5119 //QImage::Format_RGB444:
5120 QPixelFormat(QPixelFormat::RGB,
5121 /*RED*/ 4,
5122 /*GREEN*/ 4,
5123 /*BLUE*/ 4,
5124 /*FOURTH*/ 0,
5125 /*FIFTH*/ 0,
5126 /*ALPHA*/ 0,
5127 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5128 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5129 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5130 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5131 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5132 //QImage::Format_ARGB4444_Premultiplied:
5133 QPixelFormat(QPixelFormat::RGB,
5134 /*RED*/ 4,
5135 /*GREEN*/ 4,
5136 /*BLUE*/ 4,
5137 /*FOURTH*/ 0,
5138 /*FIFTH*/ 0,
5139 /*ALPHA*/ 4,
5140 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5141 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5142 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5143 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5144 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5145 //QImage::Format_RGBX8888:
5146 QPixelFormat(QPixelFormat::RGB,
5147 /*RED*/ 8,
5148 /*GREEN*/ 8,
5149 /*BLUE*/ 8,
5150 /*FOURTH*/ 0,
5151 /*FIFTH*/ 0,
5152 /*ALPHA*/ 8,
5153 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5154 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5155 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5156 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5157 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5158 //QImage::Format_RGBA8888:
5159 QPixelFormat(QPixelFormat::RGB,
5160 /*RED*/ 8,
5161 /*GREEN*/ 8,
5162 /*BLUE*/ 8,
5163 /*FOURTH*/ 0,
5164 /*FIFTH*/ 0,
5165 /*ALPHA*/ 8,
5166 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5167 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5168 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5169 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5170 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5171 //QImage::Format_RGBA8888_Premultiplied:
5172 QPixelFormat(QPixelFormat::RGB,
5173 /*RED*/ 8,
5174 /*GREEN*/ 8,
5175 /*BLUE*/ 8,
5176 /*FOURTH*/ 0,
5177 /*FIFTH*/ 0,
5178 /*ALPHA*/ 8,
5179 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5180 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5181 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5182 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5183 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5184 //QImage::Format_BGR30:
5185 QPixelFormat(QPixelFormat::BGR,
5186 /*RED*/ 10,
5187 /*GREEN*/ 10,
5188 /*BLUE*/ 10,
5189 /*FOURTH*/ 0,
5190 /*FIFTH*/ 0,
5191 /*ALPHA*/ 2,
5192 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5193 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5194 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5195 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5196 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5197 //QImage::Format_A2BGR30_Premultiplied:
5198 QPixelFormat(QPixelFormat::BGR,
5199 /*RED*/ 10,
5200 /*GREEN*/ 10,
5201 /*BLUE*/ 10,
5202 /*FOURTH*/ 0,
5203 /*FIFTH*/ 0,
5204 /*ALPHA*/ 2,
5205 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5206 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5207 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5208 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5209 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5210 //QImage::Format_RGB30:
5211 QPixelFormat(QPixelFormat::RGB,
5212 /*RED*/ 10,
5213 /*GREEN*/ 10,
5214 /*BLUE*/ 10,
5215 /*FOURTH*/ 0,
5216 /*FIFTH*/ 0,
5217 /*ALPHA*/ 2,
5218 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5219 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5220 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5221 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5222 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5223 //QImage::Format_A2RGB30_Premultiplied:
5224 QPixelFormat(QPixelFormat::RGB,
5225 /*RED*/ 10,
5226 /*GREEN*/ 10,
5227 /*BLUE*/ 10,
5228 /*FOURTH*/ 0,
5229 /*FIFTH*/ 0,
5230 /*ALPHA*/ 2,
5231 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5232 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5233 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5234 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5235 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5236 //QImage::Format_Alpha8:
5237 QPixelFormat(QPixelFormat::Alpha,
5238 /*First*/ 0,
5239 /*SECOND*/ 0,
5240 /*THIRD*/ 0,
5241 /*FOURTH*/ 0,
5242 /*FIFTH*/ 0,
5243 /*ALPHA*/ 8,
5244 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5245 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5246 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5247 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5248 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5249 //QImage::Format_Grayscale8:
5250 QPixelFormat(QPixelFormat::Grayscale,
5251 /*GRAY*/ 8,
5252 /*SECOND*/ 0,
5253 /*THIRD*/ 0,
5254 /*FOURTH*/ 0,
5255 /*FIFTH*/ 0,
5256 /*ALPHA*/ 0,
5257 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5258 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5259 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5260 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5261 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5262 //QImage::Format_RGBX64:
5263 QPixelFormat(QPixelFormat::RGB,
5264 /*RED*/ 16,
5265 /*GREEN*/ 16,
5266 /*BLUE*/ 16,
5267 /*FOURTH*/ 0,
5268 /*FIFTH*/ 0,
5269 /*ALPHA*/ 16,
5270 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5271 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5272 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5273 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5274 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5275 //QImage::Format_RGBA64:
5276 QPixelFormat(QPixelFormat::RGB,
5277 /*RED*/ 16,
5278 /*GREEN*/ 16,
5279 /*BLUE*/ 16,
5280 /*FOURTH*/ 0,
5281 /*FIFTH*/ 0,
5282 /*ALPHA*/ 16,
5283 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5284 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5285 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5286 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5287 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5288 //QImage::Format_RGBA64_Premultiplied:
5289 QPixelFormat(QPixelFormat::RGB,
5290 /*RED*/ 16,
5291 /*GREEN*/ 16,
5292 /*BLUE*/ 16,
5293 /*FOURTH*/ 0,
5294 /*FIFTH*/ 0,
5295 /*ALPHA*/ 16,
5296 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5297 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5298 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5299 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5300 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5301 //QImage::Format_Grayscale16:
5302 QPixelFormat(QPixelFormat::Grayscale,
5303 /*GRAY*/ 16,
5304 /*SECOND*/ 0,
5305 /*THIRD*/ 0,
5306 /*FOURTH*/ 0,
5307 /*FIFTH*/ 0,
5308 /*ALPHA*/ 0,
5309 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5310 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5311 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5312 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5313 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5314 //QImage::Format_BGR888:
5315 QPixelFormat(QPixelFormat::BGR,
5316 /*RED*/ 8,
5317 /*GREEN*/ 8,
5318 /*BLUE*/ 8,
5319 /*FOURTH*/ 0,
5320 /*FIFTH*/ 0,
5321 /*ALPHA*/ 0,
5322 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5323 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5324 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5325 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5326 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5327};
5328static_assert(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
5329
5330/*!
5331 Returns the QImage::Format as a QPixelFormat
5332*/
5333QPixelFormat QImage::pixelFormat() const noexcept
5334{
5335 return toPixelFormat(format());
5336}
5337
5338/*!
5339 Converts \a format into a QPixelFormat
5340*/
5341QPixelFormat QImage::toPixelFormat(QImage::Format format) noexcept
5342{
5343 Q_ASSERT(static_cast<int>(format) < NImageFormats);
5344 return pixelformats[format];
5345}
5346
5347/*!
5348 Converts \a format into a QImage::Format
5349*/
5350QImage::Format QImage::toImageFormat(QPixelFormat format) noexcept
5351{
5352 for (int i = 0; i < NImageFormats; i++) {
5353 if (format == pixelformats[i])
5354 return Format(i);
5355 }
5356 return Format_Invalid;
5357}
5358
5359Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient)
5360{
5361 if (orient == QImageIOHandler::TransformationNone)
5362 return;
5363 if (orient == QImageIOHandler::TransformationRotate270) {
5364 src = rotated270(src);
5365 } else {
5366 src = std::move(src).mirrored(orient & QImageIOHandler::TransformationMirror,
5367 orient & QImageIOHandler::TransformationFlip);
5368 if (orient & QImageIOHandler::TransformationRotate90)
5369 src = rotated90(src);
5370 }
5371}
5372
5373QMap<QString, QString> qt_getImageText(const QImage &image, const QString &description)
5374{
5375 QMap<QString, QString> text = qt_getImageTextFromDescription(description);
5376 const auto textKeys = image.textKeys();
5377 for (const QString &key : textKeys) {
5378 if (!key.isEmpty() && !text.contains(key))
5379 text.insert(key, image.text(key));
5380 }
5381 return text;
5382}
5383
5384QMap<QString, QString> qt_getImageTextFromDescription(const QString &description)
5385{
5386 QMap<QString, QString> text;
5387 const auto pairs = QStringView{description}.split(u"\n\n");
5388 for (const auto &pair : pairs) {
5389 int index = pair.indexOf(QLatin1Char(':'));
5390 if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) {
5391 if (!pair.trimmed().isEmpty())
5392 text.insert(QLatin1String("Description"), pair.toString().simplified());
5393 } else {
5394 const auto key = pair.left(index);
5395 if (!key.trimmed().isEmpty())
5396 text.insert(key.toString(), pair.mid(index + 2).toString().simplified());
5397 }
5398 }
5399 return text;
5400}
5401
5402QT_END_NAMESPACE
5403