diff --git a/kimgio/ico.cpp b/kimgio/ico.cpp index f8ae6d8f..3ea71a9c 100644 --- a/kimgio/ico.cpp +++ b/kimgio/ico.cpp @@ -193,9 +193,11 @@ bool ICOHandler::read(QImage *image) // fallbacks const int imagewidth = (icowidth ? icowidth : bmpwidth); const int imageheight = (icoheight ? icoheight : (bmpheight / 2)); + const int imagencolors = (icocolors ? icocolors : bmpncolors); int imageboundary = 0; QImage::Format imageformat = QImage::Format_ARGB32; + QList imagecolors; switch (bmpbpp) { case 32: { imageboundary = (imagewidth * imageheight * 4); @@ -206,6 +208,11 @@ bool ICOHandler::read(QImage *image) imageboundary = (imagewidth * imageheight * 3); break; } + case 8: { + imageformat = QImage::Format_RGB32; + imageboundary = (imagewidth * imageheight * 3); + break; + } default: { kWarning() << "Unsupported BMP bits per-pixel" << bmpbpp; return false; @@ -214,12 +221,29 @@ bool ICOHandler::read(QImage *image) if (Q_UNLIKELY(bmpimagesize == 0)) { kDebug() << "BMP image size is dummy" << bmpimagesize << imageboundary; - bmpimagesize = imageboundary; + bmpimagesize = (bmpbpp == 8 ? (imageboundary / 3): imageboundary); } else if (Q_UNLIKELY(bmpimagesize >= INT_MAX)) { kWarning() << "BMP image size is too big" << bmpimagesize; return false; } + if (bmpbpp == 8) { + QByteArray imagecolorbytes(imagencolors * 4, '\0'); + if (Q_UNLIKELY(datastream.readRawData(imagecolorbytes.data(), imagecolorbytes.size()) != imagecolorbytes.size())) { + kWarning() << "Could not read BMP colors data"; + return false; + } + for (int ci = 0; ci < imagecolorbytes.size(); ci += 4) { + imagecolors.append( + qRgb(imagecolorbytes.at(ci + 2), imagecolorbytes.at(ci + 1), imagecolorbytes.at(ci)) + ); + } + if (Q_UNLIKELY(imagecolors.size() != 256)) { + kWarning() << "Invalid BMP image color table" << imagecolors.size(); + return false; + } + } + imagebytes.resize(bmpimagesize); if (Q_UNLIKELY(datastream.readRawData(imagebytes.data(), bmpimagesize) != bmpimagesize)) { kWarning() << "Could not read BMP image data"; @@ -232,10 +256,6 @@ bool ICOHandler::read(QImage *image) return false; } - if (Q_UNLIKELY(bmpimagesize != imageboundary)) { - kDebug() << "BMP and QImage bytes count mismatch" << bmpimagesize << imageboundary; - } - switch (bmpbpp) { case 32: { #if Q_BYTE_ORDER == Q_BIG_ENDIAN @@ -258,6 +278,14 @@ bool ICOHandler::read(QImage *image) } break; } + case 8: { + QRgb* bmpimagebits = reinterpret_cast(bmpimage.bits()); + for (uint bi = 0; bi < (bmpimagesize * 3) && bi < imageboundary; bi += 3) { + *bmpimagebits = imagecolors[imagebytes.at(bi / 3)]; + bmpimagebits++; + } + break; + } default: { Q_ASSERT(false); break;