diff options
Diffstat (limited to 'src/gui/image/qimage.cpp')
-rw-r--r-- | src/gui/image/qimage.cpp | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index bd10012bf6..7fcae12cbd 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -127,11 +127,11 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format) const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) // sanity check for potential overflows - if (INT_MAX/depth < width + if (std::numeric_limits<int>::max()/depth < width || bytes_per_line <= 0 || height <= 0 - || INT_MAX/uint(bytes_per_line) < height - || INT_MAX/sizeof(uchar *) < uint(height)) + || std::numeric_limits<qsizetype>::max()/uint(bytes_per_line) < height + || std::numeric_limits<int>::max()/sizeof(uchar *) < uint(height)) return 0; QScopedPointer<QImageData> d(new QImageData); @@ -452,7 +452,7 @@ bool QImageData::checkForAlphaPixels() const used. For more information see the \l {QImage#Image Formats}{Image Formats} section. - The format(), bytesPerLine(), and byteCount() functions provide + The format(), bytesPerLine(), and sizeInBytes() functions provide low-level information about the data stored in the image. The cacheKey() function returns a number that uniquely @@ -1449,26 +1449,43 @@ void QImage::setDevicePixelRatio(qreal scaleFactor) /*! \since 4.6 + \obsolete Returns the number of bytes occupied by the image data. - \sa bytesPerLine(), bits(), {QImage#Image Information}{Image + Note this method should never be called on an image larger than 2 gigabytes. + Instead use sizeInBytes(). + + \sa sizeInBytes(), bytesPerLine(), bits(), {QImage#Image Information}{Image Information} */ int QImage::byteCount() const { + Q_ASSERT(!d || d->nbytes < std::numeric_limits<int>::max()); + return d ? int(d->nbytes) : 0; +} + +/*! + \since 5.10 + Returns the image data size in bytes. + + \sa byteCount(), bytesPerLine(), bits(), {QImage#Image Information}{Image + Information} +*/ +qsizetype QImage::sizeInBytes() const +{ return d ? d->nbytes : 0; } /*! Returns the number of bytes per image scanline. - This is equivalent to byteCount() / height(). + This is equivalent to sizeInBytes() / height() if height() is non-zero. \sa scanLine() */ int QImage::bytesPerLine() const { - return (d && d->height) ? d->nbytes / d->height : 0; + return d ? d->bytes_per_line : 0; } @@ -1595,7 +1612,7 @@ const uchar *QImage::constScanLine(int i) const data, thus ensuring that this QImage is the only one using the current return value. - \sa scanLine(), byteCount(), constBits() + \sa scanLine(), sizeInBytes(), constBits() */ uchar *QImage::bits() { @@ -1959,7 +1976,8 @@ QImage::Format QImage::format() const } /*! - \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const + \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) const & + \fn QImage QImage::convertToFormat(Format format, Qt::ImageConversionFlags flags) && Returns a copy of the image in the given \a format. @@ -2117,8 +2135,8 @@ QImage QImage::convertToFormat(Format format, const QVector<QRgb> &colorTable, Q /*! \since 5.9 - Changes the \a format of the image without changing the data. Only - works between formats of the same depth. + Changes the format of the image to \a format without changing the + data. Only works between formats of the same depth. Returns \c true if successful. @@ -2971,7 +2989,9 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const } /*! - \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const + \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const & + \fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) && + Returns a mirror of the image, mirrored in the horizontal and/or the vertical direction depending on whether \a horizontal and \a vertical are set to true or false. @@ -3176,7 +3196,9 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical) } /*! - \fn QImage QImage::rgbSwapped() const + \fn QImage QImage::rgbSwapped() const & + \fn QImage QImage::rgbSwapped() && + Returns a QImage in which the values of the red and blue components of all pixels have been swapped, effectively converting an RGB image to an BGR image. @@ -3245,14 +3267,31 @@ QImage QImage::rgbSwapped_helper() const res.d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00)); } break; - case Format_RGB32: - case Format_ARGB32: - case Format_ARGB32_Premultiplied: -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN case Format_RGBX8888: case Format_RGBA8888: case Format_RGBA8888_Premultiplied: +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); + for (int i = 0; i < d->height; i++) { + uint *q = (uint*)res.scanLine(i); + const uint *p = (const uint*)constScanLine(i); + const uint *end = p + d->width; + while (p < end) { + uint c = *p; + *q = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff); + p++; + q++; + } + } + break; +#else + // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32 + Q_FALLTHROUGH(); #endif + case Format_RGB32: + case Format_ARGB32: + case Format_ARGB32_Premultiplied: res = QImage(d->width, d->height, d->format); QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { @@ -3336,14 +3375,27 @@ void QImage::rgbSwapped_inplace() d->colortable[i] = QRgb(((c << 16) & 0xff0000) | ((c >> 16) & 0xff) | (c & 0xff00ff00)); } break; - case Format_RGB32: - case Format_ARGB32: - case Format_ARGB32_Premultiplied: -#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN case Format_RGBX8888: case Format_RGBA8888: case Format_RGBA8888_Premultiplied: +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < d->height; i++) { + uint *p = (uint*)scanLine(i); + uint *end = p + d->width; + while (p < end) { + uint c = *p; + *p = ((c << 16) & 0xff000000) | ((c >> 16) & 0xff00) | (c & 0x00ff00ff); + p++; + } + } + break; +#else + // On little-endian rgba8888 is abgr32 and can use same rgb-swap as argb32 + Q_FALLTHROUGH(); #endif + case Format_RGB32: + case Format_ARGB32: + case Format_ARGB32_Premultiplied: for (int i = 0; i < d->height; i++) { uint *p = (uint*)scanLine(i); uint *end = p + d->width; @@ -4662,12 +4714,12 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode if (dImage.d->colortable.size() < 256) { // colors are left in the color table, so pick that one as transparent dImage.d->colortable.append(0x0); - memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.byteCount()); + memset(dImage.bits(), dImage.d->colortable.size() - 1, dImage.d->nbytes); } else { - memset(dImage.bits(), 0, dImage.byteCount()); + memset(dImage.bits(), 0, dImage.d->nbytes); } } else - memset(dImage.bits(), 0x00, dImage.byteCount()); + memset(dImage.bits(), 0x00, dImage.d->nbytes); if (target_format >= QImage::Format_RGB32) { // Prevent QPainter from applying devicePixelRatio corrections @@ -4762,8 +4814,8 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla QDebug operator<<(QDebug dbg, const QImage &i) { QDebugStateSaver saver(dbg); - dbg.resetFormat(); dbg.nospace(); + dbg.noquote(); dbg << "QImage("; if (i.isNull()) { dbg << "null"; @@ -4771,8 +4823,15 @@ QDebug operator<<(QDebug dbg, const QImage &i) dbg << i.size() << ",format=" << i.format() << ",depth=" << i.depth(); if (i.colorCount()) dbg << ",colorCount=" << i.colorCount(); + const int bytesPerLine = i.bytesPerLine(); dbg << ",devicePixelRatio=" << i.devicePixelRatio() - << ",bytesPerLine=" << i.bytesPerLine() << ",byteCount=" << i.byteCount(); + << ",bytesPerLine=" << bytesPerLine << ",sizeInBytes=" << i.sizeInBytes(); + if (dbg.verbosity() > 2 && i.height() > 0) { + const int outputLength = qMin(bytesPerLine, 24); + dbg << ",line0=" + << QByteArray(reinterpret_cast<const char *>(i.scanLine(0)), outputLength).toHex() + << "..."; + } } dbg << ')'; return dbg; @@ -4794,7 +4853,7 @@ QDebug operator<<(QDebug dbg, const QImage &i) Returns the number of bytes occupied by the image data. - \sa byteCount() + \sa sizeInBytes() */ /*! |