Coverage Report

Created: 2026-05-31 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/image/qpixmap.cpp
Line
Count
Source
1
// Copyright (C) 2021 The Qt Company Ltd.
2
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
// Qt-Security score:significant reason:default
4
5
#include <qglobal.h>
6
7
#include "qpixmap.h"
8
#include <qpa/qplatformpixmap.h>
9
#include "qimagepixmapcleanuphooks_p.h"
10
11
#include "qbitmap.h"
12
#include "qimage.h"
13
#include "qpainter.h"
14
#include "qdatastream.h"
15
#include "qbuffer.h"
16
#include <private/qguiapplication_p.h>
17
#include "qevent.h"
18
#include "qfile.h"
19
#include "qfileinfo.h"
20
#include "qpixmapcache.h"
21
#include "qdatetime.h"
22
#include "qimagereader.h"
23
#include "qimagewriter.h"
24
#include "qpaintengine.h"
25
#include "qscreen.h"
26
#include "qthread.h"
27
#include "qdebug.h"
28
29
#include <qpa/qplatformintegration.h>
30
31
#include "qpixmap_raster_p.h"
32
#include "private/qhexstring_p.h"
33
34
#include <qtgui_tracepoints_p.h>
35
36
#include <memory>
37
38
QT_BEGIN_NAMESPACE
39
40
using namespace Qt::StringLiterals;
41
42
Q_TRACE_PARAM_REPLACE(Qt::AspectRatioMode, int);
43
Q_TRACE_PARAM_REPLACE(Qt::TransformationMode, int);
44
45
// MSVC 19.28 does show spurious warning "C4723: potential divide by 0" for code that divides
46
// by height() in release builds. Anyhow, all the code paths in this file are only executed
47
// for valid QPixmap's, where height() cannot be 0. Therefore disable the warning.
48
QT_WARNING_DISABLE_MSVC(4723)
49
50
static bool qt_pixmap_thread_test()
51
3.22M
{
52
3.22M
    if (!QCoreApplication::instanceExists()) {
53
0
        qFatal("QPixmap: Must construct a QGuiApplication before a QPixmap");
54
0
        return false;
55
0
    }
56
3.22M
    if (QGuiApplicationPrivate::instance()
57
3.22M
        && !QThread::isMainThread()
58
0
        && !QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::ThreadedPixmaps)) {
59
0
        qWarning("QPixmap: It is not safe to use pixmaps outside the GUI thread on this platform");
60
0
        return false;
61
0
    }
62
3.22M
    return true;
63
3.22M
}
64
65
void QPixmap::doInit(int w, int h, int type)
66
3.22M
{
67
3.22M
    if ((w > 0 && h > 0) || type == QPlatformPixmap::BitmapType)
68
18.6k
        data = QPlatformPixmap::create(w, h, (QPlatformPixmap::PixelType) type);
69
3.20M
    else
70
3.20M
        data = nullptr;
71
3.22M
}
72
73
/*!
74
    Constructs a null pixmap.
75
76
    \sa isNull()
77
*/
78
79
QPixmap::QPixmap()
80
3.20M
    : QPaintDevice()
81
3.20M
{
82
3.20M
    (void) qt_pixmap_thread_test();
83
3.20M
    doInit(0, 0, QPlatformPixmap::PixmapType);
84
3.20M
}
85
86
/*!
87
    \fn QPixmap::QPixmap(int width, int height)
88
89
    Constructs a pixmap with the given \a width and \a height. If
90
    either \a width or \a height is zero, a null pixmap is
91
    constructed.
92
93
    \warning This will create a QPixmap with uninitialized data. Call
94
    fill() to fill the pixmap with an appropriate color before drawing
95
    onto it with QPainter.
96
97
    \sa isNull()
98
*/
99
100
QPixmap::QPixmap(int w, int h)
101
0
    : QPixmap(QSize(w, h))
102
0
{
103
0
}
104
105
/*!
106
    \overload
107
108
    Constructs a pixmap of the given \a size.
109
110
    \warning This will create a QPixmap with uninitialized data. Call
111
    fill() to fill the pixmap with an appropriate color before drawing
112
    onto it with QPainter.
113
*/
114
115
QPixmap::QPixmap(const QSize &size)
116
18.6k
    : QPixmap(size, QPlatformPixmap::PixmapType)
117
18.6k
{
118
18.6k
}
119
120
/*!
121
  \internal
122
*/
123
QPixmap::QPixmap(const QSize &s, int type)
124
18.6k
{
125
18.6k
    if (!qt_pixmap_thread_test())
126
0
        doInit(0, 0, static_cast<QPlatformPixmap::PixelType>(type));
127
18.6k
    else
128
18.6k
        doInit(s.width(), s.height(), static_cast<QPlatformPixmap::PixelType>(type));
129
18.6k
}
130
131
/*!
132
    \internal
133
*/
134
QPixmap::QPixmap(QPlatformPixmap *d)
135
0
    : QPaintDevice(), data(d)
136
0
{
137
0
}
138
139
/*!
140
    Constructs a pixmap from the file with the given \a fileName. If the
141
    file does not exist or is of an unknown format, the pixmap becomes a
142
    null pixmap.
143
144
    The loader attempts to read the pixmap using the specified \a
145
    format. If the \a format is not specified (which is the default),
146
    the loader probes the file for a header to guess the file format.
147
148
    The file name can either refer to an actual file on disk or to
149
    one of the application's embedded resources. See the
150
    \l{resources.html}{Resource System} overview for details on how
151
    to embed images and other resource files in the application's
152
    executable.
153
154
    If the image needs to be modified to fit in a lower-resolution
155
    result (e.g. converting from 32-bit to 8-bit), use the \a
156
    flags to control the conversion.
157
158
    The \a fileName, \a format and \a flags parameters are
159
    passed on to load(). This means that the data in \a fileName is
160
    not compiled into the binary. If \a fileName contains a relative
161
    path (e.g. the filename only) the relevant file must be found
162
    relative to the runtime working directory.
163
164
    \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
165
    Image Files}
166
*/
167
168
QPixmap::QPixmap(const QString& fileName, const char *format, Qt::ImageConversionFlags flags)
169
0
    : QPaintDevice()
170
0
{
171
0
    doInit(0, 0, QPlatformPixmap::PixmapType);
172
0
    if (!qt_pixmap_thread_test())
173
0
        return;
174
175
0
    load(fileName, format, flags);
176
0
}
177
178
/*!
179
    Constructs a pixmap that is a copy of the given \a pixmap.
180
181
    \sa copy()
182
*/
183
184
QPixmap::QPixmap(const QPixmap &pixmap)
185
0
    : QPaintDevice()
