diff options
Diffstat (limited to 'src/gui/image/qimage_conversions.cpp')
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 2c3a20870e..c646ee96b4 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -108,7 +108,7 @@ void qGamma_correct_back_to_linear_cs(QImage *image) // The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion. static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) + const QVector<QRgb> *, QDitherInfo *) { for (int i = 0; i < count; ++i) buffer[i] = 0xff000000 | qUnpremultiply(src[i]); @@ -116,7 +116,7 @@ static const uint *QT_FASTCALL convertRGB32FromARGB32PM(uint *buffer, const uint } static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) + const QVector<QRgb> *, QDitherInfo *) { for (int i = 0; i < count; ++i) buffer[i] = 0xff000000 |src[i]; @@ -124,16 +124,18 @@ static const uint *QT_FASTCALL convertRGB32ToARGB32PM(uint *buffer, const uint * } #ifdef QT_COMPILER_SUPPORTS_SSE4_1 -extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, const QPixelLayout *, const QRgb *); +extern const uint *QT_FASTCALL convertRGB32FromARGB32PM_sse4(uint *buffer, const uint *src, int count, + const QVector<QRgb> *, QDitherInfo *); #endif -void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags) { // Cannot be used with indexed formats. Q_ASSERT(dest->format > QImage::Format_Indexed8); Q_ASSERT(src->format > QImage::Format_Indexed8); const int buffer_size = 2048; - uint buffer[buffer_size]; + uint buf[buffer_size]; + uint *buffer = buf; const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; const uchar *srcData = src->data; @@ -158,15 +160,26 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio convertFromARGB32PM = convertRGB32FromARGB32PM; } } + QDitherInfo dither; + QDitherInfo *ditherPtr = 0; + if ((flags & Qt::PreferDither) && (flags & Qt::Dither_Mask) != Qt::ThresholdDither) + ditherPtr = &dither; for (int y = 0; y < src->height; ++y) { + dither.y = y; int x = 0; while (x < src->width) { - int l = qMin(src->width - x, buffer_size); + dither.x = x; + int l = src->width - x; + if (destLayout->bpp == QPixelLayout::BPP32) + buffer = reinterpret_cast<uint *>(destData) + x; + else + l = qMin(l, buffer_size); const uint *ptr = fetch(buffer, srcData, x, l); - ptr = convertToARGB32PM(buffer, ptr, l, srcLayout, 0); - ptr = convertFromARGB32PM(buffer, ptr, l, destLayout, 0); - store(destData, ptr, x, l); + ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr); + ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr); + if (ptr != reinterpret_cast<uint *>(destData)) + store(destData, ptr, x, l); x += l; } srcData += src->bytes_per_line; @@ -174,7 +187,7 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio } } -bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags) +bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::ImageConversionFlags flags) { // Cannot be used with indexed formats or between formats with different pixel depths. Q_ASSERT(dst_format > QImage::Format_Indexed8); @@ -207,14 +220,20 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im convertFromARGB32PM = convertRGB32FromARGB32PM; } } + QDitherInfo dither; + QDitherInfo *ditherPtr = 0; + if ((flags & Qt::PreferDither) && (flags & Qt::Dither_Mask) != Qt::ThresholdDither) + ditherPtr = &dither; for (int y = 0; y < data->height; ++y) { + dither.y = y; int x = 0; while (x < data->width) { + dither.x = x; int l = qMin(data->width - x, buffer_size); const uint *ptr = fetch(buffer, srcData, x, l); - ptr = convertToARGB32PM(buffer, ptr, l, srcLayout, 0); - ptr = convertFromARGB32PM(buffer, ptr, l, destLayout, 0); + ptr = convertToARGB32PM(buffer, ptr, l, 0, ditherPtr); + ptr = convertFromARGB32PM(buffer, ptr, l, 0, ditherPtr); // The conversions might be passthrough and not use the buffer, in that case we are already done. if (srcData != (const uchar*)ptr) store(srcData, ptr, x, l); |