Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/image/qbitmap.cpp
Line
Count
Source
1
// Copyright (C) 2016 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:critical reason:data-parser
4
5
#include "qbitmap.h"
6
#include <qpa/qplatformpixmap.h>
7
#include <qpa/qplatformintegration.h>
8
#include "qimage.h"
9
#include "qscreen.h"
10
#include "qvariant.h"
11
#include <qpainter.h>
12
#include <private/qguiapplication_p.h>
13
14
#include <memory>
15
16
QT_BEGIN_NAMESPACE
17
18
/*!
19
    \class QBitmap
20
    \inmodule QtGui
21
    \brief The QBitmap class provides monochrome (1-bit depth) pixmaps.
22
23
    \ingroup painting
24
    \ingroup shared
25
26
    The QBitmap class is a monochrome off-screen paint device used
27
    mainly for creating custom QCursor and QBrush objects,
28
    constructing QRegion objects, and for setting masks for pixmaps
29
    and widgets.
30
31
    QBitmap is a QPixmap subclass ensuring a depth of 1, except for
32
    null objects which have a depth of 0. If a pixmap with a depth
33
    greater than 1 is assigned to a bitmap, the bitmap will be
34
    dithered automatically.
35
36
    Use the QColor objects Qt::color0 and Qt::color1 when drawing on a
37
    QBitmap object (or a QPixmap object with depth 1).
38
39
    Painting with Qt::color0 sets the bitmap bits to 0, and painting
40
    with Qt::color1 sets the bits to 1. For a bitmap, 0-bits indicate
41
    background (or transparent pixels) and 1-bits indicate foreground
42
    (or opaque pixels). Use the clear() function to set all the bits
43
    to Qt::color0. Note that using the Qt::black and Qt::white colors
44
    make no sense because the QColor::pixel() value is not necessarily
45
    0 for black and 1 for white.
46
47
    The QBitmap class provides the transformed() function returning a
48
    transformed copy of the bitmap; use the QTransform argument to
49
    translate, scale, shear, and rotate the bitmap. In addition,
50
    QBitmap provides the static fromData() function which returns a
51
    bitmap constructed from the given \c uchar data, and the static
52
    fromImage() function returning a converted copy of a QImage
53
    object.
54
55
    Just like the QPixmap class, QBitmap is optimized by the use of
56
    implicit data sharing. For more information, see the \l {Implicit
57
    Data Sharing} documentation.
58
59
    \sa QPixmap, QImage, QImageReader, QImageWriter
60
*/
61
62
/*! \typedef QBitmap::DataPtr
63
  \internal
64
 */
65
66
/*!
67
    Constructs a null bitmap.
68
69
    \sa QPixmap::isNull()
70
*/
71
QBitmap::QBitmap()
72
0
    : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
73
0
{
74
0
}
75
76
/*!
77
    \fn QBitmap::QBitmap(int width, int height)
78
79
    Constructs a bitmap with the given \a width and \a height. The pixels
80
    inside are uninitialized.
81
82
    \sa clear()
83
*/
84
QBitmap::QBitmap(int w, int h)
85
0
    : QPixmap(QSize(w, h), QPlatformPixmap::BitmapType)
86
0
{
87
0
}
88
89
/*!
90
    Constructs a bitmap with the given \a size.  The pixels in the
91
    bitmap are uninitialized.
92
93
    \sa clear()
94
*/
95
QBitmap::QBitmap(const QSize &size)
96
0
    : QPixmap(size, QPlatformPixmap::BitmapType)
97
0
{
98
0
}
99
100
/*!
101
    \internal
102
    This dtor must stay empty until Qt 7 (was inline until 6.2).
103
*/
104
0
QBitmap::~QBitmap() = default;
105
106
/*!
107
    \fn QBitmap::clear()
108
109
    Clears the bitmap, setting all its bits to Qt::color0.
110
*/
111
112
/*!
113
    Constructs a bitmap from the file specified by the given \a
114
    fileName. If the file does not exist, or has an unknown format,
115
    the bitmap becomes a null bitmap.
116
117
    The \a fileName and \a format parameters are passed on to the
118
    QPixmap::load() function. If the file format uses more than 1 bit
119
    per pixel, the resulting bitmap will be dithered automatically.
120
121
    \sa QPixmap::isNull(), QImageReader::imageFormat()
122
*/
123
QBitmap::QBitmap(const QString& fileName, const char *format)
124
0
    : QPixmap(QSize(0, 0), QPlatformPixmap::BitmapType)
