diff options
Diffstat (limited to 'src/gui/image/qppmhandler.cpp')
-rw-r--r-- | src/gui/image/qppmhandler.cpp | 116 |
1 files changed, 44 insertions, 72 deletions
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 71dbefe354..3a4af46195 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** 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" @@ -47,8 +11,8 @@ #include <qloggingcategory.h> #include <qrgba64.h> #include <qvariant.h> - -#include <ctype.h> +#include <private/qlocale_p.h> +#include <private/qtools_p.h> QT_BEGIN_NAMESPACE @@ -68,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; @@ -77,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'; @@ -86,6 +50,8 @@ static int read_pbm_int(QIODevice *d) } else { hasOverflow = true; } + if (maxDigits > 0 && --maxDigits == 0) + break; continue; } else { if (c == '#') // comment @@ -95,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; } @@ -111,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; } @@ -235,18 +206,18 @@ static bool read_pbm_body(QIODevice *device, char type, int w, int h, int mcc, Q } else { // read ascii data uchar *p; qsizetype n; - char buf; - for (y = 0; (y < h) && (device->peek(&buf, 1) == 1); y++) { + 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 } @@ -255,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) { @@ -296,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") { @@ -353,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++) { @@ -367,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; qsizetype bpl = qsizetype(w) * (gray ? 1 : 3); uchar *buf = new uchar[bpl]; if (image.format() == QImage::Format_Indexed8) { - QList<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; @@ -420,7 +392,7 @@ 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; qsizetype bpl = qsizetype(w) * 3; uchar *buf = new uchar[bpl]; |