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.cpp79
1 files changed, 72 insertions, 7 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index f3cc48cf33..9e911bdcea 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -780,9 +780,8 @@ QImage::QImage() Q_DECL_NOEXCEPT
drawing onto it with QPainter.
*/
QImage::QImage(int width, int height, Format format)
- : QPaintDevice()
+ : QImage(QSize(width, height), format)
{
- d = QImageData::create(QSize(width, height), format);
}
/*!
@@ -1889,7 +1888,7 @@ void QImage::invertPixels(InvertMode mode)
case QImage::Format_RGBA8888:
if (mode == InvertRgba)
break;
- // no break
+ Q_FALLTHROUGH();
case QImage::Format_RGBX8888:
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
xorbits = 0xffffff00;
@@ -1901,7 +1900,7 @@ void QImage::invertPixels(InvertMode mode)
case QImage::Format_ARGB32:
if (mode == InvertRgba)
break;
- // no break
+ Q_FALLTHROUGH();
case QImage::Format_RGB32:
xorbits = 0x00ffffff;
break;
@@ -2286,7 +2285,7 @@ QRgb QImage::pixel(int x, int y) const
const QPixelLayout *layout = &qPixelLayouts[d->format];
uint result;
const uint *ptr = qFetchPixels[layout->bpp](&result, s, x, 1);
- return *layout->convertToARGB32PM(&result, ptr, 1, layout, 0);
+ return *layout->convertToARGB32PM(&result, ptr, 1, 0, 0);
}
/*!
@@ -2388,7 +2387,7 @@ void QImage::setPixel(int x, int y, uint index_or_rgb)
const QPixelLayout *layout = &qPixelLayouts[d->format];
uint result;
- const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, layout, 0);
+ const uint *ptr = layout->convertFromARGB32PM(&result, &index_or_rgb, 1, 0, 0);
qStorePixels[layout->bpp](s, ptr, x, 1);
}
@@ -2574,7 +2573,7 @@ bool QImage::allGray() const
while (x < d->width) {
int l = qMin(d->width - x, buffer_size);
const uint *ptr = fetch(buffer, b, x, l);
- ptr = layout->convertToARGB32PM(buffer, ptr, l, layout, 0);
+ ptr = layout->convertToARGB32PM(buffer, ptr, l, 0, 0);
for (int i = 0; i < l; ++i) {
if (!qIsGray(ptr[i]))
return false;
@@ -3015,6 +3014,37 @@ template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
}
}
+inline void do_flip(QImageData *dst, QImageData *src, int w, int h, int depth)
+{
+ const int data_bytes_per_line = w * (depth / 8);
+ if (dst == src) {
+ uint *srcPtr = reinterpret_cast<uint *>(src->data);
+ uint *dstPtr = reinterpret_cast<uint *>(dst->data + (h - 1) * dst->bytes_per_line);
+ h = h / 2;
+ const int uint_per_line = (data_bytes_per_line + 3) >> 2; // bytes per line must be a multiple of 4
+ for (int y = 0; y < h; ++y) {
+ // This is auto-vectorized, no need for SSE2 or NEON versions:
+ for (int x = 0; x < uint_per_line; x++) {
+ const uint d = dstPtr[x];
+ const uint s = srcPtr[x];
+ dstPtr[x] = s;
+ srcPtr[x] = d;
+ }
+ srcPtr += src->bytes_per_line >> 2;
+ dstPtr -= dst->bytes_per_line >> 2;
+ }
+
+ } else {
+ const uchar *srcPtr = src->data;
+ uchar *dstPtr = dst->data + (h - 1) * dst->bytes_per_line;
+ for (int y = 0; y < h; ++y) {
+ memcpy(dstPtr, srcPtr, data_bytes_per_line);
+ srcPtr += src->bytes_per_line;
+ dstPtr -= dst->bytes_per_line;
+ }
+ }
+}
+
inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
{
Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
@@ -3027,6 +3057,12 @@ inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool ve
depth = 8;
}
+ if (vertical && !horizontal) {
+ // This one is simple and common, so do it a little more optimized
+ do_flip(dst, src, w, h, depth);
+ return;
+ }
+
int dstX0 = 0, dstXIncr = 1;
int dstY0 = 0, dstYIncr = 1;
if (horizontal) {
@@ -5217,4 +5253,33 @@ Q_GUI_EXPORT void qt_imageTransform(QImage &src, QImageIOHandler::Transformation
}
}
+QMap<QString, QString> qt_getImageText(const QImage &image, const QString &description)
+{
+ QMap<QString, QString> text = qt_getImageTextFromDescription(description);
+ const auto textKeys = image.textKeys();
+ for (const QString &key : textKeys) {
+ if (!key.isEmpty() && !text.contains(key))
+ text.insert(key, image.text(key));
+ }
+ return text;
+}
+
+QMap<QString, QString> qt_getImageTextFromDescription(const QString &description)
+{
+ QMap<QString, QString> text;
+ const auto pairs = description.splitRef(QLatin1String("\n\n"));
+ for (const QStringRef &pair : pairs) {
+ int index = pair.indexOf(QLatin1Char(':'));
+ if (index >= 0 && pair.indexOf(QLatin1Char(' ')) < index) {
+ if (!pair.trimmed().isEmpty())
+ text.insert(QLatin1String("Description"), pair.toString().simplified());
+ } else {
+ const QStringRef key = pair.left(index);
+ if (!key.trimmed().isEmpty())
+ text.insert(key.toString(), pair.mid(index + 2).toString().simplified());
+ }
+ }
+ return text;
+}
+
QT_END_NAMESPACE