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>
40} ICONDIRENTRY, *LPICONDIRENTRY;
41#define ICONDIRENTRY_SIZE 16
65#define BMP_INFOHDR_SIZE 40
137 return iodev->
write((
char*)&iconDir, 6) == 6;
167 return iconDir.idCount;
173 bool isProbablyICO =
false;
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)
186 && ikonDir.idEntries[0].dwBytesInRes >= 40
188 isProbablyICO =
true;
193 quint32 tmp = ikonDir.idEntries[0].dwImageOffset;
199 tmp = ikonDir.idEntries[0].dwBytesInRes;
205 tmp = ikonDir.idEntries[0].wBitCount;
209 tmp = ikonDir.idEntries[0].wPlanes;
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);
226 tmp = ikonDir.idType;
230 tmp = ikonDir.idReserved;
238 return isProbablyICO;
241bool ICOReader::readHeader()
243 if (iod && !headerRead) {
244 startpos = iod->
pos();
246 if (iconDir.idReserved == 0 && (iconDir.idType == 1 || iconDir.idType == 2))
269 if (iod->
seek(startpos + imageOffset)) {
280 if (icoAttrib.ncolors > 0) {
281 readColorTable(
image);
282 }
else if (icoAttrib.nbits == 16) {
290 image.setColorCount(icoAttrib.ncolors);
292 for (
int i=0;
i<icoAttrib.ncolors;
i++) {
293 if (iod->
read((
char*)
rgb, 4) != 4) {
306 if (icoAttrib.nbits == 1) {
308 }
else if (icoAttrib.nbits == 4) {
310 }
else if (icoAttrib.nbits == 8) {
312 }
else if (icoAttrib.nbits == 16 || icoAttrib.nbits == 24 || icoAttrib.nbits == 32 ) {
313 read16_24_32BMP(
image);
331 if (iod->
read((
char*)
image.scanLine(
h),bpl) != bpl) {
346 int buflen = ((icoAttrib.w+7)/8)*4;
351 if (iod->
read((
char*)
buf,buflen) != buflen) {
357 for (
int i=0;
i<icoAttrib.w/2;
i++) {
380 if (iod->
read((
char *)
image.scanLine(
h), bpl) != bpl) {
402 end =
p + icoAttrib.w;
403 if (iod->
read((
char *)
buf, bpl) != bpl) {
409 if (icoAttrib.nbits == 24)
411 else if (icoAttrib.nbits == 32)
413 b += icoAttrib.nbits/8;
432 ICONDIRENTRY iconEntry;
435 static const uchar pngMagicData[] = { 137, 80, 78, 71, 13, 10, 26, 10 };
437 if (!iod->
seek(iconEntry.dwImageOffset)
442 const bool isPngImage = (iod->
read(pngMagic.
size()) == pngMagic);
445 iod->
seek(iconEntry.dwImageOffset);
452 if (readBMPHeader(iconEntry.dwImageOffset, &
header)) {
453 icoAttrib.nbits =
header.biBitCount ?
header.biBitCount : iconEntry.wBitCount;
455 switch (icoAttrib.nbits) {
459 icoAttrib.depth = 32;
472 if (icoAttrib.depth == 32)
473 icoAttrib.ncolors = 0;
475 icoAttrib.ncolors =
header.biClrUsed ?
uint(
header.biClrUsed) : 1 << icoAttrib.nbits;
476 if (icoAttrib.ncolors > 256)
478 icoAttrib.w = iconEntry.bWidth;
479 if (icoAttrib.w == 0)
480 icoAttrib.w =
header.biWidth;
481 icoAttrib.h = iconEntry.bHeight;
482 if (icoAttrib.h == 0)
483 icoAttrib.h =
header.biHeight/2;
484 if (icoAttrib.w > 256 || icoAttrib.h > 256)
488 if (icoAttrib.nbits == 24)
490 else if (icoAttrib.ncolors == 2 && icoAttrib.depth == 1)
492 else if (icoAttrib.ncolors > 0)
496 const QSize size(icoAttrib.w, icoAttrib.h);
498 findColorInfo(
image);
499 if (!
image.isNull()) {
501 if (!
image.isNull()) {
502 if (icoAttrib.depth == 32) {
506 if (!
mask.isNull()) {
507 mask.setColorCount(2);
508 mask.setColor(0,
qRgba(255,255,255,0xff));
511 if (!
mask.isNull()) {
543 const int N = reader.count();
545 for (
int i = 0;
i < N;
i++)
566 bool retValue =
false;
577 ICONDIRENTRY * entries =
new ICONDIRENTRY[
id.idCount];
581 for (
int i=0;
i<
id.idCount;
i++) {
586 if (
image.width() > 256 ||
image.height() > 256)
595 int bpl_bmp = ((
image.width()*nbits+31)/32)*4;
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;
601 entries[
i].bWidth =
image.width() < 256 ?
image.width() : 0;
604 entries[
i].wPlanes = 1;
609 entries[
i].dwImageOffset = entries[
i-1].dwImageOffset + entries[
i-1].dwBytesInRes;
615 bmpHeaders[
i].
biHeight = entries[
i].bHeight ? entries[
i].bHeight * 2 : 256 * 2;
619 bmpHeaders[
i].
biWidth = entries[
i].bWidth ? entries[
i].bWidth : 256;
628 memset(
buf, 0, bpl_bmp );
630 for (
y =
image.height() - 1;
y >= 0;
y--) {
651 for (
y = maskImage.
height() - 1;
y >= 0;
y--)
658 for (
i = 0;
i <
id.idCount && bOK;
i++) {
662 for (
i = 0;
i <
id.idCount && bOK;
i++) {
671 delete [] bmpHeaders;
683 m_currentIconIndex = 0;
699 ICONDIRENTRY iconEntry;
700 if (m_pICOReader->
readIconEntry(m_currentIconIndex, &iconEntry)) {
703 return QSize(iconEntry.bWidth ? iconEntry.bWidth : 256,
704 iconEntry.bHeight ? iconEntry.bHeight : 256);
707 switch (iconEntry.wBitCount) {
738 bool bCanRead =
false;
745 qCWarning(lcIco,
"QtIcoHandler::canRead() called with no device");
764 bool bSuccess =
false;
793 return m_pICOReader->
count();
802 m_currentIconIndex = imageNumber;
IOBluetoothDevice * device
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
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
\inmodule QtCore \reentrant
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.
qsizetype bytesPerLine() const
Returns the number of bytes per image scanline.
void setPixel(int x, int y, uint index_or_rgb)
This is an overloaded member function, provided for convenience. It differs from the above function o...
uchar * scanLine(int)
Returns a pointer to the pixel data at the scanline with index i.
int height() const
Returns the height of the image.
Format
The following image formats are available in Qt.
@ Format_ARGB32_Premultiplied
void fill(uint pixel)
Fills the entire image with the given pixelValue.
static QImage fromData(QByteArrayView data, const char *format=nullptr)
qsizetype size() const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
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.
static QString header(const QString &name)
static bool writeIconDir(QIODevice *iodev, const ICONDIR &iconDir)
#define ICONDIRENTRY_SIZE
static const char icoOrigDepthKey[]
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)
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]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLint GLsizei GLsizei GLenum format
GLfloat GLfloat GLfloat GLfloat h
QT_BEGIN_NAMESPACE typedef unsigned int QRgb
constexpr QRgb qRgb(int r, int g, int b)
constexpr int qRed(QRgb rgb)
constexpr int qGreen(QRgb rgb)
constexpr QRgb qRgba(int r, int g, int b, int a)
constexpr int qBlue(QRgb rgb)
constexpr int qAlpha(QRgb rgb)
QLatin1StringView QLatin1String
QList< QImage > images
[6]
Q_CHECK_PTR(a=new int[80])
quint32_le biClrImportant
quint32_le biXPelsPerMeter
quint32_le biYPelsPerMeter