From 64d51ed610c7123b5b74f0f5e975b03277be43e5 Mon Sep 17 00:00:00 2001 From: Mirco Miranda Date: Fri, 12 May 2023 08:53:50 +0000 Subject: [PATCH] pcx: multiple fixes (2) - 1-bit writer: checks where is black and use NOT operator only if needed - Fix images with witdh == 65536(*) - Checks result of disk writes and reads on all formats (*) PCX formats support images with with of 65536 but only if the header field bytesPerLine is valid (no overflow). This means that the width 65536 is supported on 1bpp images only. The previous version of the plugins wrote an image with width of 65536px in the wrong way and it was unable to read it (wrong image returned). I verified that Photoshop and Gimp weren't able to read the image either. (cherry picked from commit d57ff91f8b8876472e1e588afbceb19e34d99172) --- autotests/read/pcx/mono.pcx | Bin 0 -> 32330 bytes autotests/read/pcx/mono.png | Bin 0 -> 25134 bytes src/imageformats/pcx.cpp | 197 ++++++++++++++++++++++-------------- 3 files changed, 119 insertions(+), 78 deletions(-) create mode 100644 autotests/read/pcx/mono.pcx create mode 100644 autotests/read/pcx/mono.png diff --git a/autotests/read/pcx/mono.pcx b/autotests/read/pcx/mono.pcx new file mode 100644 index 0000000000000000000000000000000000000000..3040f34c1e544ecbf412889b1fd645dfe4f5a053 GIT binary patch literal 32330 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

