diff options
Diffstat (limited to 'src/plugins/imageformats/ico/qicohandler.cpp')
-rw-r--r-- | src/plugins/imageformats/ico/qicohandler.cpp | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4cb5e22bf7..19525397fa 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -96,13 +96,14 @@ public: QImage iconAt(int index); static bool canRead(QIODevice *iodev); - static QList<QImage> read(QIODevice * device); + static QVector<QImage> read(QIODevice *device); - static bool write(QIODevice * device, const QList<QImage> & images); + 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; @@ -612,12 +613,14 @@ QImage ICOReader::iconAt(int index) \sa write() */ -QList<QImage> ICOReader::read(QIODevice * device) +QVector<QImage> ICOReader::read(QIODevice *device) { - QList<QImage> images; + QVector<QImage> images; ICOReader reader(device); - for (int i = 0; i < reader.count(); i++) + const int N = reader.count(); + images.reserve(N); + for (int i = 0; i < N; i++) images += reader.iconAt(i); return images; @@ -636,7 +639,7 @@ QList<QImage> ICOReader::read(QIODevice * device) \sa read() */ -bool ICOReader::write(QIODevice * device, const QList<QImage> & images) +bool ICOReader::write(QIODevice *device, const QVector<QImage> &images) { bool retValue = false; @@ -656,10 +659,11 @@ bool ICOReader::write(QIODevice * device, const QList<QImage> & images) for (int i=0; i<id.idCount; i++) { QImage image = images[i]; - // Scale down the image if it is larger than 128 pixels in either width or height - if (image.width() > 128 || image.height() > 128) + // Scale down the image if it is larger than 256 pixels in either width or height + // because this is a maximum size of image in the ICO file. + if (image.width() > 256 || image.height() > 256) { - image = image.scaled(128, 128, Qt::KeepAspectRatio, Qt::SmoothTransformation); + image = image.scaled(256, 256, Qt::KeepAspectRatio, Qt::SmoothTransformation); } QImage maskImage(image.width(), image.height(), QImage::Format_Mono); image = image.convertToFormat(QImage::Format_ARGB32); @@ -776,25 +780,37 @@ QtIcoHandler::~QtIcoHandler() QVariant QtIcoHandler::option(ImageOption option) const { - if (option == Size) { - QIODevice *device = QImageIOHandler::device(); - qint64 oldPos = device->pos(); + if (option == Size || option == ImageFormat) { 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)) { + switch (option) { + case Size: + return QSize(iconEntry.bWidth ? iconEntry.bWidth : 256, + iconEntry.bHeight ? iconEntry.bHeight : 256); + + case ImageFormat: + switch (iconEntry.wBitCount) { + case 2: + return QImage::Format_Mono; + case 24: + return QImage::Format_RGB32; + case 32: + return QImage::Format_ARGB32; + default: + return QImage::Format_Indexed8; + } + break; + default: + break; } } - if (!device->isSequential()) - device->seek(oldPos); } return QVariant(); } bool QtIcoHandler::supportsOption(ImageOption option) const { - return option == Size; + return (option == Size || option == ImageFormat); } /*! @@ -849,7 +865,7 @@ bool QtIcoHandler::read(QImage *image) bool QtIcoHandler::write(const QImage &image) { QIODevice *device = QImageIOHandler::device(); - QList<QImage> imgs; + QVector<QImage> imgs; imgs.append(image); return ICOReader::write(device, imgs); } @@ -879,9 +895,10 @@ bool QtIcoHandler::jumpToImage(int imageNumber) { if (imageNumber < imageCount()) { m_currentIconIndex = imageNumber; + return true; } - return imageNumber < imageCount(); + return false; } /*! \reimp |