summaryrefslogtreecommitdiffstats
path: root/src/plugins/imageformats/ico
diff options
context:
space:
mode:
authorJan-Arve Sæther <jan-arve.saether@nokia.com>2009-04-22 14:27:44 (GMT)
committerJan-Arve Sæther <jan-arve.saether@nokia.com>2009-04-22 14:36:19 (GMT)
commitfd9cdaa55da455b90eacec571aeb2c84fa55f7e0 (patch)
tree774050472bc3096e4f2eec782f897da57bad85c8 /src/plugins/imageformats/ico
parenta8d14ae567c7e847c6dbba644c36fbc6c6afc468 (diff)
downloadQt-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/ico')
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp60
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)