qpnghandler.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/image/qpnghandler.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>-
4** Copyright (C) 2015 The Qt Company Ltd.-
5** Contact: http://www.qt.io/licensing/-
6**-
7** This file is part of the QtGui module of the Qt Toolkit.-
8**-
9** $QT_BEGIN_LICENSE:LGPL21$-
10** Commercial License Usage-
11** Licensees holding valid commercial Qt licenses may use this file in-
12** accordance with the commercial license agreement provided with the-
13** Software or, alternatively, in accordance with the terms contained in-
14** a written agreement between you and The Qt Company. For licensing terms-
15** and conditions see http://www.qt.io/terms-conditions. For further-
16** information use the contact form at http://www.qt.io/contact-us.-
17**-
18** GNU Lesser General Public License Usage-
19** Alternatively, this file may be used under the terms of the GNU Lesser-
20** General Public License version 2.1 or version 3 as published by the Free-
21** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
22** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
23** following information to ensure the GNU Lesser General Public License-
24** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
25** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
26**-
27** As a special exception, The Qt Company gives you certain additional-
28** rights. These rights are described in The Qt Company LGPL Exception-
29** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
30**-
31** $QT_END_LICENSE$-
32**-
33****************************************************************************/-
34-
35#include "private/qpnghandler_p.h"-
36-
37#ifndef QT_NO_IMAGEFORMAT_PNG-
38#include <qcoreapplication.h>-
39#include <qiodevice.h>-
40#include <qimage.h>-
41#include <qlist.h>-
42#include <qtextcodec.h>-
43#include <qvariant.h>-
44#include <qvector.h>-
45-
46#include <png.h>-
47#include <pngconf.h>-
48-
49#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \-
50 && defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)-
51/*-
52 Versions 1.4.0 to 1.5.2 of libpng declare png_longjmp_ptr to-
53 have a noreturn attribute if PNG_PEDANTIC_WARNINGS_SUPPORTED-
54 is enabled, but most declarations of longjmp in the wild do-
55 not add this attribute. This causes problems when the png_jmpbuf-
56 macro expands to calling png_set_longjmp_fn with a mismatched-
57 longjmp, as compilers such as Clang will treat this as an error.-
58-
59 To work around this we override the png_jmpbuf macro to cast-
60 longjmp to a png_longjmp_ptr.-
61*/-
62# undef png_jmpbuf-
63# ifdef PNG_SETJMP_SUPPORTED-
64# define png_jmpbuf(png_ptr) \-
65 (*png_set_longjmp_fn((png_ptr), (png_longjmp_ptr)longjmp, sizeof(jmp_buf)))-
66# else-
67# define png_jmpbuf(png_ptr) \-
68 (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)-
69# endif-
70#endif-
71-
72#ifdef Q_OS_WINCE-
73#define CALLBACK_CALL_TYPE __cdecl-
74#else-
75#define CALLBACK_CALL_TYPE-
76#endif-
77-
78QT_BEGIN_NAMESPACE-
79-
80#if defined(Q_OS_WINCE) && defined(STANDARDSHELL_UI_MODEL)-
81# define Q_INTERNAL_WIN_NO_THROW __declspec(nothrow)-
82#else-
83# define Q_INTERNAL_WIN_NO_THROW-
84#endif-
85-
86// avoid going through QImage::scanLine() which calls detach-
87#define FAST_SCAN_LINE(data, bpl, y) (data + (y) * bpl)-
88-
89/*-
90 All PNG files load to the minimal QImage equivalent.-
91-
92 All QImage formats output to reasonably efficient PNG equivalents.-
93*/-
94-
95class QPngHandlerPrivate-
96{-
97public:-
98 enum State {-
99 Ready,-
100 ReadHeader,-
101 ReadingEnd,-
102 Error-
103 };-
104-
105 QPngHandlerPrivate(QPngHandler *qq)-
106 : gamma(0.0), fileGamma(0.0), quality(2), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)-
107 { }
never executed: end of block
0
108-
109 float gamma;-
110 float fileGamma;-
111 int quality;-
112 QString description;-
113 QSize scaledSize;-
114 QStringList readTexts;-
115-
116 png_struct *png_ptr;-
117 png_info *info_ptr;-
118 png_info *end_info;-
119-
120 bool readPngHeader();-
121 bool readPngImage(QImage *image);-
122 void readPngTexts(png_info *info);-
123-
124 QImage::Format readImageFormat();-
125-
126 struct AllocatedMemoryPointers {-
127 AllocatedMemoryPointers()-
128 : row_pointers(0), accRow(0), inRow(0), outRow(0)-
129 { }
never executed: end of block
0
130 void deallocate()-
131 {-
132 delete [] row_pointers;-
133 row_pointers = 0;-
134 delete [] accRow;-
135 accRow = 0;-
136 delete [] inRow;-
137 inRow = 0;-
138 delete [] outRow;-
139 outRow = 0;-
140 }
never executed: end of block
0
141-
142 png_byte **row_pointers;-
143 quint32 *accRow;-
144 png_byte *inRow;-
145 uchar *outRow;-
146 };-
147-
148 AllocatedMemoryPointers amp;-
149-
150 State state;-
151-
152 QPngHandler *q;-
153};-
154-
155-
156class QPNGImageWriter {-
157public:-
158 explicit QPNGImageWriter(QIODevice*);-
159 ~QPNGImageWriter();-
160-
161 enum DisposalMethod { Unspecified, NoDisposal, RestoreBackground, RestoreImage };-
162 void setDisposalMethod(DisposalMethod);-
163 void setLooping(int loops=0); // 0 == infinity-
164 void setFrameDelay(int msecs);-
165 void setGamma(float);-
166-
167 bool writeImage(const QImage& img, int x, int y);-
168 bool writeImage(const QImage& img, volatile int quality, const QString &description, int x, int y);-
169 bool writeImage(const QImage& img)-
170 { return writeImage(img, 0, 0); }
never executed: return writeImage(img, 0, 0);
0
171 bool writeImage(const QImage& img, int quality, const QString &description)-
172 { return writeImage(img, quality, description, 0, 0); }
never executed: return writeImage(img, quality, description, 0, 0);
0
173-
174 QIODevice* device() { return dev; }
never executed: return dev;
0
175-
176private:-
177 QIODevice* dev;-
178 int frames_written;-
179 DisposalMethod disposal;-
180 int looping;-
181 int ms_delay;-
182 float gamma;-
183};-
184-
185extern "C" {-
186static-
187void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)-
188{-
189 QPngHandlerPrivate *d = (QPngHandlerPrivate *)png_get_io_ptr(png_ptr);-
190 QIODevice *in = d->q->device();-
191-
192 if (d->state == QPngHandlerPrivate::ReadingEnd && !in->isSequential() && (in->size() - in->pos()) < 4 && length == 4) {
d->state == QP...te::ReadingEndDescription
TRUEnever evaluated
FALSEnever evaluated
!in->isSequential()Description
TRUEnever evaluated
FALSEnever evaluated
(in->size() - in->pos()) < 4Description
TRUEnever evaluated
FALSEnever evaluated
length == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
193 // Workaround for certain malformed PNGs that lack the final crc bytes-
194 uchar endcrc[4] = { 0xae, 0x42, 0x60, 0x82 };-
195 memcpy(data, endcrc, 4);-
196 in->seek(in->size());-
197 return;
never executed: return;
0
198 }-
199-
200 while (length) {
lengthDescription
TRUEnever evaluated
FALSEnever evaluated
0
201 int nr = in->read((char*)data, length);-
202 if (nr <= 0) {
nr <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
203 png_error(png_ptr, "Read Error");-
204 return;
never executed: return;
0
205 }-
206 length -= nr;-
207 }
never executed: end of block
0
208}
never executed: end of block
0
209-
210-
211static-
212void CALLBACK_CALL_TYPE qpiw_write_fn(png_structp png_ptr, png_bytep data, png_size_t length)-
213{-
214 QPNGImageWriter* qpiw = (QPNGImageWriter*)png_get_io_ptr(png_ptr);-
215 QIODevice* out = qpiw->device();-
216-
217 uint nr = out->write((char*)data, length);-
218 if (nr != length) {
nr != lengthDescription
TRUEnever evaluated
FALSEnever evaluated
0
219 png_error(png_ptr, "Write Error");-
220 return;
never executed: return;
0
221 }-
222}
never executed: end of block
0
223-
224-
225static-
226void CALLBACK_CALL_TYPE qpiw_flush_fn(png_structp /* png_ptr */)-
227{-
228}-
229-
230}-
231-
232static-
233void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0)-
234{-
235 if (screen_gamma != 0.0 && file_gamma != 0.0)
screen_gamma != 0.0Description
TRUEnever evaluated
FALSEnever evaluated
file_gamma != 0.0Description
TRUEnever evaluated
FALSEnever evaluated
0
236 png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma);
never executed: png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma);
0
237-
238 png_uint_32 width;-
239 png_uint_32 height;-
240 int bit_depth;-
241 int color_type;-
242 png_bytep trans_alpha = 0;-
243 png_color_16p trans_color_p = 0;-
244 int num_trans;-
245 png_colorp palette = 0;-
246 int num_palette;-
247 int interlace_method;-
248 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, 0, 0);-
249 png_set_interlace_handling(png_ptr);-
250-
251 if (color_type == PNG_COLOR_TYPE_GRAY) {
color_type == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
252 // Black & White or 8-bit grayscale-
253 if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
bit_depth == 1Description
TRUEnever evaluated
FALSEnever evaluated
png_get_channe...info_ptr) == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
254 png_set_invert_mono(png_ptr);-
255 png_read_update_info(png_ptr, info_ptr);-
256 if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
image.size() !...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
image.format()...e::Format_MonoDescription
TRUEnever evaluated
FALSEnever evaluated
0
257 image = QImage(width, height, QImage::Format_Mono);-
258 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
259 return;
never executed: return;
0
260 }
never executed: end of block
0
261 image.setColorCount(2);-
262 image.setColor(1, qRgb(0,0,0));-
263 image.setColor(0, qRgb(255,255,255));-
264 if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
png_get_tRNS(p...trans_color_p)Description
TRUEnever evaluated
FALSEnever evaluated
trans_color_pDescription
TRUEnever evaluated
FALSEnever evaluated
0
265 const int g = trans_color_p->gray;-
266 // the image has white in the first position of the color table,-
267 // black in the second. g is 0 for black, 1 for white.-
268 if (g == 0)
g == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
269 image.setColor(1, qRgba(0, 0, 0, 0));
never executed: image.setColor(1, qRgba(0, 0, 0, 0));
0
270 else if (g == 1)
g == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
271 image.setColor(0, qRgba(255, 255, 255, 0));
never executed: image.setColor(0, qRgba(255, 255, 255, 0));
0
272 }
never executed: end of block
0
273 } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
never executed: end of block
bit_depth == 16Description
TRUEnever evaluated
FALSEnever evaluated
png_get_valid(...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
274 png_set_expand(png_ptr);-
275 png_set_strip_16(png_ptr);-
276 png_set_gray_to_rgb(png_ptr);-
277 if (image.size() != QSize(width, height) || image.format() != QImage::Format_ARGB32) {
image.size() !...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
image.format()...:Format_ARGB32Description
TRUEnever evaluated
FALSEnever evaluated
0
278 image = QImage(width, height, QImage::Format_ARGB32);-
279 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
280 return;
never executed: return;
0
281 }
never executed: end of block
0
282 if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
QSysInfo::Byte...nfo::BigEndianDescription
TRUEnever evaluated
FALSEnever evaluated
0
283 png_set_swap_alpha(png_ptr);
never executed: png_set_swap_alpha(png_ptr);
0
284-
285 png_read_update_info(png_ptr, info_ptr);-
286 } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
never executed: end of block
bit_depth == 8Description
TRUEnever evaluated
FALSEnever evaluated
!png_get_valid...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
287 png_set_expand(png_ptr);-
288 if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale8) {
image.size() !...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
image.format()...mat_Grayscale8Description
TRUEnever evaluated
FALSEnever evaluated
0
289 image = QImage(width, height, QImage::Format_Grayscale8);-
290 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
291 return;
never executed: return;
0
292 }
never executed: end of block
0
293-
294 png_read_update_info(png_ptr, info_ptr);-
295 } else {
never executed: end of block
0
296 if (bit_depth == 16)
bit_depth == 16Description
TRUEnever evaluated
FALSEnever evaluated
0
297 png_set_strip_16(png_ptr);
never executed: png_set_strip_16(png_ptr);
0
298 else if (bit_depth < 8)
bit_depth < 8Description
TRUEnever evaluated
FALSEnever evaluated
0
299 png_set_packing(png_ptr);
never executed: png_set_packing(png_ptr);
0
300 int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
bit_depth < 8Description
TRUEnever evaluated
FALSEnever evaluated
0
301 png_read_update_info(png_ptr, info_ptr);-
302 if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) {
image.size() !...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
image.format()...ormat_Indexed8Description
TRUEnever evaluated
FALSEnever evaluated
0
303 image = QImage(width, height, QImage::Format_Indexed8);-
304 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
305 return;
never executed: return;
0
306 }
never executed: end of block
0
307 image.setColorCount(ncols);-
308 for (int i=0; i<ncols; i++) {
i<ncolsDescription
TRUEnever evaluated
FALSEnever evaluated
0
309 int c = i*255/(ncols-1);-
310 image.setColor(i, qRgba(c,c,c,0xff));-
311 }
never executed: end of block
0
312 if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_color_p) {
png_get_tRNS(p...trans_color_p)Description
TRUEnever evaluated
FALSEnever evaluated
trans_color_pDescription
TRUEnever evaluated
FALSEnever evaluated
0
313 const int g = trans_color_p->gray;-
314 if (g < ncols) {
g < ncolsDescription
TRUEnever evaluated
FALSEnever evaluated
0
315 image.setColor(g, 0);-
316 }
never executed: end of block
0
317 }
never executed: end of block
0
318 }
never executed: end of block
0
319 } else if (color_type == PNG_COLOR_TYPE_PALETTE
color_type == (2 | 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
320 && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
png_get_PLTE(p... &num_palette)Description
TRUEnever evaluated
FALSEnever evaluated
0
321 && num_palette <= 256)
num_palette <= 256Description
TRUEnever evaluated
FALSEnever evaluated
0
322 {-
323 // 1-bit and 8-bit color-
324 if (bit_depth != 1)
bit_depth != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
325 png_set_packing(png_ptr);
never executed: png_set_packing(png_ptr);
0
326 png_read_update_info(png_ptr, info_ptr);-
327 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);-
328 QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
bit_depth == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
329 if (image.size() != QSize(width, height) || image.format() != format) {
image.size() !...width, height)Description
TRUEnever evaluated
FALSEnever evaluated
image.format() != formatDescription
TRUEnever evaluated
FALSEnever evaluated
0
330 image = QImage(width, height, format);-
331 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
332 return;
never executed: return;
0
333 }
never executed: end of block
0
334 png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);-
335 image.setColorCount(num_palette);-
336 int i = 0;-
337 if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) {
png_get_tRNS(p...trans_color_p)Description
TRUEnever evaluated
FALSEnever evaluated
trans_alphaDescription
TRUEnever evaluated
FALSEnever evaluated
0
338 while (i < num_trans) {
i < num_transDescription
TRUEnever evaluated
FALSEnever evaluated
0
339 image.setColor(i, qRgba(-
340 palette[i].red,-
341 palette[i].green,-
342 palette[i].blue,-
343 trans_alpha[i]-
344 )-
345 );-
346 i++;-
347 }
never executed: end of block
0
348 }
never executed: end of block
0
349 while (i < num_palette) {
i < num_paletteDescription
TRUEnever evaluated
FALSEnever evaluated
0
350 image.setColor(i, qRgba(-
351 palette[i].red,-
352 palette[i].green,-
353 palette[i].blue,-
354 0xff-
355 )-
356 );-
357 i++;-
358 }
never executed: end of block
0
359 } else {
never executed: end of block
0
360 // 32-bit-
361 if (bit_depth == 16)
bit_depth == 16Description
TRUEnever evaluated
FALSEnever evaluated
0
362 png_set_strip_16(png_ptr);
never executed: png_set_strip_16(png_ptr);
0
363-
364 png_set_expand(png_ptr);-
365-
366 if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
color_type == (4)Description
TRUEnever evaluated
FALSEnever evaluated
0
367 png_set_gray_to_rgb(png_ptr);
never executed: png_set_gray_to_rgb(png_ptr);
0
368-
369 QImage::Format format = QImage::Format_ARGB32;-
370 // Only add filler if no alpha, or we can get 5 channel data.-
371 if (!(color_type & PNG_COLOR_MASK_ALPHA)
!(color_type & 4)Description
TRUEnever evaluated
FALSEnever evaluated
0
372 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
!png_get_valid...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
373 png_set_filler(png_ptr, 0xff, QSysInfo::ByteOrder == QSysInfo::BigEndian ?-
374 PNG_FILLER_BEFORE : PNG_FILLER_AFTER);-
375 // We want 4 bytes, but it isn't an alpha channel-
376 format = QImage::Format_RGB32;-
377 }
never executed: end of block
0
378 QSize outSize(width,height);-
379 if (!scaledSize.isEmpty() && quint32(scaledSize.width()) <= width &&
!scaledSize.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
quint32(scaled...th()) <= widthDescription
TRUEnever evaluated
FALSEnever evaluated
0
380 quint32(scaledSize.height()) <= height && interlace_method == PNG_INTERLACE_NONE) {
quint32(scaled...t()) <= heightDescription
TRUEnever evaluated
FALSEnever evaluated
interlace_method == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
381 // Do inline downscaling-
382 outSize = scaledSize;-
383 if (doScaledRead)
doScaledReadDescription
TRUEnever evaluated
FALSEnever evaluated
0
384 *doScaledRead = true;
never executed: *doScaledRead = true;
0
385 }
never executed: end of block
0
386 if (image.size() != outSize || image.format() != format) {
image.size() != outSizeDescription
TRUEnever evaluated
FALSEnever evaluated
image.format() != formatDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 image = QImage(outSize, format);-
388 if (image.isNull())
image.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
389 return;
never executed: return;
0
390 }
never executed: end of block
0
391-
392 if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
QSysInfo::Byte...nfo::BigEndianDescription
TRUEnever evaluated
FALSEnever evaluated
0
393 png_set_swap_alpha(png_ptr);
never executed: png_set_swap_alpha(png_ptr);
0
394-
395 png_read_update_info(png_ptr, info_ptr);-
396 }
never executed: end of block
0
397-
398 // Qt==ARGB==Big(ARGB)==Little(BGRA)-
399 if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
QSysInfo::Byte...::LittleEndianDescription
TRUEnever evaluated
FALSEnever evaluated
0
400 png_set_bgr(png_ptr);-
401 }
never executed: end of block
0
402}
never executed: end of block
0
403-
404static void read_image_scaled(QImage *outImage, png_structp png_ptr, png_infop info_ptr,-
405 QPngHandlerPrivate::AllocatedMemoryPointers &amp, QSize scaledSize)-
406{-
407-
408 png_uint_32 width = 0;-
409 png_uint_32 height = 0;-
410 png_int_32 offset_x = 0;-
411 png_int_32 offset_y = 0;-
412-
413 int bit_depth = 0;-
414 int color_type = 0;-
415 int unit_type = PNG_OFFSET_PIXEL;-
416 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);-
417 png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type);-
418 uchar *data = outImage->bits();-
419 int bpl = outImage->bytesPerLine();-
420-
421 if (scaledSize.isEmpty() || !width || !height)
scaledSize.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
!widthDescription
TRUEnever evaluated
FALSEnever evaluated
!heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
422 return;
never executed: return;
0
423-
424 const quint32 iysz = height;-
425 const quint32 ixsz = width;-
426 const quint32 oysz = scaledSize.height();-
427 const quint32 oxsz = scaledSize.width();-
428 const quint32 ibw = 4*width;-
429 amp.accRow = new quint32[ibw];-
430 memset(amp.accRow, 0, ibw*sizeof(quint32));-
431 amp.inRow = new png_byte[ibw];-
432 memset(amp.inRow, 0, ibw*sizeof(png_byte));-
433 amp.outRow = new uchar[ibw];-
434 memset(amp.outRow, 0, ibw*sizeof(uchar));-
435 qint32 rval = 0;-
436 for (quint32 oy=0; oy<oysz; oy++) {
oy<oyszDescription
TRUEnever evaluated
FALSEnever evaluated
0
437 // Store the rest of the previous input row, if any-
438 for (quint32 i=0; i < ibw; i++)
i < ibwDescription
TRUEnever evaluated
FALSEnever evaluated
0
439 amp.accRow[i] = rval*amp.inRow[i];
never executed: amp.accRow[i] = rval*amp.inRow[i];
0
440 // Accumulate the next input rows-
441 for (rval = iysz-rval; rval > 0; rval-=oysz) {
rval > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
442 png_read_row(png_ptr, amp.inRow, NULL);-
443 quint32 fact = qMin(oysz, quint32(rval));-
444 for (quint32 i=0; i < ibw; i++)
i < ibwDescription
TRUEnever evaluated
FALSEnever evaluated
0
445 amp.accRow[i] += fact*amp.inRow[i];
never executed: amp.accRow[i] += fact*amp.inRow[i];
0
446 }
never executed: end of block
0
447 rval *= -1;-
448-
449 // We have a full output row, store it-
450 for (quint32 i=0; i < ibw; i++)
i < ibwDescription
TRUEnever evaluated
FALSEnever evaluated
0
451 amp.outRow[i] = uchar(amp.accRow[i]/iysz);
never executed: amp.outRow[i] = uchar(amp.accRow[i]/iysz);
0
452-
453 quint32 a[4] = {0, 0, 0, 0};-
454 qint32 cval = oxsz;-
455 quint32 ix = 0;-
456 for (quint32 ox=0; ox<oxsz; ox++) {
ox<oxszDescription
TRUEnever evaluated
FALSEnever evaluated
0
457 for (quint32 i=0; i < 4; i++)
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
458 a[i] = cval * amp.outRow[ix+i];
never executed: a[i] = cval * amp.outRow[ix+i];
0
459 for (cval = ixsz - cval; cval > 0; cval-=oxsz) {
cval > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
460 ix += 4;-
461 if (ix >= ibw)
ix >= ibwDescription
TRUEnever evaluated
FALSEnever evaluated
0
462 break; // Safety belt, should not happen
never executed: break;
0
463 quint32 fact = qMin(oxsz, quint32(cval));-
464 for (quint32 i=0; i < 4; i++)
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
465 a[i] += fact * amp.outRow[ix+i];
never executed: a[i] += fact * amp.outRow[ix+i];
0
466 }
never executed: end of block
0
467 cval *= -1;-
468 for (quint32 i=0; i < 4; i++)
i < 4Description
TRUEnever evaluated
FALSEnever evaluated
0
469 data[(4*ox)+i] = uchar(a[i]/ixsz);
never executed: data[(4*ox)+i] = uchar(a[i]/ixsz);
0
470 }
never executed: end of block
0
471 data += bpl;-
472 }
never executed: end of block
0
473 amp.deallocate();-
474-
475 outImage->setDotsPerMeterX((png_get_x_pixels_per_meter(png_ptr,info_ptr)*oxsz)/ixsz);-
476 outImage->setDotsPerMeterY((png_get_y_pixels_per_meter(png_ptr,info_ptr)*oysz)/iysz);-
477-
478 if (unit_type == PNG_OFFSET_PIXEL)
unit_type == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
479 outImage->setOffset(QPoint(offset_x*oxsz/ixsz, offset_y*oysz/iysz));
never executed: outImage->setOffset(QPoint(offset_x*oxsz/ixsz, offset_y*oysz/iysz));
0
480-
481}
never executed: end of block
0
482-
483extern "C" {-
484static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const_charp message)-
485{-
486 qWarning("libpng warning: %s", message);-
487}
never executed: end of block
0
488-
489}-
490-
491-
492void Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngTexts(png_info *info)-
493{-
494 png_textp text_ptr;-
495 int num_text=0;-
496 png_get_text(png_ptr, info, &text_ptr, &num_text);-
497-
498 while (num_text--) {
num_text--Description
TRUEnever evaluated
FALSEnever evaluated
0
499 QString key, value;-
500 key = QString::fromLatin1(text_ptr->key);-
501#if defined(PNG_iTXt_SUPPORTED)-
502 if (text_ptr->itxt_length) {-
503 value = QString::fromUtf8(text_ptr->text, int(text_ptr->itxt_length));-
504 } else-
505#endif-
506 {-
507 value = QString::fromLatin1(text_ptr->text, int(text_ptr->text_length));-
508 }-
509 if (!description.isEmpty())
!description.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
510 description += QLatin1String("\n\n");
never executed: description += QLatin1String("\n\n");
0
511 description += key + QLatin1String(": ") + value.simplified();-
512 readTexts.append(key);-
513 readTexts.append(value);-
514 text_ptr++;-
515 }
never executed: end of block
0
516}
never executed: end of block
0
517-
518-
519bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngHeader()-
520{-
521 state = Error;-
522 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);-
523 if (!png_ptr)
!png_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
524 return false;
never executed: return false;
0
525-
526 png_set_error_fn(png_ptr, 0, 0, qt_png_warning);-
527-
528#if defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_MAXIMUM_INFLATE_WINDOW)-
529 // Trade off a little bit of memory for better compatibility with existing images-
530 // Ref. "invalid distance too far back" explanation in libpng-manual.txt-
531 png_set_option(png_ptr, PNG_MAXIMUM_INFLATE_WINDOW, PNG_OPTION_ON);-
532#endif-
533-
534 info_ptr = png_create_info_struct(png_ptr);-
535 if (!info_ptr) {
!info_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
536 png_destroy_read_struct(&png_ptr, 0, 0);-
537 png_ptr = 0;-
538 return false;
never executed: return false;
0
539 }-
540-
541 end_info = png_create_info_struct(png_ptr);-
542 if (!end_info) {
!end_infoDescription
TRUEnever evaluated
FALSEnever evaluated
0
543 png_destroy_read_struct(&png_ptr, &info_ptr, 0);-
544 png_ptr = 0;-
545 return false;
never executed: return false;
0
546 }-
547-
548 if (setjmp(png_jmpbuf(png_ptr))) {
_setjmp (((png_ptr)->jmpbuf))Description
TRUEnever evaluated
FALSEnever evaluated
0
549 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);-
550 png_ptr = 0;-
551 return false;
never executed: return false;
0
552 }-
553-
554 png_set_read_fn(png_ptr, this, iod_read_fn);-
555 png_read_info(png_ptr, info_ptr);-
556-
557 readPngTexts(info_ptr);-
558-
559 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
png_get_valid(...o_ptr, 0x0001)Description
TRUEnever evaluated
FALSEnever evaluated
0
560 double file_gamma = 0.0;-
561 png_get_gAMA(png_ptr, info_ptr, &file_gamma);-
562 fileGamma = file_gamma;-
563 }
never executed: end of block
0
564-
565 state = ReadHeader;-
566 return true;
never executed: return true;
0
567}-
568-
569bool Q_INTERNAL_WIN_NO_THROW QPngHandlerPrivate::readPngImage(QImage *outImage)-
570{-
571 if (state == Error)
state == ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
572 return false;
never executed: return false;
0
573-
574 if (state == Ready && !readPngHeader()) {
state == ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!readPngHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
575 state = Error;-
576 return false;
never executed: return false;
0
577 }-
578-
579 if (setjmp(png_jmpbuf(png_ptr))) {
_setjmp (((png_ptr)->jmpbuf))Description
TRUEnever evaluated
FALSEnever evaluated
0
580 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);-
581 png_ptr = 0;-
582 amp.deallocate();-
583 state = Error;-
584 return false;
never executed: return false;
0
585 }-
586-
587 bool doScaledRead = false;-
588 setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma);-
589-
590 if (outImage->isNull()) {
outImage->isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
591 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);-
592 png_ptr = 0;-
593 amp.deallocate();-
594 state = Error;-
595 return false;
never executed: return false;
0
596 }-
597-
598 if (doScaledRead) {
doScaledReadDescription
TRUEnever evaluated
FALSEnever evaluated
0
599 read_image_scaled(outImage, png_ptr, info_ptr, amp, scaledSize);-
600 } else {
never executed: end of block
0
601 png_uint_32 width = 0;-
602 png_uint_32 height = 0;-
603 png_int_32 offset_x = 0;-
604 png_int_32 offset_y = 0;-
605-
606 int bit_depth = 0;-
607 int color_type = 0;-
608 int unit_type = PNG_OFFSET_PIXEL;-
609 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);-
610 png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type);-
611 uchar *data = outImage->bits();-
612 int bpl = outImage->bytesPerLine();-
613 amp.row_pointers = new png_bytep[height];-
614-
615 for (uint y = 0; y < height; y++)
y < heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
616 amp.row_pointers[y] = data + y * bpl;
never executed: amp.row_pointers[y] = data + y * bpl;
0
617-
618 png_read_image(png_ptr, amp.row_pointers);-
619 amp.deallocate();-
620-
621 outImage->setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr));-
622 outImage->setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr));-
623-
624 if (unit_type == PNG_OFFSET_PIXEL)
unit_type == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
625 outImage->setOffset(QPoint(offset_x, offset_y));
never executed: outImage->setOffset(QPoint(offset_x, offset_y));
0
626-
627 // sanity check palette entries-
628 if (color_type == PNG_COLOR_TYPE_PALETTE && outImage->format() == QImage::Format_Indexed8) {
color_type == (2 | 1)Description
TRUEnever evaluated
FALSEnever evaluated
outImage->form...ormat_Indexed8Description
TRUEnever evaluated
FALSEnever evaluated
0
629 int color_table_size = outImage->colorCount();-
630 for (int y=0; y<(int)height; ++y) {
y<(int)heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
631 uchar *p = FAST_SCAN_LINE(data, bpl, y);-
632 uchar *end = p + width;-
633 while (p < end) {
p < endDescription
TRUEnever evaluated
FALSEnever evaluated
0
634 if (*p >= color_table_size)
*p >= color_table_sizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
635 *p = 0;
never executed: *p = 0;
0
636 ++p;-
637 }
never executed: end of block
0
638 }
never executed: end of block
0
639 }
never executed: end of block
0
640 }
never executed: end of block
0
641-
642 state = ReadingEnd;-
643 png_read_end(png_ptr, end_info);-
644-
645 readPngTexts(end_info);-
646 for (int i = 0; i < readTexts.size()-1; i+=2)
i < readTexts.size()-1Description
TRUEnever evaluated
FALSEnever evaluated
0
647 outImage->setText(readTexts.at(i), readTexts.at(i+1));
never executed: outImage->setText(readTexts.at(i), readTexts.at(i+1));
0
648-
649 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);-
650 png_ptr = 0;-
651 amp.deallocate();-
652 state = Ready;-
653-
654 if (scaledSize.isValid() && outImage->size() != scaledSize)
scaledSize.isValid()Description
TRUEnever evaluated
FALSEnever evaluated
outImage->size() != scaledSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
655 *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
never executed: *outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
0
656-
657 return true;
never executed: return true;
0
658}-
659-
660QImage::Format QPngHandlerPrivate::readImageFormat()-
661{-
662 QImage::Format format = QImage::Format_Invalid;-
663 png_uint_32 width, height;-
664 int bit_depth, color_type;-
665 png_colorp palette;-
666 int num_palette;-
667 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 0, 0, 0);-
668 if (color_type == PNG_COLOR_TYPE_GRAY) {
color_type == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
669 // Black & White or 8-bit grayscale-
670 if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
bit_depth == 1Description
TRUEnever evaluated
FALSEnever evaluated
png_get_channe...info_ptr) == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
671 format = QImage::Format_Mono;-
672 } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
never executed: end of block
bit_depth == 16Description
TRUEnever evaluated
FALSEnever evaluated
png_get_valid(...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
673 format = QImage::Format_ARGB32;-
674 } else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
never executed: end of block
bit_depth == 8Description
TRUEnever evaluated
FALSEnever evaluated
!png_get_valid...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
675 format = QImage::Format_Grayscale8;-
676 } else {
never executed: end of block
0
677 format = QImage::Format_Indexed8;-
678 }
never executed: end of block
0
679 } else if (color_type == PNG_COLOR_TYPE_PALETTE
color_type == (2 | 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
680 && png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)
png_get_PLTE(p... &num_palette)Description
TRUEnever evaluated
FALSEnever evaluated
0
681 && num_palette <= 256)
num_palette <= 256Description
TRUEnever evaluated
FALSEnever evaluated
0
682 {-
683 // 1-bit and 8-bit color-
684 format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
bit_depth == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
685 } else {
never executed: end of block
0
686 // 32-bit-
687 format = QImage::Format_ARGB32;-
688 // Only add filler if no alpha, or we can get 5 channel data.-
689 if (!(color_type & PNG_COLOR_MASK_ALPHA)
!(color_type & 4)Description
TRUEnever evaluated
FALSEnever evaluated
0
690 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
!png_get_valid...o_ptr, 0x0010)Description
TRUEnever evaluated
FALSEnever evaluated
0
691 // We want 4 bytes, but it isn't an alpha channel-
692 format = QImage::Format_RGB32;-
693 }
never executed: end of block
0
694 }
never executed: end of block
0
695-
696 return format;
never executed: return format;
0
697}-
698-
699QPNGImageWriter::QPNGImageWriter(QIODevice* iod) :-
700 dev(iod),-
701 frames_written(0),-
702 disposal(Unspecified),-
703 looping(-1),-
704 ms_delay(-1),-
705 gamma(0.0)-
706{-
707}
never executed: end of block
0
708-
709QPNGImageWriter::~QPNGImageWriter()-
710{-
711}-
712-
713void QPNGImageWriter::setDisposalMethod(DisposalMethod dm)-
714{-
715 disposal = dm;-
716}
never executed: end of block
0
717-
718void QPNGImageWriter::setLooping(int loops)-
719{-
720 looping = loops;-
721}
never executed: end of block
0
722-
723void QPNGImageWriter::setFrameDelay(int msecs)-
724{-
725 ms_delay = msecs;-
726}
never executed: end of block
0
727-
728void QPNGImageWriter::setGamma(float g)-
729{-
730 gamma = g;-
731}
never executed: end of block
0
732-
733-
734static void set_text(const QImage &image, png_structp png_ptr, png_infop info_ptr,-
735 const QString &description)-
736{-
737 QMap<QString, QString> text;-
738 foreach (const QString &key, image.textKeys()) {-
739 if (!key.isEmpty())
!key.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
740 text.insert(key, image.text(key));
never executed: text.insert(key, image.text(key));
0
741 }
never executed: end of block
0
742 foreach (const QString &pair, description.split(QLatin1String("\n\n"))) {-
743 int index = pair.indexOf(QLatin1Char(':'));-
744 if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) {
index >= 0Description
TRUEnever evaluated
FALSEnever evaluated
pair.indexOf(Q...(' ')) < indexDescription
TRUEnever evaluated
FALSEnever evaluated
0
745 QString s = pair.simplified();-
746 if (!s.isEmpty())
!s.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
747 text.insert(QLatin1String("Description"), s);
never executed: text.insert(QLatin1String("Description"), s);
0
748 } else {
never executed: end of block
0
749 QString key = pair.left(index);-
750 if (!key.simplified().isEmpty())
!key.simplified().isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
751 text.insert(key, pair.mid(index + 2).simplified());
never executed: text.insert(key, pair.mid(index + 2).simplified());
0
752 }
never executed: end of block
0
753 }-
754-
755 if (text.isEmpty())
text.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
756 return;
never executed: return;
0
757-
758 png_textp text_ptr = new png_text[text.size()];-
759 memset(text_ptr, 0, text.size() * sizeof(png_text));-
760-
761 QMap<QString, QString>::ConstIterator it = text.constBegin();-
762 int i = 0;-
763 while (it != text.constEnd()) {
it != text.constEnd()Description
TRUEnever evaluated
FALSEnever evaluated
0
764 text_ptr[i].key = qstrdup(it.key().left(79).toLatin1().constData());-
765 bool noCompress = (it.value().length() < 40);-
766-
767#ifdef PNG_iTXt_SUPPORTED-
768 bool needsItxt = false;-
769 foreach(const QChar c, it.value()) {-
770 uchar ch = c.cell();-
771 if (c.row() || (ch < 0x20 && ch != '\n') || (ch > 0x7e && ch < 0xa0)) {-
772 needsItxt = true;-
773 break;-
774 }-
775 }-
776-
777 if (needsItxt) {-
778 text_ptr[i].compression = noCompress ? PNG_ITXT_COMPRESSION_NONE : PNG_ITXT_COMPRESSION_zTXt;-
779 QByteArray value = it.value().toUtf8();-
780 text_ptr[i].text = qstrdup(value.constData());-
781 text_ptr[i].itxt_length = value.size();-
782 text_ptr[i].lang = const_cast<char*>("UTF-8");-
783 text_ptr[i].lang_key = qstrdup(it.key().toUtf8().constData());-
784 }-
785 else-
786#endif-
787 {-
788 text_ptr[i].compression = noCompress ? PNG_TEXT_COMPRESSION_NONE : PNG_TEXT_COMPRESSION_zTXt;
noCompressDescription
TRUEnever evaluated
FALSEnever evaluated
0
789 QByteArray value = it.value().toLatin1();-
790 text_ptr[i].text = qstrdup(value.constData());-
791 text_ptr[i].text_length = value.size();-
792 }-
793 ++i;-
794 ++it;-
795 }
never executed: end of block
0
796-
797 png_set_text(png_ptr, info_ptr, text_ptr, i);-
798 for (i = 0; i < text.size(); ++i) {
i < text.size()Description
TRUEnever evaluated
FALSEnever evaluated
0
799 delete [] text_ptr[i].key;-
800 delete [] text_ptr[i].text;-
801#ifdef PNG_iTXt_SUPPORTED-
802 delete [] text_ptr[i].lang_key;-
803#endif-
804 }
never executed: end of block
0
805 delete [] text_ptr;-
806}
never executed: end of block
0
807-
808bool QPNGImageWriter::writeImage(const QImage& image, int off_x, int off_y)-
809{-
810 return writeImage(image, -1, QString(), off_x, off_y);
never executed: return writeImage(image, -1, QString(), off_x, off_y);
0
811}-
812-
813bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description,-
814 int off_x_in, int off_y_in)-
815{-
816 QPoint offset = image.offset();-
817 int off_x = off_x_in + offset.x();-
818 int off_y = off_y_in + offset.y();-
819-
820 png_structp png_ptr;-
821 png_infop info_ptr;-
822-
823 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);-
824 if (!png_ptr) {
!png_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
825 return false;
never executed: return false;
0
826 }-
827-
828 png_set_error_fn(png_ptr, 0, 0, qt_png_warning);-
829-
830 info_ptr = png_create_info_struct(png_ptr);-
831 if (!info_ptr) {
!info_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
832 png_destroy_write_struct(&png_ptr, 0);-
833 return false;
never executed: return false;
0
834 }-
835-
836 if (setjmp(png_jmpbuf(png_ptr))) {
_setjmp (((png_ptr)->jmpbuf))Description
TRUEnever evaluated
FALSEnever evaluated
0
837 png_destroy_write_struct(&png_ptr, &info_ptr);-
838 return false;
never executed: return false;
0
839 }-
840-
841 int quality = quality_in;-
842 if (quality >= 0) {
quality >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
843 if (quality > 9) {
quality > 9Description
TRUEnever evaluated
FALSEnever evaluated
0
844 qWarning("PNG: Quality %d out of range", quality);-
845 quality = 9;-
846 }
never executed: end of block
0
847 png_set_compression_level(png_ptr, quality);-
848 }
never executed: end of block
0
849-
850 png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);-
851-
852-
853 int color_type = 0;-
854 if (image.colorCount()) {
image.colorCount()Description
TRUEnever evaluated
FALSEnever evaluated
0
855 if (image.isGrayscale())
image.isGrayscale()Description
TRUEnever evaluated
FALSEnever evaluated
0
856 color_type = PNG_COLOR_TYPE_GRAY;
never executed: color_type = 0;
0
857 else-
858 color_type = PNG_COLOR_TYPE_PALETTE;
never executed: color_type = (2 | 1);
0
859 }-
860 else if (image.format() == QImage::Format_Grayscale8)
image.format()...mat_Grayscale8Description
TRUEnever evaluated
FALSEnever evaluated
0
861 color_type = PNG_COLOR_TYPE_GRAY;
never executed: color_type = 0;
0
862 else if (image.hasAlphaChannel())
image.hasAlphaChannel()Description
TRUEnever evaluated
FALSEnever evaluated
0
863 color_type = PNG_COLOR_TYPE_RGB_ALPHA;
never executed: color_type = (2 | 4);
0
864 else-
865 color_type = PNG_COLOR_TYPE_RGB;
never executed: color_type = (2);
0
866-
867 png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),-
868 image.depth() == 1 ? 1 : 8, // per channel-
869 color_type, 0, 0, 0); // sets #channels-
870-
871 if (gamma != 0.0) {
gamma != 0.0Description
TRUEnever evaluated
FALSEnever evaluated
0
872 png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);-
873 }
never executed: end of block
0
874-
875 if (image.format() == QImage::Format_MonoLSB)
image.format()...Format_MonoLSBDescription
TRUEnever evaluated
FALSEnever evaluated
0
876 png_set_packswap(png_ptr);
never executed: png_set_packswap(png_ptr);
0
877-
878 if (color_type == PNG_COLOR_TYPE_PALETTE) {
color_type == (2 | 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
879 // Paletted-
880 int num_palette = qMin(256, image.colorCount());-
881 png_color palette[256];-
882 png_byte trans[256];-
883 int num_trans = 0;-
884 for (int i=0; i<num_palette; i++) {
i<num_paletteDescription
TRUEnever evaluated
FALSEnever evaluated
0
885 QRgb rgba=image.color(i);-
886 palette[i].red = qRed(rgba);-
887 palette[i].green = qGreen(rgba);-
888 palette[i].blue = qBlue(rgba);-
889 trans[i] = qAlpha(rgba);-
890 if (trans[i] < 255) {
trans[i] < 255Description
TRUEnever evaluated
FALSEnever evaluated
0
891 num_trans = i+1;-
892 }
never executed: end of block
0
893 }
never executed: end of block
0
894 png_set_PLTE(png_ptr, info_ptr, palette, num_palette);-
895-
896 if (num_trans) {
num_transDescription
TRUEnever evaluated
FALSEnever evaluated
0
897 png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0);-
898 }
never executed: end of block
0
899 }
never executed: end of block
0
900-
901 // Swap ARGB to RGBA (normal PNG format) before saving on-
902 // BigEndian machines-
903 if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
QSysInfo::Byte...nfo::BigEndianDescription
TRUEnever evaluated
FALSEnever evaluated
0
904 png_set_swap_alpha(png_ptr);-
905 }
never executed: end of block
0
906-
907 // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless-
908 if (QSysInfo::ByteOrder == QSysInfo::LittleEndian
QSysInfo::Byte...::LittleEndianDescription
TRUEnever evaluated
FALSEnever evaluated
0
909 && image.format() != QImage::Format_RGB888) {
image.format()...:Format_RGB888Description
TRUEnever evaluated
FALSEnever evaluated
0
910 png_set_bgr(png_ptr);-
911 }
never executed: end of block
0
912-
913 if (off_x || off_y) {
off_xDescription
TRUEnever evaluated
FALSEnever evaluated
off_yDescription
TRUEnever evaluated
FALSEnever evaluated
0
914 png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL);-
915 }
never executed: end of block
0
916-
917 if (frames_written > 0)
frames_written > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
918 png_set_sig_bytes(png_ptr, 8);
never executed: png_set_sig_bytes(png_ptr, 8);
0
919-
920 if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) {
image.dotsPerMeterX() > 0Description
TRUEnever evaluated
FALSEnever evaluated
image.dotsPerMeterY() > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
921 png_set_pHYs(png_ptr, info_ptr,-
922 image.dotsPerMeterX(), image.dotsPerMeterY(),-
923 PNG_RESOLUTION_METER);-
924 }
never executed: end of block
0
925-
926 set_text(image, png_ptr, info_ptr, description);-
927-
928 png_write_info(png_ptr, info_ptr);-
929-
930 if (image.depth() != 1)
image.depth() != 1Description
TRUEnever evaluated
FALSEnever evaluated
0
931 png_set_packing(png_ptr);
never executed: png_set_packing(png_ptr);
0
932-
933 if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888)
color_type == (2)Description
TRUEnever evaluated
FALSEnever evaluated
image.format()...:Format_RGB888Description
TRUEnever evaluated
FALSEnever evaluated
0
934 png_set_filler(png_ptr, 0,
never executed: png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 1);
0
935 QSysInfo::ByteOrder == QSysInfo::BigEndian ?
never executed: png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 1);
0
936 PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
never executed: png_set_filler(png_ptr, 0, QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 1);
0
937-
938 if (looping >= 0 && frames_written == 0) {
looping >= 0Description
TRUEnever evaluated
FALSEnever evaluated
frames_written == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
939 uchar data[13] = "NETSCAPE2.0";-
940 // 0123456789aBC-
941 data[0xB] = looping%0x100;-
942 data[0xC] = looping/0x100;-
943 png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13);-
944 }
never executed: end of block
0
945 if (ms_delay >= 0 || disposal!=Unspecified) {
ms_delay >= 0Description
TRUEnever evaluated
FALSEnever evaluated
disposal!=UnspecifiedDescription
TRUEnever evaluated
FALSEnever evaluated
0
946 uchar data[4];-
947 data[0] = disposal;-
948 data[1] = 0;-
949 data[2] = (ms_delay/10)/0x100; // hundredths-
950 data[3] = (ms_delay/10)%0x100;-
951 png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4);-
952 }
never executed: end of block
0
953-
954 int height = image.height();-
955 int width = image.width();-
956 switch (image.format()) {-
957 case QImage::Format_Mono:
never executed: case QImage::Format_Mono:
0
958 case QImage::Format_MonoLSB:
never executed: case QImage::Format_MonoLSB:
0
959 case QImage::Format_Indexed8:
never executed: case QImage::Format_Indexed8:
0
960 case QImage::Format_Grayscale8:
never executed: case QImage::Format_Grayscale8:
0
961 case QImage::Format_RGB32:
never executed: case QImage::Format_RGB32:
0
962 case QImage::Format_ARGB32:
never executed: case QImage::Format_ARGB32:
0
963 case QImage::Format_RGB888:
never executed: case QImage::Format_RGB888:
0
964 {-
965 png_bytep* row_pointers = new png_bytep[height];-
966 for (int y=0; y<height; y++)
y<heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
967 row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
never executed: row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
0
968 png_write_image(png_ptr, row_pointers);-
969 delete [] row_pointers;-
970 }-
971 break;
never executed: break;
0
972 default:
never executed: default:
0
973 {-
974 QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32;
image.hasAlphaChannel()Description
TRUEnever evaluated
FALSEnever evaluated
0
975 QImage row;-
976 png_bytep row_pointers[1];-
977 for (int y=0; y<height; y++) {
y<heightDescription
TRUEnever evaluated
FALSEnever evaluated
0
978 row = image.copy(0, y, width, 1).convertToFormat(fmt);-
979 row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));-
980 png_write_rows(png_ptr, row_pointers, 1);-
981 }
never executed: end of block
0
982 }-
983 break;
never executed: break;
0
984 }-
985-
986 png_write_end(png_ptr, info_ptr);-
987 frames_written++;-
988-
989 png_destroy_write_struct(&png_ptr, &info_ptr);-
990-
991 return true;
never executed: return true;
0
992}-
993-
994static bool write_png_image(const QImage &image, QIODevice *device,-
995 int quality, float gamma, const QString &description)-
996{-
997 QPNGImageWriter writer(device);-
998 if (quality >= 0) {
quality >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
999 quality = qMin(quality, 100);-
1000 quality = (100-quality) * 9 / 91; // map [0,100] -> [9,0]-
1001 }
never executed: end of block
0
1002 writer.setGamma(gamma);-
1003 return writer.writeImage(image, quality, description);
never executed: return writer.writeImage(image, quality, description);
0
1004}-
1005-
1006QPngHandler::QPngHandler()-
1007 : d(new QPngHandlerPrivate(this))-
1008{-
1009}
never executed: end of block
0
1010-
1011QPngHandler::~QPngHandler()-
1012{-
1013 if (d->png_ptr)
d->png_ptrDescription
TRUEnever evaluated
FALSEnever evaluated
0
1014 png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_info);
never executed: png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_info);
0
1015 delete d;-
1016}
never executed: end of block
0
1017-
1018bool QPngHandler::canRead() const-
1019{-
1020 if (d->state == QPngHandlerPrivate::Ready && !canRead(device()))
d->state == QP...Private::ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!canRead(device())Description
TRUEnever evaluated
FALSEnever evaluated
0
1021 return false;
never executed: return false;
0
1022-
1023 if (d->state != QPngHandlerPrivate::Error) {
d->state != QP...Private::ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1024 setFormat("png");-
1025 return true;
never executed: return true;
0
1026 }-
1027-
1028 return false;
never executed: return false;
0
1029}-
1030-
1031bool QPngHandler::canRead(QIODevice *device)-
1032{-
1033 if (!device) {
!deviceDescription
TRUEnever evaluated
FALSEnever evaluated
0
1034 qWarning("QPngHandler::canRead() called with no device");-
1035 return false;
never executed: return false;
0
1036 }-
1037-
1038 return device->peek(8) == "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
never executed: return device->peek(8) == "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
0
1039}-
1040-
1041bool QPngHandler::read(QImage *image)-
1042{-
1043 if (!canRead())
!canRead()Description
TRUEnever evaluated
FALSEnever evaluated
0
1044 return false;
never executed: return false;
0
1045 return d->readPngImage(image);
never executed: return d->readPngImage(image);
0
1046}-
1047-
1048bool QPngHandler::write(const QImage &image)-
1049{-
1050 return write_png_image(image, device(), d->quality, d->gamma, d->description);
never executed: return write_png_image(image, device(), d->quality, d->gamma, d->description);
0
1051}-
1052-
1053bool QPngHandler::supportsOption(ImageOption option) const-
1054{-
1055 return option == Gamma
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == GammaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1056 || option == Description
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == DescriptionDescription
TRUEnever evaluated
FALSEnever evaluated
0
1057 || option == ImageFormat
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == ImageFormatDescription
TRUEnever evaluated
FALSEnever evaluated
0
1058 || option == Quality
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == QualityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1059 || option == Size
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == SizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1060 || option == ScaledSize;
never executed: return option == Gamma || option == Description || option == ImageFormat || option == Quality || option == Size || option == ScaledSize;
option == ScaledSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1061}-
1062-
1063QVariant QPngHandler::option(ImageOption option) const-
1064{-
1065 if (d->state == QPngHandlerPrivate::Error)
d->state == QP...Private::ErrorDescription
TRUEnever evaluated
FALSEnever evaluated
0
1066 return QVariant();
never executed: return QVariant();
0
1067 if (d->state == QPngHandlerPrivate::Ready && !d->readPngHeader())
d->state == QP...Private::ReadyDescription
TRUEnever evaluated
FALSEnever evaluated
!d->readPngHeader()Description
TRUEnever evaluated
FALSEnever evaluated
0
1068 return QVariant();
never executed: return QVariant();
0
1069-
1070 if (option == Gamma)
option == GammaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1071 return d->gamma == 0.0 ? d->fileGamma : d->gamma;
never executed: return d->gamma == 0.0 ? d->fileGamma : d->gamma;
d->gamma == 0.0Description
TRUEnever evaluated
FALSEnever evaluated
0
1072 else if (option == Quality)
option == QualityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1073 return d->quality;
never executed: return d->quality;
0
1074 else if (option == Description)
option == DescriptionDescription
TRUEnever evaluated
FALSEnever evaluated
0
1075 return d->description;
never executed: return d->description;
0
1076 else if (option == Size)
option == SizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1077 return QSize(png_get_image_width(d->png_ptr, d->info_ptr),
never executed: return QSize(png_get_image_width(d->png_ptr, d->info_ptr), png_get_image_height(d->png_ptr, d->info_ptr));
0
1078 png_get_image_height(d->png_ptr, d->info_ptr));
never executed: return QSize(png_get_image_width(d->png_ptr, d->info_ptr), png_get_image_height(d->png_ptr, d->info_ptr));
0
1079 else if (option == ScaledSize)
option == ScaledSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1080 return d->scaledSize;
never executed: return d->scaledSize;
0
1081 else if (option == ImageFormat)
option == ImageFormatDescription
TRUEnever evaluated
FALSEnever evaluated
0
1082 return d->readImageFormat();
never executed: return d->readImageFormat();
0
1083 return QVariant();
never executed: return QVariant();
0
1084}-
1085-
1086void QPngHandler::setOption(ImageOption option, const QVariant &value)-
1087{-
1088 if (option == Gamma)
option == GammaDescription
TRUEnever evaluated
FALSEnever evaluated
0
1089 d->gamma = value.toFloat();
never executed: d->gamma = value.toFloat();
0
1090 else if (option == Quality)
option == QualityDescription
TRUEnever evaluated
FALSEnever evaluated
0
1091 d->quality = value.toInt();
never executed: d->quality = value.toInt();
0
1092 else if (option == Description)
option == DescriptionDescription
TRUEnever evaluated
FALSEnever evaluated
0
1093 d->description = value.toString();
never executed: d->description = value.toString();
0
1094 else if (option == ScaledSize)
option == ScaledSizeDescription
TRUEnever evaluated
FALSEnever evaluated
0
1095 d->scaledSize = value.toSize();
never executed: d->scaledSize = value.toSize();
0
1096}
never executed: end of block
0
1097-
1098QByteArray QPngHandler::name() const-
1099{-
1100 return "png";
never executed: return "png";
0
1101}-
1102-
1103QT_END_NAMESPACE-
1104-
1105#endif // QT_NO_IMAGEFORMAT_PNG-
Source codeSwitch to Preprocessed file

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