diff options
Diffstat (limited to 'src/gui/image/qppmhandler.cpp')
-rw-r--r-- | src/gui/image/qppmhandler.cpp | 157 |
1 files changed, 62 insertions, 95 deletions
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 13ee2eadd2..3a4af46195 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -1,54 +1,23 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "private/qppmhandler_p.h" #ifndef QT_NO_IMAGEFORMAT_PPM +#include <qdebug.h> #include <qimage.h> -#include <qvariant.h> -#include <qvector.h> -#include <ctype.h> +#include <qlist.h> +#include <qloggingcategory.h> #include <qrgba64.h> +#include <qvariant.h> +#include <private/qlocale_p.h> +#include <private/qtools_p.h> QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcImageIo) + /***************************************************************************** PBM/PGM/PPM (ASCII and RAW) image read/write functions *****************************************************************************/ @@ -63,7 +32,7 @@ static void discard_pbm_line(QIODevice *d) } while (res > 0 && buf[res-1] != '\n'); } -static int read_pbm_int(QIODevice *d) +static int read_pbm_int(QIODevice *d, bool *ok, int maxDigits = -1) { char c; int val = -1; @@ -72,7 +41,7 @@ static int read_pbm_int(QIODevice *d) for (;;) { if (!d->getChar(&c)) // end of file break; - digit = isdigit((uchar) c); + digit = QtMiscUtils::isAsciiDigit(c); if (val != -1) { if (digit) { const int cValue = c - '0'; @@ -81,6 +50,8 @@ static int read_pbm_int(QIODevice *d) } else { hasOverflow = true; } + if (maxDigits > 0 && --maxDigits == 0) + break; continue; } else { if (c == '#') // comment @@ -90,13 +61,17 @@ static int read_pbm_int(QIODevice *d) } if (digit) // first digit val = c - '0'; - else if (isspace((uchar) c)) + else if (ascii_isspace(c)) continue; else if (c == '#') discard_pbm_line(d); else break; + if (maxDigits > 0 && --maxDigits == 0) + break; } + if (val < 0) + *ok = false; return hasOverflow ? -1 : val; } @@ -106,23 +81,24 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int& if (device->read(buf, 3) != 3) // read P[1-6]<white-space> return false; - if (!(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2]))) + if (!(buf[0] == 'P' && QtMiscUtils::isAsciiDigit(buf[1]) && ascii_isspace(buf[2]))) return false; type = buf[1]; if (type < '1' || type > '6') return false; - w = read_pbm_int(device); // get image width - h = read_pbm_int(device); // get image height + bool ok = true; + w = read_pbm_int(device, &ok); // get image width + h = read_pbm_int(device, &ok); // get image height if (type == '1' || type == '4') mcc = 1; // ignore max color component else - mcc = read_pbm_int(device); // get max color component + mcc = read_pbm_int(device, &ok); // get max color component - if (w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff) - return false; // weird P.M image + if (!ok || w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 || mcc > 0xffff) + return false; // weird P.M image return true; } @@ -135,7 +111,7 @@ static inline QRgb scale_pbm_color(quint16 mx, quint16 rv, quint16 gv, quint16 b static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, QImage *outImage) { int nbits, y; - int pbm_bpl; + qsizetype pbm_bpl; bool raw; QImage::Format format; @@ -160,13 +136,10 @@ 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()) - return false; - } + if (!QImageIOHandler::allocateImage(QSize(w, h), format, outImage)) + return false; - pbm_bpl = (nbits*w+7)/8; // bytes per scanline in PBM + pbm_bpl = (qsizetype(w) * nbits + 7) / 8; // bytes per scanline in PBM if (raw) { // read raw data if (nbits == 32) { // type 6 @@ -225,26 +198,26 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q if (device->read((char *)p, pbm_bpl) != pbm_bpl) return false; if (nbits == 8 && mcc < 255) { - for (int i = 0; i < pbm_bpl; i++) + for (qsizetype i = 0; i < pbm_bpl; i++) p[i] = (p[i] * 255) / mcc; } } } } else { // read ascii data uchar *p; - int n; - char buf; - for (y = 0; (y < h) && (device->peek(&buf, 1) == 1); y++) { + qsizetype n; + bool ok = true; + for (y = 0; y < h && ok; y++) { p = outImage->scanLine(y); n = pbm_bpl; if (nbits == 1) { int b; int bitsLeft = w; - while (n--) { + while (n-- && ok) { b = 0; for (int i=0; i<8; i++) { if (i < bitsLeft) - b = (b << 1) | (read_pbm_int(device) & 1); + b = (b << 1) | (read_pbm_int(device, &ok, 1) & 1); else b = (b << 1) | (0 & 1); // pad it our self if we need to } @@ -253,36 +226,38 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q } } else if (nbits == 8) { if (mcc == 255) { - while (n--) { - *p++ = read_pbm_int(device); + while (n-- && ok) { + *p++ = read_pbm_int(device, &ok); } } else { - while (n--) { - *p++ = (read_pbm_int(device) & 0xffff) * 255 / mcc; + while (n-- && ok) { + *p++ = (read_pbm_int(device, &ok) & 0xffff) * 255 / mcc; } } } else { // 32 bits n /= 4; int r, g, b; if (mcc == 255) { - while (n--) { - r = read_pbm_int(device); - g = read_pbm_int(device); - b = read_pbm_int(device); + while (n-- && ok) { + r = read_pbm_int(device, &ok); + g = read_pbm_int(device, &ok); + b = read_pbm_int(device, &ok); *((QRgb*)p) = qRgb(r, g, b); p += 4; } } else { - while (n--) { - r = read_pbm_int(device); - g = read_pbm_int(device); - b = read_pbm_int(device); + while (n-- && ok) { + r = read_pbm_int(device, &ok); + g = read_pbm_int(device, &ok); + b = read_pbm_int(device, &ok); *((QRgb*)p) = scale_pbm_color(mcc, r, g, b); p += 4; } } } } + if (!ok) + return false; } if (format == QImage::Format_Mono) { @@ -294,13 +269,12 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q return true; } -static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QByteArray &sourceFormat) +static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, QByteArrayView sourceFormat) { QByteArray str; QImage image = sourceImage; - QByteArray format = sourceFormat; + const QByteArrayView format = sourceFormat.left(3); // ignore RAW part - format = format.left(3); // ignore RAW part bool gray = format == "pgm"; if (format == "pbm") { @@ -351,7 +325,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy switch (image.depth()) { case 1: { str.insert(1, '4'); - if (out->write(str, str.length()) != str.length()) + if (out->write(str, str.size()) != str.size()) return false; w = (w+7)/8; for (uint y=0; y<h; y++) { @@ -365,12 +339,12 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case 8: { str.insert(1, gray ? '5' : '6'); str.append("255\n"); - if (out->write(str, str.length()) != str.length()) + if (out->write(str, str.size()) != str.size()) return false; - uint bpl = w * (gray ? 1 : 3); + qsizetype bpl = qsizetype(w) * (gray ? 1 : 3); uchar *buf = new uchar[bpl]; if (image.format() == QImage::Format_Indexed8) { - QVector<QRgb> color = image.colorTable(); + const QList<QRgb> color = image.colorTable(); for (uint y=0; y<h; y++) { const uchar *b = image.constScanLine(y); uchar *p = buf; @@ -388,7 +362,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy *p++ = qBlue(rgb); } } - if (bpl != (uint)out->write((char*)buf, bpl)) + if (bpl != (qsizetype)out->write((char*)buf, bpl)) return false; } } else { @@ -407,7 +381,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy *p++ = color; } } - if (bpl != (uint)out->write((char*)buf, bpl)) + if (bpl != (qsizetype)out->write((char*)buf, bpl)) return false; } } @@ -418,9 +392,9 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case 32: { str.insert(1, '6'); str.append("255\n"); - if (out->write(str, str.length()) != str.length()) + if (out->write(str, str.size()) != str.size()) return false; - uint bpl = w * 3; + qsizetype bpl = qsizetype(w) * 3; uchar *buf = new uchar[bpl]; for (uint y=0; y<h; y++) { const QRgb *b = reinterpret_cast<const QRgb *>(image.constScanLine(y)); @@ -432,7 +406,7 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy *p++ = qGreen(rgb); *p++ = qBlue(rgb); } - if (bpl != (uint)out->write((char*)buf, bpl)) + if (bpl != (qsizetype)out->write((char*)buf, bpl)) return false; } delete [] buf; @@ -476,7 +450,7 @@ bool QPpmHandler::canRead() const bool QPpmHandler::canRead(QIODevice *device, QByteArray *subType) { if (!device) { - qWarning("QPpmHandler::canRead() called with no device"); + qCWarning(lcImageIo, "QPpmHandler::canRead() called with no device"); return false; } @@ -576,13 +550,6 @@ void QPpmHandler::setOption(ImageOption option, const QVariant &value) subType = value.toByteArray().toLower(); } -#if QT_DEPRECATED_SINCE(5, 13) -QByteArray QPpmHandler::name() const -{ - return subType.isEmpty() ? QByteArray("ppm") : subType; -} -#endif - QT_END_NAMESPACE #endif // QT_NO_IMAGEFORMAT_PPM |