Coverage Report

Created: 2026-08-14 08:24

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