summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/io/qdebug.h4
-rw-r--r--src/gui/image/image.pri2
-rw-r--r--src/gui/image/qimage.h9
-rw-r--r--src/gui/image/qimage_darwin.mm141
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp45
6 files changed, 205 insertions, 2 deletions
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index c5d891cc28..3d8baf7188 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -538,6 +538,12 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
#ifndef Q_FORWARD_DECLARE_MUTABLE_CF_TYPE
# define Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) typedef struct __ ## type * type ## Ref
#endif
+#ifndef Q_FORWARD_DECLARE_CG_TYPE
+#define Q_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type ## Ref;
+#endif
+#ifndef Q_FORWARD_DECLARE_MUTABLE_CG_TYPE
+#define Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type ## Ref;
+#endif
#ifdef Q_OS_DARWIN
# define QT_DARWIN_PLATFORM_SDK_EQUAL_OR_ABOVE(macos, ios, tvos, watchos) \
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index 8021f29e16..abc2abeaec 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -438,8 +438,8 @@ inline QDebug operator<<(QDebug debug, const QFlags<T> &flags)
#define QT_FORWARD_DECLARE_CF_TYPE(type) Q_FORWARD_DECLARE_CF_TYPE(type);
#define QT_FORWARD_DECLARE_MUTABLE_CF_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CF_TYPE(type);
-#define QT_FORWARD_DECLARE_CG_TYPE(type) typedef const struct type *type ## Ref;
-#define QT_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) typedef struct type *type ## Ref;
+#define QT_FORWARD_DECLARE_CG_TYPE(type) Q_FORWARD_DECLARE_CG_TYPE(type);
+#define QT_FORWARD_DECLARE_MUTABLE_CG_TYPE(type) Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(type);
QT_END_NAMESPACE
Q_FORWARD_DECLARE_CF_TYPE(CFString);
diff --git a/src/gui/image/image.pri b/src/gui/image/image.pri
index 378256516c..fe21ff4cc0 100644
--- a/src/gui/image/image.pri
+++ b/src/gui/image/image.pri
@@ -53,6 +53,8 @@ SOURCES += \
win32:!winrt: SOURCES += image/qpixmap_win.cpp
+darwin: OBJECTIVE_SOURCES += image/qimage_darwin.mm
+
NO_PCH_SOURCES += image/qimage_compat.cpp
false: SOURCES += $$NO_PCH_SOURCES # Hack for QtCreator
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index a99134d3bb..91aaf673d0 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -54,6 +54,10 @@
#include <QtCore/qstringlist.h>
#endif
+#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
+Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGImage);
+#endif
+
QT_BEGIN_NAMESPACE
@@ -321,6 +325,11 @@ public:
static QPixelFormat toPixelFormat(QImage::Format format) Q_DECL_NOTHROW;
static QImage::Format toImageFormat(QPixelFormat format) Q_DECL_NOTHROW;
+ // Platform spesific conversion functions
+#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
+ CGImageRef toCGImage() const Q_DECL_CF_RETURNS_RETAINED;
+#endif
+
#if QT_DEPRECATED_SINCE(5, 0)
QT_DEPRECATED inline QString text(const char *key, const char *lang = Q_NULLPTR) const;
QT_DEPRECATED inline QList<QImageTextKeyLang> textList() const;
diff --git a/src/gui/image/qimage_darwin.mm b/src/gui/image/qimage_darwin.mm
new file mode 100644
index 0000000000..d72733abd3
--- /dev/null
+++ b/src/gui/image/qimage_darwin.mm
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qimage.h"
+
+#include <private/qcore_mac_p.h>
+
+#import <Foundation/Foundation.h>
+#import <CoreGraphics/CoreGraphics.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Creates a \c CGImage equivalent to the QImage \a image. Returns a
+ \c CGImageRef handle.
+
+ The returned CGImageRef partakes in the QImage implicit sharing,
+ and holds a reference to the QImage data. CGImage is immutable
+ and will never detach the QImage. Writing to the QImage will detach
+ as usual.
+
+ This function is fast, and does not copy or convert image data.
+
+ The following image formats are supported, and will be mapped to
+ a corresponding native image type:
+
+ \table
+ \header
+ \li Qt
+ \li CoreGraphics
+ \row
+ \li Format_ARGB32
+ \li kCGImageAlphaFirst | kCGBitmapByteOrder32Host
+ \row
+ \li Format_RGB32
+ \li kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host
+ \row
+ \li Format_RGBA8888_Premultiplied
+ \li kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big
+ \row
+ \li Format_RGBA8888
+ \li kCGImageAlphaLast | kCGBitmapByteOrder32Big
+ \row
+ \li Format_RGBX8888
+ \li kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big
+ \row
+ \li Format_ARGB32_Premultiplied
+ \li kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host
+ \endtable
+
+ Other formats are not supported; this function returns a null
+ CGImageRef for those cases. Users of this function may then
+ convert the QImage to a supported formate first, for example
+ Format_ARGB32_Premultiplied.
+
+ The CGImageRef color space is set to the sRGB color space.
+
+ \sa toNSImage()
+*/
+CGImageRef QImage::toCGImage() const
+{
+ if (isNull())
+ return nil;
+
+ // Determine the target native format
+ uint cgflags = kCGImageAlphaNone;
+ switch (format()) {
+ case QImage::Format_ARGB32:
+ cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
+ break;
+ case QImage::Format_RGB32:
+ cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
+ 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;
+ case QImage::Format_ARGB32_Premultiplied:
+ cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
+ break;
+ default: break;
+ }
+
+ // Format not supported: return nil CGImageRef
+ if (cgflags == kCGImageAlphaNone)
+ return nil;
+
+ // Create a data provider that owns a copy of the QImage and references the image data.
+ auto deleter = [](void *image, const void *, size_t)
+ { delete static_cast<QImage *>(image); };
+ QCFType<CGDataProviderRef> dataProvider =
+ CGDataProviderCreateWithData(new QImage(*this), bits(), byteCount(), deleter);
+
+ QCFType<CGColorSpaceRef> colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
+
+ const size_t bitsPerComponent = 8;
+ const size_t bitsPerPixel = 32;
+ const CGFloat *decode = nullptr;
+ const bool shouldInterpolate = false;
+
+ return CGImageCreate(width(), height(), bitsPerComponent, bitsPerPixel,
+ this->bytesPerLine(), colorSpace, cgflags, dataProvider,
+ decode, shouldInterpolate, kCGRenderingIntentDefault);
+}
+
+QT_END_NAMESPACE
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index 18812fd090..a1ab812aaa 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -39,6 +39,10 @@
#include <private/qimage_p.h>
#include <private/qdrawhelper_p.h>
+#ifdef Q_OS_DARWIN
+#include <CoreGraphics/CoreGraphics.h>
+#endif
+
Q_DECLARE_METATYPE(QImage::Format)
Q_DECLARE_METATYPE(Qt::GlobalColor)
@@ -201,6 +205,11 @@ private slots:
void ditherGradient_data();
void ditherGradient();
+#ifdef Q_OS_DARWIN
+ void toCGImage_data();
+ void toCGImage();
+#endif
+
private:
const QString m_prefix;
};
@@ -3307,5 +3316,41 @@ void tst_QImage::ditherGradient()
QVERIFY(observedGradientSteps >= minimumExpectedGradient);
}
+#ifdef Q_OS_DARWIN
+
+void tst_QImage::toCGImage_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<bool>("supported");
+
+ // Populate test data with supported status for all QImage formats.
+ QSet<QImage::Format> supported =
+ { QImage::Format_ARGB32, QImage::Format_RGB32, QImage::Format_RGBA8888_Premultiplied,
+ QImage::Format_RGBA8888, QImage::Format_RGBX8888, QImage::Format_ARGB32_Premultiplied };
+
+ for (int i = QImage::Format_Invalid; i < QImage::Format_Grayscale8; ++i) {
+ QTest::newRow(qPrintable(formatToString(QImage::Format(i))))
+ << QImage::Format(i) << supported.contains(QImage::Format(i));
+ }
+}
+
+// Verify that toCGImage() returns a valid CGImageRef for supported image formats.
+void tst_QImage::toCGImage()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(bool, supported);
+
+ QImage qimage(64, 64, format);
+ qimage.fill(Qt::red);
+
+ CGImageRef cgimage = qimage.toCGImage();
+ QCOMPARE(cgimage != nullptr, supported);
+
+ CGImageRelease(cgimage);
+}
+
+#endif
+
+
QTEST_GUILESS_MAIN(tst_QImage)
#include "tst_qimage.moc"