Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qwbmphandler.cpp
Go to the documentation of this file.
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
"qwbmphandler_p.h"
6
7
/*!
8
\class QWbmpHandler
9
\since 5.0
10
\brief The QWbmpHandler class provides support for the WBMP image format.
11
\internal
12
*/
13
14
#
include
<
qimage
.
h
>
15
#
include
<
qvariant
.
h
>
16
17
QT_BEGIN_NAMESPACE
18
19
// This struct represents header of WBMP image file
20
struct
WBMPHeader
21
{
22
quint8
type
;
// Type of WBMP image (always equal to 0)
23
quint8
format
;
// Format of WBMP image
24
quint32
width
;
// Width of the image already decoded from multibyte integer
25
quint32
height
;
// Height of the image already decoded from multibyte integer
26
};
27
#
define
WBMPFIXEDHEADER_SIZE
2
28
29
// Data renderers and writers which takes care of data alignment endiness and stuff
30
static
bool
readMultiByteInt
(QIODevice *iodev, quint32 *num)
31
{
32
quint32 res = 0;
33
34
quint8 c;
35
unsigned
int
count = 0;
36
do
{
37
// Do not allow to read longer
38
// then we can store in num
39
if
(++count >
sizeof
(*num))
40
return
false
;
41
42
if
(!iodev->getChar(
reinterpret_cast
<
char
*>(&c)))
43
return
false
;
44
45
res = (res << 7) | (c & 0x7F);
46
47
}
while
(c & 0x80);
48
49
*num = res;
50
return
true
;
51
}
52
53
static
bool
writeMultiByteInt
(QIODevice *iodev, quint32 num)
54
{
55
quint64 tmp = num & 0x7F;
56
num >>= 7;
57
58
while
(num) {
59
quint8 c = num & 0x7F;
60
num = num >> 7;
61
tmp = (tmp << 8) | (c | 0x80);
62
}
63
64
while
(tmp) {
65
quint8 c = tmp & 0xFF;
66
if
(!iodev->putChar(c))
67
return
false
;
68
tmp >>= 8;
69
}
70
return
true
;
71
}
72
73
static
bool
readWBMPHeader
(QIODevice *iodev,
WBMPHeader
*hdr)
74
{
75
if
(!iodev)
76
return
false
;
77
78
uchar tmp[
WBMPFIXEDHEADER_SIZE
];
79
if
(iodev->read(
reinterpret_cast
<
char
*>(tmp),
WBMPFIXEDHEADER_SIZE
) ==
WBMPFIXEDHEADER_SIZE
) {
80
hdr->type = tmp[0];
81
hdr->format = tmp[1];
82
}
else
{
83
return
false
;
84
}
85
86
if
(readMultiByteInt(iodev, &hdr->width)
87
&& readMultiByteInt(iodev, &hdr->height)) {
88
return
true
;
89
}
90
return
false
;
91
}
92
93
static
bool
writeWBMPHeader
(QIODevice *iodev,
const
WBMPHeader
&hdr)
94
{
95
if
(iodev) {
96
uchar tmp[
WBMPFIXEDHEADER_SIZE
];
97
tmp[0] = hdr.type;
98
tmp[1] = hdr.format;
99
if
(iodev->write(
reinterpret_cast
<
char
*>(tmp),
WBMPFIXEDHEADER_SIZE
) !=
WBMPFIXEDHEADER_SIZE
)
100
return
false
;
101
102
if
(writeMultiByteInt(iodev, hdr.width) &&
103
writeMultiByteInt(iodev, hdr.height))
104
return
true
;
105
}
106
return
false
;
107
}
108
109
static
bool
writeWBMPData
(QIODevice *iodev,
const
QImage &image)
110
{
111
if
(iodev) {
112
int
h = image.height();
113
int
bpl = (image.width() + 7) / 8;
114
115
for
(
int
l=0; l<h; l++) {
116
if
(iodev->write(
reinterpret_cast
<
const
char
*>(image.constScanLine(l)), bpl) != bpl)
117
return
false
;
118
}
119
return
true
;
120
}
121
return
false
;
122
}
123
124
static
bool
readWBMPData
(QIODevice *iodev, QImage &image)
125
{
126
if
(iodev) {
127
int
h = image.height();
128
int
bpl = (image.width() + 7) / 8;
129
130
for
(
int
l = 0; l < h; l++) {
131
if
(iodev->read(
reinterpret_cast
<
char
*>(image.scanLine(l)), bpl) != bpl)
132
return
false
;
133
}
134
return
true
;
135
}
136
return
false
;
137
}
138
139
class
WBMPReader
140
{
141
public
:
142
WBMPReader
(QIODevice *iodevice);
143
144
QImage
readImage
();
145
bool
writeImage
(QImage image);
146
147
static
bool
canRead
(QIODevice *iodevice);
148
149
private
:
150
QIODevice *iodev;
151
WBMPHeader
hdr;
152
};
153
154
// WBMP common reader and writer implementation
155
WBMPReader
::
WBMPReader
(QIODevice *iodevice) : iodev(iodevice)
156
{
157
memset(&hdr, 0,
sizeof
(hdr));
158
}
159
160
QImage
WBMPReader
::
readImage
()
161
{
162
if
(!readWBMPHeader(iodev, &hdr))
163
return
QImage();
164
165
QImage image;
166
if
(!QImageIOHandler::allocateImage(QSize(hdr.width, hdr.height), QImage::Format_Mono, &image))
167
return
QImage();
168
if
(!readWBMPData(iodev, image))
169
return
QImage();
170
171
return
image;
172
}
173
174
bool
WBMPReader
::
writeImage
(QImage image)
175
{
176
if
(image.format() != QImage::Format_Mono)
177
image = image.convertToFormat(QImage::Format_Mono);
178
179
if
(image.colorTable().at(0) == image.colorTable().at(1)) {
180
// degenerate image: actually blank.
181
image.fill((qGray(image.colorTable().at(0)) < 128) ? 0 : 1);
182
}
else
if
(qGray(image.colorTable().at(0)) > qGray(image.colorTable().at(1))) {
183
// Conform to WBMP's convention about black and white
184
image.invertPixels();
185
}
186
187
hdr.type = 0;
188
hdr.format = 0;
189
hdr.width = image.width();
190
hdr.height = image.height();
191
192
if
(!writeWBMPHeader(iodev, hdr))
193
return
false
;
194
195
if
(!writeWBMPData(iodev, image))
196
return
false
;
197
198
return
true
;
199
}
200
201
bool
WBMPReader
::
canRead
(QIODevice *device)
202
{
203
if
(device) {
204
205
if
(device->isSequential())
206
return
false
;
207
208
// Save previous position
209
qint64 oldPos = device->pos();
210
211
WBMPHeader
hdr;
212
if
(
readWBMPHeader
(
device
,
&hdr
)
) {
213
if
((hdr.type == 0) && (hdr.format == 0)) {
214
const
qint64 imageSize = hdr.height * ((qint64(hdr.width) + 7) / 8);
215
qint64 available = device->bytesAvailable();
216
device->seek(oldPos);
217
return
(imageSize == available);
218
}
219
}
220
device->seek(oldPos);
221
}
222
return
false
;
223
}
224
225
/*!
226
Constructs an instance of QWbmpHandler initialized to use \a device.
227
*/
228
QWbmpHandler
::QWbmpHandler(QIODevice *device) :
229
m_reader(
new
WBMPReader(device))
230
{
231
}
232
233
/*!
234
Destructor for QWbmpHandler.
235
*/
236
QWbmpHandler
::~
QWbmpHandler
()
237
{
238
delete
m_reader;
239
}
240
241
/*!
242
* Verifies if some values (magic bytes) are set as expected in the header of the file.
243
* If the magic bytes were found, it is assumed that the QWbmpHandler can read the file.
244
*/
245
bool
QWbmpHandler
::
canRead
()
const
246
{
247
bool
bCanRead =
false
;
248
249
QIODevice *device = QImageIOHandler::device();
250
if
(device) {
251
bCanRead =
QWbmpHandler
::
canRead
(device);
252
if
(bCanRead)
253
setFormat(
"wbmp"
);
254
255
}
else
{
256
qWarning(
"QWbmpHandler::canRead() called with no device"
);
257
}
258
259
return
bCanRead;
260
}
261
262
/*! \reimp
263
*/
264
bool
QWbmpHandler
::
read
(QImage *image)
265
{
266
QImage img = m_reader->readImage();
267
if
(img.isNull())
268
return
false
;
269
*image =
std
::move(img);
270
return
true
;
271
}
272
273
/*! \reimp
274
*/
275
bool
QWbmpHandler
::
write
(
const
QImage &image)
276
{
277
if
(image.isNull())
278
return
false
;
279
280
return
m_reader->writeImage(image);
281
}
282
283
/*!
284
Only Size option is supported
285
*/
286
QVariant
QWbmpHandler
::
option
(
ImageOption
option)
const
287
{
288
if
(option == QImageIOHandler::Size) {
289
QIODevice *device = QImageIOHandler::device();
290
if
(device->isSequential())
291
return
QVariant();
292
293
// Save old position
294
qint64 oldPos = device->pos();
295
296
WBMPHeader
hdr;
297
if
(
readWBMPHeader
(
device
,
&hdr
)
) {
298
device->seek(oldPos);
299
return
QSize(hdr.width, hdr.height);
300
}
301
302
device->seek(oldPos);
303
304
}
else
if
(option == QImageIOHandler::ImageFormat) {
305
return
QVariant(QImage::Format_Mono);
306
}
307
308
return
QVariant();
309
}
310
311
bool
QWbmpHandler
::
supportsOption
(
ImageOption
option)
const
312
{
313
return
(option == QImageIOHandler::Size) ||
314
(option == QImageIOHandler::ImageFormat);
315
}
316
317
bool
QWbmpHandler
::canRead(QIODevice *device)
318
{
319
return
WBMPReader
::
canRead
(
device
)
;
320
}
321
322
QT_END_NAMESPACE
QImageIOHandler::ImageOption
ImageOption
This enum describes the different options supported by QImageIOHandler.
Definition
qimageiohandler.h:42
QWbmpHandler
The QWbmpHandler class provides support for the WBMP image format.
Definition
qwbmphandler_p.h:27
QWbmpHandler::canRead
bool canRead() const override
Verifies if some values (magic bytes) are set as expected in the header of the file.
Definition
qwbmphandler.cpp:245
QWbmpHandler::option
QVariant option(ImageOption option) const override
Only Size option is supported.
Definition
qwbmphandler.cpp:286
QWbmpHandler::~QWbmpHandler
~QWbmpHandler()
Destructor for QWbmpHandler.
Definition
qwbmphandler.cpp:236
QWbmpHandler::supportsOption
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
Definition
qwbmphandler.cpp:311
QWbmpHandler::write
bool write(const QImage &image) override
\reimp
Definition
qwbmphandler.cpp:275
QWbmpHandler::read
bool read(QImage *image) override
\reimp
Definition
qwbmphandler.cpp:264
WBMPReader
Definition
qwbmphandler.cpp:140
WBMPReader::readImage
QImage readImage()
Definition
qwbmphandler.cpp:160
WBMPReader::writeImage
bool writeImage(QImage image)
Definition
qwbmphandler.cpp:174
WBMPReader::WBMPReader
WBMPReader(QIODevice *iodevice)
Definition
qwbmphandler.cpp:155
WBMPReader::canRead
static bool canRead(QIODevice *iodevice)
Definition
qwbmphandler.cpp:201
QT_BEGIN_NAMESPACE
Combined button and popup list for selecting options.
Definition
qsequentialanimationgroup.cpp:47
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
writeWBMPData
static bool writeWBMPData(QIODevice *iodev, const QImage &image)
Definition
qwbmphandler.cpp:109
writeWBMPHeader
static bool writeWBMPHeader(QIODevice *iodev, const WBMPHeader &hdr)
Definition
qwbmphandler.cpp:93
writeMultiByteInt
static bool writeMultiByteInt(QIODevice *iodev, quint32 num)
Definition
qwbmphandler.cpp:53
WBMPFIXEDHEADER_SIZE
#define WBMPFIXEDHEADER_SIZE
Definition
qwbmphandler.cpp:27
readMultiByteInt
static bool readMultiByteInt(QIODevice *iodev, quint32 *num)
Definition
qwbmphandler.cpp:30
readWBMPHeader
static bool readWBMPHeader(QIODevice *iodev, WBMPHeader *hdr)
Definition
qwbmphandler.cpp:73
readWBMPData
static bool readWBMPData(QIODevice *iodev, QImage &image)
Definition
qwbmphandler.cpp:124
WBMPHeader
Definition
qwbmphandler.cpp:21
WBMPHeader::format
quint8 format
Definition
qwbmphandler.cpp:23
WBMPHeader::type
quint8 type
Definition
qwbmphandler.cpp:22
WBMPHeader::width
quint32 width
Definition
qwbmphandler.cpp:24
WBMPHeader::height
quint32 height
Definition
qwbmphandler.cpp:25
qtimageformats
src
plugins
imageformats
wbmp
qwbmphandler.cpp
Generated on
for Qt by
1.18.0