!-S^QFxafjk{Gxlox5ddJb5oiyoT-v! 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 AVE_OC literal 0 HcmV?d00001 diff --git a/autotests/read/pcx/mono.png b/autotests/read/pcx/mono.png new file mode 100644 index 0000000000000000000000000000000000000000..b869d2ecdfa6b7ba2ae0c103ff8bafa13a45ad73 GIT binary patch literal 25134 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 literal 0 HcmV?d00001 diff --git a/src/imageformats/pcx.cpp b/src/imageformats/pcx.cpp index 68599e4..fa18805 100644 --- a/src/imageformats/pcx.cpp +++ b/src/imageformats/pcx.cpp @@ -230,7 +230,7 @@ PCXHEADER::PCXHEADER() s >> *this; } -static void readLine(QDataStream &s, QByteArray &buf, const PCXHEADER &header) +static bool readLine(QDataStream &s, QByteArray &buf, const PCXHEADER &header) { quint32 i = 0; quint32 size = buf.size(); @@ -257,9 +257,11 @@ static void readLine(QDataStream &s, QByteArray &buf, const PCXHEADER &header) buf[i++] = byte; } } + + return (s.status() == QDataStream::Ok); } -static void readImage1(QImage &img, QDataStream &s, const PCXHEADER &header) +static bool readImage1(QImage &img, QDataStream &s, const PCXHEADER &header) { QByteArray buf(header.BytesPerLine, 0); @@ -268,16 +270,18 @@ static void readImage1(QImage &img, QDataStream &s, const PCXHEADER &header) if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(header.width(), header.height()); - return; + return false; } for (int y = 0; y < header.height(); ++y) { if (s.atEnd()) { - img = QImage(); - return; + return false; + } + + if (!readLine(s, buf, header)) { + return false; } - readLine(s, buf, header); uchar *p = img.scanLine(y); unsigned int bpl = qMin((quint16)((header.width() + 7) / 8), header.BytesPerLine); for (unsigned int x = 0; x < bpl; ++x) { @@ -288,9 +292,11 @@ static void readImage1(QImage &img, QDataStream &s, const PCXHEADER &header) // Set the color palette img.setColor(0, qRgb(0, 0, 0)); img.setColor(1, qRgb(255, 255, 255)); + + return true; } -static void readImage4(QImage &img, QDataStream &s, const PCXHEADER &header) +static bool readImage4(QImage &img, QDataStream &s, const PCXHEADER &header) { QByteArray buf(header.BytesPerLine * 4, 0); QByteArray pixbuf(header.width(), 0); @@ -299,17 +305,18 @@ static void readImage4(QImage &img, QDataStream &s, const PCXHEADER &header) img.setColorCount(16); if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(header.width(), header.height()); - return; + return false; } for (int y = 0; y < header.height(); ++y) { if (s.atEnd()) { - img = QImage(); - return; + return false; } pixbuf.fill(0); - readLine(s, buf, header); + if (!readLine(s, buf, header)) { + return false; + } for (int i = 0; i < 4; i++) { quint32 offset = i * header.BytesPerLine; @@ -333,9 +340,11 @@ static void readImage4(QImage &img, QDataStream &s, const PCXHEADER &header) for (int i = 0; i < 16; ++i) { img.setColor(i, header.ColorMap.color(i)); } + + return true; } -static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header) +static bool readImage8(QImage &img, QDataStream &s, const PCXHEADER &header) { QByteArray buf(header.BytesPerLine, 0); @@ -344,21 +353,21 @@ static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header) if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(header.width(), header.height()); - return; + return false; } for (int y = 0; y < header.height(); ++y) { if (s.atEnd()) { - img = QImage(); - return; + return false; } - readLine(s, buf, header); + if (!readLine(s, buf, header)) { + return false; + } uchar *p = img.scanLine(y); - if (!p) { - return; + return false; } unsigned int bpl = qMin(header.BytesPerLine, (quint16)header.width()); @@ -392,9 +401,11 @@ static void readImage8(QImage &img, QDataStream &s, const PCXHEADER &header) img.setColor(i, qRgb(r, g, b)); } } + + return (s.status() == QDataStream::Ok); } -static void readImage24(QImage &img, QDataStream &s, const PCXHEADER &header) +static bool readImage24(QImage &img, QDataStream &s, const PCXHEADER &header) { QByteArray r_buf(header.BytesPerLine, 0); QByteArray g_buf(header.BytesPerLine, 0); @@ -404,27 +415,34 @@ static void readImage24(QImage &img, QDataStream &s, const PCXHEADER &header) if (img.isNull()) { qWarning() << "Failed to allocate image, invalid dimensions?" << QSize(header.width(), header.height()); - return; + return false; } for (int y = 0; y < header.height(); ++y) { if (s.atEnd()) { - img = QImage(); - return; + return false; } - readLine(s, r_buf, header); - readLine(s, g_buf, header); - readLine(s, b_buf, header); + if (!readLine(s, r_buf, header)) { + return false; + } + if (!readLine(s, g_buf, header)) { + return false; + } + if (!readLine(s, b_buf, header)) { + return false; + } uint *p = (uint *)img.scanLine(y); for (int x = 0; x < header.width(); ++x) { p[x] = qRgb(r_buf[x], g_buf[x], b_buf[x]); } } + + return true; } -static void writeLine(QDataStream &s, QByteArray &buf) +static bool writeLine(QDataStream &s, QByteArray &buf) { quint32 i = 0; quint32 size = buf.size(); @@ -450,15 +468,26 @@ static void writeLine(QDataStream &s, QByteArray &buf) s << data; } + return (s.status() == QDataStream::Ok); } -static void writeImage1(QImage &img, QDataStream &s, PCXHEADER &header) +static bool writeImage1(QImage &img, QDataStream &s, PCXHEADER &header) { - img = img.convertToFormat(QImage::Format_Mono); + if (img.format() != QImage::Format_Mono) { + img = img.convertToFormat(QImage::Format_Mono); + } + if (img.isNull() || img.colorCount() < 1) { + return false; + } + auto rgb = img.color(0); + auto minIsBlack = (qRed(rgb) + qGreen(rgb) + qBlue(rgb)) / 3 < 127; header.Bpp = 1; header.NPlanes = 1; header.BytesPerLine = img.bytesPerLine(); + if (header.BytesPerLine == 0) { + return false; + } s << header; @@ -469,18 +498,24 @@ static void writeImage1(QImage &img, QDataStream &s, PCXHEADER &header) // Invert as QImage uses reverse palette for monochrome images? for (int i = 0; i < header.BytesPerLine; ++i) { - buf[i] = ~p[i]; + buf[i] = minIsBlack ? p[i] : ~p[i]; } - writeLine(s, buf); + if (!writeLine(s, buf)) { + return false; + } } + return true; } -static void writeImage4(QImage &img, QDataStream &s, PCXHEADER &header) +static bool writeImage4(QImage &img, QDataStream &s, PCXHEADER &header) { header.Bpp = 1; header.NPlanes = 4; header.BytesPerLine = header.width() / 8; + if (header.BytesPerLine == 0) { + return false; + } for (int i = 0; i < 16; ++i) { header.ColorMap.setColor(i, img.color(i)); @@ -510,16 +545,22 @@ static void writeImage4(QImage &img, QDataStream &s, PCXHEADER &header) } for (int i = 0; i < 4; ++i) { - writeLine(s, buf[i]); + if (!writeLine(s, buf[i])) { + return false; + } } } + return true; } -static void writeImage8(QImage &img, QDataStream &s, PCXHEADER &header) +static bool writeImage8(QImage &img, QDataStream &s, PCXHEADER &header) { header.Bpp = 8; header.NPlanes = 1; header.BytesPerLine = img.bytesPerLine(); + if (header.BytesPerLine == 0) { + return false; + } s << header; @@ -532,7 +573,9 @@ static void writeImage8(QImage &img, QDataStream &s, PCXHEADER &header) buf[i] = p[i]; } - writeLine(s, buf); + if (!writeLine(s, buf)) { + return false; + } } // Write palette flag @@ -543,16 +586,25 @@ static void writeImage8(QImage &img, QDataStream &s, PCXHEADER &header) for (int i = 0; i < 256; ++i) { s << RGB::from(img.color(i)); } + + return (s.status() == QDataStream::Ok); } -static void writeImage24(QImage &img, QDataStream &s, PCXHEADER &header) +static bool writeImage24(QImage &img, QDataStream &s, PCXHEADER &header) { - if(img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB32) - img = img.convertToFormat(QImage::Format_RGB32); - header.Bpp = 8; header.NPlanes = 3; header.BytesPerLine = header.width(); + if (header.BytesPerLine == 0) { + return false; + } + + if (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB32) { + img = img.convertToFormat(QImage::Format_RGB32); + } + if (img.isNull()) { + return false; + } s << header; @@ -570,10 +622,18 @@ static void writeImage24(QImage &img, QDataStream &s, PCXHEADER &header) b_buf[x] = qBlue(rgb); } - writeLine(s, r_buf); - writeLine(s, g_buf); - writeLine(s, b_buf); + if (!writeLine(s, r_buf)) { + return false; + } + if (!writeLine(s, g_buf)) { + return false; + } + if (!writeLine(s, b_buf)) { + return false; + } } + + return true; } PCXHandler::PCXHandler() @@ -602,48 +662,30 @@ bool PCXHandler::read(QImage *outImage) s >> header; - if (header.Manufacturer != 10 || s.atEnd()) { + if (header.Manufacturer != 10 || header.BytesPerLine == 0 || s.atEnd()) { return false; } - // int w = header.width(); - // int h = header.height(); - - // qDebug() << "Manufacturer: " << header.Manufacturer; - // qDebug() << "Version: " << header.Version; - // qDebug() << "Encoding: " << header.Encoding; - // qDebug() << "Bpp: " << header.Bpp; - // qDebug() << "Width: " << w; - // qDebug() << "Height: " << h; - // qDebug() << "Window: " << header.XMin << "," << header.XMax << "," - // << header.YMin << "," << header.YMax << endl; - // qDebug() << "BytesPerLine: " << header.BytesPerLine; - // qDebug() << "NPlanes: " << header.NPlanes; - + auto ok = false; QImage img; - if (header.Bpp == 1 && header.NPlanes == 1) { - readImage1(img, s, header); + ok = readImage1(img, s, header); } else if (header.Bpp == 1 && header.NPlanes == 4) { - readImage4(img, s, header); + ok = readImage4(img, s, header); } else if (header.Bpp == 8 && header.NPlanes == 1) { - readImage8(img, s, header); + ok = readImage8(img, s, header); } else if (header.Bpp == 8 && header.NPlanes == 3) { - readImage24(img, s, header); + ok = readImage24(img, s, header); } - // qDebug() << "Image Bytes: " << img.numBytes(); - // qDebug() << "Image Bytes Per Line: " << img.bytesPerLine(); - // qDebug() << "Image Depth: " << img.depth(); - - if (!img.isNull()) { - img.setDotsPerMeterX(qRound(header.HDpi / 25.4 * 1000)); - img.setDotsPerMeterY(qRound(header.YDpi / 25.4 * 1000)); - *outImage = img; - return true; - } else { + if (img.isNull() || !ok) { return false; } + + img.setDotsPerMeterX(qRound(header.HDpi / 25.4 * 1000)); + img.setDotsPerMeterY(qRound(header.YDpi / 25.4 * 1000)); + *outImage = img; + return true; } bool PCXHandler::write(const QImage &image) @@ -674,19 +716,18 @@ bool PCXHandler::write(const QImage &image) header.Reserved = 0; header.PaletteInfo = 1; + auto ok = false; if (img.depth() == 1) { - writeImage1(img, s, header); + ok = writeImage1(img, s, header); } else if (img.depth() == 8 && img.colorCount() <= 16) { - writeImage4(img, s, header); + ok = writeImage4(img, s, header); } else if (img.depth() == 8) { - writeImage8(img, s, header); + ok = writeImage8(img, s, header); } else if (img.depth() >= 24) { - writeImage24(img, s, header); - } else { - return false; + ok = writeImage24(img, s, header); } - return true; + return ok; } bool PCXHandler::canRead(QIODevice *device)