Recognize RGBA8888 formats when converting to CGImage

qt_mac_image_to_cgimage incorrectly assumes any 32bit QImage format is
one ARGB32 form. This is no longer correct with the introduction of
RGBA8888 format.

This patch recognizes the formats a maps them to the native support for
them in CGImage. It also removes a duplicate method.

The codepath appears to be only used by the old coregraphics paintengine
and MIME handling. Which means RGBA images are probably printed and
copy/pasted incorrectly at the moment.

Task-number: QTBUG-36818
Change-Id: Ie6292defdbaef3e6105cf993e12911eded0918dc
Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
Allan Sandfeld Jensen 2014-02-13 17:20:09 +01:00 committed by The Qt Project
parent 3d05fa25f2
commit a4080e4719
2 changed files with 17 additions and 45 deletions

View File

@ -102,21 +102,31 @@ CGImageRef qt_mac_toCGImage(const QImage &inImage)
uint cgflags = kCGImageAlphaNone;
switch (image.format()) {
case QImage::Format_ARGB32_Premultiplied:
cgflags = kCGImageAlphaPremultipliedFirst;
cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_ARGB32:
cgflags = kCGImageAlphaFirst;
cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
cgflags = kCGImageAlphaNoneSkipFirst;
cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB888:
cgflags |= kCGImageAlphaNone;
break;
cgflags = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888_Premultiplied:
cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBA8888:
cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
break;
case QImage::Format_RGBX8888:
cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
break;
default:
Q_ASSERT(false); // Should never be reached.
break;
}
cgflags |= kCGBitmapByteOrder32Host;
QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image);
return CGImageCreate(image.width(), image.height(), 8, 32,
image.bytesPerLine(),

View File

@ -979,43 +979,6 @@ static void drawImageReleaseData (void *info, const void *, size_t)
delete static_cast<QImage *>(info);
}
CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0)
{
QImage *image;
if (img.depth() != 32)
image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
else
image = new QImage(img);
uint cgflags = kCGImageAlphaNone;
switch (image->format()) {
case QImage::Format_ARGB32_Premultiplied:
cgflags = kCGImageAlphaPremultipliedFirst;
break;
case QImage::Format_ARGB32:
cgflags = kCGImageAlphaFirst;
break;
case QImage::Format_RGB32:
cgflags = kCGImageAlphaNoneSkipFirst;
default:
break;
}
#if defined(kCGBitmapByteOrder32Host) //only needed because CGImage.h added symbols in the minor version
cgflags |= kCGBitmapByteOrder32Host;
#endif
QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
static_cast<const QImage *>(image)->bits(),
image->byteCount(),
drawImageReleaseData);
if (imagePtr)
*imagePtr = image;
return CGImageCreate(image->width(), image->height(), 8, 32,
image->bytesPerLine(),
QCoreGraphicsPaintEngine::macGenericColorSpace(),
cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
}
void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
Qt::ImageConversionFlags flags)
{
@ -1026,8 +989,7 @@ void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, con
if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination)
return;
const QImage *image;
QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image);
QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img);
CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
if (QRectF(0, 0, img.width(), img.height()) != sr)
cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(),