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

source code of qtbase/src/gui/image/qimage.cpp