diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index cc802b456448346d85a46cf549c09bb13600eec1..f5377c92d170c5bd62494af20a2bb2be82f2ae11 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -448,10 +448,10 @@ struct AuxiliaryPictureInfo { } union HdrMetadataValue { - metadataType: HdrMetadataType; - staticMetadataArrayBuffer: HdrStaticMetadata; + hdrMetadataType: HdrMetadataType; + hdrStaticMetadata: HdrStaticMetadata; arrayBuffer: @arraybuffer Array; - gainmapMetadata: HdrGainmapMetadata; + hdrGainmapMetadata: HdrGainmapMetadata; } union PropertyValue { @@ -501,6 +501,16 @@ interface PixelMap { @overload("scaleSync") ScaleWithAntiAliasingSync(x: f64, y: f64, level: AntiAliasingLevel): void; + @gen_promise("createScaledPixelMap") + CreateScaledPixelMapSync(x: f64, y: f64, level: Optional): PixelMap; + + @gen_promise("clone") + CloneSync(): PixelMap; + + @gen_async("translate") + @gen_promise("translate") + TranslateSync(x: f64, y: f64): void; + @gen_async("crop") @gen_promise("crop") CropSync(region: Region): void; @@ -540,6 +550,11 @@ interface PixelMap { @gen_promise("unmarshalling") UnmarshallingSync(sequence: @sts_type("rpc.MessageSequence") Opaque): PixelMap; + GetMetadata(key: HdrMetadataKey): HdrMetadataValue; + + @gen_promise("setMetadata") + SetMetadataSync(key: HdrMetadataKey, value: HdrMetadataValue): void; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; @@ -968,14 +983,24 @@ function CreatePixelMapByOptionsSync(options: InitializationOptions): PixelMap; // For legacy ANI backward compatibility function CreatePixelMapByPtr(ptr: i64): PixelMap; +@gen_promise("createPixelMapFromSurface") @overload("createPixelMapFromSurfaceSync") function CreatePixelMapFromSurfaceByIdSync(surfaceId: String): PixelMap; +@gen_promise("createPixelMapFromSurface") @overload("createPixelMapFromSurfaceSync") function CreatePixelMapFromSurfaceByIdAndRegionSync(surfaceId: String, region: Region): PixelMap; function CreatePixelMapFromParcel(sequence: @sts_type("rpc.MessageSequence") Opaque): PixelMap; +@gen_async("createPremultipliedPixelMap") +@gen_promise("createPremultipliedPixelMap") +function CreatePremultipliedPixelMapSync(src: PixelMap, dst: PixelMap): void; + +@gen_async("createUnpremultipliedPixelMap") +@gen_promise("createUnpremultipliedPixelMap") +function CreateUnpremultipliedPixelMapSync(src: PixelMap, dst: PixelMap): void; + @overload("createImageSource") function CreateImageSourceByUri(uri: String): ImageSource; diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index e4b64a83b2406f023de3b72c44ce109552f49129..c2bf708ad2a39a5c04593e7f26463698309f3d2d 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -51,6 +51,9 @@ public: int32_t GetDensity(); void ScaleSync(double x, double y); void ScaleWithAntiAliasingSync(double x, double y, AntiAliasingLevel level); + PixelMap CreateScaledPixelMapSync(double x, double y, optional_view level); + PixelMap CloneSync(); + void TranslateSync(double x, double y); void CropSync(ohos::multimedia::image::image::Region const& region); void RotateSync(double angle); void FlipSync(bool horizontal, bool vertical); @@ -64,6 +67,8 @@ public: PixelMap UnmarshallingSync(uintptr_t sequence); void ToSdrSync(); void ApplyColorSpaceSync(uintptr_t targetColorSpace); + HdrMetadataValue GetMetadata(HdrMetadataKey key); + void SetMetadataSync(HdrMetadataKey key, HdrMetadataValue const& value); void ReleaseSync(); bool GetIsEditable(); bool GetIsStrideAlignment(); diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index cba0ec887ef3d8eba736be471f8fe720b909c295..70fd33ee424751762f46f62d99d35a4d31ffcb9c 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -26,12 +26,19 @@ #include "taihe/runtime.hpp" #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) #include +#include "color_utils.h" #include "pixel_map_from_surface.h" #include "transaction/rs_interfaces.h" +#include "vpe_utils.h" #endif namespace ANI::Image { +constexpr uint32_t METADATA_RED_INDEX = 0; +constexpr uint32_t METADATA_GREEN_INDEX = 1; +constexpr uint32_t METADATA_BLUE_INDEX = 2; +constexpr uint32_t METADATA_CHANNEL_COUNT = 3; + enum class FormatType : int8_t { UNKNOWN, YUV, @@ -179,6 +186,34 @@ PixelMap CreatePixelMapFromParcel(uintptr_t sequence) return Unmarshalling(sequence); } +static void ConvertPixelMapAlphaFormat(weak::PixelMap const& src, weak::PixelMap const& dst, bool isPremul) +{ + PixelMapImpl* rPixelMapImpl = reinterpret_cast(src->GetImplPtr()); + PixelMapImpl* wPixelMapImpl = reinterpret_cast(dst->GetImplPtr()); + if (rPixelMapImpl == nullptr || wPixelMapImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_READ_PIXELMAP_FAILED, "Unwrap PixelMap failed"); + } + + auto rPixelMap = rPixelMapImpl->GetNativePtr(); + auto wPixelMap = wPixelMapImpl->GetNativePtr(); + if (wPixelMap->IsEditable()) { + rPixelMap->ConvertAlphaFormat(*(wPixelMap.get()), isPremul); + } else { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_PIXELMAP_NOT_ALLOW_MODIFY, + "Target PixelMap is not editable"); + } +} + +void CreatePremultipliedPixelMapSync(weak::PixelMap src, weak::PixelMap dst) +{ + ConvertPixelMapAlphaFormat(src, dst, true); +} + +void CreateUnpremultipliedPixelMapSync(weak::PixelMap src, weak::PixelMap dst) +{ + ConvertPixelMapAlphaFormat(src, dst, false); +} + PixelMapImpl::PixelMapImpl() {} PixelMapImpl::PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions) @@ -439,6 +474,64 @@ void PixelMapImpl::ScaleWithAntiAliasingSync(double x, double y, AntiAliasingLev nativePixelMap_->scale(static_cast(x), static_cast(y), Media::AntiAliasingOption(level.get_value())); } +PixelMap PixelMapImpl::CreateScaledPixelMapSync(double x, double y, optional_view level) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Native PixelMap is nullptr"); + return make_holder(); + } + + Media::InitializationOptions opts; + std::unique_ptr clonedPixelMap = Media::PixelMap::Create(*nativePixelMap_, opts); + if (clonedPixelMap == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Clone PixelMap failed"); + return make_holder(); + } + + if (level.has_value()) { + clonedPixelMap->scale(static_cast(x), static_cast(y), + Media::AntiAliasingOption(level.value().get_value())); + } else { + clonedPixelMap->scale(static_cast(x), static_cast(y)); + } + return make_holder(std::move(clonedPixelMap)); +} + +PixelMap PixelMapImpl::CloneSync() { + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INIT_ABNORMAL, "Native PixelMap is nullptr"); + return make_holder(); + } + + int32_t errorCode = Media::SUCCESS; + auto clonedPixelMap = nativePixelMap_->Clone(errorCode); + if (clonedPixelMap == nullptr) { + if (errorCode == Media::ERR_IMAGE_INIT_ABNORMAL) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INIT_ABNORMAL, "Initialize empty PixelMap failed"); + } else if (errorCode == Media::ERR_IMAGE_MALLOC_ABNORMAL) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_MALLOC_ABNORMAL, "Copy PixelMap data failed"); + } else if (errorCode == Media::ERR_IMAGE_DATA_UNSUPPORT) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_DATA_UNSUPPORT, + "PixelMap type does not support clone"); + } else if (errorCode == Media::ERR_IMAGE_TOO_LARGE) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_TOO_LARGE, "PixelMap size (bytes) out of range"); + } else { + ImageTaiheUtils::ThrowExceptionError(errorCode, "Clone PixelMap failed"); + } + return make_holder(); + } + return make_holder(std::move(clonedPixelMap)); +} + +void PixelMapImpl::TranslateSync(double x, double y) { + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INIT_ABNORMAL, "Native PixelMap is nullptr"); + return; + } + + nativePixelMap_->translate(static_cast(x), static_cast(y)); +} + void PixelMapImpl::CropSync(ohos::multimedia::image::image::Region const& region) { if (nativePixelMap_ == nullptr) { @@ -723,6 +816,349 @@ void PixelMapImpl::ApplyColorSpaceSync(uintptr_t targetColorSpace) } } +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) +static std::map EtsMetadataMap = { + {HdrMetadataType::key_t::NONE, HDI::Display::Graphic::Common::V1_0::CM_METADATA_NONE}, + {HdrMetadataType::key_t::BASE, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_DUAL}, + {HdrMetadataType::key_t::GAINMAP, HDI::Display::Graphic::Common::V1_0::CM_METADATA_NONE}, + {HdrMetadataType::key_t::ALTERNATE, HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_SINGLE}, +}; + +static std::map MetadataEtsMap = { + {HDI::Display::Graphic::Common::V1_0::CM_METADATA_NONE, HdrMetadataType::key_t::NONE}, + {HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_DUAL, HdrMetadataType::key_t::BASE}, + {HDI::Display::Graphic::Common::V1_0::CM_IMAGE_HDR_VIVID_SINGLE, HdrMetadataType::key_t::ALTERNATE}, +}; + +static HdrStaticMetadata BuildHdrStaticMetadata( + HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata const& srcStaticMetadata) +{ + HdrStaticMetadata dstMetadata{}; + dstMetadata.displayPrimariesX = { + srcStaticMetadata.smpte2086.displayPrimaryRed.x, + srcStaticMetadata.smpte2086.displayPrimaryGreen.x, + srcStaticMetadata.smpte2086.displayPrimaryBlue.x + }; + dstMetadata.displayPrimariesY = { + srcStaticMetadata.smpte2086.displayPrimaryRed.y, + srcStaticMetadata.smpte2086.displayPrimaryGreen.y, + srcStaticMetadata.smpte2086.displayPrimaryBlue.y + }; + dstMetadata.whitePointX = srcStaticMetadata.smpte2086.whitePoint.x; + dstMetadata.whitePointY = srcStaticMetadata.smpte2086.whitePoint.y; + dstMetadata.maxLuminance = srcStaticMetadata.smpte2086.maxLuminance; + dstMetadata.minLuminance = srcStaticMetadata.smpte2086.minLuminance; + dstMetadata.maxContentLightLevel = srcStaticMetadata.cta861.maxContentLightLevel; + dstMetadata.maxFrameAverageLightLevel = srcStaticMetadata.cta861.maxFrameAverageLightLevel; + return dstMetadata; +} + +static HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata ParseHdrStaticMetadata( + HdrStaticMetadata const& srcStaticMetadata) +{ + HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata dstMetadata{}; + dstMetadata.smpte2086.displayPrimaryRed.x = srcStaticMetadata.displayPrimariesX[METADATA_RED_INDEX]; + dstMetadata.smpte2086.displayPrimaryGreen.x = srcStaticMetadata.displayPrimariesX[METADATA_GREEN_INDEX]; + dstMetadata.smpte2086.displayPrimaryBlue.x = srcStaticMetadata.displayPrimariesX[METADATA_BLUE_INDEX]; + dstMetadata.smpte2086.displayPrimaryRed.y = srcStaticMetadata.displayPrimariesY[METADATA_RED_INDEX]; + dstMetadata.smpte2086.displayPrimaryGreen.y = srcStaticMetadata.displayPrimariesY[METADATA_GREEN_INDEX]; + dstMetadata.smpte2086.displayPrimaryBlue.y = srcStaticMetadata.displayPrimariesY[METADATA_BLUE_INDEX]; + dstMetadata.smpte2086.whitePoint.x = srcStaticMetadata.whitePointX; + dstMetadata.smpte2086.whitePoint.y = srcStaticMetadata.whitePointY; + dstMetadata.smpte2086.maxLuminance = srcStaticMetadata.maxLuminance; + dstMetadata.smpte2086.minLuminance = srcStaticMetadata.minLuminance; + dstMetadata.cta861.maxContentLightLevel = srcStaticMetadata.maxContentLightLevel; + dstMetadata.cta861.maxFrameAverageLightLevel = srcStaticMetadata.maxFrameAverageLightLevel; + return dstMetadata; +} + +static HdrGainmapMetadata BuildHdrGainmapMetadata(Media::HDRVividExtendMetadata const& srcGainmapMetadata) +{ + HdrGainmapMetadata dstMetadata{}; + dstMetadata.writerVersion = static_cast(srcGainmapMetadata.metaISO.writeVersion); + dstMetadata.miniVersion = static_cast(srcGainmapMetadata.metaISO.miniVersion); + dstMetadata.gainmapChannelCount = static_cast(srcGainmapMetadata.metaISO.gainmapChannelNum); + dstMetadata.useBaseColorFlag = static_cast(srcGainmapMetadata.metaISO.useBaseColorFlag); + dstMetadata.baseHeadroom = srcGainmapMetadata.metaISO.baseHeadroom; + dstMetadata.alternateHeadroom = srcGainmapMetadata.metaISO.alternateHeadroom; + dstMetadata.channels = array::make(METADATA_CHANNEL_COUNT); + for (uint32_t i = 0; i < METADATA_CHANNEL_COUNT; ++i) { + dstMetadata.channels[i] = { + srcGainmapMetadata.metaISO.enhanceClippedThreholdMaxGainmap[i], + srcGainmapMetadata.metaISO.enhanceClippedThreholdMinGainmap[i], + srcGainmapMetadata.metaISO.enhanceMappingGamma[i], + srcGainmapMetadata.metaISO.enhanceMappingBaselineOffset[i], + srcGainmapMetadata.metaISO.enhanceMappingAlternateOffset[i] + }; + } + return dstMetadata; +} + +static void ParseHdrGainmapMetadata(HdrGainmapMetadata const& srcGainmapMetadata, + Media::HDRVividExtendMetadata &dstMetadata) +{ + dstMetadata.metaISO.writeVersion = static_cast(srcGainmapMetadata.writerVersion); + dstMetadata.metaISO.miniVersion = static_cast(srcGainmapMetadata.miniVersion); + dstMetadata.metaISO.gainmapChannelNum = static_cast(srcGainmapMetadata.gainmapChannelCount); + dstMetadata.metaISO.useBaseColorFlag = static_cast(srcGainmapMetadata.useBaseColorFlag); + dstMetadata.metaISO.baseHeadroom = srcGainmapMetadata.baseHeadroom; + dstMetadata.metaISO.alternateHeadroom = srcGainmapMetadata.alternateHeadroom; + for (uint32_t i = 0; i < METADATA_CHANNEL_COUNT; ++i) { + dstMetadata.metaISO.enhanceClippedThreholdMaxGainmap[i] = srcGainmapMetadata.channels[i].gainmapMax; + dstMetadata.metaISO.enhanceClippedThreholdMinGainmap[i] = srcGainmapMetadata.channels[i].gainmapMin; + dstMetadata.metaISO.enhanceMappingGamma[i] = srcGainmapMetadata.channels[i].gamma; + dstMetadata.metaISO.enhanceMappingBaselineOffset[i] = srcGainmapMetadata.channels[i].baseOffset; + dstMetadata.metaISO.enhanceMappingAlternateOffset[i] = srcGainmapMetadata.channels[i].alternateOffset; + } +} + +static bool GetMetadataType(sptr const& surfaceBuffer, HdrMetadataValue &metadataValue) +{ + HDI::Display::Graphic::Common::V1_0::CM_HDR_Metadata_Type type; + Media::VpeUtils::GetSbMetadataType(surfaceBuffer, type); + if (MetadataEtsMap.find(type) != MetadataEtsMap.end()) { + std::vector gainmapDataVec; + if (type == HDI::Display::Graphic::Common::V1_0::CM_HDR_Metadata_Type::CM_METADATA_NONE && + Media::VpeUtils::GetSbDynamicMetadata(surfaceBuffer, gainmapDataVec) && + gainmapDataVec.size() == sizeof(Media::HDRVividExtendMetadata)) { + metadataValue = HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::GAINMAP); + } else { + metadataValue = HdrMetadataValue::make_hdrMetadataType(MetadataEtsMap[type]); + } + return true; + } else { + IMAGE_LOGE("[%{public}s] GetMetadataType failed", __func__); + return false; + } +} + +static bool SetMetadataType(sptr &surfaceBuffer, HdrMetadataValue const& metadataValue) +{ + if (!metadataValue.holds_hdrMetadataType()) { + IMAGE_LOGE("[%{public}s] Key and value types are inconsistent", __func__); + return false; + } + + HdrMetadataType metadataType = metadataValue.get_hdrMetadataType_ref(); + if (EtsMetadataMap.find(metadataType.get_key()) != EtsMetadataMap.end()) { + Media::VpeUtils::SetSbMetadataType(surfaceBuffer, EtsMetadataMap[metadataType.get_key()]); + return true; + } else { + IMAGE_LOGE("[%{public}s] SetMetadataType failed", __func__); + return false; + } +} + +static bool GetStaticMetadata(sptr const& surfaceBuffer, HdrMetadataValue &metadataValue) +{ + HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata staticMetadata; + uint32_t vecSize = sizeof(HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata); + std::vector staticDataVec; + if (!Media::VpeUtils::GetSbStaticMetadata(surfaceBuffer, staticDataVec) || staticDataVec.size() != vecSize) { + IMAGE_LOGE("[%{public}s] GetSbStaticMetadata failed", __func__); + return false; + } + if (memcpy_s(&staticMetadata, vecSize, staticDataVec.data(), staticDataVec.size()) != EOK) { + IMAGE_LOGE("[%{public}s] memcpy failed", __func__); + return false; + } + metadataValue = HdrMetadataValue::make_hdrStaticMetadata(BuildHdrStaticMetadata(staticMetadata)); + return true; +} + +static bool SetStaticMetadata(sptr &surfaceBuffer, HdrMetadataValue const& metadataValue) +{ + if (!metadataValue.holds_hdrStaticMetadata()) { + IMAGE_LOGE("[%{public}s] Key and value types are inconsistent", __func__); + return false; + } + + auto staticMetadata = ParseHdrStaticMetadata(metadataValue.get_hdrStaticMetadata_ref()); + uint32_t vecSize = sizeof(HDI::Display::Graphic::Common::V1_0::HdrStaticMetadata); + std::vector staticDataVec(vecSize); + if (memcpy_s(staticDataVec.data(), vecSize, &staticMetadata, vecSize) != EOK) { + IMAGE_LOGE("[%{public}s] memcpy failed", __func__); + return false; + } + if (!Media::VpeUtils::SetSbStaticMetadata(surfaceBuffer, staticDataVec)) { + IMAGE_LOGE("[%{public}s] SetSbStaticMetadata failed", __func__); + return false; + } + return true; +} + +static bool GetDynamicMetadata(sptr const& surfaceBuffer, HdrMetadataValue &metadataValue) +{ + std::vector dynamicDataVec; + if (Media::VpeUtils::GetSbDynamicMetadata(surfaceBuffer, dynamicDataVec) && dynamicDataVec.size() > 0) { + array dataArr(dynamicDataVec); + metadataValue = HdrMetadataValue::make_arrayBuffer(dataArr); + return true; + } else { + IMAGE_LOGE("[%{public}s] GetSbDynamicMetadata failed", __func__); + return false; + } +} + +static bool SetDynamicMetadata(sptr &surfaceBuffer, HdrMetadataValue const& metadataValue) +{ + if (!metadataValue.holds_arrayBuffer()) { + IMAGE_LOGE("[%{public}s] Key and value types are inconsistent", __func__); + return false; + } + + std::vector dynamicDataVec; + array metadataArr = metadataValue.get_arrayBuffer_ref(); + dynamicDataVec.resize(metadataArr.size()); + if (memcpy_s(dynamicDataVec.data(), dynamicDataVec.size(), metadataArr.data(), metadataArr.size()) != EOK) { + IMAGE_LOGE("[%{public}s] memcpy failed", __func__); + return false; + } + if (!Media::VpeUtils::SetSbDynamicMetadata(surfaceBuffer, dynamicDataVec)) { + IMAGE_LOGE("[%{public}s] SetSbDynamicMetadata failed", __func__); + return false; + } + return true; +} + +static bool GetGainmapMetadata(sptr const& surfaceBuffer, HdrMetadataValue &metadataValue) +{ + std::vector gainmapDataVec; + if (Media::VpeUtils::GetSbDynamicMetadata(surfaceBuffer, gainmapDataVec) && + gainmapDataVec.size() == sizeof(Media::HDRVividExtendMetadata)) { + Media::HDRVividExtendMetadata &gainmapMetadata = + *(reinterpret_cast(gainmapDataVec.data())); + metadataValue = HdrMetadataValue::make_hdrGainmapMetadata(BuildHdrGainmapMetadata(gainmapMetadata)); + return true; + } else { + IMAGE_LOGE("[%{public}s] GetSbDynamicMetadata failed", __func__); + return false; + } +} + +static bool SetGainmapMetadata(sptr &surfaceBuffer, Media::PixelMap &pixelMap, + HdrMetadataValue const& metadataValue) +{ + if (!metadataValue.holds_hdrGainmapMetadata()) { + IMAGE_LOGE("[%{public}s] Key and value types are inconsistent", __func__); + return false; + } + + uint32_t vecSize = sizeof(Media::HDRVividExtendMetadata); + std::vector gainmapDataVec(vecSize); + Media::HDRVividExtendMetadata extendMetadata; +#ifdef IMAGE_COLORSPACE_FLAG + ColorManager::ColorSpace colorSpace = pixelMap.InnerGetGrColorSpace(); + uint16_t SS = Media::ColorUtils::GetPrimaries(colorSpace.GetColorSpaceName()); +#else + uint16_t SS = 0; +#endif + extendMetadata.baseColorMeta.baseColorPrimary = SS; + + HdrGainmapMetadata gainmapMetadata = metadataValue.get_hdrGainmapMetadata_ref(); + extendMetadata.gainmapColorMeta.combineColorPrimary = + gainmapMetadata.useBaseColorFlag ? SS : static_cast(Media::CM_BT2020_HLG_FULL); + extendMetadata.gainmapColorMeta.enhanceDataColorModel = + gainmapMetadata.useBaseColorFlag ? SS : static_cast(Media::CM_BT2020_HLG_FULL); + extendMetadata.gainmapColorMeta.alternateColorPrimary = static_cast(Media::CM_BT2020_HLG_FULL); + + ParseHdrGainmapMetadata(gainmapMetadata, extendMetadata); + + if (memcpy_s(gainmapDataVec.data(), vecSize, &extendMetadata, vecSize) != EOK) { + IMAGE_LOGE("[%{public}s] memcpy failed", __func__); + return false; + } + if (!Media::VpeUtils::SetSbDynamicMetadata(surfaceBuffer, gainmapDataVec)) { + IMAGE_LOGE("[%{public}s] SetSbDynamicMetadata failed", __func__); + return false; + } + return true; +} + +HdrMetadataValue PixelMapImpl::GetMetadata(HdrMetadataKey key) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Native PixelMap is nullptr"); + return HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::NONE); + } + if (nativePixelMap_->GetAllocatorType() != Media::AllocatorType::DMA_ALLOC) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_DMA_NOT_EXIST, "PixelMap memory type is not DMA memory"); + return HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::NONE); + } + + bool success = false; + HdrMetadataValue metadataValue = HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::NONE); + sptr surfaceBuffer(reinterpret_cast(nativePixelMap_->GetFd())); + switch (key.get_key()) { + case HdrMetadataKey::key_t::HDR_METADATA_TYPE: + success = GetMetadataType(surfaceBuffer, metadataValue); + break; + case HdrMetadataKey::key_t::HDR_STATIC_METADATA: + success = GetStaticMetadata(surfaceBuffer, metadataValue); + break; + case HdrMetadataKey::key_t::HDR_DYNAMIC_METADATA: + success = GetDynamicMetadata(surfaceBuffer, metadataValue); + break; + case HdrMetadataKey::key_t::HDR_GAINMAP_METADATA: + success = GetGainmapMetadata(surfaceBuffer, metadataValue); + break; + default: + success = false; + } + + if (!success) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEMORY_COPY_FAILED, "Get metadata failed"); + return HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::NONE); + } + return metadataValue; +} + +void PixelMapImpl::SetMetadataSync(HdrMetadataKey key, HdrMetadataValue const& value) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INVALID_PARAMETER, "Native PixelMap is nullptr"); + return; + } + if (nativePixelMap_->GetAllocatorType() != Media::AllocatorType::DMA_ALLOC) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_DMA_NOT_EXIST, "PixelMap memory type is not DMA memory"); + return; + } + + bool success = false; + sptr surfaceBuffer(reinterpret_cast(nativePixelMap_->GetFd())); + switch (key.get_key()) { + case HdrMetadataKey::key_t::HDR_METADATA_TYPE: + success = SetMetadataType(surfaceBuffer, value); + break; + case HdrMetadataKey::key_t::HDR_STATIC_METADATA: + success = SetStaticMetadata(surfaceBuffer, value); + break; + case HdrMetadataKey::key_t::HDR_DYNAMIC_METADATA: + success = SetDynamicMetadata(surfaceBuffer, value); + break; + case HdrMetadataKey::key_t::HDR_GAINMAP_METADATA: + success = SetGainmapMetadata(surfaceBuffer, *(nativePixelMap_.get()), value); + break; + default: + success = false; + } + + if (!success) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEMORY_COPY_FAILED, "Set metadata failed"); + } +} +#else +HdrMetadataValue PixelMapImpl::GetMetadata(HdrMetadataKey key) +{ + return HdrMetadataValue::make_hdrMetadataType(HdrMetadataType::key_t::NONE); +} + +void PixelMapImpl::SetMetadataSync(HdrMetadataKey key, HdrMetadataValue const& value) +{ + return; +} +#endif + void PixelMapImpl::ReleaseSync() { if (nativePixelMap_ != nullptr) { @@ -819,4 +1255,6 @@ TH_EXPORT_CPP_API_CreatePixelMapByOptionsSync(ANI::Image::CreatePixelMapByOption TH_EXPORT_CPP_API_CreatePixelMapByPtr(ANI::Image::CreatePixelMapByPtr); TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdSync(ANI::Image::CreatePixelMapFromSurfaceByIdSync); TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdAndRegionSync(ANI::Image::CreatePixelMapFromSurfaceByIdAndRegionSync); -TH_EXPORT_CPP_API_CreatePixelMapFromParcel(ANI::Image::CreatePixelMapFromParcel); \ No newline at end of file +TH_EXPORT_CPP_API_CreatePixelMapFromParcel(ANI::Image::CreatePixelMapFromParcel); +TH_EXPORT_CPP_API_CreatePremultipliedPixelMapSync(ANI::Image::CreatePremultipliedPixelMapSync); +TH_EXPORT_CPP_API_CreateUnpremultipliedPixelMapSync(ANI::Image::CreateUnpremultipliedPixelMapSync); \ No newline at end of file