186
0
{
187
0
    if (!qt_pixmap_thread_test()) {
188
0
        doInit(0, 0, QPlatformPixmap::PixmapType);
189
0
        return;
190
0
    }
191
0
    if (pixmap.paintingActive()) {                // make a deep copy
192
0
        pixmap.copy().swap(*this);
193
0
    } else {
194
0
        data = pixmap.data;
195
0
    }
196
0
}
197
198
/*! \fn QPixmap::QPixmap(QPixmap &&other)
199
    Move-constructs a QPixmap instance from \a other.
200
201
    \sa swap() operator=(QPixmap&&)
202
*/
203
204
QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QPlatformPixmap)
205
206
/*!
207
    Constructs a pixmap from the given \a xpm data, which must be a
208
    valid XPM image.
209
210
    Errors are silently ignored.
211
212
    Note that it's possible to squeeze the XPM variable a little bit
213
    by using an unusual declaration:
214
215
    \snippet code/src_gui_image_qimage.cpp 2
216
217
    The extra \c const makes the entire definition read-only, which is
218
    slightly more efficient (for example, when the code is in a shared
219
    library) and ROMable when the application is to be stored in ROM.
220
*/
221
#ifndef QT_NO_IMAGEFORMAT_XPM
222
QPixmap::QPixmap(const char * const xpm[])
223
0
    : QPaintDevice()
