Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qohosimageconversions.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtCore/private/qohoscommon_p.h>
7#include <QtCore/private/qohoslogger_p.h>
8#include <cstdint>
9#include <cstring>
10#include <optional>
11
12QT_BEGIN_NAMESPACE
13
14namespace
15{
16
17template<typename Func, Func f, typename... FuncArgs>
18QOhosInvokeResult<Func, FuncArgs...> callOhosCApiFunc(QOhosNamedFunc<Func, f> func, FuncArgs &&...funcArgs)
19{
20 return func.ptr()(std::forward<FuncArgs>(funcArgs)...);
21}
22
23template<typename Func, Func f, typename... FuncArgs>
24void callOhosCApiFuncOrFailOnErrorResult(QOhosNamedFunc<Func, f> func, FuncArgs &&...funcArgs)
25{
26 const auto result = func.ptr()(std::forward<FuncArgs>(funcArgs)...);
27 if (static_cast<int>(result) != 0) {
28 qOhosReportFatalErrorAndAbort(
29 "OHOS C API call %s failed with error: %d", func.name(), static_cast<int>(result));
30 }
31}
32
34{
35 return pixelFormat.alphaUsage() == QPixelFormat::UsesAlpha
36 ? pixelFormat.premultiplied() == QPixelFormat::Premultiplied
37 ? ::PIXELMAP_ALPHA_TYPE::PIXELMAP_ALPHA_TYPE_PREMULTIPLIED
38 : ::PIXELMAP_ALPHA_TYPE::PIXELMAP_ALPHA_TYPE_UNPREMULTIPLIED
39 : ::PIXELMAP_ALPHA_TYPE::PIXELMAP_ALPHA_TYPE_OPAQUE;
40}
41
43{
44 ::OH_Pixelmap_InitializationOptions *initOptionsPtr {};
45
46 callOhosCApiFuncOrFailOnErrorResult(
47 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_Create),
48 &initOptionsPtr);
49
50 return std::shared_ptr<::OH_Pixelmap_InitializationOptions>(
51 initOptionsPtr,
52 [](auto *initOptionsPtr) {
53 if (initOptionsPtr != nullptr) {
54 callOhosCApiFuncOrFailOnErrorResult(
55 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_Release),
56 initOptionsPtr);
57 }
58 });
59}
60
62 std::uint32_t width, std::uint32_t height, ::PIXEL_FORMAT pixelFormat,
63 ::PIXELMAP_ALPHA_TYPE alphaType)
64{
65 auto initOptions = createOhPixelmapInitializationOptions();
66
67 callOhosCApiFuncOrFailOnErrorResult(
68 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_SetWidth),
69 initOptions.get(), width);
70
71 callOhosCApiFuncOrFailOnErrorResult(
72 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_SetHeight),
73 initOptions.get(), height);
74
75 callOhosCApiFuncOrFailOnErrorResult(
76 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_SetSrcPixelFormat),
77 initOptions.get(), static_cast<int>(pixelFormat));
78
79 callOhosCApiFuncOrFailOnErrorResult(
80 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_SetPixelFormat),
81 initOptions.get(), static_cast<int>(pixelFormat));
82
83 callOhosCApiFuncOrFailOnErrorResult(
84 Q_OHOS_NAMED_FUNC(::OH_PixelmapInitializationOptions_SetAlphaType),
85 initOptions.get(), static_cast<int>(alphaType));
86
87 return initOptions;
88}
89
91{
92 static_assert(
93 Q_BYTE_ORDER == Q_LITTLE_ENDIAN,
94 "Pixel format mapping is currently supported for little-endian targets only");
95
96 switch (format) {
97 case QImage::Format_RGBA8888:
98 return ::PIXEL_FORMAT::PIXEL_FORMAT_RGBA_8888;
99 case QImage::Format_RGB888:
100 return ::PIXEL_FORMAT::PIXEL_FORMAT_RGB_888;
101 case QImage::Format_Alpha8:
102 return ::PIXEL_FORMAT::PIXEL_FORMAT_ALPHA_8;
103 case QImage::Format_ARGB32:
104 return ::PIXEL_FORMAT::PIXEL_FORMAT_BGRA_8888;
105 case QImage::Format_RGBA16FPx4:
106 return ::PIXEL_FORMAT::PIXEL_FORMAT_RGBA_F16;
107 case QImage::Format_RGB16:
108 return ::PIXEL_FORMAT::PIXEL_FORMAT_RGB_565;
109 default:
110 return {};
111 }
112}
113
114}
115
117{
118 if (qImage.isNull())
119 return makeEmptyOhosNativePixelMap();
120
121 ::OH_PixelmapNative *pixelMap {};
122
123 QImage effectiveImage =
124 tryMapQtPixelFormatToOhosPixelFormat(qImage.format()).has_value()
125 ? qImage
126 : qImage.convertToFormat(QImage::Format_RGBA8888);
127 auto optOhosPixelFormat = tryMapQtPixelFormatToOhosPixelFormat(effectiveImage.format());
128 Q_ASSERT(optOhosPixelFormat.has_value());
129 auto ohosPixelFormat = optOhosPixelFormat.value();
130
131 auto initOptions = makeNativePixelMapInitializationOptions(
132 static_cast<std::uint32_t>(effectiveImage.width()),
133 static_cast<std::uint32_t>(effectiveImage.height()), ohosPixelFormat,
134 mapQtPixelFormatToOhosPixelMapAlphaType(effectiveImage.pixelFormat()));
135
136 callOhosCApiFuncOrFailOnErrorResult(
137 Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_CreatePixelmap),
138 effectiveImage.bits(), effectiveImage.sizeInBytes(), initOptions.get(), &pixelMap);
139
140 return std::shared_ptr<::OH_PixelmapNative>(
141 pixelMap,
142 [](::OH_PixelmapNative *pixelMap) {
143 if (pixelMap != nullptr) {
144 int res = callOhosCApiFunc(Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_Release), pixelMap);
145 if (res != ::Image_ErrorCode::IMAGE_SUCCESS) {
146 qOhosPrintfError(
147 "%s: cannot release the pixel map (error code: %d).",
148 Q_FUNC_INFO, res);
149 }
150 }
151 });
152}
153
155{
156 return std::shared_ptr<::OH_PixelmapNative>(
157 pixelMap,
158 [](::OH_PixelmapNative *pixelMap) {
159 if (pixelMap != nullptr) {
160 int res = callOhosCApiFunc(Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_Release), pixelMap);
161 if (res != ::Image_ErrorCode::IMAGE_SUCCESS) {
162 qOhosPrintfError(
163 "%s: cannot release the pixel map (error code: %d).",
164 Q_FUNC_INFO, res);
165 }
166 }
167 });
168}
169
171{
172 constexpr auto pixelFormat = ::PIXEL_FORMAT::PIXEL_FORMAT_RGBA_8888;
173 constexpr auto alphaType = ::PIXELMAP_ALPHA_TYPE::PIXELMAP_ALPHA_TYPE_OPAQUE;
174
175 auto initOptions = makeNativePixelMapInitializationOptions(1, 1, pixelFormat, alphaType);
176
177 ::OH_PixelmapNative *pixelMap = {};
178 callOhosCApiFuncOrFailOnErrorResult(
179 Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_CreateEmptyPixelmap),
180 initOptions.get(), &pixelMap);
181
182 return wrapOhosNativePixelMapPtr(pixelMap);
183}
184
185QNapi::Object makeOhosNapiPixelMapFromQImage(QOhosJsState &jsState, const QImage &image)
186{
187 QImage effectiveImage =
188 tryMapQtPixelFormatToOhosPixelFormat(image.format()).has_value()
189 ? image
190 : image.convertToFormat(QImage::Format_RGBA8888);
191 auto optOhosPixelFormat = tryMapQtPixelFormatToOhosPixelFormat(effectiveImage.format());
192 Q_ASSERT(optOhosPixelFormat.has_value());
193 auto ohosPixelFormat = optOhosPixelFormat.value();
194
195 auto *env = jsState.env();
196
197 auto destBytesPerLine = effectiveImage.bytesPerLine();
198 auto arrayBuffer = QNapi::ArrayBuffer::New(env, effectiveImage.height() * destBytesPerLine);
199
200 for (int y = 0; y < effectiveImage.height(); ++y) {
201 std::memcpy(
202 static_cast<uchar *>(arrayBuffer.Data()) + y * destBytesPerLine, effectiveImage.scanLine(y), destBytesPerLine);
203 }
204
205 const auto options = QNapi::makeObject(
206 env,
207 {
208 {
209 "size",
210 QNapi::makeObject(
211 env,
212 {
213 {"width", effectiveImage.size().width()},
214 {"height", effectiveImage.size().height()},
215 })
216 },
217 {"pixelFormat", static_cast<int>(ohosPixelFormat)},
218 {"srcPixelFormat", static_cast<int>(ohosPixelFormat)},
219 });
220
221 return jsState.eval<QNapi::Object>("@ohos.multimedia.image.createPixelMapSync(*)", {arrayBuffer, options});
222}
223
224QT_END_NAMESPACE
std::optional<::PIXEL_FORMAT > tryMapQtPixelFormatToOhosPixelFormat(QImage::Format format)
::PIXELMAP_ALPHA_TYPE mapQtPixelFormatToOhosPixelMapAlphaType(const QPixelFormat &pixelFormat)
std::shared_ptr<::OH_Pixelmap_InitializationOptions > createOhPixelmapInitializationOptions()
std::shared_ptr<::OH_Pixelmap_InitializationOptions > makeNativePixelMapInitializationOptions(std::uint32_t width, std::uint32_t height, ::PIXEL_FORMAT pixelFormat, ::PIXELMAP_ALPHA_TYPE alphaType)
QOhosInvokeResult< Func, FuncArgs... > callOhosCApiFunc(QOhosNamedFunc< Func, f > func, FuncArgs &&...funcArgs)
void callOhosCApiFuncOrFailOnErrorResult(QOhosNamedFunc< Func, f > func, FuncArgs &&...funcArgs)
QNapi::Object makeOhosNapiPixelMapFromQImage(QOhosJsState &jsState, const QImage &image)
std::shared_ptr<::OH_PixelmapNative > makeEmptyOhosNativePixelMap()
std::shared_ptr<::OH_PixelmapNative > wrapOhosNativePixelMapPtr(::OH_PixelmapNative *pixelMap)
std::shared_ptr<::OH_PixelmapNative > makeOhosNativePixelMapFromQImage(QImage qImage)