summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-01-10 13:31:32 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-18 18:31:01 +0100
commitb157a5795381aea259969b4550e055d52df47bd3 (patch)
treec880b581e43b83e0679c0f2a1c20d28cc51a8540 /src
parent0e65cec6b4f5ca21f3964a18b4a3f35a32a6762f (diff)
Add generic inplace converter
The generic converter can easily be modified to work inplace. Such an inplace converter can ensure we can do direct conversion between formats of similar pixel depth. Inplace conversion is currently only used by QPixmaps, but will be used by ref qualified versions of QImage::convertToFormat in a future patch. Change-Id: Idbdaf087b53deecdee8258ba0b5d80edd37cfe79 Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
Diffstat (limited to 'src')
-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);