1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://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 http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://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 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qimage.h"
43 #include "qdatastream.h"
44 #include "qbuffer.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 <ctype.h>
54 #include <stdlib.h>
55 #include <limits.h>
56 #include <math.h>
57 #include <private/qdrawhelper_p.h>
58 #include <private/qmemrotate_p.h>
59 #include <private/qpixmapdata_p.h>
60 #include <private/qimagescale_p.h>
61 #include <private/qsimd_p.h>
62
63 #include <qhash.h>
64
65 #if defined(Q_OS_SYMBIAN)
66 #include <private/qpaintengine_raster_symbian_p.h>
67 #else
68 #include <private/qpaintengine_raster_p.h>
69 #endif
70
71 #include <private/qimage_p.h>
72 #include <private/qfont_p.h>
73
74 QT_BEGIN_NAMESPACE
75
checkPixelSize(const QImage::Format format)76 static inline bool checkPixelSize(const QImage::Format format)
77 {
78 switch (format) {
79 case QImage::Format_ARGB8565_Premultiplied:
80 return (sizeof(qargb8565) == 3);
81 case QImage::Format_RGB666:
82 return (sizeof(qrgb666) == 3);
83 case QImage::Format_ARGB6666_Premultiplied:
84 return (sizeof(qargb6666) == 3);
85 case QImage::Format_RGB555:
86 return (sizeof(qrgb555) == 2);
87 case QImage::Format_ARGB8555_Premultiplied:
88 return (sizeof(qargb8555) == 3);
89 case QImage::Format_RGB888:
90 return (sizeof(qrgb888) == 3);
91 case QImage::Format_RGB444:
92 return (sizeof(qrgb444) == 2);
93 case QImage::Format_ARGB4444_Premultiplied:
94 return (sizeof(qargb4444) == 2);
95 default:
96 return true;
97 }
98 }
99
100 #if defined(Q_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
101 #pragma message disable narrowptr
102 #endif
103
104
105 #define QIMAGE_SANITYCHECK_MEMORY(image) \
106 if ((image).isNull()) { \
107 qWarning("QImage: out of memory, returning null image"); \
108 return QImage(); \
109 }
110
111
112 static QImage rotated90(const QImage &src);
113 static QImage rotated180(const QImage &src);
114 static QImage rotated270(const QImage &src);
115
116 // ### Qt 5: remove
qt_image_id(const QImage & image)117 Q_GUI_EXPORT qint64 qt_image_id(const QImage &image)
118 {
119 return image.cacheKey();
120 }
121
qt_image_colortable(const QImage & image)122 const QVector<QRgb> *qt_image_colortable(const QImage &image)
123 {
124 return &image.d->colortable;
125 }
126
127 QBasicAtomicInt qimage_serial_number = Q_BASIC_ATOMIC_INITIALIZER(1);
128
QImageData()129 QImageData::QImageData()
130 : ref(0), width(0), height(0), depth(0), nbytes(0), data(0),
131 #ifdef QT3_SUPPORT
132 jumptable(0),
133 #endif
134 format(QImage::Format_ARGB32), bytes_per_line(0),
135 ser_no(qimage_serial_number.fetchAndAddRelaxed(1)),
136 detach_no(0),
137 dpmx(qt_defaultDpiX() * 100 / qreal(2.54)),
138 dpmy(qt_defaultDpiY() * 100 / qreal(2.54)),
139 offset(0, 0), own_data(true), ro_data(false), has_alpha_clut(false),
140 is_cached(false), paintEngine(0)
141 {
142 }
143
144 /*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors)
145
146 \internal
147
148 Creates a new image data.
149 Returns 0 if invalid parameters are give or anything else failed.
150 */
create(const QSize & size,QImage::Format format,int numColors)151 QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors)
152 {
153 if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid)
154 return 0; // invalid parameter(s)
155
156 if (!checkPixelSize(format)) {
157 qWarning("QImageData::create(): Invalid pixel size for format %i",
158 format);
159 return 0;
160 }
161
162 uint width = size.width();
163 uint height = size.height();
164 uint depth = qt_depthForFormat(format);
165
166 switch (format) {
167 case QImage::Format_Mono:
168 case QImage::Format_MonoLSB:
169 numColors = 2;
170 break;
171 case QImage::Format_Indexed8:
172 numColors = qBound(0, numColors, 256);
173 break;
174 default:
175 numColors = 0;
176 break;
177 }
178
179 const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4)
180
181 // sanity check for potential overflows
182 if (INT_MAX/depth < width
183 || bytes_per_line <= 0
184 || height <= 0
185 || INT_MAX/uint(bytes_per_line) < height
186 || INT_MAX/sizeof(uchar *) < uint(height))
187 return 0;
188
189 QScopedPointer<QImageData> d(new QImageData);
190 d->colortable.resize(numColors);
191 if (depth == 1) {
192 d->colortable[0] = QColor(Qt::black).rgba();
193 d->colortable[1] = QColor(Qt::white).rgba();
194 } else {
195 for (int i = 0; i < numColors; ++i)
196 d->colortable[i] = 0;
197 }
198
199 d->width = width;
200 d->height = height;
201 d->depth = depth;
202 d->format = format;
203 d->has_alpha_clut = false;
204 d->is_cached = false;
205
206 d->bytes_per_line = bytes_per_line;
207
208 d->nbytes = d->bytes_per_line*height;
209 d->data = (uchar *)malloc(d->nbytes);
210
211 if (!d->data) {
212 return 0;
213 }
214
215 d->ref.ref();
216 return d.take();
217
218 }
219
~QImageData()220 QImageData::~QImageData()
221 {
222 if (is_cached)
223 QImagePixmapCleanupHooks::executeImageHooks((((qint64) ser_no) << 32) | ((qint64) detach_no));
224 delete paintEngine;
225 if (data && own_data)
226 free(data);
227 #ifdef QT3_SUPPORT
228 if (jumptable)
229 free(jumptable);
230 jumptable = 0;
231 #endif
232 data = 0;
233 }
234
235
checkForAlphaPixels() const236 bool QImageData::checkForAlphaPixels() const
237 {
238 bool has_alpha_pixels = false;
239
240 switch (format) {
241
242 case QImage::Format_Mono:
243 case QImage::Format_MonoLSB:
244 case QImage::Format_Indexed8:
245 has_alpha_pixels = has_alpha_clut;
246 break;
247
248 case QImage::Format_ARGB32:
249 case QImage::Format_ARGB32_Premultiplied: {
250 uchar *bits = data;
251 for (int y=0; y<height && !has_alpha_pixels; ++y) {
252 for (int x=0; x<width; ++x)
253 has_alpha_pixels |= (((uint *)bits)[x] & 0xff000000) != 0xff000000;
254 bits += bytes_per_line;
255 }
256 } break;
257
258 case QImage::Format_ARGB8555_Premultiplied:
259 case QImage::Format_ARGB8565_Premultiplied: {
260 uchar *bits = data;
261 uchar *end_bits = data + bytes_per_line;
262
263 for (int y=0; y<height && !has_alpha_pixels; ++y) {
264 while (bits < end_bits) {
265 has_alpha_pixels |= bits[0] != 0;
266 bits += 3;
267 }
268 bits = end_bits;
269 end_bits += bytes_per_line;
270 }
271 } break;
272
273 case QImage::Format_ARGB6666_Premultiplied: {
274 uchar *bits = data;
275 uchar *end_bits = data + bytes_per_line;
276
277 for (int y=0; y<height && !has_alpha_pixels; ++y) {
278 while (bits < end_bits) {
279 has_alpha_pixels |= (bits[0] & 0xfc) != 0;
280 bits += 3;
281 }
282 bits = end_bits;
283 end_bits += bytes_per_line;
284 }
285 } break;
286
287 case QImage::Format_ARGB4444_Premultiplied: {
288 uchar *bits = data;
289 uchar *end_bits = data + bytes_per_line;
290
291 for (int y=0; y<height && !has_alpha_pixels; ++y) {
292 while (bits < end_bits) {
293 has_alpha_pixels |= (bits[0] & 0xf0) != 0;
294 bits += 2;
295 }
296 bits = end_bits;
297 end_bits += bytes_per_line;
298 }
299 } break;
300
301 default:
302 break;
303 }
304
305 return has_alpha_pixels;
306 }
307
308 /*!
309 \class QImage
310
311 \ingroup painting
312 \ingroup shared
313
314 \reentrant
315
316 \brief The QImage class provides a hardware-independent image
317 representation that allows direct access to the pixel data, and
318 can be used as a paint device.
319
320 Qt provides four classes for handling image data: QImage, QPixmap,
321 QBitmap and QPicture. QImage is designed and optimized for I/O,
322 and for direct pixel access and manipulation, while QPixmap is
323 designed and optimized for showing images on screen. QBitmap is
324 only a convenience class that inherits QPixmap, ensuring a
325 depth of 1. Finally, the QPicture class is a paint device that
326 records and replays QPainter commands.
327
328 Because QImage is a QPaintDevice subclass, QPainter can be used to
329 draw directly onto images. When using QPainter on a QImage, the
330 painting can be performed in another thread than the current GUI
331 thread.
332
333 The QImage class supports several image formats described by the
334 \l Format enum. These include monochrome, 8-bit, 32-bit and
335 alpha-blended images which are available in all versions of Qt
336 4.x.
337
338 QImage provides a collection of functions that can be used to
339 obtain a variety of information about the image. There are also
340 several functions that enables transformation of the image.
341
342 QImage objects can be passed around by value since the QImage
343 class uses \l{Implicit Data Sharing}{implicit data
344 sharing}. QImage objects can also be streamed and compared.
345
346 \note If you would like to load QImage objects in a static build of Qt,
347 refer to the \l{How To Create Qt Plugins#Static Plugins}{Plugin HowTo}.
348
349 \warning Painting on a QImage with the format
350 QImage::Format_Indexed8 is not supported.
351
352 \tableofcontents
353
354 \section1 Reading and Writing Image Files
355
356 QImage provides several ways of loading an image file: The file
357 can be loaded when constructing the QImage object, or by using the
358 load() or loadFromData() functions later on. QImage also provides
359 the static fromData() function, constructing a QImage from the
360 given data. When loading an image, the file name can either refer
361 to an actual file on disk or to one of the application's embedded
362 resources. See \l{The Qt Resource System} overview for details
363 on how to embed images and other resource files in the
364 application's executable.
365
366 Simply call the save() function to save a QImage object.
367
368 The complete list of supported file formats are available through
369 the QImageReader::supportedImageFormats() and
370 QImageWriter::supportedImageFormats() functions. New file formats
371 can be added as plugins. By default, Qt supports the following
372 formats:
373
374 \table
375 \header \o Format \o Description \o Qt's support
376 \row \o BMP \o Windows Bitmap \o Read/write
377 \row \o GIF \o Graphic Interchange Format (optional) \o Read
378 \row \o JPG \o Joint Photographic Experts Group \o Read/write
379 \row \o JPEG \o Joint Photographic Experts Group \o Read/write
380 \row \o PNG \o Portable Network Graphics \o Read/write
381 \row \o PBM \o Portable Bitmap \o Read
382 \row \o PGM \o Portable Graymap \o Read
383 \row \o PPM \o Portable Pixmap \o Read/write
384 \row \o TIFF \o Tagged Image File Format \o Read/write
385 \row \o XBM \o X11 Bitmap \o Read/write
386 \row \o XPM \o X11 Pixmap \o Read/write
387 \endtable
388
389 \section1 Image Information
390
391 QImage provides a collection of functions that can be used to
392 obtain a variety of information about the image:
393
394 \table
395 \header
396 \o \o Available Functions
397
398 \row
399 \o Geometry
400 \o
401
402 The size(), width(), height(), dotsPerMeterX(), and
403 dotsPerMeterY() functions provide information about the image size
404 and aspect ratio.
405
406 The rect() function returns the image's enclosing rectangle. The
407 valid() function tells if a given pair of coordinates is within
408 this rectangle. The offset() function returns the number of pixels
409 by which the image is intended to be offset by when positioned
410 relative to other images, which also can be manipulated using the
411 setOffset() function.
412
413 \row
414 \o Colors
415 \o
416
417 The color of a pixel can be retrieved by passing its coordinates
418 to the pixel() function. The pixel() function returns the color
419 as a QRgb value indepedent of the image's format.
420
421 In case of monochrome and 8-bit images, the colorCount() and
422 colorTable() functions provide information about the color
423 components used to store the image data: The colorTable() function
424 returns the image's entire color table. To obtain a single entry,
425 use the pixelIndex() function to retrieve the pixel index for a
426 given pair of coordinates, then use the color() function to
427 retrieve the color. Note that if you create an 8-bit image
428 manually, you have to set a valid color table on the image as
429 well.
430
431 The hasAlphaChannel() function tells if the image's format
432 respects the alpha channel, or not. The allGray() and
433 isGrayscale() functions tell whether an image's colors are all
434 shades of gray.
435
436 See also the \l {QImage#Pixel Manipulation}{Pixel Manipulation}
437 and \l {QImage#Image Transformations}{Image Transformations}
438 sections.
439
440 \row
441 \o Text
442 \o
443
444 The text() function returns the image text associated with the
445 given text key. An image's text keys can be retrieved using the
446 textKeys() function. Use the setText() function to alter an
447 image's text.
448
449 \row
450 \o Low-level information
451 \o
452
453 The depth() function returns the depth of the image. The supported
454 depths are 1 (monochrome), 8, 16, 24 and 32 bits. The
455 bitPlaneCount() function tells how many of those bits that are
456 used. For more information see the
457 \l {QImage#Image Formats}{Image Formats} section.
458
459 The format(), bytesPerLine(), and byteCount() functions provide
460 low-level information about the data stored in the image.
461
462 The cacheKey() function returns a number that uniquely
463 identifies the contents of this QImage object.
464 \endtable
465
466 \section1 Pixel Manipulation
467
468 The functions used to manipulate an image's pixels depend on the
469 image format. The reason is that monochrome and 8-bit images are
470 index-based and use a color lookup table, while 32-bit images
471 store ARGB values directly. For more information on image formats,
472 see the \l {Image Formats} section.
473
474 In case of a 32-bit image, the setPixel() function can be used to
475 alter the color of the pixel at the given coordinates to any other
476 color specified as an ARGB quadruplet. To make a suitable QRgb
477 value, use the qRgb() (adding a default alpha component to the
478 given RGB values, i.e. creating an opaque color) or qRgba()
479 function. For example:
480
481 \table
482 \header
483 \o {2,1}32-bit
484 \row
485 \o \inlineimage qimage-32bit_scaled.png
486 \o
487 \snippet doc/src/snippets/code/src_gui_image_qimage.cpp 0
488 \endtable
489
490 In case of a 8-bit and monchrome images, the pixel value is only
491 an index from the image's color table. So the setPixel() function
492 can only be used to alter the color of the pixel at the given
493 coordinates to a predefined color from the image's color table,
494 i.e. it can only change the pixel's index value. To alter or add a
495 color to an image's color table, use the setColor() function.
496
497 An entry in the color table is an ARGB quadruplet encoded as an
498 QRgb value. Use the qRgb() and qRgba() functions to make a
499 suitable QRgb value for use with the setColor() function. For
500 example:
501
502 \table
503 \header
504 \o {2,1} 8-bit
505 \row
506 \o \inlineimage qimage-8bit_scaled.png
507 \o
508 \snippet doc/src/snippets/code/src_gui_image_qimage.cpp 1
509 \endtable
510
511 QImage also provide the scanLine() function which returns a
512 pointer to the pixel data at the scanline with the given index,
513 and the bits() function which returns a pointer to the first pixel
514 data (this is equivalent to \c scanLine(0)).
515
516 \section1 Image Formats
517
518 Each pixel stored in a QImage is represented by an integer. The
519 size of the integer varies depending on the format. QImage
520 supports several image formats described by the \l Format
521 enum.
522
523 Monochrome images are stored using 1-bit indexes into a color table
524 with at most two colors. There are two different types of
525 monochrome images: big endian (MSB first) or little endian (LSB
526 first) bit order.
527
528 8-bit images are stored using 8-bit indexes into a color table,
529 i.e. they have a single byte per pixel. The color table is a
530 QVector<QRgb>, and the QRgb typedef is equivalent to an unsigned
531 int containing an ARGB quadruplet on the format 0xAARRGGBB.
532
533 32-bit images have no color table; instead, each pixel contains an
534 QRgb value. There are three different types of 32-bit images
535 storing RGB (i.e. 0xffRRGGBB), ARGB and premultiplied ARGB
536 values respectively. In the premultiplied format the red, green,
537 and blue channels are multiplied by the alpha component divided by
538 255.
539
540 An image's format can be retrieved using the format()
541 function. Use the convertToFormat() functions to convert an image
542 into another format. The allGray() and isGrayscale() functions
543 tell whether a color image can safely be converted to a grayscale
544 image.
545
546 \section1 Image Transformations
547
548 QImage supports a number of functions for creating a new image
549 that is a transformed version of the original: The
550 createAlphaMask() function builds and returns a 1-bpp mask from
551 the alpha buffer in this image, and the createHeuristicMask()
552 function creates and returns a 1-bpp heuristic mask for this
553 image. The latter function works by selecting a color from one of
554 the corners, then chipping away pixels of that color starting at
555 all the edges.
556
557 The mirrored() function returns a mirror of the image in the
558 desired direction, the scaled() returns a copy of the image scaled
559 to a rectangle of the desired measures, and the rgbSwapped() function
560 constructs a BGR image from a RGB image.
561
562 The scaledToWidth() and scaledToHeight() functions return scaled
563 copies of the image.
564
565 The transformed() function returns a copy of the image that is
566 transformed with the given transformation matrix and
567 transformation mode: Internally, the transformation matrix is
568 adjusted to compensate for unwanted translation,
569 i.e. transformed() returns the smallest image containing all
570 transformed points of the original image. The static trueMatrix()
571 function returns the actual matrix used for transforming the
572 image.
573
574 There are also functions for changing attributes of an image
575 in-place:
576
577 \table
578 \header \o Function \o Description
579 \row
580 \o setDotsPerMeterX()
581 \o Defines the aspect ratio by setting the number of pixels that fit
582 horizontally in a physical meter.
583 \row
584 \o setDotsPerMeterY()
585 \o Defines the aspect ratio by setting the number of pixels that fit
586 vertically in a physical meter.
587 \row
588 \o fill()
589 \o Fills the entire image with the given pixel value.
590 \row
591 \o invertPixels()
592 \o Inverts all pixel values in the image using the given InvertMode value.
593 \row
594 \o setColorTable()
595 \o Sets the color table used to translate color indexes. Only
596 monochrome and 8-bit formats.
597 \row
598 \o setColorCount()
599 \o Resizes the color table. Only monochrome and 8-bit formats.
600
601 \endtable
602
603 \section1 Legal Information
604
605 For smooth scaling, the transformed() functions use code based on
606 smooth scaling algorithm by Daniel M. Duley.
607
608 \legalese
609 Copyright (C) 2004, 2005 Daniel M. Duley
610
611 Redistribution and use in source and binary forms, with or without
612 modification, are permitted provided that the following conditions
613 are met:
614
615 1. Redistributions of source code must retain the above copyright
616 notice, this list of conditions and the following disclaimer.
617 2. Redistributions in binary form must reproduce the above copyright
618 notice, this list of conditions and the following disclaimer in the
619 documentation and/or other materials provided with the distribution.
620
621 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
622 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
623 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
624 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
625 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
626 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
627 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
628 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
629 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
630 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
631 \endlegalese
632
633 \sa QImageReader, QImageWriter, QPixmap, QSvgRenderer, {Image Composition Example},
634 {Image Viewer Example}, {Scribble Example}, {Pixelator Example}
635 */
636
637 /*!
638 \enum QImage::Endian
639 \compat
640
641 This enum type is used to describe the endianness of the CPU and
642 graphics hardware. It is provided here for compatibility with earlier versions of Qt.
643
644 Use the \l Format enum instead. The \l Format enum specify the
645 endianess for monchrome formats, but for other formats the
646 endianess is not relevant.
647
648 \value IgnoreEndian Endianness does not matter. Useful for some
649 operations that are independent of endianness.
650 \value BigEndian Most significant bit first or network byte order, as on SPARC, PowerPC, and Motorola CPUs.
651 \value LittleEndian Least significant bit first or little endian byte order, as on Intel x86.
652 */
653
654 /*!
655 \enum QImage::InvertMode
656
657 This enum type is used to describe how pixel values should be
658 inverted in the invertPixels() function.
659
660 \value InvertRgb Invert only the RGB values and leave the alpha
661 channel unchanged.
662
663 \value InvertRgba Invert all channels, including the alpha channel.
664
665 \sa invertPixels()
666 */
667
668 /*!
669 \enum QImage::Format
670
671 The following image formats are available in Qt. Values greater
672 than QImage::Format_RGB16 were added in Qt 4.4. See the notes
673 after the table.
674
675 \value Format_Invalid The image is invalid.
676 \value Format_Mono The image is stored using 1-bit per pixel. Bytes are
677 packed with the most significant bit (MSB) first.
678 \value Format_MonoLSB The image is stored using 1-bit per pixel. Bytes are
679 packed with the less significant bit (LSB) first.
680
681 \value Format_Indexed8 The image is stored using 8-bit indexes
682 into a colormap.
683
684 \value Format_RGB32 The image is stored using a 32-bit RGB format (0xffRRGGBB).
685
686 \value Format_ARGB32 The image is stored using a 32-bit ARGB
687 format (0xAARRGGBB).
688
689 \value Format_ARGB32_Premultiplied The image is stored using a premultiplied 32-bit
690 ARGB format (0xAARRGGBB), i.e. the red,
691 green, and blue channels are multiplied
692 by the alpha component divided by 255. (If RR, GG, or BB
693 has a higher value than the alpha channel, the results are
694 undefined.) Certain operations (such as image composition
695 using alpha blending) are faster using premultiplied ARGB32
696 than with plain ARGB32.
697
698 \value Format_RGB16 The image is stored using a 16-bit RGB format (5-6-5).
699
700 \value Format_ARGB8565_Premultiplied The image is stored using a
701 premultiplied 24-bit ARGB format (8-5-6-5).
702 \value Format_RGB666 The image is stored using a 24-bit RGB format (6-6-6).
703 The unused most significant bits is always zero.
704 \value Format_ARGB6666_Premultiplied The image is stored using a
705 premultiplied 24-bit ARGB format (6-6-6-6).
706 \value Format_RGB555 The image is stored using a 16-bit RGB format (5-5-5).
707 The unused most significant bit is always zero.
708 \value Format_ARGB8555_Premultiplied The image is stored using a
709 premultiplied 24-bit ARGB format (8-5-5-5).
710 \value Format_RGB888 The image is stored using a 24-bit RGB format (8-8-8).
711 \value Format_RGB444 The image is stored using a 16-bit RGB format (4-4-4).
712 The unused bits are always zero.
713 \value Format_ARGB4444_Premultiplied The image is stored using a
714 premultiplied 16-bit ARGB format (4-4-4-4).
715
716 \note Drawing into a QImage with QImage::Format_Indexed8 is not
717 supported.
718
719 \note Do not render into ARGB32 images using QPainter. Using
720 QImage::Format_ARGB32_Premultiplied is significantly faster.
721
722 \sa format(), convertToFormat()
723 */
724
725 /*****************************************************************************
726 QImage member functions
727 *****************************************************************************/
728
729 // table to flip bits
730 static const uchar bitflip[256] = {
731 /*
732 open OUT, "| fmt";
733 for $i (0..255) {
734 print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
735 (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
736 (($i << 7) & 0x80) | (($i << 5) & 0x40) |
737 (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
738 }
739 close OUT;
740 */
741 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
742 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
743 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
744 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
745 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
746 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
747 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
748 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
749 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
750 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
751 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
752 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
753 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
754 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
755 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
756 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
757 };
758
qt_get_bitflip_array()759 const uchar *qt_get_bitflip_array() // called from QPixmap code
760 {
761 return bitflip;
762 }
763
764 #if defined(QT3_SUPPORT)
formatFor(int depth,QImage::Endian bitOrder)765 static QImage::Format formatFor(int depth, QImage::Endian bitOrder)
766 {
767 QImage::Format format;
768 if (depth == 1) {
769 format = bitOrder == QImage::BigEndian ? QImage::Format_Mono : QImage::Format_MonoLSB;
770 } else if (depth == 8) {
771 format = QImage::Format_Indexed8;
772 } else if (depth == 32) {
773 format = QImage::Format_RGB32;
774 } else if (depth == 24) {
775 format = QImage::Format_RGB888;
776 } else if (depth == 16) {
777 format = QImage::Format_RGB16;
778 } else {
779 qWarning("QImage: Depth %d not supported", depth);
780 format = QImage::Format_Invalid;
781 }
782 return format;
783 }
784 #endif
785
786 /*!
787 Constructs a null image.
788
789 \sa isNull()
790 */
791
QImage()792 QImage::QImage()
793 : QPaintDevice()
794 {
795 d = 0;
796 }
797
798 /*!
799 Constructs an image with the given \a width, \a height and \a
800 format.
801
802 A \l{isNull()}{null} image will be returned if memory cannot be allocated.
803
804 \warning This will create a QImage with uninitialized data. Call
805 fill() to fill the image with an appropriate pixel value before
806 drawing onto it with QPainter.
807 */
QImage(int width,int height,Format format)808 QImage::QImage(int width, int height, Format format)
809 : QPaintDevice()
810 {
811 d = QImageData::create(QSize(width, height), format, 0);
812 }
813
814 /*!
815 Constructs an image with the given \a size and \a format.
816
817 A \l{isNull()}{null} image is returned if memory cannot be allocated.
818
819 \warning This will create a QImage with uninitialized data. Call
820 fill() to fill the image with an appropriate pixel value before
821 drawing onto it with QPainter.
822 */
QImage(const QSize & size,Format format)823 QImage::QImage(const QSize &size, Format format)
824 : QPaintDevice()
825 {
826 d = QImageData::create(size, format, 0);
827 }
828
829
830
create(uchar * data,int width,int height,int bpl,QImage::Format format,bool readOnly)831 QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QImage::Format format, bool readOnly)
832 {
833 QImageData *d = 0;
834
835 if (format == QImage::Format_Invalid)
836 return d;
837
838 if (!checkPixelSize(format)) {
839 qWarning("QImageData::create(): Invalid pixel size for format %i",
840 format);
841 return 0;
842 }
843
844 const int depth = qt_depthForFormat(format);
845 const int calc_bytes_per_line = ((width * depth + 31)/32) * 4;
846 const int min_bytes_per_line = (width * depth + 7)/8;
847
848 if (bpl <= 0)
849 bpl = calc_bytes_per_line;
850
851 if (width <= 0 || height <= 0 || !data
852 || INT_MAX/sizeof(uchar *) < uint(height)
853 || INT_MAX/uint(depth) < uint(width)
854 || bpl <= 0
855 || height <= 0
856 || bpl < min_bytes_per_line
857 || INT_MAX/uint(bpl) < uint(height))
858 return d; // invalid parameter(s)
859
860 d = new QImageData;
861 d->ref.ref();
862
863 d->own_data = false;
864 d->ro_data = readOnly;
865 d->data = data;
866 d->width = width;
867 d->height = height;
868 d->depth = depth;
869 d->format = format;
870
871 d->bytes_per_line = bpl;
872 d->nbytes = d->bytes_per_line * height;
873
874 return d;
875 }
876
877 /*!
878 Constructs an image with the given \a width, \a height and \a
879 format, that uses an existing memory buffer, \a data. The \a width
880 and \a height must be specified in pixels, \a data must be 32-bit aligned,
881 and each scanline of data in the image must also be 32-bit aligned.
882
883 The buffer must remain valid throughout the life of the
884 QImage. The image does not delete the buffer at destruction.
885
886 If \a format is an indexed color format, the image color table is
887 initially empty and must be sufficiently expanded with
888 setColorCount() or setColorTable() before the image is used.
889 */
QImage(uchar * data,int width,int height,Format format)890 QImage::QImage(uchar* data, int width, int height, Format format)
891 : QPaintDevice()
892 {
893 d = QImageData::create(data, width, height, 0, format, false);
894 }
895
896 /*!
897 Constructs an image with the given \a width, \a height and \a
898 format, that uses an existing read-only memory buffer, \a
899 data. The \a width and \a height must be specified in pixels, \a
900 data must be 32-bit aligned, and each scanline of data in the
901 image must also be 32-bit aligned.
902
903 The buffer must remain valid throughout the life of the QImage and
904 all copies that have not been modified or otherwise detached from
905 the original buffer. The image does not delete the buffer at
906 destruction.
907
908 If \a format is an indexed color format, the image color table is
909 initially empty and must be sufficiently expanded with
910 setColorCount() or setColorTable() before the image is used.
911
912 Unlike the similar QImage constructor that takes a non-const data buffer,
913 this version will never alter the contents of the buffer. For example,
914 calling QImage::bits() will return a deep copy of the image, rather than
915 the buffer passed to the constructor. This allows for the efficiency of
916 constructing a QImage from raw data, without the possibility of the raw
917 data being changed.
918 */
QImage(const uchar * data,int width,int height,Format format)919 QImage::QImage(const uchar* data, int width, int height, Format format)
920 : QPaintDevice()
921 {
922 d = QImageData::create(const_cast<uchar*>(data), width, height, 0, format, true);
923 }
924
925 /*!
926 Constructs an image with the given \a width, \a height and \a
927 format, that uses an existing memory buffer, \a data. The \a width
928 and \a height must be specified in pixels. \a bytesPerLine
929 specifies the number of bytes per line (stride).
930
931 The buffer must remain valid throughout the life of the
932 QImage. The image does not delete the buffer at destruction.
933
934 If \a format is an indexed color format, the image color table is
935 initially empty and must be sufficiently expanded with
936 setColorCount() or setColorTable() before the image is used.
937 */
QImage(uchar * data,int width,int height,int bytesPerLine,Format format)938 QImage::QImage(uchar *data, int width, int height, int bytesPerLine, Format format)
939 :QPaintDevice()
940 {
941 d = QImageData::create(data, width, height, bytesPerLine, format, false);
942 }
943
944
945 /*!
946 Constructs an image with the given \a width, \a height and \a
947 format, that uses an existing memory buffer, \a data. The \a width
948 and \a height must be specified in pixels. \a bytesPerLine
949 specifies the number of bytes per line (stride).
950
951 The buffer must remain valid throughout the life of the
952 QImage. The image does not delete the buffer at destruction.
953
954 If \a format is an indexed color format, the image color table is
955 initially empty and must be sufficiently expanded with
956 setColorCount() or setColorTable() before the image is used.
957
958 Unlike the similar QImage constructor that takes a non-const data buffer,
959 this version will never alter the contents of the buffer. For example,
960 calling QImage::bits() will return a deep copy of the image, rather than
961 the buffer passed to the constructor. This allows for the efficiency of
962 constructing a QImage from raw data, without the possibility of the raw
963 data being changed.
964 */
965
QImage(const uchar * data,int width,int height,int bytesPerLine,Format format)966 QImage::QImage(const uchar *data, int width, int height, int bytesPerLine, Format format)
967 :QPaintDevice()
968 {
969 d = QImageData::create(const_cast<uchar*>(data), width, height, bytesPerLine, format, true);
970 }
971
972 /*!
973 Constructs an image and tries to load the image from the file with
974 the given \a fileName.
975
976 The loader attempts to read the image using the specified \a
977 format. If the \a format is not specified (which is the default),
978 the loader probes the file for a header to guess the file format.
979
980 If the loading of the image failed, this object is a null image.
981
982 The file name can either refer to an actual file on disk or to one
983 of the application's embedded resources. See the
984 \l{resources.html}{Resource System} overview for details on how to
985 embed images and other resource files in the application's
986 executable.
987
988 \sa isNull(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
989 */
990
QImage(const QString & fileName,const char * format)991 QImage::QImage(const QString &fileName, const char *format)
992 : QPaintDevice()
993 {
994 d = 0;
995 load(fileName, format);
996 }
997
998 /*!
999 Constructs an image and tries to load the image from the file with
1000 the given \a fileName.
1001
1002 The loader attempts to read the image using the specified \a
1003 format. If the \a format is not specified (which is the default),
1004 the loader probes the file for a header to guess the file format.
1005
1006 If the loading of the image failed, this object is a null image.
1007
1008 The file name can either refer to an actual file on disk or to one
1009 of the application's embedded resources. See the
1010 \l{resources.html}{Resource System} overview for details on how to
1011 embed images and other resource files in the application's
1012 executable.
1013
1014 You can disable this constructor by defining \c
1015 QT_NO_CAST_FROM_ASCII when you compile your applications. This can
1016 be useful, for example, if you want to ensure that all
1017 user-visible strings go through QObject::tr().
1018
1019 \sa QString::fromAscii(), isNull(), {QImage#Reading and Writing
1020 Image Files}{Reading and Writing Image Files}
1021 */
1022 #ifndef QT_NO_CAST_FROM_ASCII
QImage(const char * fileName,const char * format)1023 QImage::QImage(const char *fileName, const char *format)
1024 : QPaintDevice()
1025 {
1026 // ### Qt 5: if you remove the QImage(const QByteArray &) QT3_SUPPORT
1027 // constructor, remove this constructor as well. The constructor here
1028 // exists so that QImage("foo.png") compiles without ambiguity.
1029 d = 0;
1030 load(QString::fromAscii(fileName), format);
1031 }
1032 #endif
1033
1034 #ifndef QT_NO_IMAGEFORMAT_XPM
1035 extern bool qt_read_xpm_image_or_array(QIODevice *device, const char * const *source, QImage &image);
1036
1037 /*!
1038 Constructs an image from the given \a xpm image.
1039
1040 Make sure that the image is a valid XPM image. Errors are silently
1041 ignored.
1042
1043 Note that it's possible to squeeze the XPM variable a little bit
1044 by using an unusual declaration:
1045
1046 \snippet doc/src/snippets/code/src_gui_image_qimage.cpp 2
1047
1048 The extra \c const makes the entire definition read-only, which is
1049 slightly more efficient (e.g., when the code is in a shared
1050 library) and able to be stored in ROM with the application.
1051 */
1052
QImage(const char * const xpm[])1053 QImage::QImage(const char * const xpm[])
1054 : QPaintDevice()
1055 {
1056 d = 0;
1057 if (!xpm)
1058 return;
1059 if (!qt_read_xpm_image_or_array(0, xpm, *this))
1060 // Issue: Warning because the constructor may be ambigious
1061 qWarning("QImage::QImage(), XPM is not supported");
1062 }
1063 #endif // QT_NO_IMAGEFORMAT_XPM
1064
1065 /*!
1066 \fn QImage::QImage(const QByteArray &data)
1067
1068 Use the static fromData() function instead.
1069
1070 \oldcode
1071 QByteArray data;
1072 ...
1073 QImage image(data);
1074 \newcode
1075 QByteArray data;
1076 ...
1077 QImage image = QImage::fromData(data);
1078 \endcode
1079 */
1080
1081
1082 /*!
1083 Constructs a shallow copy of the given \a image.
1084
1085 For more information about shallow copies, see the \l {Implicit
1086 Data Sharing} documentation.
1087
1088 \sa copy()
1089 */
1090
QImage(const QImage & image)1091 QImage::QImage(const QImage &image)
1092 : QPaintDevice()
1093 {
1094 if (image.paintingActive()) {
1095 d = 0;
1096 operator=(image.copy());
1097 } else {
1098 d = image.d;
1099 if (d)
1100 d->ref.ref();
1101 }
1102 }
1103
1104 #ifdef QT3_SUPPORT
1105 /*!
1106 \fn QImage::QImage(int width, int height, int depth, int numColors, Endian bitOrder)
1107
1108 Constructs an image with the given \a width, \a height, \a depth,
1109 \a numColors colors and \a bitOrder.
1110
1111 Use the constructor that accepts a width, a height and a format
1112 (i.e. specifying the depth and bit order), in combination with the
1113 setColorCount() function, instead.
1114
1115 \oldcode
1116 QImage image(width, height, depth, numColors);
1117 \newcode
1118 QImage image(width, height, format);
1119
1120 // For 8 bit images the default number of colors is 256. If
1121 // another number of colors is required it can be specified
1122 // using the setColorCount() function.
1123 image.setColorCount(numColors);
1124 \endcode
1125 */
1126
QImage(int w,int h,int depth,int colorCount,Endian bitOrder)1127 QImage::QImage(int w, int h, int depth, int colorCount, Endian bitOrder)
1128 : QPaintDevice()
1129 {
1130 d = QImageData::create(QSize(w, h), formatFor(depth, bitOrder), colorCount);
1131 }
1132
1133 /*!
1134 Constructs an image with the given \a size, \a depth, \a numColors
1135 and \a bitOrder.
1136
1137 Use the constructor that accepts a size and a format
1138 (i.e. specifying the depth and bit order), in combination with the
1139 setColorCount() function, instead.
1140
1141 \oldcode
1142 QSize mySize(width, height);
1143 QImage image(mySize, depth, numColors);
1144 \newcode
1145 QSize mySize(width, height);
1146 QImage image(mySize, format);
1147
1148 // For 8 bit images the default number of colors is 256. If
1149 // another number of colors is required it can be specified
1150 // using the setColorCount() function.
1151 image.setColorCount(numColors);
1152 \endcode
1153 */
QImage(const QSize & size,int depth,int numColors,Endian bitOrder)1154 QImage::QImage(const QSize& size, int depth, int numColors, Endian bitOrder)
1155 : QPaintDevice()
1156 {
1157 d = QImageData::create(size, formatFor(depth, bitOrder), numColors);
1158 }
1159
1160 /*!
1161 \fn QImage::QImage(uchar* data, int width, int height, int depth, const QRgb* colortable, int numColors, Endian bitOrder)
1162
1163 Constructs an image with the given \a width, \a height, depth, \a
1164 colortable, \a numColors and \a bitOrder, that uses an existing
1165 memory buffer, \a data.
1166
1167 Use the constructor that accepts a uchar pointer, a width, a
1168 height and a format (i.e. specifying the depth and bit order), in
1169 combination with the setColorTable() function, instead.
1170
1171 \oldcode
1172 uchar *myData;
1173 QRgb *myColorTable;
1174
1175 QImage image(myData, width, height, depth,
1176 myColorTable, numColors, IgnoreEndian);
1177 \newcode
1178 uchar *myData;
1179 QVector<QRgb> myColorTable;
1180
1181 QImage image(myData, width, height, format);
1182 image.setColorTable(myColorTable);
1183 \endcode
1184 */
QImage(uchar * data,int w,int h,int depth,const QRgb * colortable,int numColors,Endian bitOrder)1185 QImage::QImage(uchar* data, int w, int h, int depth, const QRgb* colortable, int numColors, Endian bitOrder)
1186 : QPaintDevice()
1187 {
1188 d = 0;
1189 Format f = formatFor(depth, bitOrder);
1190 if (f == Format_Invalid)
1191 return;
1192
1193 const int bytes_per_line = ((w*depth+31)/32)*4; // bytes per scanline
1194 if (w <= 0 || h <= 0 || numColors < 0 || !data
1195 || INT_MAX/sizeof(uchar *) < uint(h)
1196 || INT_MAX/uint(depth) < uint(w)
1197 || bytes_per_line <= 0
1198 || INT_MAX/uint(bytes_per_line) < uint(h))
1199 return; // invalid parameter(s)
1200 d = new QImageData;
1201 d->ref.ref();
1202
1203 d->own_data = false;
1204 d->data = data;
1205 d->width = w;
1206 d->height = h;
1207 d->depth = depth;
1208 d->format = f;
1209 if (depth == 32)
1210 numColors = 0;
1211
1212 d->bytes_per_line = bytes_per_line;
1213 d->nbytes = d->bytes_per_line * h;
1214 if (colortable) {
1215 d->colortable.resize(numColors);
1216 for (int i = 0; i < numColors; ++i)
1217 d->colortable[i] = colortable[i];
1218 } else if (numColors) {
1219 setColorCount(numColors);
1220 }
1221 }
1222
1223 #ifdef Q_WS_QWS
1224
1225 /*!
1226 \fn QImage::QImage(uchar* data, int width, int height, int depth, int bytesPerLine, const QRgb* colortable, int numColors, Endian bitOrder)
1227
1228 Constructs an image with the given \a width, \a height, \a depth,
1229 \a bytesPerLine, \a colortable, \a numColors and \a bitOrder, that
1230 uses an existing memory buffer, \a data. The image does not delete
1231 the buffer at destruction.
1232
1233 \warning This constructor is only available in Qt for Embedded Linux.
1234
1235 The data has to be 32-bit aligned, and each scanline of data in the image
1236 must also be 32-bit aligned, so it's no longer possible to specify a custom
1237 \a bytesPerLine value.
1238 */
QImage(uchar * data,int w,int h,int depth,int bpl,const QRgb * colortable,int numColors,Endian bitOrder)1239 QImage::QImage(uchar* data, int w, int h, int depth, int bpl, const QRgb* colortable, int numColors, Endian bitOrder)
1240 : QPaintDevice()
1241 {
1242 d = 0;
1243 Format f = formatFor(depth, bitOrder);
1244 if (f == Format_Invalid)
1245 return;
1246 if (!data || w <= 0 || h <= 0 || depth <= 0 || numColors < 0
1247 || INT_MAX/sizeof(uchar *) < uint(h)
1248 || INT_MAX/uint(depth) < uint(w)
1249 || bpl <= 0
1250 || INT_MAX/uint(bpl) < uint(h))
1251 return; // invalid parameter(s)
1252
1253 d = new QImageData;
1254 d->ref.ref();
1255 d->own_data = false;
1256 d->data = data;
1257 d->width = w;
1258 d->height = h;
1259 d->depth = depth;
1260 d->format = f;
1261 if (depth == 32)
1262 numColors = 0;
1263 d->bytes_per_line = bpl;
1264 d->nbytes = d->bytes_per_line * h;
1265 if (colortable) {
1266 d->colortable.resize(numColors);
1267 for (int i = 0; i < numColors; ++i)
1268 d->colortable[i] = colortable[i];
1269 } else if (numColors) {
1270 setColorCount(numColors);
1271 }
1272 }
1273 #endif // Q_WS_QWS
1274 #endif // QT3_SUPPORT
1275
1276 /*!
1277 Destroys the image and cleans up.
1278 */
1279
~QImage()1280 QImage::~QImage()
1281 {
1282 if (d && !d->ref.deref())
1283 delete d;
1284 }
1285
1286 /*!
1287 Assigns a shallow copy of the given \a image to this image and
1288 returns a reference to this image.
1289
1290 For more information about shallow copies, see the \l {Implicit
1291 Data Sharing} documentation.
1292
1293 \sa copy(), QImage()
1294 */
1295
operator =(const QImage & image)1296 QImage &QImage::operator=(const QImage &image)
1297 {
1298 if (image.paintingActive()) {
1299 operator=(image.copy());
1300 } else {
1301 if (image.d)
1302 image.d->ref.ref();
1303 if (d && !d->ref.deref())
1304 delete d;
1305 d = image.d;
1306 }
1307 return *this;
1308 }
1309
1310 /*!
1311 \fn void QImage::swap(QImage &other)
1312 \since 4.8
1313
1314 Swaps image \a other with this image. This operation is very
1315 fast and never fails.
1316 */
1317
1318 /*!
1319 \internal
1320 */
devType() const1321 int QImage::devType() const
1322 {
1323 return QInternal::Image;
1324 }
1325
1326 /*!
1327 Returns the image as a QVariant.
1328 */
operator QVariant() const1329 QImage::operator QVariant() const
1330 {
1331 return QVariant(QVariant::Image, this);
1332 }
1333
1334 /*!
1335 \internal
1336
1337 If multiple images share common data, this image makes a copy of
1338 the data and detaches itself from the sharing mechanism, making
1339 sure that this image is the only one referring to the data.
1340
1341 Nothing is done if there is just a single reference.
1342
1343 \sa copy(), isDetached(), {Implicit Data Sharing}
1344 */
detach()1345 void QImage::detach()
1346 {
1347 if (d) {
1348 if (d->is_cached && d->ref == 1)
1349 QImagePixmapCleanupHooks::executeImageHooks(cacheKey());
1350
1351 if (d->ref != 1 || d->ro_data)
1352 *this = copy();
1353
1354 if (d)
1355 ++d->detach_no;
1356 }
1357 }
1358
1359
1360 /*!
1361 \fn QImage QImage::copy(int x, int y, int width, int height) const
1362 \overload
1363
1364 The returned image is copied from the position (\a x, \a y) in
1365 this image, and will always have the given \a width and \a height.
1366 In areas beyond this image, pixels are set to 0.
1367
1368 */
1369
1370 /*!
1371 \fn QImage QImage::copy(const QRect& rectangle) const
1372
1373 Returns a sub-area of the image as a new image.
1374
1375 The returned image is copied from the position (\a
1376 {rectangle}.x(), \a{rectangle}.y()) in this image, and will always
1377 have the size of the given \a rectangle.
1378
1379 In areas beyond this image, pixels are set to 0. For 32-bit RGB
1380 images, this means black; for 32-bit ARGB images, this means
1381 transparent black; for 8-bit images, this means the color with
1382 index 0 in the color table which can be anything; for 1-bit
1383 images, this means Qt::color0.
1384
1385 If the given \a rectangle is a null rectangle the entire image is
1386 copied.
1387
1388 \sa QImage()
1389 */
copy(const QRect & r) const1390 QImage QImage::copy(const QRect& r) const
1391 {
1392 if (!d)
1393 return QImage();
1394
1395 if (r.isNull()) {
1396 QImage image(d->width, d->height, d->format);
1397 if (image.isNull())
1398 return image;
1399
1400 // Qt for Embedded Linux can create images with non-default bpl
1401 // make sure we don't crash.
1402 if (image.d->nbytes != d->nbytes) {
1403 int bpl = qMin(bytesPerLine(), image.bytesPerLine());
1404 for (int i = 0; i < height(); i++)
1405 memcpy(image.scanLine(i), scanLine(i), bpl);
1406 } else
1407 memcpy(image.bits(), bits(), d->nbytes);
1408 image.d->colortable = d->colortable;
1409 image.d->dpmx = d->dpmx;
1410 image.d->dpmy = d->dpmy;
1411 image.d->offset = d->offset;
1412 image.d->has_alpha_clut = d->has_alpha_clut;
1413 #ifndef QT_NO_IMAGE_TEXT
1414 image.d->text = d->text;
1415 #endif
1416 return image;
1417 }
1418
1419 int x = r.x();
1420 int y = r.y();
1421 int w = r.width();
1422 int h = r.height();
1423
1424 int dx = 0;
1425 int dy = 0;
1426 if (w <= 0 || h <= 0)
1427 return QImage();
1428
1429 QImage image(w, h, d->format);
1430 if (image.isNull())
1431 return image;
1432
1433 if (x < 0 || y < 0 || x + w > d->width || y + h > d->height) {
1434 // bitBlt will not cover entire image - clear it.
1435 image.fill(0);
1436 if (x < 0) {
1437 dx = -x;
1438 x = 0;
1439 }
1440 if (y < 0) {
1441 dy = -y;
1442 y = 0;
1443 }
1444 }
1445
1446 image.d->colortable = d->colortable;
1447
1448 int pixels_to_copy = qMax(w - dx, 0);
1449 if (x > d->width)
1450 pixels_to_copy = 0;
1451 else if (pixels_to_copy > d->width - x)
1452 pixels_to_copy = d->width - x;
1453 int lines_to_copy = qMax(h - dy, 0);
1454 if (y > d->height)
1455 lines_to_copy = 0;
1456 else if (lines_to_copy > d->height - y)
1457 lines_to_copy = d->height - y;
1458
1459 bool byteAligned = true;
1460 if (d->format == Format_Mono || d->format == Format_MonoLSB)
1461 byteAligned = !(dx & 7) && !(x & 7) && !(pixels_to_copy & 7);
1462
1463 if (byteAligned) {
1464 const uchar *src = d->data + ((x * d->depth) >> 3) + y * d->bytes_per_line;
1465 uchar *dest = image.d->data + ((dx * d->depth) >> 3) + dy * image.d->bytes_per_line;
1466 const int bytes_to_copy = (pixels_to_copy * d->depth) >> 3;
1467 for (int i = 0; i < lines_to_copy; ++i) {
1468 memcpy(dest, src, bytes_to_copy);
1469 src += d->bytes_per_line;
1470 dest += image.d->bytes_per_line;
1471 }
1472 } else if (d->format == Format_Mono) {
1473 const uchar *src = d->data + y * d->bytes_per_line;
1474 uchar *dest = image.d->data + dy * image.d->bytes_per_line;
1475 for (int i = 0; i < lines_to_copy; ++i) {
1476 for (int j = 0; j < pixels_to_copy; ++j) {
1477 if (src[(x + j) >> 3] & (0x80 >> ((x + j) & 7)))
1478 dest[(dx + j) >> 3] |= (0x80 >> ((dx + j) & 7));
1479 else
1480 dest[(dx + j) >> 3] &= ~(0x80 >> ((dx + j) & 7));
1481 }
1482 src += d->bytes_per_line;
1483 dest += image.d->bytes_per_line;
1484 }
1485 } else { // Format_MonoLSB
1486 Q_ASSERT(d->format == Format_MonoLSB);
1487 const uchar *src = d->data + y * d->bytes_per_line;
1488 uchar *dest = image.d->data + dy * image.d->bytes_per_line;
1489 for (int i = 0; i < lines_to_copy; ++i) {
1490 for (int j = 0; j < pixels_to_copy; ++j) {
1491 if (src[(x + j) >> 3] & (0x1 << ((x + j) & 7)))
1492 dest[(dx + j) >> 3] |= (0x1 << ((dx + j) & 7));
1493 else
1494 dest[(dx + j) >> 3] &= ~(0x1 << ((dx + j) & 7));
1495 }
1496 src += d->bytes_per_line;
1497 dest += image.d->bytes_per_line;
1498 }
1499 }
1500
1501 image.d->dpmx = dotsPerMeterX();
1502 image.d->dpmy = dotsPerMeterY();
1503 image.d->offset = offset();
1504 image.d->has_alpha_clut = d->has_alpha_clut;
1505 #ifndef QT_NO_IMAGE_TEXT
1506 image.d->text = d->text;
1507 #endif
1508 return image;
1509 }
1510
1511
1512 /*!
1513 \fn bool QImage::isNull() const
1514
1515 Returns true if it is a null image, otherwise returns false.
1516
1517 A null image has all parameters set to zero and no allocated data.
1518 */
isNull() const1519 bool QImage::isNull() const
1520 {
1521 return !d;
1522 }
1523
1524 /*!
1525 \fn int QImage::width() const
1526
1527 Returns the width of the image.
1528
1529 \sa {QImage#Image Information}{Image Information}
1530 */
width() const1531 int QImage::width() const
1532 {
1533 return d ? d->width : 0;
1534 }
1535
1536 /*!
1537 \fn int QImage::height() const
1538
1539 Returns the height of the image.
1540
1541 \sa {QImage#Image Information}{Image Information}
1542 */
height() const1543 int QImage::height() const
1544 {
1545 return d ? d->height : 0;
1546 }
1547
1548 /*!
1549 \fn QSize QImage::size() const
1550
1551 Returns the size of the image, i.e. its width() and height().
1552
1553 \sa {QImage#Image Information}{Image Information}
1554 */
size() const1555 QSize QImage::size() const
1556 {
1557 return d ? QSize(d->width, d->height) : QSize(0, 0);
1558 }
1559
1560 /*!
1561 \fn QRect QImage::rect() const
1562
1563 Returns the enclosing rectangle (0, 0, width(), height()) of the
1564 image.
1565
1566 \sa {QImage#Image Information}{Image Information}
1567 */
rect() const1568 QRect QImage::rect() const
1569 {
1570 return d ? QRect(0, 0, d->width, d->height) : QRect();
1571 }
1572
1573 /*!
1574 Returns the depth of the image.
1575
1576 The image depth is the number of bits used to store a single
1577 pixel, also called bits per pixel (bpp).
1578
1579 The supported depths are 1, 8, 16, 24 and 32.
1580
1581 \sa bitPlaneCount(), convertToFormat(), {QImage#Image Formats}{Image Formats},
1582 {QImage#Image Information}{Image Information}
1583
1584 */
depth() const1585 int QImage::depth() const
1586 {
1587 return d ? d->depth : 0;
1588 }
1589
1590 /*!
1591 \obsolete
1592 \fn int QImage::numColors() const
1593
1594 Returns the size of the color table for the image.
1595
1596 \sa setColorCount()
1597 */
numColors() const1598 int QImage::numColors() const
1599 {
1600 return d ? d->colortable.size() : 0;
1601 }
1602
1603 /*!
1604 \since 4.6
1605 \fn int QImage::colorCount() const
1606
1607 Returns the size of the color table for the image.
1608
1609 Notice that colorCount() returns 0 for 32-bpp images because these
1610 images do not use color tables, but instead encode pixel values as
1611 ARGB quadruplets.
1612
1613 \sa setColorCount(), {QImage#Image Information}{Image Information}
1614 */
colorCount() const1615 int QImage::colorCount() const
1616 {
1617 return d ? d->colortable.size() : 0;
1618 }
1619
1620
1621 #ifdef QT3_SUPPORT
1622 /*!
1623 \fn QImage::Endian QImage::bitOrder() const
1624
1625 Returns the bit order for the image. If it is a 1-bpp image, this
1626 function returns either QImage::BigEndian or
1627 QImage::LittleEndian. Otherwise, this function returns
1628 QImage::IgnoreEndian.
1629
1630 Use the format() function instead for the monochrome formats. For
1631 non-monochrome formats the bit order is irrelevant.
1632 */
1633
1634 /*!
1635 Returns a pointer to the scanline pointer table. This is the
1636 beginning of the data block for the image.
1637 Returns 0 in case of an error.
1638
1639 Use the bits() or scanLine() function instead.
1640 */
jumpTable()1641 uchar **QImage::jumpTable()
1642 {
1643 if (!d)
1644 return 0;
1645 detach();
1646
1647 // in case detach() ran out of memory..
1648 if (!d)
1649 return 0;
1650
1651 if (!d->jumptable) {
1652 d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
1653 if (!d->jumptable)
1654 return 0;
1655 uchar *data = d->data;
1656 int height = d->height;
1657 uchar **p = d->jumptable;
1658 while (height--) {
1659 *p++ = data;
1660 data += d->bytes_per_line;
1661 }
1662 }
1663 return d->jumptable;
1664 }
1665
1666 /*!
1667 \overload
1668 */
jumpTable() const1669 const uchar * const *QImage::jumpTable() const
1670 {
1671 if (!d)
1672 return 0;
1673 if (!d->jumptable) {
1674 d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
1675 if (!d->jumptable)
1676 return 0;
1677 uchar *data = d->data;
1678 int height = d->height;
1679 uchar **p = d->jumptable;
1680 while (height--) {
1681 *p++ = data;
1682 data += d->bytes_per_line;
1683 }
1684 }
1685 return d->jumptable;
1686 }
1687 #endif
1688
1689 /*!
1690 Sets the color table used to translate color indexes to QRgb
1691 values, to the specified \a colors.
1692
1693 When the image is used, the color table must be large enough to
1694 have entries for all the pixel/index values present in the image,
1695 otherwise the results are undefined.
1696
1697 \sa colorTable(), setColor(), {QImage#Image Transformations}{Image
1698 Transformations}
1699 */
setColorTable(const QVector<QRgb> colors)1700 void QImage::setColorTable(const QVector<QRgb> colors)
1701 {
1702 if (!d)
1703 return;
1704 detach();
1705
1706 // In case detach() ran out of memory
1707 if (!d)
1708 return;
1709
1710 d->colortable = colors;
1711 d->has_alpha_clut = false;
1712 for (int i = 0; i < d->colortable.size(); ++i) {
1713 if (qAlpha(d->colortable.at(i)) != 255) {
1714 d->has_alpha_clut = true;
1715 break;
1716 }
1717 }
1718 }
1719
1720 /*!
1721 Returns a list of the colors contained in the image's color table,
1722 or an empty list if the image does not have a color table
1723
1724 \sa setColorTable(), colorCount(), color()
1725 */
colorTable() const1726 QVector<QRgb> QImage::colorTable() const
1727 {
1728 return d ? d->colortable : QVector<QRgb>();
1729 }
1730
1731
1732 /*!
1733 \obsolete
1734 Returns the number of bytes occupied by the image data.
1735
1736 \sa byteCount()
1737 */
numBytes() const1738 int QImage::numBytes() const
1739 {
1740 return d ? d->nbytes : 0;
1741 }
1742
1743 /*!
1744 \since 4.6
1745 Returns the number of bytes occupied by the image data.
1746
1747 \sa bytesPerLine(), bits(), {QImage#Image Information}{Image
1748 Information}
1749 */
byteCount() const1750 int QImage::byteCount() const
1751 {
1752 return d ? d->nbytes : 0;
1753 }
1754
1755 /*!
1756 Returns the number of bytes per image scanline.
1757
1758 This is equivalent to byteCount() / height().
1759
1760 \sa scanLine()
1761 */
bytesPerLine() const1762 int QImage::bytesPerLine() const
1763 {
1764 return (d && d->height) ? d->nbytes / d->height : 0;
1765 }
1766
1767
1768 /*!
1769 Returns the color in the color table at index \a i. The first
1770 color is at index 0.
1771
1772 The colors in an image's color table are specified as ARGB
1773 quadruplets (QRgb). Use the qAlpha(), qRed(), qGreen(), and
1774 qBlue() functions to get the color value components.
1775
1776 \sa setColor(), pixelIndex(), {QImage#Pixel Manipulation}{Pixel
1777 Manipulation}
1778 */
color(int i) const1779 QRgb QImage::color(int i) const
1780 {
1781 Q_ASSERT(i < colorCount());
1782 return d ? d->colortable.at(i) : QRgb(uint(-1));
1783 }
1784
1785 /*!
1786 \fn void QImage::setColor(int index, QRgb colorValue)
1787
1788 Sets the color at the given \a index in the color table, to the
1789 given to \a colorValue. The color value is an ARGB quadruplet.
1790
1791 If \a index is outside the current size of the color table, it is
1792 expanded with setColorCount().
1793
1794 \sa color(), colorCount(), setColorTable(), {QImage#Pixel Manipulation}{Pixel
1795 Manipulation}
1796 */
setColor(int i,QRgb c)1797 void QImage::setColor(int i, QRgb c)
1798 {
1799 if (!d)
1800 return;
1801 if (i < 0 || d->depth > 8 || i >= 1<<d->depth) {
1802 qWarning("QImage::setColor: Index out of bound %d", i);
1803 return;
1804 }
1805 detach();
1806
1807 // In case detach() run out of memory
1808 if (!d)
1809 return;
1810
1811 if (i >= d->colortable.size())
1812 setColorCount(i+1);
1813 d->colortable[i] = c;
1814 d->has_alpha_clut |= (qAlpha(c) != 255);
1815 }
1816
1817 /*!
1818 Returns a pointer to the pixel data at the scanline with index \a
1819 i. The first scanline is at index 0.
1820
1821 The scanline data is aligned on a 32-bit boundary.
1822
1823 \warning If you are accessing 32-bpp image data, cast the returned
1824 pointer to \c{QRgb*} (QRgb has a 32-bit size) and use it to
1825 read/write the pixel value. You cannot use the \c{uchar*} pointer
1826 directly, because the pixel format depends on the byte order on
1827 the underlying platform. Use qRed(), qGreen(), qBlue(), and
1828 qAlpha() to access the pixels.
1829
1830 \sa bytesPerLine(), bits(), {QImage#Pixel Manipulation}{Pixel
1831 Manipulation}, constScanLine()
1832 */
scanLine(int i)1833 uchar *QImage::scanLine(int i)
1834 {
1835 if (!d)
1836 return 0;
1837
1838 detach();
1839
1840 // In case detach() ran out of memory
1841 if (!d)
1842 return 0;
1843
1844 return d->data + i * d->bytes_per_line;
1845 }
1846
1847 /*!
1848 \overload
1849 */
scanLine(int i) const1850 const uchar *QImage::scanLine(int i) const
1851 {
1852 if (!d)
1853 return 0;
1854
1855 Q_ASSERT(i >= 0 && i < height());
1856 return d->data + i * d->bytes_per_line;
1857 }
1858
1859
1860 /*!
1861 Returns a pointer to the pixel data at the scanline with index \a
1862 i. The first scanline is at index 0.
1863
1864 The scanline data is aligned on a 32-bit boundary.
1865
1866 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1867 sharing}, but this function does \e not perform a deep copy of the
1868 shared pixel data, because the returned data is const.
1869
1870 \sa scanLine(), constBits()
1871 \since 4.7
1872 */
constScanLine(int i) const1873 const uchar *QImage::constScanLine(int i) const
1874 {
1875 if (!d)
1876 return 0;
1877
1878 Q_ASSERT(i >= 0 && i < height());
1879 return d->data + i * d->bytes_per_line;
1880 }
1881
1882 /*!
1883 Returns a pointer to the first pixel data. This is equivalent to
1884 scanLine(0).
1885
1886 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1887 sharing}. This function performs a deep copy of the shared pixel
1888 data, thus ensuring that this QImage is the only one using the
1889 current return value.
1890
1891 \sa scanLine(), byteCount(), constBits()
1892 */
bits()1893 uchar *QImage::bits()
1894 {
1895 if (!d)
1896 return 0;
1897 detach();
1898
1899 // In case detach ran out of memory...
1900 if (!d)
1901 return 0;
1902
1903 return d->data;
1904 }
1905
1906 /*!
1907 \overload
1908
1909 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1910 sharing}, but this function does \e not perform a deep copy of the
1911 shared pixel data, because the returned data is const.
1912 */
bits() const1913 const uchar *QImage::bits() const
1914 {
1915 return d ? d->data : 0;
1916 }
1917
1918
1919 /*!
1920 Returns a pointer to the first pixel data.
1921
1922 Note that QImage uses \l{Implicit Data Sharing} {implicit data
1923 sharing}, but this function does \e not perform a deep copy of the
1924 shared pixel data, because the returned data is const.
1925
1926 \sa bits(), constScanLine()
1927 \since 4.7
1928 */
constBits() const1929 const uchar *QImage::constBits() const
1930 {
1931 return d ? d->data : 0;
1932 }
1933
1934 /*!
1935 \fn void QImage::reset()
1936
1937 Resets all image parameters and deallocates the image data.
1938
1939 Assign a null image instead.
1940
1941 \oldcode
1942 QImage image;
1943 image.reset();
1944 \newcode
1945 QImage image;
1946 image = QImage();
1947 \endcode
1948 */
1949
1950 /*!
1951 \fn void QImage::fill(uint pixelValue)
1952
1953 Fills the entire image with the given \a pixelValue.
1954
1955 If the depth of this image is 1, only the lowest bit is used. If
1956 you say fill(0), fill(2), etc., the image is filled with 0s. If
1957 you say fill(1), fill(3), etc., the image is filled with 1s. If
1958 the depth is 8, the lowest 8 bits are used and if the depth is 16
1959 the lowest 16 bits are used.
1960
1961 Note: QImage::pixel() returns the color of the pixel at the given
1962 coordinates while QColor::pixel() returns the pixel value of the
1963 underlying window system (essentially an index value), so normally
1964 you will want to use QImage::pixel() to use a color from an
1965 existing image or QColor::rgb() to use a specific color.
1966
1967 \sa depth(), {QImage#Image Transformations}{Image Transformations}
1968 */
1969
fill(uint pixel)1970 void QImage::fill(uint pixel)
1971 {
1972 if (!d)
1973 return;
1974
1975 detach();
1976
1977 // In case detach() ran out of memory
1978 if (!d)
1979 return;
1980
1981 if (d->depth == 1 || d->depth == 8) {
1982 int w = d->width;
1983 if (d->depth == 1) {
1984 if (pixel & 1)
1985 pixel = 0xffffffff;
1986 else
1987 pixel = 0;
1988 w = (w + 7) / 8;
1989 } else {
1990 pixel &= 0xff;
1991 }
1992 qt_rectfill<quint8>(d->data, pixel, 0, 0,
1993 w, d->height, d->bytes_per_line);
1994 return;
1995 } else if (d->depth == 16) {
1996 qt_rectfill<quint16>(reinterpret_cast<quint16*>(d->data), pixel,
1997 0, 0, d->width, d->height, d->bytes_per_line);
1998 return;
1999 } else if (d->depth == 24) {
2000 qt_rectfill<quint24>(reinterpret_cast<quint24*>(d->data), pixel,
2001 0, 0, d->width, d->height, d->bytes_per_line);
2002 return;
2003 }
2004
2005 if (d->format == Format_RGB32)
2006 pixel |= 0xff000000;
2007
2008 qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
2009 0, 0, d->width, d->height, d->bytes_per_line);
2010 }
2011
2012
2013 /*!
2014 \fn void QImage::fill(Qt::GlobalColor color)
2015 \overload
2016 \since 4.8
2017
2018 Fills the image with the given \a color, described as a standard global
2019 color.
2020 */
2021
fill(Qt::GlobalColor color)2022 void QImage::fill(Qt::GlobalColor color)
2023 {
2024 fill(QColor(color));
2025 }
2026
2027
2028
2029 /*!
2030 \fn void QImage::fill(const QColor &color)
2031
2032 \overload
2033
2034 Fills the entire image with the given \a color.
2035
2036 If the depth of the image is 1, the image will be filled with 1 if
2037 \a color equals Qt::color1; it will otherwise be filled with 0.
2038
2039 If the depth of the image is 8, the image will be filled with the
2040 index corresponding the \a color in the color table if present; it
2041 will otherwise be filled with 0.
2042
2043 \since 4.8
2044 */
2045
fill(const QColor & color)2046 void QImage::fill(const QColor &color)
2047 {
2048 if (!d)
2049 return;
2050 detach();
2051
2052 // In case we run out of memory
2053 if (!d)
2054 return;
2055
2056 if (d->depth == 32) {
2057 uint pixel = color.rgba();
2058 if (d->format == QImage::Format_ARGB32_Premultiplied)
2059 pixel = PREMUL(pixel);
2060 fill((uint) pixel);
2061
2062 } else if (d->depth == 16 && d->format == QImage::Format_RGB16) {
2063 qrgb565 p(color.rgba());
2064 fill((uint) p.rawValue());
2065
2066 } else if (d->depth == 1) {
2067 if (color == Qt::color1)
2068 fill((uint) 1);
2069 else
2070 fill((uint) 0);
2071
2072 } else if (d->depth == 8) {
2073 uint pixel = 0;
2074 for (int i=0; i<d->colortable.size(); ++i) {
2075 if (color.rgba() == d->colortable.at(i)) {
2076 pixel = i;
2077 break;
2078 }
2079 }
2080 fill(pixel);
2081
2082 } else {
2083 QPainter p(this);
2084 p.setCompositionMode(QPainter::CompositionMode_Source);
2085 p.fillRect(rect(), color);
2086 }
2087
2088 }
2089
2090
2091
2092
2093
2094
2095 /*!
2096 Inverts all pixel values in the image.
2097
2098 The given invert \a mode only have a meaning when the image's
2099 depth is 32. The default \a mode is InvertRgb, which leaves the
2100 alpha channel unchanged. If the \a mode is InvertRgba, the alpha
2101 bits are also inverted.
2102
2103 Inverting an 8-bit image means to replace all pixels using color
2104 index \e i with a pixel using color index 255 minus \e i. The same
2105 is the case for a 1-bit image. Note that the color table is \e not
2106 changed.
2107
2108 \sa {QImage#Image Transformations}{Image Transformations}
2109 */
2110
invertPixels(InvertMode mode)2111 void QImage::invertPixels(InvertMode mode)
2112 {
2113 if (!d)
2114 return;
2115
2116 detach();
2117
2118 // In case detach() ran out of memory
2119 if (!d)
2120 return;
2121
2122 if (depth() != 32) {
2123 // number of used bytes pr line
2124 int bpl = (d->width * d->depth + 7) / 8;
2125 int pad = d->bytes_per_line - bpl;
2126 uchar *sl = d->data;
2127 for (int y=0; y<d->height; ++y) {
2128 for (int x=0; x<bpl; ++x)
2129 *sl++ ^= 0xff;
2130 sl += pad;
2131 }
2132 } else {
2133 quint32 *p = (quint32*)d->data;
2134 quint32 *end = (quint32*)(d->data + d->nbytes);
2135 uint xorbits = (mode == InvertRgba) ? 0xffffffff : 0x00ffffff;
2136 while (p < end)
2137 *p++ ^= xorbits;
2138 }
2139 }
2140
2141 /*!
2142 \fn void QImage::invertPixels(bool invertAlpha)
2143
2144 Use the invertPixels() function that takes a QImage::InvertMode
2145 parameter instead.
2146 */
2147
2148 /*! \fn QImage::Endian QImage::systemByteOrder()
2149
2150 Determines the host computer byte order. Returns
2151 QImage::LittleEndian (LSB first) or QImage::BigEndian (MSB first).
2152
2153 This function is no longer relevant for QImage. Use QSysInfo
2154 instead.
2155 */
2156
2157 // Windows defines these
2158 #if defined(write)
2159 # undef write
2160 #endif
2161 #if defined(close)
2162 # undef close
2163 #endif
2164 #if defined(read)
2165 # undef read
2166 #endif
2167
2168 /*!
2169 \obsolete
2170 Resizes the color table to contain \a numColors entries.
2171
2172 \sa setColorCount()
2173 */
2174
setNumColors(int numColors)2175 void QImage::setNumColors(int numColors)
2176 {
2177 setColorCount(numColors);
2178 }
2179
2180 /*!
2181 \since 4.6
2182 Resizes the color table to contain \a colorCount entries.
2183
2184 If the color table is expanded, all the extra colors will be set to
2185 transparent (i.e qRgba(0, 0, 0, 0)).
2186
2187 When the image is used, the color table must be large enough to
2188 have entries for all the pixel/index values present in the image,
2189 otherwise the results are undefined.
2190
2191 \sa colorCount(), colorTable(), setColor(), {QImage#Image
2192 Transformations}{Image Transformations}
2193 */
2194
setColorCount(int colorCount)2195 void QImage::setColorCount(int colorCount)
2196 {
2197 if (!d) {
2198 qWarning("QImage::setColorCount: null image");
2199 return;
2200 }
2201
2202 detach();
2203
2204 // In case detach() ran out of memory
2205 if (!d)
2206 return;
2207
2208 if (colorCount == d->colortable.size())
2209 return;
2210 if (colorCount <= 0) { // use no color table
2211 d->colortable = QVector<QRgb>();
2212 return;
2213 }
2214 int nc = d->colortable.size();
2215 d->colortable.resize(colorCount);
2216 for (int i = nc; i < colorCount; ++i)
2217 d->colortable[i] = 0;
2218 }
2219
2220 /*!
2221 Returns the format of the image.
2222
2223 \sa {QImage#Image Formats}{Image Formats}
2224 */
format() const2225 QImage::Format QImage::format() const
2226 {
2227 return d ? d->format : Format_Invalid;
2228 }
2229
2230
2231 #ifdef QT3_SUPPORT
2232 /*!
2233 Returns true if alpha buffer mode is enabled; otherwise returns
2234 false.
2235
2236 Use the hasAlphaChannel() function instead.
2237
2238 */
hasAlphaBuffer() const2239 bool QImage::hasAlphaBuffer() const
2240 {
2241 if (!d)
2242 return false;
2243
2244 switch (d->format) {
2245 case Format_ARGB32:
2246 case Format_ARGB32_Premultiplied:
2247 case Format_ARGB8565_Premultiplied:
2248 case Format_ARGB8555_Premultiplied:
2249 case Format_ARGB6666_Premultiplied:
2250 case Format_ARGB4444_Premultiplied:
2251 return true;
2252 default:
2253 return false;
2254 }
2255 }
2256
2257 /*!
2258 Enables alpha buffer mode if \a enable is true, otherwise disables
2259 it. The alpha buffer is used to set a mask when a QImage is
2260 translated to a QPixmap.
2261
2262 If a monochrome or indexed 8-bit image has alpha channels in their
2263 color tables they will automatically detect that they have an
2264 alpha channel, so this function is not required. To force alpha
2265 channels on 32-bit images, use the convertToFormat() function.
2266 */
2267
setAlphaBuffer(bool enable)2268 void QImage::setAlphaBuffer(bool enable)
2269 {
2270 if (!d
2271 || d->format == Format_Mono
2272 || d->format == Format_MonoLSB
2273 || d->format == Format_Indexed8)
2274 return;
2275 if (enable && (d->format == Format_ARGB32 ||
2276 d->format == Format_ARGB32_Premultiplied ||
2277 d->format == Format_ARGB8565_Premultiplied ||
2278 d->format == Format_ARGB6666_Premultiplied ||
2279 d->format == Format_ARGB8555_Premultiplied ||
2280 d->format == Format_ARGB4444_Premultiplied))
2281 {
2282 return;
2283 }
2284 if (!enable && (d->format == Format_RGB32 ||
2285 d->format == Format_RGB555 ||
2286 d->format == Format_RGB666 ||
2287 d->format == Format_RGB888 ||
2288 d->format == Format_RGB444))
2289 {
2290 return;
2291 }
2292 detach();
2293 d->format = (enable ? Format_ARGB32 : Format_RGB32);
2294 }
2295
2296
2297 /*!
2298 \fn bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
2299
2300 Sets the image \a width, \a height, \a depth, its number of colors
2301 (in \a numColors), and bit order. Returns true if successful, or
2302 false if the parameters are incorrect or if memory cannot be
2303 allocated.
2304
2305 The \a width and \a height is limited to 32767. \a depth must be
2306 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to
2307 either QImage::LittleEndian or QImage::BigEndian. For other depths
2308 \a bitOrder must be QImage::IgnoreEndian.
2309
2310 This function allocates a color table and a buffer for the image
2311 data. The image data is not initialized. The image buffer is
2312 allocated as a single block that consists of a table of scanLine()
2313 pointers (jumpTable()) and the image data (bits()).
2314
2315 Use a QImage constructor instead.
2316 */
create(int width,int height,int depth,int numColors,Endian bitOrder)2317 bool QImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
2318 {
2319 if (d && !d->ref.deref())
2320 delete d;
2321 d = QImageData::create(QSize(width, height), formatFor(depth, bitOrder), numColors);
2322 return true;
2323 }
2324
2325 /*!
2326 \fn bool QImage::create(const QSize& size, int depth, int numColors, Endian bitOrder)
2327 \overload
2328
2329 The width and height are specified in the \a size argument.
2330
2331 Use a QImage constructor instead.
2332 */
create(const QSize & size,int depth,int numColors,QImage::Endian bitOrder)2333 bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian bitOrder)
2334 {
2335 if (d && !d->ref.deref())
2336 delete d;
2337 d = QImageData::create(size, formatFor(depth, bitOrder), numColors);
2338 return true;
2339 }
2340 #endif // QT3_SUPPORT
2341
2342 /*****************************************************************************
2343 Internal routines for converting image depth.
2344 *****************************************************************************/
2345
2346 typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
2347
2348 typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
2349
convert_ARGB_to_ARGB_PM(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)2350 static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
2351 {
2352 Q_ASSERT(src->format == QImage::Format_ARGB32);
2353 Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied);
2354 Q_ASSERT(src->width == dest->width);
2355 Q_ASSERT(src->height == dest->height);
2356
2357 const int src_pad = (src->bytes_per_line >> 2) - src->width;
2358 const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
2359 const QRgb *src_data = (QRgb *) src->data;
2360 QRgb *dest_data = (QRgb *) dest->data;
2361
2362 for (int i = 0; i < src->height; ++i) {
2363 const QRgb *end = src_data + src->width;
2364 while (src_data < end) {
2365 *dest_data = PREMUL(*src_data);
2366 ++src_data;
2367 ++dest_data;
2368 }
2369 src_data += src_pad;
2370 dest_data += dest_pad;
2371 }
2372 }
2373
convert_ARGB_to_ARGB_PM_inplace(QImageData * data,Qt::ImageConversionFlags)2374 static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
2375 {
2376 Q_ASSERT(data->format == QImage::Format_ARGB32);
2377
2378 const int pad = (data->bytes_per_line >> 2) - data->width;
2379 QRgb *rgb_data = (QRgb *) data->data;
2380
2381 for (int i = 0; i < data->height; ++i) {
2382 const QRgb *end = rgb_data + data->width;
2383 while (rgb_data < end) {
2384 *rgb_data = PREMUL(*rgb_data);
2385 ++rgb_data;
2386 }
2387 rgb_data += pad;
2388 }
2389 data->format = QImage::Format_ARGB32_Premultiplied;
2390 return true;
2391 }
2392
convert_indexed8_to_ARGB_PM_inplace(QImageData * data,Qt::ImageConversionFlags)2393 static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
2394 {
2395 Q_ASSERT(data->format == QImage::Format_Indexed8);
2396 const int depth = 32;
2397
2398 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
2399 const int nbytes = dst_bytes_per_line * data->height;
2400 uchar *const newData = (uchar *)realloc(data->data, nbytes);
2401 if (!newData)
2402 return false;
2403
2404 data->data = newData;
2405
2406 // start converting from the end because the end image is bigger than the source
2407 uchar *src_data = newData + data->nbytes; // end of src
2408 quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
2409 const int width = data->width;
2410 const int src_pad = data->bytes_per_line - width;
2411 const int dest_pad = (dst_bytes_per_line >> 2) - width;
2412 if (data->colortable.size() == 0) {
2413 data->colortable.resize(256);
2414 for (int i = 0; i < 256; ++i)
2415 data->colortable[i] = qRgb(i, i, i);
2416 } else {
2417 for (int i = 0; i < data->colortable.size(); ++i)
2418 data->colortable[i] = PREMUL(data->colortable.at(i));
2419
2420 // Fill the rest of the table in case src_data > colortable.size()
2421 const int oldSize = data->colortable.size();
2422 const QRgb lastColor = data->colortable.at(oldSize - 1);
2423 data->colortable.insert(oldSize, 256 - oldSize, lastColor);
2424 }
2425
2426 for (int i = 0; i < data->height; ++i) {
2427 src_data -= src_pad;
2428 dest_data -= dest_pad;
2429 for (int pixI = 0; pixI < width; ++pixI) {
2430 --src_data;
2431 --dest_data;
2432 *dest_data = data->colortable.at(*src_data);
2433 }
2434 }
2435
2436 data->colortable = QVector<QRgb>();
2437 data->format = QImage::Format_ARGB32_Premultiplied;
2438 data->bytes_per_line = dst_bytes_per_line;
2439 data->depth = depth;
2440 data->nbytes = nbytes;
2441
2442 return true;
2443 }
2444
convert_indexed8_to_RGB_inplace(QImageData * data,Qt::ImageConversionFlags)2445 static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
2446 {
2447 Q_ASSERT(data->format == QImage::Format_Indexed8);
2448 const int depth = 32;
2449
2450 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
2451 const int nbytes = dst_bytes_per_line * data->height;
2452 uchar *const newData = (uchar *)realloc(data->data, nbytes);
2453 if (!newData)
2454 return false;
2455
2456 data->data = newData;
2457
2458 // start converting from the end because the end image is bigger than the source
2459 uchar *src_data = newData + data->nbytes;
2460 quint32 *dest_data = (quint32 *) (newData + nbytes);
2461 const int width = data->width;
2462 const int src_pad = data->bytes_per_line - width;
2463 const int dest_pad = (dst_bytes_per_line >> 2) - width;
2464 if (data->colortable.size() == 0) {
2465 data->colortable.resize(256);
2466 for (int i = 0; i < 256; ++i)
2467 data->colortable[i] = qRgb(i, i, i);
2468 } else {
2469 // Fill the rest of the table in case src_data > colortable.size()
2470 const int oldSize = data->colortable.size();
2471 const QRgb lastColor = data->colortable.at(oldSize - 1);
2472 data->colortable.insert(oldSize, 256 - oldSize, lastColor);
2473 }
2474
2475 for (int i = 0; i < data->height; ++i) {
2476 src_data -= src_pad;
2477 dest_data -= dest_pad;
2478 for (int pixI = 0; pixI < width; ++pixI) {
2479 --src_data;
2480 --dest_data;
2481 *dest_data = (quint32) data->colortable.at(*src_data);
2482 }
2483 }
2484
2485 data->colortable = QVector<QRgb>();
2486 data->format = QImage::Format_RGB32;
2487 data->bytes_per_line = dst_bytes_per_line;
2488 data->depth = depth;
2489 data->nbytes = nbytes;
2490
2491 return true;
2492 }
2493
convert_indexed8_to_RGB16_inplace(QImageData * data,Qt::ImageConversionFlags)2494 static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
2495 {
2496 Q_ASSERT(data->format == QImage::Format_Indexed8);
2497 const int depth = 16;
2498
2499 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
2500 const int nbytes = dst_bytes_per_line * data->height;
2501 uchar *const newData = (uchar *)realloc(data->data, nbytes);
2502 if (!newData)
2503 return false;
2504
2505 data->data = newData;
2506
2507 // start converting from the end because the end image is bigger than the source
2508 uchar *src_data = newData + data->nbytes;
2509 quint16 *dest_data = (quint16 *) (newData + nbytes);
2510 const int width = data->width;
2511 const int src_pad = data->bytes_per_line - width;
2512 const int dest_pad = (dst_bytes_per_line >> 1) - width;
2513
2514 quint16 colorTableRGB16[256];
2515 if (data->colortable.isEmpty()) {
2516 for (int i = 0; i < 256; ++i)
2517 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(qRgb(i, i, i), 0);
2518 } else {
2519 // 1) convert the existing colors to RGB16
2520 const int tableSize = data->colortable.size();
2521 for (int i = 0; i < tableSize; ++i)
2522 colorTableRGB16[i] = qt_colorConvert<quint16, quint32>(data->colortable.at(i), 0);
2523 data->colortable = QVector<QRgb>();
2524
2525 // 2) fill the rest of the table in case src_data > colortable.size()
2526 const quint16 lastColor = colorTableRGB16[tableSize - 1];
2527 for (int i = tableSize; i < 256; ++i)
2528 colorTableRGB16[i] = lastColor;
2529 }
2530
2531 for (int i = 0; i < data->height; ++i) {
2532 src_data -= src_pad;
2533 dest_data -= dest_pad;
2534 for (int pixI = 0; pixI < width; ++pixI) {
2535 --src_data;
2536 --dest_data;
2537 *dest_data = colorTableRGB16[*src_data];
2538 }
2539 }
2540
2541 data->format = QImage::Format_RGB16;
2542 data->bytes_per_line = dst_bytes_per_line;
2543 data->depth = depth;
2544 data->nbytes = nbytes;
2545
2546 return true;
2547 }
2548
convert_RGB_to_RGB16_inplace(QImageData * data,Qt::ImageConversionFlags)2549 static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
2550 {
2551 Q_ASSERT(data->format == QImage::Format_RGB32);
2552 const int depth = 16;
2553
2554 const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
2555 const int src_bytes_per_line = data->bytes_per_line;
2556 quint32 *src_data = (quint32 *) data->data;
2557 quint16 *dst_data = (quint16 *) data->data;
2558
2559 for (int i = 0; i < data->height; ++i) {
2560 qt_memconvert(dst_data, src_data, data->width);
2561 src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
2562 dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
2563 }
2564 data->format = QImage::Format_RGB16;
2565 data->bytes_per_line = dst_bytes_per_line;
2566 data->depth = depth;
2567 data->nbytes = dst_bytes_per_line * data->height;
2568 uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
2569 if (newData) {
2570 data->data = newData;
2571 return true;
2572 } else {
2573 return false;
2574 }
2575 }
2576
convert_ARGB_PM_to_ARGB(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)2577 static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
2578 {
2579 Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
2580 Q_ASSERT(dest->format == QImage::Format_ARGB32);
2581 Q_ASSERT(src->width == dest->width);
2582 Q_ASSERT(src->height == dest->height);
2583
2584 const int src_pad = (src->bytes_per_line >> 2) - src->width;
2585 const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
2586 const QRgb *src_data = (QRgb *) src->data;
2587 QRgb *dest_data = (QRgb *) dest->data;
2588
2589 for (int i = 0; i < src->height; ++i) {
2590 const QRgb *end = src_data + src->width;
2591 while (src_data < end) {
2592 *dest_data = INV_PREMUL(*src_data);
2593 ++src_data;
2594 ++dest_data;
2595 }
2596 src_data += src_pad;
2597 dest_data += dest_pad;
2598 }
2599 }
2600
convert_ARGB_PM_to_RGB(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)2601 static void convert_ARGB_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
2602 {
2603 Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
2604 Q_ASSERT(dest->format == QImage::Format_RGB32);
2605 Q_ASSERT(src->width == dest->width);
2606 Q_ASSERT(src->height == dest->height);
2607
2608 const int src_pad = (src->bytes_per_line >> 2) - src->width;
2609 const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
2610 const QRgb *src_data = (QRgb *) src->data;
2611 QRgb *dest_data = (QRgb *) dest->data;
2612
2613 for (int i = 0; i < src->height; ++i) {
2614 const QRgb *end = src_data + src->width;
2615 while (src_data < end) {
2616 *dest_data = 0xff000000 | INV_PREMUL(*src_data);
2617 ++src_data;
2618 ++dest_data;
2619 }
2620 src_data += src_pad;
2621 dest_data += dest_pad;
2622 }
2623 }
2624
swap_bit_order(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)2625 static void swap_bit_order(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
2626 {
2627 Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
2628 Q_ASSERT(dest->format == QImage::Format_Mono || dest->format == QImage::Format_MonoLSB);
2629 Q_ASSERT(src->width == dest->width);
2630 Q_ASSERT(src->height == dest->height);
2631 Q_ASSERT(src->nbytes == dest->nbytes);
2632 Q_ASSERT(src->bytes_per_line == dest->bytes_per_line);
2633
2634 dest->colortable = src->colortable;
2635
2636 const uchar *src_data = src->data;
2637 const uchar *end = src->data + src->nbytes;
2638 uchar *dest_data = dest->data;
2639 while (src_data < end) {
2640 *dest_data = bitflip[*src_data];
2641 ++src_data;
2642 ++dest_data;
2643 }
2644 }
2645
mask_alpha_converter(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)2646 static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
2647 {
2648 Q_ASSERT(src->width == dest->width);
2649 Q_ASSERT(src->height == dest->height);
2650
2651 const int src_pad = (src->bytes_per_line >> 2) - src->width;
2652 const int dest_pad = (dest->bytes_per_line >> 2) - dest->width;
2653 const uint *src_data = (const uint *)src->data;
2654 uint *dest_data = (uint *)dest->data;
2655
2656 for (int i = 0; i < src->height; ++i) {
2657 const uint *end = src_data + src->width;
2658 while (src_data < end) {
2659 *dest_data = *src_data | 0xff000000;
2660 ++src_data;
2661 ++dest_data;
2662 }
2663 src_data += src_pad;
2664 dest_data += dest_pad;
2665 }
2666 }
2667
fix_color_table(const QVector<QRgb> & ctbl,QImage::Format format)2668 static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
2669 {
2670 QVector<QRgb> colorTable = ctbl;
2671 if (format == QImage::Format_RGB32) {
2672 // check if the color table has alpha
2673 for (int i = 0; i < colorTable.size(); ++i)
2674 if (qAlpha(colorTable.at(i) != 0xff))
2675 colorTable[i] = colorTable.at(i) | 0xff000000;
2676 } else if (format == QImage::Format_ARGB32_Premultiplied) {
2677 // check if the color table has alpha
2678 for (int i = 0; i < colorTable.size(); ++i)
2679 colorTable[i] = PREMUL(colorTable.at(i));
2680 }
2681 return colorTable;
2682 }
2683
2684 //
2685 // dither_to_1: Uses selected dithering algorithm.
2686 //
2687
dither_to_Mono(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags,bool fromalpha)2688 static void dither_to_Mono(QImageData *dst, const QImageData *src,
2689 Qt::ImageConversionFlags flags, bool fromalpha)
2690 {
2691 Q_ASSERT(src->width == dst->width);
2692 Q_ASSERT(src->height == dst->height);
2693 Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
2694
2695 dst->colortable.clear();
2696 dst->colortable.append(0xffffffff);
2697 dst->colortable.append(0xff000000);
2698
2699 enum { Threshold, Ordered, Diffuse } dithermode;
2700
2701 if (fromalpha) {
2702 if ((flags & Qt::AlphaDither_Mask) == Qt::DiffuseAlphaDither)
2703 dithermode = Diffuse;
2704 else if ((flags & Qt::AlphaDither_Mask) == Qt::OrderedAlphaDither)
2705 dithermode = Ordered;
2706 else
2707 dithermode = Threshold;
2708 } else {
2709 if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither)
2710 dithermode = Threshold;
2711 else if ((flags & Qt::Dither_Mask) == Qt::OrderedDither)
2712 dithermode = Ordered;
2713 else
2714 dithermode = Diffuse;
2715 }
2716
2717 int w = src->width;
2718 int h = src->height;
2719 int d = src->depth;
2720 uchar gray[256]; // gray map for 8 bit images
2721 bool use_gray = (d == 8);
2722 if (use_gray) { // make gray map
2723 if (fromalpha) {
2724 // Alpha 0x00 -> 0 pixels (white)
2725 // Alpha 0xFF -> 1 pixels (black)
2726 for (int i = 0; i < src->colortable.size(); i++)
2727 gray[i] = (255 - (src->colortable.at(i) >> 24));
2728 } else {
2729 // Pixel 0x00 -> 1 pixels (black)
2730 // Pixel 0xFF -> 0 pixels (white)
2731 for (int i = 0; i < src->colortable.size(); i++)
2732 gray[i] = qGray(src->colortable.at(i));
2733 }
2734 }
2735
2736 uchar *dst_data = dst->data;
2737 int dst_bpl = dst->bytes_per_line;
2738 const uchar *src_data = src->data;
2739 int src_bpl = src->bytes_per_line;
2740
2741 switch (dithermode) {
2742 case Diffuse: {
2743 QScopedArrayPointer<int> lineBuffer(new int[w * 2]);
2744 int *line1 = lineBuffer.data();
2745 int *line2 = lineBuffer.data() + w;
2746 int bmwidth = (w+7)/8;
2747
2748 int *b1, *b2;
2749 int wbytes = w * (d/8);
2750 const uchar *p = src->data;
2751 const uchar *end = p + wbytes;
2752 b2 = line2;
2753 if (use_gray) { // 8 bit image
2754 while (p < end)
2755 *b2++ = gray[*p++];
2756 } else { // 32 bit image
2757 if (fromalpha) {
2758 while (p < end) {
2759 *b2++ = 255 - (*(uint*)p >> 24);
2760 p += 4;
2761 }
2762 } else {
2763 while (p < end) {
2764 *b2++ = qGray(*(uint*)p);
2765 p += 4;
2766 }
2767 }
2768 }
2769 for (int y=0; y<h; y++) { // for each scan line...
2770 int *tmp = line1; line1 = line2; line2 = tmp;
2771 bool not_last_line = y < h - 1;
2772 if (not_last_line) { // calc. grayvals for next line
2773 p = src->data + (y+1)*src->bytes_per_line;
2774 end = p + wbytes;
2775 b2 = line2;
2776 if (use_gray) { // 8 bit image
2777 while (p < end)
2778 *b2++ = gray[*p++];
2779 } else { // 24 bit image
2780 if (fromalpha) {
2781 while (p < end) {
2782 *b2++ = 255 - (*(uint*)p >> 24);
2783 p += 4;
2784 }
2785 } else {
2786 while (p < end) {
2787 *b2++ = qGray(*(uint*)p);
2788 p += 4;
2789 }
2790 }
2791 }
2792 }
2793
2794 int err;
2795 uchar *p = dst->data + y*dst->bytes_per_line;
2796 memset(p, 0, bmwidth);
2797 b1 = line1;
2798 b2 = line2;
2799 int bit = 7;
2800 for (int x=1; x<=w; x++) {
2801 if (*b1 < 128) { // black pixel
2802 err = *b1++;
2803 *p |= 1 << bit;
2804 } else { // white pixel
2805 err = *b1++ - 255;
2806 }
2807 if (bit == 0) {
2808 p++;
2809 bit = 7;
2810 } else {
2811 bit--;
2812 }
2813 if (x < w)
2814 *b1 += (err*7)>>4; // spread error to right pixel
2815 if (not_last_line) {
2816 b2[0] += (err*5)>>4; // pixel below
2817 if (x > 1)
2818 b2[-1] += (err*3)>>4; // pixel below left
2819 if (x < w)
2820 b2[1] += err>>4; // pixel below right
2821 }
2822 b2++;
2823 }
2824 }
2825 } break;
2826 case Ordered: {
2827
2828 memset(dst->data, 0, dst->nbytes);
2829 if (d == 32) {
2830 for (int i=0; i<h; i++) {
2831 const uint *p = (const uint *)src_data;
2832 const uint *end = p + w;
2833 uchar *m = dst_data;
2834 int bit = 7;
2835 int j = 0;
2836 if (fromalpha) {
2837 while (p < end) {
2838 if ((*p++ >> 24) >= qt_bayer_matrix[j++&15][i&15])
2839 *m |= 1 << bit;
2840 if (bit == 0) {
2841 m++;
2842 bit = 7;
2843 } else {
2844 bit--;
2845 }
2846 }
2847 } else {
2848 while (p < end) {
2849 if ((uint)qGray(*p++) < qt_bayer_matrix[j++&15][i&15])
2850 *m |= 1 << bit;
2851 if (bit == 0) {
2852 m++;
2853 bit = 7;
2854 } else {
2855 bit--;
2856 }
2857 }
2858 }
2859 dst_data += dst_bpl;
2860 src_data += src_bpl;
2861 }
2862 } else
2863 /* (d == 8) */ {
2864 for (int i=0; i<h; i++) {
2865 const uchar *p = src_data;
2866 const uchar *end = p + w;
2867 uchar *m = dst_data;
2868 int bit = 7;
2869 int j = 0;
2870 while (p < end) {
2871 if ((uint)gray[*p++] < qt_bayer_matrix[j++&15][i&15])
2872 *m |= 1 << bit;
2873 if (bit == 0) {
2874 m++;
2875 bit = 7;
2876 } else {
2877 bit--;
2878 }
2879 }
2880 dst_data += dst_bpl;
2881 src_data += src_bpl;
2882 }
2883 }
2884 } break;
2885 default: { // Threshold:
2886 memset(dst->data, 0, dst->nbytes);
2887 if (d == 32) {
2888 for (int i=0; i<h; i++) {
2889 const uint *p = (const uint *)src_data;
2890 const uint *end = p + w;
2891 uchar *m = dst_data;
2892 int bit = 7;
2893 if (fromalpha) {
2894 while (p < end) {
2895 if ((*p++ >> 24) >= 128)
2896 *m |= 1 << bit; // Set mask "on"
2897 if (bit == 0) {
2898 m++;
2899 bit = 7;
2900 } else {
2901 bit--;
2902 }
2903 }
2904 } else {
2905 while (p < end) {
2906 if (qGray(*p++) < 128)
2907 *m |= 1 << bit; // Set pixel "black"
2908 if (bit == 0) {
2909 m++;
2910 bit = 7;
2911 } else {
2912 bit--;
2913 }
2914 }
2915 }
2916 dst_data += dst_bpl;
2917 src_data += src_bpl;
2918 }
2919 } else
2920 if (d == 8) {
2921 for (int i=0; i<h; i++) {
2922 const uchar *p = src_data;
2923 const uchar *end = p + w;
2924 uchar *m = dst_data;
2925 int bit = 7;
2926 while (p < end) {
2927 if (gray[*p++] < 128)
2928 *m |= 1 << bit; // Set mask "on"/ pixel "black"
2929 if (bit == 0) {
2930 m++;
2931 bit = 7;
2932 } else {
2933 bit--;
2934 }
2935 }
2936 dst_data += dst_bpl;
2937 src_data += src_bpl;
2938 }
2939 }
2940 }
2941 }
2942
2943 if (dst->format == QImage::Format_MonoLSB) {
2944 // need to swap bit order
2945 uchar *sl = dst->data;
2946 int bpl = (dst->width + 7) * dst->depth / 8;
2947 int pad = dst->bytes_per_line - bpl;
2948 for (int y=0; y<dst->height; ++y) {
2949 for (int x=0; x<bpl; ++x) {
2950 *sl = bitflip[*sl];
2951 ++sl;
2952 }
2953 sl += pad;
2954 }
2955 }
2956 }
2957
convert_X_to_Mono(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags)2958 static void convert_X_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
2959 {
2960 dither_to_Mono(dst, src, flags, false);
2961 }
2962
convert_ARGB_PM_to_Mono(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags)2963 static void convert_ARGB_PM_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
2964 {
2965 QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
2966 convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
2967 dither_to_Mono(dst, tmp.data(), flags, false);
2968 }
2969
2970 //
2971 // convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
2972 // image with a colormap. If the 32 bit image has more than 256 colors,
2973 // we convert the red,green and blue bytes into a single byte encoded
2974 // as 6 shades of each of red, green and blue.
2975 //
2976 // if dithering is needed, only 1 color at most is available for alpha.
2977 //
2978 struct QRgbMap {
QRgbMapQRgbMap2979 inline QRgbMap() : used(0) { }
2980 uchar pix;
2981 uchar used;
2982 QRgb rgb;
2983 };
2984
convert_RGB_to_Indexed8(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags)2985 static void convert_RGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
2986 {
2987 Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32);
2988 Q_ASSERT(dst->format == QImage::Format_Indexed8);
2989 Q_ASSERT(src->width == dst->width);
2990 Q_ASSERT(src->height == dst->height);
2991
2992 bool do_quant = (flags & Qt::DitherMode_Mask) == Qt::PreferDither
2993 || src->format == QImage::Format_ARGB32;
2994 uint alpha_mask = src->format == QImage::Format_RGB32 ? 0xff000000 : 0;
2995
2996 const int tablesize = 997; // prime
2997 QRgbMap table[tablesize];
2998 int pix=0;
2999
3000 if (!dst->colortable.isEmpty()) {
3001 QVector<QRgb> ctbl = dst->colortable;
3002 dst->colortable.resize(256);
3003 // Preload palette into table.
3004 // Almost same code as pixel insertion below
3005 for (int i = 0; i < dst->colortable.size(); ++i) {
3006 // Find in table...
3007 QRgb p = ctbl.at(i) | alpha_mask;
3008 int hash = p % tablesize;
3009 for (;;) {
3010 if (table[hash].used) {
3011 if (table[hash].rgb == p) {
3012 // Found previous insertion - use it
3013 break;
3014 } else {
3015 // Keep searching...
3016 if (++hash == tablesize) hash = 0;
3017 }
3018 } else {
3019 // Cannot be in table
3020 Q_ASSERT (pix != 256); // too many colors
3021 // Insert into table at this unused position
3022 dst->colortable[pix] = p;
3023 table[hash].pix = pix++;
3024 table[hash].rgb = p;
3025 table[hash].used = 1;
3026 break;
3027 }
3028 }
3029 }
3030 }
3031
3032 if ((flags & Qt::DitherMode_Mask) != Qt::PreferDither) {
3033 dst->colortable.resize(256);
3034 const uchar *src_data = src->data;
3035 uchar *dest_data = dst->data;
3036 for (int y = 0; y < src->height; y++) { // check if <= 256 colors
3037 const QRgb *s = (const QRgb *)src_data;
3038 uchar *b = dest_data;
3039 for (int x = 0; x < src->width; ++x) {
3040 QRgb p = s[x] | alpha_mask;
3041 int hash = p % tablesize;
3042 for (;;) {
3043 if (table[hash].used) {
3044 if (table[hash].rgb == (p)) {
3045 // Found previous insertion - use it
3046 break;
3047 } else {
3048 // Keep searching...
3049 if (++hash == tablesize) hash = 0;
3050 }
3051 } else {
3052 // Cannot be in table
3053 if (pix == 256) { // too many colors
3054 do_quant = true;
3055 // Break right out
3056 x = src->width;
3057 y = src->height;
3058 } else {
3059 // Insert into table at this unused position
3060 dst->colortable[pix] = p;
3061 table[hash].pix = pix++;
3062 table[hash].rgb = p;
3063 table[hash].used = 1;
3064 }
3065 break;
3066 }
3067 }
3068 *b++ = table[hash].pix; // May occur once incorrectly
3069 }
3070 src_data += src->bytes_per_line;
3071 dest_data += dst->bytes_per_line;
3072 }
3073 }
3074 int numColors = do_quant ? 256 : pix;
3075
3076 dst->colortable.resize(numColors);
3077
3078 if (do_quant) { // quantization needed
3079
3080 #define MAX_R 5
3081 #define MAX_G 5
3082 #define MAX_B 5
3083 #define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
3084
3085 for (int rc=0; rc<=MAX_R; rc++) // build 6x6x6 color cube
3086 for (int gc=0; gc<=MAX_G; gc++)
3087 for (int bc=0; bc<=MAX_B; bc++)
3088 dst->colortable[INDEXOF(rc,gc,bc)] = 0xff000000 | qRgb(rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B);
3089
3090 const uchar *src_data = src->data;
3091 uchar *dest_data = dst->data;
3092 if ((flags & Qt::Dither_Mask) == Qt::ThresholdDither) {
3093 for (int y = 0; y < src->height; y++) {
3094 const QRgb *p = (const QRgb *)src_data;
3095 const QRgb *end = p + src->width;
3096 uchar *b = dest_data;
3097
3098 while (p < end) {
3099 #define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
3100 *b++ =
3101 INDEXOF(
3102 DITHER(qRed(*p), MAX_R),
3103 DITHER(qGreen(*p), MAX_G),
3104 DITHER(qBlue(*p), MAX_B)
3105 );
3106 #undef DITHER
3107 p++;
3108 }
3109 src_data += src->bytes_per_line;
3110 dest_data += dst->bytes_per_line;
3111 }
3112 } else if ((flags & Qt::Dither_Mask) == Qt::DiffuseDither) {
3113 int* line1[3];
3114 int* line2[3];
3115 int* pv[3];
3116 QScopedArrayPointer<int> lineBuffer(new int[src->width * 9]);
3117 line1[0] = lineBuffer.data();
3118 line2[0] = lineBuffer.data() + src->width;
3119 line1[1] = lineBuffer.data() + src->width * 2;
3120 line2[1] = lineBuffer.data() + src->width * 3;
3121 line1[2] = lineBuffer.data() + src->width * 4;
3122 line2[2] = lineBuffer.data() + src->width * 5;
3123 pv[0] = lineBuffer.data() + src->width * 6;
3124 pv[1] = lineBuffer.data() + src->width * 7;
3125 pv[2] = lineBuffer.data() + src->width * 8;
3126
3127 int endian = (QSysInfo::ByteOrder == QSysInfo::BigEndian);
3128 for (int y = 0; y < src->height; y++) {
3129 const uchar* q = src_data;
3130 const uchar* q2 = y < src->height - 1 ? q + src->bytes_per_line : src->data;
3131 uchar *b = dest_data;
3132 for (int chan = 0; chan < 3; chan++) {
3133 int *l1 = (y&1) ? line2[chan] : line1[chan];
3134 int *l2 = (y&1) ? line1[chan] : line2[chan];
3135 if (y == 0) {
3136 for (int i = 0; i < src->width; i++)
3137 l1[i] = q[i*4+chan+endian];
3138 }
3139 if (y+1 < src->height) {
3140 for (int i = 0; i < src->width; i++)
3141 l2[i] = q2[i*4+chan+endian];
3142 }
3143 // Bi-directional error diffusion
3144 if (y&1) {
3145 for (int x = 0; x < src->width; x++) {
3146 int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
3147 int err = l1[x] - pix * 255 / 5;
3148 pv[chan][x] = pix;
3149
3150 // Spread the error around...
3151 if (x + 1< src->width) {
3152 l1[x+1] += (err*7)>>4;
3153 l2[x+1] += err>>4;
3154 }
3155 l2[x]+=(err*5)>>4;
3156 if (x>1)
3157 l2[x-1]+=(err*3)>>4;
3158 }
3159 } else {
3160 for (int x = src->width; x-- > 0;) {
3161 int pix = qMax(qMin(5, (l1[x] * 5 + 128)/ 255), 0);
3162 int err = l1[x] - pix * 255 / 5;
3163 pv[chan][x] = pix;
3164
3165 // Spread the error around...
3166 if (x > 0) {
3167 l1[x-1] += (err*7)>>4;
3168 l2[x-1] += err>>4;
3169 }
3170 l2[x]+=(err*5)>>4;
3171 if (x + 1 < src->width)
3172 l2[x+1]+=(err*3)>>4;
3173 }
3174 }
3175 }
3176 if (endian) {
3177 for (int x = 0; x < src->width; x++) {
3178 *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
3179 }
3180 } else {
3181 for (int x = 0; x < src->width; x++) {
3182 *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
3183 }
3184 }
3185 src_data += src->bytes_per_line;
3186 dest_data += dst->bytes_per_line;
3187 }
3188 } else { // OrderedDither
3189 for (int y = 0; y < src->height; y++) {
3190 const QRgb *p = (const QRgb *)src_data;
3191 const QRgb *end = p + src->width;
3192 uchar *b = dest_data;
3193
3194 int x = 0;
3195 while (p < end) {
3196 uint d = qt_bayer_matrix[y & 15][x & 15] << 8;
3197
3198 #define DITHER(p, d, m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) >> 16))
3199 *b++ =
3200 INDEXOF(
3201 DITHER(qRed(*p), d, MAX_R),
3202 DITHER(qGreen(*p), d, MAX_G),
3203 DITHER(qBlue(*p), d, MAX_B)
3204 );
3205 #undef DITHER
3206
3207 p++;
3208 x++;
3209 }
3210 src_data += src->bytes_per_line;
3211 dest_data += dst->bytes_per_line;
3212 }
3213 }
3214
3215 if (src->format != QImage::Format_RGB32
3216 && src->format != QImage::Format_RGB16) {
3217 const int trans = 216;
3218 Q_ASSERT(dst->colortable.size() > trans);
3219 dst->colortable[trans] = 0;
3220 QScopedPointer<QImageData> mask(QImageData::create(QSize(src->width, src->height), QImage::Format_Mono));
3221 dither_to_Mono(mask.data(), src, flags, true);
3222 uchar *dst_data = dst->data;
3223 const uchar *mask_data = mask->data;
3224 for (int y = 0; y < src->height; y++) {
3225 for (int x = 0; x < src->width ; x++) {
3226 if (!(mask_data[x>>3] & (0x80 >> (x & 7))))
3227 dst_data[x] = trans;
3228 }
3229 mask_data += mask->bytes_per_line;
3230 dst_data += dst->bytes_per_line;
3231 }
3232 dst->has_alpha_clut = true;
3233 }
3234
3235 #undef MAX_R
3236 #undef MAX_G
3237 #undef MAX_B
3238 #undef INDEXOF
3239
3240 }
3241 }
3242
convert_ARGB_PM_to_Indexed8(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags)3243 static void convert_ARGB_PM_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
3244 {
3245 QScopedPointer<QImageData> tmp(QImageData::create(QSize(src->width, src->height), QImage::Format_ARGB32));
3246 convert_ARGB_PM_to_ARGB(tmp.data(), src, flags);
3247 convert_RGB_to_Indexed8(dst, tmp.data(), flags);
3248 }
3249
convert_ARGB_to_Indexed8(QImageData * dst,const QImageData * src,Qt::ImageConversionFlags flags)3250 static void convert_ARGB_to_Indexed8(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags)
3251 {
3252 convert_RGB_to_Indexed8(dst, src, flags);
3253 }
3254
convert_Indexed8_to_X32(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)3255 static void convert_Indexed8_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
3256 {
3257 Q_ASSERT(src->format == QImage::Format_Indexed8);
3258 Q_ASSERT(dest->format == QImage::Format_RGB32
3259 || dest->format == QImage::Format_ARGB32
3260 || dest->format == QImage::Format_ARGB32_Premultiplied);
3261 Q_ASSERT(src->width == dest->width);
3262 Q_ASSERT(src->height == dest->height);
3263
3264 QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
3265 if (colorTable.size() == 0) {
3266 colorTable.resize(256);
3267 for (int i=0; i<256; ++i)
3268 colorTable[i] = qRgb(i, i, i);
3269 }
3270
3271 int w = src->width;
3272 const uchar *src_data = src->data;
3273 uchar *dest_data = dest->data;
3274 int tableSize = colorTable.size() - 1;
3275 for (int y = 0; y < src->height; y++) {
3276 uint *p = (uint *)dest_data;
3277 const uchar *b = src_data;
3278 uint *end = p + w;
3279
3280 while (p < end)
3281 *p++ = colorTable.at(qMin<int>(tableSize, *b++));
3282
3283 src_data += src->bytes_per_line;
3284 dest_data += dest->bytes_per_line;
3285 }
3286 }
3287
convert_Mono_to_X32(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)3288 static void convert_Mono_to_X32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
3289 {
3290 Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
3291 Q_ASSERT(dest->format == QImage::Format_RGB32
3292 || dest->format == QImage::Format_ARGB32
3293 || dest->format == QImage::Format_ARGB32_Premultiplied);
3294 Q_ASSERT(src->width == dest->width);
3295 Q_ASSERT(src->height == dest->height);
3296
3297 QVector<QRgb> colorTable = fix_color_table(src->colortable, dest->format);
3298
3299 // Default to black / white colors
3300 if (colorTable.size() < 2) {
3301 if (colorTable.size() == 0)
3302 colorTable << 0xff000000;
3303 colorTable << 0xffffffff;
3304 }
3305
3306 const uchar *src_data = src->data;
3307 uchar *dest_data = dest->data;
3308 if (src->format == QImage::Format_Mono) {
3309 for (int y = 0; y < dest->height; y++) {
3310 uint *p = (uint *)dest_data;
3311 for (int x = 0; x < dest->width; x++)
3312 *p++ = colorTable.at((src_data[x>>3] >> (7 - (x & 7))) & 1);
3313
3314 src_data += src->bytes_per_line;
3315 dest_data += dest->bytes_per_line;
3316 }
3317 } else {
3318 for (int y = 0; y < dest->height; y++) {
3319 uint *p = (uint *)dest_data;
3320 for (int x = 0; x < dest->width; x++)
3321 *p++ = colorTable.at((src_data[x>>3] >> (x & 7)) & 1);
3322
3323 src_data += src->bytes_per_line;
3324 dest_data += dest->bytes_per_line;
3325 }
3326 }
3327 }
3328
3329
convert_Mono_to_Indexed8(QImageData * dest,const QImageData * src,Qt::ImageConversionFlags)3330 static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
3331 {
3332 Q_ASSERT(src->format == QImage::Format_Mono || src->format == QImage::Format_MonoLSB);
3333 Q_ASSERT(dest->format == QImage::Format_Indexed8);
3334 Q_ASSERT(src->width == dest->width);
3335 Q_ASSERT(src->height == dest->height);
3336
3337 QVector<QRgb> ctbl = src->colortable;
3338 if (ctbl.size() > 2) {
3339 ctbl.resize(2);
3340 } else if (ctbl.size() < 2) {
3341 if (ctbl.size() == 0)
3342 ctbl << 0xff000000;
3343 ctbl << 0xffffffff;
3344 }
3345 dest->colortable = ctbl;
3346 dest->has_alpha_clut = src->has_alpha_clut;
3347
3348
3349 const uchar *src_data = src->data;
3350 uchar *dest_data = dest->data;
3351 if (src->format == QImage::Format_Mono) {
3352 for (int y = 0; y < dest->height; y++) {
3353 uchar *p = dest_data;
3354 for (int x = 0; x < dest->width; x++)
3355 *p++ = (src_data[x>>3] >> (7 - (x & 7))) & 1;
3356 src_data += src->bytes_per_line;
3357 dest_data += dest->bytes_per_line;
3358 }
3359 } else {
3360 for (int y = 0; y < dest->height; y++) {
3361 uchar *p = dest_data;
3362 for (int x = 0; x < dest->width; x++)
3363 *p++ = (src_data[x>>3] >> (x & 7)) & 1;
3364 src_data += src->bytes_per_line;
3365 dest_data += dest->bytes_per_line;
3366 }
3367 }
3368 }
3369
3370 #define CONVERT_DECL(DST, SRC) \
3371 static void convert_##SRC##_to_##DST(QImageData *dest, \
3372 const QImageData *src, \
3373 Qt::ImageConversionFlags) \
3374 { \
3375 qt_rectconvert<DST, SRC>(reinterpret_cast<DST*>(dest->data), \
3376 reinterpret_cast<const SRC*>(src->data), \
3377 0, 0, src->width, src->height, \
3378 dest->bytes_per_line, src->bytes_per_line); \
3379 }
3380
3381 CONVERT_DECL(quint32, quint16)
3382 CONVERT_DECL(quint16, quint32)
3383 CONVERT_DECL(quint32, qargb8565)
3384 CONVERT_DECL(qargb8565, quint32)
3385 CONVERT_DECL(quint32, qrgb555)
3386 CONVERT_DECL(qrgb666, quint32)
3387 CONVERT_DECL(quint32, qrgb666)
3388 CONVERT_DECL(qargb6666, quint32)
3389 CONVERT_DECL(quint32, qargb6666)
3390 CONVERT_DECL(qrgb555, quint32)
3391 #if !defined(Q_WS_QWS) || (defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16))
3392 CONVERT_DECL(quint16, qrgb555)
3393 CONVERT_DECL(qrgb555, quint16)
3394 #endif
3395 CONVERT_DECL(quint32, qrgb888)
3396 CONVERT_DECL(qrgb888, quint32)
3397 CONVERT_DECL(quint32, qargb8555)
3398 CONVERT_DECL(qargb8555, quint32)
3399 CONVERT_DECL(quint32, qrgb444)
3400 CONVERT_DECL(qrgb444, quint32)
3401 CONVERT_DECL(quint32, qargb4444)
3402 CONVERT_DECL(qargb4444, quint32)
3403 #undef CONVERT_DECL
3404 #define CONVERT_PTR(DST, SRC) convert_##SRC##_to_##DST
3405
3406 /*
3407 Format_Invalid,
3408 Format_Mono,
3409 Format_MonoLSB,
3410 Format_Indexed8,
3411 Format_RGB32,
3412 Format_ARGB32,
3413 Format_ARGB32_Premultiplied,
3414 Format_RGB16,
3415 Format_ARGB8565_Premultiplied,
3416 Format_RGB666,
3417 Format_ARGB6666_Premultiplied,
3418 Format_RGB555,
3419 Format_ARGB8555_Premultiplied,
3420 Format_RGB888
3421 Format_RGB444
3422 Format_ARGB4444_Premultiplied
3423 */
3424
3425
3426 // first index source, second dest
3427 static Image_Converter converter_map[QImage::NImageFormats][QImage::NImageFormats] =
3428 {
3429 {
3430 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3431 },
3432 {
3433 0,
3434 0,
3435 swap_bit_order,
3436 convert_Mono_to_Indexed8,
3437 convert_Mono_to_X32,
3438 convert_Mono_to_X32,
3439 convert_Mono_to_X32,
3440 0,
3441 0,
3442 0,
3443 0,
3444 0,
3445 0,
3446 0,
3447 0,
3448 0
3449 }, // Format_Mono
3450
3451 {
3452 0,
3453 swap_bit_order,
3454 0,
3455 convert_Mono_to_Indexed8,
3456 convert_Mono_to_X32,
3457 convert_Mono_to_X32,
3458 convert_Mono_to_X32,
3459 0,
3460 0,
3461 0,
3462 0,
3463 0,
3464 0,
3465 0,
3466 0,
3467 0
3468 }, // Format_MonoLSB
3469
3470 {
3471 0,
3472 convert_X_to_Mono,
3473 convert_X_to_Mono,
3474 0,
3475 convert_Indexed8_to_X32,
3476 convert_Indexed8_to_X32,
3477 convert_Indexed8_to_X32,
3478 0,
3479 0,
3480 0,
3481 0,
3482 0,
3483 0,
3484 0,
3485 0,
3486 0
3487 }, // Format_Indexed8
3488
3489 {
3490 0,
3491 convert_X_to_Mono,
3492 convert_X_to_Mono,
3493 convert_RGB_to_Indexed8,
3494 0,
3495 mask_alpha_converter,
3496 mask_alpha_converter,
3497 CONVERT_PTR(quint16, quint32),
3498 CONVERT_PTR(qargb8565, quint32),
3499 CONVERT_PTR(qrgb666, quint32),
3500 CONVERT_PTR(qargb6666, quint32),
3501 CONVERT_PTR(qrgb555, quint32),
3502 CONVERT_PTR(qargb8555, quint32),
3503 CONVERT_PTR(qrgb888, quint32),
3504 CONVERT_PTR(qrgb444, quint32),
3505 CONVERT_PTR(qargb4444, quint32)
3506 }, // Format_RGB32
3507
3508 {
3509 0,
3510 convert_X_to_Mono,
3511 convert_X_to_Mono,
3512 convert_ARGB_to_Indexed8,
3513 mask_alpha_converter,
3514 0,
3515 convert_ARGB_to_ARGB_PM,
3516 CONVERT_PTR(quint16, quint32),
3517 CONVERT_PTR(qargb8565, quint32),
3518 CONVERT_PTR(qrgb666, quint32),
3519 CONVERT_PTR(qargb6666, quint32),
3520 CONVERT_PTR(qrgb555, quint32),
3521 CONVERT_PTR(qargb8555, quint32),
3522 CONVERT_PTR(qrgb888, quint32),
3523 CONVERT_PTR(qrgb444, quint32),
3524 CONVERT_PTR(qargb4444, quint32)
3525 }, // Format_ARGB32
3526
3527 {
3528 0,
3529 convert_ARGB_PM_to_Mono,
3530 convert_ARGB_PM_to_Mono,
3531 convert_ARGB_PM_to_Indexed8,
3532 convert_ARGB_PM_to_RGB,
3533 convert_ARGB_PM_to_ARGB,
3534 0,
3535 0,
3536 0,
3537 0,
3538 0,
3539 0,
3540 0,
3541 0,
3542 0,
3543 0
3544 }, // Format_ARGB32_Premultiplied
3545
3546 {
3547 0,
3548 0,
3549 0,
3550 0,
3551 CONVERT_PTR(quint32, quint16),
3552 CONVERT_PTR(quint32, quint16),
3553 CONVERT_PTR(quint32, quint16),
3554 0,
3555 0,
3556 0,
3557 0,
3558 #if !defined(Q_WS_QWS) || (defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16))
3559 CONVERT_PTR(qrgb555, quint16),
3560 #else
3561 0,
3562 #endif
3563 0,
3564 0,
3565 0,
3566 0
3567 }, // Format_RGB16
3568
3569 {
3570 0,
3571 0,
3572 0,
3573 0,
3574 CONVERT_PTR(quint32, qargb8565),
3575 CONVERT_PTR(quint32, qargb8565),
3576 CONVERT_PTR(quint32, qargb8565),
3577 0,
3578 0,
3579 0,
3580 0,
3581 0,
3582 0,
3583 0,
3584 0,
3585 0
3586 }, // Format_ARGB8565_Premultiplied
3587
3588 {
3589 0,
3590 0,
3591 0,
3592 0,
3593 CONVERT_PTR(quint32, qrgb666),
3594 CONVERT_PTR(quint32, qrgb666),
3595 CONVERT_PTR(quint32, qrgb666),
3596 0,
3597 0,
3598 0,
3599 0,
3600 0,
3601 0,
3602 0,
3603 0,
3604 0
3605 }, // Format_RGB666
3606
3607 {
3608 0,
3609 0,
3610 0,
3611 0,
3612 CONVERT_PTR(quint32, qargb6666),
3613 CONVERT_PTR(quint32, qargb6666),
3614 CONVERT_PTR(quint32, qargb6666),
3615 0,
3616 0,
3617 0,
3618 0,
3619 0,
3620 0,
3621 0,
3622 0,
3623 0
3624 }, // Format_ARGB6666_Premultiplied
3625
3626 {
3627 0,
3628 0,
3629 0,
3630 0,
3631 CONVERT_PTR(quint32, qrgb555),
3632 CONVERT_PTR(quint32, qrgb555),
3633 CONVERT_PTR(quint32, qrgb555),
3634 #if !defined(Q_WS_QWS) || (defined(QT_QWS_DEPTH_15) && defined(QT_QWS_DEPTH_16))
3635 CONVERT_PTR(quint16, qrgb555),
3636 #else
3637 0,
3638 #endif
3639 0,
3640 0,
3641 0,
3642 0,
3643 0,
3644 0,
3645 0,
3646 0
3647 }, // Format_RGB555
3648
3649 {
3650 0,
3651 0,
3652 0,
3653 0,
3654 CONVERT_PTR(quint32, qargb8555),
3655 CONVERT_PTR(quint32, qargb8555),
3656 CONVERT_PTR(quint32, qargb8555),
3657 0,
3658 0,
3659 0,
3660 0,
3661 0,
3662 0,
3663 0,
3664 0,
3665 0
3666 }, // Format_ARGB8555_Premultiplied
3667
3668 {
3669 0,
3670 0,
3671 0,
3672 0,
3673 CONVERT_PTR(quint32, qrgb888),
3674 CONVERT_PTR(quint32, qrgb888),
3675 CONVERT_PTR(quint32, qrgb888),
3676 0,
3677 0,
3678 0,
3679 0,
3680 0,
3681 0,
3682 0,
3683 0,
3684 0
3685 }, // Format_RGB888
3686
3687 {
3688 0,
3689 0,
3690 0,
3691 0,
3692 CONVERT_PTR(quint32, qrgb444),
3693 CONVERT_PTR(quint32, qrgb444),
3694 CONVERT_PTR(quint32, qrgb444),
3695 0,
3696 0,
3697 0,
3698 0,
3699 0,
3700 0,
3701 0,
3702 0,
3703 0
3704 }, // Format_RGB444
3705
3706 {
3707 0,
3708 0,
3709 0,
3710 0,
3711 CONVERT_PTR(quint32, qargb4444),
3712 CONVERT_PTR(quint32, qargb4444),
3713 CONVERT_PTR(quint32, qargb4444),
3714 0,
3715 0,
3716 0,
3717 0,
3718 0,
3719 0,
3720 0,
3721 0,
3722 0
3723 } // Format_ARGB4444_Premultiplied
3724 };
3725
3726 static InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
3727 {
3728 {
3729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3730 },
3731 {
3732 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3733 }, // Format_Mono
3734 {
3735 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3736 }, // Format_MonoLSB
3737 {
3738 0,
3739 0,
3740 0,
3741 0,
3742 0,
3743 convert_indexed8_to_RGB_inplace,
3744 convert_indexed8_to_ARGB_PM_inplace,
3745 convert_indexed8_to_RGB16_inplace,
3746 0,
3747 0,
3748 0,
3749 0,
3750 0,
3751 0,
3752 0,
3753 0,
3754 }, // Format_Indexed8
3755 {
3756 0,
3757 0,
3758 0,
3759 0,
3760 0,
3761 0,
3762 0,
3763 convert_RGB_to_RGB16_inplace,
3764 0,
3765 0,
3766 0,
3767 0,
3768 0,
3769 0,
3770 0,
3771 0,
3772 }, // Format_ARGB32
3773 {
3774 0,
3775 0,
3776 0,
3777 0,
3778 0,
3779 0,
3780 convert_ARGB_to_ARGB_PM_inplace,
3781 0,
3782 0,
3783 0,
3784 0,
3785 0,
3786 0,
3787 0,
3788 0,
3789 0,
3790 }, // Format_ARGB32
3791 {
3792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3793 }, // Format_ARGB32_Premultiplied
3794 {
3795 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3796 }, // Format_RGB16
3797 {
3798 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3799 }, // Format_ARGB8565_Premultiplied
3800 {
3801 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3802 }, // Format_RGB666
3803 {
3804 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3805 }, // Format_ARGB6666_Premultiplied
3806 {
3807 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3808 }, // Format_RGB555
3809 {
3810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3811 }, // Format_ARGB8555_Premultiplied
3812 {
3813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3814 }, // Format_RGB888
3815 {
3816 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3817 }, // Format_RGB444
3818 {
3819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
3820 } // Format_ARGB4444_Premultiplied
3821 };
3822
qInitImageConversions()3823 void qInitImageConversions()
3824 {
3825 const uint features = qDetectCPUFeatures();
3826 Q_UNUSED(features);
3827
3828 #ifdef QT_HAVE_SSE2
3829 if (features & SSE2) {
3830 extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
3831 inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_sse2;
3832 }
3833 #endif
3834 #ifdef QT_HAVE_SSSE3
3835 if (features & SSSE3) {
3836 extern void convert_RGB888_to_RGB32_ssse3(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
3837 converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_ssse3;
3838 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_ssse3;
3839 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_ssse3;
3840 }
3841 #endif
3842 #ifdef QT_HAVE_NEON
3843 if (features & NEON) {
3844 extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
3845 converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
3846 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
3847 converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_neon;
3848 }
3849 #endif
3850 }
3851
qGamma_correct_back_to_linear_cs(QImage * image)3852 void qGamma_correct_back_to_linear_cs(QImage *image)
3853 {
3854 extern uchar qt_pow_rgb_gamma[256];
3855
3856 // gamma correct the pixels back to linear color space...
3857 int h = image->height();
3858 int w = image->width();
3859
3860 for (int y=0; y<h; ++y) {
3861 uint *pixels = (uint *) image->scanLine(y);
3862 for (int x=0; x<w; ++x) {
3863 uint p = pixels[x];
3864 uint r = qt_pow_rgb_gamma[qRed(p)];
3865 uint g = qt_pow_rgb_gamma[qGreen(p)];
3866 uint b = qt_pow_rgb_gamma[qBlue(p)];
3867 pixels[x] = (r << 16) | (g << 8) | b | 0xff000000;
3868 }
3869 }
3870 }
3871
3872 /*!
3873 Returns a copy of the image in the given \a format.
3874
3875 The specified image conversion \a flags control how the image data
3876 is handled during the conversion process.
3877
3878 \sa {QImage#Image Format}{Image Format}
3879 */
convertToFormat(Format format,Qt::ImageConversionFlags flags) const3880 QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const
3881 {
3882 if (!d || d->format == format)
3883 return *this;
3884
3885 if (format == Format_Invalid || d->format == Format_Invalid)
3886 return QImage();
3887
3888 const Image_Converter *converterPtr = &converter_map[d->format][format];
3889 Image_Converter converter = *converterPtr;
3890 if (converter) {
3891 QImage image(d->width, d->height, format);
3892
3893 QIMAGE_SANITYCHECK_MEMORY(image);
3894
3895 image.setDotsPerMeterY(dotsPerMeterY());
3896 image.setDotsPerMeterX(dotsPerMeterX());
3897
3898 #if !defined(QT_NO_IMAGE_TEXT)
3899 image.d->text = d->text;
3900 #endif // !QT_NO_IMAGE_TEXT
3901
3902 converter(image.d, d, flags);
3903 return image;
3904 }
3905
3906 Q_ASSERT(format != QImage::Format_ARGB32);
3907 Q_ASSERT(d->format != QImage::Format_ARGB32);
3908
3909 QImage image = convertToFormat(Format_ARGB32, flags);
3910 return image.convertToFormat(format, flags);
3911 }
3912
3913
3914
pixel_distance(QRgb p1,QRgb p2)3915 static inline int pixel_distance(QRgb p1, QRgb p2) {
3916 int r1 = qRed(p1);
3917 int g1 = qGreen(p1);
3918 int b1 = qBlue(p1);
3919 int a1 = qAlpha(p1);
3920
3921 int r2 = qRed(p2);
3922 int g2 = qGreen(p2);
3923 int b2 = qBlue(p2);
3924 int a2 = qAlpha(p2);
3925
3926 return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2) + abs(a1 - a2);
3927 }
3928
closestMatch(QRgb pixel,const QVector<QRgb> & clut)3929 static inline int closestMatch(QRgb pixel, const QVector<QRgb> &clut) {
3930 int idx = 0;
3931 int current_distance = INT_MAX;
3932 for (int i=0; i<clut.size(); ++i) {
3933 int dist = pixel_distance(pixel, clut.at(i));
3934 if (dist < current_distance) {
3935 current_distance = dist;
3936 idx = i;
3937 }
3938 }
3939 return idx;
3940 }
3941
convertWithPalette(const QImage & src,QImage::Format format,const QVector<QRgb> & clut)3942 static QImage convertWithPalette(const QImage &src, QImage::Format format,
3943 const QVector<QRgb> &clut) {
3944 QImage dest(src.size(), format);
3945 QIMAGE_SANITYCHECK_MEMORY(dest);
3946 dest.setColorTable(clut);
3947
3948 #if !defined(QT_NO_IMAGE_TEXT)
3949 QString textsKeys = src.text();
3950 QStringList textKeyList = textsKeys.split(QLatin1Char('\n'), QString::SkipEmptyParts);
3951 foreach (const QString &textKey, textKeyList) {
3952 QStringList textKeySplitted = textKey.split(QLatin1String(": "));
3953 dest.setText(textKeySplitted[0], textKeySplitted[1]);
3954 }
3955 #endif // !QT_NO_IMAGE_TEXT
3956
3957 int h = src.height();
3958 int w = src.width();
3959
3960 QHash<QRgb, int> cache;
3961
3962 if (format == QImage::Format_Indexed8) {
3963 for (int y=0; y<h; ++y) {
3964 QRgb *src_pixels = (QRgb *) src.scanLine(y);
3965 uchar *dest_pixels = (uchar *) dest.scanLine(y);
3966 for (int x=0; x<w; ++x) {
3967 int src_pixel = src_pixels[x];
3968 int value = cache.value(src_pixel, -1);
3969 if (value == -1) {
3970 value = closestMatch(src_pixel, clut);
3971 cache.insert(src_pixel, value);
3972 }
3973 dest_pixels[x] = (uchar) value;
3974 }
3975 }
3976 } else {
3977 QVector<QRgb> table = clut;
3978 table.resize(2);
3979 for (int y=0; y<h; ++y) {
3980 QRgb *src_pixels = (QRgb *) src.scanLine(y);
3981 for (int x=0; x<w; ++x) {
3982 int src_pixel = src_pixels[x];
3983 int value = cache.value(src_pixel, -1);
3984 if (value == -1) {
3985 value = closestMatch(src_pixel, table);
3986 cache.insert(src_pixel, value);
3987 }
3988 dest.setPixel(x, y, value);
3989 }
3990 }
3991 }
3992
3993 return dest;
3994 }
3995
3996 /*!
3997 \overload
3998
3999 Returns a copy of the image converted to the given \a format,
4000 using the specified \a colorTable.
4001
4002 Conversion from 32 bit to 8 bit indexed is a slow operation and
4003 will use a straightforward nearest color approach, with no
4004 dithering.
4005 */
convertToFormat(Format format,const QVector<QRgb> & colorTable,Qt::ImageConversionFlags flags) const4006 QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Qt::ImageConversionFlags flags) const
4007 {
4008 if (d->format == format)
4009 return *this;
4010
4011 if (format <= QImage::Format_Indexed8 && depth() == 32) {
4012 return convertWithPalette(*this, format, colorTable);
4013 }
4014
4015 const Image_Converter *converterPtr = &converter_map[d->format][format];
4016 Image_Converter converter = *converterPtr;
4017 if (!converter)
4018 return QImage();
4019
4020 QImage image(d->width, d->height, format);
4021 QIMAGE_SANITYCHECK_MEMORY(image);
4022
4023 #if !defined(QT_NO_IMAGE_TEXT)
4024 image.d->text = d->text;
4025 #endif // !QT_NO_IMAGE_TEXT
4026
4027 converter(image.d, d, flags);
4028 return image;
4029 }
4030
4031 #ifdef QT3_SUPPORT
4032 /*!
4033 Converts the depth (bpp) of the image to the given \a depth and
4034 returns the converted image. The original image is not changed.
4035 Returns this image if \a depth is equal to the image depth, or a
4036 null image if this image cannot be converted. The \a depth
4037 argument must be 1, 8 or 32. If the image needs to be modified to
4038 fit in a lower-resolution result (e.g. converting from 32-bit to
4039 8-bit), use the \a flags to specify how you'd prefer this to
4040 happen.
4041
4042 Use the convertToFormat() function instead.
4043 */
4044
convertDepth(int depth,Qt::ImageConversionFlags flags) const4045 QImage QImage::convertDepth(int depth, Qt::ImageConversionFlags flags) const
4046 {
4047 if (!d || d->depth == depth)
4048 return *this;
4049
4050 Format format = formatFor (depth, QImage::LittleEndian);
4051 return convertToFormat(format, flags);
4052 }
4053 #endif
4054
4055 /*!
4056 \fn bool QImage::valid(const QPoint &pos) const
4057
4058 Returns true if \a pos is a valid coordinate pair within the
4059 image; otherwise returns false.
4060
4061 \sa rect(), QRect::contains()
4062 */
4063
4064 /*!
4065 \overload
4066
4067 Returns true if QPoint(\a x, \a y) is a valid coordinate pair
4068 within the image; otherwise returns false.
4069 */
valid(int x,int y) const4070 bool QImage::valid(int x, int y) const
4071 {
4072 return d
4073 && x >= 0 && x < d->width
4074 && y >= 0 && y < d->height;
4075 }
4076
4077 /*!
4078 \fn int QImage::pixelIndex(const QPoint &position) const
4079
4080 Returns the pixel index at the given \a position.
4081
4082 If \a position is not valid, or if the image is not a paletted
4083 image (depth() > 8), the results are undefined.
4084
4085 \sa valid(), depth(), {QImage#Pixel Manipulation}{Pixel Manipulation}
4086 */
4087
4088 /*!
4089 \overload
4090
4091 Returns the pixel index at (\a x, \a y).
4092 */
pixelIndex(int x,int y) const4093 int QImage::pixelIndex(int x, int y) const
4094 {
4095 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
4096 qWarning("QImage::pixelIndex: coordinate (%d,%d) out of range", x, y);
4097 return -12345;
4098 }
4099 const uchar * s = scanLine(y);
4100 switch(d->format) {
4101 case Format_Mono:
4102 return (*(s + (x >> 3)) >> (7- (x & 7))) & 1;
4103 case Format_MonoLSB:
4104 return (*(s + (x >> 3)) >> (x & 7)) & 1;
4105 case Format_Indexed8:
4106 return (int)s[x];
4107 default:
4108 qWarning("QImage::pixelIndex: Not applicable for %d-bpp images (no palette)", d->depth);
4109 }
4110 return 0;
4111 }
4112
4113
4114 /*!
4115 \fn QRgb QImage::pixel(const QPoint &position) const
4116
4117 Returns the color of the pixel at the given \a position.
4118
4119 If the \a position is not valid, the results are undefined.
4120
4121 \warning This function is expensive when used for massive pixel
4122 manipulations.
4123
4124 \sa setPixel(), valid(), {QImage#Pixel Manipulation}{Pixel
4125 Manipulation}
4126 */
4127
4128 /*!
4129 \overload
4130
4131 Returns the color of the pixel at coordinates (\a x, \a y).
4132 */
pixel(int x,int y) const4133 QRgb QImage::pixel(int x, int y) const
4134 {
4135 if (!d || x < 0 || x >= d->width || y < 0 || y >= height()) {
4136 qWarning("QImage::pixel: coordinate (%d,%d) out of range", x, y);
4137 return 12345;
4138 }
4139 const uchar * s = scanLine(y);
4140 switch(d->format) {
4141 case Format_Mono:
4142 return d->colortable.at((*(s + (x >> 3)) >> (7- (x & 7))) & 1);
4143 case Format_MonoLSB:
4144 return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1);
4145 case Format_Indexed8:
4146 return d->colortable.at((int)s[x]);
4147 case Format_ARGB8565_Premultiplied:
4148 return qt_colorConvert<quint32, qargb8565>(reinterpret_cast<const qargb8565*>(s)[x], 0);
4149 case Format_RGB666:
4150 return qt_colorConvert<quint32, qrgb666>(reinterpret_cast<const qrgb666*>(s)[x], 0);
4151 case Format_ARGB6666_Premultiplied:
4152 return qt_colorConvert<quint32, qargb6666>(reinterpret_cast<const qargb6666*>(s)[x], 0);
4153 case Format_RGB555:
4154 return qt_colorConvert<quint32, qrgb555>(reinterpret_cast<const qrgb555*>(s)[x], 0);
4155 case Format_ARGB8555_Premultiplied:
4156 return qt_colorConvert<quint32, qargb8555>(reinterpret_cast<const qargb8555*>(s)[x], 0);
4157 case Format_RGB888:
4158 return qt_colorConvert<quint32, qrgb888>(reinterpret_cast<const qrgb888*>(s)[x], 0);
4159 case Format_RGB444:
4160 return qt_colorConvert<quint32, qrgb444>(reinterpret_cast<const qrgb444*>(s)[x], 0);
4161 case Format_ARGB4444_Premultiplied:
4162 return qt_colorConvert<quint32, qargb4444>(reinterpret_cast<const qargb4444*>(s)[x], 0);
4163 case Format_RGB16:
4164 return qt_colorConvert<quint32, quint16>(reinterpret_cast<const quint16*>(s)[x], 0);
4165 default:
4166 return ((QRgb*)s)[x];
4167 }
4168 }
4169
4170
4171 /*!
4172 \fn void QImage::setPixel(const QPoint &position, uint index_or_rgb)
4173
4174 Sets the pixel index or color at the given \a position to \a
4175 index_or_rgb.
4176
4177 If the image's format is either monochrome or 8-bit, the given \a
4178 index_or_rgb value must be an index in the image's color table,
4179 otherwise the parameter must be a QRgb value.
4180
4181 If \a position is not a valid coordinate pair in the image, or if
4182 \a index_or_rgb >= colorCount() in the case of monochrome and
4183 8-bit images, the result is undefined.
4184
4185 \warning This function is expensive due to the call of the internal
4186 \c{detach()} function called within; if performance is a concern, we
4187 recommend the use of \l{QImage::}{scanLine()} to access pixel data
4188 directly.
4189
4190 \sa pixel(), {QImage#Pixel Manipulation}{Pixel Manipulation}
4191 */
4192
4193 /*!
4194 \overload
4195
4196 Sets the pixel index or color at (\a x, \a y) to \a index_or_rgb.
4197 */
setPixel(int x,int y,uint index_or_rgb)4198 void QImage::setPixel(int x, int y, uint index_or_rgb)
4199 {
4200 if (!d || x < 0 || x >= width() || y < 0 || y >= height()) {
4201 qWarning("QImage::setPixel: coordinate (%d,%d) out of range", x, y);
4202 return;
4203 }
4204 // detach is called from within scanLine
4205 uchar * s = scanLine(y);
4206 if (!s) {
4207 qWarning("setPixel: Out of memory");
4208 return;
4209 }
4210 const quint32p p = quint32p::fromRawData(index_or_rgb);
4211 switch(d->format) {
4212 case Format_Mono:
4213 case Format_MonoLSB:
4214 if (index_or_rgb > 1) {
4215 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
4216 } else if (format() == Format_MonoLSB) {
4217 if (index_or_rgb==0)
4218 *(s + (x >> 3)) &= ~(1 << (x & 7));
4219 else
4220 *(s + (x >> 3)) |= (1 << (x & 7));
4221 } else {
4222 if (index_or_rgb==0)
4223 *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
4224 else
4225 *(s + (x >> 3)) |= (1 << (7-(x & 7)));
4226 }
4227 break;
4228 case Format_Indexed8:
4229 if (index_or_rgb >= (uint)d->colortable.size()) {
4230 qWarning("QImage::setPixel: Index %d out of range", index_or_rgb);
4231 return;
4232 }
4233 s[x] = index_or_rgb;
4234 break;
4235 case Format_RGB32:
4236 //make sure alpha is 255, we depend on it in qdrawhelper for cases
4237 // when image is set as a texture pattern on a qbrush
4238 ((uint *)s)[x] = uint(255 << 24) | index_or_rgb;
4239 break;
4240 case Format_ARGB32:
4241 case Format_ARGB32_Premultiplied:
4242 ((uint *)s)[x] = index_or_rgb;
4243 break;
4244 case Format_RGB16:
4245 ((quint16 *)s)[x] = qt_colorConvert<quint16, quint32p>(p, 0);
4246 break;
4247 case Format_ARGB8565_Premultiplied:
4248 ((qargb8565*)s)[x] = qt_colorConvert<qargb8565, quint32p>(p, 0);
4249 break;
4250 case Format_RGB666:
4251 ((qrgb666*)s)[x] = qt_colorConvert<qrgb666, quint32p>(p, 0);
4252 break;
4253 case Format_ARGB6666_Premultiplied:
4254 ((qargb6666*)s)[x] = qt_colorConvert<qargb6666, quint32p>(p, 0);
4255 break;
4256 case Format_RGB555:
4257 ((qrgb555*)s)[x] = qt_colorConvert<qrgb555, quint32p>(p, 0);
4258 break;
4259 case Format_ARGB8555_Premultiplied:
4260 ((qargb8555*)s)[x] = qt_colorConvert<qargb8555, quint32p>(p, 0);
4261 break;
4262 case Format_RGB888:
4263 ((qrgb888*)s)[x] = qt_colorConvert<qrgb888, quint32p>(p, 0);
4264 break;
4265 case Format_RGB444:
4266 ((qrgb444*)s)[x] = qt_colorConvert<qrgb444, quint32p>(p, 0);
4267 break;
4268 case Format_ARGB4444_Premultiplied:
4269 ((qargb4444*)s)[x] = qt_colorConvert<qargb4444, quint32p>(p, 0);
4270 break;
4271 case Format_Invalid:
4272 case NImageFormats:
4273 Q_ASSERT(false);
4274 }
4275 }
4276
4277 #ifdef QT3_SUPPORT
4278 /*!
4279 Converts the bit order of the image to the given \a bitOrder and
4280 returns the converted image. The original image is not changed.
4281 Returns this image if the given \a bitOrder is equal to the image
4282 current bit order, or a null image if this image cannot be
4283 converted.
4284
4285 Use convertToFormat() instead.
4286 */
4287
convertBitOrder(Endian bitOrder) const4288 QImage QImage::convertBitOrder(Endian bitOrder) const
4289 {
4290 if (!d || isNull() || d->depth != 1 || !(bitOrder == BigEndian || bitOrder == LittleEndian))
4291 return QImage();
4292
4293 if ((d->format == Format_Mono && bitOrder == BigEndian)
4294 || (d->format == Format_MonoLSB && bitOrder == LittleEndian))
4295 return *this;
4296
4297 QImage image(d->width, d->height, d->format == Format_Mono ? Format_MonoLSB : Format_Mono);
4298 QIMAGE_SANITYCHECK_MEMORY(image);
4299
4300 const uchar *data = d->data;
4301 const uchar *end = data + d->nbytes;
4302 uchar *ndata = image.d->data;
4303 while (data < end)
4304 *ndata++ = bitflip[*data++];
4305
4306 image.setDotsPerMeterX(dotsPerMeterX());
4307 image.setDotsPerMeterY(dotsPerMeterY());
4308
4309 image.d->colortable = d->colortable;
4310 return image;
4311 }
4312 #endif
4313 /*!
4314 Returns true if all the colors in the image are shades of gray
4315 (i.e. their red, green and blue components are equal); otherwise
4316 false.
4317
4318 Note that this function is slow for images without color table.
4319
4320 \sa isGrayscale()
4321 */
allGray() const4322 bool QImage::allGray() const
4323 {
4324 if (!d)
4325 return true;
4326
4327 if (d->depth == 32) {
4328 int p = width()*height();
4329 const QRgb* b = (const QRgb*)bits();
4330 while (p--)
4331 if (!qIsGray(*b++))
4332 return false;
4333 } else if (d->depth == 16) {
4334 int p = width()*height();
4335 const ushort* b = (const ushort *)bits();
4336 while (p--)
4337 if (!qIsGray(qt_colorConvert<quint32, quint16>(*b++, 0)))
4338 return false;
4339 } else if (d->format == QImage::Format_RGB888) {
4340 int p = width()*height();
4341 const qrgb888* b = (const qrgb888 *)bits();
4342 while (p--)
4343 if (!qIsGray(qt_colorConvert<quint32, qrgb888>(*b++, 0)))
4344 return false;
4345 } else {
4346 if (d->colortable.isEmpty())
4347 return true;
4348 for (int i = 0; i < colorCount(); i++)
4349 if (!qIsGray(d->colortable.at(i)))
4350 return false;
4351 }
4352 return true;
4353 }
4354
4355 /*!
4356 For 32-bit images, this function is equivalent to allGray().
4357
4358 For 8-bpp images, this function returns true if color(i) is
4359 QRgb(i, i, i) for all indexes of the color table; otherwise
4360 returns false.
4361
4362 \sa allGray(), {QImage#Image Formats}{Image Formats}
4363 */
isGrayscale() const4364 bool QImage::isGrayscale() const
4365 {
4366 if (!d)
4367 return false;
4368
4369 switch (depth()) {
4370 case 32:
4371 case 24:
4372 case 16:
4373 return allGray();
4374 case 8: {
4375 for (int i = 0; i < colorCount(); i++)
4376 if (d->colortable.at(i) != qRgb(i,i,i))
4377 return false;
4378 return true;
4379 }
4380 }
4381 return false;
4382 }
4383
4384
4385 /*!
4386 \fn QImage QImage::smoothScale(int width, int height, Qt::AspectRatioMode mode) const
4387
4388 Use scaled() instead.
4389
4390 \oldcode
4391 QImage image;
4392 image.smoothScale(width, height, mode);
4393 \newcode
4394 QImage image;
4395 image.scaled(width, height, mode, Qt::SmoothTransformation);
4396 \endcode
4397 */
4398
4399 /*!
4400 \fn QImage QImage::smoothScale(const QSize &size, Qt::AspectRatioMode mode) const
4401 \overload
4402
4403 Use scaled() instead.
4404
4405 \oldcode
4406 QImage image;
4407 image.smoothScale(size, mode);
4408 \newcode
4409 QImage image;
4410 image.scaled(size, mode, Qt::SmoothTransformation);
4411 \endcode
4412 */
4413
4414 /*!
4415 \fn QImage QImage::scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode,
4416 Qt::TransformationMode transformMode) const
4417 \overload
4418
4419 Returns a copy of the image scaled to a rectangle with the given
4420 \a width and \a height according to the given \a aspectRatioMode
4421 and \a transformMode.
4422
4423 If either the \a width or the \a height is zero or negative, this
4424 function returns a null image.
4425 */
4426
4427 /*!
4428 \fn QImage QImage::scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode,
4429 Qt::TransformationMode transformMode) const
4430
4431 Returns a copy of the image scaled to a rectangle defined by the
4432 given \a size according to the given \a aspectRatioMode and \a
4433 transformMode.
4434
4435 \image qimage-scaling.png
4436
4437 \list
4438 \i If \a aspectRatioMode is Qt::IgnoreAspectRatio, the image
4439 is scaled to \a size.
4440 \i If \a aspectRatioMode is Qt::KeepAspectRatio, the image is
4441 scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
4442 \i If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
4443 the image is scaled to a rectangle as small as possible
4444 outside \a size, preserving the aspect ratio.
4445 \endlist
4446
4447 If the given \a size is empty, this function returns a null image.
4448
4449 \sa isNull(), {QImage#Image Transformations}{Image
4450 Transformations}
4451 */
scaled(const QSize & s,Qt::AspectRatioMode aspectMode,Qt::TransformationMode mode) const4452 QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
4453 {
4454 if (!d) {
4455 qWarning("QImage::scaled: Image is a null image");
4456 return QImage();
4457 }
4458 if (s.isEmpty())
4459 return QImage();
4460
4461 QSize newSize = size();
4462 newSize.scale(s, aspectMode);
4463 newSize.rwidth() = qMax(newSize.width(), 1);
4464 newSize.rheight() = qMax(newSize.height(), 1);
4465 if (newSize == size())
4466 return *this;
4467
4468 QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height());
4469 QImage img = transformed(wm, mode);
4470 return img;
4471 }
4472
4473 /*!
4474 \fn QImage QImage::scaledToWidth(int width, Qt::TransformationMode mode) const
4475
4476 Returns a scaled copy of the image. The returned image is scaled
4477 to the given \a width using the specified transformation \a
4478 mode.
4479
4480 This function automatically calculates the height of the image so
4481 that its aspect ratio is preserved.
4482
4483 If the given \a width is 0 or negative, a null image is returned.
4484
4485 \sa {QImage#Image Transformations}{Image Transformations}
4486 */
scaledToWidth(int w,Qt::TransformationMode mode) const4487 QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const
4488 {
4489 if (!d) {
4490 qWarning("QImage::scaleWidth: Image is a null image");
4491 return QImage();
4492 }
4493 if (w <= 0)
4494 return QImage();
4495
4496 qreal factor = (qreal) w / width();
4497 QTransform wm = QTransform::fromScale(factor, factor);
4498 return transformed(wm, mode);
4499 }
4500
4501 /*!
4502 \fn QImage QImage::scaledToHeight(int height, Qt::TransformationMode mode) const
4503
4504 Returns a scaled copy of the image. The returned image is scaled
4505 to the given \a height using the specified transformation \a
4506 mode.
4507
4508 This function automatically calculates the width of the image so that
4509 the ratio of the image is preserved.
4510
4511 If the given \a height is 0 or negative, a null image is returned.
4512
4513 \sa {QImage#Image Transformations}{Image Transformations}
4514 */
scaledToHeight(int h,Qt::TransformationMode mode) const4515 QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const
4516 {
4517 if (!d) {
4518 qWarning("QImage::scaleHeight: Image is a null image");
4519 return QImage();
4520 }
4521 if (h <= 0)
4522 return QImage();
4523
4524 qreal factor = (qreal) h / height();
4525 QTransform wm = QTransform::fromScale(factor, factor);
4526 return transformed(wm, mode);
4527 }
4528
4529
4530 /*!
4531 \fn QMatrix QImage::trueMatrix(const QMatrix &matrix, int width, int height)
4532
4533 Returns the actual matrix used for transforming an image with the
4534 given \a width, \a height and \a matrix.
4535
4536 When transforming an image using the transformed() function, the
4537 transformation matrix is internally adjusted to compensate for
4538 unwanted translation, i.e. transformed() returns the smallest
4539 image containing all transformed points of the original image.
4540 This function returns the modified matrix, which maps points
4541 correctly from the original image into the new image.
4542
4543 \sa transformed(), {QImage#Image Transformations}{Image
4544 Transformations}
4545 */
trueMatrix(const QMatrix & matrix,int w,int h)4546 QMatrix QImage::trueMatrix(const QMatrix &matrix, int w, int h)
4547 {
4548 return trueMatrix(QTransform(matrix), w, h).toAffine();
4549 }
4550
4551 /*!
4552 Returns a copy of the image that is transformed using the given
4553 transformation \a matrix and transformation \a mode.
4554
4555 The transformation \a matrix is internally adjusted to compensate
4556 for unwanted translation; i.e. the image produced is the smallest
4557 image that contains all the transformed points of the original
4558 image. Use the trueMatrix() function to retrieve the actual matrix
4559 used for transforming an image.
4560
4561 \sa trueMatrix(), {QImage#Image Transformations}{Image
4562 Transformations}
4563 */
transformed(const QMatrix & matrix,Qt::TransformationMode mode) const4564 QImage QImage::transformed(const QMatrix &matrix, Qt::TransformationMode mode) const
4565 {
4566 return transformed(QTransform(matrix), mode);
4567 }
4568
4569 /*!
4570 Builds and returns a 1-bpp mask from the alpha buffer in this
4571 image. Returns a null image if the image's format is
4572 QImage::Format_RGB32.
4573
4574 The \a flags argument is a bitwise-OR of the
4575 Qt::ImageConversionFlags, and controls the conversion
4576 process. Passing 0 for flags sets all the default options.
4577
4578 The returned image has little-endian bit order (i.e. the image's
4579 format is QImage::Format_MonoLSB), which you can convert to
4580 big-endian (QImage::Format_Mono) using the convertToFormat()
4581 function.
4582
4583 \sa createHeuristicMask(), {QImage#Image Transformations}{Image
4584 Transformations}
4585 */
createAlphaMask(Qt::ImageConversionFlags flags) const4586 QImage QImage::createAlphaMask(Qt::ImageConversionFlags flags) const
4587 {
4588 if (!d || d->format == QImage::Format_RGB32)
4589 return QImage();
4590
4591 if (d->depth == 1) {
4592 // A monochrome pixmap, with alpha channels on those two colors.
4593 // Pretty unlikely, so use less efficient solution.
4594 return convertToFormat(Format_Indexed8, flags).createAlphaMask(flags);
4595 }
4596
4597 QImage mask(d->width, d->height, Format_MonoLSB);
4598 if (!mask.isNull())
4599 dither_to_Mono(mask.d, d, flags, true);
4600 return mask;
4601 }
4602
4603 #ifndef QT_NO_IMAGE_HEURISTIC_MASK
4604 /*!
4605 Creates and returns a 1-bpp heuristic mask for this image.
4606
4607 The function works by selecting a color from one of the corners,
4608 then chipping away pixels of that color starting at all the edges.
4609 The four corners vote for which color is to be masked away. In
4610 case of a draw (this generally means that this function is not
4611 applicable to the image), the result is arbitrary.
4612
4613 The returned image has little-endian bit order (i.e. the image's
4614 format is QImage::Format_MonoLSB), which you can convert to
4615 big-endian (QImage::Format_Mono) using the convertToFormat()
4616 function.
4617
4618 If \a clipTight is true (the default) the mask is just large
4619 enough to cover the pixels; otherwise, the mask is larger than the
4620 data pixels.
4621
4622 Note that this function disregards the alpha buffer.
4623
4624 \sa createAlphaMask(), {QImage#Image Transformations}{Image
4625 Transformations}
4626 */
4627
createHeuristicMask(bool clipTight) const4628 QImage QImage::createHeuristicMask(bool clipTight) const
4629 {
4630 if (!d)
4631 return QImage();
4632
4633 if (d->depth != 32) {
4634 QImage img32 = convertToFormat(Format_RGB32);
4635 return img32.createHeuristicMask(clipTight);
4636 }
4637
4638 #define PIX(x,y) (*((QRgb*)scanLine(y)+x) & 0x00ffffff)
4639
4640 int w = width();
4641 int h = height();
4642 QImage m(w, h, Format_MonoLSB);
4643 QIMAGE_SANITYCHECK_MEMORY(m);
4644 m.setColorCount(2);
4645 m.setColor(0, QColor(Qt::color0).rgba());
4646 m.setColor(1, QColor(Qt::color1).rgba());
4647 m.fill(0xff);
4648
4649 QRgb background = PIX(0,0);
4650 if (background != PIX(w-1,0) &&
4651 background != PIX(0,h-1) &&
4652 background != PIX(w-1,h-1)) {
4653 background = PIX(w-1,0);
4654 if (background != PIX(w-1,h-1) &&
4655 background != PIX(0,h-1) &&
4656 PIX(0,h-1) == PIX(w-1,h-1)) {
4657 background = PIX(w-1,h-1);
4658 }
4659 }
4660
4661 int x,y;
4662 bool done = false;
4663 uchar *ypp, *ypc, *ypn;
4664 while(!done) {
4665 done = true;
4666 ypn = m.scanLine(0);
4667 ypc = 0;
4668 for (y = 0; y < h; y++) {
4669 ypp = ypc;
4670 ypc = ypn;
4671 ypn = (y == h-1) ? 0 : m.scanLine(y+1);
4672 QRgb *p = (QRgb *)scanLine(y);
4673 for (x = 0; x < w; x++) {
4674 // slowness here - it's possible to do six of these tests
4675 // together in one go. oh well.
4676 if ((x == 0 || y == 0 || x == w-1 || y == h-1 ||
4677 !(*(ypc + ((x-1) >> 3)) & (1 << ((x-1) & 7))) ||
4678 !(*(ypc + ((x+1) >> 3)) & (1 << ((x+1) & 7))) ||
4679 !(*(ypp + (x >> 3)) & (1 << (x & 7))) ||
4680 !(*(ypn + (x >> 3)) & (1 << (x & 7)))) &&
4681 ( (*(ypc + (x >> 3)) & (1 << (x & 7)))) &&
4682 ((*p & 0x00ffffff) == background)) {
4683 done = false;
4684 *(ypc + (x >> 3)) &= ~(1 << (x & 7));
4685 }
4686 p++;
4687 }
4688 }
4689 }
4690
4691 if (!clipTight) {
4692 ypn = m.scanLine(0);
4693 ypc = 0;
4694 for (y = 0; y < h; y++) {
4695 ypp = ypc;
4696 ypc = ypn;
4697 ypn = (y == h-1) ? 0 : m.scanLine(y+1);
4698 QRgb *p = (QRgb *)scanLine(y);
4699 for (x = 0; x < w; x++) {
4700 if ((*p & 0x00ffffff) != background) {
4701 if (x > 0)
4702 *(ypc + ((x-1) >> 3)) |= (1 << ((x-1) & 7));
4703 if (x < w-1)
4704 *(ypc + ((x+1) >> 3)) |= (1 << ((x+1) & 7));
4705 if (y > 0)
4706 *(ypp + (x >> 3)) |= (1 << (x & 7));
4707 if (y < h-1)
4708 *(ypn + (x >> 3)) |= (1 << (x & 7));
4709 }
4710 p++;
4711 }
4712 }
4713 }
4714
4715 #undef PIX
4716
4717 return m;
4718 }
4719 #endif //QT_NO_IMAGE_HEURISTIC_MASK
4720
4721 /*!
4722 Creates and returns a mask for this image based on the given \a
4723 color value. If the \a mode is MaskInColor (the default value),
4724 all pixels matching \a color will be opaque pixels in the mask. If
4725 \a mode is MaskOutColor, all pixels matching the given color will
4726 be transparent.
4727
4728 \sa createAlphaMask(), createHeuristicMask()
4729 */
4730
createMaskFromColor(QRgb color,Qt::MaskMode mode) const4731 QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
4732 {
4733 if (!d)
4734 return QImage();
4735 QImage maskImage(size(), QImage::Format_MonoLSB);
4736 QIMAGE_SANITYCHECK_MEMORY(maskImage);
4737 maskImage.fill(0);
4738 uchar *s = maskImage.bits();
4739
4740 if (depth() == 32) {
4741 for (int h = 0; h < d->height; h++) {
4742 const uint *sl = (uint *) scanLine(h);
4743 for (int w = 0; w < d->width; w++) {
4744 if (sl[w] == color)
4745 *(s + (w >> 3)) |= (1 << (w & 7));
4746 }
4747 s += maskImage.bytesPerLine();
4748 }
4749 } else {
4750 for (int h = 0; h < d->height; h++) {
4751 for (int w = 0; w < d->width; w++) {
4752 if ((uint) pixel(w, h) == color)
4753 *(s + (w >> 3)) |= (1 << (w & 7));
4754 }
4755 s += maskImage.bytesPerLine();
4756 }
4757 }
4758 if (mode == Qt::MaskOutColor)
4759 maskImage.invertPixels();
4760 return maskImage;
4761 }
4762
4763
4764 /*!
4765 \fn QImage QImage::mirror(bool horizontal, bool vertical) const
4766
4767 Use mirrored() instead.
4768 */
4769
do_mirror_data(QImageData * dst,QImageData * src,int dstX0,int dstY0,int dstXIncr,int dstYIncr,int w,int h)4770 template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
4771 int dstX0, int dstY0,
4772 int dstXIncr, int dstYIncr,
4773 int w, int h)
4774 {
4775 if (dst == src) {
4776 // When mirroring in-place, stop in the middle for one of the directions, since we
4777 // are swapping the bytes instead of merely copying.
4778 const int srcXEnd = dstX0 ? w / 2 : w;
4779 const int srcYEnd = !dstX0 && dstY0 ? h / 2 : h;
4780 for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) {
4781 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
4782 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
4783 for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr)
4784 qSwap(srcPtr[srcX], dstPtr[dstX]);
4785 }
4786 } else {
4787 for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) {
4788 T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
4789 T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
4790 for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr)
4791 dstPtr[dstX] = srcPtr[srcX];
4792 }
4793 }
4794 }
4795
do_mirror(QImageData * dst,QImageData * src,bool horizontal,bool vertical)4796 inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
4797 {
4798 Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
4799 int w = src->width;
4800 int h = src->height;
4801 int depth = src->depth;
4802
4803 if (src->depth == 1) {
4804 w = (w + 7) / 8; // byte aligned width
4805 depth = 8;
4806 }
4807
4808 int dstX0 = 0, dstXIncr = 1;
4809 int dstY0 = 0, dstYIncr = 1;
4810 if (horizontal) {
4811 // 0 -> w-1, 1 -> w-2, 2 -> w-3, ...
4812 dstX0 = w - 1;
4813 dstXIncr = -1;
4814 }
4815 if (vertical) {
4816 // 0 -> h-1, 1 -> h-2, 2 -> h-3, ...
4817 dstY0 = h - 1;
4818 dstYIncr = -1;
4819 }
4820
4821 switch (depth) {
4822 case 32:
4823 do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
4824 break;
4825 case 24:
4826 do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
4827 break;
4828 case 16:
4829 do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
4830 break;
4831 case 8:
4832 do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
4833 break;
4834 default:
4835 Q_ASSERT(false);
4836 break;
4837 }
4838
4839 // The bytes are now all in the correct place. In addition, the bits in the individual
4840 // bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image.
4841 if (horizontal && dst->depth == 1) {
4842 Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
4843 const int shift = 8 - (dst->width % 8);
4844 const uchar *bitflip = qt_get_bitflip_array();
4845 for (int y = 0; y < h; ++y) {
4846 uchar *begin = dst->data + y * dst->bytes_per_line;
4847 uchar *end = begin + dst->bytes_per_line;
4848 for (uchar *p = begin; p < end; ++p) {
4849 *p = bitflip[*p];
4850 // When the data is non-byte aligned, an extra bit shift (of the number of
4851 // unused bits at the end) is needed for the entire scanline.
4852 if (shift != 8 && p != begin) {
4853 if (dst->format == QImage::Format_Mono) {
4854 for (int i = 0; i < shift; ++i) {
4855 p[-1] <<= 1;
4856 p[-1] |= (*p & (128 >> i)) >> (7 - i);
4857 }
4858 } else {
4859 for (int i = 0; i < shift; ++i) {
4860 p[-1] >>= 1;
4861 p[-1] |= (*p & (1 << i)) << (7 - i);
4862 }
4863 }
4864 }
4865 }
4866 if (shift != 8) {
4867 if (dst->format == QImage::Format_Mono)
4868 end[-1] <<= shift;
4869 else
4870 end[-1] >>= shift;
4871 }
4872 }
4873 }
4874 }
4875
4876 /*!
4877 Returns a mirror of the image, mirrored in the horizontal and/or
4878 the vertical direction depending on whether \a horizontal and \a
4879 vertical are set to true or false.
4880
4881 Note that the original image is not changed.
4882
4883 \sa {QImage#Image Transformations}{Image Transformations}
4884 */
mirrored(bool horizontal,bool vertical) const4885 QImage QImage::mirrored(bool horizontal, bool vertical) const
4886 {
4887 if (!d)
4888 return QImage();
4889
4890 if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
4891 return *this;
4892
4893 // Create result image, copy colormap
4894 QImage result(d->width, d->height, d->format);
4895 QIMAGE_SANITYCHECK_MEMORY(result);
4896
4897 // check if we ran out of of memory..
4898 if (!result.d)
4899 return QImage();
4900
4901 result.d->colortable = d->colortable;
4902 result.d->has_alpha_clut = d->has_alpha_clut;
4903 result.d->dpmx = d->dpmx;
4904 result.d->dpmy = d->dpmy;
4905
4906 do_mirror(result.d, d, horizontal, vertical);
4907
4908 return result;
4909 }
4910
4911 /*!
4912 \fn QImage QImage::swapRGB() const
4913
4914 Use rgbSwapped() instead.
4915
4916 \omit
4917 Returns a QImage in which the values of the red and blue
4918 components of all pixels have been swapped, effectively converting
4919 an RGB image to an BGR image. The original QImage is not changed.
4920 \endomit
4921 */
4922
4923 /*!
4924 Returns a QImage in which the values of the red and blue
4925 components of all pixels have been swapped, effectively converting
4926 an RGB image to an BGR image.
4927
4928 The original QImage is not changed.
4929
4930 \sa {QImage#Image Transformations}{Image Transformations}
4931 */
rgbSwapped() const4932 QImage QImage::rgbSwapped() const
4933 {
4934 if (isNull())
4935 return *this;
4936 QImage res;
4937 switch (d->format) {
4938 case Format_Invalid:
4939 case NImageFormats:
4940 Q_ASSERT(false);
4941 break;
4942 case Format_Mono:
4943 case Format_MonoLSB:
4944 case Format_Indexed8:
4945 res = copy();
4946 QIMAGE_SANITYCHECK_MEMORY(res);
4947 for (int i = 0; i < res.d->colortable.size(); i++) {
4948 QRgb c = res.d->colortable.at(i);
4949 res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00));
4950 }
4951 break;
4952 case Format_RGB32:
4953 case Format_ARGB32:
4954 case Format_ARGB32_Premultiplied:
4955 res = QImage(d->width, d->height, d->format);
4956 QIMAGE_SANITYCHECK_MEMORY(res);
4957 for (int i = 0; i < d->height; i++) {
4958 uint *q = (uint*)res.scanLine(i);
4959 uint *p = (uint*)constScanLine(i);
4960 uint *end = p + d->width;
4961 while (p < end) {
4962 *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
4963 p++;
4964 q++;
4965 }
4966 }
4967 break;
4968 case Format_RGB16:
4969 res = QImage(d->width, d->height, d->format);
4970 QIMAGE_SANITYCHECK_MEMORY(res);
4971 for (int i = 0; i < d->height; i++) {
4972 ushort *q = (ushort*)res.scanLine(i);
4973 const ushort *p = (const ushort*)constScanLine(i);
4974 const ushort *end = p + d->width;
4975 while (p < end) {
4976 *q = ((*p << 11) & 0xf800) | ((*p >> 11) & 0x1f) | (*p & 0x07e0);
4977 p++;
4978 q++;
4979 }
4980 }
4981 break;
4982 case Format_ARGB8565_Premultiplied:
4983 res = QImage(d->width, d->height, d->format);
4984 QIMAGE_SANITYCHECK_MEMORY(res);
4985 for (int i = 0; i < d->height; i++) {
4986 const quint8 *p = constScanLine(i);
4987 quint8 *q = res.scanLine(i);
4988 const quint8 *end = p + d->width * sizeof(qargb8565);
4989 while (p < end) {
4990 q[0] = p[0];
4991 q[1] = (p[1] & 0xe0) | (p[2] >> 3);
4992 q[2] = (p[2] & 0x07) | (p[1] << 3);
4993 p += sizeof(qargb8565);
4994 q += sizeof(qargb8565);
4995 }
4996 }
4997 break;
4998 case Format_RGB666:
4999 res = QImage(d->width, d->height, d->format);
5000 QIMAGE_SANITYCHECK_MEMORY(res);
5001 for (int i = 0; i < d->height; i++) {
5002 qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i));
5003 const qrgb666 *p = reinterpret_cast<const qrgb666*>(constScanLine(i));
5004 const qrgb666 *end = p + d->width;
5005 while (p < end) {
5006 const QRgb rgb = quint32(*p++);
5007 *q++ = qRgb(qBlue(rgb), qGreen(rgb), qRed(rgb));
5008 }
5009 }
5010 break;
5011 case Format_ARGB6666_Premultiplied:
5012 res = QImage(d->width, d->height, d->format);
5013 QIMAGE_SANITYCHECK_MEMORY(res);
5014 for (int i = 0; i < d->height; i++) {
5015 const quint8 *p = constScanLine(i);
5016 const quint8 *end = p + d->width * sizeof(qargb6666);
5017 quint8 *q = res.scanLine(i);
5018 while (p < end) {
5019 q[0] = (p[1] >> 4) | ((p[2] & 0x3) << 4) | (p[0] & 0xc0);
5020 q[1] = (p[1] & 0xf) | (p[0] << 4);
5021 q[2] = (p[2] & 0xfc) | ((p[0] >> 4) & 0x3);
5022 p += sizeof(qargb6666);
5023 q += sizeof(qargb6666);
5024 }
5025 }
5026 break;
5027 case Format_RGB555:
5028 res = QImage(d->width, d->height, d->format);
5029 QIMAGE_SANITYCHECK_MEMORY(res);
5030 for (int i = 0; i < d->height; i++) {
5031 quint16 *q = (quint16*)res.scanLine(i);
5032 const quint16 *p = (const quint16*)constScanLine(i);
5033 const quint16 *end = p + d->width;
5034 while (p < end) {
5035 *q = ((*p << 10) & 0x7c00) | ((*p >> 10) & 0x1f) | (*p & 0x3e0);
5036 p++;
5037 q++;
5038 }
5039 }
5040 break;
5041 case Format_ARGB8555_Premultiplied:
5042 res = QImage(d->width, d->height, d->format);
5043 QIMAGE_SANITYCHECK_MEMORY(res);
5044 for (int i = 0; i < d->height; i++) {
5045 const quint8 *p = constScanLine(i);
5046 quint8 *q = res.scanLine(i);
5047 const quint8 *end = p + d->width * sizeof(qargb8555);
5048 while (p < end) {
5049 q[0] = p[0];
5050 q[1] = (p[1] & 0xe0) | (p[2] >> 2);
5051 q[2] = (p[2] & 0x03) | ((p[1] << 2) & 0x7f);
5052 p += sizeof(qargb8555);
5053 q += sizeof(qargb8555);
5054 }
5055 }
5056 break;
5057 case Format_RGB888:
5058 res = QImage(d->width, d->height, d->format);
5059 QIMAGE_SANITYCHECK_MEMORY(res);
5060 for (int i = 0; i < d->height; i++) {
5061 quint8 *q = res.scanLine(i);
5062 const quint8 *p = constScanLine(i);
5063 const quint8 *end = p + d->width * sizeof(qrgb888);
5064 while (p < end) {
5065 q[0] = p[2];
5066 q[1] = p[1];
5067 q[2] = p[0];
5068 q += sizeof(qrgb888);
5069 p += sizeof(qrgb888);
5070 }
5071 }
5072 break;
5073 case Format_RGB444:
5074 case Format_ARGB4444_Premultiplied:
5075 res = QImage(d->width, d->height, d->format);
5076 QIMAGE_SANITYCHECK_MEMORY(res);
5077 for (int i = 0; i < d->height; i++) {
5078 quint16 *q = reinterpret_cast<quint16*>(res.scanLine(i));
5079 const quint16 *p = reinterpret_cast<const quint16*>(constScanLine(i));
5080 const quint16 *end = p + d->width;
5081 while (p < end) {
5082 *q = (*p & 0xf0f0) | ((*p & 0x0f) << 8) | ((*p & 0xf00) >> 8);
5083 p++;
5084 q++;
5085 }
5086 }
5087 break;
5088 }
5089 return res;
5090 }
5091
5092 /*!
5093 Loads an image from the file with the given \a fileName. Returns true if
5094 the image was successfully loaded; otherwise returns false.
5095
5096 The loader attempts to read the image using the specified \a format, e.g.,
5097 PNG or JPG. If \a format is not specified (which is the default), the
5098 loader probes the file for a header to guess the file format.
5099
5100 The file name can either refer to an actual file on disk or to one
5101 of the application's embedded resources. See the
5102 \l{resources.html}{Resource System} overview for details on how to
5103 embed images and other resource files in the application's
5104 executable.
5105
5106 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
5107 */
5108
load(const QString & fileName,const char * format)5109 bool QImage::load(const QString &fileName, const char* format)
5110 {
5111 if (fileName.isEmpty())
5112 return false;
5113
5114 QImage image = QImageReader(fileName, format).read();
5115 if (!image.isNull()) {
5116 operator=(image);
5117 return true;
5118 }
5119 return false;
5120 }
5121
5122 /*!
5123 \overload
5124
5125 This function reads a QImage from the given \a device. This can,
5126 for example, be used to load an image directly into a QByteArray.
5127 */
5128
load(QIODevice * device,const char * format)5129 bool QImage::load(QIODevice* device, const char* format)
5130 {
5131 QImage image = QImageReader(device, format).read();
5132 if(!image.isNull()) {
5133 operator=(image);
5134 return true;
5135 }
5136 return false;
5137 }
5138
5139 /*!
5140 \fn bool QImage::loadFromData(const uchar *data, int len, const char *format)
5141
5142 Loads an image from the first \a len bytes of the given binary \a
5143 data. Returns true if the image was successfully loaded; otherwise
5144 returns false.
5145
5146 The loader attempts to read the image using the specified \a format, e.g.,
5147 PNG or JPG. If \a format is not specified (which is the default), the
5148 loader probes the file for a header to guess the file format.
5149
5150 \sa {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
5151 */
5152
loadFromData(const uchar * data,int len,const char * format)5153 bool QImage::loadFromData(const uchar *data, int len, const char *format)
5154 {
5155 QImage image = fromData(data, len, format);
5156 if (!image.isNull()) {
5157 operator=(image);
5158 return true;
5159 }
5160 return false;
5161 }
5162
5163 /*!
5164 \fn bool QImage::loadFromData(const QByteArray &data, const char *format)
5165
5166 \overload
5167
5168 Loads an image from the given QByteArray \a data.
5169 */
5170
5171 /*!
5172 \fn QImage QImage::fromData(const uchar *data, int size, const char *format)
5173
5174 Constructs a QImage from the first \a size bytes of the given
5175 binary \a data. The loader attempts to read the image using the
5176 specified \a format. If \a format is not specified (which is the default),
5177 the loader probes the file for a header to guess the file format.
5178 binary \a data. The loader attempts to read the image, either using the
5179 optional image \a format specified or by determining the image format from
5180 the data.
5181
5182 If \a format is not specified (which is the default), the loader probes the
5183 file for a header to determine the file format. If \a format is specified,
5184 it must be one of the values returned by QImageReader::supportedImageFormats().
5185
5186 If the loading of the image fails, the image returned will be a null image.
5187
5188 \sa load(), save(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files}
5189 */
5190
fromData(const uchar * data,int size,const char * format)5191 QImage QImage::fromData(const uchar *data, int size, const char *format)
5192 {
5193 QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(data), size);
5194 QBuffer b;
5195 b.setData(a);
5196 b.open(QIODevice::ReadOnly);
5197 return QImageReader(&b, format).read();
5198 }
5199
5200 /*!
5201 \fn QImage QImage::fromData(const QByteArray &data, const char *format)
5202
5203 \overload
5204
5205 Loads an image from the given QByteArray \a data.
5206 */
5207
5208 /*!
5209 Saves the image to the file with the given \a fileName, using the
5210 given image file \a format and \a quality factor. If \a format is
5211 0, QImage will attempt to guess the format by looking at \a fileName's
5212 suffix.
5213
5214 The \a quality factor must be in the range 0 to 100 or -1. Specify
5215 0 to obtain small compressed files, 100 for large uncompressed
5216 files, and -1 (the default) to use the default settings.
5217
5218 Returns true if the image was successfully saved; otherwise
5219 returns false.
5220
5221 \sa {QImage#Reading and Writing Image Files}{Reading and Writing
5222 Image Files}
5223 */
save(const QString & fileName,const char * format,int quality) const5224 bool QImage::save(const QString &fileName, const char *format, int quality) const
5225 {
5226 if (isNull())
5227 return false;
5228 QImageWriter writer(fileName, format);
5229 return d->doImageIO(this, &writer, quality);
5230 }
5231
5232 /*!
5233 \overload
5234
5235 This function writes a QImage to the given \a device.
5236
5237 This can, for example, be used to save an image directly into a
5238 QByteArray:
5239
5240 \snippet doc/src/snippets/image/image.cpp 0
5241 */
5242
save(QIODevice * device,const char * format,int quality) const5243 bool QImage::save(QIODevice* device, const char* format, int quality) const
5244 {
5245 if (isNull())
5246 return false; // nothing to save
5247 QImageWriter writer(device, format);
5248 return d->doImageIO(this, &writer, quality);
5249 }
5250
5251 /* \internal
5252 */
5253
doImageIO(const QImage * image,QImageWriter * writer,int quality) const5254 bool QImageData::doImageIO(const QImage *image, QImageWriter *writer, int quality) const
5255 {
5256 if (quality > 100 || quality < -1)
5257 qWarning("QPixmap::save: Quality out of range [-1, 100]");
5258 if (quality >= 0)
5259 writer->setQuality(qMin(quality,100));
5260 return writer->write(*image);
5261 }
5262
5263 /*****************************************************************************
5264 QImage stream functions
5265 *****************************************************************************/
5266 #if !defined(QT_NO_DATASTREAM)
5267 /*!
5268 \fn QDataStream &operator<<(QDataStream &stream, const QImage &image)
5269 \relates QImage
5270
5271 Writes the given \a image to the given \a stream as a PNG image,
5272 or as a BMP image if the stream's version is 1. Note that writing
5273 the stream to a file will not produce a valid image file.
5274
5275 \sa QImage::save(), {Serializing Qt Data Types}
5276 */
5277
operator <<(QDataStream & s,const QImage & image)5278 QDataStream &operator<<(QDataStream &s, const QImage &image)
5279 {
5280 if (s.version() >= 5) {
5281 if (image.isNull()) {
5282 s << (qint32) 0; // null image marker
5283 return s;
5284 } else {
5285 s << (qint32) 1;
5286 // continue ...
5287 }
5288 }
5289 QImageWriter writer(s.device(), s.version() == 1 ? "bmp" : "png");
5290 writer.write(image);
5291 return s;
5292 }
5293
5294 /*!
5295 \fn QDataStream &operator>>(QDataStream &stream, QImage &image)
5296 \relates QImage
5297
5298 Reads an image from the given \a stream and stores it in the given
5299 \a image.
5300
5301 \sa QImage::load(), {Serializing Qt Data Types}
5302 */
5303
operator >>(QDataStream & s,QImage & image)5304 QDataStream &operator>>(QDataStream &s, QImage &image)
5305 {
5306 if (s.version() >= 5) {
5307 qint32 nullMarker;
5308 s >> nullMarker;
5309 if (!nullMarker) {
5310 image = QImage(); // null image
5311 return s;
5312 }
5313 }
5314 image = QImageReader(s.device(), 0).read();
5315 return s;
5316 }
5317 #endif // QT_NO_DATASTREAM
5318
5319
5320 #ifdef QT3_SUPPORT
5321 /*!
5322 \fn QImage QImage::convertDepthWithPalette(int depth, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
5323
5324 Returns an image with the given \a depth, using the \a
5325 palette_count colors pointed to by \a palette. If \a depth is 1 or
5326 8, the returned image will have its color table ordered in the
5327 same way as \a palette.
5328
5329 If the image needs to be modified to fit in a lower-resolution
5330 result (e.g. converting from 32-bit to 8-bit), use the \a flags to
5331 specify how you'd prefer this to happen.
5332
5333 Note: currently no closest-color search is made. If colors are
5334 found that are not in the palette, the palette may not be used at
5335 all. This result should not be considered valid because it may
5336 change in future implementations.
5337
5338 Currently inefficient for non-32-bit images.
5339
5340 Use the convertToFormat() function in combination with the
5341 setColorTable() function instead.
5342 */
convertDepthWithPalette(int d,QRgb * palette,int palette_count,Qt::ImageConversionFlags flags) const5343 QImage QImage::convertDepthWithPalette(int d, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
5344 {
5345 Format f = formatFor(d, QImage::LittleEndian);
5346 QVector<QRgb> colortable;
5347 for (int i = 0; i < palette_count; ++i)
5348 colortable.append(palette[i]);
5349 return convertToFormat(f, colortable, flags);
5350 }
5351
5352 /*!
5353 \relates QImage
5354
5355 Copies a block of pixels from \a src to \a dst. The pixels
5356 copied from source (src) are converted according to
5357 \a flags if it is incompatible with the destination
5358 (\a dst).
5359
5360 \a sx, \a sy is the top-left pixel in \a src, \a dx, \a dy is the
5361 top-left position in \a dst and \a sw, \a sh is the size of the
5362 copied block. The copying is clipped if areas outside \a src or \a
5363 dst are specified. If \a sw is -1, it is adjusted to
5364 src->width(). Similarly, if \a sh is -1, it is adjusted to
5365 src->height().
5366
5367 Currently inefficient for non 32-bit images.
5368
5369 Use copy() or QPainter::drawImage() instead.
5370 */
bitBlt(QImage * dst,int dx,int dy,const QImage * src,int sx,int sy,int sw,int sh,Qt::ImageConversionFlags flags)5371 void bitBlt(QImage *dst, int dx, int dy, const QImage *src, int sx, int sy, int sw, int sh,
5372 Qt::ImageConversionFlags flags)
5373 {
5374 if (dst->isNull() || src->isNull())
5375 return;
5376 QPainter p(dst);
5377 p.drawImage(QPoint(dx, dy), *src, QRect(sx, sy, sw, sh), flags);
5378 }
5379 #endif
5380
5381 /*!
5382 \fn bool QImage::operator==(const QImage & image) const
5383
5384 Returns true if this image and the given \a image have the same
5385 contents; otherwise returns false.
5386
5387 The comparison can be slow, unless there is some obvious
5388 difference (e.g. different size or format), in which case the
5389 function will return quickly.
5390
5391 \sa operator=()
5392 */
5393
operator ==(const QImage & i) const5394 bool QImage::operator==(const QImage & i) const
5395 {
5396 // same object, or shared?
5397 if (i.d == d)
5398 return true;
5399 if (!i.d || !d)
5400 return false;
5401
5402 // obviously different stuff?
5403 if (i.d->height != d->height || i.d->width != d->width || i.d->format != d->format)
5404 return false;
5405
5406 if (d->format != Format_RGB32) {
5407 if (d->format >= Format_ARGB32) { // all bits defined
5408 const int n = d->width * d->depth / 8;
5409 if (n == d->bytes_per_line && n == i.d->bytes_per_line) {
5410 if (memcmp(bits(), i.bits(), d->nbytes))
5411 return false;
5412 } else {
5413 for (int y = 0; y < d->height; ++y) {
5414 if (memcmp(scanLine(y), i.scanLine(y), n))
5415 return false;
5416 }
5417 }
5418 } else {
5419 const int w = width();
5420 const int h = height();
5421 const QVector<QRgb> &colortable = d->colortable;
5422 const QVector<QRgb> &icolortable = i.d->colortable;
5423 for (int y=0; y<h; ++y) {
5424 for (int x=0; x<w; ++x) {
5425 if (colortable[pixelIndex(x, y)] != icolortable[i.pixelIndex(x, y)])
5426 return false;
5427 }
5428 }
5429 }
5430 } else {
5431 //alpha channel undefined, so we must mask it out
5432 for(int l = 0; l < d->height; l++) {
5433 int w = d->width;
5434 const uint *p1 = reinterpret_cast<const uint*>(scanLine(l));
5435 const uint *p2 = reinterpret_cast<const uint*>(i.scanLine(l));
5436 while (w--) {
5437 if ((*p1++ & 0x00ffffff) != (*p2++ & 0x00ffffff))
5438 return false;
5439 }
5440 }
5441 }
5442 return true;
5443 }
5444
5445
5446 /*!
5447 \fn bool QImage::operator!=(const QImage & image) const
5448
5449 Returns true if this image and the given \a image have different
5450 contents; otherwise returns false.
5451
5452 The comparison can be slow, unless there is some obvious
5453 difference, such as different widths, in which case the function
5454 will return quickly.
5455
5456 \sa operator=()
5457 */
5458
operator !=(const QImage & i) const5459 bool QImage::operator!=(const QImage & i) const
5460 {
5461 return !(*this == i);
5462 }
5463
5464
5465
5466
5467 /*!
5468 Returns the number of pixels that fit horizontally in a physical
5469 meter. Together with dotsPerMeterY(), this number defines the
5470 intended scale and aspect ratio of the image.
5471
5472 \sa setDotsPerMeterX(), {QImage#Image Information}{Image
5473 Information}
5474 */
dotsPerMeterX() const5475 int QImage::dotsPerMeterX() const
5476 {
5477 return d ? qRound(d->dpmx) : 0;
5478 }
5479
5480 /*!
5481 Returns the number of pixels that fit vertically in a physical
5482 meter. Together with dotsPerMeterX(), this number defines the
5483 intended scale and aspect ratio of the image.
5484
5485 \sa setDotsPerMeterY(), {QImage#Image Information}{Image
5486 Information}
5487 */
dotsPerMeterY() const5488 int QImage::dotsPerMeterY() const
5489 {
5490 return d ? qRound(d->dpmy) : 0;
5491 }
5492
5493 /*!
5494 Sets the number of pixels that fit horizontally in a physical
5495 meter, to \a x.
5496
5497 Together with dotsPerMeterY(), this number defines the intended
5498 scale and aspect ratio of the image, and determines the scale
5499 at which QPainter will draw graphics on the image. It does not
5500 change the scale or aspect ratio of the image when it is rendered
5501 on other paint devices.
5502
5503 \sa dotsPerMeterX(), {QImage#Image Information}{Image Information}
5504 */
setDotsPerMeterX(int x)5505 void QImage::setDotsPerMeterX(int x)
5506 {
5507 if (!d || !x)
5508 return;
5509 detach();
5510
5511 if (d)
5512 d->dpmx = x;
5513 }
5514
5515 /*!
5516 Sets the number of pixels that fit vertically in a physical meter,
5517 to \a y.
5518
5519 Together with dotsPerMeterX(), this number defines the intended
5520 scale and aspect ratio of the image, and determines the scale
5521 at which QPainter will draw graphics on the image. It does not
5522 change the scale or aspect ratio of the image when it is rendered
5523 on other paint devices.
5524
5525 \sa dotsPerMeterY(), {QImage#Image Information}{Image Information}
5526 */
setDotsPerMeterY(int y)5527 void QImage::setDotsPerMeterY(int y)
5528 {
5529 if (!d || !y)
5530 return;
5531 detach();
5532
5533 if (d)
5534 d->dpmy = y;
5535 }
5536
5537 /*!
5538 \fn QPoint QImage::offset() const
5539
5540 Returns the number of pixels by which the image is intended to be
5541 offset by when positioning relative to other images.
5542
5543 \sa setOffset(), {QImage#Image Information}{Image Information}
5544 */
offset() const5545 QPoint QImage::offset() const
5546 {
5547 return d ? d->offset : QPoint();
5548 }
5549
5550
5551 /*!
5552 \fn void QImage::setOffset(const QPoint& offset)
5553
5554 Sets the number of pixels by which the image is intended to be
5555 offset by when positioning relative to other images, to \a offset.
5556
5557 \sa offset(), {QImage#Image Information}{Image Information}
5558 */
setOffset(const QPoint & p)5559 void QImage::setOffset(const QPoint& p)
5560 {
5561 if (!d)
5562 return;
5563 detach();
5564
5565 if (d)
5566 d->offset = p;
5567 }
5568 #ifndef QT_NO_IMAGE_TEXT
5569
5570 /*!
5571 Returns the text keys for this image.
5572
5573 You can use these keys with text() to list the image text for a
5574 certain key.
5575
5576 \sa text()
5577 */
textKeys() const5578 QStringList QImage::textKeys() const
5579 {
5580 return d ? QStringList(d->text.keys()) : QStringList();
5581 }
5582
5583 /*!
5584 Returns the image text associated with the given \a key. If the
5585 specified \a key is an empty string, the whole image text is
5586 returned, with each key-text pair separated by a newline.
5587
5588 \sa setText(), textKeys()
5589 */
text(const QString & key) const5590 QString QImage::text(const QString &key) const
5591 {
5592 if (!d)
5593 return QString();
5594
5595 if (!key.isEmpty())
5596 return d->text.value(key);
5597
5598 QString tmp;
5599 foreach (const QString &key, d->text.keys()) {
5600 if (!tmp.isEmpty())
5601 tmp += QLatin1String("\n\n");
5602 tmp += key + QLatin1String(": ") + d->text.value(key).simplified();
5603 }
5604 return tmp;
5605 }
5606
5607 /*!
5608 \fn void QImage::setText(const QString &key, const QString &text)
5609
5610 Sets the image text to the given \a text and associate it with the
5611 given \a key.
5612
5613 If you just want to store a single text block (i.e., a "comment"
5614 or just a description), you can either pass an empty key, or use a
5615 generic key like "Description".
5616
5617 The image text is embedded into the image data when you
5618 call save() or QImageWriter::write().
5619
5620 Not all image formats support embedded text. You can find out
5621 if a specific image or format supports embedding text
5622 by using QImageWriter::supportsOption(). We give an example:
5623
5624 \snippet doc/src/snippets/image/supportedformat.cpp 0
5625
5626 You can use QImageWriter::supportedImageFormats() to find out
5627 which image formats are available to you.
5628
5629 \sa text(), textKeys()
5630 */
setText(const QString & key,const QString & value)5631 void QImage::setText(const QString &key, const QString &value)
5632 {
5633 if (!d)
5634 return;
5635 detach();
5636
5637 if (d)
5638 d->text.insert(key, value);
5639 }
5640
5641 /*!
5642 \fn QString QImage::text(const char* key, const char* language) const
5643 \obsolete
5644
5645 Returns the text recorded for the given \a key in the given \a
5646 language, or in a default language if \a language is 0.
5647
5648 Use text() instead.
5649
5650 The language the text is recorded in is no longer relevant since
5651 the text is always set using QString and UTF-8 representation.
5652 */
text(const char * key,const char * lang) const5653 QString QImage::text(const char* key, const char* lang) const
5654 {
5655 if (!d)
5656 return QString();
5657 QString k = QString::fromAscii(key);
5658 if (lang && *lang)
5659 k += QLatin1Char('/') + QString::fromAscii(lang);
5660 return d->text.value(k);
5661 }
5662
5663 /*!
5664 \fn QString QImage::text(const QImageTextKeyLang& keywordAndLanguage) const
5665 \overload
5666 \obsolete
5667
5668 Returns the text recorded for the given \a keywordAndLanguage.
5669
5670 Use text() instead.
5671
5672 The language the text is recorded in is no longer relevant since
5673 the text is always set using QString and UTF-8 representation.
5674 */
text(const QImageTextKeyLang & kl) const5675 QString QImage::text(const QImageTextKeyLang& kl) const
5676 {
5677 if (!d)
5678 return QString();
5679 QString k = QString::fromAscii(kl.key);
5680 if (!kl.lang.isEmpty())
5681 k += QLatin1Char('/') + QString::fromAscii(kl.lang);
5682 return d->text.value(k);
5683 }
5684
5685 /*!
5686 \obsolete
5687
5688 Returns the language identifiers for which some texts are
5689 recorded. Note that if you want to iterate over the list, you
5690 should iterate over a copy.
5691
5692 The language the text is recorded in is no longer relevant since
5693 the text is always set using QString and UTF-8 representation.
5694 */
textLanguages() const5695 QStringList QImage::textLanguages() const
5696 {
5697 if (!d)
5698 return QStringList();
5699 QStringList keys = textKeys();
5700 QStringList languages;
5701 for (int i = 0; i < keys.size(); ++i) {
5702 int index = keys.at(i).indexOf(QLatin1Char('/'));
5703 if (index > 0)
5704 languages += keys.at(i).mid(index+1);
5705 }
5706
5707 return languages;
5708 }
5709
5710 /*!
5711 \obsolete
5712
5713 Returns a list of QImageTextKeyLang objects that enumerate all the
5714 texts key/language pairs set for this image.
5715
5716 Use textKeys() instead.
5717
5718 The language the text is recorded in is no longer relevant since
5719 the text is always set using QString and UTF-8 representation.
5720 */
textList() const5721 QList<QImageTextKeyLang> QImage::textList() const
5722 {
5723 QList<QImageTextKeyLang> imageTextKeys;
5724 if (!d)
5725 return imageTextKeys;
5726 QStringList keys = textKeys();
5727 for (int i = 0; i < keys.size(); ++i) {
5728 int index = keys.at(i).indexOf(QLatin1Char('/'));
5729 if (index > 0) {
5730 QImageTextKeyLang tkl;
5731 tkl.key = keys.at(i).left(index).toAscii();
5732 tkl.lang = keys.at(i).mid(index+1).toAscii();
5733 imageTextKeys += tkl;
5734 }
5735 }
5736
5737 return imageTextKeys;
5738 }
5739
5740 /*!
5741 \fn void QImage::setText(const char* key, const char* language, const QString& text)
5742 \obsolete
5743
5744 Sets the image text to the given \a text and associate it with the
5745 given \a key. The text is recorded in the specified \a language,
5746 or in a default language if \a language is 0.
5747
5748 Use setText() instead.
5749
5750 The language the text is recorded in is no longer relevant since
5751 the text is always set using QString and UTF-8 representation.
5752
5753 \omit
5754 Records string \a for the keyword \a key. The \a key should be
5755 a portable keyword recognizable by other software - some suggested
5756 values can be found in
5757 \l{http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.Anc-text}
5758 {the PNG specification}. \a s can be any text. \a lang should
5759 specify the language code (see
5760 \l{http://www.rfc-editor.org/rfc/rfc1766.txt}{RFC 1766}) or 0.
5761 \endomit
5762 */
setText(const char * key,const char * lang,const QString & s)5763 void QImage::setText(const char* key, const char* lang, const QString& s)
5764 {
5765 if (!d)
5766 return;
5767 detach();
5768
5769 // In case detach() ran out of memory
5770 if (!d)
5771 return;
5772
5773 QString k = QString::fromAscii(key);
5774 if (lang && *lang)
5775 k += QLatin1Char('/') + QString::fromAscii(lang);
5776 d->text.insert(k, s);
5777 }
5778
5779 #endif // QT_NO_IMAGE_TEXT
5780
5781 /*
5782 Sets the image bits to the \a pixmap contents and returns a
5783 reference to the image.
5784
5785 If the image shares data with other images, it will first
5786 dereference the shared data.
5787
5788 Makes a call to QPixmap::convertToImage().
5789 */
5790
5791 /*! \fn QImage::Endian QImage::systemBitOrder()
5792
5793 Determines the bit order of the display hardware. Returns
5794 QImage::LittleEndian (LSB first) or QImage::BigEndian (MSB first).
5795
5796 This function is no longer relevant for QImage. Use QSysInfo
5797 instead.
5798 */
5799
5800
5801 /*!
5802 \internal
5803
5804 Used by QPainter to retrieve a paint engine for the image.
5805 */
5806
paintEngine() const5807 QPaintEngine *QImage::paintEngine() const
5808 {
5809 if (!d)
5810 return 0;
5811
5812 if (!d->paintEngine) {
5813 #ifdef Q_OS_SYMBIAN
5814 d->paintEngine = new QSymbianRasterPaintEngine(const_cast<QImage *>(this));
5815 #else
5816 d->paintEngine = new QRasterPaintEngine(const_cast<QImage *>(this));
5817 #endif
5818 }
5819
5820 return d->paintEngine;
5821 }
5822
5823
5824 /*!
5825 \internal
5826
5827 Returns the size for the specified \a metric on the device.
5828 */
metric(PaintDeviceMetric metric) const5829 int QImage::metric(PaintDeviceMetric metric) const
5830 {
5831 if (!d)
5832 return 0;
5833
5834 switch (metric) {
5835 case PdmWidth:
5836 return d->width;
5837 break;
5838
5839 case PdmHeight:
5840 return d->height;
5841 break;
5842
5843 case PdmWidthMM:
5844 return qRound(d->width * 1000 / d->dpmx);
5845 break;
5846
5847 case PdmHeightMM:
5848 return qRound(d->height * 1000 / d->dpmy);
5849 break;
5850
5851 case PdmNumColors:
5852 return d->colortable.size();
5853 break;
5854
5855 case PdmDepth:
5856 return d->depth;
5857 break;
5858
5859 case PdmDpiX:
5860 return qRound(d->dpmx * 0.0254);
5861 break;
5862
5863 case PdmDpiY:
5864 return qRound(d->dpmy * 0.0254);
5865 break;
5866
5867 case PdmPhysicalDpiX:
5868 return qRound(d->dpmx * 0.0254);
5869 break;
5870
5871 case PdmPhysicalDpiY:
5872 return qRound(d->dpmy * 0.0254);
5873 break;
5874
5875 default:
5876 qWarning("QImage::metric(): Unhandled metric type %d", metric);
5877 break;
5878 }
5879 return 0;
5880 }
5881
5882
5883
5884 /*****************************************************************************
5885 QPixmap (and QImage) helper functions
5886 *****************************************************************************/
5887 /*
5888 This internal function contains the common (i.e. platform independent) code
5889 to do a transformation of pixel data. It is used by QPixmap::transform() and by
5890 QImage::transform().
5891
5892 \a trueMat is the true transformation matrix (see QPixmap::trueMatrix()) and
5893 \a xoffset is an offset to the matrix.
5894
5895 \a msbfirst specifies for 1bpp images, if the MSB or LSB comes first and \a
5896 depth specifies the colordepth of the data.
5897
5898 \a dptr is a pointer to the destination data, \a dbpl specifies the bits per
5899 line for the destination data, \a p_inc is the offset that we advance for
5900 every scanline and \a dHeight is the height of the destination image.
5901
5902 \a sprt is the pointer to the source data, \a sbpl specifies the bits per
5903 line of the source data, \a sWidth and \a sHeight are the width and height of
5904 the source data.
5905 */
5906
5907 #undef IWX_MSB
5908 #define IWX_MSB(b) if (trigx < maxws && trigy < maxhs) { \
5909 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
5910 (1 << (7-((trigx>>12)&7)))) \
5911 *dptr |= b; \
5912 } \
5913 trigx += m11; \
5914 trigy += m12;
5915 // END OF MACRO
5916 #undef IWX_LSB
5917 #define IWX_LSB(b) if (trigx < maxws && trigy < maxhs) { \
5918 if (*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
5919 (1 << ((trigx>>12)&7))) \
5920 *dptr |= b; \
5921 } \
5922 trigx += m11; \
5923 trigy += m12;
5924 // END OF MACRO
5925 #undef IWX_PIX
5926 #define IWX_PIX(b) if (trigx < maxws && trigy < maxhs) { \
5927 if ((*(sptr+sbpl*(trigy>>12)+(trigx>>15)) & \
5928 (1 << (7-((trigx>>12)&7)))) == 0) \
5929 *dptr &= ~b; \
5930 } \
5931 trigx += m11; \
5932 trigy += m12;
5933 // 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)5934 bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth,
5935 uchar *dptr, int dbpl, int p_inc, int dHeight,
5936 const uchar *sptr, int sbpl, int sWidth, int sHeight)
5937 {
5938 int m11 = int(trueMat.m11()*qreal(4096.0));
5939 int m12 = int(trueMat.m12()*qreal(4096.0));
5940 int m21 = int(trueMat.m21()*qreal(4096.0));
5941 int m22 = int(trueMat.m22()*qreal(4096.0));
5942 int dx = qRound(trueMat.dx()*qreal(4096.0));
5943 int dy = qRound(trueMat.dy()*qreal(4096.0));
5944
5945 int m21ydx = dx + (xoffset<<16) + (m11 + m21) / 2;
5946 int m22ydy = dy + (m12 + m22) / 2;
5947 uint trigx;
5948 uint trigy;
5949 uint maxws = sWidth<<12;
5950 uint maxhs = sHeight<<12;
5951
5952 for (int y=0; y<dHeight; y++) { // for each target scanline
5953 trigx = m21ydx;
5954 trigy = m22ydy;
5955 uchar *maxp = dptr + dbpl;
5956 if (depth != 1) {
5957 switch (depth) {
5958 case 8: // 8 bpp transform
5959 while (dptr < maxp) {
5960 if (trigx < maxws && trigy < maxhs)
5961 *dptr = *(sptr+sbpl*(trigy>>12)+(trigx>>12));
5962 trigx += m11;
5963 trigy += m12;
5964 dptr++;
5965 }
5966 break;
5967
5968 case 16: // 16 bpp transform
5969 while (dptr < maxp) {
5970 if (trigx < maxws && trigy < maxhs)
5971 *((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>12) +
5972 ((trigx>>12)<<1)));
5973 trigx += m11;
5974 trigy += m12;
5975 dptr++;
5976 dptr++;
5977 }
5978 break;
5979
5980 case 24: // 24 bpp transform
5981 while (dptr < maxp) {
5982 if (trigx < maxws && trigy < maxhs) {
5983 const uchar *p2 = sptr+sbpl*(trigy>>12) + ((trigx>>12)*3);
5984 dptr[0] = p2[0];
5985 dptr[1] = p2[1];
5986 dptr[2] = p2[2];
5987 }
5988 trigx += m11;
5989 trigy += m12;
5990 dptr += 3;
5991 }
5992 break;
5993
5994 case 32: // 32 bpp transform
5995 while (dptr < maxp) {
5996 if (trigx < maxws && trigy < maxhs)
5997 *((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>12) +
5998 ((trigx>>12)<<2)));
5999 trigx += m11;
6000 trigy += m12;
6001 dptr += 4;
6002 }
6003 break;
6004
6005 default: {
6006 return false;
6007 }
6008 }
6009 } else {
6010 switch (type) {
6011 case QT_XFORM_TYPE_MSBFIRST:
6012 while (dptr < maxp) {
6013 IWX_MSB(128);
6014 IWX_MSB(64);
6015 IWX_MSB(32);
6016 IWX_MSB(16);
6017 IWX_MSB(8);
6018 IWX_MSB(4);
6019 IWX_MSB(2);
6020 IWX_MSB(1);
6021 dptr++;
6022 }
6023 break;
6024 case QT_XFORM_TYPE_LSBFIRST:
6025 while (dptr < maxp) {
6026 IWX_LSB(1);
6027 IWX_LSB(2);
6028 IWX_LSB(4);
6029 IWX_LSB(8);
6030 IWX_LSB(16);
6031 IWX_LSB(32);
6032 IWX_LSB(64);
6033 IWX_LSB(128);
6034 dptr++;
6035 }
6036 break;
6037 # if defined(Q_WS_WIN)
6038 case QT_XFORM_TYPE_WINDOWSPIXMAP:
6039 while (dptr < maxp) {
6040 IWX_PIX(128);
6041 IWX_PIX(64);
6042 IWX_PIX(32);
6043 IWX_PIX(16);
6044 IWX_PIX(8);
6045 IWX_PIX(4);
6046 IWX_PIX(2);
6047 IWX_PIX(1);
6048 dptr++;
6049 }
6050 break;
6051 # endif
6052 }
6053 }
6054 m21ydx += m21;
6055 m22ydy += m22;
6056 dptr += p_inc;
6057 }
6058 return true;
6059 }
6060 #undef IWX_MSB
6061 #undef IWX_LSB
6062 #undef IWX_PIX
6063
6064 /*!
6065 \fn QImage QImage::xForm(const QMatrix &matrix) const
6066
6067 Use transformed() instead.
6068
6069 \oldcode
6070 QImage image;
6071 ...
6072 image.xForm(matrix);
6073 \newcode
6074 QImage image;
6075 ...
6076 image.transformed(matrix);
6077 \endcode
6078 */
6079
6080 /*! \obsolete
6081 Returns a number that identifies the contents of this
6082 QImage object. Distinct QImage objects can only have the same
6083 serial number if they refer to the same contents (but they don't
6084 have to).
6085
6086 Use cacheKey() instead.
6087
6088 \warning The serial number doesn't necessarily change when the
6089 image is altered. This means that it may be dangerous to use
6090 it as a cache key.
6091
6092 \sa operator==()
6093 */
6094
serialNumber() const6095 int QImage::serialNumber() const
6096 {
6097 if (!d)
6098 return 0;
6099 else
6100 return d->ser_no;
6101 }
6102
6103 /*!
6104 Returns a number that identifies the contents of this QImage
6105 object. Distinct QImage objects can only have the same key if they
6106 refer to the same contents.
6107
6108 The key will change when the image is altered.
6109 */
cacheKey() const6110 qint64 QImage::cacheKey() const
6111 {
6112 if (!d)
6113 return 0;
6114 else
6115 return (((qint64) d->ser_no) << 32) | ((qint64) d->detach_no);
6116 }
6117
6118 /*!
6119 \internal
6120
6121 Returns true if the image is detached; otherwise returns false.
6122
6123 \sa detach(), {Implicit Data Sharing}
6124 */
6125
isDetached() const6126 bool QImage::isDetached() const
6127 {
6128 return d && d->ref == 1;
6129 }
6130
6131
6132 /*!
6133 \obsolete
6134 Sets the alpha channel of this image to the given \a alphaChannel.
6135
6136 If \a alphaChannel is an 8 bit grayscale image, the intensity values are
6137 written into this buffer directly. Otherwise, \a alphaChannel is converted
6138 to 32 bit and the intensity of the RGB pixel values is used.
6139
6140 Note that the image will be converted to the Format_ARGB32_Premultiplied
6141 format if the function succeeds.
6142
6143 Use one of the composition modes in QPainter::CompositionMode instead.
6144
6145 \warning This function is expensive.
6146
6147 \sa alphaChannel(), {QImage#Image Transformations}{Image
6148 Transformations}, {QImage#Image Formats}{Image Formats}
6149 */
6150
setAlphaChannel(const QImage & alphaChannel)6151 void QImage::setAlphaChannel(const QImage &alphaChannel)
6152 {
6153 if (!d)
6154 return;
6155
6156 int w = d->width;
6157 int h = d->height;
6158
6159 if (w != alphaChannel.d->width || h != alphaChannel.d->height) {
6160 qWarning("QImage::setAlphaChannel: "
6161 "Alpha channel must have same dimensions as the target image");
6162 return;
6163 }
6164
6165 if (d->paintEngine && d->paintEngine->isActive()) {
6166 qWarning("QImage::setAlphaChannel: "
6167 "Unable to set alpha channel while image is being painted on");
6168 return;
6169 }
6170
6171 if (d->format == QImage::Format_ARGB32_Premultiplied)
6172 detach();
6173 else
6174 *this = convertToFormat(QImage::Format_ARGB32_Premultiplied);
6175
6176 if (isNull())
6177 return;
6178
6179 // Slight optimization since alphachannels are returned as 8-bit grays.
6180 if (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()) {
6181 const uchar *src_data = alphaChannel.d->data;
6182 const uchar *dest_data = d->data;
6183 for (int y=0; y<h; ++y) {
6184 const uchar *src = src_data;
6185 QRgb *dest = (QRgb *)dest_data;
6186 for (int x=0; x<w; ++x) {
6187 int alpha = *src;
6188 int destAlpha = qt_div_255(alpha * qAlpha(*dest));
6189 *dest = ((destAlpha << 24)
6190 | (qt_div_255(qRed(*dest) * alpha) << 16)
6191 | (qt_div_255(qGreen(*dest) * alpha) << 8)
6192 | (qt_div_255(qBlue(*dest) * alpha)));
6193 ++dest;
6194 ++src;
6195 }
6196 src_data += alphaChannel.d->bytes_per_line;
6197 dest_data += d->bytes_per_line;
6198 }
6199
6200 } else {
6201 const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32);
6202 if (sourceImage.isNull()) {
6203 qWarning("QImage::setAlphaChannel: out of memory");
6204 return;
6205 }
6206 const uchar *src_data = sourceImage.d->data;
6207 const uchar *dest_data = d->data;
6208 for (int y=0; y<h; ++y) {
6209 const QRgb *src = (const QRgb *) src_data;
6210 QRgb *dest = (QRgb *) dest_data;
6211 for (int x=0; x<w; ++x) {
6212 int alpha = qGray(*src);
6213 int destAlpha = qt_div_255(alpha * qAlpha(*dest));
6214 *dest = ((destAlpha << 24)
6215 | (qt_div_255(qRed(*dest) * alpha) << 16)
6216 | (qt_div_255(qGreen(*dest) * alpha) << 8)
6217 | (qt_div_255(qBlue(*dest) * alpha)));
6218 ++dest;
6219 ++src;
6220 }
6221 src_data += sourceImage.d->bytes_per_line;
6222 dest_data += d->bytes_per_line;
6223 }
6224 }
6225 }
6226
6227
6228 /*!
6229 \obsolete
6230
6231 Returns the alpha channel of the image as a new grayscale QImage in which
6232 each pixel's red, green, and blue values are given the alpha value of the
6233 original image. The color depth of the returned image is 8-bit.
6234
6235 You can see an example of use of this function in QPixmap's
6236 \l{QPixmap::}{alphaChannel()}, which works in the same way as
6237 this function on QPixmaps.
6238
6239 Most usecases for this function can be replaced with QPainter and
6240 using composition modes.
6241
6242 \warning This is an expensive function.
6243
6244 \sa setAlphaChannel(), hasAlphaChannel(),
6245 {QPixmap#Pixmap Information}{Pixmap},
6246 {QImage#Image Transformations}{Image Transformations}
6247 */
6248
alphaChannel() const6249 QImage QImage::alphaChannel() const
6250 {
6251 if (!d)
6252 return QImage();
6253
6254 int w = d->width;
6255 int h = d->height;
6256
6257 QImage image(w, h, Format_Indexed8);
6258 QIMAGE_SANITYCHECK_MEMORY(image);
6259 image.setColorCount(256);
6260
6261 // set up gray scale table.
6262 for (int i=0; i<256; ++i)
6263 image.setColor(i, qRgb(i, i, i));
6264
6265 if (!hasAlphaChannel()) {
6266 image.fill(255);
6267 return image;
6268 }
6269
6270 if (d->format == Format_Indexed8) {
6271 const uchar *src_data = d->data;
6272 uchar *dest_data = image.d->data;
6273 for (int y=0; y<h; ++y) {
6274 const uchar *src = src_data;
6275 uchar *dest = dest_data;
6276 for (int x=0; x<w; ++x) {
6277 *dest = qAlpha(d->colortable.at(*src));
6278 ++dest;
6279 ++src;
6280 }
6281 src_data += d->bytes_per_line;
6282 dest_data += image.d->bytes_per_line;
6283 }
6284 } else {
6285 QImage alpha32 = *this;
6286 if (d->format != Format_ARGB32 && d->format != Format_ARGB32_Premultiplied)
6287 alpha32 = convertToFormat(Format_ARGB32);
6288 QIMAGE_SANITYCHECK_MEMORY(alpha32);
6289
6290 const uchar *src_data = alpha32.d->data;
6291 uchar *dest_data = image.d->data;
6292 for (int y=0; y<h; ++y) {
6293 const QRgb *src = (const QRgb *) src_data;
6294 uchar *dest = dest_data;
6295 for (int x=0; x<w; ++x) {
6296 *dest = qAlpha(*src);
6297 ++dest;
6298 ++src;
6299 }
6300 src_data += alpha32.d->bytes_per_line;
6301 dest_data += image.d->bytes_per_line;
6302 }
6303 }
6304
6305 return image;
6306 }
6307
6308 /*!
6309 Returns true if the image has a format that respects the alpha
6310 channel, otherwise returns false.
6311
6312 \sa {QImage#Image Information}{Image Information}
6313 */
hasAlphaChannel() const6314 bool QImage::hasAlphaChannel() const
6315 {
6316 return d && (d->format == Format_ARGB32_Premultiplied
6317 || d->format == Format_ARGB32
6318 || d->format == Format_ARGB8565_Premultiplied
6319 || d->format == Format_ARGB8555_Premultiplied
6320 || d->format == Format_ARGB6666_Premultiplied
6321 || d->format == Format_ARGB4444_Premultiplied
6322 || (d->has_alpha_clut && (d->format == Format_Indexed8
6323 || d->format == Format_Mono
6324 || d->format == Format_MonoLSB)));
6325 }
6326
6327
6328 /*!
6329 \since 4.7
6330 Returns the number of bit planes in the image.
6331
6332 The number of bit planes is the number of bits of color and
6333 transparency information for each pixel. This is different from
6334 (i.e. smaller than) the depth when the image format contains
6335 unused bits.
6336
6337 \sa depth(), format(), {QImage#Image Formats}{Image Formats}
6338 */
bitPlaneCount() const6339 int QImage::bitPlaneCount() const
6340 {
6341 if (!d)
6342 return 0;
6343 int bpc = 0;
6344 switch (d->format) {
6345 case QImage::Format_Invalid:
6346 break;
6347 case QImage::Format_RGB32:
6348 bpc = 24;
6349 break;
6350 case QImage::Format_RGB666:
6351 bpc = 18;
6352 break;
6353 case QImage::Format_RGB555:
6354 bpc = 15;
6355 break;
6356 case QImage::Format_ARGB8555_Premultiplied:
6357 bpc = 23;
6358 break;
6359 case QImage::Format_RGB444:
6360 bpc = 12;
6361 break;
6362 default:
6363 bpc = qt_depthForFormat(d->format);
6364 break;
6365 }
6366 return bpc;
6367 }
6368
6369
6370 #ifdef QT3_SUPPORT
6371 #if defined(Q_WS_X11)
6372 QT_BEGIN_INCLUDE_NAMESPACE
6373 #include <private/qt_x11_p.h>
6374 QT_END_INCLUDE_NAMESPACE
6375 #endif
6376
systemBitOrder()6377 QImage::Endian QImage::systemBitOrder()
6378 {
6379 #if defined(Q_WS_X11)
6380 return BitmapBitOrder(X11->display) == MSBFirst ? BigEndian : LittleEndian;
6381 #else
6382 return BigEndian;
6383 #endif
6384 }
6385 #endif
6386
6387 /*!
6388 \fn QImage QImage::copy(const QRect &rect, Qt::ImageConversionFlags flags) const
6389 \compat
6390
6391 Use copy() instead.
6392 */
6393
6394 /*!
6395 \fn QImage QImage::copy(int x, int y, int w, int h, Qt::ImageConversionFlags flags) const
6396 \compat
6397
6398 Use copy() instead.
6399 */
6400
6401 /*!
6402 \fn QImage QImage::scaleWidth(int w) const
6403 \compat
6404
6405 Use scaledToWidth() instead.
6406 */
6407
6408 /*!
6409 \fn QImage QImage::scaleHeight(int h) const
6410 \compat
6411
6412 Use scaledToHeight() instead.
6413 */
6414
smoothScaled(const QImage & source,int w,int h)6415 static QImage smoothScaled(const QImage &source, int w, int h) {
6416 QImage src = source;
6417 if (src.format() == QImage::Format_ARGB32)
6418 src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
6419 else if (src.depth() < 32) {
6420 if (src.hasAlphaChannel())
6421 src = src.convertToFormat(QImage::Format_ARGB32_Premultiplied);
6422 else
6423 src = src.convertToFormat(QImage::Format_RGB32);
6424 }
6425
6426 return qSmoothScaleImage(src, w, h);
6427 }
6428
6429
rotated90(const QImage & image)6430 static QImage rotated90(const QImage &image) {
6431 QImage out(image.height(), image.width(), image.format());
6432 QIMAGE_SANITYCHECK_MEMORY(out);
6433 if (image.colorCount() > 0)
6434 out.setColorTable(image.colorTable());
6435 int w = image.width();
6436 int h = image.height();
6437 switch (image.format()) {
6438 case QImage::Format_RGB32:
6439 case QImage::Format_ARGB32:
6440 case QImage::Format_ARGB32_Premultiplied:
6441 qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()),
6442 w, h, image.bytesPerLine(),
6443 reinterpret_cast<quint32*>(out.bits()),
6444 out.bytesPerLine());
6445 break;
6446 case QImage::Format_RGB666:
6447 case QImage::Format_ARGB6666_Premultiplied:
6448 case QImage::Format_ARGB8565_Premultiplied:
6449 case QImage::Format_ARGB8555_Premultiplied:
6450 case QImage::Format_RGB888:
6451 qt_memrotate270(reinterpret_cast<const quint24*>(image.bits()),
6452 w, h, image.bytesPerLine(),
6453 reinterpret_cast<quint24*>(out.bits()),
6454 out.bytesPerLine());
6455 break;
6456 case QImage::Format_RGB555:
6457 case QImage::Format_RGB16:
6458 case QImage::Format_ARGB4444_Premultiplied:
6459 qt_memrotate270(reinterpret_cast<const quint16*>(image.bits()),
6460 w, h, image.bytesPerLine(),
6461 reinterpret_cast<quint16*>(out.bits()),
6462 out.bytesPerLine());
6463 break;
6464 case QImage::Format_Indexed8:
6465 qt_memrotate270(reinterpret_cast<const quint8*>(image.bits()),
6466 w, h, image.bytesPerLine(),
6467 reinterpret_cast<quint8*>(out.bits()),
6468 out.bytesPerLine());
6469 break;
6470 default:
6471 for (int y=0; y<h; ++y) {
6472 if (image.colorCount())
6473 for (int x=0; x<w; ++x)
6474 out.setPixel(h-y-1, x, image.pixelIndex(x, y));
6475 else
6476 for (int x=0; x<w; ++x)
6477 out.setPixel(h-y-1, x, image.pixel(x, y));
6478 }
6479 break;
6480 }
6481 return out;
6482 }
6483
6484
rotated180(const QImage & image)6485 static QImage rotated180(const QImage &image) {
6486 return image.mirrored(true, true);
6487 }
6488
6489
rotated270(const QImage & image)6490 static QImage rotated270(const QImage &image) {
6491 QImage out(image.height(), image.width(), image.format());
6492 QIMAGE_SANITYCHECK_MEMORY(out);
6493 if (image.colorCount() > 0)
6494 out.setColorTable(image.colorTable());
6495 int w = image.width();
6496 int h = image.height();
6497 switch (image.format()) {
6498 case QImage::Format_RGB32:
6499 case QImage::Format_ARGB32:
6500 case QImage::Format_ARGB32_Premultiplied:
6501 qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()),
6502 w, h, image.bytesPerLine(),
6503 reinterpret_cast<quint32*>(out.bits()),
6504 out.bytesPerLine());
6505 break;
6506 case QImage::Format_RGB666:
6507 case QImage::Format_ARGB6666_Premultiplied:
6508 case QImage::Format_ARGB8565_Premultiplied:
6509 case QImage::Format_ARGB8555_Premultiplied:
6510 case QImage::Format_RGB888:
6511 qt_memrotate90(reinterpret_cast<const quint24*>(image.bits()),
6512 w, h, image.bytesPerLine(),
6513 reinterpret_cast<quint24*>(out.bits()),
6514 out.bytesPerLine());
6515 break;
6516 case QImage::Format_RGB555:
6517 case QImage::Format_RGB16:
6518 case QImage::Format_ARGB4444_Premultiplied:
6519 qt_memrotate90(reinterpret_cast<const quint16*>(image.bits()),
6520 w, h, image.bytesPerLine(),
6521 reinterpret_cast<quint16*>(out.bits()),
6522 out.bytesPerLine());
6523 break;
6524 case QImage::Format_Indexed8:
6525 qt_memrotate90(reinterpret_cast<const quint8*>(image.bits()),
6526 w, h, image.bytesPerLine(),
6527 reinterpret_cast<quint8*>(out.bits()),
6528 out.bytesPerLine());
6529 break;
6530 default:
6531 for (int y=0; y<h; ++y) {
6532 if (image.colorCount())
6533 for (int x=0; x<w; ++x)
6534 out.setPixel(y, w-x-1, image.pixelIndex(x, y));
6535 else
6536 for (int x=0; x<w; ++x)
6537 out.setPixel(y, w-x-1, image.pixel(x, y));
6538 }
6539 break;
6540 }
6541 return out;
6542 }
6543
6544 /*!
6545 Returns a copy of the image that is transformed using the given
6546 transformation \a matrix and transformation \a mode.
6547
6548 The transformation \a matrix is internally adjusted to compensate
6549 for unwanted translation; i.e. the image produced is the smallest
6550 image that contains all the transformed points of the original
6551 image. Use the trueMatrix() function to retrieve the actual matrix
6552 used for transforming an image.
6553
6554 Unlike the other overload, this function can be used to perform perspective
6555 transformations on images.
6556
6557 \sa trueMatrix(), {QImage#Image Transformations}{Image
6558 Transformations}
6559 */
6560
transformed(const QTransform & matrix,Qt::TransformationMode mode) const6561 QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode ) const
6562 {
6563 if (!d)
6564 return QImage();
6565
6566 // source image data
6567 int ws = width();
6568 int hs = height();
6569
6570 // target image data
6571 int wd;
6572 int hd;
6573
6574 // compute size of target image
6575 QTransform mat = trueMatrix(matrix, ws, hs);
6576 bool complex_xform = false;
6577 bool scale_xform = false;
6578 if (mat.type() <= QTransform::TxScale) {
6579 if (mat.type() == QTransform::TxNone) // identity matrix
6580 return *this;
6581 else if (mat.m11() == -1. && mat.m22() == -1.)
6582 return rotated180(*this);
6583
6584 if (mode == Qt::FastTransformation) {
6585 hd = qRound(qAbs(mat.m22()) * hs);
6586 wd = qRound(qAbs(mat.m11()) * ws);
6587 } else {
6588 hd = int(qAbs(mat.m22()) * hs + 0.9999);
6589 wd = int(qAbs(mat.m11()) * ws + 0.9999);
6590 }
6591 scale_xform = true;
6592 } else {
6593 if (mat.type() <= QTransform::TxRotate && mat.m11() == 0 && mat.m22() == 0) {
6594 if (mat.m12() == 1. && mat.m21() == -1.)
6595 return rotated90(*this);
6596 else if (mat.m12() == -1. && mat.m21() == 1.)
6597 return rotated270(*this);
6598 }
6599
6600 QPolygonF a(QRectF(0, 0, ws, hs));
6601 a = mat.map(a);
6602 QRect r = a.boundingRect().toAlignedRect();
6603 wd = r.width();
6604 hd = r.height();
6605 complex_xform = true;
6606 }
6607
6608 if (wd == 0 || hd == 0)
6609 return QImage();
6610
6611 // Make use of the optimized algorithm when we're scaling
6612 if (scale_xform && mode == Qt::SmoothTransformation) {
6613 if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip
6614 return smoothScaled(mirrored(true, true), wd, hd);
6615 } else if (mat.m11() < 0.0F) { // horizontal flip
6616 return smoothScaled(mirrored(true, false), wd, hd);
6617 } else if (mat.m22() < 0.0F) { // vertical flip
6618 return smoothScaled(mirrored(false, true), wd, hd);
6619 } else { // no flipping
6620 return smoothScaled(*this, wd, hd);
6621 }
6622 }
6623
6624 int bpp = depth();
6625
6626 int sbpl = bytesPerLine();
6627 const uchar *sptr = bits();
6628
6629 QImage::Format target_format = d->format;
6630
6631 if (complex_xform || mode == Qt::SmoothTransformation) {
6632 if (d->format < QImage::Format_RGB32 || !hasAlphaChannel()) {
6633 switch(d->format) {
6634 case QImage::Format_RGB16:
6635 target_format = Format_ARGB8565_Premultiplied;
6636 break;
6637 case QImage::Format_RGB555:
6638 target_format = Format_ARGB8555_Premultiplied;
6639 break;
6640 case QImage::Format_RGB666:
6641 target_format = Format_ARGB6666_Premultiplied;
6642 break;
6643 case QImage::Format_RGB444:
6644 target_format = Format_ARGB4444_Premultiplied;
6645 break;
6646 default:
6647 target_format = Format_ARGB32_Premultiplied;
6648 break;
6649 }
6650 }
6651 }
6652
6653 QImage dImage(wd, hd, target_format);
6654 QIMAGE_SANITYCHECK_MEMORY(dImage);
6655
6656 if (target_format == QImage::Format_MonoLSB
6657 || target_format == QImage::Format_Mono
6658 || target_format == QImage::Format_Indexed8) {
6659 dImage.d->colortable = d->colortable;
6660 dImage.d->has_alpha_clut = d->has_alpha_clut | complex_xform;
6661 }
6662
6663 dImage.d->dpmx = dotsPerMeterX();
6664 dImage.d->dpmy = dotsPerMeterY();
6665
6666 switch (bpp) {
6667 // initizialize the data
6668 case 8:
6669 if (dImage.d->colortable.size() < 256) {
6670 // colors are left in the color table, so pick that one as transparent
6671 dImage.d->colortable.append(0x0);
6672 memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.byteCount());
6673 } else {
6674 memset(dImage.bits(), 0, dImage.byteCount());
6675 }
6676 break;
6677 case 1:
6678 case 16:
6679 case 24:
6680 case 32:
6681 memset(dImage.bits(), 0x00, dImage.byteCount());
6682 break;
6683 }
6684
6685 if (target_format >= QImage::Format_RGB32) {
6686 QPainter p(&dImage);
6687 if (mode == Qt::SmoothTransformation) {
6688 p.setRenderHint(QPainter::Antialiasing);
6689 p.setRenderHint(QPainter::SmoothPixmapTransform);
6690 }
6691 p.setTransform(mat);
6692 p.drawImage(QPoint(0, 0), *this);
6693 } else {
6694 bool invertible;
6695 mat = mat.inverted(&invertible); // invert matrix
6696 if (!invertible) // error, return null image
6697 return QImage();
6698
6699 // create target image (some of the code is from QImage::copy())
6700 int type = format() == Format_Mono ? QT_XFORM_TYPE_MSBFIRST : QT_XFORM_TYPE_LSBFIRST;
6701 int dbpl = dImage.bytesPerLine();
6702 qt_xForm_helper(mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl, ws, hs);
6703 }
6704 return dImage;
6705 }
6706
6707 /*!
6708 \fn QTransform QImage::trueMatrix(const QTransform &matrix, int width, int height)
6709
6710 Returns the actual matrix used for transforming an image with the
6711 given \a width, \a height and \a matrix.
6712
6713 When transforming an image using the transformed() function, the
6714 transformation matrix is internally adjusted to compensate for
6715 unwanted translation, i.e. transformed() returns the smallest
6716 image containing all transformed points of the original image.
6717 This function returns the modified matrix, which maps points
6718 correctly from the original image into the new image.
6719
6720 Unlike the other overload, this function creates transformation
6721 matrices that can be used to perform perspective
6722 transformations on images.
6723
6724 \sa transformed(), {QImage#Image Transformations}{Image
6725 Transformations}
6726 */
6727
trueMatrix(const QTransform & matrix,int w,int h)6728 QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h)
6729 {
6730 const QRectF rect(0, 0, w, h);
6731 const QRect mapped = matrix.mapRect(rect).toAlignedRect();
6732 const QPoint delta = mapped.topLeft();
6733 return matrix * QTransform().translate(-delta.x(), -delta.y());
6734 }
6735
convertInPlace(QImage::Format newFormat,Qt::ImageConversionFlags flags)6736 bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags)
6737 {
6738 if (format == newFormat)
6739 return true;
6740
6741 // No in-place conversion if we have to detach
6742 if (ref > 1)
6743 return false;
6744
6745 const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat];
6746 InPlace_Image_Converter converter = *converterPtr;
6747 if (converter)
6748 return converter(this, flags);
6749 else
6750 return false;
6751 }
6752
6753 /*!
6754 \typedef QImage::DataPtr
6755 \internal
6756 */
6757
6758 /*!
6759 \fn DataPtr & QImage::data_ptr()
6760 \internal
6761 */
6762
6763 QT_END_NAMESPACE
6764