summaryrefslogtreecommitdiffstats
path: root/src/gui/image
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image')
-rw-r--r--src/gui/image/qimage.cpp2
-rw-r--r--src/gui/image/qimage_conversions.cpp34
-rw-r--r--src/gui/image/qimage_p.h1
3 files changed, 37 insertions, 0 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 944dd04b8c..d6037fb2d6 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -4424,6 +4424,8 @@ bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFla
InPlace_Image_Converter converter = *converterPtr;
if (converter)
return converter(this, flags);
+ else if (format > QImage::Format_Indexed8 && newFormat > QImage::Format_Indexed8)
+ return convert_generic_inplace(this, newFormat, flags);
else
return false;
}
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 193ef59fcd..f53eed1c43 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -138,6 +138,40 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
}
}
+// Cannot be used with indexed formats or between formats with different pixel depths.
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(dst_format > QImage::Format_Indexed8);
+ Q_ASSERT(data->format > QImage::Format_Indexed8);
+ if (data->depth != qt_depthForFormat(dst_format))
+ return false;
+
+ const int buffer_size = 2048;
+ uint buffer[buffer_size];
+ const QPixelLayout *srcLayout = &qPixelLayouts[data->format];
+ const QPixelLayout *destLayout = &qPixelLayouts[dst_format];
+
+ uchar *srcData = data->data;
+
+ FetchPixelsFunc fetch = qFetchPixels[srcLayout->bpp];
+ StorePixelsFunc store = qStorePixels[destLayout->bpp];
+
+ for (int y = 0; y < data->height; ++y) {
+ int x = 0;
+ while (x < data->width) {
+ int l = qMin(data->width - x, buffer_size);
+ const uint *ptr = fetch(buffer, srcData, x, l);
+ ptr = srcLayout->convertToARGB32PM(buffer, ptr, l, srcLayout, 0);
+ ptr = destLayout->convertFromARGB32PM(buffer, ptr, l, destLayout, 0);
+ store(srcData, ptr, x, l);
+ x += l;
+ }
+ srcData += data->bytes_per_line;
+ }
+ data->format = dst_format;
+ return true;
+}
+
static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32 || src->format == QImage::Format_RGBA8888);
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 2a280a2b18..81730b92f2 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -115,6 +115,7 @@ extern Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImag
extern InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats];
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags);
void dither_to_Mono(QImageData *dst, const QImageData *src, Qt::ImageConversionFlags flags, bool fromalpha);