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
79 QT_BEGIN_NAMESPACE
80
isLocked(QImageData * data)81 static 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
98 static QImage rotated90(const QImage &src);
99 static QImage rotated180(const QImage &src);
100 static QImage rotated270(const QImage &src);
101
next_qimage_serial_number()102 static int next_qimage_serial_number()
103 {
104 static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0);
105 return 1 + serial.fetchAndAddRelaxed(1);
106 }
107
QImageData()108 QImageData::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 */
create(const QSize & size,QImage::Format format)128 QImageData * 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(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(d->nbytes);
165
166 if (!d->data)
167 return nullptr;
168
169 d->ref.ref();
170 return d.take();
171 }
172
~QImageData()173 QImageData::~QImageData()
174 {
175 if (cleanupFunction)
176 cleanupFunction(cleanupInfo);
177 if (is_cached)
178 QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no));
179 delete paintEngine;
180 if (data && own_data)
181 free(data);
182 data = nullptr;
183 }
184
185 #if defined(_M_ARM) && defined(_MSC_VER)
186 #pragma optimize("", off)
187 #endif
188
checkForAlphaPixels() const189 bool 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
QImage()755 QImage::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 */
QImage(int width,int height,Format format)771 QImage::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 */
QImage(const QSize & size,Format format)785 QImage::QImage(const QSize &size, Format format)
786 : QPaintDevice()
787 {
788 d = QImageData::create(size, format);
789 }
790
791
792
create(uchar * data,int width,int height,int bpl,QImage::Format format,bool readOnly,QImageCleanupFunction cleanupFunction,void * cleanupInfo)793 QImageData *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>(bpl, height, ¶ms.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 */
QImage(uchar * data,int width,int height,Format format,QImageCleanupFunction cleanupFunction,void * cleanupInfo)852 QImage::QImage(uchar* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
853 : QPaintDevice()
854 {
855 d = QImageData::create(data, width, height, 0, format, 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 */
QImage(const uchar * data,int width,int height,Format format,QImageCleanupFunction cleanupFunction,void * cleanupInfo)883 QImage::QImage(const uchar* data, int width, int height, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
884 : QPaintDevice()
885 {
886 d = QImageData::create(const_cast<uchar*>(data), width, height, 0, format, 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 */
QImage(uchar * data,int width,int height,int bytesPerLine,Format format,QImageCleanupFunction cleanupFunction,void * cleanupInfo)906 QImage::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, bytesPerLine, format, 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
QImage(const uchar * data,int width,int height,int bytesPerLine,Format format,QImageCleanupFunction cleanupFunction,void * cleanupInfo)938 QImage::QImage(const uchar *data, int width, int height, int bytesPerLine, Format format, QImageCleanupFunction cleanupFunction, void *cleanupInfo)
939 :QPaintDevice()
940 {
941 d = QImageData::create(const_cast<uchar*>(data), width, height, bytesPerLine, format, 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
QImage(const QString & fileName,const char * format)964 QImage::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
972 extern 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
QImage(const char * const xpm[])990 QImage::QImage(const char * const xpm[])
991 : QPaintDevice()
992 {
993 d = nullptr;
994 if (!xpm)
995 return;
996 if (!qt_read_xpm_image_or_array(nullptr, xpm, *this))
997 // Issue: Warning because the constructor may be ambigious
998 qWarning("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
QImage(const QImage & image)1011 QImage::QImage(const QImage &image)
1012 : QPaintDevice()
1013 {
1014 if (image.paintingActive() || isLocked(image.d)) {
1015 d = nullptr;
1016 image.copy().swap(*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
~QImage()1028 QImage::~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
operator =(const QImage & image)1044 QImage &QImage::operator=(const QImage &image)
1045 {
1046 if (image.paintingActive() || isLocked(image.d)) {
1047 operator=(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 */
devType() const1069 int QImage::devType() const
1070 {
1071 return QInternal::Image;
1072 }
1073
1074 /*!
1075 Returns the image as a QVariant.
1076 */
operator QVariant() const1077 QImage::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 */
detach()1093 void QImage::detach()
1094 {
1095 if (d) {
1096 if (d->is_cached && d->ref.loadRelaxed() == 1)
1097 QImagePixmapCleanupHooks::executeImageHooks(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
copyPhysicalMetadata(QImageData * dst,const QImageData * src)1108 static 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
copyMetadata(QImageData * dst,const QImageData * src)1115 static 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
copyMetadata(QImage * dst,const QImage & src)1123 static 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, 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 */
copy(const QRect & r) const1164 QImage 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(bytesPerLine(), image.bytesPerLine());
1179 for (int i = 0; i < height(); i++)
1180 memcpy(image.scanLine(i), scanLine(i), bpl);
1181 } else
1182 memcpy(image.bits(), bits(), 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(image.d, 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(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(w - dx, 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(h - dy, 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, src, 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(image.d, 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 */
isNull() const1286 bool 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 */
width() const1298 int 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 */
height() const1310 int 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 */
size() const1322 QSize 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 */
rect() const1335 QRect 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 */
depth() const1352 int 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 */
colorCount() const1378 int 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)
setColorTable(const QVector<QRgb> & colors)1395 void QImage::setColorTable(const QVector<QRgb> &colors)
1396 #else
1397 void 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(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 */
colorTable() const1428 QVector<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 */
devicePixelRatio() const1444 qreal 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 */
setDevicePixelRatio(qreal scaleFactor)1472 void 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 */
byteCount() const1497 int 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 */
sizeInBytes() const1511 qsizetype 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)
bytesPerLine() const1524 qsizetype QImage::bytesPerLine() const
1525 {
1526 return d ? d->bytes_per_line : 0;
1527 }
1528 #else
bytesPerLine() const1529 int 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 */
color(int i) const1547 QRgb 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 */
setColor(int i,QRgb c)1565 void 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("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(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 */
scanLine(int i)1603 uchar *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 */
scanLine(int i) const1620 const 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 */
constScanLine(int i) const1645 const 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 */
bits()1665 uchar *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 */
bits() const1685 const 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 */
constBits() const1701 const 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
fill(uint pixel)1726 void 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>(d->data, pixel, 0, 0,
1749 w, d->height, d->bytes_per_line);
1750 return;
1751 } else if (d->depth == 16) {
1752 qt_rectfill<quint16>(reinterpret_cast<quint16*>(d->data), pixel,
1753 0, 0, d->width, d->height, d->bytes_per_line);
1754 return;
1755 } else if (d->depth == 24) {
1756 qt_rectfill<quint24>(reinterpret_cast<quint24*>(d->data), pixel,
1757 0, 0, d->width, d->height, d->bytes_per_line);
1758 return;
1759 } else if (d->depth == 64) {
1760 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), QRgba64::fromArgb32(pixel),
1761 0, 0, d->width, d->height, d->bytes_per_line);
1762 return;
1763 }
1764
1765 if (d->format == Format_RGB32)
1766 pixel |= 0xff000000;
1767 if (d->format == Format_RGBX8888)
1768 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
1769 pixel |= 0xff000000;
1770 #else
1771 pixel |= 0x000000ff;
1772 #endif
1773 if (d->format == Format_BGR30 || d->format == Format_RGB30)
1774 pixel |= 0xc0000000;
1775
1776 qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
1777 0, 0, d->width, d->height, d->bytes_per_line);
1778 }
1779
1780
1781 /*!
1782 \fn void QImage::fill(Qt::GlobalColor color)
1783 \overload
1784 \since 4.8
1785
1786 Fills the image with the given \a color, described as a standard global
1787 color.
1788 */
1789
fill(Qt::GlobalColor color)1790 void QImage::fill(Qt::GlobalColor color)
1791 {
1792 fill(QColor(color));
1793 }
1794
1795
1796
1797 /*!
1798 \fn void QImage::fill(const QColor &color)
1799
1800 \overload
1801
1802 Fills the entire image with the given \a color.
1803
1804 If the depth of the image is 1, the image will be filled with 1 if
1805 \a color equals Qt::color1; it will otherwise be filled with 0.
1806
1807 If the depth of the image is 8, the image will be filled with the
1808 index corresponding the \a color in the color table if present; it
1809 will otherwise be filled with 0.
1810
1811 \since 4.8
1812 */
1813
fill(const QColor & color)1814 void QImage::fill(const QColor &color)
1815 {
1816 if (!d)
1817 return;
1818 detach();
1819
1820 // In case we run out of memory
1821 if (!d)
1822 return;
1823
1824 switch (d->format) {
1825 case QImage::Format_RGB32:
1826 case QImage::Format_ARGB32:
1827 fill(color.rgba());
1828 break;
1829 case QImage::Format_ARGB32_Premultiplied:
1830 fill(qPremultiply(color.rgba()));
1831 break;
1832 case QImage::Format_RGBX8888:
1833 fill(ARGB2RGBA(color.rgba() | 0xff000000));
1834 break;
1835 case QImage::Format_RGBA8888:
1836 fill(ARGB2RGBA(color.rgba()));
1837 break;
1838 case QImage::Format_RGBA8888_Premultiplied:
1839 fill(ARGB2RGBA(qPremultiply(color.rgba())));
1840 break;
1841 case QImage::Format_BGR30:
1842 case QImage::Format_A2BGR30_Premultiplied:
1843 fill(qConvertRgb64ToRgb30<PixelOrderBGR>(color.rgba64()));
1844 break;
1845 case QImage::Format_RGB30:
1846 case QImage::Format_A2RGB30_Premultiplied:
1847 fill(qConvertRgb64ToRgb30<PixelOrderRGB>(color.rgba64()));
1848 break;
1849 case QImage::Format_RGB16:
1850 fill((uint) qConvertRgb32To16(color.rgba()));
1851 break;
1852 case QImage::Format_Indexed8: {
1853 uint pixel = 0;
1854 for (int i=0; i<d->colortable.size(); ++i) {
1855 if (color.rgba() == d->colortable.at(i)) {
1856 pixel = i;
1857 break;
1858 }
1859 }
1860 fill(pixel);
1861 break;
1862 }
1863 case QImage::Format_Mono:
1864 case QImage::Format_MonoLSB:
1865 if (color == Qt::color1)
1866 fill((uint) 1);
1867 else
1868 fill((uint) 0);
1869 break;
1870 case QImage::Format_RGBX64: {
1871 QRgba64 c = color.rgba64();
1872 c.setAlpha(65535);
1873 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), c,
1874 0, 0, d->width, d->height, d->bytes_per_line);
1875 break;
1876
1877 }
1878 case QImage::Format_RGBA64:
1879 case QImage::Format_RGBA64_Premultiplied:
1880 qt_rectfill<quint64>(reinterpret_cast<quint64*>(d->data), color.rgba64(),
1881 0, 0, d->width, d->height, d->bytes_per_line);
1882 break;
1883 default: {
1884 QPainter p(this);
1885 p.setCompositionMode(QPainter::CompositionMode_Source);
1886 p.fillRect(rect(), color);
1887 }}
1888 }
1889
1890
1891
1892 /*!
1893 Inverts all pixel values in the image.
1894
1895 The given invert \a mode only have a meaning when the image's
1896 depth is 32. The default \a mode is InvertRgb, which leaves the
1897 alpha channel unchanged. If the \a mode is InvertRgba, the alpha
1898 bits are also inverted.
1899
1900 Inverting an 8-bit image means to replace all pixels using color
1901 index \e i with a pixel using color index 255 minus \e i. The same
1902 is the case for a 1-bit image. Note that the color table is \e not
1903 changed.
1904
1905 If the image has a premultiplied alpha channel, the image is first
1906 converted to an unpremultiplied image format to be inverted and
1907 then converted back.
1908
1909 \sa {QImage#Image Transformations}{Image Transformations}
1910 */
1911
invertPixels(InvertMode mode)1912 void QImage::invertPixels(InvertMode mode)
1913 {
1914 if (!d)
1915 return;
1916
1917 detach();
1918
1919 // In case detach() ran out of memory
1920 if (!d)
1921 return;
1922
1923 QImage::Format originalFormat = d->format;
1924 // Inverting premultiplied pixels would produce invalid image data.
1925 if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied) {
1926 if (depth() > 32) {
1927 if (!d->convertInPlace(QImage::Format_RGBA64, { }))
1928 *this = convertToFormat(QImage::Format_RGBA64);
1929 } else {
1930 if (!d->convertInPlace(QImage::Format_ARGB32, { }))
1931 *this = convertToFormat(QImage::Format_ARGB32);
1932 }
1933 }
1934
1935 if (depth() < 32) {
1936 // This assumes no alpha-channel as the only formats with non-premultipled alpha are 32bit.
1937 int bpl = (d->width * d->depth + 7) / 8;
1938 int pad = d->bytes_per_line - bpl;
1939 uchar *sl = d->data;
1940 for (int y=0; y<d->height; ++y) {
1941 for (int x=0; x<bpl; ++x)
1942 *sl++ ^= 0xff;
1943 sl += pad;
1944 }
1945 }
1946 else if (depth() == 64) {
1947 quint16 *p = (quint16*)d->data;
1948 quint16 *end = (quint16*)(d->data + d->nbytes);
1949 quint16 xorbits = 0xffff;
1950 while (p < end) {
1951 *p++ ^= xorbits;
1952 *p++ ^= xorbits;
1953 *p++ ^= xorbits;
1954 if (mode == InvertRgba)
1955 *p++ ^= xorbits;
1956 else
1957 p++;
1958 }
1959 } else {
1960 quint32 *p = (quint32*)d->data;
1961 quint32 *end = (quint32*)(d->data + d->nbytes);
1962 quint32 xorbits = 0xffffffff;
1963 switch (d->format) {
1964 case QImage::Format_RGBA8888:
1965 if (mode == InvertRgba)
1966 break;
1967 Q_FALLTHROUGH();
1968 case QImage::Format_RGBX8888:
1969 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
1970 xorbits = 0xffffff00;
1971 break;
1972 #else
1973 xorbits = 0x00ffffff;
1974 break;
1975 #endif
1976 case QImage::Format_ARGB32:
1977 if (mode == InvertRgba)
1978 break;
1979 Q_FALLTHROUGH();
1980 case QImage::Format_RGB32:
1981 xorbits = 0x00ffffff;
1982 break;
1983 case QImage::Format_BGR30:
1984 case QImage::Format_RGB30:
1985 xorbits = 0x3fffffff;
1986 break;
1987 default:
1988 Q_UNREACHABLE();
1989 xorbits = 0;
1990 break;
1991 }
1992 while (p < end)
1993 *p++ ^= xorbits;
1994 }
1995
1996 if (originalFormat != d->format) {
1997 if (!d->convertInPlace(originalFormat, { }))
1998 *this = convertToFormat(originalFormat);
1999 }
2000 }
2001
2002 // Windows defines these
2003 #if defined(write)
2004 # undef write
2005 #endif
2006 #if defined(close)
2007 # undef close
2008 #endif
2009 #if defined(read)
2010 # undef read
2011 #endif
2012
2013 /*!
2014 \since 4.6
2015 Resizes the color table to contain \a colorCount entries.
2016
2017 If the color table is expanded, all the extra colors will be set to
2018 transparent (i.e qRgba(0, 0, 0, 0)).
2019
2020 When the image is used, the color table must be large enough to
2021 have entries for all the pixel/index values present in the image,
2022 otherwise the results are undefined.
2023
2024 \sa colorCount(), colorTable(), setColor(), {QImage#Image
2025 Transformations}{Image Transformations}
2026 */
2027
setColorCount(int colorCount)2028 void QImage::setColorCount(int colorCount)
2029 {
2030 if (!d) {
2031 qWarning("QImage::setColorCount: null image");
2032 return;
2033 }
2034
2035 detach();
2036
2037 // In case detach() ran out of memory
2038 if (!d)
2039 return;
2040
2041 if (colorCount == d->colortable.size())
2042 return;
2043 if (colorCount <= 0) { // use no color table
2044 d->colortable = QVector<QRgb>();
2045 return;
2046 }
2047 int nc = d->colortable.size();
2048 d->colortable.resize(colorCount);
2049 for (int i = nc; i < colorCount; ++i)
2050 d->colortable[i] = 0;
2051 }
2052
2053 /*!
2054 Returns the format of the image.
2055
2056 \sa {QImage#Image Formats}{Image Formats}
2057 */
format() const2058 QImage::Format QImage::format() const
2059 {
2060 return d ? d->format : Format_Invalid;
2061 }
2062
2063 /*!
2064 \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const &
2065 \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) &&
2066
2067 Returns a copy of the image in the given \a format.
2068
2069 The specified image conversion \a flags control how the image data
2070 is handled during the conversion process.
2071
2072 \sa {Image Formats}
2073 */
2074
2075 /*!
2076 \internal
2077 */
convertToFormat_helper(Format format,Qt::ImageConversionFlags flags) const2078 QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags flags) const
2079 {
2080 if (!d || d->format == format)
2081 return *this;
2082
2083 if (format == Format_Invalid || d->format == Format_Invalid)
2084 return QImage();
2085
2086 const QPixelLayout *destLayout = &qPixelLayouts[format];
2087 Image_Converter converter = qimage_converter_map[d->format][format];
2088 if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) {
2089 if (qt_highColorPrecision(d->format, !destLayout->hasAlphaChannel)
2090 && qt_highColorPrecision(format, !hasAlphaChannel())) {
2091 converter = convert_generic_to_rgb64;
2092 } else
2093 converter = convert_generic;
2094 }
2095 if (converter) {
2096 QImage image(d->width, d->height, format);
2097
2098 QIMAGE_SANITYCHECK_MEMORY(image);
2099
2100 image.d->offset = offset();
2101 copyMetadata(image.d, d);
2102
2103 converter(image.d, d, flags);
2104 return image;
2105 }
2106
2107 // Convert indexed formats over ARGB32 or RGB32 to the final format.
2108 Q_ASSERT(format != QImage::Format_ARGB32 && format != QImage::Format_RGB32);
2109 Q_ASSERT(d->format != QImage::Format_ARGB32 && d->format != QImage::Format_RGB32);
2110
2111 if (!hasAlphaChannel())
2112 return convertToFormat(Format_RGB32, flags).convertToFormat(format, flags);
2113
2114 return convertToFormat(Format_ARGB32, flags).convertToFormat(format, flags);
2115 }
2116
2117 /*!
2118 \internal
2119 */
convertToFormat_inplace(Format format,Qt::ImageConversionFlags flags)2120 bool QImage::convertToFormat_inplace(Format format, Qt::ImageConversionFlags flags)
2121 {
2122 return d && d->convertInPlace(format, flags);
2123 }
2124
pixel_distance(QRgb p1,QRgb p2)2125 static inline int pixel_distance(QRgb p1, QRgb p2) {
2126 int r1 = qRed(p1);
2127 int g1 = qGreen(p1);
2128 int b1 = qBlue(p1);
2129 int a1 = qAlpha(p1);
2130
2131 int r2 = qRed(p2);
2132 int g2 = qGreen(p2);
2133 int b2 = qBlue(p2);
2134 int a2 = qAlpha(p2);
2135
2136 return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) + abs(a1 - a2);
2137 }
2138
closestMatch(QRgb pixel,const QVector<QRgb> & clut)2139 static inline int closestMatch(QRgb pixel, const QVector<QRgb> &clut) {
2140 int idx = 0;
2141 int current_distance = INT_MAX;
2142 for (int i=0; i<clut.size(); ++i) {
2143 int dist = pixel_distance(pixel, clut.at(i));
2144 if (dist < current_distance) {
2145 current_distance = dist;
2146 idx = i;
2147 }
2148 }
2149 return idx;
2150 }
2151
convertWithPalette(const QImage & src,QImage::Format format,const QVector<QRgb> & clut)2152 static QImage convertWithPalette(const QImage &src, QImage::Format format,
2153 const QVector<QRgb> &clut) {
2154 QImage dest(src.size(), format);
2155 dest.setColorTable(clut);
2156
2157 QImageData::get(dest)->text = QImageData::get(src)->text;
2158
2159 int h = src.height();
2160 int w = src.width();
2161
2162 QHash<QRgb, int> cache;
2163
2164 if (format == QImage::Format_Indexed8) {
2165 for (int y=0; y<h; ++y) {
2166 const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
2167 uchar *dest_pixels = (uchar *) dest.scanLine(y);
2168 for (int x=0; x<w; ++x) {
2169 int src_pixel = src_pixels[x];
2170 int value = cache.value(src_pixel, -1);
2171 if (value == -1) {
2172 value = closestMatch(src_pixel, clut);
2173 cache.insert(src_pixel, value);
2174 }
2175 dest_pixels[x] = (uchar) value;
2176 }
2177 }
2178 } else {
2179 QVector<QRgb> table = clut;
2180 table.resize(2);
2181 for (int y=0; y<h; ++y) {
2182 const QRgb *src_pixels = (const QRgb *) src.scanLine(y);
2183 for (int x=0; x<w; ++x) {
2184 int src_pixel = src_pixels[x];
2185 int value = cache.value(src_pixel, -1);
2186 if (value == -1) {
2187 value = closestMatch(src_pixel, table);
2188 cache.insert(src_pixel, value);
2189 }
2190 dest.setPixel(x, y, value);
2191 }
2192 }
2193 }
2194
2195 return dest;
2196 }
2197
2198 /*!
2199 \overload
2200
2201 Returns a copy of the image converted to the given \a format,
2202 using the specified \a colorTable.
2203
2204 Conversion from RGB formats to indexed formats is a slow operation
2205 and will use a straightforward nearest color approach, with no
2206 dithering.
2207 */
convertToFormat(Format format,const QVector<QRgb> & colorTable,Qt::ImageConversionFlags flags) const2208 QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags) const
2209 {
2210 if (!d || d->format == format)
2211 return *this;
2212
2213 if (format == QImage::Format_Invalid)
2214 return QImage();
2215 if (format <= QImage::Format_Indexed8)
2216 return convertWithPalette(convertToFormat(QImage::Format_ARGB32, flags), format, colorTable);
2217
2218 return convertToFormat(format, flags);
2219 }
2220
2221 /*!
2222 \since 5.9
2223
2224 Changes the format of the image to \a format without changing the
2225 data. Only works between formats of the same depth.
2226
2227 Returns \c true if successful.
2228
2229 This function can be used to change images with alpha-channels to
2230 their corresponding opaque formats if the data is known to be opaque-only,
2231 or to change the format of a given image buffer before overwriting
2232 it with new data.
2233
2234 \warning The function does not check if the image data is valid in the
2235 new format and will still return \c true if the depths are compatible.
2236 Operations on an image with invalid data are undefined.
2237
2238 \warning If the image is not detached, this will cause the data to be
2239 copied.
2240
2241 \sa hasAlphaChannel(), convertToFormat()
2242 */
2243
reinterpretAsFormat(Format format)2244 bool QImage::reinterpretAsFormat(Format format)
2245 {
2246 if (!d)
2247 return false;
2248 if (d->format == format)
2249 return true;
2250 if (qt_depthForFormat(format) != qt_depthForFormat(d->format))
2251 return false;
2252 if (!isDetached()) { // Detach only if shared, not for read-only data.
2253 QImageData *oldD = d;
2254 detach();
2255 // In case detach() ran out of memory
2256 if (!d) {
2257 d = oldD;
2258 d->ref.ref();
2259 return false;
2260 }
2261 }
2262
2263 d->format = format;
2264 return true;
2265 }
2266
2267 /*!
2268 \since 5.13
2269
2270 Detach and convert the image to the given \a format in place.
2271
2272 The specified image conversion \a flags control how the image data
2273 is handled during the conversion process.
2274
2275 \sa convertToFormat()
2276 */
2277
convertTo(Format format,Qt::ImageConversionFlags flags)2278 void QImage::convertTo(Format format, Qt::ImageConversionFlags flags)
2279 {
2280 if (!d || format == QImage::Format_Invalid)
2281 return;
2282
2283 detach();
2284 if (convertToFormat_inplace(format, flags))
2285 return;
2286
2287 *this = convertToFormat_helper(format, flags);
2288 }
2289
2290 /*!
2291 \fn bool QImage::valid(const QPoint &pos) const
2292
2293 Returns \c true if \a pos is a valid coordinate pair within the
2294 image; otherwise returns \c false.
2295
2296 \sa rect(), QRect::contains()
2297 */
2298
2299 /*!
2300 \overload
2301
2302 Returns \c true if QPoint(\a x, \a y) is a valid coordinate pair
2303 within the image; otherwise returns \c false.
2304 */
valid(int x,int y) const2305 bool QImage::valid(int x, int y) const
2306 {
2307 return d
2308 && x >= 0 && x < d->width
2309 && y >= 0 && y < d->height;
2310 }
2311
2312 /*!
2313 \fn int QImage::pixelIndex(const QPoint &position) const
2314
2315 Returns the pixel index at the given \a position.
2316
2317 If \a position is not valid, or if the image is not a paletted
2318 image (depth() > 8), the results are undefined.
2319
2320 \sa valid(), depth(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2321 */
2322
2323 /*!
2324 \overload
2325
2326 Returns the pixel index at (\a x, \a y).
2327 */
pixelIndex(int x,int y) const2328 int QImage::pixelIndex(int x, int y) const
2329 {
2330 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
2331 qWarning("QImage::pixelIndex: coordinate (%d,%d) out of range", x, y);
2332 return -12345;
2333 }
2334 const uchar * s = scanLine(y);
2335 switch(d->format) {
2336 case Format_Mono:
2337 return (*(s + (x >> 3)) >> (7- (x & 7))) & 1;
2338 case Format_MonoLSB:
2339 return (*(s + (x >> 3)) >> (x & 7)) & 1;
2340 case Format_Indexed8:
2341 return (int)s[x];
2342 default:
2343 qWarning("QImage::pixelIndex: Not applicable for %d-bpp images (no palette)", d->depth);
2344 }
2345 return 0;
2346 }
2347
2348
2349 /*!
2350 \fn QRgb QImage::pixel(const QPoint &position) const
2351
2352 Returns the color of the pixel at the given \a position.
2353
2354 If the \a position is not valid, the results are undefined.
2355
2356 \warning This function is expensive when used for massive pixel
2357 manipulations. Use constBits() or constScanLine() when many
2358 pixels needs to be read.
2359
2360 \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
2361 Manipulation}
2362 */
2363
2364 /*!
2365 \overload
2366
2367 Returns the color of the pixel at coordinates (\a x, \a y).
2368 */
pixel(int x,int y) const2369 QRgb QImage::pixel(int x, int y) const
2370 {
2371 if (!d || x < 0 || x >= d->width || y < 0 || y >= d->height) {
2372 qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
2373 return 12345;
2374 }
2375
2376 const uchar *s = d->data + y * d->bytes_per_line;
2377
2378 int index = -1;
2379 switch (d->format) {
2380 case Format_Mono:
2381 index = (*(s + (x >> 3)) >> (~x & 7)) & 1;
2382 break;
2383 case Format_MonoLSB:
2384 index = (*(s + (x >> 3)) >> (x & 7)) & 1;
2385 break;
2386 case Format_Indexed8:
2387 index = s[x];
2388 break;
2389 default:
2390 break;
2391 }
2392 if (index >= 0) { // Indexed format
2393 if (index >= d->colortable.size()) {
2394 qWarning("QImage::pixel: color table index %d out of range.", index);
2395 return 0;
2396 }
2397 return d->colortable.at(index);
2398 }
2399
2400 switch (d->format) {
2401 case Format_RGB32:
2402 return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x];
2403 case Format_ARGB32: // Keep old behaviour.
2404 case Format_ARGB32_Premultiplied:
2405 return reinterpret_cast<const QRgb *>(s)[x];
2406 case Format_RGBX8888:
2407 case Format_RGBA8888: // Match ARGB32 behavior.
2408 case Format_RGBA8888_Premultiplied:
2409 return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]);
2410 case Format_BGR30:
2411 case Format_A2BGR30_Premultiplied:
2412 return qConvertA2rgb30ToArgb32<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
2413 case Format_RGB30:
2414 case Format_A2RGB30_Premultiplied:
2415 return qConvertA2rgb30ToArgb32<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
2416 case Format_RGB16:
2417 return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]);
2418 case Format_RGBX64:
2419 case Format_RGBA64: // Match ARGB32 behavior.
2420 case Format_RGBA64_Premultiplied:
2421 return reinterpret_cast<const QRgba64 *>(s)[x].toArgb32();
2422 default:
2423 break;
2424 }
2425 const QPixelLayout *layout = &qPixelLayouts[d->format];
2426 uint result;
2427 return *layout->fetchToARGB32PM(&result, s, x, 1, nullptr, nullptr);
2428 }
2429
2430 /*!
2431 \fn void QImage::setPixel(const QPoint &position, uint index_or_rgb)
2432
2433 Sets the pixel index or color at the given \a position to \a
2434 index_or_rgb.
2435
2436 If the image's format is either monochrome or paletted, the given \a
2437 index_or_rgb value must be an index in the image's color table,
2438 otherwise the parameter must be a QRgb value.
2439
2440 If \a position is not a valid coordinate pair in the image, or if
2441 \a index_or_rgb >= colorCount() in the case of monochrome and
2442 paletted images, the result is undefined.
2443
2444 \warning This function is expensive due to the call of the internal
2445 \c{detach()} function called within; if performance is a concern, we
2446 recommend the use of scanLine() or bits() to access pixel data directly.
2447
2448 \sa pixel(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2449 */
2450
2451 /*!
2452 \overload
2453
2454 Sets the pixel index or color at (\a x, \a y) to \a index_or_rgb.
2455 */
setPixel(int x,int y,uint index_or_rgb)2456 void QImage::setPixel(int x, int y, uint index_or_rgb)
2457 {
2458 if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
2459 qWarning("QImage::setPixel: coordinate (%d,%d) out of range", x, y);
2460 return;
2461 }
2462 // detach is called from within scanLine
2463 uchar * s = scanLine(y);
2464 switch(d->format) {
2465 case Format_Mono:
2466 case Format_MonoLSB:
2467 if (index_or_rgb > 1) {
2468 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
2469 } else if (format() == Format_MonoLSB) {
2470 if (index_or_rgb==0)
2471 *(s + (x >> 3)) &= ~(1 << (x & 7));
2472 else
2473 *(s + (x >> 3)) |= (1 << (x & 7));
2474 } else {
2475 if (index_or_rgb==0)
2476 *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
2477 else
2478 *(s + (x >> 3)) |= (1 << (7-(x & 7)));
2479 }
2480 return;
2481 case Format_Indexed8:
2482 if (index_or_rgb >= (uint)d->colortable.size()) {
2483 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
2484 return;
2485 }
2486 s[x] = index_or_rgb;
2487 return;
2488 case Format_RGB32:
2489 //make sure alpha is 255, we depend on it in qdrawhelper for cases
2490 // when image is set as a texture pattern on a qbrush
2491 ((uint *)s)[x] = 0xff000000 | index_or_rgb;
2492 return;
2493 case Format_ARGB32:
2494 case Format_ARGB32_Premultiplied:
2495 ((uint *)s)[x] = index_or_rgb;
2496 return;
2497 case Format_RGB16:
2498 ((quint16 *)s)[x] = qConvertRgb32To16(qUnpremultiply(index_or_rgb));
2499 return;
2500 case Format_RGBX8888:
2501 ((uint *)s)[x] = ARGB2RGBA(0xff000000 | index_or_rgb);
2502 return;
2503 case Format_RGBA8888:
2504 case Format_RGBA8888_Premultiplied:
2505 ((uint *)s)[x] = ARGB2RGBA(index_or_rgb);
2506 return;
2507 case Format_BGR30:
2508 ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderBGR>(index_or_rgb);
2509 return;
2510 case Format_A2BGR30_Premultiplied:
2511 ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderBGR>(index_or_rgb);
2512 return;
2513 case Format_RGB30:
2514 ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderRGB>(index_or_rgb);
2515 return;
2516 case Format_A2RGB30_Premultiplied:
2517 ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderRGB>(index_or_rgb);
2518 return;
2519 case Format_Invalid:
2520 case NImageFormats:
2521 Q_ASSERT(false);
2522 return;
2523 default:
2524 break;
2525 }
2526
2527 const QPixelLayout *layout = &qPixelLayouts[d->format];
2528 layout->storeFromARGB32PM(s, &index_or_rgb, x, 1, nullptr, nullptr);
2529 }
2530
2531 /*!
2532 \fn QColor QImage::pixelColor(const QPoint &position) const
2533 \since 5.6
2534
2535 Returns the color of the pixel at the given \a position as a QColor.
2536
2537 If the \a position is not valid, an invalid QColor is returned.
2538
2539 \warning This function is expensive when used for massive pixel
2540 manipulations. Use constBits() or constScanLine() when many
2541 pixels needs to be read.
2542
2543 \sa setPixel(), valid(), constBits(), constScanLine(), {QImage#Pixel Manipulation}{Pixel
2544 Manipulation}
2545 */
2546
2547 /*!
2548 \overload
2549 \since 5.6
2550
2551 Returns the color of the pixel at coordinates (\a x, \a y) as a QColor.
2552 */
pixelColor(int x,int y) const2553 QColor QImage::pixelColor(int x, int y) const
2554 {
2555 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
2556 qWarning("QImage::pixelColor: coordinate (%d,%d) out of range", x, y);
2557 return QColor();
2558 }
2559
2560 QRgba64 c;
2561 const uchar * s = constScanLine(y);
2562 switch (d->format) {
2563 case Format_BGR30:
2564 case Format_A2BGR30_Premultiplied:
2565 c = qConvertA2rgb30ToRgb64<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]);
2566 break;
2567 case Format_RGB30:
2568 case Format_A2RGB30_Premultiplied:
2569 c = qConvertA2rgb30ToRgb64<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]);
2570 break;
2571 case Format_RGBX64:
2572 case Format_RGBA64:
2573 case Format_RGBA64_Premultiplied:
2574 c = reinterpret_cast<const QRgba64 *>(s)[x];
2575 break;
2576 case Format_Grayscale16: {
2577 quint16 v = reinterpret_cast<const quint16 *>(s)[x];
2578 return QColor(qRgba64(v, v, v, 0xffff));
2579 }
2580 default:
2581 c = QRgba64::fromArgb32(pixel(x, y));
2582 break;
2583 }
2584 // QColor is always unpremultiplied
2585 if (hasAlphaChannel() && qPixelLayouts[d->format].premultiplied)
2586 c = c.unpremultiplied();
2587 return QColor(c);
2588 }
2589
2590 /*!
2591 \fn void QImage::setPixelColor(const QPoint &position, const QColor &color)
2592 \since 5.6
2593
2594 Sets the color at the given \a position to \a color.
2595
2596 If \a position is not a valid coordinate pair in the image, or
2597 the image's format is either monochrome or paletted, the result is undefined.
2598
2599 \warning This function is expensive due to the call of the internal
2600 \c{detach()} function called within; if performance is a concern, we
2601 recommend the use of scanLine() or bits() to access pixel data directly.
2602
2603 \sa pixel(), bits(), scanLine(), {QImage#Pixel Manipulation}{Pixel Manipulation}
2604 */
2605
2606 /*!
2607 \overload
2608 \since 5.6
2609
2610 Sets the pixel color at (\a x, \a y) to \a color.
2611 */
setPixelColor(int x,int y,const QColor & color)2612 void QImage::setPixelColor(int x, int y, const QColor &color)
2613 {
2614 if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
2615 qWarning("QImage::setPixelColor: coordinate (%d,%d) out of range", x, y);
2616 return;
2617 }
2618
2619 if (!color.isValid()) {
2620 qWarning("QImage::setPixelColor: color is invalid");
2621 return;
2622 }
2623
2624 // QColor is always unpremultiplied
2625 QRgba64 c = color.rgba64();
2626 if (!hasAlphaChannel())
2627 c.setAlpha(65535);
2628 else if (qPixelLayouts[d->format].premultiplied)
2629 c = c.premultiplied();
2630 // detach is called from within scanLine
2631 uchar * s = scanLine(y);
2632 switch (d->format) {
2633 case Format_Mono:
2634 case Format_MonoLSB:
2635 case Format_Indexed8:
2636 qWarning("QImage::setPixelColor: called on monochrome or indexed format");
2637 return;
2638 case Format_BGR30:
2639 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c) | 0xc0000000;
2640 return;
2641 case Format_A2BGR30_Premultiplied:
2642 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderBGR>(c);
2643 return;
2644 case Format_RGB30:
2645 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c) | 0xc0000000;
2646 return;
2647 case Format_A2RGB30_Premultiplied:
2648 ((uint *)s)[x] = qConvertRgb64ToRgb30<PixelOrderRGB>(c);
2649 return;
2650 case Format_RGBX64:
2651 case Format_RGBA64:
2652 case Format_RGBA64_Premultiplied:
2653 ((QRgba64 *)s)[x] = c;
2654 return;
2655 default:
2656 setPixel(x, y, c.toArgb32());
2657 return;
2658 }
2659 }
2660
2661 /*!
2662 Returns \c true if all the colors in the image are shades of gray
2663 (i.e. their red, green and blue components are equal); otherwise
2664 false.
2665
2666 Note that this function is slow for images without color table.
2667
2668 \sa isGrayscale()
2669 */
allGray() const2670 bool QImage::allGray() const
2671 {
2672 if (!d)
2673 return true;
2674
2675 switch (d->format) {
2676 case Format_Mono:
2677 case Format_MonoLSB:
2678 case Format_Indexed8:
2679 for (int i = 0; i < d->colortable.size(); ++i) {
2680 if (!qIsGray(d->colortable.at(i)))
2681 return false;
2682 }
2683 return true;
2684 case Format_Alpha8:
2685 return false;
2686 case Format_Grayscale8:
2687 case Format_Grayscale16:
2688 return true;
2689 case Format_RGB32:
2690 case Format_ARGB32:
2691 case Format_ARGB32_Premultiplied:
2692 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
2693 case Format_RGBX8888:
2694 case Format_RGBA8888:
2695 case Format_RGBA8888_Premultiplied:
2696 #endif
2697 for (int j = 0; j < d->height; ++j) {
2698 const QRgb *b = (const QRgb *)constScanLine(j);
2699 for (int i = 0; i < d->width; ++i) {
2700 if (!qIsGray(b[i]))
2701 return false;
2702 }
2703 }
2704 return true;
2705 case Format_RGB16:
2706 for (int j = 0; j < d->height; ++j) {
2707 const quint16 *b = (const quint16 *)constScanLine(j);
2708 for (int i = 0; i < d->width; ++i) {
2709 if (!qIsGray(qConvertRgb16To32(b[i])))
2710 return false;
2711 }
2712 }
2713 return true;
2714 default:
2715 break;
2716 }
2717
2718 uint buffer[BufferSize];
2719 const QPixelLayout *layout = &qPixelLayouts[d->format];
2720 const auto fetch = layout->fetchToARGB32PM;
2721 for (int j = 0; j < d->height; ++j) {
2722 const uchar *b = constScanLine(j);
2723 int x = 0;
2724 while (x < d->width) {
2725 int l = qMin(d->width - x, BufferSize);
2726 const uint *ptr = fetch(buffer, b, x, l, nullptr, nullptr);
2727 for (int i = 0; i < l; ++i) {
2728 if (!qIsGray(ptr[i]))
2729 return false;
2730 }
2731 x += l;
2732 }
2733 }
2734 return true;
2735 }
2736
2737 /*!
2738 For 32-bit images, this function is equivalent to allGray().
2739
2740 For color indexed images, this function returns \c true if
2741 color(i) is QRgb(i, i, i) for all indexes of the color table;
2742 otherwise returns \c false.
2743
2744 \sa allGray(), {QImage#Image Formats}{Image Formats}
2745 */
isGrayscale() const2746 bool QImage::isGrayscale() const
2747 {
2748 if (!d)
2749 return false;
2750
2751 if (d->format == QImage::Format_Alpha8)
2752 return false;
2753
2754 if (d->format == QImage::Format_Grayscale8 || d->format == QImage::Format_Grayscale16)
2755 return true;
2756
2757 switch (depth()) {
2758 case 32:
2759 case 24:
2760 case 16:
2761 return allGray();
2762 case 8: {
2763 Q_ASSERT(d->format == QImage::Format_Indexed8);
2764 for (int i = 0; i < colorCount(); i++)
2765 if (d->colortable.at(i) != qRgb(i,i,i))
2766 return false;
2767 return true;
2768 }
2769 }
2770 return false;
2771 }
2772
2773 /*!
2774 \fn QImage QImage::scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode,
2775 Qt::TransformationMode transformMode) const
2776 \overload
2777
2778 Returns a copy of the image scaled to a rectangle with the given
2779 \a width and \a height according to the given \a aspectRatioMode
2780 and \a transformMode.
2781
2782 If either the \a width or the \a height is zero or negative, this
2783 function returns a null image.
2784 */
2785
2786 /*!
2787 \fn QImage QImage::scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode,
2788 Qt::TransformationMode transformMode) const
2789
2790 Returns a copy of the image scaled to a rectangle defined by the
2791 given \a size according to the given \a aspectRatioMode and \a
2792 transformMode.
2793
2794 \image qimage-scaling.png
2795
2796 \list
2797 \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the image
2798 is scaled to \a size.
2799 \li If \a aspectRatioMode is Qt::KeepAspectRatio, the image is
2800 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
2801 \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
2802 the image is scaled to a rectangle as small as possible
2803 outside \a size, preserving the aspect ratio.
2804 \endlist
2805
2806 If the given \a size is empty, this function returns a null image.
2807
2808 \sa isNull(), {QImage#Image Transformations}{Image
2809 Transformations}
2810 */
scaled(const QSize & s,Qt::AspectRatioMode aspectMode,Qt::TransformationMode mode) const2811 QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
2812 {
2813 if (!d) {
2814 qWarning("QImage::scaled: Image is a null image");
2815 return QImage();
2816 }
2817 if (s.isEmpty())
2818 return QImage();
2819
2820 QSize newSize = size();
2821 newSize.scale(s, aspectMode);
2822 newSize.rwidth() = qMax(newSize.width(), 1);
2823 newSize.rheight() = qMax(newSize.height(), 1);
2824 if (newSize == size())
2825 return *this;
2826
2827 Q_TRACE_SCOPE(QImage_scaled, s, aspectMode, mode);
2828
2829 QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());
2830 QImage img = transformed(wm, mode);
2831 return img;
2832 }
2833
2834 /*!
2835 \fn QImage QImage::scaledToWidth(int width, Qt::TransformationMode mode) const
2836
2837 Returns a scaled copy of the image. The returned image is scaled
2838 to the given \a width using the specified transformation \a
2839 mode.
2840
2841 This function automatically calculates the height of the image so
2842 that its aspect ratio is preserved.
2843
2844 If the given \a width is 0 or negative, a null image is returned.
2845
2846 \sa {QImage#Image Transformations}{Image Transformations}
2847 */
scaledToWidth(int w,Qt::TransformationMode mode) const2848 QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const
2849 {
2850 if (!d) {
2851 qWarning("QImage::scaleWidth: Image is a null image");
2852 return QImage();
2853 }
2854 if (w <= 0)
2855 return QImage();
2856
2857 Q_TRACE_SCOPE(QImage_scaledToWidth, w, mode);
2858
2859 qreal factor = (qreal) w / width();
2860 QTransform wm = QTransform::fromScale(factor, factor);
2861 return transformed(wm, mode);
2862 }
2863
2864 /*!
2865 \fn QImage QImage::scaledToHeight(int height, Qt::TransformationMode mode) const
2866
2867 Returns a scaled copy of the image. The returned image is scaled
2868 to the given \a height using the specified transformation \a
2869 mode.
2870
2871 This function automatically calculates the width of the image so that
2872 the ratio of the image is preserved.
2873
2874 If the given \a height is 0 or negative, a null image is returned.
2875
2876 \sa {QImage#Image Transformations}{Image Transformations}
2877 */
scaledToHeight(int h,Qt::TransformationMode mode) const2878 QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const
2879 {
2880 if (!d) {
2881 qWarning("QImage::scaleHeight: Image is a null image");
2882 return QImage();
2883 }
2884 if (h <= 0)
2885 return QImage();
2886
2887 Q_TRACE_SCOPE(QImage_scaledToHeight, h, mode);
2888
2889 qreal factor = (qreal) h / height();
2890 QTransform wm = QTransform::fromScale(factor, factor);
2891 return transformed(wm, mode);
2892 }
2893
2894
2895 #if QT_DEPRECATED_SINCE(5, 15)
2896
2897 /*!
2898 \obsolete
2899
2900 Use trueMatrix(const QTransform &matrix, int w, int h) instead.
2901
2902 \fn QMatrix QImage::trueMatrix(const QMatrix &matrix, int width, int height)
2903
2904 Returns the actual matrix used for transforming an image with the
2905 given \a width, \a height and \a matrix.
2906
2907 When transforming an image using the transformed() function, the
2908 transformation matrix is internally adjusted to compensate for
2909 unwanted translation, i.e. transformed() returns the smallest
2910 image containing all transformed points of the original image.
2911 This function returns the modified matrix, which maps points
2912 correctly from the original image into the new image.
2913
2914 \sa transformed(), {QImage#Image Transformations}{Image
2915 Transformations}
2916 */
trueMatrix(const QMatrix & matrix,int w,int h)2917 QMatrix QImage::trueMatrix(const QMatrix &matrix, int w, int h)
2918 {
2919 return trueMatrix(QTransform(matrix), w, h).toAffine();
2920 }
2921
2922 /*!
2923 \obsolete
2924
2925 Use transformed(const QTransform &matrix, Qt::TransformationMode mode) instead.
2926
2927 Returns a copy of the image that is transformed using the given
2928 transformation \a matrix and transformation \a mode.
2929
2930 The returned image will normally have the same {Image Formats}{format} as
2931 the original image. However, a complex transformation may result in an
2932 image where not all pixels are covered by the transformed pixels of the
2933 original image. In such cases, those background pixels will be assigned a
2934 transparent color value, and the transformed image will be given a format
2935 with an alpha channel, even if the orginal image did not have that.
2936
2937 The transformation \a matrix is internally adjusted to compensate
2938 for unwanted translation; i.e. the image produced is the smallest
2939 image that contains all the transformed points of the original
2940 image. Use the trueMatrix() function to retrieve the actual matrix
2941 used for transforming an image.
2942
2943 \sa trueMatrix(), {QImage#Image Transformations}{Image
2944 Transformations}
2945 */
transformed(const QMatrix & matrix,Qt::TransformationMode mode) const2946 QImage QImage::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
2947 {
2948 return transformed(QTransform(matrix), mode);
2949 }
2950
2951 #endif // QT_DEPRECATED_SINCE(5, 15)
2952
2953 /*!
2954 Builds and returns a 1-bpp mask from the alpha buffer in this
2955 image. Returns a null image if the image's format is
2956 QImage::Format_RGB32.
2957
2958 The \a flags argument is a bitwise-OR of the
2959 Qt::ImageConversionFlags, and controls the conversion
2960 process. Passing 0 for flags sets all the default options.
2961
2962 The returned image has little-endian bit order (i.e. the image's
2963 format is QImage::Format_MonoLSB), which you can convert to
2964 big-endian (QImage::Format_Mono) using the convertToFormat()
2965 function.
2966
2967 \sa createHeuristicMask(), {QImage#Image Transformations}{Image
2968 Transformations}
2969 */
createAlphaMask(Qt::ImageConversionFlags flags) const2970 QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
2971 {
2972 if (!d || d->format == QImage::Format_RGB32)
2973 return QImage();
2974
2975 if (d->depth == 1) {
2976 // A monochrome pixmap, with alpha channels on those two colors.
2977 // Pretty unlikely, so use less efficient solution.
2978 return convertToFormat(Format_Indexed8, flags).createAlphaMask(flags);
2979 }
2980
2981 QImage mask(d->width, d->height, Format_MonoLSB);
2982 if (!mask.isNull()) {
2983 dither_to_Mono(mask.d, d, flags, true);
2984 copyPhysicalMetadata(mask.d, d);
2985 }
2986 return mask;
2987 }
2988
2989 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
2990 /*!
2991 Creates and returns a 1-bpp heuristic mask for this image.
2992
2993 The function works by selecting a color from one of the corners,
2994 then chipping away pixels of that color starting at all the edges.
2995 The four corners vote for which color is to be masked away. In
2996 case of a draw (this generally means that this function is not
2997 applicable to the image), the result is arbitrary.
2998
2999 The returned image has little-endian bit order (i.e. the image's
3000 format is QImage::Format_MonoLSB), which you can convert to
3001 big-endian (QImage::Format_Mono) using the convertToFormat()
3002 function.
3003
3004 If \a clipTight is true (the default) the mask is just large
3005 enough to cover the pixels; otherwise, the mask is larger than the
3006 data pixels.
3007
3008 Note that this function disregards the alpha buffer.
3009
3010 \sa createAlphaMask(), {QImage#Image Transformations}{Image
3011 Transformations}
3012 */
3013
createHeuristicMask(bool clipTight) const3014 QImage QImage::createHeuristicMask(bool clipTight) const
3015 {
3016 if (!d)
3017 return QImage();
3018
3019 if (d->depth != 32) {
3020 QImage img32 = convertToFormat(Format_RGB32);
3021 return img32.createHeuristicMask(clipTight);
3022 }
3023
3024 #define PIX(x,y) (*((const QRgb*)scanLine(y)+x) & 0x00ffffff)
3025
3026 int w = width();
3027 int h = height();
3028 QImage m(w, h, Format_MonoLSB);
3029 QIMAGE_SANITYCHECK_MEMORY(m);
3030 m.setColorCount(2);
3031 m.setColor(0, QColor(Qt::color0).rgba());
3032 m.setColor(1, QColor(Qt::color1).rgba());
3033 m.fill(0xff);
3034
3035 QRgb background = PIX(0,0);
3036 if (background != PIX(w-1,0) &&
3037 background != PIX(0,h-1) &&
3038 background != PIX(w-1,h-1)) {
3039 background = PIX(w-1,0);
3040 if (background != PIX(w-1,h-1) &&
3041 background != PIX(0,h-1) &&
3042 PIX(0,h-1) == PIX(w-1,h-1)) {
3043 background = PIX(w-1,h-1);
3044 }
3045 }
3046
3047 int x,y;
3048 bool done = false;
3049 uchar *ypp, *ypc, *ypn;
3050 while(!done) {
3051 done = true;
3052 ypn = m.scanLine(0);
3053 ypc = nullptr;
3054 for (y = 0; y < h; y++) {
3055 ypp = ypc;
3056 ypc = ypn;
3057 ypn = (y == h-1) ? nullptr : m.scanLine(y+1);
3058 const QRgb *p = (const QRgb *)scanLine(y);
3059 for (x = 0; x < w; x++) {
3060 // slowness here - it's possible to do six of these tests
3061 // together in one go. oh well.
3062 if ((x == 0 || y == 0 || x == w-1 || y == h-1 ||
3063 !(*(ypc + ((x-1) >> 3)) & (1 << ((x-1) & 7))) ||
3064 !(*(ypc + ((x+1) >> 3)) & (1 << ((x+1) & 7))) ||
3065 !(*(ypp + (x >> 3)) & (1 << (x & 7))) ||
3066 !(*(ypn + (x >> 3)) & (1 << (x & 7)))) &&
3067 ( (*(ypc + (x >> 3)) & (1 << (x & 7)))) &&
3068 ((*p & 0x00ffffff) == background)) {
3069 done = false;
3070 *(ypc + (x >> 3)) &= ~(1 << (x & 7));
3071 }
3072 p++;
3073 }
3074 }
3075 }
3076
3077 if (!clipTight) {
3078 ypn = m.scanLine(0);
3079 ypc = nullptr;
3080 for (y = 0; y < h; y++) {
3081 ypp = ypc;
3082 ypc = ypn;
3083 ypn = (y == h-1) ? nullptr : m.scanLine(y+1);
3084 const QRgb *p = (const QRgb *)scanLine(y);
3085 for (x = 0; x < w; x++) {
3086 if ((*p & 0x00ffffff) != background) {
3087 if (x > 0)
3088 *(ypc + ((x-1) >> 3)) |= (1 << ((x-1) & 7));
3089 if (x < w-1)
3090 *(ypc + ((x+1) >> 3)) |= (1 << ((x+1) & 7));
3091 if (y > 0)
3092 *(ypp + (x >> 3)) |= (1 << (x & 7));
3093 if (y < h-1)
3094 *(ypn + (x >> 3)) |= (1 << (x & 7));
3095 }
3096 p++;
3097 }
3098 }
3099 }
3100
3101 #undef PIX
3102
3103 copyPhysicalMetadata(m.d, d);
3104 return m;
3105 }
3106 #endif //QT_NO_IMAGE_HEURISTIC_MASK
3107
3108 /*!
3109 Creates and returns a mask for this image based on the given \a
3110 color value. If the \a mode is MaskInColor (the default value),
3111 all pixels matching \a color will be opaque pixels in the mask. If
3112 \a mode is MaskOutColor, all pixels matching the given color will
3113 be transparent.
3114
3115 \sa createAlphaMask(), createHeuristicMask()
3116 */
3117
createMaskFromColor(QRgb color,Qt::MaskMode mode) const3118 QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
3119 {
3120 if (!d)
3121 return QImage();
3122 QImage maskImage(size(), QImage::Format_MonoLSB);
3123 QIMAGE_SANITYCHECK_MEMORY(maskImage);
3124 maskImage.fill(0);
3125 uchar *s = maskImage.bits();
3126
3127 if (depth() == 32) {
3128 for (int h = 0; h < d->height; h++) {
3129 const uint *sl = (const uint *) scanLine(h);
3130 for (int w = 0; w < d->width; w++) {
3131 if (sl[w] == color)
3132 *(s + (w >> 3)) |= (1 << (w & 7));
3133 }
3134 s += maskImage.bytesPerLine();
3135 }
3136 } else {
3137 for (int h = 0; h < d->height; h++) {
3138 for (int w = 0; w < d->width; w++) {
3139 if ((uint) pixel(w, h) == color)
3140 *(s + (w >> 3)) |= (1 << (w & 7));
3141 }
3142 s += maskImage.bytesPerLine();
3143 }
3144 }
3145 if (mode == Qt::MaskOutColor)
3146 maskImage.invertPixels();
3147
3148 copyPhysicalMetadata(maskImage.d, d);
3149 return maskImage;
3150 }
3151
3152 /*!
3153 \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const &
3154 \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) &&
3155
3156 Returns a mirror of the image, mirrored in the horizontal and/or
3157 the vertical direction depending on whether \a horizontal and \a
3158 vertical are set to true or false.
3159
3160 Note that the original image is not changed.
3161
3162 \sa {QImage#Image Transformations}{Image Transformations}
3163 */
3164
do_mirror_data(QImageData * dst,QImageData * src,int dstX0,int dstY0,int dstXIncr,int dstYIncr,int w,int h)3165 template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
3166 int dstX0, int dstY0,
3167 int dstXIncr, int dstYIncr,
3168 int w, int h)
3169 {
3170 if (dst == src) {
3171 // When mirroring in-place, stop in the middle for one of the directions, since we
3172 // are swapping the bytes instead of merely copying.
3173 const int srcXEnd = (dstX0 && !dstY0) ? w / 2 : w;
3174 const int srcYEnd = dstY0 ? h / 2 : h;
3175 for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) {
3176 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3177 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
3178 for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr)
3179 std::swap(srcPtr[srcX], dstPtr[dstX]);
3180 }
3181 // If mirroring both ways, the middle line needs to be mirrored horizontally only.
3182 if (dstX0 && dstY0 && (h & 1)) {
3183 int srcY = h / 2;
3184 int srcXEnd2 = w / 2;
3185 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3186 for (int srcX = 0, dstX = dstX0; srcX < srcXEnd2; ++srcX, dstX += dstXIncr)
3187 std::swap(srcPtr[srcX], srcPtr[dstX]);
3188 }
3189 } else {
3190 for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) {
3191 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
3192 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
3193 for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr)
3194 dstPtr[dstX] = srcPtr[srcX];
3195 }
3196 }
3197 }
3198
do_flip(QImageData * dst,QImageData * src,int w,int h,int depth)3199 inline void do_flip(QImageData *dst, QImageData *src, int w, int h, int depth)
3200 {
3201 const int data_bytes_per_line = w * (depth / 8);
3202 if (dst == src) {
3203 uint *srcPtr = reinterpret_cast<uint *>(src->data);
3204 uint *dstPtr = reinterpret_cast<uint *>(dst->data + (h - 1) * dst->bytes_per_line);
3205 h = h / 2;
3206 const int uint_per_line = (data_bytes_per_line + 3) >> 2; // bytes per line must be a multiple of 4
3207 for (int y = 0; y < h; ++y) {
3208 // This is auto-vectorized, no need for SSE2 or NEON versions:
3209 for (int x = 0; x < uint_per_line; x++) {
3210 const uint d = dstPtr[x];
3211 const uint s = srcPtr[x];
3212 dstPtr[x] = s;
3213 srcPtr[x] = d;
3214 }
3215 srcPtr += src->bytes_per_line >> 2;
3216 dstPtr -= dst->bytes_per_line >> 2;
3217 }
3218
3219 } else {
3220 const uchar *srcPtr = src->data;
3221 uchar *dstPtr = dst->data + (h - 1) * dst->bytes_per_line;
3222 for (int y = 0; y < h; ++y) {
3223 memcpy(dstPtr, srcPtr, data_bytes_per_line);
3224 srcPtr += src->bytes_per_line;
3225 dstPtr -= dst->bytes_per_line;
3226 }
3227 }
3228 }
3229
do_mirror(QImageData * dst,QImageData * src,bool horizontal,bool vertical)3230 inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
3231 {
3232 Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
3233 int w = src->width;
3234 int h = src->height;
3235 int depth = src->depth;
3236
3237 if (src->depth == 1) {
3238 w = (w + 7) / 8; // byte aligned width
3239 depth = 8;
3240 }
3241
3242 if (vertical && !horizontal) {
3243 // This one is simple and common, so do it a little more optimized
3244 do_flip(dst, src, w, h, depth);
3245 return;
3246 }
3247
3248 int dstX0 = 0, dstXIncr = 1;
3249 int dstY0 = 0, dstYIncr = 1;
3250 if (horizontal) {
3251 // 0 -> w-1, 1 -> w-2, 2 -> w-3, ...
3252 dstX0 = w - 1;
3253 dstXIncr = -1;
3254 }
3255 if (vertical) {
3256 // 0 -> h-1, 1 -> h-2, 2 -> h-3, ...
3257 dstY0 = h - 1;
3258 dstYIncr = -1;
3259 }
3260
3261 switch (depth) {
3262 case 64:
3263 do_mirror_data<quint64>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3264 break;
3265 case 32:
3266 do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3267 break;
3268 case 24:
3269 do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3270 break;
3271 case 16:
3272 do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3273 break;
3274 case 8:
3275 do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
3276 break;
3277 default:
3278 Q_ASSERT(false);
3279 break;
3280 }
3281
3282 // The bytes are now all in the correct place. In addition, the bits in the individual
3283 // bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image.
3284 if (horizontal && dst->depth == 1) {
3285 Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
3286 const int shift = 8 - (dst->width % 8);
3287 const uchar *bitflip = qt_get_bitflip_array();
3288 for (int y = 0; y < h; ++y) {
3289 uchar *begin = dst->data + y * dst->bytes_per_line;
3290 uchar *end = begin + dst->bytes_per_line;
3291 for (uchar *p = begin; p < end; ++p) {
3292 *p = bitflip[*p];
3293 // When the data is non-byte aligned, an extra bit shift (of the number of
3294 // unused bits at the end) is needed for the entire scanline.
3295 if (shift != 8 && p != begin) {
3296 if (dst->format == QImage::Format_Mono) {
3297 for (int i = 0; i < shift; ++i) {
3298 p[-1] <<= 1;
3299 p[-1] |= (*p & (128 >> i)) >> (7 - i);
3300 }
3301 } else {
3302 for (int i = 0; i < shift; ++i) {
3303 p[-1] >>= 1;
3304 p[-1] |= (*p & (1 << i)) << (7 - i);
3305 }
3306 }
3307 }
3308 }
3309 if (shift != 8) {
3310 if (dst->format == QImage::Format_Mono)
3311 end[-1] <<= shift;
3312 else
3313 end[-1] >>= shift;
3314 }
3315 }
3316 }
3317 }
3318
3319 /*!
3320 \internal
3321 */
mirrored_helper(bool horizontal,bool vertical) const3322 QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
3323 {
3324 if (!d)
3325 return QImage();
3326
3327 if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
3328 return *this;
3329
3330 // Create result image, copy colormap
3331 QImage result(d->width, d->height, d->format);
3332 QIMAGE_SANITYCHECK_MEMORY(result);
3333
3334 // check if we ran out of of memory..
3335 if (!result.d)
3336 return QImage();
3337
3338 result.d->colortable = d->colortable;
3339 result.d->has_alpha_clut = d->has_alpha_clut;
3340 copyMetadata(result.d, d);
3341
3342 do_mirror(result.d, d, horizontal, vertical);
3343
3344 return result;
3345 }
3346
3347 /*!
3348 \internal
3349 */
mirrored_inplace(bool horizontal,bool vertical)3350 void QImage::mirrored_inplace(bool horizontal, bool vertical)
3351 {
3352 if (!d || (d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
3353 return;
3354
3355 detach();
3356 if (!d)
3357 return;
3358 if (!d->own_data)
3359 *this = copy();
3360
3361 do_mirror(d, d, horizontal, vertical);
3362 }
3363
3364 /*!
3365 \fn QImage QImage::rgbSwapped() const &
3366 \fn QImage QImage::rgbSwapped() &&
3367
3368 Returns a QImage in which the values of the red and blue
3369 components of all pixels have been swapped, effectively converting
3370 an RGB image to an BGR image.
3371
3372 The original QImage is not changed.
3373
3374 \sa {QImage#Image Transformations}{Image Transformations}
3375 */
3376
rgbSwapped_generic(int width,int height,const QImage * src,QImage * dst,const QPixelLayout * layout)3377 static inline void rgbSwapped_generic(int width, int height, const QImage *src, QImage *dst, const QPixelLayout* layout)
3378 {
3379 const RbSwapFunc func = layout->rbSwap;
3380 if (!func) {
3381 qWarning("Trying to rb-swap an image format where it doesn't make sense");
3382 if (src != dst)
3383 *dst = *src;
3384 return;
3385 }
3386
3387 for (int i = 0; i < height; ++i) {
3388 uchar *q = dst->scanLine(i);
3389 const uchar *p = src->constScanLine(i);
3390 func(q, p, width);
3391 }
3392 }
3393
3394 /*!
3395 \internal
3396 */
rgbSwapped_helper() const3397 QImage QImage::rgbSwapped_helper() const
3398 {
3399 if (isNull())
3400 return *this;
3401
3402 Q_TRACE_SCOPE(QImage_rgbSwapped_helper);
3403
3404 QImage res;
3405
3406 switch (d->format) {
3407 case Format_Invalid:
3408 case NImageFormats:
3409 Q_ASSERT(false);
3410 break;
3411 case Format_Alpha8:
3412 case Format_Grayscale8:
3413 case Format_Grayscale16:
3414 return *this;
3415 case Format_Mono:
3416 case Format_MonoLSB:
3417 case Format_Indexed8:
3418 res = copy();
3419 for (int i = 0; i < res.d->colortable.size(); i++) {
3420 QRgb c = res.d->colortable.at(i);
3421 res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
3422 }
3423 break;
3424 case Format_RGBX8888:
3425 case Format_RGBA8888:
3426 case Format_RGBA8888_Premultiplied:
3427 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
3428 res = QImage(d->width, d->height, d->format);
3429 QIMAGE_SANITYCHECK_MEMORY(res);
3430 for (int i = 0; i < d->height; i++) {
3431 uint *q = (uint*)res.scanLine(i);
3432 const uint *p = (const uint*)constScanLine(i);
3433 const uint *end = p + d->width;
3434 while (p < end) {
3435 uint c = *p;
3436 *q = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff);
3437 p++;
3438 q++;
3439 }
3440 }
3441 break;
3442 #else
3443 // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32
3444 Q_FALLTHROUGH();
3445 #endif
3446 case Format_RGB32:
3447 case Format_ARGB32:
3448 case Format_ARGB32_Premultiplied:
3449 res = QImage(d->width, d->height, d->format);
3450 QIMAGE_SANITYCHECK_MEMORY(res);
3451 for (int i = 0; i < d->height; i++) {
3452 uint *q = (uint*)res.scanLine(i);
3453 const uint *p = (const uint*)constScanLine(i);
3454 const uint *end = p + d->width;
3455 while (p < end) {
3456 uint c = *p;
3457 *q = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
3458 p++;
3459 q++;
3460 }
3461 }
3462 break;
3463 case Format_RGB16:
3464 res = QImage(d->width, d->height, d->format);
3465 QIMAGE_SANITYCHECK_MEMORY(res);
3466 for (int i = 0; i < d->height; i++) {
3467 ushort *q = (ushort*)res.scanLine(i);
3468 const ushort *p = (const ushort*)constScanLine(i);
3469 const ushort *end = p + d->width;
3470 while (p < end) {
3471 ushort c = *p;
3472 *q = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
3473 p++;
3474 q++;
3475 }
3476 }
3477 break;
3478 case Format_RGBX64:
3479 case Format_RGBA64:
3480 case Format_RGBA64_Premultiplied:
3481 res = QImage(d->width, d->height, d->format);
3482 QIMAGE_SANITYCHECK_MEMORY(res);
3483 for (int i = 0; i < d->height; i++) {
3484 QRgba64 *q = reinterpret_cast<QRgba64 *>(res.scanLine(i));
3485 const QRgba64 *p = reinterpret_cast<const QRgba64 *>(constScanLine(i));
3486 const QRgba64 *end = p + d->width;
3487 while (p < end) {
3488 QRgba64 c = *p;
3489 *q = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
3490 p++;
3491 q++;
3492 }
3493 }
3494 break;
3495 default:
3496 res = QImage(d->width, d->height, d->format);
3497 rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]);
3498 break;
3499 }
3500 copyMetadata(res.d, d);
3501 return res;
3502 }
3503
3504 /*!
3505 \internal
3506 */
rgbSwapped_inplace()3507 void QImage::rgbSwapped_inplace()
3508 {
3509 if (isNull())
3510 return;
3511
3512 detach();
3513 if (!d)
3514 return;
3515 if (!d->own_data)
3516 *this = copy();
3517
3518 switch (d->format) {
3519 case Format_Invalid:
3520 case NImageFormats:
3521 Q_ASSERT(false);
3522 break;
3523 case Format_Alpha8:
3524 case Format_Grayscale8:
3525 case Format_Grayscale16:
3526 return;
3527 case Format_Mono:
3528 case Format_MonoLSB:
3529 case Format_Indexed8:
3530 for (int i = 0; i < d->colortable.size(); i++) {
3531 QRgb c = d->colortable.at(i);
3532 d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
3533 }
3534 break;
3535 case Format_RGBX8888:
3536 case Format_RGBA8888:
3537 case Format_RGBA8888_Premultiplied:
3538 #if Q_BYTE_ORDER == Q_BIG_ENDIAN
3539 for (int i = 0; i < d->height; i++) {
3540 uint *p = (uint*)scanLine(i);
3541 uint *end = p + d->width;
3542 while (p < end) {
3543 uint c = *p;
3544 *p = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff);
3545 p++;
3546 }
3547 }
3548 break;
3549 #else
3550 // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32
3551 Q_FALLTHROUGH();
3552 #endif
3553 case Format_RGB32:
3554 case Format_ARGB32:
3555 case Format_ARGB32_Premultiplied:
3556 for (int i = 0; i < d->height; i++) {
3557 uint *p = (uint*)scanLine(i);
3558 uint *end = p + d->width;
3559 while (p < end) {
3560 uint c = *p;
3561 *p = ((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00);
3562 p++;
3563 }
3564 }
3565 break;
3566 case Format_RGB16:
3567 for (int i = 0; i < d->height; i++) {
3568 ushort *p = (ushort*)scanLine(i);
3569 ushort *end = p + d->width;
3570 while (p < end) {
3571 ushort c = *p;
3572 *p = ((c << 11) & 0xf800) | ((c >> 11) & 0x1f) | (c & 0x07e0);
3573 p++;
3574 }
3575 }
3576 break;
3577 case Format_BGR30:
3578 case Format_A2BGR30_Premultiplied:
3579 case Format_RGB30:
3580 case Format_A2RGB30_Premultiplied:
3581 for (int i = 0; i < d->height; i++) {
3582 uint *p = (uint*)scanLine(i);
3583 uint *end = p + d->width;
3584 while (p < end) {
3585 *p = qRgbSwapRgb30(*p);
3586 p++;
3587 }
3588 }
3589 break;
3590 case Format_RGBX64:
3591 case Format_RGBA64:
3592 case Format_RGBA64_Premultiplied:
3593 for (int i = 0; i < d->height; i++) {
3594 QRgba64 *p = reinterpret_cast<QRgba64 *>(scanLine(i));
3595 QRgba64 *end = p + d->width;
3596 while (p < end) {
3597 QRgba64 c = *p;
3598 *p = QRgba64::fromRgba64(c.blue(), c.green(), c.red(), c.alpha());
3599 p++;
3600 }
3601 }
3602 break;
3603 default:
3604 rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]);
3605 break;
3606 }
3607 }
3608
3609 /*!
3610 Loads an image from the file with the given \a fileName. Returns \c true if
3611 the image was successfully loaded; otherwise invalidates the image
3612 and returns \c false.
3613
3614 The loader attempts to read the image using the specified \a format, e.g.,
3615 PNG or JPG. If \a format is not specified (which is the default), it is
3616 auto-detected based on the file's suffix and header. For details, see
3617 QImageReader::setAutoDetectImageFormat().
3618
3619 The file name can either refer to an actual file on disk or to one
3620 of the application's embedded resources. See the
3621 \l{resources.html}{Resource System} overview for details on how to
3622 embed images and other resource files in the application's
3623 executable.
3624
3625 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3626 */
3627
load(const QString & fileName,const char * format)3628 bool QImage::load(const QString &fileName, const char* format)
3629 {
3630 *this = QImageReader(fileName, format).read();
3631 return !isNull();
3632 }
3633
3634 /*!
3635 \overload
3636
3637 This function reads a QImage from the given \a device. This can,
3638 for example, be used to load an image directly into a QByteArray.
3639 */
3640
load(QIODevice * device,const char * format)3641 bool QImage::load(QIODevice* device, const char* format)
3642 {
3643 *this = QImageReader(device, format).read();
3644 return !isNull();
3645 }
3646
3647 /*!
3648 \fn bool QImage::loadFromData(const uchar *data, int len, const char *format)
3649
3650 Loads an image from the first \a len bytes of the given binary \a
3651 data. Returns \c true if the image was successfully loaded; otherwise
3652 invalidates the image and returns \c false.
3653
3654 The loader attempts to read the image using the specified \a format, e.g.,
3655 PNG or JPG. If \a format is not specified (which is the default), the
3656 loader probes the file for a header to guess the file format.
3657
3658 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3659 */
3660
loadFromData(const uchar * data,int len,const char * format)3661 bool QImage::loadFromData(const uchar *data, int len, const char *format)
3662 {
3663 *this = fromData(data, len, format);
3664 return !isNull();
3665 }
3666
3667 /*!
3668 \fn bool QImage::loadFromData(const QByteArray &data, const char *format)
3669
3670 \overload
3671
3672 Loads an image from the given QByteArray \a data.
3673 */
3674
3675 /*!
3676 \fn QImage QImage::fromData(const uchar *data, int size, const char *format)
3677
3678 Constructs a QImage from the first \a size bytes of the given
3679 binary \a data. The loader attempts to read the image using the
3680 specified \a format. If \a format is not specified (which is the default),
3681 the loader probes the data for a header to guess the file format.
3682
3683 If \a format is specified, it must be one of the values returned by
3684 QImageReader::supportedImageFormats().
3685
3686 If the loading of the image fails, the image returned will be a null image.
3687
3688 \sa load(), save(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
3689 */
3690
fromData(const uchar * data,int size,const char * format)3691 QImage QImage::fromData(const uchar *data, int size, const char *format)
3692 {
3693 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(data), size);
3694 QBuffer b;
3695 b.setData(a);
3696 b.open(QIODevice::ReadOnly);
3697 return QImageReader(&b, format).read();
3698 }
3699
3700 /*!
3701 \fn QImage QImage::fromData(const QByteArray &data, const char *format)
3702
3703 \overload
3704
3705 Loads an image from the given QByteArray \a data.
3706 */
3707
3708 /*!
3709 Saves the image to the file with the given \a fileName, using the
3710 given image file \a format and \a quality factor. If \a format is
3711 \nullptr, QImage will attempt to guess the format by looking at
3712 \a fileName's suffix.
3713
3714 The \a quality factor must be in the range 0 to 100 or -1. Specify
3715 0 to obtain small compressed files, 100 for large uncompressed
3716 files, and -1 (the default) to use the default settings.
3717
3718 Returns \c true if the image was successfully saved; otherwise
3719 returns \c false.
3720
3721 \sa {QImage#Reading and Writing Image Files}{Reading and Writing
3722 Image Files}
3723 */
save(const QString & fileName,const char * format,int quality) const3724 bool QImage::save(const QString &fileName, const char *format, int quality) const
3725 {
3726 if (isNull())
3727 return false;
3728 QImageWriter writer(fileName, format);
3729 return d->doImageIO(this, &writer, quality);
3730 }
3731
3732 /*!
3733 \overload
3734
3735 This function writes a QImage to the given \a device.
3736
3737 This can, for example, be used to save an image directly into a
3738 QByteArray:
3739
3740 \snippet image/image.cpp 0
3741 */
3742
save(QIODevice * device,const char * format,int quality) const3743 bool QImage::save(QIODevice* device, const char* format, int quality) const
3744 {
3745 if (isNull())
3746 return false; // nothing to save
3747 QImageWriter writer(device, format);
3748 return d->doImageIO(this, &writer, quality);
3749 }
3750
3751 /* \internal
3752 */
3753
doImageIO(const QImage * image,QImageWriter * writer,int quality) const3754 bool QImageData::doImageIO(const QImage *image, QImageWriter *writer, int quality) const
3755 {
3756 if (quality > 100 || quality < -1)
3757 qWarning("QPixmap::save: Quality out of range [-1, 100]");
3758 if (quality >= 0)
3759 writer->setQuality(qMin(quality,100));
3760 return writer->write(*image);
3761 }
3762
3763 /*****************************************************************************
3764 QImage stream functions
3765 *****************************************************************************/
3766 #if !defined(QT_NO_DATASTREAM)
3767 /*!
3768 \fn QDataStream &operator<<(QDataStream &stream, const QImage &image)
3769 \relates QImage
3770
3771 Writes the given \a image to the given \a stream as a PNG image,
3772 or as a BMP image if the stream's version is 1. Note that writing
3773 the stream to a file will not produce a valid image file.
3774
3775 \sa QImage::save(), {Serializing Qt Data Types}
3776 */
3777
operator <<(QDataStream & s,const QImage & image)3778 QDataStream &operator<<(QDataStream &s, const QImage &image)
3779 {
3780 if (s.version() >= 5) {
3781 if (image.isNull()) {
3782 s << (qint32) 0; // null image marker
3783 return s;
3784 } else {
3785 s << (qint32) 1;
3786 // continue ...
3787 }
3788 }
3789 QImageWriter writer(s.device(), s.version() == 1 ? "bmp" : "png");
3790 writer.write(image);
3791 return s;
3792 }
3793
3794 /*!
3795 \fn QDataStream &operator>>(QDataStream &stream, QImage &image)
3796 \relates QImage
3797
3798 Reads an image from the given \a stream and stores it in the given
3799 \a image.
3800
3801 \sa QImage::load(), {Serializing Qt Data Types}
3802 */
3803
operator >>(QDataStream & s,QImage & image)3804 QDataStream &operator>>(QDataStream &s, QImage &image)
3805 {
3806 if (s.version() >= 5) {
3807 qint32 nullMarker;
3808 s >> nullMarker;
3809 if (!nullMarker) {
3810 image = QImage(); // null image
3811 return s;
3812 }
3813 }
3814 image = QImageReader(s.device(), s.version() == 1 ? "bmp" : "png").read();
3815 if (image.isNull() && s.version() >= 5)
3816 s.setStatus(QDataStream::ReadPastEnd);
3817 return s;
3818 }
3819 #endif // QT_NO_DATASTREAM
3820
3821
3822
3823 /*!
3824 \fn bool QImage::operator==(const QImage & image) const
3825
3826 Returns \c true if this image and the given \a image have the same
3827 contents; otherwise returns \c false.
3828
3829 The comparison can be slow, unless there is some obvious
3830 difference (e.g. different size or format), in which case the
3831 function will return quickly.
3832
3833 \sa operator=()
3834 */
3835
operator ==(const QImage & i) const3836 bool QImage::operator==(const QImage & i) const
3837 {
3838 // same object, or shared?
3839 if (i.d == d)
3840 return true;
3841 if (!i.d || !d)
3842 return false;
3843
3844 // obviously different stuff?
3845 if (i.d->height != d->height || i.d->width != d->width || i.d->format != d->format)
3846 return false;
3847
3848 if (d->format != Format_RGB32) {
3849 if (d->format >= Format_ARGB32) { // all bits defined
3850 const int n = d->width * d->depth / 8;
3851 if (n == d->bytes_per_line && n == i.d->bytes_per_line) {
3852 if (memcmp(bits(), i.bits(), d->nbytes))
3853 return false;
3854 } else {
3855 for (int y = 0; y < d->height; ++y) {
3856 if (memcmp(scanLine(y), i.scanLine(y), n))
3857 return false;
3858 }
3859 }
3860 } else {
3861 const int w = width();
3862 const int h = height();
3863 const QVector<QRgb> &colortable = d->colortable;
3864 const QVector<QRgb> &icolortable = i.d->colortable;
3865 for (int y=0; y<h; ++y) {
3866 for (int x=0; x<w; ++x) {
3867 if (colortable[pixelIndex(x, y)] != icolortable[i.pixelIndex(x, y)])
3868 return false;
3869 }
3870 }
3871 }
3872 } else {
3873 //alpha channel undefined, so we must mask it out
3874 for(int l = 0; l < d->height; l++) {
3875 int w = d->width;
3876 const uint *p1 = reinterpret_cast<const uint*>(scanLine(l));
3877 const uint *p2 = reinterpret_cast<const uint*>(i.scanLine(l));
3878 while (w--) {
3879 if ((*p1++ & 0x00ffffff) != (*p2++ & 0x00ffffff))
3880 return false;
3881 }
3882 }
3883 }
3884 return true;
3885 }
3886
3887
3888 /*!
3889 \fn bool QImage::operator!=(const QImage & image) const
3890
3891 Returns \c true if this image and the given \a image have different
3892 contents; otherwise returns \c false.
3893
3894 The comparison can be slow, unless there is some obvious
3895 difference, such as different widths, in which case the function
3896 will return quickly.
3897
3898 \sa operator=()
3899 */
3900
operator !=(const QImage & i) const3901 bool QImage::operator!=(const QImage & i) const
3902 {
3903 return !(*this == i);
3904 }
3905
3906
3907
3908
3909 /*!
3910 Returns the number of pixels that fit horizontally in a physical
3911 meter. Together with dotsPerMeterY(), this number defines the
3912 intended scale and aspect ratio of the image.
3913
3914 \sa setDotsPerMeterX(), {QImage#Image Information}{Image
3915 Information}
3916 */
dotsPerMeterX() const3917 int QImage::dotsPerMeterX() const
3918 {
3919 return d ? qRound(d->dpmx) : 0;
3920 }
3921
3922 /*!
3923 Returns the number of pixels that fit vertically in a physical
3924 meter. Together with dotsPerMeterX(), this number defines the
3925 intended scale and aspect ratio of the image.
3926
3927 \sa setDotsPerMeterY(), {QImage#Image Information}{Image
3928 Information}
3929 */
dotsPerMeterY() const3930 int QImage::dotsPerMeterY() const
3931 {
3932 return d ? qRound(d->dpmy) : 0;
3933 }
3934
3935 /*!
3936 Sets the number of pixels that fit horizontally in a physical
3937 meter, to \a x.
3938
3939 Together with dotsPerMeterY(), this number defines the intended
3940 scale and aspect ratio of the image, and determines the scale
3941 at which QPainter will draw graphics on the image. It does not
3942 change the scale or aspect ratio of the image when it is rendered
3943 on other paint devices.
3944
3945 \sa dotsPerMeterX(), {QImage#Image Information}{Image Information}
3946 */
setDotsPerMeterX(int x)3947 void QImage::setDotsPerMeterX(int x)
3948 {
3949 if (!d || !x)
3950 return;
3951 detach();
3952
3953 if (d)
3954 d->dpmx = x;
3955 }
3956
3957 /*!
3958 Sets the number of pixels that fit vertically in a physical meter,
3959 to \a y.
3960
3961 Together with dotsPerMeterX(), this number defines the intended
3962 scale and aspect ratio of the image, and determines the scale
3963 at which QPainter will draw graphics on the image. It does not
3964 change the scale or aspect ratio of the image when it is rendered
3965 on other paint devices.
3966
3967 \sa dotsPerMeterY(), {QImage#Image Information}{Image Information}
3968 */
setDotsPerMeterY(int y)3969 void QImage::setDotsPerMeterY(int y)
3970 {
3971 if (!d || !y)
3972 return;
3973 detach();
3974
3975 if (d)
3976 d->dpmy = y;
3977 }
3978
3979 /*!
3980 \fn QPoint QImage::offset() const
3981
3982 Returns the number of pixels by which the image is intended to be
3983 offset by when positioning relative to other images.
3984
3985 \sa setOffset(), {QImage#Image Information}{Image Information}
3986 */
offset() const3987 QPoint QImage::offset() const
3988 {
3989 return d ? d->offset : QPoint();
3990 }
3991
3992
3993 /*!
3994 \fn void QImage::setOffset(const QPoint& offset)
3995
3996 Sets the number of pixels by which the image is intended to be
3997 offset by when positioning relative to other images, to \a offset.
3998
3999 \sa offset(), {QImage#Image Information}{Image Information}
4000 */
setOffset(const QPoint & p)4001 void QImage::setOffset(const QPoint& p)
4002 {
4003 if (!d)
4004 return;
4005 detach();
4006
4007 if (d)
4008 d->offset = p;
4009 }
4010
4011 /*!
4012 Returns the text keys for this image.
4013
4014 You can use these keys with text() to list the image text for a
4015 certain key.
4016
4017 \sa text()
4018 */
textKeys() const4019 QStringList QImage::textKeys() const
4020 {
4021 return d ? QStringList(d->text.keys()) : QStringList();
4022 }
4023
4024 /*!
4025 Returns the image text associated with the given \a key. If the
4026 specified \a key is an empty string, the whole image text is
4027 returned, with each key-text pair separated by a newline.
4028
4029 \sa setText(), textKeys()
4030 */
text(const QString & key) const4031 QString QImage::text(const QString &key) const
4032 {
4033 if (!d)
4034 return QString();
4035
4036 if (!key.isEmpty())
4037 return d->text.value(key);
4038
4039 QString tmp;
4040 for (auto it = d->text.begin(), end = d->text.end(); it != end; ++it)
4041 tmp += it.key() + QLatin1String(": ") + it.value().simplified() + QLatin1String("\n\n");
4042 if (!tmp.isEmpty())
4043 tmp.chop(2); // remove final \n\n
4044 return tmp;
4045 }
4046
4047 /*!
4048 \fn void QImage::setText(const QString &key, const QString &text)
4049
4050 Sets the image text to the given \a text and associate it with the
4051 given \a key.
4052
4053 If you just want to store a single text block (i.e., a "comment"
4054 or just a description), you can either pass an empty key, or use a
4055 generic key like "Description".
4056
4057 The image text is embedded into the image data when you
4058 call save() or QImageWriter::write().
4059
4060 Not all image formats support embedded text. You can find out
4061 if a specific image or format supports embedding text
4062 by using QImageWriter::supportsOption(). We give an example:
4063
4064 \snippet image/supportedformat.cpp 0
4065
4066 You can use QImageWriter::supportedImageFormats() to find out
4067 which image formats are available to you.
4068
4069 \sa text(), textKeys()
4070 */
setText(const QString & key,const QString & value)4071 void QImage::setText(const QString &key, const QString &value)
4072 {
4073 if (!d)
4074 return;
4075 detach();
4076
4077 if (d)
4078 d->text.insert(key, value);
4079 }
4080
4081 /*!
4082 \fn QString QImage::text(const char* key, const char* language) const
4083 \obsolete
4084
4085 Returns the text recorded for the given \a key in the given \a
4086 language, or in a default language if \a language is \nullptr.
4087
4088 Use text() instead.
4089
4090 The language the text is recorded in is no longer relevant since
4091 the text is always set using QString and UTF-8 representation.
4092 */
4093
4094 /*!
4095 \fn QString QImage::text(const QImageTextKeyLang& keywordAndLanguage) const
4096 \overload
4097 \obsolete
4098
4099 Returns the text recorded for the given \a keywordAndLanguage.
4100
4101 Use text() instead.
4102
4103 The language the text is recorded in is no longer relevant since
4104 the text is always set using QString and UTF-8 representation.
4105 */
4106
4107 /*!
4108 \fn void QImage::setText(const char* key, const char* language, const QString& text)
4109 \obsolete
4110
4111 Sets the image text to the given \a text and associate it with the
4112 given \a key. The text is recorded in the specified \a language,
4113 or in a default language if \a language is \nullptr.
4114
4115 Use setText() instead.
4116
4117 The language the text is recorded in is no longer relevant since
4118 the text is always set using QString and UTF-8 representation.
4119
4120 \omit
4121 Records string \a for the keyword \a key. The \a key should be
4122 a portable keyword recognizable by other software - some suggested
4123 values can be found in
4124 \l{http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.Anc-text}
4125 {the PNG specification}. \a s can be any text. \a lang should
4126 specify the language code (see
4127 \l{http://www.rfc-editor.org/rfc/rfc1766.txt}{RFC 1766}) or \nullptr.
4128 \endomit
4129 */
4130
4131 /*
4132 Sets the image bits to the \a pixmap contents and returns a
4133 reference to the image.
4134
4135 If the image shares data with other images, it will first
4136 dereference the shared data.
4137
4138 Makes a call to QPixmap::convertToImage().
4139 */
4140
4141 /*!
4142 \internal
4143
4144 Used by QPainter to retrieve a paint engine for the image.
4145 */
4146
paintEngine() const4147 QPaintEngine *QImage::paintEngine() const
4148 {
4149 if (!d)
4150 return nullptr;
4151
4152 if (!d->paintEngine) {
4153 QPaintDevice *paintDevice = const_cast<QImage *>(this);
4154 QPlatformIntegration *platformIntegration = QGuiApplicationPrivate::platformIntegration();
4155 if (platformIntegration)
4156 d->paintEngine = platformIntegration->createImagePaintEngine(paintDevice);
4157 if (!d->paintEngine)
4158 d->paintEngine = new QRasterPaintEngine(paintDevice);
4159 }
4160
4161 return d->paintEngine;
4162 }
4163
4164
4165 /*!
4166 \internal
4167
4168 Returns the size for the specified \a metric on the device.
4169 */
metric(PaintDeviceMetric metric) const4170 int QImage::metric(PaintDeviceMetric metric) const
4171 {
4172 if (!d)
4173 return 0;
4174
4175 switch (metric) {
4176 case PdmWidth:
4177 return d->width;
4178
4179 case PdmHeight:
4180 return d->height;
4181
4182 case PdmWidthMM:
4183 return qRound(d->width * 1000 / d->dpmx);
4184
4185 case PdmHeightMM:
4186 return qRound(d->height * 1000 / d->dpmy);
4187
4188 case PdmNumColors:
4189 return d->colortable.size();
4190
4191 case PdmDepth:
4192 return d->depth;
4193
4194 case PdmDpiX:
4195 return qRound(d->dpmx * 0.0254);
4196 break;
4197
4198 case PdmDpiY:
4199 return qRound(d->dpmy * 0.0254);
4200 break;
4201
4202 case PdmPhysicalDpiX:
4203 return qRound(d->dpmx * 0.0254);
4204 break;
4205
4206 case PdmPhysicalDpiY:
4207 return qRound(d->dpmy * 0.0254);
4208 break;
4209
4210 case PdmDevicePixelRatio:
4211 return d->devicePixelRatio;
4212 break;
4213
4214 case PdmDevicePixelRatioScaled:
4215 return d->devicePixelRatio * QPaintDevice::devicePixelRatioFScale();
4216 break;
4217
4218 default:
4219 qWarning("QImage::metric(): Unhandled metric type %d", metric);
4220 break;
4221 }
4222 return 0;
4223 }
4224
4225
4226
4227 /*****************************************************************************
4228 QPixmap (and QImage) helper functions
4229 *****************************************************************************/
4230 /*
4231 This internal function contains the common (i.e. platform independent) code
4232 to do a transformation of pixel data. It is used by QPixmap::transform() and by
4233 QImage::transform().
4234
4235 \a trueMat is the true transformation matrix (see QPixmap::trueMatrix()) and
4236 \a xoffset is an offset to the matrix.
4237
4238 \a msbfirst specifies for 1bpp images, if the MSB or LSB comes first and \a
4239 depth specifies the colordepth of the data.
4240
4241 \a dptr is a pointer to the destination data, \a dbpl specifies the bits per
4242 line for the destination data, \a p_inc is the offset that we advance for
4243 every scanline and \a dHeight is the height of the destination image.
4244
4245 \a sprt is the pointer to the source data, \a sbpl specifies the bits per
4246 line of the source data, \a sWidth and \a sHeight are the width and height of
4247 the source data.
4248 */
4249
4250 #undef IWX_MSB
4251 #define IWX_MSB(b) if (trigx < maxws && trigy < maxhs) { \
4252 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4253 (1 << (7-((trigx>>12)&7)))) \
4254 *dptr |= b; \
4255 } \
4256 trigx += m11; \
4257 trigy += m12;
4258 // END OF MACRO
4259 #undef IWX_LSB
4260 #define IWX_LSB(b) if (trigx < maxws && trigy < maxhs) { \
4261 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4262 (1 << ((trigx>>12)&7))) \
4263 *dptr |= b; \
4264 } \
4265 trigx += m11; \
4266 trigy += m12;
4267 // END OF MACRO
4268 #undef IWX_PIX
4269 #define IWX_PIX(b) if (trigx < maxws && trigy < maxhs) { \
4270 if ((*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
4271 (1 << (7-((trigx>>12)&7)))) == 0) \
4272 *dptr &= ~b; \
4273 } \
4274 trigx += m11; \
4275 trigy += m12;
4276 // END OF MACRO
qt_xForm_helper(const QTransform & trueMat,int xoffset,int type,int depth,uchar * dptr,int dbpl,int p_inc,int dHeight,const uchar * sptr,int sbpl,int sWidth,int sHeight)4277 bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth,
4278 uchar *dptr, int dbpl, int p_inc, int dHeight,
4279 const uchar *sptr, int sbpl, int sWidth, int sHeight)
4280 {
4281 int m11 = int(trueMat.m11()*4096.0);
4282 int m12 = int(trueMat.m12()*4096.0);
4283 int m21 = int(trueMat.m21()*4096.0);
4284 int m22 = int(trueMat.m22()*4096.0);
4285 int dx = qRound(trueMat.dx()*4096.0);
4286 int dy = qRound(trueMat.dy()*4096.0);
4287
4288 int m21ydx = dx + (xoffset<<16) + (m11 + m21) / 2;
4289 int m22ydy = dy + (m12 + m22) / 2;
4290 uint trigx;
4291 uint trigy;
4292 uint maxws = sWidth<<12;
4293 uint maxhs = sHeight<<12;
4294
4295 for (int y=0; y<dHeight; y++) { // for each target scanline
4296 trigx = m21ydx;
4297 trigy = m22ydy;
4298 uchar *maxp = dptr + dbpl;
4299 if (depth != 1) {
4300 switch (depth) {
4301 case 8: // 8 bpp transform
4302 while (dptr < maxp) {
4303 if (trigx < maxws && trigy < maxhs)
4304 *dptr = *(sptr+sbpl*(trigy>>12)+(trigx>>12));
4305 trigx += m11;
4306 trigy += m12;
4307 dptr++;
4308 }
4309 break;
4310
4311 case 16: // 16 bpp transform
4312 while (dptr < maxp) {
4313 if (trigx < maxws && trigy < maxhs)
4314 *((ushort*)dptr) = *((const ushort *)(sptr+sbpl*(trigy>>12) +
4315 ((trigx>>12)<<1)));
4316 trigx += m11;
4317 trigy += m12;
4318 dptr++;
4319 dptr++;
4320 }
4321 break;
4322
4323 case 24: // 24 bpp transform
4324 while (dptr < maxp) {
4325 if (trigx < maxws && trigy < maxhs) {
4326 const uchar *p2 = sptr+sbpl*(trigy>>12) + ((trigx>>12)*3);
4327 dptr[0] = p2[0];
4328 dptr[1] = p2[1];
4329 dptr[2] = p2[2];
4330 }
4331 trigx += m11;
4332 trigy += m12;
4333 dptr += 3;
4334 }
4335 break;
4336
4337 case 32: // 32 bpp transform
4338 while (dptr < maxp) {
4339 if (trigx < maxws && trigy < maxhs)
4340 *((uint*)dptr) = *((const uint *)(sptr+sbpl*(trigy>>12) +
4341 ((trigx>>12)<<2)));
4342 trigx += m11;
4343 trigy += m12;
4344 dptr += 4;
4345 }
4346 break;
4347
4348 default: {
4349 return false;
4350 }
4351 }
4352 } else {
4353 switch (type) {
4354 case QT_XFORM_TYPE_MSBFIRST:
4355 while (dptr < maxp) {
4356 IWX_MSB(128);
4357 IWX_MSB(64);
4358 IWX_MSB(32);
4359 IWX_MSB(16);
4360 IWX_MSB(8);
4361 IWX_MSB(4);
4362 IWX_MSB(2);
4363 IWX_MSB(1);
4364 dptr++;
4365 }
4366 break;
4367 case QT_XFORM_TYPE_LSBFIRST:
4368 while (dptr < maxp) {
4369 IWX_LSB(1);
4370 IWX_LSB(2);
4371 IWX_LSB(4);
4372 IWX_LSB(8);
4373 IWX_LSB(16);
4374 IWX_LSB(32);
4375 IWX_LSB(64);
4376 IWX_LSB(128);
4377 dptr++;
4378 }
4379 break;
4380 }
4381 }
4382 m21ydx += m21;
4383 m22ydy += m22;
4384 dptr += p_inc;
4385 }
4386 return true;
4387 }
4388 #undef IWX_MSB
4389 #undef IWX_LSB
4390 #undef IWX_PIX
4391
4392 /*! \fn int QImage::serialNumber() const
4393 \obsolete
4394 Returns a number that identifies the contents of this
4395 QImage object. Distinct QImage objects can only have the same
4396 serial number if they refer to the same contents (but they don't
4397 have to).
4398
4399 Use cacheKey() instead.
4400
4401 \warning The serial number doesn't necessarily change when the
4402 image is altered. This means that it may be dangerous to use
4403 it as a cache key.
4404
4405 \sa operator==()
4406 */
4407
4408 /*!
4409 Returns a number that identifies the contents of this QImage
4410 object. Distinct QImage objects can only have the same key if they
4411 refer to the same contents.
4412
4413 The key will change when the image is altered.
4414 */
cacheKey() const4415 qint64 QImage::cacheKey() const
4416 {
4417 if (!d)
4418 return 0;
4419 else
4420 return (((qint64) d->ser_no) << 32) | ((qint64) d->detach_no);
4421 }
4422
4423 /*!
4424 \internal
4425
4426 Returns \c true if the image is detached; otherwise returns \c false.
4427
4428 \sa detach(), {Implicit Data Sharing}
4429 */
4430
isDetached() const4431 bool QImage::isDetached() const
4432 {
4433 return d && d->ref.loadRelaxed() == 1;
4434 }
4435
4436
4437 /*!
4438 Sets the alpha channel of this image to the given \a alphaChannel.
4439
4440 If \a alphaChannel is an 8 bit alpha image, the alpha values are
4441 used directly. Otherwise, \a alphaChannel is converted to 8 bit
4442 grayscale and the intensity of the pixel values is used.
4443
4444 If the image already has an alpha channel, the existing alpha channel
4445 is multiplied with the new one. If the image doesn't have an alpha
4446 channel it will be converted to a format that does.
4447
4448 The operation is similar to painting \a alphaChannel as an alpha image
4449 over this image using \c QPainter::CompositionMode_DestinationIn.
4450
4451 \sa hasAlphaChannel(), alphaChannel(),
4452 {QImage#Image Transformations}{Image Transformations},
4453 {QImage#Image Formats}{Image Formats}
4454 */
4455
setAlphaChannel(const QImage & alphaChannel)4456 void QImage::setAlphaChannel(const QImage &alphaChannel)
4457 {
4458 if (!d || alphaChannel.isNull())
4459 return;
4460
4461 if (d->paintEngine && d->paintEngine->isActive()) {
4462 qWarning("QImage::setAlphaChannel: "
4463 "Unable to set alpha channel while image is being painted on");
4464 return;
4465 }
4466
4467 const Format alphaFormat = qt_alphaVersionForPainting(d->format);
4468 if (d->format == alphaFormat)
4469 detach();
4470 else
4471 convertTo(alphaFormat);
4472
4473 if (isNull())
4474 return;
4475
4476 QImage sourceImage;
4477 if (alphaChannel.format() == QImage::Format_Alpha8 || (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()))
4478 sourceImage = alphaChannel;
4479 else
4480 sourceImage = alphaChannel.convertToFormat(QImage::Format_Grayscale8);
4481 if (!sourceImage.reinterpretAsFormat(QImage::Format_Alpha8))
4482 return;
4483
4484 QPainter painter(this);
4485 if (sourceImage.size() != size())
4486 painter.setRenderHint(QPainter::SmoothPixmapTransform);
4487 painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
4488 painter.drawImage(rect(), sourceImage);
4489 }
4490
4491
4492 #if QT_DEPRECATED_SINCE(5, 15)
4493 /*!
4494 \obsolete
4495
4496 Returns the alpha channel of the image as a new grayscale QImage in which
4497 each pixel's red, green, and blue values are given the alpha value of the
4498 original image. The color depth of the returned image is 8-bit.
4499
4500 You can see an example of use of this function in QPixmap's
4501 \l{QPixmap::}{alphaChannel()}, which works in the same way as
4502 this function on QPixmaps.
4503
4504 Most usecases for this function can be replaced with QPainter and
4505 using composition modes.
4506
4507 Note this returns a color-indexed image if you want the alpha channel in
4508 the alpha8 format instead use convertToFormat(Format_Alpha8) on the source
4509 image.
4510
4511 \warning This is an expensive function.
4512
4513 \sa setAlphaChannel(), hasAlphaChannel(), convertToFormat(),
4514 {QPixmap#Pixmap Information}{Pixmap},
4515 {QImage#Image Transformations}{Image Transformations}
4516 */
4517
alphaChannel() const4518 QImage QImage::alphaChannel() const
4519 {
4520 if (!d)
4521 return QImage();
4522
4523 int w = d->width;
4524 int h = d->height;
4525
4526 QImage image(w, h, Format_Indexed8);
4527 image.setColorCount(256);
4528
4529 // set up gray scale table.
4530 for (int i=0; i<256; ++i)
4531 image.setColor(i, qRgb(i, i, i));
4532
4533 if (!hasAlphaChannel()) {
4534 image.fill(255);
4535 return image;
4536 }
4537
4538 if (d->format == Format_Indexed8) {
4539 const uchar *src_data = d->data;
4540 uchar *dest_data = image.d->data;
4541 for (int y=0; y<h; ++y) {
4542 const uchar *src = src_data;
4543 uchar *dest = dest_data;
4544 for (int x=0; x<w; ++x) {
4545 *dest = qAlpha(d->colortable.at(*src));
4546 ++dest;
4547 ++src;
4548 }
4549 src_data += d->bytes_per_line;
4550 dest_data += image.d->bytes_per_line;
4551 }
4552 } else if (d->format == Format_Alpha8) {
4553 const uchar *src_data = d->data;
4554 uchar *dest_data = image.d->data;
4555 memcpy(dest_data, src_data, d->bytes_per_line * h);
4556 } else {
4557 QImage alpha32 = *this;
4558 bool canSkipConversion = (d->format == Format_ARGB32 || d->format == Format_ARGB32_Premultiplied);
4559 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4560 canSkipConversion = canSkipConversion || (d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied);
4561 #endif
4562 if (!canSkipConversion)
4563 alpha32 = convertToFormat(Format_ARGB32);
4564
4565 const uchar *src_data = alpha32.d->data;
4566 uchar *dest_data = image.d->data;
4567 for (int y=0; y<h; ++y) {
4568 const QRgb *src = (const QRgb *) src_data;
4569 uchar *dest = dest_data;
4570 for (int x=0; x<w; ++x) {
4571 *dest = qAlpha(*src);
4572 ++dest;
4573 ++src;
4574 }
4575 src_data += alpha32.d->bytes_per_line;
4576 dest_data += image.d->bytes_per_line;
4577 }
4578 }
4579
4580 return image;
4581 }
4582 #endif
4583
4584 /*!
4585 Returns \c true if the image has a format that respects the alpha
4586 channel, otherwise returns \c false.
4587
4588 \sa {QImage#Image Information}{Image Information}
4589 */
hasAlphaChannel() const4590 bool QImage::hasAlphaChannel() const
4591 {
4592 if (!d)
4593 return false;
4594 const QPixelFormat format = pixelFormat();
4595 if (format.alphaUsage() == QPixelFormat::UsesAlpha)
4596 return true;
4597 if (format.colorModel() == QPixelFormat::Indexed)
4598 return d->has_alpha_clut;
4599 return false;
4600 }
4601
4602 /*!
4603 \since 4.7
4604 Returns the number of bit planes in the image.
4605
4606 The number of bit planes is the number of bits of color and
4607 transparency information for each pixel. This is different from
4608 (i.e. smaller than) the depth when the image format contains
4609 unused bits.
4610
4611 \sa depth(), format(), {QImage#Image Formats}{Image Formats}
4612 */
bitPlaneCount() const4613 int QImage::bitPlaneCount() const
4614 {
4615 if (!d)
4616 return 0;
4617 int bpc = 0;
4618 switch (d->format) {
4619 case QImage::Format_Invalid:
4620 break;
4621 case QImage::Format_BGR30:
4622 case QImage::Format_RGB30:
4623 bpc = 30;
4624 break;
4625 case QImage::Format_RGB32:
4626 case QImage::Format_RGBX8888:
4627 bpc = 24;
4628 break;
4629 case QImage::Format_RGB666:
4630 bpc = 18;
4631 break;
4632 case QImage::Format_RGB555:
4633 bpc = 15;
4634 break;
4635 case QImage::Format_ARGB8555_Premultiplied:
4636 bpc = 23;
4637 break;
4638 case QImage::Format_RGB444:
4639 bpc = 12;
4640 break;
4641 case QImage::Format_RGBX64:
4642 bpc = 48;
4643 break;
4644 default:
4645 bpc = qt_depthForFormat(d->format);
4646 break;
4647 }
4648 return bpc;
4649 }
4650
4651 /*!
4652 Returns a smoothly scaled copy of the image. The returned image has a size
4653 of width \a w by height \a h pixels.
4654 */
smoothScaled(int w,int h) const4655 QImage QImage::smoothScaled(int w, int h) const {
4656 QImage src = *this;
4657 switch (src.format()) {
4658 case QImage::Format_RGB32:
4659 case QImage::Format_ARGB32_Premultiplied:
4660 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
4661 case QImage::Format_RGBX8888:
4662 #endif
4663 case QImage::Format_RGBA8888_Premultiplied:
4664 #if QT_CONFIG(raster_64bit)
4665 case QImage::Format_RGBX64:
4666 case QImage::Format_RGBA64_Premultiplied:
4667 break;
4668 case QImage::Format_RGBA64:
4669 src = src.convertToFormat(QImage::Format_RGBA64_Premultiplied);
4670 break;
4671 #endif
4672 default:
4673 if (src.hasAlphaChannel())
4674 src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
4675 else
4676 src = src.convertToFormat(QImage::Format_RGB32);
4677 }
4678 src = qSmoothScaleImage(src, w, h);
4679 if (!src.isNull())
4680 copyMetadata(src.d, d);
4681 return src;
4682 }
4683
rotated90(const QImage & image)4684 static QImage rotated90(const QImage &image)
4685 {
4686 QImage out(image.height(), image.width(), image.format());
4687 copyMetadata(&out, image);
4688 if (image.colorCount() > 0)
4689 out.setColorTable(image.colorTable());
4690 int w = image.width();
4691 int h = image.height();
4692 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][2];
4693 if (memrotate) {
4694 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4695 } else {
4696 for (int y=0; y<h; ++y) {
4697 if (image.colorCount())
4698 for (int x=0; x<w; ++x)
4699 out.setPixel(h-y-1, x, image.pixelIndex(x, y));
4700 else
4701 for (int x=0; x<w; ++x)
4702 out.setPixel(h-y-1, x, image.pixel(x, y));
4703 }
4704 }
4705 return out;
4706 }
4707
rotated180(const QImage & image)4708 static QImage rotated180(const QImage &image)
4709 {
4710 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][1];
4711 if (!memrotate)
4712 return image.mirrored(true, true);
4713
4714 QImage out(image.width(), image.height(), image.format());
4715 copyMetadata(&out, image);
4716 if (image.colorCount() > 0)
4717 out.setColorTable(image.colorTable());
4718 int w = image.width();
4719 int h = image.height();
4720 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4721 return out;
4722 }
4723
rotated270(const QImage & image)4724 static QImage rotated270(const QImage &image)
4725 {
4726 QImage out(image.height(), image.width(), image.format());
4727 copyMetadata(&out, image);
4728 if (image.colorCount() > 0)
4729 out.setColorTable(image.colorTable());
4730 int w = image.width();
4731 int h = image.height();
4732 const MemRotateFunc memrotate = qMemRotateFunctions[qPixelLayouts[image.format()].bpp][0];
4733 if (memrotate) {
4734 memrotate(image.constBits(), w, h, image.bytesPerLine(), out.bits(), out.bytesPerLine());
4735 } else {
4736 for (int y=0; y<h; ++y) {
4737 if (image.colorCount())
4738 for (int x=0; x<w; ++x)
4739 out.setPixel(y, w-x-1, image.pixelIndex(x, y));
4740 else
4741 for (int x=0; x<w; ++x)
4742 out.setPixel(y, w-x-1, image.pixel(x, y));
4743 }
4744 }
4745 return out;
4746 }
4747
4748 /*!
4749 Returns a copy of the image that is transformed using the given
4750 transformation \a matrix and transformation \a mode.
4751
4752 The returned image will normally have the same {Image Formats}{format} as
4753 the original image. However, a complex transformation may result in an
4754 image where not all pixels are covered by the transformed pixels of the
4755 original image. In such cases, those background pixels will be assigned a
4756 transparent color value, and the transformed image will be given a format
4757 with an alpha channel, even if the orginal image did not have that.
4758
4759 The transformation \a matrix is internally adjusted to compensate
4760 for unwanted translation; i.e. the image produced is the smallest
4761 image that contains all the transformed points of the original
4762 image. Use the trueMatrix() function to retrieve the actual matrix
4763 used for transforming an image.
4764
4765 Unlike the other overload, this function can be used to perform perspective
4766 transformations on images.
4767
4768 \sa trueMatrix(), {QImage#Image Transformations}{Image
4769 Transformations}
4770 */
4771
transformed(const QTransform & matrix,Qt::TransformationMode mode) const4772 QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
4773 {
4774 if (!d)
4775 return QImage();
4776
4777 Q_TRACE_SCOPE(QImage_transformed, matrix, mode);
4778
4779 // source image data
4780 int ws = width();
4781 int hs = height();
4782
4783 // target image data
4784 int wd;
4785 int hd;
4786
4787 // compute size of target image
4788 QTransform mat = trueMatrix(matrix, ws, hs);
4789 bool complex_xform = false;
4790 bool scale_xform = false;
4791 if (mat.type() <= QTransform::TxScale) {
4792 if (mat.type() == QTransform::TxNone) // identity matrix
4793 return *this;
4794 else if (mat.m11() == -1. && mat.m22() == -1.)
4795 return rotated180(*this);
4796
4797 if (mode == Qt::FastTransformation) {
4798 hd = qRound(qAbs(mat.m22()) * hs);
4799 wd = qRound(qAbs(mat.m11()) * ws);
4800 } else {
4801 hd = int(qAbs(mat.m22()) * hs + 0.9999);
4802 wd = int(qAbs(mat.m11()) * ws + 0.9999);
4803 }
4804 scale_xform = true;
4805 } else {
4806 if (mat.type() <= QTransform::TxRotate && mat.m11() == 0 && mat.m22() == 0) {
4807 if (mat.m12() == 1. && mat.m21() == -1.)
4808 return rotated90(*this);
4809 else if (mat.m12() == -1. && mat.m21() == 1.)
4810 return rotated270(*this);
4811 }
4812
4813 QPolygonF a(QRectF(0, 0, ws, hs));
4814 a = mat.map(a);
4815 QRect r = a.boundingRect().toAlignedRect();
4816 wd = r.width();
4817 hd = r.height();
4818 complex_xform = true;
4819 }
4820
4821 if (wd == 0 || hd == 0)
4822 return QImage();
4823
4824 // Make use of the optimized algorithm when we're scaling
4825 if (scale_xform && mode == Qt::SmoothTransformation) {
4826 if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip
4827 return smoothScaled(wd, hd).mirrored(true, true);
4828 } else if (mat.m11() < 0.0F) { // horizontal flip
4829 return smoothScaled(wd, hd).mirrored(true, false);
4830 } else if (mat.m22() < 0.0F) { // vertical flip
4831 return smoothScaled(wd, hd).mirrored(false, true);
4832 } else { // no flipping
4833 return smoothScaled(wd, hd);
4834 }
4835 }
4836
4837 int bpp = depth();
4838
4839 int sbpl = bytesPerLine();
4840 const uchar *sptr = bits();
4841
4842 QImage::Format target_format = d->format;
4843
4844 if (complex_xform || mode == Qt::SmoothTransformation) {
4845 if (d->format < QImage::Format_RGB32 || !hasAlphaChannel()) {
4846 target_format = qt_alphaVersion(d->format);
4847 }
4848 }
4849
4850 QImage dImage(wd, hd, target_format);
4851 QIMAGE_SANITYCHECK_MEMORY(dImage);
4852
4853 if (target_format == QImage::Format_MonoLSB
4854 || target_format == QImage::Format_Mono
4855 || target_format == QImage::Format_Indexed8) {
4856 dImage.d->colortable = d->colortable;
4857 dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform;
4858 }
4859
4860 // initizialize the data
4861 if (target_format == QImage::Format_Indexed8) {
4862 if (dImage.d->colortable.size() < 256) {
4863 // colors are left in the color table, so pick that one as transparent
4864 dImage.d->colortable.append(0x0);
4865 memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.d->nbytes);
4866 } else {
4867 memset(dImage.bits(), 0, dImage.d->nbytes);
4868 }
4869 } else
4870 memset(dImage.bits(), 0x00, dImage.d->nbytes);
4871
4872 if (target_format >= QImage::Format_RGB32) {
4873 // Prevent QPainter from applying devicePixelRatio corrections
4874 const QImage sImage = (devicePixelRatio() != 1) ? QImage(constBits(), width(), height(), format()) : *this;
4875
4876 Q_ASSERT(sImage.devicePixelRatio() == 1);
4877 Q_ASSERT(sImage.devicePixelRatio() == dImage.devicePixelRatio());
4878
4879 QPainter p(&dImage);
4880 if (mode == Qt::SmoothTransformation) {
4881 p.setRenderHint(QPainter::Antialiasing);
4882 p.setRenderHint(QPainter::SmoothPixmapTransform);
4883 }
4884 p.setTransform(mat);
4885 p.drawImage(QPoint(0, 0), sImage);
4886 } else {
4887 bool invertible;
4888 mat = mat.inverted(&invertible); // invert matrix
4889 if (!invertible) // error, return null image
4890 return QImage();
4891
4892 // create target image (some of the code is from QImage::copy())
4893 int type = format() == Format_Mono ? QT_XFORM_TYPE_MSBFIRST : QT_XFORM_TYPE_LSBFIRST;
4894 int dbpl = dImage.bytesPerLine();
4895 qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs);
4896 }
4897 copyMetadata(dImage.d, d);
4898
4899 return dImage;
4900 }
4901
4902 /*!
4903 \fn QTransform QImage::trueMatrix(const QTransform &matrix, int width, int height)
4904
4905 Returns the actual matrix used for transforming an image with the
4906 given \a width, \a height and \a matrix.
4907
4908 When transforming an image using the transformed() function, the
4909 transformation matrix is internally adjusted to compensate for
4910 unwanted translation, i.e. transformed() returns the smallest
4911 image containing all transformed points of the original image.
4912 This function returns the modified matrix, which maps points
4913 correctly from the original image into the new image.
4914
4915 Unlike the other overload, this function creates transformation
4916 matrices that can be used to perform perspective
4917 transformations on images.
4918
4919 \sa transformed(), {QImage#Image Transformations}{Image
4920 Transformations}
4921 */
4922
trueMatrix(const QTransform & matrix,int w,int h)4923 QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h)
4924 {
4925 const QRectF rect(0, 0, w, h);
4926 const QRect mapped = matrix.mapRect(rect).toAlignedRect();
4927 const QPoint delta = mapped.topLeft();
4928 return matrix * QTransform().translate(-delta.x(), -delta.y());
4929 }
4930
4931 /*!
4932 \since 5.14
4933
4934 Sets the image color space to \a colorSpace without performing any conversions on image data.
4935
4936 \sa colorSpace()
4937 */
setColorSpace(const QColorSpace & colorSpace)4938 void QImage::setColorSpace(const QColorSpace &colorSpace)
4939 {
4940 if (!d)
4941 return;
4942 if (d->colorSpace == colorSpace)
4943 return;
4944 if (!isDetached()) // Detach only if shared, not for read-only data.
4945 detach();
4946 d->colorSpace = colorSpace;
4947 }
4948
4949 /*!
4950 \since 5.14
4951
4952 Converts the image to \a colorSpace.
4953
4954 If the image has no valid color space, the method does nothing.
4955
4956 \sa convertedToColorSpace(), setColorSpace()
4957 */
convertToColorSpace(const QColorSpace & colorSpace)4958 void QImage::convertToColorSpace(const QColorSpace &colorSpace)
4959 {
4960 if (!d)
4961 return;
4962 if (!d->colorSpace.isValid())
4963 return;
4964 if (!colorSpace.isValid()) {
4965 qWarning() << "QImage::convertToColorSpace: Output colorspace is not valid";
4966 return;
4967 }
4968 detach();
4969 applyColorTransform(d->colorSpace.transformationToColorSpace(colorSpace));
4970 d->colorSpace = colorSpace;
4971 }
4972
4973 /*!
4974 \since 5.14
4975
4976 Returns the image converted to \a colorSpace.
4977
4978 If the image has no valid color space, a null QImage is returned.
4979
4980 \sa convertToColorSpace()
4981 */
convertedToColorSpace(const QColorSpace & colorSpace) const4982 QImage QImage::convertedToColorSpace(const QColorSpace &colorSpace) const
4983 {
4984 if (!d || !d->colorSpace.isValid() || !colorSpace.isValid())
4985 return QImage();
4986 QImage image = copy();
4987 image.convertToColorSpace(colorSpace);
4988 return image;
4989 }
4990
4991 /*!
4992 \since 5.14
4993
4994 Returns the color space of the image if a color space is defined.
4995 */
colorSpace() const4996 QColorSpace QImage::colorSpace() const
4997 {
4998 if (!d)
4999 return QColorSpace();
5000 return d->colorSpace;
5001 }
5002
5003 /*!
5004 \since 5.14
5005
5006 Applies the color transformation \a transform to all pixels in the image.
5007 */
applyColorTransform(const QColorTransform & transform)5008 void QImage::applyColorTransform(const QColorTransform &transform)
5009 {
5010 QImage::Format oldFormat = format();
5011 if (depth() > 32) {
5012 if (format() != QImage::Format_RGBX64 && format() != QImage::Format_RGBA64
5013 && format() != QImage::Format_RGBA64_Premultiplied)
5014 *this = std::move(*this).convertToFormat(QImage::Format_RGBA64);
5015 } else if (format() != QImage::Format_ARGB32 && format() != QImage::Format_RGB32
5016 && format() != QImage::Format_ARGB32_Premultiplied) {
5017 if (hasAlphaChannel())
5018 *this = std::move(*this).convertToFormat(QImage::Format_ARGB32);
5019 else
5020 *this = std::move(*this).convertToFormat(QImage::Format_RGB32);
5021 }
5022
5023 QColorTransformPrivate::TransformFlags flags = QColorTransformPrivate::Unpremultiplied;
5024 switch (format()) {
5025 case Format_ARGB32_Premultiplied:
5026 case Format_RGBA64_Premultiplied:
5027 flags = QColorTransformPrivate::Premultiplied;
5028 break;
5029 case Format_RGB32:
5030 case Format_RGBX64:
5031 flags = QColorTransformPrivate::InputOpaque;
5032 break;
5033 case Format_ARGB32:
5034 case Format_RGBA64:
5035 break;
5036 default:
5037 Q_UNREACHABLE();
5038 }
5039
5040 std::function<void(int,int)> transformSegment;
5041
5042 if (depth() > 32) {
5043 transformSegment = [&](int yStart, int yEnd) {
5044 for (int y = yStart; y < yEnd; ++y) {
5045 QRgba64 *scanline = reinterpret_cast<QRgba64 *>(scanLine(y));
5046 transform.d->apply(scanline, scanline, width(), flags);
5047 }
5048 };
5049 } else {
5050 transformSegment = [&](int yStart, int yEnd) {
5051 for (int y = yStart; y < yEnd; ++y) {
5052 QRgb *scanline = reinterpret_cast<QRgb *>(scanLine(y));
5053 transform.d->apply(scanline, scanline, width(), flags);
5054 }
5055 };
5056 }
5057
5058 #if QT_CONFIG(thread) && !defined(Q_OS_WASM)
5059 int segments = sizeInBytes() / (1<<16);
5060 segments = std::min(segments, height());
5061 QThreadPool *threadPool = QThreadPool::globalInstance();
5062 if (segments > 1 && threadPool && !threadPool->contains(QThread::currentThread())) {
5063 QSemaphore semaphore;
5064 int y = 0;
5065 for (int i = 0; i < segments; ++i) {
5066 int yn = (height() - y) / (segments - i);
5067 threadPool->start([&, y, yn]() {
5068 transformSegment(y, y + yn);
5069 semaphore.release(1);
5070 });
5071 y += yn;
5072 }
5073 semaphore.acquire(segments);
5074 } else
5075 #endif
5076 transformSegment(0, height());
5077
5078 if (oldFormat != format())
5079 *this = std::move(*this).convertToFormat(oldFormat);
5080 }
5081
5082
convertInPlace(QImage::Format newFormat,Qt::ImageConversionFlags flags)5083 bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags)
5084 {
5085 if (format == newFormat)
5086 return true;
5087
5088 // No in-place conversion if we have to detach
5089 if (ref.loadRelaxed() > 1 || !own_data)
5090 return false;
5091
5092 InPlace_Image_Converter converter = qimage_inplace_converter_map[format][newFormat];
5093 if (converter)
5094 return converter(this, flags);
5095 else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8 && !qimage_converter_map[format][newFormat])
5096 // Convert inplace generic, but only if there are no direct converters,
5097 // any direct ones are probably better even if not inplace.
5098 return convert_generic_inplace(this, newFormat, flags);
5099 else
5100 return false;
5101 }
5102
5103 /*!
5104 \typedef QImage::DataPtr
5105 \internal
5106 */
5107
5108 /*!
5109 \fn DataPtr & QImage::data_ptr()
5110 \internal
5111 */
5112
5113 #ifndef QT_NO_DEBUG_STREAM
operator <<(QDebug dbg,const QImage & i)5114 QDebug operator<<(QDebug dbg, const QImage &i)
5115 {
5116 QDebugStateSaver saver(dbg);
5117 dbg.nospace();
5118 dbg.noquote();
5119 dbg << "QImage(";
5120 if (i.isNull()) {
5121 dbg << "null";
5122 } else {
5123 dbg << i.size() << ",format=" << i.format() << ",depth=" << i.depth();
5124 if (i.colorCount())
5125 dbg << ",colorCount=" << i.colorCount();
5126 const int bytesPerLine = i.bytesPerLine();
5127 dbg << ",devicePixelRatio=" << i.devicePixelRatio()
5128 << ",bytesPerLine=" << bytesPerLine << ",sizeInBytes=" << i.sizeInBytes();
5129 if (dbg.verbosity() > 2 && i.height() > 0) {
5130 const int outputLength = qMin(bytesPerLine, 24);
5131 dbg << ",line0="
5132 << QByteArray(reinterpret_cast<const char *>(i.scanLine(0)), outputLength).toHex()
5133 << "...";
5134 }
5135 }
5136 dbg << ')';
5137 return dbg;
5138 }
5139 #endif
5140
5141 /*!
5142 \fn void QImage::setNumColors(int n)
5143 \obsolete
5144
5145 Resizes the color table to contain \a n entries.
5146
5147 \sa setColorCount()
5148 */
5149
5150 /*!
5151 \fn int QImage::numBytes() const
5152 \obsolete
5153
5154 Returns the number of bytes occupied by the image data.
5155
5156 \sa sizeInBytes()
5157 */
5158
5159 /*!
5160 \fn QStringList QImage::textLanguages() const
5161 \obsolete
5162
5163 Returns the language identifiers for which some texts are recorded.
5164 Note that if you want to iterate over the list, you should iterate over a copy.
5165
5166 The language the text is recorded in is no longer relevant since the text is
5167 always set using QString and UTF-8 representation.
5168
5169 \sa textKeys()
5170 */
5171
5172 /*!
5173 \fn QList<QImageTextKeyLang> QImage::textList() const
5174 \obsolete
5175
5176 Returns a list of QImageTextKeyLang objects that enumerate all the texts
5177 key/language pairs set for this image.
5178
5179 The language the text is recorded in is no longer relevant since the text
5180 is always set using QString and UTF-8 representation.
5181
5182 \sa textKeys()
5183 */
5184
5185 static Q_CONSTEXPR QPixelFormat pixelformats[] = {
5186 //QImage::Format_Invalid:
5187 QPixelFormat(),
5188 //QImage::Format_Mono:
5189 QPixelFormat(QPixelFormat::Indexed,
5190 /*RED*/ 1,
5191 /*GREEN*/ 0,
5192 /*BLUE*/ 0,
5193 /*FOURTH*/ 0,
5194 /*FIFTH*/ 0,
5195 /*ALPHA*/ 0,
5196 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5197 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5198 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5199 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5200 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5201 //QImage::Format_MonoLSB:
5202 QPixelFormat(QPixelFormat::Indexed,
5203 /*RED*/ 1,
5204 /*GREEN*/ 0,
5205 /*BLUE*/ 0,
5206 /*FOURTH*/ 0,
5207 /*FIFTH*/ 0,
5208 /*ALPHA*/ 0,
5209 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5210 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5211 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5212 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5213 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5214 //QImage::Format_Indexed8:
5215 QPixelFormat(QPixelFormat::Indexed,
5216 /*RED*/ 8,
5217 /*GREEN*/ 0,
5218 /*BLUE*/ 0,
5219 /*FOURTH*/ 0,
5220 /*FIFTH*/ 0,
5221 /*ALPHA*/ 0,
5222 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5223 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5224 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5225 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5226 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5227 //QImage::Format_RGB32:
5228 QPixelFormat(QPixelFormat::RGB,
5229 /*RED*/ 8,
5230 /*GREEN*/ 8,
5231 /*BLUE*/ 8,
5232 /*FOURTH*/ 0,
5233 /*FIFTH*/ 0,
5234 /*ALPHA*/ 8,
5235 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5236 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5237 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5238 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5239 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5240 //QImage::Format_ARGB32:
5241 QPixelFormat(QPixelFormat::RGB,
5242 /*RED*/ 8,
5243 /*GREEN*/ 8,
5244 /*BLUE*/ 8,
5245 /*FOURTH*/ 0,
5246 /*FIFTH*/ 0,
5247 /*ALPHA*/ 8,
5248 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5249 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5250 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5251 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5252 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5253 //QImage::Format_ARGB32_Premultiplied:
5254 QPixelFormat(QPixelFormat::RGB,
5255 /*RED*/ 8,
5256 /*GREEN*/ 8,
5257 /*BLUE*/ 8,
5258 /*FOURTH*/ 0,
5259 /*FIFTH*/ 0,
5260 /*ALPHA*/ 8,
5261 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5262 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5263 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5264 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5265 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5266 //QImage::Format_RGB16:
5267 QPixelFormat(QPixelFormat::RGB,
5268 /*RED*/ 5,
5269 /*GREEN*/ 6,
5270 /*BLUE*/ 5,
5271 /*FOURTH*/ 0,
5272 /*FIFTH*/ 0,
5273 /*ALPHA*/ 0,
5274 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5275 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5276 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5277 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5278 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5279 //QImage::Format_ARGB8565_Premultiplied:
5280 QPixelFormat(QPixelFormat::RGB,
5281 /*RED*/ 5,
5282 /*GREEN*/ 6,
5283 /*BLUE*/ 5,
5284 /*FOURTH*/ 0,
5285 /*FIFTH*/ 0,
5286 /*ALPHA*/ 8,
5287 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5288 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5289 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5290 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5291 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5292 //QImage::Format_RGB666:
5293 QPixelFormat(QPixelFormat::RGB,
5294 /*RED*/ 6,
5295 /*GREEN*/ 6,
5296 /*BLUE*/ 6,
5297 /*FOURTH*/ 0,
5298 /*FIFTH*/ 0,
5299 /*ALPHA*/ 0,
5300 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5301 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5302 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5303 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5304 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5305 //QImage::Format_ARGB6666_Premultiplied:
5306 QPixelFormat(QPixelFormat::RGB,
5307 /*RED*/ 6,
5308 /*GREEN*/ 6,
5309 /*BLUE*/ 6,
5310 /*FOURTH*/ 0,
5311 /*FIFTH*/ 0,
5312 /*ALPHA*/ 6,
5313 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5314 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5315 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5316 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5317 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5318 //QImage::Format_RGB555:
5319 QPixelFormat(QPixelFormat::RGB,
5320 /*RED*/ 5,
5321 /*GREEN*/ 5,
5322 /*BLUE*/ 5,
5323 /*FOURTH*/ 0,
5324 /*FIFTH*/ 0,
5325 /*ALPHA*/ 0,
5326 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5327 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5328 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5329 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5330 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5331 //QImage::Format_ARGB8555_Premultiplied:
5332 QPixelFormat(QPixelFormat::RGB,
5333 /*RED*/ 5,
5334 /*GREEN*/ 5,
5335 /*BLUE*/ 5,
5336 /*FOURTH*/ 0,
5337 /*FIFTH*/ 0,
5338 /*ALPHA*/ 8,
5339 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5340 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5341 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5342 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5343 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5344 //QImage::Format_RGB888:
5345 QPixelFormat(QPixelFormat::RGB,
5346 /*RED*/ 8,
5347 /*GREEN*/ 8,
5348 /*BLUE*/ 8,
5349 /*FOURTH*/ 0,
5350 /*FIFTH*/ 0,
5351 /*ALPHA*/ 0,
5352 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5353 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5354 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5355 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5356 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5357 //QImage::Format_RGB444:
5358 QPixelFormat(QPixelFormat::RGB,
5359 /*RED*/ 4,
5360 /*GREEN*/ 4,
5361 /*BLUE*/ 4,
5362 /*FOURTH*/ 0,
5363 /*FIFTH*/ 0,
5364 /*ALPHA*/ 0,
5365 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5366 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5367 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5368 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5369 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5370 //QImage::Format_ARGB4444_Premultiplied:
5371 QPixelFormat(QPixelFormat::RGB,
5372 /*RED*/ 4,
5373 /*GREEN*/ 4,
5374 /*BLUE*/ 4,
5375 /*FOURTH*/ 0,
5376 /*FIFTH*/ 0,
5377 /*ALPHA*/ 4,
5378 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5379 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5380 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5381 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5382 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5383 //QImage::Format_RGBX8888:
5384 QPixelFormat(QPixelFormat::RGB,
5385 /*RED*/ 8,
5386 /*GREEN*/ 8,
5387 /*BLUE*/ 8,
5388 /*FOURTH*/ 0,
5389 /*FIFTH*/ 0,
5390 /*ALPHA*/ 8,
5391 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5392 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5393 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5394 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5395 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5396 //QImage::Format_RGBA8888:
5397 QPixelFormat(QPixelFormat::RGB,
5398 /*RED*/ 8,
5399 /*GREEN*/ 8,
5400 /*BLUE*/ 8,
5401 /*FOURTH*/ 0,
5402 /*FIFTH*/ 0,
5403 /*ALPHA*/ 8,
5404 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5405 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5406 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5407 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5408 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5409 //QImage::Format_RGBA8888_Premultiplied:
5410 QPixelFormat(QPixelFormat::RGB,
5411 /*RED*/ 8,
5412 /*GREEN*/ 8,
5413 /*BLUE*/ 8,
5414 /*FOURTH*/ 0,
5415 /*FIFTH*/ 0,
5416 /*ALPHA*/ 8,
5417 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5418 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5419 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5420 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5421 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5422 //QImage::Format_BGR30:
5423 QPixelFormat(QPixelFormat::BGR,
5424 /*RED*/ 10,
5425 /*GREEN*/ 10,
5426 /*BLUE*/ 10,
5427 /*FOURTH*/ 0,
5428 /*FIFTH*/ 0,
5429 /*ALPHA*/ 2,
5430 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5431 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5432 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5433 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5434 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5435 //QImage::Format_A2BGR30_Premultiplied:
5436 QPixelFormat(QPixelFormat::BGR,
5437 /*RED*/ 10,
5438 /*GREEN*/ 10,
5439 /*BLUE*/ 10,
5440 /*FOURTH*/ 0,
5441 /*FIFTH*/ 0,
5442 /*ALPHA*/ 2,
5443 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5444 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5445 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5446 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5447 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5448 //QImage::Format_RGB30:
5449 QPixelFormat(QPixelFormat::RGB,
5450 /*RED*/ 10,
5451 /*GREEN*/ 10,
5452 /*BLUE*/ 10,
5453 /*FOURTH*/ 0,
5454 /*FIFTH*/ 0,
5455 /*ALPHA*/ 2,
5456 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5457 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5458 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5459 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5460 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5461 //QImage::Format_A2RGB30_Premultiplied:
5462 QPixelFormat(QPixelFormat::RGB,
5463 /*RED*/ 10,
5464 /*GREEN*/ 10,
5465 /*BLUE*/ 10,
5466 /*FOURTH*/ 0,
5467 /*FIFTH*/ 0,
5468 /*ALPHA*/ 2,
5469 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5470 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5471 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5472 /*INTERPRETATION*/ QPixelFormat::UnsignedInteger,
5473 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5474 //QImage::Format_Alpha8:
5475 QPixelFormat(QPixelFormat::Alpha,
5476 /*First*/ 0,
5477 /*SECOND*/ 0,
5478 /*THIRD*/ 0,
5479 /*FOURTH*/ 0,
5480 /*FIFTH*/ 0,
5481 /*ALPHA*/ 8,
5482 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5483 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5484 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5485 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5486 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5487 //QImage::Format_Grayscale8:
5488 QPixelFormat(QPixelFormat::Grayscale,
5489 /*GRAY*/ 8,
5490 /*SECOND*/ 0,
5491 /*THIRD*/ 0,
5492 /*FOURTH*/ 0,
5493 /*FIFTH*/ 0,
5494 /*ALPHA*/ 0,
5495 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5496 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5497 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5498 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5499 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5500 //QImage::Format_RGBX64:
5501 QPixelFormat(QPixelFormat::RGB,
5502 /*RED*/ 16,
5503 /*GREEN*/ 16,
5504 /*BLUE*/ 16,
5505 /*FOURTH*/ 0,
5506 /*FIFTH*/ 0,
5507 /*ALPHA*/ 16,
5508 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5509 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5510 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5511 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5512 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5513 //QImage::Format_RGBA64:
5514 QPixelFormat(QPixelFormat::RGB,
5515 /*RED*/ 16,
5516 /*GREEN*/ 16,
5517 /*BLUE*/ 16,
5518 /*FOURTH*/ 0,
5519 /*FIFTH*/ 0,
5520 /*ALPHA*/ 16,
5521 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5522 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5523 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5524 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5525 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5526 //QImage::Format_RGBA64_Premultiplied:
5527 QPixelFormat(QPixelFormat::RGB,
5528 /*RED*/ 16,
5529 /*GREEN*/ 16,
5530 /*BLUE*/ 16,
5531 /*FOURTH*/ 0,
5532 /*FIFTH*/ 0,
5533 /*ALPHA*/ 16,
5534 /*ALPHA USAGE*/ QPixelFormat::UsesAlpha,
5535 /*ALPHA POSITION*/ QPixelFormat::AtEnd,
5536 /*PREMULTIPLIED*/ QPixelFormat::Premultiplied,
5537 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5538 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5539 //QImage::Format_Grayscale16:
5540 QPixelFormat(QPixelFormat::Grayscale,
5541 /*GRAY*/ 16,
5542 /*SECOND*/ 0,
5543 /*THIRD*/ 0,
5544 /*FOURTH*/ 0,
5545 /*FIFTH*/ 0,
5546 /*ALPHA*/ 0,
5547 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5548 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5549 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5550 /*INTERPRETATION*/ QPixelFormat::UnsignedShort,
5551 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5552 //QImage::Format_BGR888:
5553 QPixelFormat(QPixelFormat::BGR,
5554 /*RED*/ 8,
5555 /*GREEN*/ 8,
5556 /*BLUE*/ 8,
5557 /*FOURTH*/ 0,
5558 /*FIFTH*/ 0,
5559 /*ALPHA*/ 0,
5560 /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha,
5561 /*ALPHA POSITION*/ QPixelFormat::AtBeginning,
5562 /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied,
5563 /*INTERPRETATION*/ QPixelFormat::UnsignedByte,
5564 /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian),
5565 };
5566 Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats);
5567
5568 /*!
5569 Returns the QImage::Format as a QPixelFormat
5570 */
pixelFormat() const5571 QPixelFormat QImage::pixelFormat() const noexcept
5572 {
5573 return toPixelFormat(format());
5574 }
5575
5576 /*!
5577 Converts \a format into a QPixelFormat
5578 */
toPixelFormat(QImage::Format format)5579 QPixelFormat QImage::toPixelFormat(QImage::Format format) noexcept
5580 {
5581 Q_ASSERT(static_cast<int>(format) < NImageFormats);
5582 return pixelformats[format];
5583 }
5584
5585 /*!
5586 Converts \a format into a QImage::Format
5587 */
toImageFormat(QPixelFormat format)5588 QImage::Format QImage::toImageFormat(QPixelFormat format) noexcept
5589 {
5590 for (int i = 0; i < NImageFormats; i++) {
5591 if (format == pixelformats[i])
5592 return Format(i);
5593 }
5594 return Format_Invalid;
5595 }
5596
qt_imageTransform(QImage & src,QImageIOHandler::Transformations orient)5597 Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformations orient)
5598 {
5599 if (orient == QImageIOHandler::TransformationNone)
5600 return;
5601 if (orient == QImageIOHandler::TransformationRotate270) {
5602 src = rotated270(src);
5603 } else {
5604 src = std::move(src).mirrored(orient & QImageIOHandler::TransformationMirror,
5605 orient & QImageIOHandler::TransformationFlip);
5606 if (orient & QImageIOHandler::TransformationRotate90)
5607 src = rotated90(src);
5608 }
5609 }
5610
qt_getImageText(const QImage & image,const QString & description)5611 QMap<QString, QString> qt_getImageText(const QImage &image, const QString &description)
5612 {
5613 QMap<QString, QString> text = qt_getImageTextFromDescription(description);
5614 const auto textKeys = image.textKeys();
5615 for (const QString &key : textKeys) {
5616 if (!key.isEmpty() && !text.contains(key))
5617 text.insert(key, image.text(key));
5618 }
5619 return text;
5620 }
5621
qt_getImageTextFromDescription(const QString & description)5622 QMap<QString, QString> qt_getImageTextFromDescription(const QString &description)
5623 {
5624 QMap<QString, QString> text;
5625 const auto pairs = description.splitRef(QLatin1String("\n\n"));
5626 for (const QStringRef &pair : pairs) {
5627 int index = pair.indexOf(QLatin1Char(':'));
5628 if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) {
5629 if (!pair.trimmed().isEmpty())
5630 text.insert(QLatin1String("Description"), pair.toString().simplified());
5631 } else {
5632 const QStringRef key = pair.left(index);
5633 if (!key.trimmed().isEmpty())
5634 text.insert(key.toString(), pair.mid(index + 2).toString().simplified());
5635 }
5636 }
5637 return text;
5638 }
5639
5640 QT_END_NAMESPACE
5641