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 ::OH_PixelmapNative *pixelMap {};
119
120 QImage effectiveImage =
121 tryMapQtPixelFormatToOhosPixelFormat(qImage.format()).has_value()
122 ? qImage
123 : qImage.convertToFormat(QImage::Format_RGBA8888);
124 auto optOhosPixelFormat = tryMapQtPixelFormatToOhosPixelFormat(effectiveImage.format());
125 Q_ASSERT(optOhosPixelFormat.has_value());
126 auto ohosPixelFormat = optOhosPixelFormat.value();
127
128 auto initOptions = makeNativePixelMapInitializationOptions(
129 static_cast<std::uint32_t>(effectiveImage.width()),
130 static_cast<std::uint32_t>(effectiveImage.height()), ohosPixelFormat,
131 mapQtPixelFormatToOhosPixelMapAlphaType(effectiveImage.pixelFormat()));
132
133 callOhosCApiFuncOrFailOnErrorResult(
134 Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_CreatePixelmap),
135 effectiveImage.bits(), effectiveImage.sizeInBytes(), initOptions.get(), &pixelMap);
136
137 return std::shared_ptr<::OH_PixelmapNative>(
138 pixelMap,
139 [](::OH_PixelmapNative *pixelMap) {
140 if (pixelMap != nullptr) {
141 int res = callOhosCApiFunc(Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_Release), pixelMap);
142 if (res != ::Image_ErrorCode::IMAGE_SUCCESS) {
143 qOhosPrintfError(
144 "%s: cannot release the pixel map (error code: %d).",
145 Q_FUNC_INFO, res);
146 }
147 }
148 });
149}
150
152{
153 return std::shared_ptr<::OH_PixelmapNative>(
154 pixelMap,
155 [](::OH_PixelmapNative *pixelMap) {
156 if (pixelMap != nullptr) {
157 int res = callOhosCApiFunc(Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_Release), pixelMap);
158 if (res != ::Image_ErrorCode::IMAGE_SUCCESS) {
159 qOhosPrintfError(
160 "%s: cannot release the pixel map (error code: %d).",
161 Q_FUNC_INFO, res);
162 }
163 }
164 });
165}
166
168{
169 constexpr auto pixelFormat = ::PIXEL_FORMAT::PIXEL_FORMAT_RGBA_8888;
170 constexpr auto alphaType = ::PIXELMAP_ALPHA_TYPE::PIXELMAP_ALPHA_TYPE_OPAQUE;
171
172 auto initOptions = makeNativePixelMapInitializationOptions(1, 1, pixelFormat, alphaType);
173
174 ::OH_PixelmapNative *pixelMap = {};
175 callOhosCApiFuncOrFailOnErrorResult(
176 Q_OHOS_NAMED_FUNC(::OH_PixelmapNative_CreateEmptyPixelmap),
177 initOptions.get(), &pixelMap);
178
179 return wrapOhosNativePixelMapPtr(pixelMap);
180}
181
182QNapi::Object makeOhosNapiPixelMapFromQImage(QOhosJsState &jsState, const QImage &image)
183{
184 QImage effectiveImage =
185 tryMapQtPixelFormatToOhosPixelFormat(image.format()).has_value()
186 ? image
187 : image.convertToFormat(QImage::Format_RGBA8888);
188 auto optOhosPixelFormat = tryMapQtPixelFormatToOhosPixelFormat(effectiveImage.format());
189 Q_ASSERT(optOhosPixelFormat.has_value());
190 auto ohosPixelFormat = optOhosPixelFormat.value();
191
192 auto *env = jsState.env();
193
194 auto destBytesPerLine = effectiveImage.bytesPerLine();
195 auto arrayBuffer = QNapi::ArrayBuffer::New(env, effectiveImage.height() * destBytesPerLine);
196
197 for (int y = 0; y < effectiveImage.height(); ++y) {
198 std::memcpy(
199 static_cast<uchar *>(arrayBuffer.Data()) + y * destBytesPerLine, effectiveImage.scanLine(y), destBytesPerLine);
200 }
201
202 const auto options = QNapi::makeObject(
203 env,
204 {
205 {
206 "size",
207 QNapi::makeObject(
208 env,
209 {
210 {"width", effectiveImage.size().width()},
211 {"height", effectiveImage.size().height()},
212 })
213 },
214 {"pixelFormat", static_cast<int>(ohosPixelFormat)},
215 {"srcPixelFormat", static_cast<int>(ohosPixelFormat)},
216 });
217
218 return jsState.eval<QNapi::Object>("@ohos.multimedia.image.createPixelMapSync(*)", {arrayBuffer, options});
219}
220
221QT_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)