224
0
{
225
0
    doInit(0, 0, QPlatformPixmap::PixmapType);
226
0
    if (!xpm)
227
0
        return;
228
229
0
    QImage image(xpm);
230
0
    if (!image.isNull()) {
231
0
        if (data && data->pixelType() == QPlatformPixmap::BitmapType)
232
0
            *this = QBitmap::fromImage(std::move(image));
233
0
        else
234
0
            *this = fromImage(std::move(image));
235
0
    }
236
0
}
237
#endif
238
239
240
/*!
241
    Destroys the pixmap.
242
*/
243
244
QPixmap::~QPixmap()
245
3.24M
{
246
3.24M
    Q_ASSERT(!data || data->ref.loadRelaxed() >= 1); // Catch if ref-counting changes again
247
3.24M
}
248
249
/*!
250
  \internal
251
*/
252
int QPixmap::devType() const
253
130k
{
254
130k
    return QInternal::Pixmap;
255
130k
}
256
257
/*!
258
    \fn QPixmap QPixmap::copy(int x, int y, int width, int height) const
259
    \overload
260
261
    Returns a deep copy of the subset of the pixmap that is specified
262
    by the rectangle QRect( \a x, \a y, \a width, \a height).
263
*/
264
265
/*!
266
    \fn QPixmap QPixmap::copy(const QRect &rectangle) const
267
268
    Returns a deep copy of the subset of the pixmap that is specified
269
    by the given \a rectangle. For more information on deep copies,
270
    see the \l {Implicit Data Sharing} documentation.
271
272
    If the given \a rectangle is empty, the whole image is copied.
273
274
    \sa operator=(), QPixmap(), {QPixmap#Pixmap
275
    Transformations}{Pixmap Transformations}
276
*/
277
QPixmap QPixmap::copy(const QRect &rect) const
278
0
{
279
0
    if (isNull())
280
0
        return QPixmap();
281
282
0
    QRect r(0, 0, width(), height());
283
0
    if (!rect.isEmpty())
284
0
        r = r.intersected(rect);
285
286
0
    QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
287
0
    d->copy(data.data(), r);
288
0
    return QPixmap(d);
289
0
}
290
291
/*!
292
    \fn QPixmap::scroll(int dx, int dy, int x, int y, int width, int height, QRegion *exposed)
293
294
    This convenience function is equivalent to calling QPixmap::scroll(\a dx,
295
    \a dy, QRect(\a x, \a y, \a width, \a height), \a exposed).
296
297
    \sa QWidget::scroll(), QGraphicsItem::scroll()
298
*/
299
300
/*!
301
    Scrolls the area \a rect of this pixmap by (\a dx, \a dy). The exposed
302
    region is left unchanged. You can optionally pass a pointer to an empty
303
    QRegion to get the region that is \a exposed by the scroll operation.
304
305
    \snippet code/src_gui_image_qpixmap.cpp 2
306
307
    You cannot scroll while there is an active painter on the pixmap.
308
309
    \sa QWidget::scroll(), QGraphicsItem::scroll()
310
*/
311
void QPixmap::scroll(int dx, int dy, const QRect &rect, QRegion *exposed)
312
0
{
313
0
    if (isNull() || (dx == 0 && dy == 0))
314
0
        return;
315
0
    QRect dest = rect & this->rect();
316
0
    QRect src = dest.translated(-dx, -dy) & dest;
317
0
    if (src.isEmpty()) {
318
0
        if (exposed)
319
0
            *exposed += dest;
320
0
        return;
321
0
    }
322
323
0
    detach();
324
325
0
    if (!data->scroll(dx, dy, src)) {
326
        // Fallback
327
0
        QPixmap pix = *this;
328
0
        QPainter painter(&pix);
329
0
        painter.setCompositionMode(QPainter::CompositionMode_Source);
330
0
        painter.drawPixmap(src.translated(dx, dy), *this, src);
331
0
        painter.end();
332
0
        *this = pix;
333
0
    }
334
335
0
    if (exposed) {
336
0
        *exposed += dest;
337
0
        *exposed -= src.translated(dx, dy);
338
0
    }
339
0
}
340
341
/*!
342
    Assigns the given \a pixmap to this pixmap and returns a reference
343
    to this pixmap.
344
345
    \sa copy(), QPixmap()
346
*/
347
348
QPixmap &QPixmap::operator=(const QPixmap &pixmap)
349
0
{
350
0
    if (paintingActive()) {
351
0
        qWarning("QPixmap::operator=: Cannot assign to pixmap during painting");
352
0
        return *this;
353
0
    }
354
0
    if (pixmap.paintingActive()) {                // make a deep copy
355
0
        pixmap.copy().swap(*this);
356
0
    } else {
357
0
        data = pixmap.data;
358
0
    }
359
0
    return *this;
360
0
}
361
362
/*!
363
    \fn QPixmap &QPixmap::operator=(QPixmap &&other)
364
365
    Move-assigns \a other to this QPixmap instance.
366
367
    \since 5.2
368
*/
369
370
/*!
371
    \fn void QPixmap::swap(QPixmap &other)
372
    \memberswap{pixmap}
373
*/
374
375
/*!
376
   Returns the pixmap as a QVariant.
377
*/
378
QPixmap::operator QVariant() const
379
0
{
380
0
    return QVariant::fromValue(*this);
381
0
}
382
383
/*!
384
    \fn bool QPixmap::operator!() const
385
386
    Returns \c true if this is a null pixmap; otherwise returns \c false.
387
388
    \sa isNull()
389
*/
390
391
/*!
392
    Converts the pixmap to a QImage. Returns a null image if the
393
    conversion fails.
394
395
    If the pixmap has 1-bit depth, the returned image will also be 1
396
    bit deep. Images with more bits will be returned in a format
397
    closely represents the underlying system. Usually this will be
398
    QImage::Format_ARGB32_Premultiplied for pixmaps with an alpha and
399
    QImage::Format_RGB32 or QImage::Format_RGB16 for pixmaps without
400
    alpha.
401
402
    Note that for the moment, alpha masks on monochrome images are
403
    ignored.
404
405
    \sa fromImage(), {QImage#Image Formats}{Image Formats}
406
*/
407
QImage QPixmap::toImage() const
408
18.6k
{
409
18.6k
    if (isNull())
410
0
        return QImage();
411
412
18.6k
    return data->toImage();
413
18.6k
}
414
415
/*!
416
    \fn QTransform QPixmap::trueMatrix(const QTransform &matrix, int width, int height)
417
418
    Returns the actual matrix used for transforming a pixmap with the
419
    given \a width, \a height and \a matrix.
420
421
    When transforming a pixmap using the transformed() function, the
422
    transformation matrix is internally adjusted to compensate for
423
    unwanted translation, i.e. transformed() returns the smallest
424
    pixmap containing all transformed points of the original
425
    pixmap. This function returns the modified matrix, which maps
426
    points correctly from the original pixmap into the new pixmap.
427
428
    \sa transformed(), {QPixmap#Pixmap Transformations}{Pixmap
429
    Transformations}
430
*/
431
QTransform QPixmap::trueMatrix(const QTransform &m, int w, int h)
432
0
{
433
0
    return QImage::trueMatrix(m, w, h);
434
0
}
435
436
/*!
437
    \fn bool QPixmap::isQBitmap() const
438
439
    Returns \c true if this is a QBitmap; otherwise returns \c false.
440
*/
441
442
bool QPixmap::isQBitmap() const
443
0
{
444
0
    return data && data->type == QPlatformPixmap::BitmapType;
445
0
}
446
447
/*!
448
    \fn bool QPixmap::isNull() const
449
450
    Returns \c true if this is a null pixmap; otherwise returns \c false.
451
452
    A null pixmap has zero width, zero height and no contents. You
453
    cannot draw in a null pixmap.
454
*/
455
bool QPixmap::isNull() const
456
74.5k
{
457
74.5k
    return !data || data->isNull();
458
74.5k
}
459
460
/*!
461
    \fn int QPixmap::width() const
462
463
    Returns the width of the pixmap.
464
465
    \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
466
*/
467
int QPixmap::width() const
468
0
{
469
0
    return data ? data->width() : 0;
470
0
}
471
472
/*!
473
    \fn int QPixmap::height() const
474
475
    Returns the height of the pixmap.
476
477
    \sa size(), {QPixmap#Pixmap Information}{Pixmap Information}
478
*/
479
int QPixmap::height() const
480
0
{
481
0
    return data ? data->height() : 0;
482
0
}
483
484
/*!
485
    \fn QSize QPixmap::size() const
486
487
    Returns the size of the pixmap.
488
489
    \sa width(), height(), {QPixmap#Pixmap Information}{Pixmap
490
    Information}
491
*/
492
QSize QPixmap::size() const
493
18.6k
{
494
18.6k
    return data ? QSize(data->width(), data->height()) : QSize(0, 0);
495
18.6k
}
496
497
/*!
498
    \fn QRect QPixmap::rect() const
499
500
    Returns the pixmap's enclosing rectangle.
501
502
    \sa {QPixmap#Pixmap Information}{Pixmap Information}
503
*/
504
QRect QPixmap::rect() const
505
0
{
506
0
    return data ? QRect(0, 0, data->width(), data->height()) : QRect();
507
0
}
508
509
/*!
510
    \fn int QPixmap::depth() const
511
512
    Returns the depth of the pixmap.
513
514
    The pixmap depth is also called bits per pixel (bpp) or bit planes
515
    of a pixmap. A null pixmap has depth 0.
516
517
    \sa defaultDepth(), {QPixmap#Pixmap Information}{Pixmap
518
    Information}
519
*/
520
int QPixmap::depth() const
521
18.6k
{
522
18.6k
    return data ? data->depth() : 0;
523
18.6k
}
524
525
/*!
526
    Sets a mask bitmap.
527
528
    This function merges the \a mask with the pixmap's alpha channel. A pixel
529
    value of 1 on the mask means the pixmap's pixel is unchanged; a value of 0
530
    means the pixel is transparent. The mask must have the same size as this
531
    pixmap.
532
533
    Setting a null mask resets the mask, leaving the previously transparent
534
    pixels black. The effect of this function is undefined when the pixmap is
535
    being painted on.
536
537
    \warning This is potentially an expensive operation.
538
539
    \sa mask(), {QPixmap#Pixmap Transformations}{Pixmap Transformations},
540
    QBitmap
541
*/
542
void QPixmap::setMask(const QBitmap &mask)
543
0
{
544
0
    if (paintingActive()) {
545
0
        qWarning("QPixmap::setMask: Cannot set mask while pixmap is being painted on");
546
0
        return;
547
0
    }
548
549
0
    if (!mask.isNull() && mask.size() != size()) {
550
0
        qWarning("QPixmap::setMask() mask size differs from pixmap size");
551
0
        return;
552
0
    }
553
554
0
    if (isNull())
555
0
        return;
556
557
0
    if (static_cast<const QPixmap &>(mask).data == data) // trying to selfmask
558
0
       return;
559
560
0
    detach();
561
0
    data->setMask(mask);
562
0
}
563
564
/*!
565
    Returns the device pixel ratio for the pixmap. This is the
566
    ratio between \e{device pixels} and \e{device independent pixels}.
567
568
    Use this function when calculating layout geometry based on
569
    the pixmap size: QSize layoutSize = image.size() / image.devicePixelRatio()
570
571
    The default value is 1.0.
572
573
    \sa setDevicePixelRatio(), QImageReader
574
*/
575
qreal QPixmap::devicePixelRatio() const
576
0
{
577
0
    if (!data)
578
0
        return qreal(1.0);
579
0
    return data->devicePixelRatio();
580
0
}
581
582
/*!
583
    Sets the device pixel ratio for the pixmap. This is the
584
    ratio between image pixels and device-independent pixels.
585
586
    The default \a scaleFactor is 1.0. Setting it to something else has
587
    two effects:
588
589
    QPainters that are opened on the pixmap will be scaled. For
590
    example, painting on a 200x200 image if with a ratio of 2.0
591
    will result in effective (device-independent) painting bounds
592
    of 100x100.
593
594
    Code paths in Qt that calculate layout geometry based on the
595
    pixmap size will take the ratio into account:
596
    QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio()
597
    The net effect of this is that the pixmap is displayed as
598
    high-DPI pixmap rather than a large pixmap
599
    (see \l{Drawing High Resolution Versions of Pixmaps and Images}).
600
601
    \sa devicePixelRatio(), deviceIndependentSize()
602
*/
603
void QPixmap::setDevicePixelRatio(qreal scaleFactor)
604
18.6k
{
605
18.6k
    if (isNull())
606
0
        return;
607
608
18.6k
    if (scaleFactor == data->devicePixelRatio())
609
18.6k
        return;
610
611
0
    detach();
612
0
    data->setDevicePixelRatio(scaleFactor);
613
0
}
614
615
/*!
616
    Returns the size of the pixmap in device independent pixels.
617
618
    This value should be used when using the pixmap size in user interface
619
    size calculations.
620
621
    The return value is equivalent to pixmap.size() / pixmap.devicePixelRatio().
622
623
    \since 6.2
624
*/
625
QSizeF QPixmap::deviceIndependentSize() const
626
0
{
627
0
    if (!data)
628
0
        return QSizeF(0, 0);
629
0
    return QSizeF(data->width(), data->height()) / data->devicePixelRatio();
630
0
}
631
632
#ifndef QT_NO_IMAGE_HEURISTIC_MASK
633
/*!
634
    Creates and returns a heuristic mask for this pixmap.
635
636
    The function works by selecting a color from one of the corners
637
    and then chipping away pixels of that color, starting at all the
638
    edges.  If \a clipTight is true (the default) the mask is just
639
    large enough to cover the pixels; otherwise, the mask is larger
640
    than the data pixels.
641
642
    The mask may not be perfect but it should be reasonable, so you
643
    can do things such as the following:
644
645
    \snippet code/src_gui_image_qpixmap.cpp 1
646
647
    This function is slow because it involves converting to/from a
648
    QImage, and non-trivial computations.
649
650
    \sa QImage::createHeuristicMask(), createMaskFromColor()
651
*/
652
QBitmap QPixmap::createHeuristicMask(bool clipTight) const
653
0
{
654
0
    QBitmap m = QBitmap::fromImage(toImage().createHeuristicMask(clipTight));
655
0
    return m;
656
0
}
657
#endif
658
659
/*!
660
    Creates and returns a mask for this pixmap based on the given \a
661
    maskColor. If the \a mode is Qt::MaskInColor, all pixels matching the
662
    maskColor will be transparent. If \a mode is Qt::MaskOutColor, all pixels
663
    matching the maskColor will be opaque.
664
665
    This function is slow because it involves converting to/from a
666
    QImage.
667
668
    \sa createHeuristicMask(), QImage::createMaskFromColor()
669
*/
670
QBitmap QPixmap::createMaskFromColor(const QColor &maskColor, Qt::MaskMode mode) const
671
0
{
672
0
    QImage image = toImage().convertToFormat(QImage::Format_ARGB32);
673
0
    return QBitmap::fromImage(std::move(image).createMaskFromColor(maskColor.rgba(), mode));
674
0
}
675
676
/*!
677
    Loads a pixmap from the file with the given \a fileName. Returns
678
    true if the pixmap was successfully loaded; otherwise invalidates
679
    the pixmap and returns \c false.
680
681
    The loader attempts to read the pixmap using the specified \a
682
    format. If the \a format is not specified (which is the default),
683
    the loader probes the file for a header to guess the file format.
684
685
    The file name can either refer to an actual file on disk or to one
686
    of the application's embedded resources. See the
687
    \l{resources.html}{Resource System} overview for details on how to
688
    embed pixmaps and other resource files in the application's
689
    executable.
690
691
    If the data needs to be modified to fit in a lower-resolution
692
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
693
    control the conversion.
694
695
    Note that QPixmaps are automatically added to the QPixmapCache
696
    when loaded from a file in main thread; the key used is internal
697
    and cannot be acquired.
698
699
    \sa loadFromData(), {QPixmap#Reading and Writing Image
700
    Files}{Reading and Writing Image Files}
701
*/
702
703
bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConversionFlags flags)
704
0
{
705
0
    if (!fileName.isEmpty()) {
706
707
0
        QFileInfo info(fileName);
708
        // Note: If no extension is provided, we try to match the
709
        // file against known plugin extensions
710
0
        if (info.completeSuffix().isEmpty() || info.exists()) {
711
0
            const bool inGuiThread = qApp->thread() == QThread::currentThread();
712
713
0
            QString key = "qt_pixmap"_L1
714
0
                    % info.absoluteFilePath()
715
0
                    % HexString<uint>(info.lastModified(QTimeZone::UTC).toSecsSinceEpoch())
716
0
                    % HexString<quint64>(info.size())
717
0
                    % HexString<uint>(data ? data->pixelType() : QPlatformPixmap::PixmapType);
718
719
0
            if (inGuiThread && QPixmapCache::find(key, this))
720
0
                return true;
721
722
0
            data = QPlatformPixmap::create(0, 0, data ? data->pixelType() : QPlatformPixmap::PixmapType);
723
724
0
            if (data->fromFile(fileName, format, flags)) {
725
0
                if (inGuiThread)
726
0
                    QPixmapCache::insert(key, *this);
727
0
                return true;
728
0
            }
729
0
        }
730
0
    }
731
732
0
    if (!isNull()) {
733
0
        if (isQBitmap())
734
0
            *this = QBitmap();
735
0
        else
736
0
            data.reset();
737
0
    }
738
0
    return false;
739
0
}
740
741
/*!
742
    \fn bool QPixmap::loadFromData(const uchar *data, uint len, const char *format, Qt::ImageConversionFlags flags)
743
744
    Loads a pixmap from the \a len first bytes of the given binary \a
745
    data.  Returns \c true if the pixmap was loaded successfully;
746
    otherwise invalidates the pixmap and returns \c false.
747
748
    The loader attempts to read the pixmap using the specified \a
749
    format. If the \a format is not specified (which is the default),
750
    the loader probes the file for a header to guess the file format.
751
752
    If the data needs to be modified to fit in a lower-resolution
753
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
754
    control the conversion.
755
756
    \sa load(), {QPixmap#Reading and Writing Image Files}{Reading and
757
    Writing Image Files}
758
*/
759
760
bool QPixmap::loadFromData(const uchar *buf, uint len, const char *format, Qt::ImageConversionFlags flags)
761
0
{
762
0
    if (len == 0 || buf == nullptr) {
763
0
        data.reset();
764
0
        return false;
765
0
    }
766
767
0
    data = QPlatformPixmap::create(0, 0, QPlatformPixmap::PixmapType);
768
769
0
    if (data->fromData(buf, len, format, flags))
770
0
        return true;
771
772
0
    data.reset();
773
0
    return false;
774
0
}
775
776
/*!
777
    \fn bool QPixmap::loadFromData(const QByteArray &data, const char *format, Qt::ImageConversionFlags flags)
778
779
    \overload
780
781
    Loads a pixmap from the binary \a data using the specified \a
782
    format and conversion \a flags.
783
*/
784
785
786
/*!
787
    Saves the pixmap to the file with the given \a fileName using the
788
    specified image file \a format and \a quality factor. Returns \c true
789
    if successful; otherwise returns \c false.
790
791
    The \a quality factor must be in the range [0,100] or -1. Specify
792
    0 to obtain small compressed files, 100 for large uncompressed
793
    files, and -1 to use the default settings.
794
795
    If \a format is \nullptr, an image format will be chosen from
796
    \a fileName's suffix.
797
798
    \sa {QPixmap#Reading and Writing Image Files}{Reading and Writing
799
    Image Files}
800
*/
801
802
bool QPixmap::save(const QString &fileName, const char *format, int quality) const
803
0
{
804
0
    if (isNull())
805
0
        return false;                                // nothing to save
806
0
    QImageWriter writer(fileName, format);
807
0
    return doImageIO(&writer, quality);
808
0
}
809
810
/*!
811
    \overload
812
813
    This function writes a QPixmap to the given \a device using the
814
    specified image file \a format and \a quality factor. This can be
815
    used, for example, to save a pixmap directly into a QByteArray:
816
817
    \snippet image/image.cpp 1
818
*/
819
820
bool QPixmap::save(QIODevice* device, const char* format, int quality) const
821
0
{
822
0
    if (isNull())
823
0
        return false;                                // nothing to save
824
0
    QImageWriter writer(device, format);
825
0
    return doImageIO(&writer, quality);
826
0
}
827
828
/*! \internal
829
*/
830
bool QPixmap::doImageIO(QImageWriter *writer, int quality) const
831
0
{
832
0
    if (quality > 100  || quality < -1)
833
0
        qWarning("QPixmap::save: quality out of range [-1,100]");
834
0
    if (quality >= 0)
835
0
        writer->setQuality(qMin(quality,100));
836
0
    return writer->write(toImage());
837
0
}
838
839
840
/*!
841
    Fills the pixmap with the given \a color.
842
843
    The effect of this function is undefined when the pixmap is
844
    being painted on.
845
846
    \sa {QPixmap#Pixmap Transformations}{Pixmap Transformations}
847
*/
848
849
void QPixmap::fill(const QColor &color)
850
18.6k
{
851
18.6k
    if (isNull())
852
0
        return;
853
854
    // Some people are probably already calling fill while a painter is active, so to not break
855
    // their programs, only print a warning and return when the fill operation could cause a crash.
856
18.6k
    if (paintingActive() && (color.alpha() != 255) && !hasAlphaChannel()) {
857
0
        qWarning("QPixmap::fill: Cannot fill while pixmap is being painted on");
858
0
        return;
859
0
    }
860
861
18.6k
    if (data->ref.loadRelaxed() == 1) {
862
        // detach() will also remove this pixmap from caches, so
863
        // it has to be called even when ref == 1.
864
18.6k
        detach();
865
18.6k
    } else {
866
        // Don't bother to make a copy of the data object, since
867
        // it will be filled with new pixel data anyway.
868
0
        QPlatformPixmap *d = data->createCompatiblePlatformPixmap();
869
0
        d->resize(data->width(), data->height());
870
0
        d->setDevicePixelRatio(data->devicePixelRatio());
871
0
        data = d;
872
0
    }
873
18.6k
    data->fill(color);
874
18.6k
}
875
876
/*!
877
    Returns a number that identifies this QPixmap. Distinct QPixmap
878
    objects can only have the same cache key if they refer to the same
879
    contents.
880
881
    The cacheKey() will change when the pixmap is altered.
882
*/
883
qint64 QPixmap::cacheKey() const
884
0
{
885
0
    if (isNull())
886
0
        return 0;
887
888
0
    Q_ASSERT(data);
889
0
    return data->cacheKey();
890
0
}
891
892
#if 0
893
static void sendResizeEvents(QWidget *target)
894
{
895
    QResizeEvent e(target->size(), QSize());
896
    QApplication::sendEvent(target, &e);
897
898
    const QObjectList children = target->children();
899
    for (int i = 0; i < children.size(); ++i) {
900
        QWidget *child = static_cast<QWidget*>(children.at(i));
901
        if (child->isWidgetType() && !child->isWindow() && child->testAttribute(Qt::WA_PendingResizeEvent))
902
            sendResizeEvents(child);
903
    }
904
}
905
#endif
906
907
908
/*****************************************************************************
909
  QPixmap stream functions
910
 *****************************************************************************/
