summaryrefslogtreecommitdiffstats
path: root/src/plugins/imageformats/ico/qicohandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/imageformats/ico/qicohandler.cpp')
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp67
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