From c961d1a6d29af8ea385c042ec0d2d419e3bbfa84 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Fri, 12 Oct 2018 11:10:07 +0200 Subject: Make convert_generic_to_rgb64 more generic This makes it possible to get rid of specialized functions for converting to RGBA64PM, while at the same time making the conversion faster as the painter routines are better optimized. Change-Id: I3e73856b2c1411977450e72af1741aab0ecf537e Reviewed-by: Eirik Aavitsland --- src/gui/image/qimage.cpp | 8 +-- src/gui/image/qimage_conversions.cpp | 127 +++++++---------------------------- 2 files changed, 25 insertions(+), 110 deletions(-) (limited to 'src') diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 4c00c7705a..efef5eee58 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2062,13 +2062,7 @@ QImage QImage::convertToFormat_helper(Format format, Qt::ImageConversionFlags fl Image_Converter converter = qimage_converter_map[d->format][format]; if (!converter && format > QImage::Format_Indexed8 && d->format > QImage::Format_Indexed8) { if (highColorPrecision(format) && highColorPrecision(d->format)) { - // Convert over RGBA64_Premultiplied - if (format == QImage::Format_RGBA64_Premultiplied) - converter = convert_generic_to_rgb64; - else { - Q_ASSERT(d->format != QImage::Format_RGBA64_Premultiplied); - return convertToFormat(Format_RGBA64_Premultiplied, flags).convertToFormat(format, flags); - } + converter = convert_generic_to_rgb64; } else converter = convert_generic; } diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index ea9347183e..82ffb8af8b 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -223,18 +223,29 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio void convert_generic_to_rgb64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { - Q_ASSERT(dest->format == QImage::Format_RGBA64_Premultiplied); + Q_ASSERT(dest->format > QImage::Format_Indexed8); Q_ASSERT(src->format > QImage::Format_Indexed8); + QRgba64 buf[BufferSize]; + QRgba64 *buffer = buf; const QPixelLayout *srcLayout = &qPixelLayouts[src->format]; + const QPixelLayout *destLayout = &qPixelLayouts[dest->format]; const uchar *srcData = src->data; uchar *destData = dest->data; const FetchAndConvertPixelsFunc64 fetch = srcLayout->fetchToRGBA64PM; + const ConvertAndStorePixelsFunc64 store = qStoreFromRGBA64PM[dest->format]; for (int y = 0; y < src->height; ++y) { - const QRgba64 *ptr = fetch((QRgba64*)destData, srcData, 0, src->width, nullptr, nullptr); - if (ptr != (const QRgba64*)destData) { - memcpy(destData, ptr, dest->bytes_per_line); + int x = 0; + while (x < src->width) { + int l = src->width - x; + if (destLayout->bpp == QPixelLayout::BPP64) + buffer = reinterpret_cast(destData) + x; + else + l = qMin(l, BufferSize); + const QRgba64 *ptr = fetch(buffer, srcData, x, l, nullptr, nullptr); + store(destData, ptr, x, l, nullptr, nullptr); + x += l; } srcData += src->bytes_per_line; destData += dest->bytes_per_line; @@ -1204,33 +1215,6 @@ static void convert_RGBA64_to_ARGB32(QImageData *dest, const QImageData *src, Qt } } -template -static void convert_RGBA64PM_to_ARGB32(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(RGBA || dest->format == QImage::Format_ARGB32); - Q_ASSERT(!RGBA || dest->format == QImage::Format_RGBA8888); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - QRgba64 s = src_data->unpremultiplied(); - *dest_data = RGBA ? ARGB2RGBA(s.toArgb32()) : s.toArgb32(); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - template static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) { @@ -1240,74 +1224,14 @@ static void convert_ARGB32_to_RGBA64(QImageData *dest, const QImageData *src, Qt Q_ASSERT(src->width == dest->width); Q_ASSERT(src->height == dest->height); - const int src_pad = (src->bytes_per_line >> 2) - src->width; - const int dest_pad = (dest->bytes_per_line >> 3) - dest->width; - const uint *src_data = reinterpret_cast(src->data); - QRgba64 *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const uint *end = src_data + src->width; - while (src_data < end) { - if (RGBA) - *dest_data = QRgba64::fromArgb32(RGBA2ARGB(*src_data)); - else - *dest_data = QRgba64::fromArgb32(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template -static void convert_RGBA64PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); - - for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - *dest_data = 0xc0000000 | qConvertRgb64ToRgb30(src_data->unpremultiplied()); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; - } -} - -template -static void convert_RGBA64PM_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) -{ - Q_ASSERT(src->format == QImage::Format_RGBA64_Premultiplied); - Q_ASSERT(dest->format == QImage::Format_A2RGB30_Premultiplied - || dest->format == QImage::Format_A2BGR30_Premultiplied); - Q_ASSERT(src->width == dest->width); - Q_ASSERT(src->height == dest->height); - - const int src_pad = (src->bytes_per_line >> 3) - src->width; - const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; - const QRgba64 *src_data = reinterpret_cast(src->data); - uint *dest_data = reinterpret_cast(dest->data); + const uchar *src_data = src->data; + uchar *dest_data = dest->data; + const FetchAndConvertPixelsFunc64 fetch = qPixelLayouts[src->format + 1].fetchToRGBA64PM; for (int i = 0; i < src->height; ++i) { - const QRgba64 *end = src_data + src->width; - while (src_data < end) { - *dest_data = qConvertRgb64ToRgb30(*src_data); - ++src_data; - ++dest_data; - } - src_data += src_pad; - dest_data += dest_pad; + fetch(reinterpret_cast(dest_data), src_data, 0, src->width, nullptr, nullptr); + src_data += src->bytes_per_line;; + dest_data += dest->bytes_per_line; } } @@ -2958,7 +2882,6 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGBA64PM_to_ARGB32, 0, 0, 0, @@ -2970,12 +2893,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - convert_RGBA64PM_to_ARGB32, 0, - convert_RGBA64PM_to_RGB30, - convert_RGBA64PM_to_A2RGB30, - convert_RGBA64PM_to_RGB30, - convert_RGBA64PM_to_A2RGB30, + 0, + 0, + 0, 0, 0, 0, 0, 0, convert_RGBA64PM_to_RGBA64, convert_RGBA64PM_to_RGBA64, -- cgit v1.2.3