911
#if !defined(QT_NO_DATASTREAM)
912
/*!
913
    \relates QPixmap
914
915
    Writes the given \a pixmap to the given \a stream as a PNG
916
    image. Note that writing the stream to a file will not produce a
917
    valid image file.
918
919
    \sa QPixmap::save(), {Serializing Qt Data Types}
920
*/
921
922
QDataStream &operator<<(QDataStream &stream, const QPixmap &pixmap)
923
0
{
924
0
    return stream << pixmap.toImage();
925
0
}
926
927
/*!
928
    \relates QPixmap
929
930
    Reads an image from the given \a stream into the given \a pixmap.
931
932
    \sa QPixmap::load(), {Serializing Qt Data Types}
933
*/
934
935
QDataStream &operator>>(QDataStream &stream, QPixmap &pixmap)
936
0
{
937
0
    QImage image;
938
0
    stream >> image;
939
940
0
    if (image.isNull()) {
941
0
        pixmap = QPixmap();
942
0
    } else if (image.depth() == 1) {
943
0
        pixmap = QBitmap::fromImage(std::move(image));
944
0
    } else {
945
0
        pixmap = QPixmap::fromImage(std::move(image));
946
0
    }
947
0
    return stream;
948
0
}
949
950
#endif // QT_NO_DATASTREAM
951
952
/*!
953
    \internal
954
*/
955
956
bool QPixmap::isDetached() const
957
0
{
958
0
    return data && data->ref.loadRelaxed() == 1;
959
0
}
960
961
/*!
962
    Replaces this pixmap's data with the given \a image using the
963
    specified \a flags to control the conversion.  The \a flags
964
    argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
965
    Passing 0 for \a flags sets all the default options. Returns \c true
966
    if the result is that this pixmap is not null.
967
968
    \sa fromImage()
969
*/
970
bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
971
0
{
972
0
    detach();
973
0
    if (image.isNull() || !data)
974
0
        *this = QPixmap::fromImage(image, flags);
975
0
    else
976
0
        data->fromImage(image, flags);
977
0
    return !isNull();
978
0
}
979
980
/*!
981
    \fn QPixmap QPixmap::scaled(int width, int height,
982
    Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode
983
    transformMode) const
984
985
    \overload
986
987
    Returns a copy of the pixmap scaled to a rectangle with the given
988
    \a width and \a height according to the given \a aspectRatioMode and
989
    \a transformMode.
990
991
    If either the \a width or the \a height is zero or negative, this
992
    function returns a null pixmap.
993
*/
994
995
/*!
996
    \fn QPixmap QPixmap::scaled(const QSize &size, Qt::AspectRatioMode
997
    aspectRatioMode, Qt::TransformationMode transformMode) const
998
999
    Scales the pixmap to the given \a size, using the aspect ratio and
1000
    transformation modes specified by \a aspectRatioMode and \a
1001
    transformMode.
1002
1003
    \image qimage-scaling.png {Three aspect ratio modes compared}
1004
1005
    \list
1006
    \li If \a aspectRatioMode is Qt::IgnoreAspectRatio, the pixmap
1007
       is scaled to \a size.
1008
    \li If \a aspectRatioMode is Qt::KeepAspectRatio, the pixmap is
1009
       scaled to a rectangle as large as possible inside \a size, preserving the aspect ratio.
1010
    \li If \a aspectRatioMode is Qt::KeepAspectRatioByExpanding,
1011
       the pixmap is scaled to a rectangle as small as possible
1012
       outside \a size, preserving the aspect ratio.
1013
    \endlist
1014
1015
    If the given \a size is empty, this function returns a null
1016
    pixmap.
1017
1018
1019
    In some cases it can be more beneficial to draw the pixmap to a
1020
    painter with a scale set rather than scaling the pixmap. This is
1021
    the case when the painter is for instance based on OpenGL or when
1022
    the scale factor changes rapidly.
1023
1024
    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1025
    Transformations}
1026
1027
*/
1028
QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::TransformationMode mode) const
1029
0
{
1030
0
    if (isNull()) {
1031
0
        qWarning("QPixmap::scaled: Pixmap is a null pixmap");
1032
0
        return QPixmap();
1033
0
    }
1034
0
    if (s.isEmpty())
1035
0
        return QPixmap();
1036
1037
0
    QSize newSize = size();
1038
0
    newSize.scale(s, aspectMode);
1039
0
    newSize.rwidth() = qMax(newSize.width(), 1);
1040
0
    newSize.rheight() = qMax(newSize.height(), 1);
1041
0
    if (newSize == size())
1042
0
        return *this;
1043
1044
0
    Q_TRACE_SCOPE(QPixmap_scaled, s, aspectMode, mode);
1045
1046
0
    QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(),
1047
0
                                          (qreal)newSize.height() / height());
