kimgio: implement reading of 8-bit depth BMP images for ico plugin

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-08-04 07:29:17 +03:00
parent 2647be1ab2
commit 970e069cd1

View file

@ -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<QRgb> 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<QRgb*>(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;