diff options
Diffstat (limited to 'src/gui/image/qimage_conversions.cpp')
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 333 |
1 files changed, 292 insertions, 41 deletions
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 858a0d9f21..2e8fc1963d 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -1861,11 +1861,154 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt } } +static void convert_Indexed8_to_Alpha8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_Indexed8); + Q_ASSERT(dest->format == QImage::Format_Alpha8); + + uchar translate[256]; + const QVector<QRgb> &colors = src->colortable; + bool simpleCase = (colors.size() == 256); + for (int i = 0; i < colors.size(); ++i) { + uchar alpha = qAlpha(colors[i]); + translate[i] = alpha; + simpleCase = simpleCase && (alpha == i); + } + + if (simpleCase) + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + else { + int size = src->bytes_per_line * src->height; + for (int i = 0; i < size; ++i) { + dest->data[i] = translate[src->data[i]]; + } + } +} + +static void convert_Indexed8_to_Grayscale8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_Indexed8); + Q_ASSERT(dest->format == QImage::Format_Grayscale8); + + uchar translate[256]; + const QVector<QRgb> &colors = src->colortable; + bool simpleCase = (colors.size() == 256); + for (int i = 0; i < colors.size(); ++i) { + uchar gray = qGray(colors[i]); + translate[i] = gray; + simpleCase = simpleCase && (gray == i); + } + + if (simpleCase) + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + else { + int size = src->bytes_per_line * src->height; + for (int i = 0; i < size; ++i) { + dest->data[i] = translate[src->data[i]]; + } + } +} + +static bool convert_Indexed8_to_Alpha8_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + + // Just check if this is an Alpha8 in Indexed8 disguise. + const QVector<QRgb> &colors = data->colortable; + if (colors.size() != 256) + return false; + for (int i = 0; i < colors.size(); ++i) { + if (i != qAlpha(colors[i])) + return false; + } + + data->colortable.clear(); + data->format = QImage::Format_Alpha8; + + return true; +} + +static bool convert_Indexed8_to_Grayscale8_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Indexed8); + + // Just check if this is a Grayscale8 in Indexed8 disguise. + const QVector<QRgb> &colors = data->colortable; + if (colors.size() != 256) + return false; + for (int i = 0; i < colors.size(); ++i) { + if (i != qGray(colors[i])) + return false; + } + + data->colortable.clear(); + data->format = QImage::Format_Grayscale8; + + return true; +} + +static void convert_Alpha8_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_Alpha8); + Q_ASSERT(dest->format == QImage::Format_Indexed8); + + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + + QVector<QRgb> colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgba(0, 0, 0, i); + + dest->colortable = colors; +} + +static void convert_Grayscale8_to_Indexed8(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_Grayscale8); + Q_ASSERT(dest->format == QImage::Format_Indexed8); + + memcpy(dest->data, src->data, src->bytes_per_line * src->height); + + QVector<QRgb> colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgb(i, i, i); + + dest->colortable = colors; +} + +static bool convert_Alpha8_to_Indexed8_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Alpha8); + + QVector<QRgb> colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgba(0, 0, 0, i); + + data->colortable = colors; + data->format = QImage::Format_Indexed8; + + return true; +} + +static bool convert_Grayscale8_to_Indexed8_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_Grayscale8); + + QVector<QRgb> colors(256); + for (int i=0; i<256; ++i) + colors[i] = qRgb(i, i, i); + + data->colortable = colors; + data->format = QImage::Format_Indexed8; + + return true; +} + + // first index source, second dest Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, @@ -1886,7 +2029,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { @@ -1908,7 +2051,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -1930,7 +2073,9 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + convert_Indexed8_to_Alpha8, + convert_Indexed8_to_Grayscale8, }, // Format_Indexed8 { @@ -1957,6 +2102,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_RGB_to_RGB30<PixelOrderBGR>, convert_RGB_to_RGB30<PixelOrderRGB>, convert_RGB_to_RGB30<PixelOrderRGB>, + 0, 0 }, // Format_RGB32 { @@ -1983,6 +2129,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGB_to_RGB30<PixelOrderRGB>, 0, + 0, 0 }, // Format_ARGB32 { @@ -2009,6 +2156,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_A2RGB30<PixelOrderBGR>, convert_ARGB_PM_to_RGB30<PixelOrderRGB>, convert_ARGB_to_A2RGB30<PixelOrderRGB>, + 0, 0 }, // Format_ARGB32_Premultiplied { @@ -2030,7 +2178,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -2052,7 +2200,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -2074,7 +2222,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -2096,7 +2244,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -2118,7 +2266,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -2140,7 +2288,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -2162,7 +2310,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { @@ -2184,7 +2332,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -2205,7 +2353,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2227,7 +2375,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, mask_alpha_converter_RGBx, mask_alpha_converter_RGBx, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2254,7 +2402,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, #endif - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888 { @@ -2283,7 +2431,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, #endif - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { @@ -2309,7 +2457,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_passthrough, convert_BGR30_to_RGB30, - convert_BGR30_to_RGB30 + convert_BGR30_to_RGB30, + 0, 0 }, // Format_BGR30 { 0, @@ -2334,7 +2483,8 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_A2RGB30_PM_to_RGB30, 0, 0, - convert_BGR30_to_RGB30 + convert_BGR30_to_RGB30, + 0, 0 }, // Format_BGR30A2_Premultiplied { 0, @@ -2360,6 +2510,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, convert_passthrough, + 0, 0 }, // Format_RGB30 { 0, @@ -2385,19 +2536,61 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_BGR30_to_RGB30, convert_A2RGB30_PM_to_RGB30, 0, + 0, + 0, }, // Format_RGB30A2_Premultiplied + { + 0, + 0, + 0, + convert_Alpha8_to_Indexed8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, 0, 0, 0, 0, 0 + }, // Format_Alpha8 + { + 0, + 0, + 0, + convert_Grayscale8_to_Indexed8, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0, 0, 0, 0, 0, 0 + } // Format_Grayscale8 }; InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] = { { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_Mono { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_MonoLSB { 0, @@ -2418,7 +2611,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + convert_Indexed8_to_Alpha8_inplace, + convert_Indexed8_to_Grayscale8_inplace, }, // Format_Indexed8 { 0, @@ -2439,7 +2634,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB32 { 0, @@ -2464,7 +2659,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -2486,34 +2681,34 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_ARGB32_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB16 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB666 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB555 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB888 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_RGB444 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -2535,7 +2730,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, convert_passthrough_inplace<QImage::Format_RGBA8888>, convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2557,7 +2752,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -2579,7 +2774,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0 }, // Format_RGBA8888_Premultiplied { 0, @@ -2604,7 +2799,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>, convert_BGR30_to_RGB30_inplace, - convert_BGR30_to_RGB30_inplace + convert_BGR30_to_RGB30_inplace, + 0, 0 }, // Format_BGR30 { 0, @@ -2629,7 +2825,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_A2RGB30_PM_to_RGB30_inplace, 0, 0, - convert_BGR30_to_RGB30_inplace + convert_BGR30_to_RGB30_inplace, + 0, 0 }, // Format_BGR30A2_Premultiplied { 0, @@ -2654,7 +2851,8 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma convert_BGR30_to_RGB30_inplace, convert_BGR30_to_RGB30_inplace, 0, - convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied> + convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied>, + 0, 0 }, // Format_RGB30 { 0, @@ -2679,8 +2877,61 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, convert_BGR30_to_RGB30_inplace, convert_A2RGB30_PM_to_RGB30_inplace, - 0 + 0, + 0, 0 }, // Format_RGB30A2_Premultiplied + { + 0, + 0, + 0, + convert_Alpha8_to_Indexed8_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0 + }, // Format_Alpha8 + { + 0, + 0, + 0, + convert_Grayscale8_to_Indexed8_inplace, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, 0 + } // Format_Grayscale8 }; void qInitImageConversions() |