1048
0
    QPixmap pix = transformed(wm, mode);
1049
0
    return pix;
1050
0
}
1051
1052
/*!
1053
    \fn QPixmap QPixmap::scaledToWidth(int width, Qt::TransformationMode
1054
    mode) const
1055
1056
    Returns a scaled copy of the image. The returned image is scaled
1057
    to the given \a width using the specified transformation \a mode.
1058
    The height of the pixmap is automatically calculated so that the
1059
    aspect ratio of the pixmap is preserved.
1060
1061
    If \a width is 0 or negative, a null pixmap is returned.
1062
1063
    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1064
    Transformations}
1065
*/
1066
QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToWidth(int w, Qt::TransformationMode mode) const
1067
0
{
1068
0
    if (isNull()) {
1069
0
        qWarning("QPixmap::scaleWidth: Pixmap is a null pixmap");
1070
0
        return copy();
1071
0
    }
1072
0
    if (w <= 0)
1073
0
        return QPixmap();
1074
1075
0
    Q_TRACE_SCOPE(QPixmap_scaledToWidth, w, mode);
1076
1077
0
    qreal factor = (qreal) w / width();
1078
0
    QTransform wm = QTransform::fromScale(factor, factor);
1079
0
    return transformed(wm, mode);
1080
0
}
1081
1082
/*!
1083
    \fn QPixmap QPixmap::scaledToHeight(int height,
1084
    Qt::TransformationMode mode) const
1085
1086
    Returns a scaled copy of the image. The returned image is scaled
1087
    to the given \a height using the specified transformation \a mode.
1088
    The width of the pixmap is automatically calculated so that the
1089
    aspect ratio of the pixmap is preserved.
1090
1091
    If \a height is 0 or negative, a null pixmap is returned.
1092
1093
    \sa isNull(), {QPixmap#Pixmap Transformations}{Pixmap
1094
    Transformations}
1095
*/
1096
QPixmap Q_TRACE_INSTRUMENT(qtgui) QPixmap::scaledToHeight(int h, Qt::TransformationMode mode) const
1097
0
{
1098
0
    if (isNull()) {
1099
0
        qWarning("QPixmap::scaleHeight: Pixmap is a null pixmap");
1100
0
        return copy();
1101
0
    }
1102
0
    if (h <= 0)
1103
0
        return QPixmap();
1104
1105
0
    Q_TRACE_SCOPE(QPixmap_scaledToHeight, h, mode);
1106
1107
0
    qreal factor = (qreal) h / height();
1108
0
    QTransform wm = QTransform::fromScale(factor, factor);
1109
0
    return transformed(wm, mode);
1110
0
}
1111
1112
/*!
1113
    Returns a copy of the pixmap that is transformed using the given
1114
    transformation \a transform and transformation \a mode. The original
1115
    pixmap is not changed.
1116
1117
    The transformation \a transform is internally adjusted to compensate
1118
    for unwanted translation; i.e. the pixmap produced is the smallest
1119
    pixmap that contains all the transformed points of the original
1120
    pixmap. Use the trueMatrix() function to retrieve the actual
1121
    matrix used for transforming the pixmap.
1122
1123
    This function is slow because it involves transformation to a
1124
    QImage, non-trivial computations and a transformation back to a
1125
    QPixmap.
1126
1127
    \sa trueMatrix(), {QPixmap#Pixmap Transformations}{Pixmap
1128
    Transformations}
1129
*/
1130
QPixmap QPixmap::transformed(const QTransform &transform,
1131
                             Qt::TransformationMode mode) const
