summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qimage.cpp')
-rw-r--r--src/gui/image/qimage.cpp113
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()
*/
/*!