Fix QImageReader::size() to return correct size for .ico files.
According to MSDN, the zero value of ICONDIRENTRY bHeight and bWidth fields mean a maximum icon size 256 pixels. So QtIcoHandler::option() should return 256 instead of 0 pixels for such icons. Also there is fixed wrong seek offset at the second call on this method. http://blogs.msdn.com/b/oldnewthing/archive/2010/10/18/10077133.aspx Task-number: QTBUG-48103 Change-Id: I99f0c9720fd58889045b0c73c51498f2065b0b91 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: aavit <eirik.aavitsland@theqtcompany.com>
This commit is contained in:
parent
d36a1dfb51
commit
f807a6de2c
@ -100,9 +100,10 @@ public:
|
||||
|
||||
static bool write(QIODevice *device, const QVector<QImage> &images);
|
||||
|
||||
bool readIconEntry(int index, ICONDIRENTRY * iconEntry);
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
bool readIconEntry(int index, ICONDIRENTRY * iconEntry);
|
||||
|
||||
bool readBMPHeader(quint32 imageOffset, BMP_INFOHDR * header);
|
||||
void findColorInfo(QImage & image);
|
||||
@ -341,7 +342,7 @@ bool ICOReader::readHeader()
|
||||
|
||||
bool ICOReader::readIconEntry(int index, ICONDIRENTRY *iconEntry)
|
||||
{
|
||||
if (iod) {
|
||||
if (readHeader()) {
|
||||
if (iod->seek(startpos + ICONDIR_SIZE + (index * ICONDIRENTRY_SIZE))) {
|
||||
return readIconDirEntry(iod, iconEntry);
|
||||
}
|
||||
@ -558,10 +559,10 @@ QImage ICOReader::iconAt(int index)
|
||||
if (icoAttrib.ncolors > 256) //color table can't be more than 256
|
||||
return img;
|
||||
icoAttrib.w = iconEntry.bWidth;
|
||||
if (icoAttrib.w == 0)
|
||||
if (icoAttrib.w == 0) // means 256 pixels
|
||||
icoAttrib.w = header.biWidth;
|
||||
icoAttrib.h = iconEntry.bHeight;
|
||||
if (icoAttrib.h == 0)
|
||||
if (icoAttrib.h == 0) // means 256 pixels
|
||||
icoAttrib.h = header.biHeight/2;
|
||||
|
||||
QImage::Format format = QImage::Format_ARGB32;
|
||||
@ -779,17 +780,11 @@ QtIcoHandler::~QtIcoHandler()
|
||||
QVariant QtIcoHandler::option(ImageOption option) const
|
||||
{
|
||||
if (option == Size) {
|
||||
QIODevice *device = QImageIOHandler::device();
|
||||
qint64 oldPos = device->pos();
|
||||
ICONDIRENTRY iconEntry;
|
||||
if (device->seek(oldPos + ICONDIR_SIZE + (m_currentIconIndex * ICONDIRENTRY_SIZE))) {
|
||||
if (readIconDirEntry(device, &iconEntry)) {
|
||||
device->seek(oldPos);
|
||||
return QSize(iconEntry.bWidth, iconEntry.bHeight);
|
||||
}
|
||||
if (m_pICOReader->readIconEntry(m_currentIconIndex, &iconEntry)) {
|
||||
return QSize(iconEntry.bWidth ? iconEntry.bWidth : 256,
|
||||
iconEntry.bHeight ? iconEntry.bHeight : 256);
|
||||
}
|
||||
if (!device->isSequential())
|
||||
device->seek(oldPos);
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
@ -324,6 +324,11 @@ void tst_QIcoImageFormat::pngCompression()
|
||||
|
||||
QImage image;
|
||||
reader.jumpToImage(index);
|
||||
|
||||
QSize size = reader.size();
|
||||
QCOMPARE(size.width(), width);
|
||||
QCOMPARE(size.height(), height);
|
||||
|
||||
reader.read(&image);
|
||||
|
||||
QCOMPARE(image.width(), width);
|
||||
|
Loading…
Reference in New Issue
Block a user