Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qicohandler.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
13#include "qicohandler.h"
14#include <QtCore/qendian.h>
15#include <private/qendian_p.h>
16#include <QtGui/QImage>
17#include <QtCore/QBuffer>
18#include <QtCore/QFile>
19#include <QtCore/QLoggingCategory>
20#include <qvariant.h>
21
23
24Q_LOGGING_CATEGORY(lcIco, "qt.gui.imageio.ico")
25
26namespace {
27
28// These next two structs represent how the icon information is stored
29// in an ICO file.
30typedef struct
31{
32 quint8 bWidth; // Width of the image
33 quint8 bHeight; // Height of the image (actual height, not times 2)
34 quint8 bColorCount; // Number of colors in image (0 if >=8bpp) [ not ture ]
35 quint8 bReserved; // Reserved
36 quint16_le wPlanes; // Color Planes
37 quint16_le wBitCount; // Bits per pixel
38 quint32_le dwBytesInRes; // how many bytes in this resource?
39 quint32_le dwImageOffset; // where in the file is this image
40} ICONDIRENTRY, *LPICONDIRENTRY;
41#define ICONDIRENTRY_SIZE 16
42
43typedef struct
44{
46 quint16_le idType; // resource type (1 for icons, 2 for cursors)
47 quint16_le idCount; // how many images?
48 ICONDIRENTRY idEntries[1]; // the entries for each image
49} ICONDIR, *LPICONDIR;
50#define ICONDIR_SIZE 6 // Exclude the idEntries field
51
52typedef struct { // BMP information header
53 quint32_le biSize; // size of this struct
54 quint32_le biWidth; // pixmap width
55 quint32_le biHeight; // pixmap height (specifies the combined height of the XOR and AND masks)
56 quint16_le biPlanes; // should be 1
57 quint16_le biBitCount; // number of bits per pixel
58 quint32_le biCompression; // compression method
59 quint32_le biSizeImage; // size of image
60 quint32_le biXPelsPerMeter; // horizontal resolution
61 quint32_le biYPelsPerMeter; // vertical resolution
62 quint32_le biClrUsed; // number of colors used
63 quint32_le biClrImportant; // number of important colors
64} BMP_INFOHDR ,*LPBMP_INFOHDR;
65#define BMP_INFOHDR_SIZE 40
66
67}
68
70{
71public:
72 ICOReader(QIODevice * iodevice);
73 int count();
74 QImage iconAt(int index);
75 static bool canRead(QIODevice *iodev);
76
77 static QList<QImage> read(QIODevice *device);
78
79 static bool write(QIODevice *device, const QList<QImage> &images);
80
81 bool readIconEntry(int index, ICONDIRENTRY * iconEntry);
82
83private:
84 bool readHeader();
85
86 bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header);
87 void findColorInfo(QImage & image);
88 void readColorTable(QImage & image);
89
90 void readBMP(QImage & image);
91 void read1BitBMP(QImage & image);
92 void read4BitBMP(QImage & image);
93 void read8BitBMP(QImage & image);
94 void read16_24_32BMP(QImage & image);
95
96 struct IcoAttrib
97 {
98 int nbits;
99 int ncolors;
100 int h;
101 int w;
102 int depth;
103 } icoAttrib;
104
105 QIODevice * iod;
106 qint64 startpos;
107 bool headerRead;
108 ICONDIR iconDir;
109
110};
111
112// Data readers and writers that takes care of alignment and endian stuff.
113static bool readIconDirEntry(QIODevice *iodev, ICONDIRENTRY *iconDirEntry)
114{
115 if (iodev)
116 return (iodev->read((char*)iconDirEntry, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE);
117 return false;
118}
119
120static bool writeIconDirEntry(QIODevice *iodev, const ICONDIRENTRY &iconEntry)
121{
122 if (iodev)
123 return iodev->write((char*)&iconEntry, ICONDIRENTRY_SIZE) == ICONDIRENTRY_SIZE;
124 return false;
125}
126
127static bool readIconDir(QIODevice *iodev, ICONDIR *iconDir)
128{
129 if (iodev)
130 return (iodev->read((char*)iconDir, ICONDIR_SIZE) == ICONDIR_SIZE);
131 return false;
132}
133
134static bool writeIconDir(QIODevice *iodev, const ICONDIR &iconDir)
135{
136 if (iodev)
137 return iodev->write((char*)&iconDir, 6) == 6;
138 return false;
139}
140
141static bool readBMPInfoHeader(QIODevice *iodev, BMP_INFOHDR *pHeader)
142{
143 if (iodev)
144 return (iodev->read((char*)pHeader, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE);
145 return false;
146}
147
149{
150 if (iodev)
151 return iodev->write((char*)&header, BMP_INFOHDR_SIZE) == BMP_INFOHDR_SIZE;
152 return false;
153}
154
155
157: iod(iodevice)
158, startpos(0)
159, headerRead(false)
160{
161}
162
163
165{
166 if (readHeader())
167 return iconDir.idCount;
168 return 0;
169}
170
172{
173 bool isProbablyICO = false;
174 if (iodev) {
175 qint64 oldPos = iodev->pos();
176
177 ICONDIR ikonDir;
178 if (readIconDir(iodev, &ikonDir)) {
179 if (readIconDirEntry(iodev, &ikonDir.idEntries[0])) {
180 // ICO format does not have a magic identifier, so we read 6 different values, which will hopefully be enough to identify the file.
181 if ( ikonDir.idReserved == 0
182 && (ikonDir.idType == 1 || ikonDir.idType == 2)
183 && ikonDir.idEntries[0].bReserved == 0
184 && (ikonDir.idEntries[0].wPlanes <= 1 || ikonDir.idType == 2)
185 && (ikonDir.idEntries[0].wBitCount <= 32 || ikonDir.idType == 2) // Bits per pixel
186 && ikonDir.idEntries[0].dwBytesInRes >= 40 // Must be over 40, since sizeof (infoheader) == 40
187 ) {
188 isProbablyICO = true;
189 }
190
191 if (iodev->isSequential()) {
192 // Our structs might be padded due to alignment, so we need to fetch each member before we ungetChar() !
193 quint32 tmp = ikonDir.idEntries[0].dwImageOffset;
194 iodev->ungetChar((tmp >> 24) & 0xff);
195 iodev->ungetChar((tmp >> 16) & 0xff);
196 iodev->ungetChar((tmp >> 8) & 0xff);
197 iodev->ungetChar(tmp & 0xff);
198
199 tmp = ikonDir.idEntries[0].dwBytesInRes;
200 iodev->ungetChar((tmp >> 24) & 0xff);
201 iodev->ungetChar((tmp >> 16) & 0xff);
202 iodev->ungetChar((tmp >> 8) & 0xff);
203 iodev->ungetChar(tmp & 0xff);
204
205 tmp = ikonDir.idEntries[0].wBitCount;
206 iodev->ungetChar((tmp >> 8) & 0xff);
207 iodev->ungetChar(tmp & 0xff);
208
209 tmp = ikonDir.idEntries[0].wPlanes;
210 iodev->ungetChar((tmp >> 8) & 0xff);
211 iodev->ungetChar(tmp & 0xff);
212
213 iodev->ungetChar(ikonDir.idEntries[0].bReserved);
214 iodev->ungetChar(ikonDir.idEntries[0].bColorCount);
215 iodev->ungetChar(ikonDir.idEntries[0].bHeight);
216 iodev->ungetChar(ikonDir.idEntries[0].bWidth);
217 }
218 }
219
220 if (iodev->isSequential()) {
221 // Our structs might be padded due to alignment, so we need to fetch each member before we ungetChar() !
222 quint32 tmp = ikonDir.idCount;
223 iodev->ungetChar((tmp >> 8) & 0xff);
224 iodev->ungetChar(tmp & 0xff);
225
226 tmp = ikonDir.idType;
227 iodev->ungetChar((tmp >> 8) & 0xff);
228 iodev->ungetChar(tmp & 0xff);
229
230 tmp = ikonDir.idReserved;
231 iodev->ungetChar((tmp >> 8) & 0xff);
232 iodev->ungetChar(tmp & 0xff);
233 }
234 }
235 if (!iodev->isSequential()) iodev->seek(oldPos);
236 }
237
238 return isProbablyICO;
239}
240
241bool ICOReader::readHeader()
242{
243 if (iod && !headerRead) {
244 startpos = iod->pos();
245 if (readIconDir(iod, &iconDir)) {
246 if (iconDir.idReserved == 0 && (iconDir.idType == 1 || iconDir.idType == 2))
247 headerRead = true;
248 }
249 }
250
251 return headerRead;
252}
253
254bool ICOReader::readIconEntry(int index, ICONDIRENTRY *iconEntry)
255{
256 if (readHeader()) {
257 if (iod->seek(startpos + ICONDIR_SIZE + (index * ICONDIRENTRY_SIZE))) {
258 return readIconDirEntry(iod, iconEntry);
259 }
260 }
261 return false;
262}
263
264
265
266bool ICOReader::readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header)
267{
268 if (iod) {
269 if (iod->seek(startpos + imageOffset)) {
270 if (readBMPInfoHeader(iod, header)) {
271 return true;
272 }
273 }
274 }
275 return false;
276}
277
278void ICOReader::findColorInfo(QImage & image)
279{
280 if (icoAttrib.ncolors > 0) { // set color table
281 readColorTable(image);
282 } else if (icoAttrib.nbits == 16) { // don't support RGB values for 15/16 bpp
283 image = QImage();
284 }
285}
286
287void ICOReader::readColorTable(QImage & image)
288{
289 if (iod) {
290 image.setColorCount(icoAttrib.ncolors);
291 uchar rgb[4];
292 for (int i=0; i<icoAttrib.ncolors; i++) {
293 if (iod->read((char*)rgb, 4) != 4) {
294 image = QImage();
295 break;
296 }
297 image.setColor(i, qRgb(rgb[2],rgb[1],rgb[0]));
298 }
299 } else {
300 image = QImage();
301 }
302}
303
304void ICOReader::readBMP(QImage & image)
305{
306 if (icoAttrib.nbits == 1) { // 1 bit BMP image
307 read1BitBMP(image);
308 } else if (icoAttrib.nbits == 4) { // 4 bit BMP image
309 read4BitBMP(image);
310 } else if (icoAttrib.nbits == 8) {
311 read8BitBMP(image);
312 } else if (icoAttrib.nbits == 16 || icoAttrib.nbits == 24 || icoAttrib.nbits == 32 ) { // 16,24,32 bit BMP image
313 read16_24_32BMP(image);
314 }
315}
316
317
323void ICOReader::read1BitBMP(QImage & image)
324{
325 if (iod) {
326
327 int h = image.height();
328 qsizetype bpl = image.bytesPerLine();
329
330 while (--h >= 0) {
331 if (iod->read((char*)image.scanLine(h),bpl) != bpl) {
332 image = QImage();
333 break;
334 }
335 }
336 } else {
337 image = QImage();
338 }
339}
340
341void ICOReader::read4BitBMP(QImage & image)
342{
343 if (iod) {
344
345 int h = icoAttrib.h;
346 int buflen = ((icoAttrib.w+7)/8)*4;
347 uchar *buf = new uchar[buflen];
349
350 while (--h >= 0) {
351 if (iod->read((char*)buf,buflen) != buflen) {
352 image = QImage();
353 break;
354 }
355 uchar *p = image.scanLine(h);
356 uchar *b = buf;
357 for (int i=0; i<icoAttrib.w/2; i++) { // convert nibbles to bytes
358 *p++ = *b >> 4;
359 *p++ = *b++ & 0x0f;
360 }
361 if (icoAttrib.w & 1) // the last nibble
362 *p = *b >> 4;
363 }
364
365 delete [] buf;
366
367 } else {
368 image = QImage();
369 }
370}
371
372void ICOReader::read8BitBMP(QImage & image)
373{
374 if (iod) {
375
376 int h = icoAttrib.h;
377 qsizetype bpl = image.bytesPerLine();
378
379 while (--h >= 0) {
380 if (iod->read((char *)image.scanLine(h), bpl) != bpl) {
381 image = QImage();
382 break;
383 }
384 }
385 } else {
386 image = QImage();
387 }
388}
389
390void ICOReader::read16_24_32BMP(QImage & image)
391{
392 if (iod) {
393 int h = icoAttrib.h;
394 QRgb *p;
395 QRgb *end;
396 uchar *buf = new uchar[image.bytesPerLine()];
397 qsizetype bpl = ((qsizetype(icoAttrib.w)*icoAttrib.nbits+31)/32)*4;
398 uchar *b;
399
400 while (--h >= 0) {
401 p = (QRgb *)image.scanLine(h);
402 end = p + icoAttrib.w;
403 if (iod->read((char *)buf, bpl) != bpl) {
404 image = QImage();
405 break;
406 }
407 b = buf;
408 while (p < end) {
409 if (icoAttrib.nbits == 24)
410 *p++ = qRgb(*(b+2), *(b+1), *b);
411 else if (icoAttrib.nbits == 32)
412 *p++ = qRgba(*(b+2), *(b+1), *b, *(b+3));
413 b += icoAttrib.nbits/8;
414 }
415 }
416
417 delete[] buf;
418
419 } else {
420 image = QImage();
421 }
422}
423
424static const char icoOrigDepthKey[] = "_q_icoOrigDepth";
425
427{
428 QImage img;
429
430 if (count() > index) { // forces header to be read
431
432 ICONDIRENTRY iconEntry;
433 if (readIconEntry(index, &iconEntry)) {
434
435 static const uchar pngMagicData[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
436
437 if (!iod->seek(iconEntry.dwImageOffset)
438 || iconEntry.dwBytesInRes > iod->bytesAvailable())
439 return img;
440
441 const QByteArray pngMagic = QByteArray::fromRawData((const char*)pngMagicData, sizeof(pngMagicData));
442 const bool isPngImage = (iod->read(pngMagic.size()) == pngMagic);
443
444 if (isPngImage) {
445 iod->seek(iconEntry.dwImageOffset);
446 QImage image = QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
447 image.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
448 return image;
449 }
450
452 if (readBMPHeader(iconEntry.dwImageOffset, &header)) {
453 icoAttrib.nbits = header.biBitCount ? header.biBitCount : iconEntry.wBitCount;
454
455 switch (icoAttrib.nbits) {
456 case 32:
457 case 24:
458 case 16:
459 icoAttrib.depth = 32;
460 break;
461 case 8:
462 case 4:
463 icoAttrib.depth = 8;
464 break;
465 case 1:
466 icoAttrib.depth = 1;
467 break;
468 default:
469 return img;
470 break;
471 }
472 if (icoAttrib.depth == 32) // there's no colormap
473 icoAttrib.ncolors = 0;
474 else // # colors used
475 icoAttrib.ncolors = header.biClrUsed ? uint(header.biClrUsed) : 1 << icoAttrib.nbits;
476 if (icoAttrib.ncolors > 256) //color table can't be more than 256
477 return img;
478 icoAttrib.w = iconEntry.bWidth;
479 if (icoAttrib.w == 0) // means 256 pixels
480 icoAttrib.w = header.biWidth;
481 icoAttrib.h = iconEntry.bHeight;
482 if (icoAttrib.h == 0) // means 256 pixels
483 icoAttrib.h = header.biHeight/2;
484 if (icoAttrib.w > 256 || icoAttrib.h > 256) // Max ico size
485 return img;
486
488 if (icoAttrib.nbits == 24)
490 else if (icoAttrib.ncolors == 2 && icoAttrib.depth == 1)
492 else if (icoAttrib.ncolors > 0)
494
496 const QSize size(icoAttrib.w, icoAttrib.h);
498 findColorInfo(image);
499 if (!image.isNull()) {
500 readBMP(image);
501 if (!image.isNull()) {
502 if (icoAttrib.nbits == 32) {
503 img = std::move(image).convertToFormat(QImage::Format_ARGB32_Premultiplied);
504 } else {
505 QImage mask(image.width(), image.height(), QImage::Format_Mono);
506 if (!mask.isNull()) {
507 mask.setColorCount(2);
508 mask.setColor(0, qRgba(255,255,255,0xff));
509 mask.setColor(1, qRgba(0 ,0 ,0 ,0xff));
510 read1BitBMP(mask);
511 if (!mask.isNull()) {
512 img = image;
513 img.setAlphaChannel(mask);
514 }
515 }
516 }
517 }
518 }
519 }
520 img.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
521 }
522 }
523 }
524
525 return img;
526}
527
528
539{
540 QList<QImage> images;
541
542 ICOReader reader(device);
543 const int N = reader.count();
544 images.reserve(N);
545 for (int i = 0; i < N; i++)
546 images += reader.iconAt(i);
547
548 return images;
549}
550
551
564bool ICOReader::write(QIODevice *device, const QList<QImage> &images)
565{
566 bool retValue = false;
567
568 if (images.size()) {
569
570 qint64 origOffset = device->pos();
571
572 ICONDIR id;
573 id.idReserved = 0;
574 id.idType = 1;
575 id.idCount = images.size();
576
577 ICONDIRENTRY * entries = new ICONDIRENTRY[id.idCount];
578 BMP_INFOHDR * bmpHeaders = new BMP_INFOHDR[id.idCount];
579 QByteArray * imageData = new QByteArray[id.idCount];
580
581 for (int i=0; i<id.idCount; i++) {
582
583 QImage image = images[i];
584 // Scale down the image if it is larger than 256 pixels in either width or height
585 // because this is a maximum size of image in the ICO file.
586 if (image.width() > 256 || image.height() > 256)
587 {
589 }
590 QImage maskImage(image.width(), image.height(), QImage::Format_Mono);
591 image = image.convertToFormat(QImage::Format_ARGB32);
592 maskImage.fill(Qt::color1);
593
594 int nbits = 32;
595 int bpl_bmp = ((image.width()*nbits+31)/32)*4;
596
597 entries[i].bColorCount = 0;
598 entries[i].bReserved = 0;
599 entries[i].wBitCount = nbits;
600 entries[i].bHeight = image.height() < 256 ? image.height() : 0; // 0 means 256
601 entries[i].bWidth = image.width() < 256 ? image.width() : 0; // 0 means 256
602 entries[i].dwBytesInRes = BMP_INFOHDR_SIZE + (bpl_bmp * image.height())
603 + (maskImage.bytesPerLine() * maskImage.height());
604 entries[i].wPlanes = 1;
605 if (i == 0)
606 entries[i].dwImageOffset = origOffset + ICONDIR_SIZE
607 + (id.idCount * ICONDIRENTRY_SIZE);
608 else
609 entries[i].dwImageOffset = entries[i-1].dwImageOffset + entries[i-1].dwBytesInRes;
610
611 bmpHeaders[i].biBitCount = entries[i].wBitCount;
612 bmpHeaders[i].biClrImportant = 0;
613 bmpHeaders[i].biClrUsed = entries[i].bColorCount;
614 bmpHeaders[i].biCompression = 0;
615 bmpHeaders[i].biHeight = entries[i].bHeight ? entries[i].bHeight * 2 : 256 * 2; // 2 is for the mask
616 bmpHeaders[i].biPlanes = entries[i].wPlanes;
617 bmpHeaders[i].biSize = BMP_INFOHDR_SIZE;
618 bmpHeaders[i].biSizeImage = entries[i].dwBytesInRes - BMP_INFOHDR_SIZE;
619 bmpHeaders[i].biWidth = entries[i].bWidth ? entries[i].bWidth : 256;
620 bmpHeaders[i].biXPelsPerMeter = 0;
621 bmpHeaders[i].biYPelsPerMeter = 0;
622
625
626 uchar *buf = new uchar[bpl_bmp];
627 uchar *b;
628 memset( buf, 0, bpl_bmp );
629 int y;
630 for (y = image.height() - 1; y >= 0; y--) { // write the image bits
631 // 32 bits
632 QRgb *p = (QRgb *)image.scanLine(y);
633 QRgb *end = p + image.width();
634 b = buf;
635 int x = 0;
636 while (p < end) {
637 *b++ = qBlue(*p);
638 *b++ = qGreen(*p);
639 *b++ = qRed(*p);
640 *b++ = qAlpha(*p);
641 if (qAlpha(*p) > 0) // Even mostly transparent pixels must not be masked away
642 maskImage.setPixel(x, y, 0);
643 p++;
644 x++;
645 }
646 buffer.write((char*)buf, bpl_bmp);
647 }
648 delete[] buf;
649
650 // NOTE! !! The mask is only flipped vertically - not horizontally !!
651 for (y = maskImage.height() - 1; y >= 0; y--)
652 buffer.write((char*)maskImage.scanLine(y), maskImage.bytesPerLine());
653 }
654
655 if (writeIconDir(device, id)) {
656 int i;
657 bool bOK = true;
658 for (i = 0; i < id.idCount && bOK; i++) {
659 bOK = writeIconDirEntry(device, entries[i]);
660 }
661 if (bOK) {
662 for (i = 0; i < id.idCount && bOK; i++) {
663 bOK = writeBMPInfoHeader(device, bmpHeaders[i]);
664 bOK &= (device->write(imageData[i]) == (int) imageData[i].size());
665 }
666 retValue = bOK;
667 }
668 }
669
670 delete [] entries;
671 delete [] bmpHeaders;
672 delete [] imageData;
673
674 }
675 return retValue;
676}
677
682{
683 m_currentIconIndex = 0;
685 m_pICOReader = new ICOReader(device);
686}
687
692{
693 delete m_pICOReader;
694}
695
697{
698 if (option == Size || option == ImageFormat) {
699 ICONDIRENTRY iconEntry;
700 if (m_pICOReader->readIconEntry(m_currentIconIndex, &iconEntry)) {
701 switch (option) {
702 case Size:
703 return QSize(iconEntry.bWidth ? iconEntry.bWidth : 256,
704 iconEntry.bHeight ? iconEntry.bHeight : 256);
705
706 case ImageFormat:
707 switch (iconEntry.wBitCount) {
708 case 2:
709 return QImage::Format_Mono;
710 case 24:
712 case 32:
714 default:
716 }
717 break;
718 default:
719 break;
720 }
721 }
722 }
723 return QVariant();
724}
725
727{
728 return (option == Size || option == ImageFormat);
729}
730
737{
738 if (knownCanRead)
739 return true;
740 bool bCanRead = false;
742 if (device) {
743 bCanRead = ICOReader::canRead(device);
744 if (bCanRead)
745 setFormat("ico");
746 } else {
747 qCWarning(lcIco, "QtIcoHandler::canRead() called with no device");
748 }
749 knownCanRead = bCanRead;
750 return bCanRead;
751}
752
761
766{
767 bool bSuccess = false;
768 QImage img = m_pICOReader->iconAt(m_currentIconIndex);
769
770 // Make sure we only write to \a image when we succeed.
771 if (!img.isNull()) {
772 bSuccess = true;
773 *image = img;
774 }
775
776 return bSuccess;
777}
778
779
784{
786 QList<QImage> imgs;
787 imgs.append(image);
788 return ICOReader::write(device, imgs);
789}
790
795{
796 return m_pICOReader->count();
797}
798
802bool QtIcoHandler::jumpToImage(int imageNumber)
803{
804 if (imageNumber < imageCount()) {
805 m_currentIconIndex = imageNumber;
806 return true;
807 }
808
809 return false;
810}
811
816{
817 return jumpToImage(m_currentIconIndex + 1);
818}
819
IOBluetoothDevice * device
QImage iconAt(int index)
static QList< QImage > read(QIODevice *device)
Reads all the icons from the given device, and returns them as a list of QImage objects.
bool readIconEntry(int index, ICONDIRENTRY *iconEntry)
ICOReader(QIODevice *iodevice)
static bool write(QIODevice *device, const QList< QImage > &images)
Writes all the QImages in the images list to the given device.
static bool canRead(QIODevice *iodev)
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
virtual qint64 bytesAvailable() const
Returns the number of bytes that are available for reading.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
void ungetChar(char c)
Puts the character c back into the device, and decrements the current position unless the position is...
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
ImageOption
This enum describes the different options supported by QImageIOHandler.
static bool allocateImage(QSize size, QImage::Format format, QImage *image)
QIODevice * device() const
Returns the device currently assigned to the QImageIOHandler.
void setDevice(QIODevice *device)
Sets the device of the QImageIOHandler to device.
void setFormat(const QByteArray &format)
Sets the format of the QImageIOHandler to format.
\inmodule QtGui
Definition qimage.h:37
Format
The following image formats are available in Qt.
Definition qimage.h:41
@ Format_RGB32
Definition qimage.h:46
@ Format_Mono
Definition qimage.h:43
@ Format_Indexed8
Definition qimage.h:45
@ Format_ARGB32_Premultiplied
Definition qimage.h:48
@ Format_ARGB32
Definition qimage.h:47
static QImage fromData(QByteArrayView data, const char *format=nullptr)
Definition qimage.cpp:3841
qsizetype size() const noexcept
Definition qlist.h:397
void reserve(qsizetype size)
Definition qlist.h:753
\inmodule QtCore
Definition qsize.h:25
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
Definition qvariant.h:65
bool canRead() const override
Verifies if some values (magic bytes) are set as expected in the header of the file.
bool read(QImage *image) override
\reimp
virtual ~QtIcoHandler()
Destructor for QtIcoHandler.
bool supportsOption(ImageOption option) const override
Returns true if the QImageIOHandler supports the option option; otherwise returns false.
bool jumpToNextImage() override
\reimp
int imageCount() const override
\reimp
QVariant option(ImageOption option) const override
Returns the value assigned to option as a QVariant.
bool jumpToImage(int imageNumber) override
\reimp
bool write(const QImage &image) override
\reimp
QtIcoHandler(QIODevice *device)
Constructs an instance of QtIcoHandler initialized to use device.
Combined button and popup list for selecting options.
@ SmoothTransformation
@ KeepAspectRatio
@ color1
Definition qnamespace.h:29
Definition image.cpp:4
#define rgb(r, g, b)
Definition qcolor.cpp:124
static QString header(const QString &name)
static bool writeIconDir(QIODevice *iodev, const ICONDIR &iconDir)
#define ICONDIRENTRY_SIZE
static const char icoOrigDepthKey[]
#define BMP_INFOHDR_SIZE
static bool readIconDir(QIODevice *iodev, ICONDIR *iconDir)
static bool readIconDirEntry(QIODevice *iodev, ICONDIRENTRY *iconDirEntry)
static bool writeBMPInfoHeader(QIODevice *iodev, const BMP_INFOHDR &header)
static bool writeIconDirEntry(QIODevice *iodev, const ICONDIRENTRY &iconEntry)
#define ICONDIR_SIZE
static bool readBMPInfoHeader(QIODevice *iodev, BMP_INFOHDR *pHeader)
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLfloat GLfloat GLfloat w
[0]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLuint id
[7]
GLenum GLuint buffer
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLint void * img
Definition qopenglext.h:233
GLfloat GLfloat p
[1]
GLuint GLenum option
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
Definition qrgb.h:13
constexpr QRgb qRgb(int r, int g, int b)
Definition qrgb.h:30
constexpr int qRed(QRgb rgb)
Definition qrgb.h:18
constexpr int qGreen(QRgb rgb)
Definition qrgb.h:21
constexpr QRgb qRgba(int r, int g, int b, int a)
Definition qrgb.h:33
constexpr int qBlue(QRgb rgb)
Definition qrgb.h:24
constexpr int qAlpha(QRgb rgb)
Definition qrgb.h:27
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
unsigned char quint8
Definition qtypes.h:46
QList< QImage > images
[6]
Q_CHECK_PTR(a=new int[80])
QByteArray imageData
[15]