1132
0
{
1133
0
    if (isNull() || transform.type() <= QTransform::TxTranslate)
1134
0
        return *this;
1135
1136
0
    return data->transformed(transform, mode);
1137
0
}
1138
1139
/*!
1140
    \class QPixmap
1141
    \inmodule QtGui
1142
1143
    \brief The QPixmap class is an off-screen image representation
1144
    that can be used as a paint device.
1145
1146
    \ingroup painting
1147
    \ingroup shared
1148
1149
1150
    Qt provides four classes for handling image data: QImage, QPixmap,
1151
    QBitmap and QPicture. QImage is designed and optimized for I/O,
1152
    and for direct pixel access and manipulation, while QPixmap is
1153
    designed and optimized for showing images on screen. QBitmap is
1154
    only a convenience class that inherits QPixmap, ensuring a depth
1155
    of 1. The isQBitmap() function returns \c true if a QPixmap object is
1156
    really a bitmap, otherwise returns \c false. Finally, the QPicture class
1157
    is a paint device that records and replays QPainter commands.
1158
1159
    A QPixmap can easily be displayed on the screen using QLabel or
1160
    one of QAbstractButton's subclasses (such as QPushButton and
1161
    QToolButton). QLabel has a pixmap property, whereas
1162
    QAbstractButton has an icon property.
1163
1164
    QPixmap objects can be passed around by value since the QPixmap
1165
    class uses implicit data sharing. For more information, see the \l
1166
    {Implicit Data Sharing} documentation. QPixmap objects can also be
1167
    streamed.
1168
1169
    Note that the pixel data in a pixmap is internal and is managed by
1170
    the underlying window system. Because QPixmap is a QPaintDevice
1171
    subclass, QPainter can be used to draw directly onto pixmaps.
1172
    Pixels can only be accessed through QPainter functions or by
1173
    converting the QPixmap to a QImage. However, the fill() function
1174
    is available for initializing the entire pixmap with a given color.
1175
1176
    There are functions to convert between QImage and
1177
    QPixmap. Typically, the QImage class is used to load an image
1178
    file, optionally manipulating the image data, before the QImage
1179
    object is converted into a QPixmap to be shown on
1180
    screen. Alternatively, if no manipulation is desired, the image
1181
    file can be loaded directly into a QPixmap.
1182
1183
    QPixmap provides a collection of functions that can be used to
1184
    obtain a variety of information about the pixmap. In addition,
1185
    there are several functions that enables transformation of the
1186
    pixmap.
1187
1188
    \section1 Reading and Writing Image Files
1189
1190
    QPixmap provides several ways of reading an image file: The file
1191
    can be loaded when constructing the QPixmap object, or by using
1192
    the load() or loadFromData() functions later on. When loading an
1193
    image, the file name can either refer to an actual file on disk or
1194
    to one of the application's embedded resources. See \l{The Qt
1195
    Resource System} overview for details on how to embed images and
1196
    other resource files in the application's executable.
1197
1198
    Simply call the save() function to save a QPixmap object.
1199
1200
    The complete list of supported file formats are available through
1201
    the QImageReader::supportedImageFormats() and
1202
    QImageWriter::supportedImageFormats() functions. New file formats
1203
    can be added as plugins. By default, Qt supports the following
1204
    formats:
1205
1206
    \table
1207
    \header \li Format \li Description                      \li Qt's support
1208
    \row    \li BMP    \li Windows Bitmap                   \li Read/write
1209
    \row    \li CUR    \li Windows Cursor                   \li Read/write
1210
    \row    \li GIF    \li Graphic Interchange Format       \li Read
1211
    \row    \li ICO    \li Windows Icon                     \li Read/write
1212
    \row    \li JFIF   \li JPEG File Interchange Format     \li Read/write
1213
    \row    \li JPEG   \li Joint Photographic Experts Group \li Read/write
1214
    \row    \li JPG    \li Joint Photographic Experts Group \li Read/write
1215
    \row    \li PBM    \li Portable Bitmap                  \li Read/write
1216
    \row    \li PGM    \li Portable Graymap                 \li Read/write
1217
    \row    \li PNG    \li Portable Network Graphics        \li Read/write
1218
    \row    \li PPM    \li Portable Pixmap                  \li Read/write
1219
    \row    \li SVG    \li Scalable Vector Graphics         \li Read
1220
    \row    \li SVGZ   \li Scalable Vector Graphics (Compressed) \li Read
1221
    \row    \li XBM    \li X11 Bitmap                       \li Read/write
1222
    \row    \li XPM    \li X11 Pixmap                       \li Read/write
1223
    \endtable
1224
1225
    Further formats are supported if the \l{Qt Image Formats} module is installed.
1226
1227
    \section1 Pixmap Information
1228
1229
    QPixmap provides a collection of functions that can be used to
1230
    obtain a variety of information about the pixmap:
1231
1232
    \table
1233
    \header
1234
    \li \li Available Functions
1235
    \row
1236
    \li Geometry
1237
    \li
1238
    The size(), width() and height() functions provide information
1239
    about the pixmap's size. The rect() function returns the image's
1240
    enclosing rectangle.
1241
1242
    \row
1243
    \li Alpha component
1244
    \li
1245
1246
    The hasAlphaChannel() returns \c true if the pixmap has a format that
1247
    respects the alpha channel, otherwise returns \c false. The hasAlpha(),
1248
    setMask() and mask() functions are legacy and should not be used.
1249
    They are potentially very slow.
1250
1251
    The createHeuristicMask() function creates and returns a 1-bpp
1252
    heuristic mask (i.e. a QBitmap) for this pixmap. It works by
1253
    selecting a color from one of the corners and then chipping away
1254
    pixels of that color, starting at all the edges. The
1255
    createMaskFromColor() function creates and returns a mask (i.e. a
1256
    QBitmap) for the pixmap based on a given color.
1257
1258
    \row
1259
    \li Low-level information
1260
    \li
1261
1262
    The depth() function returns the depth of the pixmap. The
1263
    defaultDepth() function returns the default depth, i.e. the depth
1264
    used by the application on the given screen.
1265
1266
    The cacheKey() function returns a number that uniquely
1267
    identifies the contents of the QPixmap object.
1268
1269
    \endtable
1270
1271
    \section1 Pixmap Conversion
1272
1273
    A QPixmap object can be converted into a QImage using the
1274
    toImage() function. Likewise, a QImage can be converted into a
1275
    QPixmap using the fromImage(). If this is too expensive an
1276
    operation, you can use QBitmap::fromImage() instead.
1277
1278
    To convert a QPixmap to and from HICON you can use the
1279
    QImage::toHICON() and QImage::fromHICON() functions respectively
1280
    (after converting the QPixmap to a QImage, as explained above).
1281
1282
    \section1 Pixmap Transformations
1283
1284
    QPixmap supports a number of functions for creating a new pixmap
1285
    that is a transformed version of the original:
1286
1287
    The scaled(), scaledToWidth() and scaledToHeight() functions
1288
    return scaled copies of the pixmap, while the copy() function
1289
    creates a QPixmap that is a plain copy of the original one.
1290
1291
    The transformed() function returns a copy of the pixmap that is
1292
    transformed with the given transformation matrix and
1293
    transformation mode: Internally, the transformation matrix is
1294
    adjusted to compensate for unwanted translation,
1295
    i.e. transformed() returns the smallest pixmap containing all
1296
    transformed points of the original pixmap. The static trueMatrix()
1297
    function returns the actual matrix used for transforming the
1298
    pixmap.
1299
1300
    \sa QBitmap, QImage, QImageReader, QImageWriter
1301
*/
1302
1303
1304
/*!
1305
    \typedef QPixmap::DataPtr
1306
    \internal
1307
*/
1308
1309
/*!
1310
    \fn DataPtr &QPixmap::data_ptr()
1311
    \internal
1312
*/
1313
1314
/*!
1315
    Returns \c true if this pixmap has an alpha channel, \e or has a
1316
    mask, otherwise returns \c false.
1317
1318
    \sa hasAlphaChannel(), mask()
1319
*/
1320
bool QPixmap::hasAlpha() const
1321
0
{
1322
0
    return data && data->hasAlphaChannel();
1323
0
}
1324
1325
/*!
1326
    Returns \c true if the pixmap has a format that respects the alpha
1327
    channel, otherwise returns \c false.
1328
1329
    \sa hasAlpha()
1330
*/
1331
bool QPixmap::hasAlphaChannel() const
1332
0
{
1333
0
    return data && data->hasAlphaChannel();
1334
0
}
1335
1336
/*!
1337
    \internal
1338
*/
1339
int QPixmap::metric(PaintDeviceMetric metric) const
1340
93.0k
{
1341
93.0k
    return data ? data->metric(metric) : 0;
1342
93.0k
}
1343
1344
/*!
1345
    \internal
1346
*/
1347
QPaintEngine *QPixmap::paintEngine() const
1348
18.6k
{
1349
18.6k
    return data ? data->paintEngine() : nullptr;
1350
18.6k
}
1351
1352
/*!
1353
    \fn QBitmap QPixmap::mask() const
1354
1355
    Extracts a bitmap mask from the pixmap's alpha channel.
1356
1357
    \warning This is potentially an expensive operation. The mask of
1358
    the pixmap is extracted dynamically from the pixeldata.
1359
1360
    \sa setMask(), {QPixmap#Pixmap Information}{Pixmap Information}
1361
*/
1362
QBitmap QPixmap::mask() const
1363
0
{
1364
0
    return data ? data->mask() : QBitmap();
1365
0
}
1366
1367
/*!
1368
    Returns the default pixmap depth used by the application.
1369
1370
    On all platforms the depth of the primary screen will be returned.
1371
1372
    \note QGuiApplication must be created before calling this function.
1373
1374
    \sa depth(), {QPixmap#Pixmap Information}{Pixmap Information}
1375
1376
*/
1377
int QPixmap::defaultDepth()
1378
0
{
1379
0
    QScreen *primary = QGuiApplication::primaryScreen();
1380
0
    if (Q_LIKELY(primary))
1381
0
        return primary->depth();
1382
0
    qWarning("QPixmap: QGuiApplication must be created before calling defaultDepth().");
1383
0
    return 0;
1384
0
}
1385
1386
/*!
1387
    Detaches the pixmap from shared pixmap data.
1388
1389
    A pixmap is automatically detached by Qt whenever its contents are
1390
    about to change. This is done in almost all QPixmap member
1391
    functions that modify the pixmap (fill(), fromImage(),
1392
    load(), etc.), and in QPainter::begin() on a pixmap.
1393
1394
    There are two exceptions in which detach() must be called
1395
    explicitly, that is when calling the handle() or the
1396
    x11PictureHandle() function (only available on X11). Otherwise,
1397
    any modifications done using system calls, will be performed on
1398
    the shared data.
1399
1400
    The detach() function returns immediately if there is just a
1401
    single reference or if the pixmap has not been initialized yet.
1402
*/
1403
void QPixmap::detach()
1404
37.2k
{
1405
37.2k
    if (!data)
1406
0
        return;
1407
1408
    // QPixmap.data member may be QRuntimePlatformPixmap so use handle() function to get
1409
    // the actual underlying runtime pixmap data.
1410
37.2k
    QPlatformPixmap *pd = handle();
1411
37.2k
    QPlatformPixmap::ClassId id = pd->classId();
1412
37.2k
    if (id == QPlatformPixmap::RasterClass) {
1413
37.2k
        QRasterPlatformPixmap *rasterData = static_cast<QRasterPlatformPixmap*>(pd);
1414
37.2k
        rasterData->image.detach();
1415
37.2k
    }
1416
1417
37.2k
    if (data->is_cached && data->ref.loadRelaxed() == 1)
1418
0
        QImagePixmapCleanupHooks::executePlatformPixmapModificationHooks(data.data());
1419
1420
37.2k
    if (data->ref.loadRelaxed() != 1) {
1421
0
        *this = copy();
1422
0
    }
1423
37.2k
    ++data->detach_no;
1424
37.2k
}
1425
1426
/*!
1427
    \fn QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1428
1429
    Converts the given \a image to a pixmap using the specified \a
1430
    flags to control the conversion.  The \a flags argument is a
1431
    bitwise-OR of the \l{Qt::ImageConversionFlags}. Passing 0 for \a
1432
    flags sets all the default options.
1433
1434
    In case of monochrome and 8-bit images, the image is first
1435
    converted to a 32-bit pixmap and then filled with the colors in
1436
    the color table. If this is too expensive an operation, you can
1437
    use QBitmap::fromImage() instead.
1438
1439
    \sa fromImageReader(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1440
*/
1441
QPixmap QPixmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
1442
0
{
1443
0
    if (image.isNull())
1444
0
        return QPixmap();
1445
1446
0
    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1447
0
        qWarning("QPixmap::fromImage: QPixmap cannot be created without a QGuiApplication");
1448
0
        return QPixmap();
1449
0
    }
