Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/gui/image/qppmhandler.cpp |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 "private/qppmhandler_p.h" | - | ||||||||||||||||||||||||||||||
41 | - | |||||||||||||||||||||||||||||||
42 | #ifndef QT_NO_IMAGEFORMAT_PPM | - | ||||||||||||||||||||||||||||||
43 | - | |||||||||||||||||||||||||||||||
44 | #include <qimage.h> | - | ||||||||||||||||||||||||||||||
45 | #include <qvariant.h> | - | ||||||||||||||||||||||||||||||
46 | #include <qvector.h> | - | ||||||||||||||||||||||||||||||
47 | #include <ctype.h> | - | ||||||||||||||||||||||||||||||
48 | - | |||||||||||||||||||||||||||||||
49 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||||||||||||||
50 | - | |||||||||||||||||||||||||||||||
51 | /***************************************************************************** | - | ||||||||||||||||||||||||||||||
52 | PBM/PGM/PPM (ASCII and RAW) image read/write functions | - | ||||||||||||||||||||||||||||||
53 | *****************************************************************************/ | - | ||||||||||||||||||||||||||||||
54 | - | |||||||||||||||||||||||||||||||
55 | static void discard_pbm_line(QIODevice *d) | - | ||||||||||||||||||||||||||||||
56 | { | - | ||||||||||||||||||||||||||||||
57 | const int buflen = 100; | - | ||||||||||||||||||||||||||||||
58 | char buf[buflen]; | - | ||||||||||||||||||||||||||||||
59 | int res = 0; | - | ||||||||||||||||||||||||||||||
60 | do { | - | ||||||||||||||||||||||||||||||
61 | res = d->readLine(buf, buflen); | - | ||||||||||||||||||||||||||||||
62 | } while (res > 0 && buf[res-1] != '\n'); never executed: end of block
| 0 | ||||||||||||||||||||||||||||||
63 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
64 | - | |||||||||||||||||||||||||||||||
65 | static int read_pbm_int(QIODevice *d) | - | ||||||||||||||||||||||||||||||
66 | { | - | ||||||||||||||||||||||||||||||
67 | char c; | - | ||||||||||||||||||||||||||||||
68 | int val = -1; | - | ||||||||||||||||||||||||||||||
69 | bool digit; | - | ||||||||||||||||||||||||||||||
70 | for (;;) { | - | ||||||||||||||||||||||||||||||
71 | if (!d->getChar(&c)) // end of file
| 0 | ||||||||||||||||||||||||||||||
72 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
73 | digit = isdigit((uchar) c); | - | ||||||||||||||||||||||||||||||
74 | if (val != -1) {
| 0 | ||||||||||||||||||||||||||||||
75 | if (digit) {
| 0 | ||||||||||||||||||||||||||||||
76 | val = 10*val + c - '0'; | - | ||||||||||||||||||||||||||||||
77 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||||||||
78 | } else { | - | ||||||||||||||||||||||||||||||
79 | if (c == '#') // comment
| 0 | ||||||||||||||||||||||||||||||
80 | discard_pbm_line(d); never executed: discard_pbm_line(d); | 0 | ||||||||||||||||||||||||||||||
81 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
82 | } | - | ||||||||||||||||||||||||||||||
83 | } | - | ||||||||||||||||||||||||||||||
84 | if (digit) // first digit
| 0 | ||||||||||||||||||||||||||||||
85 | val = c - '0'; never executed: val = c - '0'; | 0 | ||||||||||||||||||||||||||||||
86 | else if (isspace((uchar) c))
| 0 | ||||||||||||||||||||||||||||||
87 | continue; never executed: continue; | 0 | ||||||||||||||||||||||||||||||
88 | else if (c == '#')
| 0 | ||||||||||||||||||||||||||||||
89 | discard_pbm_line(d); never executed: discard_pbm_line(d); | 0 | ||||||||||||||||||||||||||||||
90 | else | - | ||||||||||||||||||||||||||||||
91 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
92 | } | - | ||||||||||||||||||||||||||||||
93 | return val; never executed: return val; | 0 | ||||||||||||||||||||||||||||||
94 | } | - | ||||||||||||||||||||||||||||||
95 | - | |||||||||||||||||||||||||||||||
96 | static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int& mcc) | - | ||||||||||||||||||||||||||||||
97 | { | - | ||||||||||||||||||||||||||||||
98 | char buf[3]; | - | ||||||||||||||||||||||||||||||
99 | if (device->read(buf, 3) != 3) // read P[1-6]<white-space>
| 0 | ||||||||||||||||||||||||||||||
100 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
101 | - | |||||||||||||||||||||||||||||||
102 | if (!(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2])))
| 0 | ||||||||||||||||||||||||||||||
103 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
104 | - | |||||||||||||||||||||||||||||||
105 | type = buf[1]; | - | ||||||||||||||||||||||||||||||
106 | if (type < '1' || type > '6')
| 0 | ||||||||||||||||||||||||||||||
107 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
108 | - | |||||||||||||||||||||||||||||||
109 | w = read_pbm_int(device); // get image width | - | ||||||||||||||||||||||||||||||
110 | h = read_pbm_int(device); // get image height | - | ||||||||||||||||||||||||||||||
111 | - | |||||||||||||||||||||||||||||||
112 | if (type == '1' || type == '4')
| 0 | ||||||||||||||||||||||||||||||
113 | mcc = 1; // ignore max color component never executed: mcc = 1; | 0 | ||||||||||||||||||||||||||||||
114 | else | - | ||||||||||||||||||||||||||||||
115 | mcc = read_pbm_int(device); // get max color component never executed: mcc = read_pbm_int(device); | 0 | ||||||||||||||||||||||||||||||
116 | - | |||||||||||||||||||||||||||||||
117 | if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0)
| 0 | ||||||||||||||||||||||||||||||
118 | return false; // weird P.M image never executed: return false; | 0 | ||||||||||||||||||||||||||||||
119 | - | |||||||||||||||||||||||||||||||
120 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
121 | } | - | ||||||||||||||||||||||||||||||
122 | - | |||||||||||||||||||||||||||||||
123 | static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, QImage *outImage) | - | ||||||||||||||||||||||||||||||
124 | { | - | ||||||||||||||||||||||||||||||
125 | int nbits, y; | - | ||||||||||||||||||||||||||||||
126 | int pbm_bpl; | - | ||||||||||||||||||||||||||||||
127 | bool raw; | - | ||||||||||||||||||||||||||||||
128 | - | |||||||||||||||||||||||||||||||
129 | QImage::Format format; | - | ||||||||||||||||||||||||||||||
130 | switch (type) { | - | ||||||||||||||||||||||||||||||
131 | case '1': // ascii PBM never executed: case '1': | 0 | ||||||||||||||||||||||||||||||
132 | case '4': // raw PBM never executed: case '4': | 0 | ||||||||||||||||||||||||||||||
133 | nbits = 1; | - | ||||||||||||||||||||||||||||||
134 | format = QImage::Format_Mono; | - | ||||||||||||||||||||||||||||||
135 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
136 | case '2': // ascii PGM never executed: case '2': | 0 | ||||||||||||||||||||||||||||||
137 | case '5': // raw PGM never executed: case '5': | 0 | ||||||||||||||||||||||||||||||
138 | nbits = 8; | - | ||||||||||||||||||||||||||||||
139 | format = QImage::Format_Grayscale8; | - | ||||||||||||||||||||||||||||||
140 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
141 | case '3': // ascii PPM never executed: case '3': | 0 | ||||||||||||||||||||||||||||||
142 | case '6': // raw PPM never executed: case '6': | 0 | ||||||||||||||||||||||||||||||
143 | nbits = 32; | - | ||||||||||||||||||||||||||||||
144 | format = QImage::Format_RGB32; | - | ||||||||||||||||||||||||||||||
145 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
146 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
147 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
148 | } | - | ||||||||||||||||||||||||||||||
149 | raw = type >= '4'; | - | ||||||||||||||||||||||||||||||
150 | - | |||||||||||||||||||||||||||||||
151 | int maxc = mcc; | - | ||||||||||||||||||||||||||||||
152 | if (maxc > 255)
| 0 | ||||||||||||||||||||||||||||||
153 | maxc = 255; never executed: maxc = 255; | 0 | ||||||||||||||||||||||||||||||
154 | if (outImage->size() != QSize(w, h) || outImage->format() != format) {
| 0 | ||||||||||||||||||||||||||||||
155 | *outImage = QImage(w, h, format); | - | ||||||||||||||||||||||||||||||
156 | if (outImage->isNull())
| 0 | ||||||||||||||||||||||||||||||
157 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
158 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
159 | - | |||||||||||||||||||||||||||||||
160 | pbm_bpl = (nbits*w+7)/8; // bytes per scanline in PBM | - | ||||||||||||||||||||||||||||||
161 | - | |||||||||||||||||||||||||||||||
162 | if (raw) { // read raw data
| 0 | ||||||||||||||||||||||||||||||
163 | if (nbits == 32) { // type 6
| 0 | ||||||||||||||||||||||||||||||
164 | pbm_bpl = mcc < 256 ? 3*w : 6*w;
| 0 | ||||||||||||||||||||||||||||||
165 | uchar *buf24 = new uchar[pbm_bpl], *b; | - | ||||||||||||||||||||||||||||||
166 | QRgb *p; | - | ||||||||||||||||||||||||||||||
167 | QRgb *end; | - | ||||||||||||||||||||||||||||||
168 | for (y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
169 | if (device->read((char *)buf24, pbm_bpl) != pbm_bpl) {
| 0 | ||||||||||||||||||||||||||||||
170 | delete[] buf24; | - | ||||||||||||||||||||||||||||||
171 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
172 | } | - | ||||||||||||||||||||||||||||||
173 | p = (QRgb *)outImage->scanLine(y); | - | ||||||||||||||||||||||||||||||
174 | end = p + w; | - | ||||||||||||||||||||||||||||||
175 | b = buf24; | - | ||||||||||||||||||||||||||||||
176 | while (p < end) {
| 0 | ||||||||||||||||||||||||||||||
177 | if (mcc < 256) {
| 0 | ||||||||||||||||||||||||||||||
178 | *p++ = qRgb(b[0],b[1],b[2]); | - | ||||||||||||||||||||||||||||||
179 | b += 3; | - | ||||||||||||||||||||||||||||||
180 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
181 | *p++ = qRgb(((int(b[0]) * 256 + int(b[1]) + 1) * 256) / (mcc + 1) - 1, | - | ||||||||||||||||||||||||||||||
182 | ((int(b[2]) * 256 + int(b[3]) + 1) * 256) / (mcc + 1) - 1, | - | ||||||||||||||||||||||||||||||
183 | ((int(b[4]) * 256 + int(b[5]) + 1) * 256) / (mcc + 1) - 1); | - | ||||||||||||||||||||||||||||||
184 | b += 6; | - | ||||||||||||||||||||||||||||||
185 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
186 | } | - | ||||||||||||||||||||||||||||||
187 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
188 | delete[] buf24; | - | ||||||||||||||||||||||||||||||
189 | } else { // type 4,5 never executed: end of block | 0 | ||||||||||||||||||||||||||||||
190 | for (y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
191 | if (device->read((char *)outImage->scanLine(y), pbm_bpl)
| 0 | ||||||||||||||||||||||||||||||
192 | != pbm_bpl)
| 0 | ||||||||||||||||||||||||||||||
193 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
194 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
195 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
196 | } else { // read ascii data | - | ||||||||||||||||||||||||||||||
197 | uchar *p; | - | ||||||||||||||||||||||||||||||
198 | int n; | - | ||||||||||||||||||||||||||||||
199 | char buf; | - | ||||||||||||||||||||||||||||||
200 | for (y = 0; (y < h) && (device->peek(&buf, 1) == 1); y++) {
| 0 | ||||||||||||||||||||||||||||||
201 | p = outImage->scanLine(y); | - | ||||||||||||||||||||||||||||||
202 | n = pbm_bpl; | - | ||||||||||||||||||||||||||||||
203 | if (nbits == 1) {
| 0 | ||||||||||||||||||||||||||||||
204 | int b; | - | ||||||||||||||||||||||||||||||
205 | int bitsLeft = w; | - | ||||||||||||||||||||||||||||||
206 | while (n--) {
| 0 | ||||||||||||||||||||||||||||||
207 | b = 0; | - | ||||||||||||||||||||||||||||||
208 | for (int i=0; i<8; i++) {
| 0 | ||||||||||||||||||||||||||||||
209 | if (i < bitsLeft)
| 0 | ||||||||||||||||||||||||||||||
210 | b = (b << 1) | (read_pbm_int(device) & 1); never executed: b = (b << 1) | (read_pbm_int(device) & 1); | 0 | ||||||||||||||||||||||||||||||
211 | else | - | ||||||||||||||||||||||||||||||
212 | b = (b << 1) | (0 & 1); // pad it our self if we need to never executed: b = (b << 1) | (0 & 1); | 0 | ||||||||||||||||||||||||||||||
213 | } | - | ||||||||||||||||||||||||||||||
214 | bitsLeft -= 8; | - | ||||||||||||||||||||||||||||||
215 | *p++ = b; | - | ||||||||||||||||||||||||||||||
216 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
217 | } else if (nbits == 8) { never executed: end of block
| 0 | ||||||||||||||||||||||||||||||
218 | if (mcc == 255) {
| 0 | ||||||||||||||||||||||||||||||
219 | while (n--) {
| 0 | ||||||||||||||||||||||||||||||
220 | *p++ = read_pbm_int(device); | - | ||||||||||||||||||||||||||||||
221 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
222 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
223 | while (n--) {
| 0 | ||||||||||||||||||||||||||||||
224 | *p++ = read_pbm_int(device) * 255 / mcc; | - | ||||||||||||||||||||||||||||||
225 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
226 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
227 | } else { // 32 bits | - | ||||||||||||||||||||||||||||||
228 | n /= 4; | - | ||||||||||||||||||||||||||||||
229 | int r, g, b; | - | ||||||||||||||||||||||||||||||
230 | if (mcc == maxc) {
| 0 | ||||||||||||||||||||||||||||||
231 | while (n--) {
| 0 | ||||||||||||||||||||||||||||||
232 | r = read_pbm_int(device); | - | ||||||||||||||||||||||||||||||
233 | g = read_pbm_int(device); | - | ||||||||||||||||||||||||||||||
234 | b = read_pbm_int(device); | - | ||||||||||||||||||||||||||||||
235 | *((QRgb*)p) = qRgb(r, g, b); | - | ||||||||||||||||||||||||||||||
236 | p += 4; | - | ||||||||||||||||||||||||||||||
237 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
238 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
239 | while (n--) {
| 0 | ||||||||||||||||||||||||||||||
240 | r = read_pbm_int(device) * maxc / mcc; | - | ||||||||||||||||||||||||||||||
241 | g = read_pbm_int(device) * maxc / mcc; | - | ||||||||||||||||||||||||||||||
242 | b = read_pbm_int(device) * maxc / mcc; | - | ||||||||||||||||||||||||||||||
243 | *((QRgb*)p) = qRgb(r, g, b); | - | ||||||||||||||||||||||||||||||
244 | p += 4; | - | ||||||||||||||||||||||||||||||
245 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
246 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
247 | } | - | ||||||||||||||||||||||||||||||
248 | } | - | ||||||||||||||||||||||||||||||
249 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
250 | - | |||||||||||||||||||||||||||||||
251 | if (format == QImage::Format_Mono) {
| 0 | ||||||||||||||||||||||||||||||
252 | outImage->setColorCount(2); | - | ||||||||||||||||||||||||||||||
253 | outImage->setColor(0, qRgb(255,255,255)); // white | - | ||||||||||||||||||||||||||||||
254 | outImage->setColor(1, qRgb(0,0,0)); // black | - | ||||||||||||||||||||||||||||||
255 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
256 | - | |||||||||||||||||||||||||||||||
257 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
258 | } | - | ||||||||||||||||||||||||||||||
259 | - | |||||||||||||||||||||||||||||||
260 | static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QByteArray &sourceFormat) | - | ||||||||||||||||||||||||||||||
261 | { | - | ||||||||||||||||||||||||||||||
262 | QByteArray str; | - | ||||||||||||||||||||||||||||||
263 | QImage image = sourceImage; | - | ||||||||||||||||||||||||||||||
264 | QByteArray format = sourceFormat; | - | ||||||||||||||||||||||||||||||
265 | - | |||||||||||||||||||||||||||||||
266 | format = format.left(3); // ignore RAW part | - | ||||||||||||||||||||||||||||||
267 | bool gray = format == "pgm"; | - | ||||||||||||||||||||||||||||||
268 | - | |||||||||||||||||||||||||||||||
269 | if (format == "pbm") {
| 0 | ||||||||||||||||||||||||||||||
270 | image = image.convertToFormat(QImage::Format_Mono); | - | ||||||||||||||||||||||||||||||
271 | } else if (gray) { never executed: end of block
| 0 | ||||||||||||||||||||||||||||||
272 | image = image.convertToFormat(QImage::Format_Grayscale8); | - | ||||||||||||||||||||||||||||||
273 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
274 | switch (image.format()) { | - | ||||||||||||||||||||||||||||||
275 | case QImage::Format_Mono: never executed: case QImage::Format_Mono: | 0 | ||||||||||||||||||||||||||||||
276 | case QImage::Format_MonoLSB: never executed: case QImage::Format_MonoLSB: | 0 | ||||||||||||||||||||||||||||||
277 | image = image.convertToFormat(QImage::Format_Indexed8); | - | ||||||||||||||||||||||||||||||
278 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
279 | case QImage::Format_Indexed8: never executed: case QImage::Format_Indexed8: | 0 | ||||||||||||||||||||||||||||||
280 | case QImage::Format_RGB32: never executed: case QImage::Format_RGB32: | 0 | ||||||||||||||||||||||||||||||
281 | case QImage::Format_ARGB32: never executed: case QImage::Format_ARGB32: | 0 | ||||||||||||||||||||||||||||||
282 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
283 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
284 | if (image.hasAlphaChannel())
| 0 | ||||||||||||||||||||||||||||||
285 | image = image.convertToFormat(QImage::Format_ARGB32); never executed: image = image.convertToFormat(QImage::Format_ARGB32); | 0 | ||||||||||||||||||||||||||||||
286 | else | - | ||||||||||||||||||||||||||||||
287 | image = image.convertToFormat(QImage::Format_RGB32); never executed: image = image.convertToFormat(QImage::Format_RGB32); | 0 | ||||||||||||||||||||||||||||||
288 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
289 | } | - | ||||||||||||||||||||||||||||||
290 | } | - | ||||||||||||||||||||||||||||||
291 | - | |||||||||||||||||||||||||||||||
292 | if (image.depth() == 1 && image.colorCount() == 2) {
| 0 | ||||||||||||||||||||||||||||||
293 | if (qGray(image.color(0)) < qGray(image.color(1))) {
| 0 | ||||||||||||||||||||||||||||||
294 | // 0=dark/black, 1=light/white - invert | - | ||||||||||||||||||||||||||||||
295 | image.detach(); | - | ||||||||||||||||||||||||||||||
296 | for (int y=0; y<image.height(); y++) {
| 0 | ||||||||||||||||||||||||||||||
297 | uchar *p = image.scanLine(y); | - | ||||||||||||||||||||||||||||||
298 | uchar *end = p + image.bytesPerLine(); | - | ||||||||||||||||||||||||||||||
299 | while (p < end)
| 0 | ||||||||||||||||||||||||||||||
300 | *p++ ^= 0xff; never executed: *p++ ^= 0xff; | 0 | ||||||||||||||||||||||||||||||
301 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
302 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
303 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
304 | - | |||||||||||||||||||||||||||||||
305 | uint w = image.width(); | - | ||||||||||||||||||||||||||||||
306 | uint h = image.height(); | - | ||||||||||||||||||||||||||||||
307 | - | |||||||||||||||||||||||||||||||
308 | str = "P\n"; | - | ||||||||||||||||||||||||||||||
309 | str += QByteArray::number(w); | - | ||||||||||||||||||||||||||||||
310 | str += ' '; | - | ||||||||||||||||||||||||||||||
311 | str += QByteArray::number(h); | - | ||||||||||||||||||||||||||||||
312 | str += '\n'; | - | ||||||||||||||||||||||||||||||
313 | - | |||||||||||||||||||||||||||||||
314 | switch (image.depth()) { | - | ||||||||||||||||||||||||||||||
315 | case 1: { never executed: case 1: | 0 | ||||||||||||||||||||||||||||||
316 | str.insert(1, '4'); | - | ||||||||||||||||||||||||||||||
317 | if (out->write(str, str.length()) != str.length())
| 0 | ||||||||||||||||||||||||||||||
318 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
319 | w = (w+7)/8; | - | ||||||||||||||||||||||||||||||
320 | for (uint y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
321 | uchar* line = image.scanLine(y); | - | ||||||||||||||||||||||||||||||
322 | if (w != (uint)out->write((char*)line, w))
| 0 | ||||||||||||||||||||||||||||||
323 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
324 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
325 | } | - | ||||||||||||||||||||||||||||||
326 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
327 | - | |||||||||||||||||||||||||||||||
328 | case 8: { never executed: case 8: | 0 | ||||||||||||||||||||||||||||||
329 | str.insert(1, gray ? '5' : '6'); | - | ||||||||||||||||||||||||||||||
330 | str.append("255\n"); | - | ||||||||||||||||||||||||||||||
331 | if (out->write(str, str.length()) != str.length())
| 0 | ||||||||||||||||||||||||||||||
332 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
333 | uint bpl = w * (gray ? 1 : 3); | - | ||||||||||||||||||||||||||||||
334 | uchar *buf = new uchar[bpl]; | - | ||||||||||||||||||||||||||||||
335 | if (image.format() == QImage::Format_Indexed8) {
| 0 | ||||||||||||||||||||||||||||||
336 | QVector<QRgb> color = image.colorTable(); | - | ||||||||||||||||||||||||||||||
337 | for (uint y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
338 | const uchar *b = image.constScanLine(y); | - | ||||||||||||||||||||||||||||||
339 | uchar *p = buf; | - | ||||||||||||||||||||||||||||||
340 | uchar *end = buf+bpl; | - | ||||||||||||||||||||||||||||||
341 | if (gray) {
| 0 | ||||||||||||||||||||||||||||||
342 | while (p < end) {
| 0 | ||||||||||||||||||||||||||||||
343 | uchar g = (uchar)qGray(color[*b++]); | - | ||||||||||||||||||||||||||||||
344 | *p++ = g; | - | ||||||||||||||||||||||||||||||
345 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
346 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
347 | while (p < end) {
| 0 | ||||||||||||||||||||||||||||||
348 | QRgb rgb = color[*b++]; | - | ||||||||||||||||||||||||||||||
349 | *p++ = qRed(rgb); | - | ||||||||||||||||||||||||||||||
350 | *p++ = qGreen(rgb); | - | ||||||||||||||||||||||||||||||
351 | *p++ = qBlue(rgb); | - | ||||||||||||||||||||||||||||||
352 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
353 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
354 | if (bpl != (uint)out->write((char*)buf, bpl))
| 0 | ||||||||||||||||||||||||||||||
355 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
356 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
357 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
358 | for (uint y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
359 | const uchar *b = image.constScanLine(y); | - | ||||||||||||||||||||||||||||||
360 | uchar *p = buf; | - | ||||||||||||||||||||||||||||||
361 | uchar *end = buf + bpl; | - | ||||||||||||||||||||||||||||||
362 | if (gray) {
| 0 | ||||||||||||||||||||||||||||||
363 | while (p < end)
| 0 | ||||||||||||||||||||||||||||||
364 | *p++ = *b++; never executed: *p++ = *b++; | 0 | ||||||||||||||||||||||||||||||
365 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
366 | while (p < end) {
| 0 | ||||||||||||||||||||||||||||||
367 | uchar color = *b++; | - | ||||||||||||||||||||||||||||||
368 | *p++ = color; | - | ||||||||||||||||||||||||||||||
369 | *p++ = color; | - | ||||||||||||||||||||||||||||||
370 | *p++ = color; | - | ||||||||||||||||||||||||||||||
371 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
372 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
373 | if (bpl != (uint)out->write((char*)buf, bpl))
| 0 | ||||||||||||||||||||||||||||||
374 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
375 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
376 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
377 | delete [] buf; | - | ||||||||||||||||||||||||||||||
378 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
379 | } | - | ||||||||||||||||||||||||||||||
380 | - | |||||||||||||||||||||||||||||||
381 | case 32: { never executed: case 32: | 0 | ||||||||||||||||||||||||||||||
382 | str.insert(1, '6'); | - | ||||||||||||||||||||||||||||||
383 | str.append("255\n"); | - | ||||||||||||||||||||||||||||||
384 | if (out->write(str, str.length()) != str.length())
| 0 | ||||||||||||||||||||||||||||||
385 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
386 | uint bpl = w * 3; | - | ||||||||||||||||||||||||||||||
387 | uchar *buf = new uchar[bpl]; | - | ||||||||||||||||||||||||||||||
388 | for (uint y=0; y<h; y++) {
| 0 | ||||||||||||||||||||||||||||||
389 | const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y)); | - | ||||||||||||||||||||||||||||||
390 | uchar *p = buf; | - | ||||||||||||||||||||||||||||||
391 | uchar *end = buf+bpl; | - | ||||||||||||||||||||||||||||||
392 | while (p < end) {
| 0 | ||||||||||||||||||||||||||||||
393 | QRgb rgb = *b++; | - | ||||||||||||||||||||||||||||||
394 | *p++ = qRed(rgb); | - | ||||||||||||||||||||||||||||||
395 | *p++ = qGreen(rgb); | - | ||||||||||||||||||||||||||||||
396 | *p++ = qBlue(rgb); | - | ||||||||||||||||||||||||||||||
397 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
398 | if (bpl != (uint)out->write((char*)buf, bpl))
| 0 | ||||||||||||||||||||||||||||||
399 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
400 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
401 | delete [] buf; | - | ||||||||||||||||||||||||||||||
402 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
403 | } | - | ||||||||||||||||||||||||||||||
404 | - | |||||||||||||||||||||||||||||||
405 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
406 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
407 | } | - | ||||||||||||||||||||||||||||||
408 | - | |||||||||||||||||||||||||||||||
409 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
410 | } | - | ||||||||||||||||||||||||||||||
411 | - | |||||||||||||||||||||||||||||||
412 | QPpmHandler::QPpmHandler() | - | ||||||||||||||||||||||||||||||
413 | : state(Ready) | - | ||||||||||||||||||||||||||||||
414 | { | - | ||||||||||||||||||||||||||||||
415 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
416 | - | |||||||||||||||||||||||||||||||
417 | bool QPpmHandler::readHeader() | - | ||||||||||||||||||||||||||||||
418 | { | - | ||||||||||||||||||||||||||||||
419 | state = Error; | - | ||||||||||||||||||||||||||||||
420 | if (!read_pbm_header(device(), type, width, height, mcc))
| 0 | ||||||||||||||||||||||||||||||
421 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
422 | state = ReadHeader; | - | ||||||||||||||||||||||||||||||
423 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
424 | } | - | ||||||||||||||||||||||||||||||
425 | - | |||||||||||||||||||||||||||||||
426 | bool QPpmHandler::canRead() const | - | ||||||||||||||||||||||||||||||
427 | { | - | ||||||||||||||||||||||||||||||
428 | if (state == Ready && !canRead(device(), &subType))
| 0 | ||||||||||||||||||||||||||||||
429 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
430 | - | |||||||||||||||||||||||||||||||
431 | if (state != Error) {
| 0 | ||||||||||||||||||||||||||||||
432 | setFormat(subType); | - | ||||||||||||||||||||||||||||||
433 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
434 | } | - | ||||||||||||||||||||||||||||||
435 | - | |||||||||||||||||||||||||||||||
436 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
437 | } | - | ||||||||||||||||||||||||||||||
438 | - | |||||||||||||||||||||||||||||||
439 | bool QPpmHandler::canRead(QIODevice *device, QByteArray *subType) | - | ||||||||||||||||||||||||||||||
440 | { | - | ||||||||||||||||||||||||||||||
441 | if (!device) {
| 0 | ||||||||||||||||||||||||||||||
442 | qWarning("QPpmHandler::canRead() called with no device"); | - | ||||||||||||||||||||||||||||||
443 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
444 | } | - | ||||||||||||||||||||||||||||||
445 | - | |||||||||||||||||||||||||||||||
446 | char head[2]; | - | ||||||||||||||||||||||||||||||
447 | if (device->peek(head, sizeof(head)) != sizeof(head))
| 0 | ||||||||||||||||||||||||||||||
448 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
449 | - | |||||||||||||||||||||||||||||||
450 | if (head[0] != 'P')
| 0 | ||||||||||||||||||||||||||||||
451 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
452 | - | |||||||||||||||||||||||||||||||
453 | if (head[1] == '1' || head[1] == '4') {
| 0 | ||||||||||||||||||||||||||||||
454 | if (subType)
| 0 | ||||||||||||||||||||||||||||||
455 | *subType = "pbm"; never executed: *subType = "pbm"; | 0 | ||||||||||||||||||||||||||||||
456 | } else if (head[1] == '2' || head[1] == '5') { never executed: end of block
| 0 | ||||||||||||||||||||||||||||||
457 | if (subType)
| 0 | ||||||||||||||||||||||||||||||
458 | *subType = "pgm"; never executed: *subType = "pgm"; | 0 | ||||||||||||||||||||||||||||||
459 | } else if (head[1] == '3' || head[1] == '6') { never executed: end of block
| 0 | ||||||||||||||||||||||||||||||
460 | if (subType)
| 0 | ||||||||||||||||||||||||||||||
461 | *subType = "ppm"; never executed: *subType = "ppm"; | 0 | ||||||||||||||||||||||||||||||
462 | } else { never executed: end of block | 0 | ||||||||||||||||||||||||||||||
463 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
464 | } | - | ||||||||||||||||||||||||||||||
465 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
466 | } | - | ||||||||||||||||||||||||||||||
467 | - | |||||||||||||||||||||||||||||||
468 | bool QPpmHandler::read(QImage *image) | - | ||||||||||||||||||||||||||||||
469 | { | - | ||||||||||||||||||||||||||||||
470 | if (state == Error)
| 0 | ||||||||||||||||||||||||||||||
471 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
472 | - | |||||||||||||||||||||||||||||||
473 | if (state == Ready && !readHeader()) {
| 0 | ||||||||||||||||||||||||||||||
474 | state = Error; | - | ||||||||||||||||||||||||||||||
475 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
476 | } | - | ||||||||||||||||||||||||||||||
477 | - | |||||||||||||||||||||||||||||||
478 | if (!read_pbm_body(device(), type, width, height, mcc, image)) {
| 0 | ||||||||||||||||||||||||||||||
479 | state = Error; | - | ||||||||||||||||||||||||||||||
480 | return false; never executed: return false; | 0 | ||||||||||||||||||||||||||||||
481 | } | - | ||||||||||||||||||||||||||||||
482 | - | |||||||||||||||||||||||||||||||
483 | state = Ready; | - | ||||||||||||||||||||||||||||||
484 | return true; never executed: return true; | 0 | ||||||||||||||||||||||||||||||
485 | } | - | ||||||||||||||||||||||||||||||
486 | - | |||||||||||||||||||||||||||||||
487 | bool QPpmHandler::write(const QImage &image) | - | ||||||||||||||||||||||||||||||
488 | { | - | ||||||||||||||||||||||||||||||
489 | return write_pbm_image(device(), image, subType); never executed: return write_pbm_image(device(), image, subType); | 0 | ||||||||||||||||||||||||||||||
490 | } | - | ||||||||||||||||||||||||||||||
491 | - | |||||||||||||||||||||||||||||||
492 | bool QPpmHandler::supportsOption(ImageOption option) const | - | ||||||||||||||||||||||||||||||
493 | { | - | ||||||||||||||||||||||||||||||
494 | return option == SubType never executed: return option == SubType || option == Size || option == ImageFormat; | 0 | ||||||||||||||||||||||||||||||
495 | || option == Size never executed: return option == SubType || option == Size || option == ImageFormat; | 0 | ||||||||||||||||||||||||||||||
496 | || option == ImageFormat; never executed: return option == SubType || option == Size || option == ImageFormat; | 0 | ||||||||||||||||||||||||||||||
497 | } | - | ||||||||||||||||||||||||||||||
498 | - | |||||||||||||||||||||||||||||||
499 | QVariant QPpmHandler::option(ImageOption option) const | - | ||||||||||||||||||||||||||||||
500 | { | - | ||||||||||||||||||||||||||||||
501 | if (option == SubType) {
| 0 | ||||||||||||||||||||||||||||||
502 | return subType; never executed: return subType; | 0 | ||||||||||||||||||||||||||||||
503 | } else if (option == Size) {
| 0 | ||||||||||||||||||||||||||||||
504 | if (state == Error)
| 0 | ||||||||||||||||||||||||||||||
505 | return QVariant(); never executed: return QVariant(); | 0 | ||||||||||||||||||||||||||||||
506 | if (state == Ready && !const_cast<QPpmHandler*>(this)->readHeader())
| 0 | ||||||||||||||||||||||||||||||
507 | return QVariant(); never executed: return QVariant(); | 0 | ||||||||||||||||||||||||||||||
508 | return QSize(width, height); never executed: return QSize(width, height); | 0 | ||||||||||||||||||||||||||||||
509 | } else if (option == ImageFormat) {
| 0 | ||||||||||||||||||||||||||||||
510 | if (state == Error)
| 0 | ||||||||||||||||||||||||||||||
511 | return QVariant(); never executed: return QVariant(); | 0 | ||||||||||||||||||||||||||||||
512 | if (state == Ready && !const_cast<QPpmHandler*>(this)->readHeader())
| 0 | ||||||||||||||||||||||||||||||
513 | return QVariant(); never executed: return QVariant(); | 0 | ||||||||||||||||||||||||||||||
514 | QImage::Format format = QImage::Format_Invalid; | - | ||||||||||||||||||||||||||||||
515 | switch (type) { | - | ||||||||||||||||||||||||||||||
516 | case '1': // ascii PBM never executed: case '1': | 0 | ||||||||||||||||||||||||||||||
517 | case '4': // raw PBM never executed: case '4': | 0 | ||||||||||||||||||||||||||||||
518 | format = QImage::Format_Mono; | - | ||||||||||||||||||||||||||||||
519 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
520 | case '2': // ascii PGM never executed: case '2': | 0 | ||||||||||||||||||||||||||||||
521 | case '5': // raw PGM never executed: case '5': | 0 | ||||||||||||||||||||||||||||||
522 | format = QImage::Format_Grayscale8; | - | ||||||||||||||||||||||||||||||
523 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
524 | case '3': // ascii PPM never executed: case '3': | 0 | ||||||||||||||||||||||||||||||
525 | case '6': // raw PPM never executed: case '6': | 0 | ||||||||||||||||||||||||||||||
526 | format = QImage::Format_RGB32; | - | ||||||||||||||||||||||||||||||
527 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
528 | default: never executed: default: | 0 | ||||||||||||||||||||||||||||||
529 | break; never executed: break; | 0 | ||||||||||||||||||||||||||||||
530 | } | - | ||||||||||||||||||||||||||||||
531 | return format; never executed: return format; | 0 | ||||||||||||||||||||||||||||||
532 | } | - | ||||||||||||||||||||||||||||||
533 | return QVariant(); never executed: return QVariant(); | 0 | ||||||||||||||||||||||||||||||
534 | } | - | ||||||||||||||||||||||||||||||
535 | - | |||||||||||||||||||||||||||||||
536 | void QPpmHandler::setOption(ImageOption option, const QVariant &value) | - | ||||||||||||||||||||||||||||||
537 | { | - | ||||||||||||||||||||||||||||||
538 | if (option == SubType)
| 0 | ||||||||||||||||||||||||||||||
539 | subType = value.toByteArray().toLower(); never executed: subType = value.toByteArray().toLower(); | 0 | ||||||||||||||||||||||||||||||
540 | } never executed: end of block | 0 | ||||||||||||||||||||||||||||||
541 | - | |||||||||||||||||||||||||||||||
542 | QByteArray QPpmHandler::name() const | - | ||||||||||||||||||||||||||||||
543 | { | - | ||||||||||||||||||||||||||||||
544 | return subType.isEmpty() ? QByteArray("ppm") : subType; never executed: return subType.isEmpty() ? QByteArray("ppm") : subType; | 0 | ||||||||||||||||||||||||||||||
545 | } | - | ||||||||||||||||||||||||||||||
546 | - | |||||||||||||||||||||||||||||||
547 | QT_END_NAMESPACE | - | ||||||||||||||||||||||||||||||
548 | - | |||||||||||||||||||||||||||||||
549 | #endif // QT_NO_IMAGEFORMAT_PPM | - | ||||||||||||||||||||||||||||||
Source code | Switch to Preprocessed file |