QImageIO: use the new allocation checker in the format handlers

Change-Id: I604d99ce476d4758a1e20b78257082911f1f1546
Task-number: QTBUG-85037
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Eirik Aavitsland 2020-06-05 16:09:43 +02:00
parent 5dea4fe956
commit 1a63409579
8 changed files with 45 additions and 88 deletions

View File

@ -280,17 +280,8 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
if (bi.biHeight < 0)
h = -h; // support images with negative height
if (image.size() != QSize(w, h) || image.format() != format) {
image = QImage(w, h, format);
if (image.isNull()) // could not create image
if (!QImageIOHandler::allocateImage(QSize(w, h), format, &image))
return false;
if (ncols)
image.setColorCount(ncols); // Ensure valid QImage
}
image.setDotsPerMeterX(bi.biXPelsPerMeter);
image.setDotsPerMeterY(bi.biYPelsPerMeter);
if (ncols > 0) { // read color table
image.setColorCount(ncols);
uchar rgb[4];
@ -339,6 +330,9 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, qint64 offset,
blue_scale = 8;
}
image.setDotsPerMeterX(bi.biXPelsPerMeter);
image.setDotsPerMeterY(bi.biYPelsPerMeter);
#if 0
qDebug("Rmask: %08x Rshift: %08x Rscale:%08x", red_mask, red_shift, red_scale);
qDebug("Gmask: %08x Gshift: %08x Gscale:%08x", green_mask, green_shift, green_scale);

View File

@ -239,7 +239,7 @@ void qpiw_flush_fn(png_structp /* png_ptr */)
}
static
void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead)
bool setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead)
{
png_uint_32 width = 0;
png_uint_32 height = 0;
@ -252,6 +252,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
int num_palette;
int interlace_method = PNG_INTERLACE_LAST;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, nullptr, nullptr);
QSize size(width, height);
png_set_interlace_handling(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY) {
@ -259,11 +260,8 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
if (bit_depth == 1 && png_get_channels(png_ptr, info_ptr) == 1) {
png_set_invert_mono(png_ptr);
png_read_update_info(png_ptr, info_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Mono) {
image = QImage(width, height, QImage::Format_Mono);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, QImage::Format_Mono, &image))
return false;
image.setColorCount(2);
image.setColor(1, qRgb(0,0,0));
image.setColor(0, qRgb(255,255,255));
@ -279,12 +277,8 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
} else if (bit_depth == 16
&& png_get_channels(png_ptr, info_ptr) == 1
&& !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale16) {
image = QImage(width, height, QImage::Format_Grayscale16);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, QImage::Format_Grayscale16, &image))
return false;
png_read_update_info(png_ptr, info_ptr);
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
png_set_swap(png_ptr);
@ -296,33 +290,23 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_set_expand(png_ptr);
png_set_gray_to_rgb(png_ptr);
QImage::Format format = hasMask ? QImage::Format_RGBA64 : QImage::Format_RGBX64;
if (image.size() != QSize(width, height) || image.format() != format) {
image = QImage(width, height, format);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, format, &image))
return false;
png_read_update_info(png_ptr, info_ptr);
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
png_set_swap(png_ptr);
} else if (bit_depth == 8 && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_expand(png_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Grayscale8) {
image = QImage(width, height, QImage::Format_Grayscale8);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, QImage::Format_Grayscale8, &image))
return false;
png_read_update_info(png_ptr, info_ptr);
} else {
if (bit_depth < 8)
png_set_packing(png_ptr);
int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
png_read_update_info(png_ptr, info_ptr);
if (image.size() != QSize(width, height) || image.format() != QImage::Format_Indexed8) {
image = QImage(width, height, QImage::Format_Indexed8);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, QImage::Format_Indexed8, &image))
return false;
image.setColorCount(ncols);
for (int i=0; i<ncols; i++) {
int c = i*255/(ncols-1);
@ -344,12 +328,10 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_set_packing(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr);
size = QSize(width, height);
QImage::Format format = bit_depth == 1 ? QImage::Format_Mono : QImage::Format_Indexed8;
if (image.size() != QSize(width, height) || image.format() != format) {
image = QImage(width, height, format);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, format, &image))
return false;
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
image.setColorCount((format == QImage::Format_Mono) ? 2 : num_palette);
int i = 0;
@ -387,11 +369,8 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
}
if (!(color_type & PNG_COLOR_MASK_COLOR))
png_set_gray_to_rgb(png_ptr);
if (image.size() != QSize(width, height) || image.format() != format) {
image = QImage(width, height, format);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(size, format, &image))
return false;
png_read_update_info(png_ptr, info_ptr);
if (QSysInfo::ByteOrder == QSysInfo::LittleEndian)
png_set_swap(png_ptr);
@ -422,11 +401,8 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
if (doScaledRead)
*doScaledRead = true;
}
if (image.size() != outSize || image.format() != format) {
image = QImage(outSize, format);
if (image.isNull())
return;
}
if (!QImageIOHandler::allocateImage(outSize, format, &image))
return false;
if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
png_set_swap_alpha(png_ptr);
@ -438,6 +414,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
png_read_update_info(png_ptr, info_ptr);
}
return true;
}
static void read_image_scaled(QImage *outImage, png_structp png_ptr, png_infop info_ptr,
@ -689,9 +666,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage)
}
bool doScaledRead = false;
setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead);
if (outImage->isNull()) {
if (!setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead)) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
png_ptr = nullptr;
amp.deallocate();

