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