imageAlloc: add image initialization support

This commit is contained in:
Mirco Miranda
2026-05-07 08:41:10 +02:00
parent 3488077d8d
commit 1206598337
2 changed files with 37 additions and 6 deletions

View File

@@ -1031,7 +1031,7 @@ bool JXRHandler::read(QImage *outImage)
PKPixelFormatGUID convFmt;
auto imageFmt = d->imageFormat(&convFmt);
auto img = imageAlloc(d->imageSize(), imageFmt);
auto img = imageAlloc(d->imageSize(), imageFmt, ImageInitToZero::FPOnly);
if (img.isNull()) {
return false;
}

View File

@@ -13,6 +13,7 @@
#include <QImage>
#include <QImageIOHandler>
#include <QIODevice>
#include <QPixelFormat>
// Default maximum width and height for the large image plugins.
#ifndef KIF_LARGE_IMAGE_PIXEL_LIMIT
@@ -63,20 +64,50 @@
// QList uses some extra space for stuff, hence the 32 here suggested by Thiago Macieira
static constexpr int kMaxQVectorSize = std::numeric_limits<int>::max() - 32;
// On Qt 6 to make the plugins fail to allocate if the image size is greater than QImageReader::allocationLimit()
// it is necessary to allocate the image with QImageIOHandler::allocateImage().
inline QImage imageAlloc(const QSize &size, const QImage::Format &format)
/*!
* \brief The ImageInitToZero enum
*/
enum class ImageInitToZero
{
None, /**< Do not initialize the image. */
All, /**< Initialize all images. */
PremulOnly, /**< Initialize only images with premultiplied alpha. */
FPOnly, /**< Initialize only images with floating point format. */
FPAndPremul /**< Initialize floating point and premultiplied formats. */
};
/*!
* \brief imageAlloc
* Helper function to initialize framework images.
* \param size The image size.
* \param format The image format,
* \param init Whether and which images should be initialized to zero.
* \return The allocated image or a null image on error.
*/
inline QImage imageAlloc(const QSize &size, const QImage::Format &format, const ImageInitToZero& init = ImageInitToZero::None)
{
QImage img;
if (!QImageIOHandler::allocateImage(size, format, &img)) {
img = QImage(); // paranoia
}
if (init != ImageInitToZero::None && !img.isNull()) {
auto pixelFormat = img.pixelFormat();
auto isFloat = pixelFormat.typeInterpretation() == QPixelFormat::FloatingPoint;
auto isPremul = pixelFormat.premultiplied();
if (init == ImageInitToZero::All) {
img.fill(0);
} else if (isFloat && (init == ImageInitToZero::FPOnly || init == ImageInitToZero::FPAndPremul)) {
img.fill(0);
} else if (isPremul && (init == ImageInitToZero::PremulOnly || init == ImageInitToZero::FPAndPremul)) {
img.fill(0);
}
}
return img;
}
inline QImage imageAlloc(qint32 width, qint32 height, const QImage::Format &format)
inline QImage imageAlloc(qint32 width, qint32 height, const QImage::Format &format, const ImageInitToZero& init = ImageInitToZero::None)
{
return imageAlloc(QSize(width, height), format);
return imageAlloc(QSize(width, height), format, init);
}
template<class TI, class SF> // SF = source FP, TI = target INT