View File

@ -160,11 +160,8 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q
}
raw = type >= '4';
if (outImage->size() != QSize(w, h) || outImage->format() != format) {
*outImage = QImage(w, h, format);
if (outImage->isNull())
if (!QImageIOHandler::allocateImage(QSize(w, h), format, outImage))
return false;
}
pbm_bpl = (qsizetype(w) * nbits + 7) / 8; // bytes per scanline in PBM

View File

@ -147,11 +147,8 @@ static bool read_xbm_body(QIODevice *device, int w, int h, QImage *outImage)
p = strstr(buf, "0x");
} while (!p);
if (outImage->size() != QSize(w, h) || outImage->format() != QImage::Format_MonoLSB) {
*outImage = QImage(w, h, QImage::Format_MonoLSB);
if (outImage->isNull())
if (!QImageIOHandler::allocateImage(QSize(w, h), QImage::Format_MonoLSB, outImage))
return false;
}
outImage->fill(Qt::color0); // in case the image data does not cover the full image

View File

@ -881,11 +881,8 @@ static bool read_xpm_body(
// create it in correct format (Format_RGB32 vs Format_ARGB32,
// depending on absence or presence of "c none", respectively)
if (ncols <= 256) {
if (image.size() != QSize(w, h) || image.format() != QImage::Format_Indexed8) {
image = QImage(w, h, QImage::Format_Indexed8);
if (image.isNull())
if (!QImageIOHandler::allocateImage(QSize(w, h), QImage::Format_Indexed8, &image))
return false;
}
image.setColorCount(ncols);
}
@ -954,12 +951,9 @@ static bool read_xpm_body(
// Now we can create 32-bit image of appropriate format
QImage::Format format = hasTransparency ?
QImage::Format_ARGB32 : QImage::Format_RGB32;
if (image.size() != QSize(w, h) || image.format() != format) {
image = QImage(w, h, format);
if (image.isNull())
if (!QImageIOHandler::allocateImage(QSize(w, h), format, &image))
return false;
}
}
// Read pixels
for(int y=0; y<h; y++) {

View File

@ -358,7 +358,10 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
state = Error;
return -1;
}
(*image) = QImage(swidth, sheight, format);
if (!QImageIOHandler::allocateImage(QSize(swidth, sheight), format, image)) {
state = Error;
return -1;
}
bpl = image->bytesPerLine();
bits = image->bits();
if (bits)
@ -425,10 +428,9 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
return -1;
}
// We just use the backing store as a byte array
backingstore = QImage(qMax(backingstore.width(), w),
qMax(backingstore.height(), h),
QImage::Format_RGB32);
if (backingstore.isNull()) {
QSize bsSize(qMax(backingstore.width(), w), qMax(backingstore.height(), h));
if (!QImageIOHandler::allocateImage(bsSize, QImage::Format_RGB32,
&backingstore)) {
state = Error;
return -1;
}

View File

@ -521,8 +521,9 @@ QImage ICOReader::iconAt(int index)
else if (icoAttrib.ncolors > 0)
format = QImage::Format_Indexed8;
QImage image(icoAttrib.w, icoAttrib.h, format);
if (!image.isNull()) {
QImage image;
const QSize size(icoAttrib.w, icoAttrib.h);
if (QImageIOHandler::allocateImage(size, format, &image)) {
findColorInfo(image);
if (!image.isNull()) {
readBMP(image);

View File

@ -240,10 +240,7 @@ static bool ensureValidImage(QImage *dest, struct jpeg_decompress_struct *info,
return false; // unsupported format
}
if (dest->size() != size || dest->format() != format)
*dest = QImage(size, format);
return !dest->isNull();
return QImageIOHandler::allocateImage(size, format, dest);
}
static bool read_jpeg_image(QImage *outImage,