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