diff options
author | Jan-Arve Sæther <jan-arve.saether@nokia.com> | 2009-04-22 14:27:44 (GMT) |
---|---|---|
committer | Jan-Arve Sæther <jan-arve.saether@nokia.com> | 2009-04-22 14:36:19 (GMT) |
commit | fd9cdaa55da455b90eacec571aeb2c84fa55f7e0 (patch) | |
tree | 774050472bc3096e4f2eec782f897da57bad85c8 /src/plugins/imageformats | |
parent | a8d14ae567c7e847c6dbba644c36fbc6c6afc468 (diff) | |
download | Qt-fd9cdaa55da455b90eacec571aeb2c84fa55f7e0.zip Qt-fd9cdaa55da455b90eacec571aeb2c84fa55f7e0.tar.gz Qt-fd9cdaa55da455b90eacec571aeb2c84fa55f7e0.tar.bz2 |
Improve the icon parsing for files with a slightly wrong BMP header.
The reason it failed was that we always expected the height property
of the BMP header to be double the height of the icon. The
kde_favicon.ico did not fulfill this requirement. We can fix that by
simply reading from the ICONDIR entry instead, since that has always
the correct height.
Task-number: 229829
Reviewed-by: alexis
Diffstat (limited to 'src/plugins/imageformats')
-rw-r--r-- | src/plugins/imageformats/ico/qicohandler.cpp | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index aa53370..da5ae15 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -80,7 +80,7 @@ typedef struct typedef struct { // BMP information header quint32 biSize; // size of this struct quint32 biWidth; // pixmap width - quint32 biHeight; // pixmap height + quint32 biHeight; // pixmap height (specifies the combined height of the XOR and AND masks) quint16 biPlanes; // should be 1 quint16 biBitCount; // number of bits per pixel quint32 biCompression; // compression method @@ -108,7 +108,7 @@ private: bool readHeader(); bool readIconEntry(int index, ICONDIRENTRY * iconEntry); - bool readBMPHeader(ICONDIRENTRY & iconEntry, BMP_INFOHDR * header); + bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header); void findColorInfo(QImage & image); void readColorTable(QImage & image); @@ -343,7 +343,7 @@ bool ICOReader::readHeader() return headerRead; } -bool ICOReader::readIconEntry(int index, ICONDIRENTRY * iconEntry) +bool ICOReader::readIconEntry(int index, ICONDIRENTRY *iconEntry) { if (iod) { if (iod->seek(startpos + ICONDIR_SIZE + (index * ICONDIRENTRY_SIZE))) { @@ -355,37 +355,12 @@ bool ICOReader::readIconEntry(int index, ICONDIRENTRY * iconEntry) -bool ICOReader::readBMPHeader(ICONDIRENTRY & iconEntry, BMP_INFOHDR * header) +bool ICOReader::readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header) { - memset(&icoAttrib, 0, sizeof(IcoAttrib)); if (iod) { - if (iod->seek(startpos + iconEntry.dwImageOffset)) { + if (iod->seek(startpos + imageOffset)) { if (readBMPInfoHeader(iod, header)) { - - icoAttrib.nbits = header->biBitCount ? header->biBitCount : iconEntry.wBitCount; - icoAttrib.h = header->biHeight / 2; // this height is always double the iconEntry height (for the mask) - icoAttrib.w = header->biWidth; - - switch (icoAttrib.nbits) { - case 32: - case 24: - case 16: - icoAttrib.depth = 32; - break; - case 8: - case 4: - icoAttrib.depth = 8; - break; - default: - icoAttrib.depth = 1; - } - - if ( icoAttrib.depth == 32 ) // there's no colormap - icoAttrib.ncolors = 0; - else // # colors used - icoAttrib.ncolors = header->biClrUsed ? header->biClrUsed : 1 << icoAttrib.nbits; - //qDebug() << "Bits:" << icoAttrib.nbits << "Depth:" << icoAttrib.depth << "Ncols:" << icoAttrib.ncolors; - return TRUE; + return TRUE; } } } @@ -548,7 +523,28 @@ QImage ICOReader::iconAt(int index) if (readIconEntry(index, &iconEntry)) { BMP_INFOHDR header; - if (readBMPHeader(iconEntry, &header)) { + if (readBMPHeader(iconEntry.dwImageOffset, &header)) { + icoAttrib.nbits = header.biBitCount ? header.biBitCount : iconEntry.wBitCount; + + switch (icoAttrib.nbits) { + case 32: + case 24: + case 16: + icoAttrib.depth = 32; + break; + case 8: + case 4: + icoAttrib.depth = 8; + break; + default: + icoAttrib.depth = 1; + } + if (icoAttrib.depth == 32) // there's no colormap + icoAttrib.ncolors = 0; + else // # colors used + icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits; + icoAttrib.w = iconEntry.bWidth; + icoAttrib.h = iconEntry.bHeight; QImage::Format format = QImage::Format_ARGB32; if (icoAttrib.nbits == 24) |