diff options
Diffstat (limited to 'src/gui/image/qimage.cpp')
-rw-r--r-- | src/gui/image/qimage.cpp | 416 |
1 files changed, 416 insertions, 0 deletions
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 |