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_trace.h"
22 #include "image_utils.h"
23 #include "image_mime_type.h"
24 #include "image_source.h"
25 #include "jpeg_mpf_parser.h"
26 #include "metadata.h"
27 #include "pixel_map.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 bool cond = (auxPicture == nullptr);
248 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_GET_DATA_ABNORMAL, "DecodeHdrMetadata: AuxiliaryPicture is null");
249 std::shared_ptr<HdrMetadata> hdrMetadata = std::make_shared<HdrMetadata>(extDecoder->GetHdrMetadata(hdrType));
250 std::shared_ptr<PixelMap> pixelMap = auxPicture->GetContentPixel();
251 cond = (pixelMap == nullptr);
252 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_GET_DATA_ABNORMAL, "Get invalid content pixel map for hdr metadata");
253 pixelMap->SetHdrMetadata(hdrMetadata);
254 pixelMap->SetHdrType(hdrType);
255 return SUCCESS;
256 }
257
DecodeHeifFragmentMetadata(std::unique_ptr<AbsImageDecoder> & extDecoder,std::unique_ptr<AuxiliaryPicture> & auxPicture)258 static uint32_t DecodeHeifFragmentMetadata(std::unique_ptr<AbsImageDecoder> &extDecoder,
259 std::unique_ptr<AuxiliaryPicture> &auxPicture)
260 {
261 Rect fragmentRect;
262 bool cond = extDecoder->GetHeifFragmentMetadata(fragmentRect);
263 CHECK_ERROR_RETURN_RET_LOG(!cond, ERR_IMAGE_GET_DATA_ABNORMAL, "Heif parsing fragment metadata failed");
264 std::shared_ptr<ImageMetadata> fragmentMetadata = std::make_shared<FragmentMetadata>();
265 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_X, std::to_string(fragmentRect.left));
266 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_Y, std::to_string(fragmentRect.top));
267 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_WIDTH, std::to_string(fragmentRect.width));
268 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_HEIGHT, std::to_string(fragmentRect.height));
269 auxPicture->SetMetadata(MetadataType::FRAGMENT, fragmentMetadata);
270 return SUCCESS;
271 }
272
DecodeJpegFragmentMetadata(std::unique_ptr<InputDataStream> & auxStream,std::unique_ptr<AuxiliaryPicture> & auxPicture)273 static uint32_t DecodeJpegFragmentMetadata(std::unique_ptr<InputDataStream> &auxStream,
274 std::unique_ptr<AuxiliaryPicture> &auxPicture)
275 {
276 uint8_t *data = auxStream->GetDataPtr();
277 uint32_t size = auxStream->GetStreamSize();
278 Rect fragmentRect;
279 bool cond = JpegMpfParser::ParsingFragmentMetadata(data, size, fragmentRect);
280 CHECK_ERROR_RETURN_RET_LOG(!cond, ERR_IMAGE_GET_DATA_ABNORMAL, "Jpeg parsing fragment metadata failed");
281 std::shared_ptr<ImageMetadata> fragmentMetadata = std::make_shared<FragmentMetadata>();
282 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_X, std::to_string(fragmentRect.left));
283 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_Y, std::to_string(fragmentRect.top));
284 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_WIDTH, std::to_string(fragmentRect.width));
285 fragmentMetadata->SetValue(FRAGMENT_METADATA_KEY_HEIGHT, std::to_string(fragmentRect.height));
286 auxPicture->SetMetadata(MetadataType::FRAGMENT, fragmentMetadata);
287 return SUCCESS;
288 }
289
AllocSurfaceBuffer(Size & size,int32_t format,uint32_t & errorCode)290 static sptr<SurfaceBuffer> AllocSurfaceBuffer(Size &size, int32_t format, uint32_t &errorCode)
291 {
292 IMAGE_LOGD("SurfaceBuffer alloc width: %{public}d, height: %{public}d, format: %{public}d",
293 size.width, size.height, format);
294 sptr<SurfaceBuffer> sb = SurfaceBuffer::Create();
295 BufferRequestConfig requestConfig = {
296 .width = size.width,
297 .height = size.height,
298 .strideAlignment = 0x8, // set 0x8 as default value to alloc SurfaceBufferImpl
299 .format = format,
300 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_MEM_MMZ_CACHE,
301 .timeout = 0,
302 };
303 GSError ret = sb->Alloc(requestConfig);
304 if (ret != GSERROR_OK) {
305 IMAGE_LOGE("SurfaceBuffer alloc failed, %{public}s", GSErrorStr(ret).c_str());
306 errorCode = ERR_DMA_NOT_EXIST;
307 return nullptr;
308 }
309 errorCode = SUCCESS;
310 return sb;
311 }
312
CopyToSurfaceBuffer(std::unique_ptr<InputDataStream> & stream,sptr<SurfaceBuffer> & surfaceBuffer)313 static uint32_t CopyToSurfaceBuffer(std::unique_ptr<InputDataStream> &stream, sptr<SurfaceBuffer> &surfaceBuffer)
314 {
315 uint8_t *src = stream->GetDataPtr();
316 uint32_t srcSize = stream->GetStreamSize();
317 uint8_t *dst = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
318 uint32_t dstSize = surfaceBuffer->GetSize();
319 bool cond = (src == nullptr || dst == nullptr || srcSize == 0 || dstSize == 0);
320 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "%{public}s: invalid input data", __func__);
321 IMAGE_LOGD("SurfaceBuffer size: %{public}u, stream size: %{public}u", dstSize, srcSize);
322 cond = (memcpy_s(dst, dstSize, src, srcSize) != EOK);
323 CHECK_ERROR_RETURN_RET_LOG(cond, ERR_MEMORY_COPY_FAILED, "%{public}s: memcpy failed", __func__);
324 return SUCCESS;
325 }
326
SetUncodedAuxilaryPictureInfo(std::unique_ptr<AuxiliaryPicture> & auxPicture)327 static void SetUncodedAuxilaryPictureInfo(std::unique_ptr<AuxiliaryPicture> &auxPicture)
328 {
329 if (auxPicture == nullptr || auxPicture->GetContentPixel() == nullptr) {
330 IMAGE_LOGE("%{public}s auxPicture or auxPixelMap is nullptr", __func__);
331 return;
332 }
333 auto auxPixelMap = auxPicture->GetContentPixel();
334 ImageInfo imageInfo;
335 auxPixelMap->GetImageInfo(imageInfo);
336 auto auxInfo = MakeAuxiliaryPictureInfo(auxPicture->GetType(), imageInfo.size, auxPixelMap->GetRowStride(),
337 imageInfo.pixelFormat, imageInfo.colorSpace);
338 auxPicture->SetAuxiliaryPictureInfo(auxInfo);
339 }
340
GenerateAuxiliaryPicture(const MainPictureInfo & mainInfo,AuxiliaryPictureType type,const std::string & format,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)341 static std::unique_ptr<AuxiliaryPicture> GenerateAuxiliaryPicture(const MainPictureInfo &mainInfo,
342 AuxiliaryPictureType type, const std::string &format,
343 std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
344 {
345 IMAGE_LOGI("Generate by decoder, type: %{public}d, format: %{public}s", static_cast<int>(type), format.c_str());
346 DecodeContext context;
347 context.allocatorType = AllocatorType::DMA_ALLOC;
348 errorCode = SetAuxiliaryDecodeOption(extDecoder, mainInfo.imageInfo.pixelFormat, context.info, type);
349 if (errorCode != SUCCESS) {
350 IMAGE_LOGE("Set auxiliary decode option failed! errorCode: %{public}u", errorCode);
351 return nullptr;
352 }
353 if (format == IMAGE_HEIF_FORMAT) {
354 #ifdef HEIF_HW_DECODE_ENABLE
355 if (type == AuxiliaryPictureType::LINEAR_MAP || type == AuxiliaryPictureType::DEPTH_MAP) {
356 context.pixelFormat = PixelFormat::RGBA_F16;
357 context.info.pixelFormat = PixelFormat::RGBA_F16;
358 }
359 if (!extDecoder->DecodeHeifAuxiliaryMap(context, type)) {
360 errorCode = ERR_IMAGE_DECODE_FAILED;
361 }
362 #else
363 errorCode = ERR_IMAGE_HW_DECODE_UNSUPPORT;
364 #endif
365 } else if (format == IMAGE_JPEG_FORMAT) {
366 errorCode = extDecoder->Decode(FIRST_FRAME, context);
367 context.hdrType = mainInfo.hdrType;
368 } else {
369 errorCode = ERR_MEDIA_DATA_UNSUPPORT;
370 }
371 if (errorCode != SUCCESS) {
372 IMAGE_LOGE("Decode failed! Format: %{public}s, errorCode: %{public}u", format.c_str(), errorCode);
373 FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer);
374 return nullptr;
375 }
376
377 std::string encodedFormat = ImageUtils::IsAuxiliaryPictureEncoded(type) ? format : "";
378 std::shared_ptr<PixelMap> pixelMap = CreatePixelMapByContext(context, extDecoder, encodedFormat, errorCode);
379 bool cond = pixelMap == nullptr || errorCode != SUCCESS;
380 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "%{public}s CreatePixelMapByContext failed!", __func__);
381 auto auxPicture = AuxiliaryPicture::Create(pixelMap, type, context.outInfo.size);
382 auxPicture->SetAuxiliaryPictureInfo(
383 MakeAuxiliaryPictureInfo(type, context.outInfo.size, pixelMap->GetRowStride(),
384 context.pixelFormat, context.outInfo.colorSpace));
385 return auxPicture;
386 }
387
GenerateHeifAuxiliaryPicture(const MainPictureInfo & mainInfo,AuxiliaryPictureType type,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)388 std::shared_ptr<AuxiliaryPicture> AuxiliaryGenerator::GenerateHeifAuxiliaryPicture(const MainPictureInfo &mainInfo,
389 AuxiliaryPictureType type, std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
390 {
391 IMAGE_LOGI("Generate heif auxiliary picture, type: %{public}d", static_cast<int>(type));
392 if (!ImageUtils::IsAuxiliaryPictureTypeSupported(type) || extDecoder == nullptr) {
393 errorCode = ERR_IMAGE_INVALID_PARAMETER;
394 return nullptr;
395 }
396
397 auto auxPicture = GenerateAuxiliaryPicture(mainInfo, type, IMAGE_HEIF_FORMAT, extDecoder, errorCode);
398 bool cond = (errorCode != SUCCESS);
399 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
400 "Generate heif auxiliary picture failed! errorCode: %{public}u", errorCode);
401 if (type == AuxiliaryPictureType::GAINMAP) {
402 errorCode = DecodeHdrMetadata(mainInfo.hdrType, extDecoder, auxPicture);
403 } else if (type == AuxiliaryPictureType::FRAGMENT_MAP) {
404 errorCode = DecodeHeifFragmentMetadata(extDecoder, auxPicture);
405 }
406 cond = (errorCode != SUCCESS);
407 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "Decode heif metadata failed! errorCode: %{public}u", errorCode);
408 return std::move(auxPicture);
409 }
410
GenerateJpegAuxiliaryPicture(const MainPictureInfo & mainInfo,AuxiliaryPictureType type,std::unique_ptr<InputDataStream> & auxStream,std::unique_ptr<AbsImageDecoder> & extDecoder,uint32_t & errorCode)411 std::shared_ptr<AuxiliaryPicture> AuxiliaryGenerator::GenerateJpegAuxiliaryPicture(
412 const MainPictureInfo &mainInfo, AuxiliaryPictureType type, std::unique_ptr<InputDataStream> &auxStream,
413 std::unique_ptr<AbsImageDecoder> &extDecoder, uint32_t &errorCode)
414 {
415 ImageTrace trace("GenerateJpegAuxiliaryPicture Type:(%d)", static_cast<int>(type));
416 IMAGE_LOGI("Generate jpeg auxiliary picture, type: %{public}d", static_cast<int>(type));
417 if (!ImageUtils::IsAuxiliaryPictureTypeSupported(type) || auxStream == nullptr || extDecoder == nullptr) {
418 errorCode = ERR_IMAGE_INVALID_PARAMETER;
419 return nullptr;
420 }
421
422 if (ImageUtils::IsAuxiliaryPictureEncoded(type)) {
423 auto auxPicture = GenerateAuxiliaryPicture(mainInfo, type, IMAGE_JPEG_FORMAT, extDecoder, errorCode);
424 if (errorCode != SUCCESS) {
425 IMAGE_LOGE("Generate jpeg auxiliary picture failed! errorCode: %{public}u", errorCode);
426 return nullptr;
427 }
428 if (type == AuxiliaryPictureType::GAINMAP) {
429 errorCode = DecodeHdrMetadata(mainInfo.hdrType, extDecoder, auxPicture);
430 } else if (type == AuxiliaryPictureType::FRAGMENT_MAP) {
431 errorCode = DecodeJpegFragmentMetadata(auxStream, auxPicture);
432 }
433 if (errorCode != SUCCESS) {
434 IMAGE_LOGE("Decode jpeg metadata failed! errorCode: %{public}u", errorCode);
435 return nullptr;
436 }
437 return auxPicture;
438 }
439
440 int32_t denominator = GetAuxiliaryPictureDenominator(type);
441 denominator = (denominator == 0) ? DEFAULT_SCALE_DENOMINATOR : denominator;
442 Size size = {mainInfo.imageInfo.size.width / denominator, mainInfo.imageInfo.size.height / denominator};
443 sptr<SurfaceBuffer> surfaceBuffer = AllocSurfaceBuffer(size, GRAPHIC_PIXEL_FMT_RGBA16_FLOAT, errorCode);
444 bool cond = (errorCode != SUCCESS || surfaceBuffer == nullptr);
445 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr, "Alloc surface buffer failed! errorCode: %{public}u", errorCode);
446 errorCode = CopyToSurfaceBuffer(auxStream, surfaceBuffer);
447 cond = (errorCode != SUCCESS);
448 CHECK_ERROR_RETURN_RET_LOG(cond, nullptr,
449 "Convert stream to surface buffer failed! errorCode: %{public}u", errorCode);
450 auto auxPicture = AuxiliaryPicture::Create(surfaceBuffer, type, size);
451 SetUncodedAuxilaryPictureInfo(auxPicture);
452 return auxPicture;
453 }
454
455 } // namespace Media
456 } // namespace OHOS
457