image/qimage.cpp

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

Generated by Squish Coco Non-Commercial