125
0
{
126
0
    load(fileName, format, Qt::MonoOnly);
127
0
}
128
129
/*!
130
    \fn void QBitmap::swap(QBitmap &other)
131
    \memberswap{bitmap}
132
*/
133
134
/*!
135
   Returns the bitmap as a QVariant.
136
*/
137
QBitmap::operator QVariant() const
138
0
{
139
0
    return QVariant::fromValue(*this);
140
0
}
141
142
static QBitmap makeBitmap(QImage &&image, Qt::ImageConversionFlags flags)
143
0
{
144
    // make sure image.color(0) == Qt::color0 (white)
145
    // and image.color(1) == Qt::color1 (black)
146
0
    const QRgb c0 = QColor(Qt::black).rgb();
147
0
    const QRgb c1 = QColor(Qt::white).rgb();
148
0
    if (image.color(0) == c0 && image.color(1) == c1) {
149
0
        image.invertPixels();
150
0
        image.setColor(0, c1);
151
0
        image.setColor(1, c0);
152
0
    }
153
154
0
    std::unique_ptr<QPlatformPixmap> data(QGuiApplicationPrivate::platformIntegration()->createPlatformPixmap(QPlatformPixmap::BitmapType));
155
156
0
    data->fromImageInPlace(image, flags | Qt::MonoOnly);
157
0
    return QBitmap::fromPixmap(QPixmap(data.release()));
158
0
}
159
160
/*!
161
    Returns a copy of the given \a image converted to a bitmap using
162
    the specified image conversion \a flags.
163
164
    \sa fromData()
165
*/
166
QBitmap QBitmap::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
167
0
{
168
0
    if (image.isNull())
169
0
        return QBitmap();
170
171
0
    return makeBitmap(image.convertToFormat(QImage::Format_MonoLSB, flags), flags);
172
0
}
173
174
/*!
175
    \since 5.12
176
    \overload
177
178
    Returns a copy of the given \a image converted to a bitmap using
179
    the specified image conversion \a flags.
180
181
    \sa fromData()
182
*/
183
QBitmap QBitmap::fromImage(QImage &&image, Qt::ImageConversionFlags flags)
184
0
{
185
0
    if (image.isNull())
186
0
        return QBitmap();
187
188
0
    return makeBitmap(std::move(image).convertToFormat(QImage::Format_MonoLSB, flags), flags);
189
0
}
190
191
/*!
192
    Constructs a bitmap with the given \a size, and sets the contents to
193
    the \a bits supplied.
194
195
    The bitmap data has to be byte aligned and provided in the bit
196
    order specified by \a monoFormat. The mono format must be either
197
    QImage::Format_Mono or QImage::Format_MonoLSB. Use
198
    QImage::Format_Mono to specify data on the XBM format.
199
200
    \sa fromImage()
201
202
*/
203
QBitmap QBitmap::fromData(const QSize &size, const uchar *bits, QImage::Format monoFormat)
204
0
{
205
0
    Q_ASSERT(monoFormat == QImage::Format_Mono || monoFormat == QImage::Format_MonoLSB);
206
207
0
    QImage image(size, monoFormat);
208
0
    image.setColor(0, QColor(Qt::color0).rgb());
209
0
    image.setColor(1, QColor(Qt::color1).rgb());
210
211
    // Need to memcpy each line separately since QImage is 32bit aligned and
212
    // this data is only byte aligned...
213
0
    int bytesPerLine = (size.width() + 7) / 8;
214
0
    for (int y = 0; y < size.height(); ++y)
215
0
        memcpy(image.scanLine(y), bits + bytesPerLine * y, bytesPerLine);
216
0
    return QBitmap::fromImage(std::move(image));
217
0
}
218
219
/*!
220
    Returns a copy of the given \a pixmap converted to a bitmap.
221
222
    If the pixmap has a depth greater than 1, the resulting bitmap
223
    will be dithered automatically.
224
225
    \since 6.0
226
227
    \sa QPixmap::depth()
228
*/
229
230
QBitmap QBitmap::fromPixmap(const QPixmap &pixmap)
231
0
{
232
0
    if (pixmap.isNull()) {                        // a null pixmap
233
0
        return QBitmap(0, 0);
234
0
    } else if (pixmap.depth() == 1) {             // 1-bit pixmap
235
0
        QBitmap bm;
236
0
        if (pixmap.paintingActive()) {            // make a deep copy
237
0
            pixmap.copy().swap(bm);
238
0
        } else {
239
0
            bm.data = pixmap.data;                // shallow assignment
240
0
        }
241
0
        return bm;
242
0
    }
243
    // n-bit depth pixmap, will dither image
244
0
    return fromImage(pixmap.toImage());
245
0
}
246
247
#if QT_DEPRECATED_SINCE(6, 0)
248
/*!
249
    \deprecated [6.0] Use fromPixmap instead.
250
    Constructs a bitmap that is a copy of the given \a pixmap.
251
252
    If the pixmap has a depth greater than 1, the resulting bitmap
253
    will be dithered automatically.
254
255
    \sa QPixmap::depth(), fromImage(), fromData()
256
*/
257
QBitmap::QBitmap(const QPixmap &pixmap)
258
0
{
259
0
    *this = QBitmap::fromPixmap(pixmap);
260
0
}
261
262
/*!
263
    \deprecated [6.0] Use fromPixmap instead.
264
    \overload
265
266
    Assigns the given \a pixmap to this bitmap and returns a reference
267
    to this bitmap.
268
269
    If the pixmap has a depth greater than 1, the resulting bitmap
270
    will be dithered automatically.
271
272
    \sa QPixmap::depth()
273
 */
274
QBitmap &QBitmap::operator=(const QPixmap &pixmap)
275
0
{
276
0
    *this = QBitmap::fromPixmap(pixmap);
277
0
    return *this;
278
0
}
279
#endif
280
281
/*!
282
    Returns a copy of this bitmap, transformed according to the given
283
    \a matrix.
284
285
    \sa QPixmap::transformed()
286
 */
287
QBitmap QBitmap::transformed(const QTransform &matrix) const
288
0
{
289
0
    return QBitmap::fromPixmap(QPixmap::transformed(matrix));
290
0
}
291
292
QT_END_NAMESPACE