1 /*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "auxiliary_generator.h"
17 #include "abs_image_decoder.h"
18 #include "fragment_metadata.h"
19 #include "hdr_type.h"
20 #include "image_log.h"
21 #include "image_utils.h"
22 #include "image_mime_type.h"
23 #include "image_source.h"
24 #include "jpeg_mpf_parser.h"
25 #include "metadata.h"
26 #include "pixel_map.h"
27 #include "pixel_map_utils.h"
28 #include "pixel_yuv.h"
29 #ifdef EXT_PIXEL
30 #include "pixel_yuv_ext.h"
31 #endif
32 #include "securec.h"
33 #include "surface_buffer.h"
34
35 namespace OHOS {
36 namespace Media {
37 using namespace ImagePlugin;
38
39 static constexpr uint32_t FIRST_FRAME = 0;
40 static constexpr int32_t DEFAULT_SCALE_DENOMINATOR = 1;
41 static constexpr int32_t DEPTH_SCALE_DENOMINATOR = 4;
42 static constexpr int32_t LINEAR_SCALE_DENOMINATOR = 4;
43 static constexpr uint32_t NV12_PLANE_UV_INDEX = 1;
44 static constexpr uint32_t NV21_PLANE_UV_INDEX = 2;
45
IsSizeVailed(const Size & size)46 static inline bool IsSizeVailed(const Size &size)
47 {
48 return (size.width != 0 && size.height != 0);
49 }
50
GetAuxiliaryPictureDenominator(AuxiliaryPictureType type)51 static int32_t GetAuxiliaryPictureDenominator(AuxiliaryPictureType type)
52 {
53 int32_t denominator = DEFAULT_SCALE_DENOMINATOR;
54 switch (type) {
55 case AuxiliaryPictureType::DEPTH_MAP:
56 denominator = DEPTH_SCALE_DENOMINATOR;
57 break;
58 case AuxiliaryPictureType::LINEAR_MAP:
59 denominator = LINEAR_SCALE_DENOMINATOR;
60 break;
61 default:
62 break;
63 }
64 return denominator;
65 }
66
SetAuxiliaryDecodeOption(std::unique_ptr<AbsImageDecoder> & decoder,PixelFormat mainPixelFormat,PlImageInfo & plInfo,AuxiliaryPictureType type)67 static uint32_t SetAuxiliaryDecodeOption(std::unique_ptr<AbsImageDecoder> &decoder, PixelFormat mainPixelFormat,
68 PlImageInfo &plInfo, AuxiliaryPictureType type)
69 {
70 Size size;
71 uint32_t errorCode = decoder->GetImageSize(FIRST_FRAME, size);
72 if (errorCode != SUCCESS || !IsSizeVailed(size)) {
73 return ERR_IMAGE_DATA_ABNORMAL;
74 }
75 PixelDecodeOptions plOptions;
76 plOptions.desiredSize = size;
77 bool useF16Format = (type == AuxiliaryPictureType::LINEAR_MAP || type == AuxiliaryPictureType::DEPTH_MAP);
78 plOptions.desiredPixelFormat = useF16Format ? PixelFormat::RGBA_F16 : mainPixelFormat;
79 IMAGE_LOGI("%{public}s desiredPixelFormat is %{public}d", __func__, plOptions.desiredPixelFormat);
80 errorCode = decoder->SetDecodeOptions(FIRST_FRAME, plOptions, plInfo);
81 return errorCode;
82 }
83
FreeContextBuffer(const Media::CustomFreePixelMap & func,AllocatorType allocType,PlImageBuffer & buffer)84 static void FreeContextBuffer(const Media::CustomFreePixelMap &func, AllocatorType allocType, PlImageBuffer &buffer)
85 {
86 if (func != nullptr) {
87 func(buffer.buffer, buffer.context, buffer.bufferSize);
88 return;
89 }
90
91 #if !defined(_WIN32) && !defined(_APPLE) && !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM)
92 if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
93 int *fd = static_cast<int *>(buffer.context);
94 if (buffer.buffer != nullptr) {
95 ::munmap(buffer.buffer, buffer.bufferSize);
96 }
97 if (fd != nullptr) {
98 ::close(*fd);
99 }
100 return;
101 } else if (allocType == AllocatorType::DMA_ALLOC) {
102 if (buffer.buffer != nullptr) {
103 ImageUtils::SurfaceBuffer_Unreference(static_cast<SurfaceBuffer *>(buffer.context));
104 buffer.context = nullptr;
105 }
106 } else if (allocType == AllocatorType::HEAP_ALLOC) {
107 if (buffer.buffer != nullptr) {
108 free(buffer.buffer);
109 buffer.buffer = nullptr;
110 }
111 }
112 #else
113 if (buffer.buffer != nullptr) {
114 free(buffer.buffer);
115 buffer.buffer = nullptr;
116 }
117 #endif
118 }
119
MakeImageInfo(const Size & size,PixelFormat format,AlphaType alphaType,ColorSpace colorSpace,const std::string & encodedFormat)120 static ImageInfo MakeImageInfo(const Size &size, PixelFormat format, AlphaType alphaType,
121 ColorSpace colorSpace, const std::string &encodedFormat)
122 {
123 ImageInfo info;
124 info.size.width = size.width;
125 info.size.height = size.height;
126 info.pixelFormat = format;
127 info.alphaType = alphaType;
128 info.colorSpace = colorSpace;
129 info.encodedFormat = encodedFormat;
130 return info;
131 }
132
MakeAuxiliaryPictureInfo(AuxiliaryPictureType type,const Size & size,uint32_t rowStride,PixelFormat format,ColorSpace colorSpace)133 static AuxiliaryPictureInfo MakeAuxiliaryPictureInfo(AuxiliaryPictureType type,
134 const Size &size, uint32_t rowStride, PixelFormat format, ColorSpace colorSpace)
135 {
136 AuxiliaryPictureInfo info;
137 info.auxiliaryPictureType = type;
138 info.size.width = size.width;
139 info.size.height = size.height;
140 info.rowStride = rowStride;
141 info.pixelFormat = format;
142 info.colorSpace = colorSpace;
143 return info;
144 }
145
SetDmaYuvInfo(SurfaceBuffer * & surfaceBuffer,PixelFormat format,YUVDataInfo & yuvInfo)146 static void SetDmaYuvInfo(SurfaceBuffer *&surfaceBuffer, PixelFormat format, YUVDataInfo &yuvInfo)
147 {
148 if (surfaceBuffer == nullptr) {
149 IMAGE_LOGE("%{public}s: surfacebuffer is nullptr", __func__);
150 return;
151 }
152 OH_NativeBuffer_Planes *planes = nullptr;
153 GSError retVal = surfaceBuffer->GetPlanesInfo(reinterpret_cast<void **>(&planes));
154 if (retVal != OHOS::GSERROR_OK || planes == nullptr) {
155 IMAGE_LOGE("%{public}s: GetPlanesInfo failed retVal: %{public}d", __func__, retVal);
156 return;
157 }
158 const OH_NativeBuffer_Plane &planeY = planes->planes[0];
159 bool isNV21 = (format == PixelFormat::NV21 || format == PixelFormat::YCRCB_P010);
160 const OH_NativeBuffer_Plane &planeUV = planes->planes[isNV21 ? NV21_PLANE_UV_INDEX : NV12_PLANE_UV_INDEX];
161 if (format == PixelFormat::YCRCB_P010 || format == PixelFormat::YCBCR_P010) {
162 yuvInfo.yStride = planeY.columnStride / 2;
163 yuvInfo.uvStride = planeUV.columnStride / 2;
164 yuvInfo.yOffset = planeY.offset / 2;
165 yuvInfo.uvOffset = planeUV.offset / 2;
166 } else {
167 yuvInfo.yStride = planeY.columnStride;
168 yuvInfo.uvStride = planeUV.columnStride;
169 yuvInfo.yOffset = planeY.offset;
170 yuvInfo.uvOffset = planeUV.offset;
171 }
172 }
173
SetNonDmaYuvInfo(int32_t width,int32_t height,YUVDataInfo & yuvInfo)174 static void SetNonDmaYuvInfo(int32_t width, int32_t height, YUVDataInfo &yuvInfo)
175 {
176 yuvInfo.yWidth = static_cast<uint32_t>(width);
177 yuvInfo.yHeight = static_cast<uint32_t>(height);
178 yuvInfo.uvWidth = static_cast<uint32_t>((width + 1) / 2);
179 yuvInfo.uvHeight = static_cast<uint32_t>((height + 1) / 2);
180 yuvInfo.yStride = static_cast<uint32_t>(width);
181 yuvInfo.uvStride = static_cast<uint32_t>(((width + 1) / 2) * 2);
182 yuvInfo.uvOffset = static_cast<uint32_t>(width) * static_cast<uint32_t>(height);
183 }
184
TrySetYUVDataInfo(std::shared_ptr<PixelMap> & pixelMap)185 static void TrySetYUVDataInfo(std::shared_ptr<PixelMap> &pixelMap)
186 {
187 if (pixelMap == nullptr) {
188 IMAGE_LOGE("%{public}s pixelMap is nullptr", __func__);
189 return;
190 }
191 PixelFormat format = pixelMap->GetPixelFormat();
192 if (!ImageSource::IsYuvFormat(format)) {
193 IMAGE_LOGI("%{public}s pixelMap is not YUV format", __func__);
194 return;
195 }
196
197 YUVDataInfo info;
198 if (pixelMap->GetAllocatorType() == AllocatorType::DMA_ALLOC && pixelMap->GetFd() != nullptr) {
199 SurfaceBuffer *surfaceBuffer = reinterpret_cast<SurfaceBuffer *>(pixelMap->GetFd());
200 SetDmaYuvInfo(surfaceBuffer, format, info);
201 } else {
202 SetNonDmaYuvInfo(pixelMap->GetWidth(), pixelMap->GetHeight(), info);
203 }
204 pixelMap->SetImageYUVInfo(info);
205 }
206
CreatePixelMapByContext(DecodeContext & context,std::unique_ptr<AbsImageDecoder> & decoder,const std::string & encodedFormat,uint32_t & errorCode)207 static std::shared_ptr<PixelMap> CreatePixelMapByContext(DecodeContext &context,
208 std::unique_ptr<AbsImageDecoder> &decoder, const std::string &encodedFormat, uint32_t &errorCode)
209 {
210 std::shared_ptr<PixelMap> pixelMap;
211 if (ImageSource::IsYuvFormat(context.info.pixelFormat)) {
212 #ifdef EXT_PIXEL
213 pixelMap = std::make_shared<PixelYuvExt>();
214 #else
215 pixelMap = std::make_shared<PixelYuv>();
216 #endif
217 } else {
218 pixelMap = std::make_shared<PixelMap>();
219 }
220 if (pixelMap == nullptr) {
221 errorCode = ERR_IMAGE_ADD_PIXEL_MAP_FAILED;
222 return nullptr;
223 }
224
225 ImageInfo imageinfo = MakeImageInfo(context.outInfo.size, context.info.pixelFormat,
226 context.info.alphaType, context.colorSpace, encodedFormat);
227 pixelMap->SetImageInfo(imageinfo, true);
228
229 PixelMapAddrInfos addrInfos;
230 ImageSource::ContextToAddrInfos(context, addrInfos);
231 pixelMap->SetPixelsAddr(addrInfos.addr, addrInfos.context, addrInfos.size, addrInfos.type, addrInfos.func);
232 TrySetYUVDataInfo(pixelMap);
233
234 #ifdef IMAGE_COLORSPACE_FLAG
235 if (context.hdrType > ImageHdrType::SDR) {
236 pixelMap->InnerSetColorSpace(ColorManager::ColorSpace(context.grColorSpaceName));
237 } else if (decoder->IsSupportICCProfile()) {
238 pixelMap->InnerSetColorSpace(decoder->GetPixelMapColorSpace());
239 }
240 #endif
241 return pixelMap;
242 }
243
DecodeHdrMetadata(ImageHdrType hdrType,std::unique_ptr<AbsImageDecoder> & extDecoder,std::unique_ptr<AuxiliaryPicture> & auxPicture)244 static uint32_t DecodeHdrMetadata(ImageHdrType hdrType, std::unique_ptr<AbsImageDecoder> &extDecoder,
245 std::unique_ptr<AuxiliaryPicture> &auxPicture)
246 {
247 if (auxPicture == nullptr) {
248 IMAGE_LOGE("DecodeHdrMetadata: AuxiliaryPicture is null");
249 return ERR_IMAGE_GET_DATA_ABNORMAL;
250 }
251 std::shared_ptr<HdrMetadata> hdrMetadata = std::make_shared<HdrMetadata>(extDecoder->GetHdrMetadata(hdrType));
252 std::shared_ptr<PixelMap> pixelMap = auxPicture->GetContentPixel();
253 if (pixelMap == nullptr) {
254 IMAGE_LOGE("Get invalid content pixel map for hdr metadata");
255 return ERR_IMAGE_GET_DATA_ABNORMAL;
256 }
257 pixelMap->SetHdrMetadata(hdrMetadata);
258 pixelMap->SetHdrType(hdrType);
259 return SUCCESS;
260 }
261
DecodeHeifFragmentMetadata(std::unique_ptr<AbsImageDecoder> & extDecoder,std::unique_ptr<AuxiliaryPicture> & auxPicture)262 static uint32_t DecodeHeifFragmentMetadata(std::unique_ptr<AbsImageDecoder> &extDecoder,
263 std::unique_ptr<AuxiliaryPicture> &auxPicture)
264 {
265 Rect fragmentRect;
266 if (!extDecoder->GetHeifFragmentMetadata(fragmentRect)) {
267 IMAGE_LOGE("Heif parsing fragment metadata failed");
268 return ERR_IMAGE_GET_DATA_ABNORMAL;
269 }
270 std::shared_ptr<ImageMetadata> fragmentMetadata = std::make_shared<FragmentMetadata>();
271 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_X, std::to_string(fragmentRect.left));
272 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_Y, std::to_string(fragmentRect.top));
273 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_WIDTH, std::to_string(fragmentRect.width));
274 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_HEIGHT, std::to_string(fragmentRect.height));
275 auxPicture->SetMetadata(MetadataType::FRAGMENT, fragmentMetadata);
276 return SUCCESS;
277 }
278
DecodeJpegFragmentMetadata(std::unique_ptr<InputDataStream> & auxStream,std::unique_ptr<AuxiliaryPicture> & auxPicture)279 static uint32_t DecodeJpegFragmentMetadata(std::unique_ptr<InputDataStream> &auxStream,
280 std::unique_ptr<AuxiliaryPicture> &auxPicture)
281 {
282 uint8_t *data = auxStream->GetDataPtr();
283 uint32_t size = auxStream->GetStreamSize();
284 Rect fragmentRect;
285 if (!JpegMpfParser::ParsingFragmentMetadata(data, size, fragmentRect)) {
286 IMAGE_LOGE("Jpeg parsing fragment metadata failed");
287 return ERR_IMAGE_GET_DATA_ABNORMAL;
288 }
289 std::shared_ptr<ImageMetadata> fragmentMetadata = std::make_shared<FragmentMetadata>();
290 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_X, std::to_string(fragmentRect.left));
291 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_Y, std::to_string(fragmentRect.top));
292 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_WIDTH, std::to_string(fragmentRect.width));
293 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_HEIGHT, std::to_string(fragmentRect.height));
294 auxPicture->SetMetadata(MetadataType::FRAGMENT, fragmentMetadata);
295 return SUCCESS;
296 }
297
AllocSurfaceBuffer(Size & size,int32_t format,uint32_t & errorCode)298 static sptr<SurfaceBuffer> AllocSurfaceBuffer(Size &size, int32_t format, uint32_t &errorCode)
299 {
300 IMAGE_LOGD("SurfaceBuffer alloc width: %{public}d, height: %{public}d, format: %{public}d",
301 size.width, size.height, format);
302 sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
303 BufferRequestConfig requestConfig = {
304 .width = size.width,
305 .height = size.height,
306 .strideAlignment = 0x8, // set 0x8 as default value to alloc SurfaceBufferImpl
307 .format = format,
308 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
309 .timeout = 0,
310 };
311 GSError ret = sb->Alloc(requestConfig);
312 if (ret != GSERROR_OK) {
313 IMAGE_LOGE("SurfaceBuffer alloc failed, %{public}s", GSErrorStr(ret).c_str());
314 errorCode = ERR_DMA_NOT_EXIST;
315 return nullptr;
316 }
317 errorCode = SUCCESS;
318 return sb;
319 }
320
CopyToSurfaceBuffer(std::unique_ptr<InputDataStream> & stream,sptr<SurfaceBuffer> & surfaceBuffer)321 static uint32_t CopyToSurfaceBuffer(std::unique_ptr<InputDataStream> &stream, sptr<SurfaceBuffer> &surfaceBuffer)
322 {
323 uint8_t *src = stream->GetDataPtr();
324 uint32_t srcSize = stream->GetStreamSize();
325 uint8_t *dst = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
326 uint32_t dstSize = surfaceBuffer->GetSize();
327 if (src == nullptr || dst == nullptr || srcSize == 0 || dstSize == 0) {
328 IMAGE_LOGE("%{public}s: invalid input data", __func__);
329 return ERR_IMAGE_INVALID_PARAMETER;
330 }
331 IMAGE_LOGD("SurfaceBuffer size: %{public}u, stream size: %{public}u", dstSize, srcSize);
332 if (memcpy_s(dst, dstSize, src, srcSize) != EOK) {
333 IMAGE_LOGE("%{public}s: memcpy failed", __func__);
334 return ERR_MEMORY_COPY_FAILED;
335 }
336 return SUCCESS;
337 }
338
SetUncodedAuxilaryPictureInfo(std::unique_ptr<AuxiliaryPicture> & auxPicture)339 static void SetUncodedAuxilaryPictureInfo(std::unique_ptr<AuxiliaryPicture> &auxPicture)
340 {
341 if (auxPicture == nullptr || auxPicture->GetContentPixel() == nullptr) {
342 IMAGE_LOGE("%{public}s auxPicture or auxPixelMap is nullptr", __func__);
343 return;
344 }
345 auto auxPixelMap = auxPicture->GetContentPixel();
346 ImageInfo imageInfo;
347 auxPixelMap->GetImageInfo(imageInfo);
348 auto auxInfo = MakeAuxiliaryPictureInfo(auxPicture->GetType(), imageInfo.size, auxPixelMap->GetRowStride(),
349 imageInfo.pixelFormat, imageInfo.colorSpace);
350 auxPicture->SetAuxiliaryPictureInfo(auxInfo);
351 }
352
GenerateAuxiliaryPicture(MainPictureInfo & mainInfo,AuxiliaryPictureType type,const std::string & format,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)353 static std::unique_ptr<AuxiliaryPicture> GenerateAuxiliaryPicture(MainPictureInfo &mainInfo,
354 AuxiliaryPictureType type, const std::string &format,
355 std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
356 {
357 IMAGE_LOGI("Generate by decoder, type: %{public}d, format: %{public}s", static_cast<int>(type), format.c_str());
358 if (mainInfo.imageInfo.pixelFormat == PixelFormat::ARGB_8888) {
359 IMAGE_LOGW("The auxiliaryPicture cannot use ARGB_8888, convert to RGBA_8888");
360 mainInfo.imageInfo.pixelFormat = PixelFormat::RGBA_8888;
361 }
362 DecodeContext context;
363 context.allocatorType = AllocatorType::DMA_ALLOC;
364 errorCode = SetAuxiliaryDecodeOption(extDecoder, mainInfo.imageInfo.pixelFormat, context.info, type);
365 if (errorCode != SUCCESS) {
366 IMAGE_LOGE("Set auxiliary decode option failed! errorCode: %{public}u", errorCode);
367 return nullptr;
368 }
369 if (format == IMAGE_HEIF_FORMAT) {
370 #ifdef HEIF_HW_DECODE_ENABLE
371 if (type == AuxiliaryPictureType::LINEAR_MAP || type == AuxiliaryPictureType::DEPTH_MAP) {
372 context.pixelFormat = PixelFormat::RGBA_F16;
373 context.info.pixelFormat = PixelFormat::RGBA_F16;
374 }
375 if (!extDecoder->DecodeHeifAuxiliaryMap(context, type)) {
376 errorCode = ERR_IMAGE_DECODE_FAILED;
377 }
378 #else
379 errorCode = ERR_IMAGE_HW_DECODE_UNSUPPORT;
380 #endif
381 } else if (format == IMAGE_JPEG_FORMAT) {
382 errorCode = extDecoder->Decode(FIRST_FRAME, context);
383 context.hdrType = mainInfo.hdrType;
384 } else {
385 errorCode = ERR_MEDIA_DATA_UNSUPPORT;
386 }
387 if (errorCode != SUCCESS) {
388 IMAGE_LOGE("Decode failed! Format: %{public}s, errorCode: %{public}u", format.c_str(), errorCode);
389 FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
390 return nullptr;
391 }
392
393 std::string encodedFormat = ImageUtils::IsAuxiliaryPictureEncoded(type) ? format : "";
394 std::shared_ptr<PixelMap> pixelMap = CreatePixelMapByContext(context, extDecoder, encodedFormat, errorCode);
395 bool cond = pixelMap == nullptr || errorCode != SUCCESS;
396 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "%{public}s CreatePixelMapByContext failed!", __func__);
397 auto auxPicture = AuxiliaryPicture::Create(pixelMap, type, context.outInfo.size);
398 auxPicture->SetAuxiliaryPictureInfo(
399 MakeAuxiliaryPictureInfo(type, context.outInfo.size, pixelMap->GetRowStride(),
400 context.pixelFormat, context.outInfo.colorSpace));
401 return auxPicture;
402 }
403
GenerateHeifAuxiliaryPicture(MainPictureInfo & mainInfo,AuxiliaryPictureType type,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)404 std::shared_ptr<AuxiliaryPicture> AuxiliaryGenerator::GenerateHeifAuxiliaryPicture(MainPictureInfo &mainInfo,
405 AuxiliaryPictureType type, std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
406 {
407 IMAGE_LOGI("Generate heif auxiliary picture, type: %{public}d", static_cast<int>(type));
408 if (!ImageUtils::IsAuxiliaryPictureTypeSupported(type) || extDecoder == nullptr) {
409 errorCode = ERR_IMAGE_INVALID_PARAMETER;
410 return nullptr;
411 }
412
413 auto auxPicture = GenerateAuxiliaryPicture(mainInfo, type, IMAGE_HEIF_FORMAT, extDecoder, errorCode);
414 if (errorCode != SUCCESS) {
415 IMAGE_LOGE("Generate heif auxiliary picture failed! errorCode: %{public}u", errorCode);
416 return nullptr;
417 }
418 if (type == AuxiliaryPictureType::GAINMAP) {
419 errorCode = DecodeHdrMetadata(mainInfo.hdrType, extDecoder, auxPicture);
420 } else if (type == AuxiliaryPictureType::FRAGMENT_MAP) {
421 errorCode = DecodeHeifFragmentMetadata(extDecoder, auxPicture);
422 }
423 if (errorCode != SUCCESS) {
424 IMAGE_LOGE("Decode heif metadata failed! errorCode: %{public}u", errorCode);
425 return nullptr;
426 }
427 return std::move(auxPicture);
428 }
429
GenerateJpegAuxiliaryPicture(MainPictureInfo & mainInfo,AuxiliaryPictureType type,std::unique_ptr<InputDataStream> & auxStream,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)430 std::shared_ptr<AuxiliaryPicture> AuxiliaryGenerator::GenerateJpegAuxiliaryPicture(
431 MainPictureInfo &mainInfo, AuxiliaryPictureType type, std::unique_ptr<InputDataStream> &auxStream,
432 std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
433 {
434 IMAGE_LOGI("Generate jpeg auxiliary picture, type: %{public}d", static_cast<int>(type));
435 if (!ImageUtils::IsAuxiliaryPictureTypeSupported(type) || auxStream == nullptr || extDecoder == nullptr) {
436 errorCode = ERR_IMAGE_INVALID_PARAMETER;
437 return nullptr;
438 }
439
440 if (ImageUtils::IsAuxiliaryPictureEncoded(type)) {
441 auto auxPicture = GenerateAuxiliaryPicture(mainInfo, type, IMAGE_JPEG_FORMAT, extDecoder, errorCode);
442 if (errorCode != SUCCESS) {
443 IMAGE_LOGE("Generate jpeg auxiliary picture failed! errorCode: %{public}u", errorCode);
444 return nullptr;
445 }
446 if (type == AuxiliaryPictureType::GAINMAP) {
447 errorCode = DecodeHdrMetadata(mainInfo.hdrType, extDecoder, auxPicture);
448 } else if (type == AuxiliaryPictureType::FRAGMENT_MAP) {
449 errorCode = DecodeJpegFragmentMetadata(auxStream, auxPicture);
450 }
451 if (errorCode != SUCCESS) {
452 IMAGE_LOGE("Decode jpeg metadata failed! errorCode: %{public}u", errorCode);
453 return nullptr;
454 }
455 return auxPicture;
456 }
457
458 int32_t denominator = GetAuxiliaryPictureDenominator(type);
459 denominator = (denominator == 0) ? DEFAULT_SCALE_DENOMINATOR : denominator;
460 Size size = {mainInfo.imageInfo.size.width / denominator, mainInfo.imageInfo.size.height / denominator};
461 sptr<SurfaceBuffer> surfaceBuffer = AllocSurfaceBuffer(size, GRAPHIC_PIXEL_FMT_RGBA16_FLOAT, errorCode);
462 if (errorCode != SUCCESS || surfaceBuffer == nullptr) {
463 IMAGE_LOGE("Alloc surface buffer failed! errorCode: %{public}u", errorCode);
464 return nullptr;
465 }
466 errorCode = CopyToSurfaceBuffer(auxStream, surfaceBuffer);
467 if (errorCode != SUCCESS) {
468 IMAGE_LOGE("Convert stream to surface buffer failed! errorCode: %{public}u", errorCode);
469 return nullptr;
470 }
471 auto auxPicture = AuxiliaryPicture::Create(surfaceBuffer, type, size);
472 SetUncodedAuxilaryPictureInfo(auxPicture);
473 return auxPicture;
474 }
475
476 } // namespace Media
477 } // namespace OHOS
478