qppmhandler.cpp

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

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