1450
1451
0
    std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1452
0
    data->fromImage(image, flags);
1453
0
    return QPixmap(data.release());
1454
0
}
1455
1456
/*!
1457
    \fn QPixmap QPixmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
1458
    \since 5.3
1459
    \overload
1460
1461
    Converts the given \a image to a pixmap without copying if possible.
1462
*/
1463
1464
1465
/*!
1466
    \internal
1467
*/
1468
QPixmap QPixmap::fromImageInPlace(QImage &image, Qt::ImageConversionFlags flags)
1469
0
{
1470
0
    if (image.isNull())
1471
0
        return QPixmap();
1472
1473
0
    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1474
0
        qWarning("QPixmap::fromImageInPlace: QPixmap cannot be created without a QGuiApplication");
1475
0
        return QPixmap();
1476
0
    }
1477
1478
0
    std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1479
0
    data->fromImageInPlace(image, flags);
1480
0
    return QPixmap(data.release());
1481
0
}
1482
1483
/*!
1484
    \fn QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1485
1486
    Create a QPixmap from an image read directly from an \a imageReader.
1487
    The \a flags argument is a bitwise-OR of the \l{Qt::ImageConversionFlags}.
1488
    Passing 0 for \a flags sets all the default options.
1489
1490
    On some systems, reading an image directly to QPixmap can use less memory than
1491
    reading a QImage to convert it to QPixmap.
1492
1493
    \sa fromImage(), toImage(), {QPixmap#Pixmap Conversion}{Pixmap Conversion}
1494
*/
1495
QPixmap QPixmap::fromImageReader(QImageReader *imageReader, Qt::ImageConversionFlags flags)
1496
0
{
1497
0
    if (Q_UNLIKELY(!qobject_cast<QGuiApplication *>(QCoreApplication::instance()))) {
1498
0
        qWarning("QPixmap::fromImageReader: QPixmap cannot be created without a QGuiApplication");
1499
0
        return QPixmap();
1500
0
    }
1501
1502
0
    std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::PixmapType));
1503
0
    data->fromImageReader(imageReader, flags);
1504
0
    return QPixmap(data.release());
1505
0
}
1506
1507
/*!
1508
  \internal
1509
*/
1510
QPlatformPixmap* QPixmap::handle() const
1511
55.8k
{
1512
55.8k
    return data.data();
1513
55.8k
}
1514
1515
#ifndef QT_NO_DEBUG_STREAM
1516
QDebug operator<<(QDebug dbg, const QPixmap &r)
1517
0
{
1518
0
    QDebugStateSaver saver(dbg);
1519
0
    dbg.resetFormat();
1520
0
    dbg.nospace();
1521
0
    dbg << "QPixmap(";
1522
0
    if (r.isNull()) {
1523
0
        dbg << "null";
1524
0
    } else {
1525
0
        dbg << r.size() << ",depth=" << r.depth()
1526
0
            << ",devicePixelRatio=" << r.devicePixelRatio()
1527
0
            << ",cacheKey=" << Qt::showbase << Qt::hex << r.cacheKey() << Qt::dec << Qt::noshowbase;
1528
0
    }
1529
0
    dbg << ')';
1530
0
    return dbg;
1531
0
}
1532
#endif
1533
1534
QT_END_NAMESPACE