diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/qbmphandler.cpp | 4 | ||||
-rw-r--r-- | src/gui/image/qicon_p.h | 4 | ||||
-rw-r--r-- | src/gui/image/qimage.cpp | 416 | ||||
-rw-r--r-- | src/gui/image/qimage.h | 9 | ||||
-rw-r--r-- | src/gui/image/qimage_conversions.cpp | 615 | ||||
-rw-r--r-- | src/gui/image/qimage_mips_dspr2.cpp | 20 | ||||
-rw-r--r-- | src/gui/image/qimage_mips_dspr2_asm.S | 92 | ||||
-rw-r--r-- | src/gui/image/qimage_p.h | 6 | ||||
-rw-r--r-- | src/gui/image/qimagereader.cpp | 37 | ||||
-rw-r--r-- | src/gui/image/qimagereader.h | 2 | ||||
-rw-r--r-- | src/gui/image/qimagewriter.cpp | 41 | ||||
-rw-r--r-- | src/gui/image/qimagewriter.h | 2 | ||||
-rw-r--r-- | src/gui/image/qjpeghandler.cpp | 6 | ||||
-rw-r--r-- | src/gui/image/qpicture.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qpixmap.cpp | 3 | ||||
-rw-r--r-- | src/gui/image/qppmhandler.cpp | 4 |
16 files changed, 1176 insertions, 87 deletions
diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index bb79a139b3..036d0615e3 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -798,6 +798,8 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: image = img.convertToFormat(QImage::Format_ARGB32); break; case QImage::Format_RGB16: @@ -806,6 +808,8 @@ bool QBmpHandler::write(const QImage &img) case QImage::Format_RGB555: case QImage::Format_RGB444: case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: image = img.convertToFormat(QImage::Format_RGB32); break; default: diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h index 68cd4a5452..eb94457f48 100644 --- a/src/gui/image/qicon_p.h +++ b/src/gui/image/qicon_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtGui module of the Qt Toolkit. @@ -129,7 +129,7 @@ private: QPixmapIconEngineEntry *tryMatch(const QSize &size, QIcon::Mode mode, QIcon::State state); QVector<QPixmapIconEngineEntry> pixmaps; - friend QDataStream &operator<<(QDataStream &s, const QIcon &icon); + friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const QIcon &icon); friend class QIconThemeEngine; }; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 273c1c922e..d8c3a8c2eb 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -222,6 +222,16 @@ bool QImageData::checkForAlphaPixels() const } } break; + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: { + uchar *bits = data; + for (int y=0; y<height && !has_alpha_pixels; ++y) { + for (int x=0; x<width; ++x) + has_alpha_pixels |= (((uint *)bits)[x] & 0xc0000000) != 0xc0000000; + bits += bytes_per_line; + } + } break; + case QImage::Format_ARGB8555_Premultiplied: case QImage::Format_ARGB8565_Premultiplied: { uchar *bits = data; @@ -701,6 +711,10 @@ bool QImageData::checkForAlphaPixels() const is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA. \value Format_RGBA8888_Premultiplied The image is stored using a premultiplied 32-bit byte-ordered RGBA format (8-8-8-8). + \value Format_BGR30 The image is stored using a 32-bit BGR format (x-10-10-10). + \value Format_A2BGR30_Premultiplied The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10). + \value Format_RGB30 The image is stored using a 32-bit RGB format (x-10-10-10). + \value Format_A2RGB30_Premultiplied The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10). \note Drawing into a QImage with QImage::Format_Indexed8 is not supported. @@ -708,6 +722,9 @@ bool QImageData::checkForAlphaPixels() const \note Do not render into ARGB32 images using QPainter. Using QImage::Format_ARGB32_Premultiplied is significantly faster. + \note Formats with more than 8 bit per color channel will only be processed by the raster engine using 8 bit + per color. + \sa format(), convertToFormat() */ @@ -1670,6 +1687,8 @@ void QImage::fill(uint pixel) #else pixel |= 0x000000ff; #endif + if (d->format == Format_BGR30 || d->format == Format_RGB30) + pixel |= 0xc0000000; qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel, 0, 0, d->width, d->height, d->bytes_per_line); @@ -1736,6 +1755,14 @@ void QImage::fill(const QColor &color) case QImage::Format_RGBA8888_Premultiplied: fill(ARGB2RGBA(qPremultiply(color.rgba()))); break; + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + fill(qConvertArgb32ToA2rgb30<PixelOrderBGR>(color.rgba())); + break; + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: + fill(qConvertArgb32ToA2rgb30<PixelOrderRGB>(color.rgba())); + break; case QImage::Format_RGB16: fill((uint) qConvertRgb32To16(color.rgba())); break; @@ -2142,6 +2169,12 @@ QRgb QImage::pixel(int x, int y) const case Format_RGBA8888: // Match ARGB32 behavior. case Format_RGBA8888_Premultiplied: return RGBA2ARGB(reinterpret_cast<const quint32 *>(s)[x]); + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + return qConvertA2rgb30ToArgb32<PixelOrderBGR>(reinterpret_cast<const quint32 *>(s)[x]); + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + return qConvertA2rgb30ToArgb32<PixelOrderRGB>(reinterpret_cast<const quint32 *>(s)[x]); case Format_RGB16: return qConvertRgb16To32(reinterpret_cast<const quint16 *>(s)[x]); default: @@ -2232,6 +2265,18 @@ void QImage::setPixel(int x, int y, uint index_or_rgb) case Format_RGBA8888_Premultiplied: ((uint *)s)[x] = ARGB2RGBA(index_or_rgb); return; + case Format_BGR30: + ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderBGR>(index_or_rgb); + return; + case Format_A2BGR30_Premultiplied: + ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderBGR>(index_or_rgb); + return; + case Format_RGB30: + ((uint *)s)[x] = qConvertRgb32ToRgb30<PixelOrderRGB>(index_or_rgb); + return; + case Format_A2RGB30_Premultiplied: + ((uint *)s)[x] = qConvertArgb32ToA2rgb30<PixelOrderRGB>(index_or_rgb); + return; case Format_Invalid: case NImageFormats: Q_ASSERT(false); @@ -2959,6 +3004,23 @@ QImage QImage::rgbSwapped_helper() const } } break; + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); + for (int i = 0; i < d->height; i++) { + uint *q = (uint*)res.scanLine(i); + const uint *p = (const uint*)constScanLine(i); + const uint *end = p + d->width; + while (p < end) { + *q = qRgbSwapRgb30(*p); + p++; + q++; + } + } + break; default: res = QImage(d->width, d->height, d->format); rgbSwapped_generic(d->width, d->height, this, &res, &qPixelLayouts[d->format]); @@ -3019,6 +3081,19 @@ void QImage::rgbSwapped_inplace() } } break; + case Format_BGR30: + case Format_A2BGR30_Premultiplied: + case Format_RGB30: + case Format_A2RGB30_Premultiplied: + for (int i = 0; i < d->height; i++) { + uint *p = (uint*)scanLine(i); + uint *end = p + d->width; + while (p < end) { + *p = qRgbSwapRgb30(*p); + p++; + } + } + break; default: rgbSwapped_generic(d->width, d->height, this, this, &qPixelLayouts[d->format]); break; @@ -4044,6 +4119,8 @@ bool QImage::hasAlphaChannel() const || d->format == Format_ARGB4444_Premultiplied || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied + || d->format == Format_A2BGR30_Premultiplied + || d->format == Format_A2RGB30_Premultiplied || (d->has_alpha_clut && (d->format == Format_Indexed8 || d->format == Format_Mono || d->format == Format_MonoLSB))); @@ -4069,6 +4146,10 @@ int QImage::bitPlaneCount() const switch (d->format) { case QImage::Format_Invalid: break; + case QImage::Format_BGR30: + case QImage::Format_RGB30: + bpc = 30; + break; case QImage::Format_RGB32: case QImage::Format_RGBX8888: bpc = 24; @@ -4122,6 +4203,10 @@ static QImage rotated90(const QImage &image) { case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: qt_memrotate270(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -4184,6 +4269,10 @@ static QImage rotated270(const QImage &image) { case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: qt_memrotate90(reinterpret_cast<const quint32*>(image.bits()), w, h, image.bytesPerLine(), reinterpret_cast<quint32*>(out.bits()), @@ -4332,6 +4421,12 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode case QImage::Format_RGBX8888: target_format = Format_RGBA8888_Premultiplied; break; + case QImage::Format_BGR30: + target_format = Format_A2BGR30_Premultiplied; + break; + case QImage::Format_RGB30: + target_format = Format_A2RGB30_Premultiplied; + break; default: target_format = Format_ARGB32_Premultiplied; break; @@ -4504,4 +4599,325 @@ QDebug operator<<(QDebug dbg, const QImage &i) \sa textKeys() */ +static const QPixelFormat pixelformats[] = { + //QImage::Format_Invalid: + QPixelFormat(), + //QImage::Format_Mono: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_MonoLSB: + QPixelFormat(QPixelFormat::GrayScale, + /*RED*/ 1, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_Indexed8: + QPixelFormat(QPixelFormat::Indexed, + /*RED*/ 8, + /*GREEN*/ 0, + /*BLUE*/ 0, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB32_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB16: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8565_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 6, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB666: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB6666_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 6, + /*GREEN*/ 6, + /*BLUE*/ 6, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 6, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB555: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB8555_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 5, + /*GREEN*/ 5, + /*BLUE*/ 5, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB444: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 0, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_ARGB4444_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 4, + /*GREEN*/ 4, + /*BLUE*/ 4, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 4, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedShort, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBX8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGBA8888_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 8, + /*GREEN*/ 8, + /*BLUE*/ 8, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 8, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtEnd, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedByte, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_BGR30: + QPixelFormat(QPixelFormat::BGR, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_A2BGR30_Premultiplied: + QPixelFormat(QPixelFormat::BGR, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_RGB30: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::IgnoresAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::NotPremultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), + //QImage::Format_A2RGB30_Premultiplied: + QPixelFormat(QPixelFormat::RGB, + /*RED*/ 10, + /*GREEN*/ 10, + /*BLUE*/ 10, + /*FOURTH*/ 0, + /*FIFTH*/ 0, + /*ALPHA*/ 2, + /*ALPHA USAGE*/ QPixelFormat::UsesAlpha, + /*ALPHA POSITION*/ QPixelFormat::AtBeginning, + /*PREMULTIPLIED*/ QPixelFormat::Premultiplied, + /*INTERPRETATION*/ QPixelFormat::UnsignedInteger, + /*BYTE ORDER*/ QPixelFormat::CurrentSystemEndian), +}; +Q_STATIC_ASSERT(sizeof(pixelformats) / sizeof(*pixelformats) == QImage::NImageFormats); + +/*! + Returns the QImage::Format as a QPixelFormat +*/ +QPixelFormat QImage::pixelFormat() const Q_DECL_NOTHROW +{ + return toPixelFormat(format()); +} + +/*! + Converts \a format into a QPixelFormat +*/ +QPixelFormat QImage::toPixelFormat(QImage::Format format) Q_DECL_NOTHROW +{ + Q_ASSERT(static_cast<int>(format) < NImageFormats); + return pixelformats[format]; +} + +/*! + Converts \a format into a QImage::Format +*/ +QImage::Format QImage::toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW +{ + for (int i = 0; i < NImageFormats; i++) { + if (format == pixelformats[i]) + return Format(i); + } + return Format_Invalid; +} + QT_END_NAMESPACE diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h index 4326d5dbbc..62f9f5cce2 100644 --- a/src/gui/image/qimage.h +++ b/src/gui/image/qimage.h @@ -45,6 +45,7 @@ #include <QtGui/qtransform.h> #include <QtGui/qpaintdevice.h> #include <QtGui/qrgb.h> +#include <QtGui/qpixelformat.h> #include <QtCore/qbytearray.h> #include <QtCore/qrect.h> #include <QtCore/qstring.h> @@ -123,6 +124,10 @@ public: Format_Grayscale2, Format_Grayscale2LSB #endif + Format_BGR30, + Format_A2BGR30_Premultiplied, + Format_RGB30, + Format_A2RGB30_Premultiplied, #ifndef Q_QDOC NImageFormats #endif @@ -305,6 +310,10 @@ public: QString text(const QString &key = QString()) const; void setText(const QString &key, const QString &value); + QPixelFormat pixelFormat() const Q_DECL_NOTHROW; + static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW; + static QImage::Format toImageFormat(const QPixelFormat &format) Q_DECL_NOTHROW; + #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED inline QString text(const char* key, const char* lang=0) const; QT_DEPRECATED inline QList<QImageTextKeyLang> textList() const; diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp index 629a7c9b69..195b56afbe 100644 --- a/src/gui/image/qimage_conversions.cpp +++ b/src/gui/image/qimage_conversions.cpp @@ -172,6 +172,35 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im return true; } +static void convert_passthrough(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = *src_data; + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QImage::Format Format> +static bool convert_passthrough_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + data->format = 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); @@ -404,6 +433,292 @@ static bool convert_RGBA_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversio return true; } +template<QtPixelOrder PixelOrder> +static void convert_RGB_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + + Q_ASSERT(src->format == QImage::Format_RGB32 || src->format == QImage::Format_ARGB32); + Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_A2BGR30_Premultiplied + || dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_A2RGB30_Premultiplied); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertRgb32ToRgb30<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_RGB30_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_BGR30 || src->format == QImage::Format_RGB30); + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_A2RGB30_PM_to_RGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB32); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = 0xff000000 | qUnpremultiply(qConvertA2rgb30ToArgb32<PixelOrder>(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_ARGB_PM_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_BGR30 || dest->format == QImage::Format_RGB30); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertRgb32ToRgb30<PixelOrder>(qUnpremultiply(*src_data)); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_ARGB_to_A2RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_A2BGR30_Premultiplied || dest->format == QImage::Format_A2RGB30_Premultiplied); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertArgb32ToA2rgb30<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +template<QtPixelOrder PixelOrder> +static void convert_A2RGB30_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_A2BGR30_Premultiplied || src->format == QImage::Format_A2RGB30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_ARGB32_Premultiplied); + 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 >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qConvertA2rgb30ToArgb32<PixelOrder>(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static inline uint qUnpremultiplyRgb30(uint rgb30) +{ + const uint a = rgb30 >> 30; + switch (a) { + case 0: + return 0; + case 1: { + uint rgb = rgb30 & 0x3fffffff; + rgb *= 3; + return (a << 30) | rgb; + } + case 2: { + uint rgb = rgb30 & 0x3fffffff; + rgb += rgb >> 1; + return (a << 30) | rgb; + } + case 3: + return rgb30; + } + Q_UNREACHABLE(); + return 0; +} + +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); + 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 >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + 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); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +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); + + const int pad = (data->bytes_per_line >> 2) - data->width; + uint *rgb_data = (uint *) data->data; + + 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); + ++rgb_data; + } + rgb_data += pad; + } + + if (data->format == QImage::Format_A2RGB30_Premultiplied) + data->format = QImage::Format_RGB30; + else + data->format = QImage::Format_BGR30; + return true; +} + +static void convert_BGR30_to_RGB30(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB30 || src->format == QImage::Format_BGR30 || + src->format == QImage::Format_A2RGB30_Premultiplied || src->format == QImage::Format_A2BGR30_Premultiplied); + Q_ASSERT(dest->format == QImage::Format_RGB30 || dest->format == QImage::Format_BGR30 || + 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 >> 2) - src->width; + const int dest_pad = (dest->bytes_per_line >> 2) - dest->width; + const quint32 *src_data = (quint32 *) src->data; + quint32 *dest_data = (quint32 *) dest->data; + + for (int i = 0; i < src->height; ++i) { + const quint32 *end = src_data + src->width; + while (src_data < end) { + *dest_data = qRgbSwapRgb30(*src_data); + ++src_data; + ++dest_data; + } + src_data += src_pad; + dest_data += dest_pad; + } +} + +static bool convert_BGR30_to_RGB30_inplace(QImageData *data, Qt::ImageConversionFlags) +{ + Q_ASSERT(data->format == QImage::Format_RGB30 || data->format == QImage::Format_BGR30 || + data->format == QImage::Format_A2RGB30_Premultiplied || data->format == QImage::Format_A2BGR30_Premultiplied); + + const int pad = (data->bytes_per_line >> 2) - data->width; + uint *rgb_data = (uint *) data->data; + + for (int i = 0; i < data->height; ++i) { + const uint *end = rgb_data + data->width; + while (rgb_data < end) { + *rgb_data = qRgbSwapRgb30(*rgb_data); + ++rgb_data; + } + rgb_data += pad; + } + + switch (data->format) { + case QImage::Format_BGR30: + data->format = QImage::Format_RGB30; + break; + case QImage::Format_A2BGR30_Premultiplied: + data->format = QImage::Format_A2RGB30_Premultiplied; + break; + case QImage::Format_RGB30: + data->format = QImage::Format_BGR30; + break; + case QImage::Format_A2RGB30_Premultiplied: + data->format = QImage::Format_A2BGR30_Premultiplied; + break; + default: + Q_UNREACHABLE(); + data->format = QImage::Format_Invalid; + return false; + } + return true; +} + static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags) { Q_ASSERT(data->format == QImage::Format_Indexed8); @@ -1557,7 +1872,7 @@ static void convert_Mono_to_Indexed8(QImageData *dest, const QImageData *src, Qt 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, @@ -1578,7 +1893,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_Mono { @@ -1600,7 +1915,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_MonoLSB { @@ -1622,7 +1937,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_Indexed8 { @@ -1644,7 +1959,11 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, convert_RGB_to_RGBA, convert_RGB_to_RGBA, - convert_RGB_to_RGBA + convert_RGB_to_RGBA, + convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderBGR>, + convert_RGB_to_RGB30<PixelOrderRGB>, + convert_RGB_to_RGB30<PixelOrderRGB>, }, // Format_RGB32 { @@ -1667,6 +1986,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_to_RGBx, convert_ARGB_to_RGBA, convert_ARGB_to_RGBA_PM, + convert_RGB_to_RGB30<PixelOrderBGR>, + 0, + convert_RGB_to_RGB30<PixelOrderRGB>, + 0, }, // Format_ARGB32 { @@ -1689,6 +2012,10 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat convert_ARGB_PM_to_RGBx, convert_ARGB_PM_to_RGBA, convert_ARGB_to_RGBA, + convert_ARGB_PM_to_RGB30<PixelOrderBGR>, + convert_ARGB_to_A2RGB30<PixelOrderBGR>, + convert_ARGB_PM_to_RGB30<PixelOrderRGB>, + convert_ARGB_to_A2RGB30<PixelOrderRGB>, }, // Format_ARGB32_Premultiplied { @@ -1710,7 +2037,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB16 { @@ -1732,7 +2059,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB8565_Premultiplied { @@ -1754,7 +2081,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB666 { @@ -1776,7 +2103,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB6666_Premultiplied { @@ -1798,7 +2125,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB555 { @@ -1820,7 +2147,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB8555_Premultiplied { @@ -1842,7 +2169,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB888 { @@ -1864,7 +2191,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_RGB444 { @@ -1885,7 +2212,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0, 0, - 0 + 0, 0, 0, 0, 0 }, // Format_ARGB4444_Premultiplied { 0, @@ -1907,6 +2234,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, mask_alpha_converter_RGBx, mask_alpha_converter_RGBx, + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -1933,6 +2261,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0 #endif + 0, 0, 0, 0 }, // Format_RGBA8888 { @@ -1961,19 +2290,121 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat 0, 0 #endif - } // Format_RGBA8888_Premultiplied + 0, 0, 0, 0 + }, // Format_RGBA8888_Premultiplied + + { + 0, + 0, + 0, + 0, + convert_RGB30_to_RGB<PixelOrderBGR>, + convert_RGB30_to_RGB<PixelOrderBGR>, + convert_RGB30_to_RGB<PixelOrderBGR>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_passthrough, + convert_BGR30_to_RGB30, + convert_BGR30_to_RGB30 + }, // Format_BGR30 + { + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB<PixelOrderBGR>, + 0, + convert_A2RGB30_to_ARGB<PixelOrderBGR>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB30, + 0, + 0, + convert_BGR30_to_RGB30 + }, // Format_BGR30A2_Premultiplied + { + 0, + 0, + 0, + 0, + convert_RGB30_to_RGB<PixelOrderRGB>, + convert_RGB30_to_RGB<PixelOrderRGB>, + convert_RGB30_to_RGB<PixelOrderRGB>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30, + convert_BGR30_to_RGB30, + 0, + 0, + convert_passthrough, + }, // Format_RGB30 + { + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB<PixelOrderRGB>, + 0, + convert_A2RGB30_to_ARGB<PixelOrderRGB>, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30, + convert_A2RGB30_PM_to_RGB30, + 0, + }, // Format_RGB30A2_Premultiplied }; 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 }, // 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 }, // Format_MonoLSB { 0, @@ -1994,7 +2425,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + 0, 0, 0, 0, 0 }, // Format_Indexed8 { 0, @@ -2015,7 +2446,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, + 0, 0, 0, 0, 0 }, // Format_RGB32 { 0, @@ -2040,7 +2471,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, convert_ARGB_to_RGBA_inplace, - 0, + 0, 0, 0, 0, 0 }, // Format_ARGB32 { 0, @@ -2061,34 +2492,35 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - convert_ARGB_to_RGBA_inplace + convert_ARGB_to_RGBA_inplace, + 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // 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 }, // Format_ARGB4444_Premultiplied { 0, @@ -2108,8 +2540,9 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - 0, - 0, + convert_passthrough_inplace<QImage::Format_RGBA8888>, + convert_passthrough_inplace<QImage::Format_RGBA8888_Premultiplied>, + 0, 0, 0, 0 }, // Format_RGBX8888 { 0, @@ -2131,6 +2564,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, + 0, 0, 0, 0 }, // Format_RGBA8888 { 0, @@ -2152,7 +2586,108 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma 0, 0, 0, - } // Format_RGBA8888_Premultiplied + 0, 0, 0, 0 + }, // Format_RGBA8888_Premultiplied + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_passthrough_inplace<QImage::Format_A2BGR30_Premultiplied>, + convert_BGR30_to_RGB30_inplace, + convert_BGR30_to_RGB30_inplace + }, // Format_BGR30 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_A2RGB30_PM_to_RGB30_inplace, + 0, + 0, + convert_BGR30_to_RGB30_inplace + }, // Format_BGR30A2_Premultiplied + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30_inplace, + convert_BGR30_to_RGB30_inplace, + 0, + convert_passthrough_inplace<QImage::Format_A2RGB30_Premultiplied> + }, // Format_RGB30 + { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + convert_BGR30_to_RGB30_inplace, + convert_A2RGB30_PM_to_RGB30_inplace, + 0 + }, // Format_RGB30A2_Premultiplied }; void qInitImageConversions() @@ -2174,9 +2709,15 @@ void qInitImageConversions() #endif #ifdef QT_COMPILER_SUPPORTS_MIPS_DSPR2 - extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags); - inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2; - return; + if (qCpuHasFeature(DSPR2)) { + extern bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConversionFlags); + qimage_inplace_converter_map[QImage::Format_ARGB32][QImage::Format_ARGB32_Premultiplied] = convert_ARGB_to_ARGB_PM_inplace_mips_dspr2; + + extern void convert_RGB888_to_RGB32_mips_dspr2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags); + qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_mips_dspr2; + qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_mips_dspr2; + qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32_Premultiplied] = convert_RGB888_to_RGB32_mips_dspr2; + } #endif } diff --git a/src/gui/image/qimage_mips_dspr2.cpp b/src/gui/image/qimage_mips_dspr2.cpp index a1c40a16df..f61a2262d2 100644 --- a/src/gui/image/qimage_mips_dspr2.cpp +++ b/src/gui/image/qimage_mips_dspr2.cpp @@ -66,4 +66,24 @@ bool convert_ARGB_to_ARGB_PM_inplace_mips_dspr2(QImageData *data, Qt::ImageConve return true; } +extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(uint *dst, const uchar *src, int len); + +void convert_RGB888_to_RGB32_mips_dspr2(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags) +{ + Q_ASSERT(src->format == QImage::Format_RGB888); + Q_ASSERT(dest->format == QImage::Format_RGB32 || dest->format == QImage::Format_ARGB32 || dest->format == QImage::Format_ARGB32_Premultiplied); + Q_ASSERT(src->width == dest->width); + Q_ASSERT(src->height == dest->height); + + const uchar *src_data = (const uchar*) src->data; + quint32 *dest_data = (quint32*) dest->data; + + for (int i = 0; i < src->height; ++i) { + qt_convert_rgb888_to_rgb32_mips_dspr2_asm(dest_data, src_data, src->width); + src_data += src->bytes_per_line; + dest_data = (quint32*) ((uchar*) dest_data + dest->bytes_per_line); + } +} + QT_END_NAMESPACE + diff --git a/src/gui/image/qimage_mips_dspr2_asm.S b/src/gui/image/qimage_mips_dspr2_asm.S index 1f03b72dd4..df626586dc 100644 --- a/src/gui/image/qimage_mips_dspr2_asm.S +++ b/src/gui/image/qimage_mips_dspr2_asm.S @@ -205,3 +205,95 @@ LEAF_MIPS_DSPR2(premultiply_argb_inplace_mips_asm) END(premultiply_argb_inplace_mips_asm) + +LEAF_MIPS_DSPR2(qt_convert_rgb888_to_rgb32_mips_dspr2_asm) +/* + * Parameters: + * a0 - dst *a8r8g8b8 + * a1 - src *r8g8b8 + * a2 - len + * + * R G B r g b R G B r g b R G B r g b . . . -- input + * ------- ------- ------- ------- ------- + * _ R G B _ r g b _ R G B _ r g b _ R G . . -- output + * + * Register usage: + * a2 - tail (len % 4) == (len & 0x3) + * t0 - batches (len / 4) == (len >> 2) + * t1-t7, s1-s3 - temporary + */ + + srl t0, a2, 2 /* batches = len / 4 */ + andi a2, a2, 0x3 /* tail = len % 4 */ + + beqz t0, 5f /* if !batches: tail */ + lui t7, 0xff00 /* [FF 00 00 00] */ + SAVE_REGS_ON_STACK 8, s1, s2, s3, s0, v0, v1 + +1: pref 4, 0 (a1) /* hint: read-streamed */ + pref 5, 0 (a0) /* hint: prepare-write */ + addiu t0, t0, -1 /* batches-- */ + + lbu t1, 0 (a1) /* [__ __ __ R1] */ + lbu t2, 1 (a1) /* [__ __ __ G1] */ + lbu t3, 2 (a1) /* [__ __ __ B1] */ + + lbu t4, 3 (a1) /* [__ __ __ r2] */ + lbu t5, 4 (a1) /* [__ __ __ g2] */ + lbu t6, 5 (a1) /* [__ __ __ b2] */ + + lbu s1, 6 (a1) /* [__ __ __ R3] */ + lbu s2, 7 (a1) /* [__ __ __ G3] */ + lbu s3, 8 (a1) /* [__ __ __ B3] */ + + lbu s0, 9 (a1) /* [__ __ __ r4] */ + lbu v0, 10 (a1) /* [__ __ __ g4] */ + lbu v1, 11 (a1) /* [__ __ __ b4] */ + + append t1, t2, 8 /* [__ __ R1 G1] */ + append t4, t5, 8 /* [__ __ r2 g2] */ + append s1, s2, 8 /* [__ __ R3 G3] */ + append s0, v0, 8 /* [__ __ r4 g4] */ + append t1, t3, 8 /* [__ R1 G1 B1] */ + append t4, t6, 8 /* [__ r2 g2 b2] */ + append s1, s3, 8 /* [__ R3 G4 B3] */ + append s0, v1, 8 /* [__ r4 g4 b4] */ + or t1, t1, t7 /* [FF R1 G1 B1] */ + or t4, t4, t7 /* [FF r2 g2 b2] */ + or s1, s1, t7 /* [FF R3 G3 B3] */ + or s0, s0, t7 /* [FF r4 g4 b4] */ + + sw t1, 0 (a0) + sw t4, 4 (a0) + sw s1, 8 (a0) + sw s0, 12 (a0) + + addiu a1, a1, 12 /* src += 4*3 */ + bnez t0, 1b /* if batches: loop */ + addiu a0, a0, 16 /* dst += 4 */ + + RESTORE_REGS_FROM_STACK 8, s1, s2, s3, s0, v0, v1 + + /* handle remaining "tail" (a2) items */ +5: beqz a2, 0f + lui t0, 0xff00 /* [FF __ __ __] */ + +1: lbu t1, 0 (a1) /* [__ __ __ RR] */ + lbu t2, 1 (a1) /* [__ __ __ GG] */ + lbu t3, 2 (a1) /* [__ __ __ BB] */ + sll t1, t1, 16 /* [__ RR __ __] */ + sll t2, t2, 8 /* [__ __ GG __] */ + or t0, t0, t1 /* [FF RR __ __] */ + or t2, t2, t3 /* [__ __ GG BB] */ + addi a2, a2, -1 /* len-- */ + or t0, t0, t2 /* [FF RR GG BB] */ + addiu a1, a1, 3 /* src += 3 */ + sw t0, 0 (a0) + addiu a0, a0, 4 /* dst++ */ + bnez a2, 1b /* if tail: loop */ + lui t0, 0xff00 /* [FF __ __ __] */ + +0: jr ra + nop + +END(qt_convert_rgb888_to_rgb32_mips_dspr2_asm) diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 81730b92f2..a22e207812 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -130,7 +130,7 @@ inline int qt_depthForFormat(QImage::Format format) switch(format) { case QImage::Format_Invalid: case QImage::NImageFormats: - Q_ASSERT(false); + Q_UNREACHABLE(); case QImage::Format_Mono: case QImage::Format_MonoLSB: depth = 1; @@ -144,6 +144,10 @@ inline int qt_depthForFormat(QImage::Format format) case QImage::Format_RGBX8888: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_BGR30: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_RGB30: + case QImage::Format_A2RGB30_Premultiplied: depth = 32; break; case QImage::Format_RGB555: diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index a10198a006..d3edf40acc 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -125,7 +125,6 @@ #include <qimageiohandler.h> #include <qlist.h> #include <qrect.h> -#include <qset.h> #include <qsize.h> #include <qcolor.h> #include <qvariant.h> @@ -568,7 +567,7 @@ bool QImageReaderPrivate::initHandler() // check some preconditions if (!device || (!deleteDevice && !device->isOpen() && !device->open(QIODevice::ReadOnly))) { imageReaderError = QImageReader::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Invalid device")); + errorString = QImageReader::tr("Invalid device"); return false; } @@ -595,7 +594,7 @@ bool QImageReaderPrivate::initHandler() if (!device->isOpen()) { imageReaderError = QImageReader::FileNotFoundError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "File not found")); + errorString = QImageReader::tr("File not found"); file->setFileName(fileName); // restore the old file name return false; } @@ -604,7 +603,7 @@ bool QImageReaderPrivate::initHandler() // assign a handler if (!handler && (handler = createReadHandlerHelper(device, format, autoDetectImageFormat, ignoresFormatAndExtension)) == 0) { imageReaderError = QImageReader::UnsupportedFormatError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unsupported image format")); + errorString = QImageReader::tr("Unsupported image format"); return false; } return true; @@ -1191,7 +1190,7 @@ bool QImageReader::read(QImage *image) // read the image if (!d->handler->read(image)) { d->imageReaderError = InvalidDataError; - d->errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unable to read image data")); + d->errorString = QImageReader::tr("Unable to read image data"); return false; } @@ -1384,7 +1383,7 @@ QImageReader::ImageReaderError QImageReader::error() const QString QImageReader::errorString() const { if (d->errorString.isEmpty()) - return QLatin1String(QT_TRANSLATE_NOOP(QImageReader, "Unknown error")); + return QImageReader::tr("Unknown error"); return d->errorString; } @@ -1445,11 +1444,11 @@ QByteArray QImageReader::imageFormat(QIODevice *device) #ifndef QT_NO_IMAGEFORMATPLUGIN void supportedImageHandlerFormats(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result); + QList<QByteArray> *result); void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result); + QList<QByteArray> *result); #endif /*! @@ -1482,7 +1481,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QList<QByteArray> QImageReader::supportedImageFormats() { - QSet<QByteArray> formats; + QList<QByteArray> formats; for (int i = 0; i < _qt_NumFormats; ++i) formats << _qt_BuiltInFormats[i].extension; @@ -1490,12 +1489,9 @@ QList<QByteArray> QImageReader::supportedImageFormats() supportedImageHandlerFormats(loader(), QImageIOPlugin::CanRead, &formats); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedFormats; - for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it) - sortedFormats << *it; - - std::sort(sortedFormats.begin(), sortedFormats.end()); - return sortedFormats; + std::sort(formats.begin(), formats.end()); + formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); + return formats; } /*! @@ -1509,7 +1505,7 @@ QList<QByteArray> QImageReader::supportedImageFormats() QList<QByteArray> QImageReader::supportedMimeTypes() { - QSet<QByteArray> mimeTypes; + QList<QByteArray> mimeTypes; for (int i = 0; i < _qt_NumFormats; ++i) mimeTypes << _qt_BuiltInFormats[i].mimeType; @@ -1517,12 +1513,9 @@ QList<QByteArray> QImageReader::supportedMimeTypes() supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanRead, &mimeTypes); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedMimeTypes; - for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) - sortedMimeTypes << *it; - - std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end()); - return sortedMimeTypes; + std::sort(mimeTypes.begin(), mimeTypes.end()); + mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); + return mimeTypes; } QT_END_NAMESPACE diff --git a/src/gui/image/qimagereader.h b/src/gui/image/qimagereader.h index 4f3c93af7d..8409545079 100644 --- a/src/gui/image/qimagereader.h +++ b/src/gui/image/qimagereader.h @@ -43,6 +43,7 @@ #define QIMAGEREADER_H #include <QtCore/qbytearray.h> +#include <QtCore/qcoreapplication.h> #include <QtGui/qimage.h> #include <QtGui/qimageiohandler.h> @@ -58,6 +59,7 @@ class QStringList; class QImageReaderPrivate; class Q_GUI_EXPORT QImageReader { + Q_DECLARE_TR_FUNCTIONS(QImageReader) public: enum ImageReaderError { UnknownError, diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index c12dbb6544..c003e56573 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -279,7 +279,7 @@ QImageWriterPrivate::QImageWriterPrivate(QImageWriter *qq) compression = 0; gamma = 0.0; imageWriterError = QImageWriter::UnknownError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unknown error")); + errorString = QImageWriter::tr("Unknown error"); q = qq; } @@ -288,19 +288,19 @@ bool QImageWriterPrivate::canWriteHelper() { if (!device) { imageWriterError = QImageWriter::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device is not set")); + errorString = QImageWriter::tr("Device is not set"); return false; } if (!device->isOpen()) device->open(QIODevice::WriteOnly); if (!device->isWritable()) { imageWriterError = QImageWriter::DeviceError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Device not writable")); + errorString = QImageWriter::tr("Device not writable"); return false; } if (!handler && (handler = createWriteHandlerHelper(device, format)) == 0) { imageWriterError = QImageWriter::UnsupportedFormatError; - errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format")); + errorString = QImageWriter::tr("Unsupported image format"); return false; } return true; @@ -667,7 +667,7 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const { if (!d->handler && (d->handler = createWriteHandlerHelper(d->device, d->format)) == 0) { d->imageWriterError = QImageWriter::UnsupportedFormatError; - d->errorString = QLatin1String(QT_TRANSLATE_NOOP(QImageWriter, "Unsupported image format")); + d->errorString = QImageWriter::tr("Unsupported image format"); return false; } @@ -678,7 +678,7 @@ bool QImageWriter::supportsOption(QImageIOHandler::ImageOption option) const #ifndef QT_NO_IMAGEFORMATPLUGIN void supportedImageHandlerFormats(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result) + QList<QByteArray> *result) { typedef QMultiMap<int, QString> PluginKeyMap; typedef PluginKeyMap::const_iterator PluginKeyMapConstIterator; @@ -687,6 +687,7 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, const PluginKeyMapConstIterator cend = keyMap.constEnd(); int i = -1; QImageIOPlugin *plugin = 0; + result->reserve(result->size() + keyMap.size()); for (PluginKeyMapConstIterator it = keyMap.constBegin(); it != cend; ++it) { if (it.key() != i) { i = it.key(); @@ -694,13 +695,13 @@ void supportedImageHandlerFormats(QFactoryLoader *loader, } const QByteArray key = it.value().toLatin1(); if (plugin && (plugin->capabilities(0, key) & cap) != 0) - result->insert(key); + result->append(key); } } void supportedImageHandlerMimeTypes(QFactoryLoader *loader, QImageIOPlugin::Capability cap, - QSet<QByteArray> *result) + QList<QByteArray> *result) { QList<QJsonObject> metaDataList = loader->metaData(); @@ -713,7 +714,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, const int keyCount = keys.size(); for (int k = 0; k < keyCount; ++k) { if (plugin && (plugin->capabilities(0, keys.at(k).toString().toLatin1()) & cap) != 0) - result->insert(mimeTypes.at(k).toString().toLatin1()); + result->append(mimeTypes.at(k).toString().toLatin1()); } } } @@ -746,7 +747,7 @@ void supportedImageHandlerMimeTypes(QFactoryLoader *loader, */ QList<QByteArray> QImageWriter::supportedImageFormats() { - QSet<QByteArray> formats; + QList<QByteArray> formats; #ifndef QT_NO_IMAGEFORMAT_BMP formats << "bmp"; #endif @@ -770,12 +771,9 @@ QList<QByteArray> QImageWriter::supportedImageFormats() supportedImageHandlerFormats(loader(), QImageIOPlugin::CanWrite, &formats); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedFormats; - for (QSet<QByteArray>::ConstIterator it = formats.constBegin(); it != formats.constEnd(); ++it) - sortedFormats << *it; - - std::sort(sortedFormats.begin(), sortedFormats.end()); - return sortedFormats; + std::sort(formats.begin(), formats.end()); + formats.erase(std::unique(formats.begin(), formats.end()), formats.end()); + return formats; } /*! @@ -788,7 +786,7 @@ QList<QByteArray> QImageWriter::supportedImageFormats() */ QList<QByteArray> QImageWriter::supportedMimeTypes() { - QSet<QByteArray> mimeTypes; + QList<QByteArray> mimeTypes; #ifndef QT_NO_IMAGEFORMAT_BMP mimeTypes << "image/bmp"; #endif @@ -814,12 +812,9 @@ QList<QByteArray> QImageWriter::supportedMimeTypes() supportedImageHandlerMimeTypes(loader(), QImageIOPlugin::CanWrite, &mimeTypes); #endif // QT_NO_IMAGEFORMATPLUGIN - QList<QByteArray> sortedMimeTypes; - for (QSet<QByteArray>::ConstIterator it = mimeTypes.constBegin(); it != mimeTypes.constEnd(); ++it) - sortedMimeTypes << *it; - - std::sort(sortedMimeTypes.begin(), sortedMimeTypes.end()); - return sortedMimeTypes; + std::sort(mimeTypes.begin(), mimeTypes.end()); + mimeTypes.erase(std::unique(mimeTypes.begin(), mimeTypes.end()), mimeTypes.end()); + return mimeTypes; } QT_END_NAMESPACE diff --git a/src/gui/image/qimagewriter.h b/src/gui/image/qimagewriter.h index 3f5cf9c454..024ad3aa5a 100644 --- a/src/gui/image/qimagewriter.h +++ b/src/gui/image/qimagewriter.h @@ -43,6 +43,7 @@ #define QIMAGEWRITER_H #include <QtCore/qbytearray.h> +#include <QtCore/qcoreapplication.h> #include <QtCore/qlist.h> #include <QtGui/qimageiohandler.h> @@ -55,6 +56,7 @@ class QImage; class QImageWriterPrivate; class Q_GUI_EXPORT QImageWriter { + Q_DECLARE_TR_FUNCTIONS(QImageWriter) public: enum ImageWriterError { UnknownError, diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp index 5008b1982b..c1d3ff9a85 100644 --- a/src/gui/image/qjpeghandler.cpp +++ b/src/gui/image/qjpeghandler.cpp @@ -856,6 +856,7 @@ bool QJpegHandlerPrivate::read(QImage *image) Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len); Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len); +extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uchar *src, int len); QJpegHandler::QJpegHandler() : d(new QJpegHandlerPrivate(this)) @@ -874,6 +875,11 @@ QJpegHandler::QJpegHandler() rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_ssse3; } #endif // QT_COMPILER_SUPPORTS_SSSE3 +#if defined(QT_COMPILER_SUPPORTS_MIPS_DSPR2) + if (qCpuHasFeature(DSPR2)) { + rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_mips_dspr2_asm; + } +#endif // QT_COMPILER_SUPPORTS_DSPR2 } QJpegHandler::~QJpegHandler() diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index ec89b405b5..807746a26e 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -118,7 +118,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, */ const char *qt_mfhdr_tag = "QPIC"; // header tag -static const quint16 mfhdr_maj = 11; // major version # +static const quint16 mfhdr_maj = QDataStream::Qt_DefaultCompiledVersion; // major version # static const quint16 mfhdr_min = 0; // minor version # /*! diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index c6d8d19bb1..f4222d2360 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1511,7 +1511,8 @@ QBitmap QPixmap::mask() const return QBitmap(); const QImage img = toImage(); - const QImage image = (img.depth() < 32 ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); + bool shouldConvert = (img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_ARGB32_Premultiplied); + const QImage image = (shouldConvert ? img.convertToFormat(QImage::Format_ARGB32_Premultiplied) : img); const int w = image.width(); const int h = image.height(); diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp index 39f63a620c..64eaf7f19e 100644 --- a/src/gui/image/qppmhandler.cpp +++ b/src/gui/image/qppmhandler.cpp @@ -275,6 +275,8 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case QImage::Format_RGB888: case QImage::Format_RGB444: case QImage::Format_RGBX8888: + case QImage::Format_BGR30: + case QImage::Format_RGB30: image = image.convertToFormat(QImage::Format_RGB32); break; case QImage::Format_ARGB8565_Premultiplied: @@ -283,6 +285,8 @@ static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QBy case QImage::Format_ARGB4444_Premultiplied: case QImage::Format_RGBA8888: case QImage::Format_RGBA8888_Premultiplied: + case QImage::Format_A2BGR30_Premultiplied: + case QImage::Format_A2RGB30_Premultiplied: image = image.convertToFormat(QImage::Format_ARGB32); break; default: |