summaryrefslogtreecommitdiffstats
path: root/src/gui/image/qimage_conversions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/image/qimage_conversions.cpp')
-rw-r--r--src/gui/image/qimage_conversions.cpp126
1 files changed, 92 insertions, 34 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index e1be032215..74ad1127a9 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -425,25 +425,25 @@ static void convert_ARGB_to_RGBA(QImageData *dest, const QImageData *src, Qt::Im
}
}
+template<QImage::Format DestFormat>
static bool convert_ARGB_to_RGBA_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_ARGB32_Premultiplied);
const int pad = (data->bytes_per_line >> 2) - data->width;
quint32 *rgb_data = (quint32 *) data->data;
+ Q_CONSTEXPR uint mask = (DestFormat == QImage::Format_RGBX8888) ? 0xff000000 : 0;
for (int i = 0; i < data->height; ++i) {
const quint32 *end = rgb_data + data->width;
while (rgb_data < end) {
- *rgb_data = ARGB2RGBA(*rgb_data);
+ *rgb_data = ARGB2RGBA(*rgb_data | mask);
++rgb_data;
}
rgb_data += pad;
}
- if (data->format == QImage::Format_ARGB32)
- data->format = QImage::Format_RGBA8888;
- else
- data->format = QImage::Format_RGBA8888_Premultiplied;
+
+ data->format = DestFormat;
return true;
}
@@ -567,6 +567,7 @@ static inline uint qUnpremultiplyRgb30(uint rgb30)
return 0;
}
+template<bool rgbswap>
static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied);
@@ -582,7 +583,8 @@ static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src,
for (int i = 0; i < src->height; ++i) {
const quint32 *end = src_data + src->width;
while (src_data < end) {
- *dest_data = 0xc0000000 | qUnpremultiplyRgb30(*src_data);
+ const uint p = 0xc0000000 | qUnpremultiplyRgb30(*src_data);
+ *dest_data = (rgbswap) ? qRgbSwapRgb30(p) : p;
++src_data;
++dest_data;
}
@@ -591,6 +593,7 @@ static void convert_A2RGB30_PM_to_RGB30(QImageData *dest, const QImageData *src,
}
}
+template<bool rgbswap>
static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied);
@@ -601,16 +604,17 @@ static bool convert_A2RGB30_PM_to_RGB30_inplace(QImageData *data, Qt::ImageConve
for (int i = 0; i < data->height; ++i) {
const uint *end = rgb_data + data->width;
while (rgb_data < end) {
- *rgb_data = 0xc0000000 | qUnpremultiplyRgb30(*rgb_data);
+ const uint p = 0xc0000000 | qUnpremultiplyRgb30(*rgb_data);
+ *rgb_data = (rgbswap) ? qRgbSwapRgb30(p) : p;
++rgb_data;
}
rgb_data += pad;
}
if (data->format == QImage::Format_A2RGB30_Premultiplied)
- data->format = QImage::Format_RGB30;
+ data->format = (rgbswap) ? QImage::Format_BGR30 : QImage::Format_RGB30;
else
- data->format = QImage::Format_BGR30;
+ data->format = (rgbswap) ? QImage::Format_RGB30 : QImage::Format_BGR30;
return true;
}
@@ -678,6 +682,19 @@ static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversion
return true;
}
+static bool convert_BGR30_to_A2RGB30_inplace(QImageData *data, Qt::ImageConversionFlags flags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30);
+ if (!convert_BGR30_to_RGB30_inplace(data, flags))
+ return false;
+
+ if (data->format == QImage::Format_RGB30)
+ data->format = QImage::Format_A2RGB30_Premultiplied;
+ else
+ data->format = QImage::Format_A2BGR30_Premultiplied;
+ return true;
+}
+
static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_Indexed8);
@@ -732,7 +749,7 @@ static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConve
return true;
}
-static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+static bool convert_indexed8_to_ARGB_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_Indexed8);
if (!data->own_data)
@@ -775,7 +792,7 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio
}
data->colortable = QVector<QRgb>();
- data->format = QImage::Format_RGB32;
+ data->format = QImage::Format_ARGB32;
data->bytes_per_line = dst_bytes_per_line;
data->depth = depth;
data->nbytes = nbytes;
@@ -783,6 +800,24 @@ static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversio
return true;
}
+static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags flags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ if (!data->own_data)
+ return false;
+
+ if (data->has_alpha_clut) {
+ for (int i = 0; i < data->colortable.size(); ++i)
+ data->colortable[i] |= 0xff000000;
+ }
+
+ if (!convert_indexed8_to_ARGB_inplace(data, flags))
+ return false;
+
+ data->format = QImage::Format_RGB32;
+ return true;
+}
+
static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
{
Q_ASSERT(data->format == QImage::Format_Indexed8);
@@ -965,8 +1000,9 @@ static void mask_alpha_converter(QImageData *dest, const QImageData *src, Qt::Im
template<QImage::Format DestFormat>
static bool mask_alpha_converter_inplace(QImageData *data, Qt::ImageConversionFlags)
{
- Q_ASSERT(data->format == QImage::Format_RGB32 || DestFormat == QImage::Format_RGB32);
-
+ Q_ASSERT(data->format == QImage::Format_RGB32
+ || DestFormat == QImage::Format_RGB32
+ || DestFormat == QImage::Format_RGBX8888);
const int pad = (data->bytes_per_line >> 2) - data->width;
QRgb *rgb_data = (QRgb *) data->data;
@@ -1009,6 +1045,29 @@ static void mask_alpha_converter_RGBx(QImageData *dest, const QImageData *src, Q
#endif
}
+static bool mask_alpha_converter_rgbx_inplace(QImageData *data, Qt::ImageConversionFlags flags)
+{
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ return mask_alpha_converter_inplace<QImage::Format_RGBX8888>(data, flags);
+#else
+ Q_UNUSED(flags);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = *rgb_data | 0x000000fff;
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = DestFormat;
+ return true;
+#endif
+}
+
static QVector<QRgb> fix_color_table(const QVector<QRgb> &ctbl, QImage::Format format)
{
QVector<QRgb> colorTable = ctbl;
@@ -2323,9 +2382,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- convert_A2RGB30_PM_to_RGB30,
- 0,
+ convert_A2RGB30_PM_to_RGB30<false>,
0,
+ convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
0, 0
}, // Format_BGR30A2_Premultiplied
@@ -2375,12 +2434,11 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
0,
0,
- 0,
+ convert_A2RGB30_PM_to_RGB30<true>,
convert_BGR30_to_RGB30,
- convert_A2RGB30_PM_to_RGB30,
- 0,
- 0,
+ convert_A2RGB30_PM_to_RGB30<false>,
0,
+ 0, 0
}, // Format_RGB30A2_Premultiplied
{
0,
@@ -2440,8 +2498,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0,
convert_indexed8_to_RGB_inplace,
+ convert_indexed8_to_ARGB_inplace,
convert_indexed8_to_ARGB_PM_inplace,
convert_indexed8_to_RGB16_inplace,
0,
@@ -2501,8 +2559,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0,
- convert_ARGB_to_RGBA_inplace,
+ convert_ARGB_to_RGBA_inplace<QImage::Format_RGBX8888>,
+ convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888>,
0,
0, 0, 0, 0, 0, 0
}, // Format_ARGB32
@@ -2525,7 +2583,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_ARGB_to_RGBA_inplace,
+ convert_ARGB_to_RGBA_inplace<QImage::Format_RGBA8888_Premultiplied>,
0, 0, 0, 0, 0, 0
}, // Format_ARGB32_Premultiplied
{
@@ -2594,7 +2652,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0,
+ mask_alpha_converter_rgbx_inplace,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__
0,
convert_ARGB_to_ARGB_PM_inplace_sse2,
@@ -2646,10 +2704,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0,
+ 0, // self
convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>,
convert_BGR30_to_RGB30_inplace,
- convert_BGR30_to_RGB30_inplace,
+ convert_BGR30_to_A2RGB30_inplace,
0, 0
}, // Format_BGR30
{
@@ -2672,9 +2730,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- convert_A2RGB30_PM_to_RGB30_inplace,
- 0,
- 0,
+ convert_A2RGB30_PM_to_RGB30_inplace<false>,
+ 0, // self
+ convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
0, 0
}, // Format_BGR30A2_Premultiplied
@@ -2699,8 +2757,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
convert_BGR30_to_RGB30_inplace,
- convert_BGR30_to_RGB30_inplace,
- 0,
+ convert_BGR30_to_A2RGB30_inplace,
+ 0, // self
convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>,
0, 0
}, // Format_RGB30
@@ -2724,10 +2782,10 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
0,
0,
0,
- 0,
+ convert_A2RGB30_PM_to_RGB30_inplace<true>,
convert_BGR30_to_RGB30_inplace,
- convert_A2RGB30_PM_to_RGB30_inplace,
- 0,
+ convert_A2RGB30_PM_to_RGB30_inplace<false>,
+ 0, // self
0, 0
}, // Format_RGB30A2_Premultiplied
{