Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
4#include "qwbmphandler_p.h"
5
13#include <qimage.h>
14#include <qvariant.h>
15
17
18// This struct represents header of WBMP image file
20{
21 quint8 type; // Type of WBMP image (always equal to 0)
22 quint8 format; // Format of WBMP image
23 quint32 width; // Width of the image already decoded from multibyte integer
24 quint32 height; // Height of the image already decoded from multibyte integer
25};
26#define WBMPFIXEDHEADER_SIZE 2
27
28// Data renderers and writers which takes care of data alignment endiness and stuff
30{
31 quint32 res = 0;
32
33 quint8 c;
34 unsigned int count = 0;
35 do {
36 // Do not allow to read longer
37 // then we can store in num
38 if (++count > sizeof(*num))
39 return false;
40
41 if (!iodev->getChar(reinterpret_cast<char *>(&c)))
42 return false;
43
44 res = (res << 7) | (c & 0x7F);
45
46 } while (c & 0x80);
47
48 *num = res;
49 return true;
50}
51
53{
54 quint64 tmp = num & 0x7F;
55 num >>= 7;
56
57 while (num) {
58 quint8 c = num & 0x7F;
59 num = num >> 7;
60 tmp = (tmp << 8) | (c | 0x80);
61 }
62
63 while (tmp) {
64 quint8 c = tmp & 0xFF;
65 if (!iodev->putChar(c))
66 return false;
67 tmp >>= 8;
68 }
69 return true;
70}
71
72static bool readWBMPHeader(QIODevice *iodev, WBMPHeader *hdr)
73{
74 if (!iodev)
75 return false;
76
78 if (iodev->read(reinterpret_cast<char *>(tmp), WBMPFIXEDHEADER_SIZE) == WBMPFIXEDHEADER_SIZE) {
79 hdr->type = tmp[0];
80 hdr->format = tmp[1];
81 } else {
82 return false;
83 }
84
85 if (readMultiByteInt(iodev, &hdr->width)
86 && readMultiByteInt(iodev, &hdr->height)) {
87 return true;
88 }
89 return false;
90}
91
92static bool writeWBMPHeader(QIODevice *iodev, const WBMPHeader &hdr)
93{
94 if (iodev) {
96 tmp[0] = hdr.type;
97 tmp[1] = hdr.format;
98 if (iodev->write(reinterpret_cast<char *>(tmp), WBMPFIXEDHEADER_SIZE) != WBMPFIXEDHEADER_SIZE)
99 return false;
100
101 if (writeMultiByteInt(iodev, hdr.width) &&
102 writeMultiByteInt(iodev, hdr.height))
103 return true;
104 }
105 return false;
106}
107
108static bool writeWBMPData(QIODevice *iodev, const QImage &image)
109{
110 if (iodev) {
111 int h = image.height();
112 int bpl = (image.width() + 7) / 8;
113
114 for (int l=0; l<h; l++) {
115 if (iodev->write(reinterpret_cast<const char *>(image.constScanLine(l)), bpl) != bpl)
116 return false;
117 }
118 return true;
119 }
120 return false;
121}
122
123static bool readWBMPData(QIODevice *iodev, QImage &image)
124{
125 if (iodev) {
126 int h = image.height();
127 int bpl = (image.width() + 7) / 8;
128
129 for (int l = 0; l < h; l++) {
130 if (iodev->read(reinterpret_cast<char *>(image.scanLine(l)), bpl) != bpl)
131 return false;
132 }
133 return true;
134 }
135 return false;
136}
137
139{
140public:
141 WBMPReader(QIODevice *iodevice);
142
144 bool writeImage(QImage image);
145
146 static bool canRead(QIODevice *iodevice);
147
148private:
149 QIODevice *iodev;
150 WBMPHeader hdr;
151};
152
153// WBMP common reader and writer implementation
154WBMPReader::WBMPReader(QIODevice *iodevice) : iodev(iodevice)
155{
156 memset(&hdr, 0, sizeof(hdr));
157}
158
160{
161 if (!readWBMPHeader(iodev, &hdr))
162 return QImage();
163
166 return QImage();
167 if (!readWBMPData(iodev, image))
168 return QImage();
169
170 return image;
171}
172
174{
175 if (image.format() != QImage::Format_Mono)
176 image = image.convertToFormat(QImage::Format_Mono);
177
178 if (image.colorTable().at(0) == image.colorTable().at(1)) {
179 // degenerate image: actually blank.
180 image.fill((qGray(image.colorTable().at(0)) < 128) ? 0 : 1);
181 } else if (qGray(image.colorTable().at(0)) > qGray(image.colorTable().at(1))) {
182 // Conform to WBMP's convention about black and white
183 image.invertPixels();
184 }
185
186 hdr.type = 0;
187 hdr.format = 0;
188 hdr.width = image.width();
189 hdr.height = image.height();
190
191 if (!writeWBMPHeader(iodev, hdr))
192 return false;
193
194 if (!writeWBMPData(iodev, image))
195 return false;
196
197 return true;
198}
199
201{
202 if (device) {
203
204 if (device->isSequential())
205 return false;
206
207 // Save previous position
208 qint64 oldPos = device->pos();
209
210 WBMPHeader hdr;
211 if (readWBMPHeader(device, &hdr)) {
212 if ((hdr.type == 0) && (hdr.format == 0)) {
213 const qint64 imageSize = hdr.height * ((qint64(hdr.width) + 7) / 8);
214 qint64 available = device->bytesAvailable();
215 device->seek(oldPos);
216 return (imageSize == available);
217 }
218 }
219 device->seek(oldPos);
220 }
221 return false;
222}
223
231
236{
237 delete m_reader;
238}
239
245{
246 bool bCanRead = false;
247
249 if (device) {
250 bCanRead = QWbmpHandler::canRead(device);
251 if (bCanRead)
252 setFormat("wbmp");
253
254 } else {
255 qWarning("QWbmpHandler::canRead() called with no device");
256 }
257
258 return bCanRead;
259}
260
264{
265 bool bSuccess = false;
266 QImage img = m_reader->readImage();
267
268 if (!img.isNull()) {
269 bSuccess = true;
270 *image = img;
271 }
272
273 return bSuccess;
274}
275
279{
280 if (image.isNull())
281 return false;
282
283 return m_reader->writeImage(image);
284}
285
290{
293 if (device->isSequential())
294 return QVariant();
295
296 // Save old position
297 qint64 oldPos = device->pos();
298
299 WBMPHeader hdr;
300 if (readWBMPHeader(device, &hdr)) {
301 device->seek(oldPos);
302 return QSize(hdr.width, hdr.height);
303 }
304
305 device->seek(oldPos);
306
307 } else if (option == QImageIOHandler::ImageFormat) {
309 }
310
311 return QVariant();
312}
313
319
324
IOBluetoothDevice * device
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
bool putChar(char c)
Writes the character c to the device.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
bool getChar(char *c)
Reads one character from the device and stores it in c.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
ImageOption
This enum describes the different options supported by QImageIOHandler.
static bool allocateImage(QSize size, QImage::Format format, QImage *image)
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
\inmodule QtGui
Definition qimage.h:37
@ Format_Mono
Definition qimage.h:43
\inmodule QtCore
Definition qsize.h:25
\inmodule QtCore
Definition qvariant.h:65
bool canRead() const override
Verifies if some values (magic bytes) are set as expected in the header of the file.
QVariant option(ImageOption option) const override
Only Size option is supported.
~QWbmpHandler()
Destructor for QWbmpHandler.
QWbmpHandler(QIODevice *device)
Constructs an instance of QWbmpHandler initialized to use device.
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
bool write(const QImage &image) override
\reimp
bool read(QImage *image) override
\reimp
QImage readImage()
bool writeImage(QImage image)
WBMPReader(QIODevice *iodevice)
static bool canRead(QIODevice *iodevice)
Combined button and popup list for selecting options.
Definition image.cpp:4
#define qWarning
Definition qlogging.h:166
GLenum GLenum GLsizei count
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei imageSize
GLfloat GLfloat GLfloat GLfloat h
GLuint res
const GLubyte * c
GLint void * img
Definition qopenglext.h:233
GLuint GLenum option
GLuint num
constexpr int qGray(int r, int g, int b)
Definition qrgb.h:36
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
unsigned long long quint64
Definition qtypes.h:61
long long qint64
Definition qtypes.h:60
unsigned char quint8
Definition qtypes.h:46
static bool writeWBMPData(QIODevice *iodev, const QImage &image)
static bool writeWBMPHeader(QIODevice *iodev, const WBMPHeader &hdr)
static bool writeMultiByteInt(QIODevice *iodev, quint32 num)
#define WBMPFIXEDHEADER_SIZE
static bool readMultiByteInt(QIODevice *iodev, quint32 *num)
static bool readWBMPHeader(QIODevice *iodev, WBMPHeader *hdr)
static bool readWBMPData(QIODevice *iodev, QImage &image)
quint32 width
quint32 height