OpenCoverage

qxbmhandler.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/image/qxbmhandler.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#include <qplatformdefs.h>-
41#include "private/qxbmhandler_p.h"-
42-
43#ifndef QT_NO_IMAGEFORMAT_XBM-
44-
45#include <qimage.h>-
46#include <qiodevice.h>-
47#include <qvariant.h>-
48-
49#include <stdio.h>-
50#include <ctype.h>-
51-
52QT_BEGIN_NAMESPACE-
53-
54/*****************************************************************************-
55 X bitmap image read/write functions-
56 *****************************************************************************/-
57-
58static inline int hex2byte(char *p)-
59{-
60 return ((isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4) |
never executed: return ((isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4) | (isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10);
0
61 (isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10);
never executed: return ((isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4) | (isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10);
0
62}-
63-
64static bool read_xbm_header(QIODevice *device, int& w, int& h)-
65{-
66 const int buflen = 300;-
67 const int maxlen = 4096;-
68 char buf[buflen + 1];-
69 QRegExp r1(QLatin1String("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+"));-
70 QRegExp r2(QLatin1String("[0-9]+"));-
71-
72 qint64 readBytes = 0;-
73 qint64 totalReadBytes = 0;-
74-
75 buf[0] = '\0';-
76-
77 // skip initial comment, if any-
78 while (buf[0] != '#') {
buf[0] != '#'Description
TRUEnever evaluated
FALSEnever evaluated
0
79 readBytes = device->readLine(buf, buflen);-
80-
81 // if readBytes >= buflen, it's very probably not a C file-
82 if (readBytes <= 0 || readBytes >= buflen -1)
readBytes <= 0Description
TRUEnever evaluated
FALSEnever evaluated
readBytes >= buflen -1Description
TRUEnever evaluated
FALSEnever evaluated
0
83 return false;
never executed: return false;
0
84-
85 // limit xbm headers to the first 4k in the file to prevent-
86 // excessive reads on non-xbm files-
87 totalReadBytes += readBytes;-
88 if (totalReadBytes >= maxlen)
totalReadBytes >= maxlenDescription
TRUEnever evaluated
FALSEnever evaluated
0
89 return false;
never executed: return false;
0
90 }
never executed: end of block
0
91-
92 buf[readBytes - 1] = '\0';-
93 QString sbuf;-
94 sbuf = QString::fromLatin1(buf);-
95-
96 // "#define .._width <num>"-
97 if (r1.indexIn(sbuf) == 0 &&
r1.indexIn(sbuf) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
98 r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength())
r2.indexIn(sbu...atchedLength()Description
TRUEnever evaluated
FALSEnever evaluated
0
99 w = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt();
never executed: w = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt();
0
100-
101 // "#define .._height <num>"-
102 readBytes = device->readLine(buf, buflen);-
103 if (readBytes <= 0)
readBytes <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
104 return false;
never executed: return false;
0
105 buf[readBytes - 1] = '\0';-
106-
107 sbuf = QString::fromLatin1(buf);-
108-
109 if (r1.indexIn(sbuf) == 0 &&
r1.indexIn(sbuf) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
110 r2.indexIn(sbuf, r1.matchedLength()) == r1.matchedLength())
r2.indexIn(sbu...atchedLength()Description
TRUEnever evaluated
FALSEnever evaluated
0
111 h = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt();
never executed: h = QByteArray(&buf[r1.matchedLength()]).trimmed().toInt();
0
112-
113 // format error-
114 if (w <= 0 || w > 32767 || h <= 0 || h > 32767)
w <= 0Description
TRUEnever evaluated
FALSEnever evaluated
w > 32767Description
TRUEnever evaluated
FALSEnever evaluated
h <= 0Description
TRUEnever evaluated
FALSEnever evaluated
h > 32767Description
TRUEnever evaluated
FALSEnever evaluated
0
115 return false;
never executed: return false;
0
116-
117 return true;
never executed: return true;
0
118}-
119-
120static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage)-
121{-
122 const int buflen = 300;-
123 char buf[buflen + 1];-
124-
125 qint64 readBytes = 0;-
126-
127 char *p;-
128-
129 // scan for database-
130 do {-
131 if ((readBytes = device->readLine(buf, buflen)) <= 0) {
(readBytes = d... buflen)) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
132 // end of file-
133 return false;
never executed: return false;
0
134 }-
135-
136 buf[readBytes] = '\0';-
137 p = strstr(buf, "0x");-
138 } while (!p);
never executed: end of block
!pDescription
TRUEnever evaluated
FALSEnever evaluated
0
139-
140 if (outImage->size() != QSize(w, h) || outImage->format() != QImage::Format_MonoLSB) {
outImage->size...!= QSize(w, h)Description
TRUEnever evaluated
FALSEnever evaluated
outImage->form...Format_MonoLSBDescription
TRUEnever evaluated
FALSEnever evaluated
0
141 *outImage = QImage(w, h, QImage::Format_MonoLSB);-
142 if (outImage->isNull())
outImage->isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
143 return false;
never executed: return false;
0
144 }
never executed: end of block
0
145-
146 outImage->setColorCount(2);-
147 outImage->setColor(0, qRgb(255,255,255)); // white-
148 outImage->setColor(1, qRgb(0,0,0)); // black-
149-
150 int x = 0, y = 0;-
151 uchar *b = outImage->scanLine(0);-
152 w = (w+7)/8; // byte width-
153-
154 while (y < h) { // for all encoded bytes...
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
155 if (p) { // p = "0x.."
pDescription
TRUEnever evaluated
FALSEnever evaluated
0
156 *b++ = hex2byte(p+2);-
157 p += 2;-
158 if (++x == w && ++y < h) {
++x == wDescription
TRUEnever evaluated
FALSEnever evaluated
++y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
159 b = outImage->scanLine(y);-
160 x = 0;-
161 }
never executed: end of block
0
162 p = strstr(p, "0x");-
163 } else { // read another line
never executed: end of block
0
164 if ((readBytes = device->readLine(buf,buflen)) <= 0) // EOF ==> truncated image
(readBytes = d...,buflen)) <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
165 break;
never executed: break;
0
166 buf[readBytes] = '\0';-
167 p = strstr(buf, "0x");-
168 }
never executed: end of block
0
169 }-
170-
171 return true;
never executed: return true;
0
172}-
173-
174static bool read_xbm_image(QIODevice *device, QImage *outImage)-
175{-
176 int w = 0, h = 0;-
177 if (!read_xbm_header(device, w, h))
!read_xbm_header(device, w, h)Description
TRUEnever evaluated
FALSEnever evaluated
0
178 return false;
never executed: return false;
0
179 return read_xbm_body(device, w, h, outImage);
never executed: return read_xbm_body(device, w, h, outImage);
0
180}-
181-
182static bool write_xbm_image(const QImage &sourceImage, QIODevice *device, const QString &fileName)-
183{-
184 QImage image = sourceImage;-
185 int w = image.width();-
186 int h = image.height();-
187 int i;-
188 QString s = fileName; // get file base name-
189 int msize = s.length() + 100;-
190 char *buf = new char[msize];-
191-
192 qsnprintf(buf, msize, "#define %s_width %d\n", s.toUtf8().data(), w);-
193 device->write(buf, qstrlen(buf));-
194 qsnprintf(buf, msize, "#define %s_height %d\n", s.toUtf8().data(), h);-
195 device->write(buf, qstrlen(buf));-
196 qsnprintf(buf, msize, "static char %s_bits[] = {\n ", s.toUtf8().data());-
197 device->write(buf, qstrlen(buf));-
198-
199 if (image.format() != QImage::Format_MonoLSB)
image.format()...Format_MonoLSBDescription
TRUEnever evaluated
FALSEnever evaluated
0
200 image = image.convertToFormat(QImage::Format_MonoLSB);
never executed: image = image.convertToFormat(QImage::Format_MonoLSB);
0
201-
202 bool invert = qGray(image.color(0)) < qGray(image.color(1));-
203 char hexrep[16];-
204 for (i=0; i<10; i++)
i<10Description
TRUEnever evaluated
FALSEnever evaluated
0
205 hexrep[i] = '0' + i;
never executed: hexrep[i] = '0' + i;
0
206 for (i=10; i<16; i++)
i<16Description
TRUEnever evaluated
FALSEnever evaluated
0
207 hexrep[i] = 'a' -10 + i;
never executed: hexrep[i] = 'a' -10 + i;
0
208 if (invert) {
invertDescription
TRUEnever evaluated
FALSEnever evaluated
0
209 char t;-
210 for (i=0; i<8; i++) {
i<8Description
TRUEnever evaluated
FALSEnever evaluated
0
211 t = hexrep[15-i];-
212 hexrep[15-i] = hexrep[i];-
213 hexrep[i] = t;-
214 }
never executed: end of block
0
215 }
never executed: end of block
0
216 int bcnt = 0;-
217 char *p = buf;-
218 int bpl = (w+7)/8;-
219 for (int y = 0; y < h; ++y) {
y < hDescription
TRUEnever evaluated
FALSEnever evaluated
0
220 const uchar *b = image.constScanLine(y);-
221 for (i = 0; i < bpl; ++i) {
i < bplDescription
TRUEnever evaluated
FALSEnever evaluated
0
222 *p++ = '0'; *p++ = 'x';-
223 *p++ = hexrep[*b >> 4];-
224 *p++ = hexrep[*b++ & 0xf];-
225-
226 if (i < bpl - 1 || y < h - 1) {
i < bpl - 1Description
TRUEnever evaluated
FALSEnever evaluated
y < h - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
227 *p++ = ',';-
228 if (++bcnt > 14) {
++bcnt > 14Description
TRUEnever evaluated
FALSEnever evaluated
0
229 *p++ = '\n';-
230 *p++ = ' ';-
231 *p = '\0';-
232 if ((int)qstrlen(buf) != device->write(buf, qstrlen(buf))) {
(int)qstrlen(b... qstrlen(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
233 delete [] buf;-
234 return false;
never executed: return false;
0
235 }-
236 p = buf;-
237 bcnt = 0;-
238 }
never executed: end of block
0
239 }
never executed: end of block
0
240 }
never executed: end of block
0
241 }
never executed: end of block
0
242#if defined(_MSC_VER) && _MSC_VER >= 1400-
243 strcpy_s(p, sizeof(" };\n"), " };\n");-
244#else-
245 strcpy(p, " };\n");-
246#endif-
247 if ((int)qstrlen(buf) != device->write(buf, qstrlen(buf))) {
(int)qstrlen(b... qstrlen(buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
248 delete [] buf;-
249 return false;
never executed: return false;
0
250 }-
251-
252 delete [] buf;-
253 return true;
never executed: return true;
0
254}-
255-
256QXbmHandler::QXbmHandler()-
257 : state(Ready)-
258{-
259}
never executed: end of block
0
260-
261bool QXbmHandler::readHeader()-
262{-
263 state = Error;-
264 if (!read_xbm_header(device(), width, height))
!read_xbm_head...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
0
265 return false;
never executed: return false;
0
266 state = ReadHeader;-
267 return true;
never executed: return true;
0
268}-
269-
270bool QXbmHandler::canRead() const-
271{-
272 if (state == Ready && !canRead(device()))
state == ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!canRead(device())Description
TRUEnever evaluated
FALSEnever evaluated
0
273 return false;
never executed: return false;
0
274-
275 if (state != Error) {
state != ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
276 setFormat("xbm");-
277 return true;
never executed: return true;
0
278 }-
279-
280 return false;
never executed: return false;
0
281}-
282-
283bool QXbmHandler::canRead(QIODevice *device)-
284{-
285 QImage image;-
286-
287 // it's impossible to tell whether we can load an XBM or not when-
288 // it's from a sequential device, as the only way to do it is to-
289 // attempt to parse the whole image.-
290 if (device->isSequential())
device->isSequential()Description
TRUEnever evaluated
FALSEnever evaluated
0
291 return false;
never executed: return false;
0
292-
293 qint64 oldPos = device->pos();-
294 bool success = read_xbm_image(device, &image);-
295 device->seek(oldPos);-
296-
297 return success;
never executed: return success;
0
298}-
299-
300bool QXbmHandler::read(QImage *image)-
301{-
302 if (state == Error)
state == ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
303 return false;
never executed: return false;
0
304-
305 if (state == Ready && !readHeader()) {
state == ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!readHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
306 state = Error;-
307 return false;
never executed: return false;
0
308 }-
309-
310 if (!read_xbm_body(device(), width, height, image)) {
!read_xbm_body...height, image)Description
TRUEnever evaluated
FALSEnever evaluated
0
311 state = Error;-
312 return false;
never executed: return false;
0
313 }-
314-
315 state = Ready;-
316 return true;
never executed: return true;
0
317}-
318-
319bool QXbmHandler::write(const QImage &image)-
320{-
321 return write_xbm_image(image, device(), fileName);
never executed: return write_xbm_image(image, device(), fileName);
0
322}-
323-
324bool QXbmHandler::supportsOption(ImageOption option) const-
325{-
326 return option == Name
never executed: return option == Name || option == Size || option == ImageFormat;
0
327 || option == Size
never executed: return option == Name || option == Size || option == ImageFormat;
0
328 || option == ImageFormat;
never executed: return option == Name || option == Size || option == ImageFormat;
0
329}-
330-
331QVariant QXbmHandler::option(ImageOption option) const-
332{-
333 if (option == Name) {
option == NameDescription
TRUEnever evaluated
FALSEnever evaluated
0
334 return fileName;
never executed: return fileName;
0
335 } else if (option == Size) {
option == SizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
336 if (state == Error)
state == ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
337 return QVariant();
never executed: return QVariant();
0
338 if (state == Ready && !const_cast<QXbmHandler*>(this)->readHeader())
state == ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!const_cast<QX...->readHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
339 return QVariant();
never executed: return QVariant();
0
340 return QSize(width, height);
never executed: return QSize(width, height);
0
341 } else if (option == ImageFormat) {
option == ImageFormatDescription
TRUEnever evaluated
FALSEnever evaluated
0
342 return QImage::Format_MonoLSB;
never executed: return QImage::Format_MonoLSB;
0
343 }-
344 return QVariant();
never executed: return QVariant();
0
345}-
346-
347void QXbmHandler::setOption(ImageOption option, const QVariant &value)-
348{-
349 if (option == Name)
option == NameDescription
TRUEnever evaluated
FALSEnever evaluated
0
350 fileName = value.toString();
never executed: fileName = value.toString();
0
351}
never executed: end of block
0
352-
353QByteArray QXbmHandler::name() const-
354{-
355 return "xbm";
never executed: return "xbm";
0
356}-
357-
358QT_END_NAMESPACE-
359-
360#endif // QT_NO_IMAGEFORMAT_XBM-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9