/*
 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "camera_metadata_info.h"
#include <securec.h>
#include "metadata_log.h"
#include <dlfcn.h>
#include <memory>
#include <vector>
#include <map>
#include "camera_metadata_item_info.h"
#include "camera_vendor_tag.h"

namespace OHOS::Camera {
static CameraVendorTag* g_vendorTagImpl = nullptr;
const char* g_exampleVendorTagLib = "libcamera_example_vendor_tag_impl.z.so";
const char* g_vendorTagLib = "libcamera_vendor_tag_impl.z.so";
const int METADATA_HEADER_DATA_SIZE = 4;
const uint32_t itemLen = sizeof(camera_metadata_item_entry_t);
const std::vector<uint32_t> g_metadataTags = {
    OHOS_ABILITY_CAMERA_POSITION,
    OHOS_ABILITY_CAMERA_TYPE,
    OHOS_ABILITY_CAMERA_CONNECTION_TYPE,
    OHOS_ABILITY_MEMORY_TYPE,
    OHOS_ABILITY_FPS_RANGES,
    OHOS_ABILITY_FLASH_AVAILABLE,
    OHOS_CAMERA_STREAM_ID,
    OHOS_ABILITY_PRELAUNCH_AVAILABLE,
    OHOS_ABILITY_CUSTOM_VIDEO_FPS,
    OHOS_ABILITY_CAMERA_MODES,
    OHOS_ABILITY_SKETCH_ENABLE_RATIO,
    OHOS_ABILITY_SKETCH_REFERENCE_FOV_RATIO,
    OHOS_ABILITY_CAMERA_FOLDSCREEN_TYPE,
    OHOS_ABILITY_AVAILABLE_COLOR_SPACES,
    OHOS_ABILITY_NIGHT_MODE_SUPPORTED_EXPOSURE_TIME,
    OHOS_CAMERA_MESURE_EXPOSURE_TIME,
    OHOS_CAMERA_EXPOSURE_MODE_PREVIEW_STATE,
    OHOS_CAMERA_USER_ID,
    OHOS_ABILITY_MOON_CAPTURE_BOOST,
    OHOS_CONTROL_MOON_CAPTURE_BOOST,
    OHOS_STATUS_MOON_CAPTURE_DETECTION,
    OHOS_ABILITY_CAPTURE_DURATION_SUPPORTED,
    OHOS_CAMERA_CUSTOM_SNAPSHOT_DURATION,
    OHOS_ABILITY_MOVING_PHOTO,
    OHOS_ABILITY_FLASH_SUGGESTION_SUPPORTED,
    OHOS_CONTROL_FLASH_SUGGESTION_SWITCH,
    OHOS_STATUS_FLASH_SUGGESTION,
    OHOS_ABILITY_HIGH_QUALITY_SUPPORT,
    OHOS_ABILITY_CAMERA_FOLD_STATUS,
    OHOS_STATUS_CAMERA_OCCLUSION_DETECTION,
    OHOS_ABILITY_STATISTICS_DETECT_TYPE,
    OHOS_CONTROL_STATISTICS_DETECT_SETTING,
    OHOS_ABILITY_AVAILABLE_EXTENDED_STREAM_INFO_TYPES,
    OHOS_ABILITY_AUTO_DEFERRED_VIDEO_ENHANCE,
    OHOS_CONTROL_AUTO_DEFERRED_VIDEO_ENHANCE,
    OHOS_ABILITY_AUTO_CLOUD_IMAGE_ENHANCE,
    OHOS_CONTROL_AUTO_CLOUD_IMAGE_ENHANCE,
    OHOS_ABILITY_TRIPOD_DETECTION,
    OHOS_CONTROL_TRIPOD_DETECTION,
    OHOS_CONTROL_TRIPOD_STABLITATION,
    OHOS_STATUS_TRIPOD_DETECTION_STATUS,
    OHOS_STATUS_SKETCH_POINT,
    OHOS_ABILITY_LOW_LIGHT_BOOST,
    OHOS_CONTROL_LOW_LIGHT_DETECT,
    OHOS_CONTROL_LOW_LIGHT_BOOST,
    OHOS_STATUS_LOW_LIGHT_DETECTION,
    OHOS_STATUS_CAMERA_LENS_DIRTY_DETECTION,
    OHOS_DEVICE_PROTECTION_STATE,

    OHOS_SENSOR_EXPOSURE_TIME,
    OHOS_SENSOR_COLOR_CORRECTION_GAINS,
    OHOS_SENSOR_ORIENTATION,
    OHOS_ABILITY_MUTE_MODES,
    OHOS_CONTROL_MUTE_MODE,

    OHOS_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
    OHOS_SENSOR_INFO_SENSITIVITY_RANGE,
    OHOS_SENSOR_INFO_MAX_FRAME_DURATION,
    OHOS_SENSOR_INFO_PHYSICAL_SIZE,
    OHOS_SENSOR_INFO_PIXEL_ARRAY_SIZE,
    OHOS_SENSOR_INFO_TIMESTAMP,

    OHOS_STATISTICS_FACE_DETECT_MODE,
    OHOS_STATISTICS_FACE_DETECT_SWITCH,
    OHOS_STATISTICS_FACE_DETECT_MAX_NUM,
    OHOS_STATISTICS_HISTOGRAM_MODE,
    OHOS_STATISTICS_FACE_IDS,
    OHOS_STATISTICS_FACE_LANDMARKS,
    OHOS_STATISTICS_FACE_RECTANGLES,
    OHOS_STATISTICS_FACE_SCORES,
    OHOS_STATISTICS_DETECT_HUMAN_FACE_INFOS,
    OHOS_STATISTICS_DETECT_HUMAN_BODY_INFOS,
    OHOS_STATISTICS_DETECT_CAT_FACE_INFOS,
    OHOS_STATISTICS_DETECT_CAT_BODY_INFOS,
    OHOS_STATISTICS_DETECT_DOG_FACE_INFOS,
    OHOS_STATISTICS_DETECT_DOG_BODY_INFOS,
    OHOS_STATISTICS_DETECT_SALIENT_INFOS,
    OHOS_STATISTICS_DETECT_BAR_CODE_INFOS,
    OHOS_STATISTICS_DETECT_BASE_FACE_INFO,

    OHOS_CONTROL_AE_ANTIBANDING_MODE,
    OHOS_CONTROL_AE_EXPOSURE_COMPENSATION,
    OHOS_CONTROL_AE_LOCK,
    OHOS_CONTROL_AE_MODE,
    OHOS_CONTROL_AE_REGIONS,
    OHOS_CONTROL_AE_TARGET_FPS_RANGE,
    OHOS_CONTROL_FPS_RANGES,
    OHOS_CONTROL_AF_MODE,
    OHOS_CONTROL_AF_REGIONS,
    OHOS_CONTROL_AF_TRIGGER,
    OHOS_CONTROL_AF_TRIGGER_ID,
    OHOS_CONTROL_AF_STATE,
    OHOS_CONTROL_AWB_LOCK,
    OHOS_CONTROL_AWB_MODE,
    OHOS_CONTROL_AWB_REGIONS,
    OHOS_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES,
    OHOS_CONTROL_AE_AVAILABLE_MODES,
    OHOS_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
    OHOS_CONTROL_AE_COMPENSATION_RANGE,
    OHOS_CONTROL_AE_COMPENSATION_STEP,
    OHOS_ABILITY_AE_COMPENSATION_RANGE,
    OHOS_ABILITY_AE_COMPENSATION_STEP,
    OHOS_CONTROL_AF_AVAILABLE_MODES,
    OHOS_CONTROL_AWB_AVAILABLE_MODES,
    OHOS_CONTROL_CAPTURE_MIRROR_SUPPORTED,
    OHOS_CONTROL_CAPTURE_MIRROR,
    OHOS_CONTROL_FOCUS_STATE,
    OHOS_CONTROL_METER_POINT,
    OHOS_CONTROL_METER_MODE,
    OHOS_CONTROL_EXPOSURE_STATE,
    OHOS_CONTROL_FOCUSED_POINT,
    OHOS_CONTROL_NIGHT_MODE_TRY_AE,
    OHOS_CONTROL_MANUAL_EXPOSURE_TIME,
    OHOS_STATUS_CAMERA_CURRENT_FPS,
    OHOS_ABILITY_ISO_VALUES,
    OHOS_CONTROL_ISO_VALUE,
    OHOS_STATUS_ISO_VALUE,
    OHOS_ABILITY_SENSOR_EXPOSURE_TIME_RANGE,
    OHOS_CONTROL_SENSOR_EXPOSURE_TIME,
    OHOS_STATUS_SENSOR_EXPOSURE_TIME,
    OHOS_CONTROL_MOVING_PHOTO,
    OHOS_ABILITY_SENSOR_WB_VALUES,
    OHOS_CONTROL_SENSOR_WB_VALUE,
    OHOS_CONTROL_HIGH_QUALITY_MODE,
    OHOS_CONTROL_BURST_CAPTURE,
    OHOS_CONTROL_CAMERA_USED_AS_POSITION,
    OHOS_CONTROL_CAMERA_SESSION_USAGE,
    OHOS_CONTROL_EJECT_RETRY,
    OHOS_CONTROL_FALL_PROTECTION,
    OHOS_CONTROL_QUALITY_PRIORITIZATION,

    // Camera device image acquisition related
    OHOS_ABILITY_DEVICE_AVAILABLE_EXPOSUREMODES,
    OHOS_CONTROL_EXPOSUREMODE,
    OHOS_ABILITY_EXPOSURE_MODES,
    OHOS_CONTROL_EXPOSURE_MODE,
    OHOS_ABILITY_METER_MODES,
    OHOS_ABILITY_SCENE_EXPOSURE_MODES,
    OHOS_ABILITY_EXPOSURE_TIME,
    OHOS_ABILITY_AE_LOCK,

    OHOS_ABILITY_DEVICE_AVAILABLE_FOCUSMODES,
    OHOS_CONTROL_FOCUSMODE,
    OHOS_ABILITY_FOCUS_MODES,
    OHOS_CONTROL_FOCUS_MODE,
    OHOS_ABILITY_FOCAL_LENGTH,
    OHOS_ABILITY_SCENE_FOCUS_MODES,
    OHOS_ABILITY_FOCUS_ASSIST_FLASH_SUPPORTED_MODES,
    OHOS_CONTROL_FOCUS_ASSIST_FLASH_SUPPORTED_MODE,
    OHOS_ABILITY_LENS_INFO_MINIMUM_FOCUS_DISTANCE,
    OHOS_CONTROL_LENS_FOCUS_DISTANCE,
    OHOS_ABILITY_EQUIVALENT_FOCUS,
    OHOS_CONTROL_FOCUS_DISTANCE,

    OHOS_ABILITY_DEVICE_AVAILABLE_AWBMODES,
    OHOS_ABILITY_AWB_MODES,
    OHOS_ABILITY_AWB_LOCK,
    OHOS_ABILITY_DEVICE_AVAILABLE_FLASHMODES,
    OHOS_CONTROL_FLASHMODE,
    OHOS_ABILITY_FLASH_MODES,
    OHOS_CONTROL_FLASH_MODE,
    OHOS_CONTROL_FLASH_STATE,
    OHOS_ABILITY_SCENE_FLASH_MODES,

    OHOS_ABILITY_ZOOM_RATIO_RANGE,
    OHOS_CONTROL_ZOOM_RATIO,
    OHOS_CONTROL_ZOOM_CROP_REGION,
    OHOS_ABILITY_ZOOM_CAP,
    OHOS_ABILITY_SCENE_ZOOM_CAP,
    OHOS_STATUS_CAMERA_CURRENT_ZOOM_RATIO,
    OHOS_CONTROL_SMOOTH_ZOOM_RATIOS,
    OHOS_CONTROL_PREPARE_ZOOM,
    OHOS_ABILITY_CAMERA_ZOOM_PERFORMANCE,

    // Camera flow control related
    OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS,
    OHOS_STREAM_AVAILABLE_FORMATS,
    OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS,
    OHOS_ABILITY_STREAM_QUICK_THUMBNAIL_AVAILABLE,
    OHOS_ABILITY_PORTRAIT_RESOLUSION,
    OHOS_ABILITY_SCENE_STREAM_QUICK_THUMBNAIL_AVAILABLE,
    OHOS_ABILITY_DEFERRED_IMAGE_DELIVERY,
    OHOS_CONTROL_DEFERRED_IMAGE_DELIVERY,

    OHOS_JPEG_GPS_COORDINATES,
    OHOS_JPEG_GPS_PROCESSING_METHOD,
    OHOS_JPEG_GPS_TIMESTAMP,
    OHOS_JPEG_ORIENTATION,
    OHOS_JPEG_QUALITY,
    OHOS_JPEG_THUMBNAIL_QUALITY,
    OHOS_JPEG_THUMBNAIL_SIZE,
    OHOS_JPEG_AVAILABLE_THUMBNAIL_SIZES,
    OHOS_JPEG_MAX_SIZE,
    OHOS_JPEG_SIZE,

    OHOS_ABILITY_VIDEO_STABILIZATION_MODES,
    OHOS_CONTROL_VIDEO_STABILIZATION_MODE,
    OHOS_CONTROL_VIDEO_DEBUG_SWITCH,

    // camera effects & algorithms
    OHOS_ABILITY_SCENE_FILTER_TYPES,
    OHOS_CONTROL_FILTER_TYPE,
    OHOS_ABILITY_SCENE_PORTRAIT_EFFECT_TYPES,
    OHOS_CONTROL_PORTRAIT_EFFECT_TYPE,
    OHOS_ABILITY_SCENE_BEAUTY_TYPES,
    OHOS_CONTROL_BEAUTY_TYPE,
    OHOS_ABILITY_BEAUTY_AUTO_VALUES,
    OHOS_CONTROL_BEAUTY_AUTO_VALUE,
    OHOS_ABILITY_BEAUTY_FACE_SLENDER_VALUES,
    OHOS_CONTROL_BEAUTY_FACE_SLENDER_VALUE,
    OHOS_ABILITY_BEAUTY_SKIN_TONE_VALUES,
    OHOS_CONTROL_BEAUTY_SKIN_TONE_VALUE,
    OHOS_ABILITY_BEAUTY_SKIN_SMOOTH_VALUES,
    OHOS_CONTROL_BEAUTY_SKIN_SMOOTH_VALUE,
    OHOS_ABILITY_CAMERA_MACRO_SUPPORTED,
    OHOS_ABILITY_SCENE_MACRO_CAP,
    OHOS_CAMERA_MACRO_STATUS,
    OHOS_CONTROL_CAMERA_MACRO,
    OHOS_ABILITY_CAMERA_VIRTUAL_APERTURE_RANGE,
    OHOS_CONTROL_CAMERA_VIRTUAL_APERTURE_VALUE,
    OHOS_ABILITY_CAMERA_PHYSICAL_APERTURE_RANGE,
    OHOS_CONTROL_CAMERA_PHYSICAL_APERTURE_VALUE,
    OHOS_STATUS_CAMERA_APERTURE_VALUE,
    OHOS_DEVICE_EXITCAMERA_EVENT,
    OHOS_CONTROL_MOTION_DETECTION_CHECK_AREA,
    OHOS_STATUS_SLOW_MOTION_DETECTION,
    OHOS_ABILITY_MOTION_DETECTION_SUPPORT,
    OHOS_CONTROL_MOTION_DETECTION,
    OHOS_ABILITY_EXPOSURE_HINT_SUPPORTED,
    OHOS_CONTROL_EXPOSURE_HINT_MODE,
    OHOS_STATUS_ALGO_MEAN_Y,
    OHOS_STATUS_PREVIEW_PHYSICAL_CAMERA_ID,
    OHOS_ABILITY_CAPTURE_EXPECT_TIME,
    OHOS_ABILITY_EFFECT_SUGGESTION_SUPPORTED,
    OHOS_CONTROL_EFFECT_SUGGESTION,
    OHOS_CONTROL_EFFECT_SUGGESTION_DETECTION,
    OHOS_CAMERA_EFFECT_SUGGESTION_TYPE,
    OHOS_CONTROL_EFFECT_SUGGESTION_TYPE,
    OHOS_ABILITY_AVAILABLE_PROFILE_LEVEL,
    OHOS_ABILITY_AVAILABLE_PREVIEW_PROFILE,
    OHOS_ABILITY_AVAILABLE_PHOTO_PROFILE,
    OHOS_ABILITY_AVAILABLE_VIDEO_PROFILE,
    OHOS_ABILITY_AVAILABLE_METADATA_PROFILE,
    OHOS_ABILITY_AVAILABLE_CONFIGURATIONS,
    OHOS_ABILITY_CONFLICT_CONFIGURATIONS,
    OHOS_ABILITY_LIGHT_PAINTING_TYPE,
    OHOS_CONTROL_LIGHT_PAINTING_TYPE,
    OHOS_CONTROL_LIGHT_PAINTING_FLASH,
    OHOS_CONTROL_TIME_LAPSE_INTERVAL,
    OHOS_CONTROL_TIME_LAPSE_TRYAE_STATE,
    OHOS_STATUS_TIME_LAPSE_PREVIEW_TYPE,
    OHOS_STATUS_TIME_LAPSE_TRYAE_HINT,
    OHOS_STATUS_TIME_LAPSE_CAPTURE_INTERVAL,
    OHOS_STATUS_TIME_LAPSE_TRYAE_DONE,
    OHOS_CONTROL_TIME_LAPSE_RECORD_STATE,
    OHOS_CONTROL_TIME_LAPSE_PREVIEW_TYPE,
    OHOS_ABILITY_TIME_LAPSE_INTERVAL_RANGE,
    OHOS_ABILITY_LCD_FLASH,
    OHOS_CONTROL_LCD_FLASH_DETECTION,
    OHOS_CONTROL_LCD_FLASH,
    OHOS_STATUS_LCD_FLASH_STATUS,
    OHOS_ABILITY_DEPTH_DATA_DELIVERY,
    OHOS_CONTROL_DEPTH_DATA_DELIVERY_SWITCH,
    OHOS_ABILITY_DEPTH_DATA_PROFILES,
    OHOS_CONTROL_DEPTH_DATA_ACCURACY,
    OHOS_ABILITY_CAPTURE_MACRO_DEPTH_FUSION_SUPPORTED,
    OHOS_ABILITY_CAPTURE_MACRO_DEPTH_FUSION_ZOOM_RANGE,
    OHOS_CONTROL_CAPTURE_MACRO_DEPTH_FUSION,
    OHOS_ABILITY_CAMERA_PORTRAIT_THEME_SUPPORTED,
    OHOS_ABILITY_CAMERA_PORTRAIT_THEME_TYPES,
    OHOS_CONTROL_CAMERA_PORTRAIT_THEME_TYPE,
    OHOS_ABILITY_CAMERA_VIDEO_ROTATION_SUPPORTED,
    OHOS_ABILITY_CAMERA_VIDEO_ROTATION,
    OHOS_CONTROL_CAMERA_VIDEO_ROTATION,
    OHOS_MOVING_PHOTO_BUFFER_DURATION,
    OHOS_MOVING_PHOTO_START,
    OHOS_MOVING_PHOTO_END,

    // camera secure related
    OHOS_CONTROL_SECURE_FACE_MODE,
    OHOS_CONTROL_SECURE_FACE_INFO,
    OHOS_CONTROL_SECURE_FACE_AUTH_RESULT,
    OHOS_CONTROL_SECURE_FLASH_SEQ,
    OHOS_CONTROL_SECURE_IR_LED_SWITCH,
    OHOS_CONTROL_SECURE_IR_LOCKAE_SWITCH,

    //XMAGE MODES
    OHOS_ABILITY_SUPPORTED_COLOR_MODES,
    OHOS_CONTROL_SUPPORTED_COLOR_MODES,
};

std::map<uint32_t, uint32_t> g_metadataSectionMap = {
    {OHOS_CAMERA_PROPERTIES, OHOS_SECTION_CAMERA_PROPERTIES},
    {OHOS_CAMERA_SENSOR, OHOS_SECTION_CAMERA_SENSOR},
    {OHOS_CAMERA_SENSOR_INFO, OHOS_SECTION_CAMERA_SENSOR_INFO},
    {OHOS_CAMERA_STATISTICS, OHOS_SECTION_CAMERA_STATISTICS},
    {OHOS_DEVICE_CONTROL, OHOS_SECTION_CAMERA_CONTROL},
    {OHOS_DEVICE_EXPOSURE, OHOS_SECTION_DEVICE_EXPOSURE},
    {OHOS_DEVICE_FOCUS, OHOS_SECTION_DEVICE_FOCUS},
    {OHOS_DEVICE_WHITE_BLANCE, OHOS_SECTION_DEVICE_WHITE},
    {OHOS_DEVICE_FLASH, OHOS_SECTION_DEVICE_FLASH},
    {OHOS_DEVICE_ZOOM, OHOS_SECTION_DEVICE_ZOOM},
    {OHOS_STREAM_ABILITY, OHOS_SECTION_STREAM_ABILITY},
    {OHOS_STREAM_JPEG, OHOS_SECTION_STREAM_JPEG},
    {OHOS_STREAM_VIDEO, OHOS_SECTION_STREAM_VIDEO},
    {OHOS_CAMERA_EFFECT, OHOS_SECTION_CAMERA_EFFECT},
    {OHOS_CAMERA_SECURE, OHOS_SECTION_CAMERA_SECURE},
    {OHOS_XMAGE_COLOR_ABILITY, OHOS_SECTION_CAMERA_XMAGE}
};

CameraMetadata::CameraMetadata(size_t itemCapacity, size_t dataCapacity)
{
    metadata_ = AllocateCameraMetadataBuffer(itemCapacity, AlignTo(dataCapacity, DATA_ALIGNMENT));
}

CameraMetadata::~CameraMetadata()
{
    if (metadata_) {
        FreeCameraMetadataBuffer(metadata_);
        metadata_ = nullptr;
    }
}

bool CameraMetadata::addEntry(uint32_t item, const void *data, size_t data_count)
{
    if (metadata_ == nullptr) {
        METADATA_ERR_LOG("metadata_ is null");
        return false;
    }

    auto result = AddCameraMetadataItem(metadata_, item, data, data_count);
    if (!result) {
        return true;
    }

    if (result != CAM_META_ITEM_CAP_EXCEED && result != CAM_META_DATA_CAP_EXCEED) {
        const char *name = GetCameraMetadataItemName(item);

        if (name) {
            METADATA_ERR_LOG("Failed to add tag. tagname = %{public}s", name);
        } else {
            METADATA_ERR_LOG("Failed to add unknown tag");
        }
        return false;
    }

    return resize_add_metadata(item, data, data_count);
}

bool CameraMetadata::resize_add_metadata(uint32_t item, const void *data, size_t data_count)
{
    uint32_t data_type;

    auto itemCapacity = GetCameraMetadataItemCapacity(metadata_);
    auto data_capacity = GetCameraMetadataDataSize(metadata_);

    int32_t ret = GetCameraMetadataItemType(item, &data_type);
    if (ret != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("GetCameraMetadataItemType invalid item type");
        return false;
    }
    int32_t size = CalculateCameraMetadataItemDataSize(data_type, data_count);
    if (size == CAM_META_FAILURE) {
        METADATA_ERR_LOG("CalculateCameraMetadataItemDataSize invalid datatype:%{public}d", data_type);
        return false;
    }

    common_metadata_header_t *newMetadata = AllocateCameraMetadataBuffer((itemCapacity + 1) * INDEX_COUNTER,
        AlignTo((data_capacity + size) * INDEX_COUNTER, DATA_ALIGNMENT));

    if (newMetadata == nullptr) {
        METADATA_ERR_LOG("Failed to resize the metadata buffer");
        return false;
    }

    auto result = CopyCameraMetadataItems(newMetadata, metadata_);
    if (result != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("Failed to copy the old metadata to new metadata");
        FreeCameraMetadataBuffer(newMetadata);
        return false;
    }

    result = AddCameraMetadataItem(newMetadata, item, data, data_count);
    if (result != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("Failed to add new entry");
        FreeCameraMetadataBuffer(newMetadata);
        return false;
    }
    replace_metadata(newMetadata);

    return true;
}

void CameraMetadata::replace_metadata(common_metadata_header_t *newMetadata)
{
    if (metadata_ == newMetadata) {
        return;
    }

    FreeCameraMetadataBuffer(metadata_);
    metadata_ = newMetadata;
}

bool CameraMetadata::updateEntry(uint32_t tag, const void *data, size_t dataCount)
{
    if (metadata_ == nullptr) {
        METADATA_ERR_LOG("metadata_ is null");
        return false;
    }

    const char *name = GetCameraMetadataItemName(tag);
    (void)name;
    camera_metadata_item_t item;
    int ret = FindCameraMetadataItem(metadata_, tag, &item);
    if (ret) {
        METADATA_ERR_LOG("Failed to update tag tagname = %{public}s : not present", (name ? name : "<unknown>"));
        return false;
    }
    METADATA_INFO_LOG("updateEntry item id: %{public}d, name: %{public}s, "
                      "dataCount: %{public}zu", tag, name ? name : "<unknown>", dataCount);
    ret = UpdateCameraMetadataItemByIndex(metadata_, item.index, data, dataCount, nullptr);
    if (ret) {
        const char *name_ = GetCameraMetadataItemName(tag);
        (void)name_;
        METADATA_ERR_LOG("Failed to update tag tagname = %{public}s", (name_ ? name_ : "<unknown>"));
        return false;
    }

    return true;
}

common_metadata_header_t *CameraMetadata::get()
{
    return metadata_;
}

const common_metadata_header_t *CameraMetadata::get() const
{
    return metadata_;
}

bool CameraMetadata::isValid() const
{
    return metadata_ != nullptr;
}

uint32_t CameraMetadata::AlignTo(uint32_t val, uint32_t alignment)
{
    return static_cast<uint32_t>((static_cast<uintptr_t>(val) + ((alignment) - 1)) & ~((alignment) - 1));
}

uint32_t CameraMetadata::MaxAlignment(uint32_t dataAlignment, uint32_t metadataAlignment)
{
    return ((dataAlignment > metadataAlignment) ? dataAlignment : metadataAlignment);
}

uint8_t *CameraMetadata::GetMetadataData(const common_metadata_header_t *metadataHeader)
{
    if (!metadataHeader) {
        METADATA_ERR_LOG("GetMetadataData metadataHeader is null");
        return nullptr;
    }
    return (uint8_t *)metadataHeader + metadataHeader->data_start;
}

camera_metadata_item_entry_t *CameraMetadata::GetMetadataItems(const common_metadata_header_t *metadataHeader)
{
    return reinterpret_cast<camera_metadata_item_entry_t *>(
        (reinterpret_cast<uint8_t *>(const_cast<common_metadata_header_t *>(metadataHeader)) +
        metadataHeader->items_start));
}

common_metadata_header_t *CameraMetadata::FillCameraMetadata(common_metadata_header_t *buffer, size_t memoryRequired,
    uint32_t itemCapacity, uint32_t dataCapacity)
{
    METADATA_DEBUG_LOG("FillCameraMetadata start");
    if (buffer == nullptr) {
        METADATA_ERR_LOG("FillCameraMetadata buffer is null");
        return nullptr;
    }

    common_metadata_header_t *metadataHeader = static_cast<common_metadata_header_t *>(buffer);
    metadataHeader->version = CURRENT_CAMERA_METADATA_VERSION;
    metadataHeader->size = memoryRequired;
    metadataHeader->item_count = 0;
    metadataHeader->item_capacity = itemCapacity;
    metadataHeader->items_start = AlignTo(sizeof(common_metadata_header_t), ITEM_ALIGNMENT);
    metadataHeader->data_count = 0;
    metadataHeader->data_capacity = dataCapacity;
    size_t dataUnaligned = reinterpret_cast<uint8_t *>(GetMetadataItems(metadataHeader) +
        metadataHeader->item_capacity) - reinterpret_cast<uint8_t *>(metadataHeader);
    metadataHeader->data_start = AlignTo(dataUnaligned, DATA_ALIGNMENT);

    METADATA_DEBUG_LOG("MetadataHeader ItemCapacity Size = %{public}u, DataCapacity Size = %{public}u",
        metadataHeader->item_capacity, metadataHeader->data_capacity);
    METADATA_DEBUG_LOG("FillCameraMetadata end");
    return metadataHeader;
}

size_t CameraMetadata::CalculateCameraMetadataMemoryRequired(uint32_t itemCount, uint32_t dataCount)
{
    METADATA_DEBUG_LOG("CalculateCameraMetadataMemoryRequired start");
    size_t memoryRequired = sizeof(common_metadata_header_t);
    memoryRequired = CameraMetadata::AlignTo(memoryRequired, ITEM_ALIGNMENT);

    memoryRequired += sizeof(camera_metadata_item_entry_t[itemCount]);
    memoryRequired = CameraMetadata::AlignTo(memoryRequired, DATA_ALIGNMENT);

    memoryRequired += sizeof(uint8_t[dataCount]);
    memoryRequired = CameraMetadata::AlignTo(memoryRequired, METADATA_PACKET_ALIGNMENT);

    METADATA_DEBUG_LOG("CalculateCameraMetadataMemoryRequired memoryRequired: %{public}zu", memoryRequired);
    METADATA_DEBUG_LOG("CalculateCameraMetadataMemoryRequired end");
    return memoryRequired;
}

common_metadata_header_t *CameraMetadata::AllocateCameraMetadataBuffer(uint32_t item_capacity, uint32_t data_capacity)
{
    METADATA_DEBUG_LOG("AllocateCameraMetadataBuffer start");
    METADATA_DEBUG_LOG("AllocateCameraMetadataBuffer item_capacity: %{public}u, data_capacity: %{public}u",
        item_capacity, data_capacity);
    if (item_capacity > MAX_ITEM_CAPACITY || data_capacity > MAX_DATA_CAPACITY) {
        METADATA_ERR_LOG("AllocateCameraMetadataBuffer invalid item_capacity or data_capacity");
        return nullptr;
    }
    size_t memoryRequired = CalculateCameraMetadataMemoryRequired(item_capacity, data_capacity);
    void *buffer = calloc(1, memoryRequired);
    if (buffer == nullptr) {
        METADATA_ERR_LOG("AllocateCameraMetadataBuffer memory allocation failed");
        return reinterpret_cast<common_metadata_header_t *>(buffer);
    }

    common_metadata_header_t *metadataHeader = FillCameraMetadata(reinterpret_cast<common_metadata_header_t *>(buffer),
        memoryRequired, item_capacity, data_capacity);
    if (metadataHeader == nullptr) {
        METADATA_ERR_LOG("AllocateCameraMetadataBuffer metadataHeader is null");
        free(buffer);
    }

    METADATA_DEBUG_LOG("AllocateCameraMetadataBuffer end");
    return metadataHeader;
}

// Load vendor tag impl
int32_t LoadVendorTagImpl()
{
    if (g_vendorTagImpl == nullptr) {
        void* libHandle = nullptr;
#ifndef CAMERA_VENDOR_TAG
        libHandle = dlopen(g_exampleVendorTagLib, RTLD_LAZY);
#else
        libHandle = dlopen(g_vendorTagLib, RTLD_LAZY);
#endif
        if (libHandle == nullptr) {
            METADATA_ERR_LOG("dlopen failed %{public}s", __func__);
            return CAM_META_FAILURE;
        }

        CreateCameraVendorTag* createVendorTag =
            reinterpret_cast<CreateCameraVendorTag*>(dlsym(libHandle, "CreateVendorTagImpl"));
        if (createVendorTag == nullptr) {
            METADATA_ERR_LOG("CreateCameraVendorTag failed %{public}s", __func__);
            dlclose(libHandle);
            return CAM_META_FAILURE;
        }

        g_vendorTagImpl = createVendorTag();
        if (g_vendorTagImpl == nullptr) {
            METADATA_ERR_LOG("createVendorTag failed %{public}s", __func__);
            dlclose(libHandle);
            return CAM_META_FAILURE;
        }
    }

    return CAM_META_SUCCESS;
}

int32_t CameraMetadata::GetMetadataSection(uint32_t itemSection, uint32_t *section)
{
    METADATA_DEBUG_LOG("GetMetadataSection start");
    if (itemSection < OHOS_CAMERA_PROPERTIES ||
        itemSection >= OHOS_ABILITY_SECTION_END) {
        METADATA_ERR_LOG("GetMetadataSection itemSection is not valid");
        return CAM_META_FAILURE;
    }

    int32_t ret = CAM_META_SUCCESS;
    auto iter = g_metadataSectionMap.find(itemSection);
    if (iter != g_metadataSectionMap.end()) {
        *section = iter->second;
    } else {
        METADATA_ERR_LOG("GetMetadataSection item section is not defined");
        ret = CAM_META_FAILURE;
    }

    METADATA_DEBUG_LOG("GetMetadataSection end");
    return ret;
}

int32_t CameraMetadata::GetCameraMetadataItemType(uint32_t item, uint32_t *dataType)
{
    METADATA_DEBUG_LOG("GetCameraMetadataItemType start");
    if (dataType == nullptr) {
        METADATA_ERR_LOG("GetCameraMetadataItemType dataType is null");
        return CAM_META_INVALID_PARAM;
    }
    uint32_t section;
    uint32_t itemTag = item >> BITWISE_SHIFT_16;
    if (itemTag >= OHOS_VENDOR_SECTION) {
        int32_t ret = LoadVendorTagImpl();
        if (ret != CAM_META_SUCCESS) {
            METADATA_ERR_LOG("LoadVendorTagImpl failed");
            return CAM_META_FAILURE;
        }
        *dataType = g_vendorTagImpl->GetVendorTagType(item);
        return CAM_META_SUCCESS;
    }
    int32_t ret = GetMetadataSection(itemTag, &section);
    if (ret != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("GetCameraMetadataItemType section is not valid");
        return ret;
    }

    if (item >= g_ohosCameraSectionBounds[section][1]) {
        METADATA_ERR_LOG("GetCameraMetadataItemType item is not in section bound");
        return CAM_META_FAILURE;
    }

    uint32_t itemIndex = item & 0xFFFF;
    if (g_ohosItemInfo[section][itemIndex].item_type < META_TYPE_BYTE) {
        METADATA_ERR_LOG("GetCameraMetadataItemType item is not initialized");
        return CAM_META_FAILURE;
    }

    *dataType = g_ohosItemInfo[section][itemIndex].item_type;

    METADATA_DEBUG_LOG("GetCameraMetadataItemType end");
    return CAM_META_SUCCESS;
}

const char *CameraMetadata::GetCameraMetadataItemName(uint32_t item)
{
    METADATA_DEBUG_LOG("GetCameraMetadataItemName start");
    METADATA_DEBUG_LOG("GetCameraMetadataItemName item: %{public}u", item);
    uint32_t section;
    uint32_t itemTag = item >> BITWISE_SHIFT_16;
    if (itemTag >= OHOS_VENDOR_SECTION) {
        int32_t ret = LoadVendorTagImpl();
        if (ret != CAM_META_SUCCESS) {
            METADATA_ERR_LOG("LoadVendorTagImpl failed");
            return nullptr;
        }
        const char* tagName = g_vendorTagImpl->GetVendorTagName(item);
        return tagName;
    }
    int32_t ret = GetMetadataSection(itemTag, &section);
    if (ret != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("GetCameraMetadataItemName section is not valid");
        return nullptr;
    }

    if (item >= g_ohosCameraSectionBounds[section][1]) {
        METADATA_ERR_LOG("GetCameraMetadataItemName item is not in section bound");
        return nullptr;
    }

    uint32_t itemIndex = item & 0xFFFF;
    METADATA_DEBUG_LOG("GetCameraMetadataItemName end");
    return g_ohosItemInfo[section][itemIndex].item_name;
}

int32_t CameraMetadata::CalculateCameraMetadataItemDataSize(uint32_t type, size_t dataCount)
{
    METADATA_DEBUG_LOG("CalculateCameraMetadataItemDataSize start");
    if (type < META_TYPE_BYTE || type >= META_NUM_TYPES) {
        METADATA_ERR_LOG("CalculateCameraMetadataItemDataSize invalid type");
        return CAM_META_FAILURE;
    }

    size_t dataBytes = dataCount * OHOS_CAMERA_METADATA_TYPE_SIZE[type];

    METADATA_DEBUG_LOG("CalculateCameraMetadataItemDataSize end");
    return (dataBytes <= METADATA_HEADER_DATA_SIZE) ? 0 : AlignTo(dataBytes, DATA_ALIGNMENT);
}

int CameraMetadata::AddCameraMetadataItemVerify(common_metadata_header_t *dst,
    uint32_t item, const void *data, size_t dataCount, uint32_t *dataType)
{
    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        name = "<unknown>";
    }
    METADATA_DEBUG_LOG("AddCameraMetadataItemVerify item id: %{public}u, name: %{public}s, "
        "dataCount: %{public}zu", item, name, dataCount);

    if (dst == nullptr) {
        METADATA_ERR_LOG("AddCameraMetadataItemVerify common_metadata_header_t is null");
        return CAM_META_INVALID_PARAM;
    }

    if (!dataCount || data == nullptr) {
        METADATA_ERR_LOG("AddCameraMetadataItemVerify data is not valid. item: %{public}u, "
            "dataCount: %{public}zu", item, dataCount);
        return CAM_META_INVALID_PARAM;
    }

    if (dst->item_count == dst->item_capacity) {
        METADATA_ERR_LOG("AddCameraMetadataItemVerify item_capacity limit reached. "
            "item_count: %{public}d, item_capacity: %{public}d", dst->item_count, dst->item_capacity);
        return CAM_META_ITEM_CAP_EXCEED;
    }

    int32_t ret = GetCameraMetadataItemType(item, dataType);
    if (ret != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("AddCameraMetadataItemVerify invalid item type");
        return CAM_META_INVALID_PARAM;
    }

    if (*dataType < META_TYPE_BYTE || *dataType >= META_NUM_TYPES) {
        METADATA_ERR_LOG("AddCameraMetadataItemVerify invalid type");
        return CAM_META_INVALID_PARAM;
    }

    return CAM_META_SUCCESS;
}

int CameraMetadata::AddCameraMetadataItem(common_metadata_header_t *dst, uint32_t item,
    const void *data, size_t dataCount)
{
    METADATA_DEBUG_LOG("AddCameraMetadataItem start");
    uint32_t dataType;
    int32_t ret = AddCameraMetadataItemVerify(dst, item, data, dataCount, &dataType);
    if (ret != CAM_META_SUCCESS) return ret;

    if ((dst->size - dst->items_start) < (uint64_t)dst->item_count * itemLen ||
        (dst->size - dst->data_start) < dst->data_count) {
        METADATA_ERR_LOG("AddCameraMetadataItem fail: invalid argument.");
        return CAM_META_INVALID_PARAM;
    }
    
    int32_t dataBytes = CalculateCameraMetadataItemDataSize(dataType, dataCount);
    if ((uint32_t)dataBytes >= (UINT32_MAX - dst->data_count) ||
        (uint32_t)dataBytes + dst->data_count > dst->data_capacity) {
        METADATA_ERR_LOG("AddCameraMetadataItem data_capacity limit reached");
        return CAM_META_DATA_CAP_EXCEED;
    }

    size_t dataPayloadBytes = dataCount * OHOS_CAMERA_METADATA_TYPE_SIZE[dataType];
    camera_metadata_item_entry_t *metadataItem = GetMetadataItems(dst) + dst->item_count;
    ret = memset_s(metadataItem, sizeof(camera_metadata_item_entry_t), 0, sizeof(camera_metadata_item_entry_t));
    if (ret != EOK) {
        METADATA_ERR_LOG("AddCameraMetadataItem: memset_s failed");
        return CAM_META_FAILURE;
    }
    metadataItem->item = item;
    metadataItem->data_type = dataType;
    metadataItem->count = dataCount;

    if (dataBytes == 0) {
        ret = memcpy_s(metadataItem->data.value, METADATA_HEADER_DATA_SIZE, data, dataPayloadBytes);
        if (ret != EOK) {
            METADATA_ERR_LOG("AddCameraMetadataItem memory copy failed");
            return CAM_META_FAILURE;
        }
    } else {
        metadataItem->data.offset = dst->data_count;
        uint8_t *dstMetadataData = GetMetadataData(dst);
        if (dstMetadataData == nullptr) {
            METADATA_ERR_LOG("AddCameraMetadataItem GetMetadataData failed");
            return CAM_META_FAILURE;
        }
        if (dst->data_capacity < metadataItem->data.offset) {
            METADATA_ERR_LOG("AddCameraMetadataItem Invalid data capacity and data offset failed");
            return CAM_META_FAILURE;
        }
        size_t remaind = dst->data_capacity - metadataItem->data.offset;
        if (remaind < dataPayloadBytes) {
            METADATA_ERR_LOG("AddCameraMetadataItem Insufficient capacity for copying");
            return CAM_META_FAILURE;
        }
        ret = memcpy_s(dstMetadataData + metadataItem->data.offset, remaind, data, dataPayloadBytes);
        if (ret != EOK) {
            METADATA_ERR_LOG("AddCameraMetadataItem memory copy failed");
            return CAM_META_FAILURE;
        }
        if (dst->data_count > UINT32_MAX - (uint32_t)dataBytes) {
            METADATA_ERR_LOG("AddCameraMetadataItem Insufficient capacity");
            return CAM_META_FAILURE;
        }
        dst->data_count += (uint32_t)dataBytes;
    }
    dst->item_count++;

    METADATA_DEBUG_LOG("AddCameraMetadataItem end");
    return CAM_META_SUCCESS;
}

int CameraMetadata::GetCameraMetadataItem(const common_metadata_header_t *src, uint32_t index,
    camera_metadata_item_t *item)
{
    METADATA_DEBUG_LOG("GetCameraMetadataItem start");
    if (src == nullptr || item == nullptr) {
        METADATA_ERR_LOG("GetCameraMetadataItem src or item is null");
        return CAM_META_INVALID_PARAM;
    }

    int32_t ret = memset_s(item, sizeof(camera_metadata_item_t), 0, sizeof(camera_metadata_item_t));
    if (ret != EOK) {
        METADATA_ERR_LOG("GetCameraMetadataItem: memset_s failed");
        return CAM_META_FAILURE;
    }
    if (index >= src->item_count) {
        METADATA_ERR_LOG("GetCameraMetadataItem index is greater than item count");
        return CAM_META_INVALID_PARAM;
    }

    camera_metadata_item_entry_t *localItem = GetMetadataItems(src) + index;

    item->index = index;
    item->item = localItem->item;
    item->data_type = localItem->data_type;
    item->count = localItem->count;

    int32_t dataBytes = CalculateCameraMetadataItemDataSize(localItem->data_type, localItem->count);
    if (dataBytes == 0) {
        item->data.u8 = localItem->data.value;
    } else if (dataBytes == CAM_META_FAILURE) {
        METADATA_ERR_LOG("GetCameraMetadataItem invalid datatype:%{public}d", localItem->data_type);
        return CAM_META_FAILURE;
    } else {
        uint8_t *srcMetadataData = GetMetadataData(src);
        if (srcMetadataData == nullptr) {
            METADATA_ERR_LOG("GetCameraMetadataItem GetMetadataData failed");
            return CAM_META_FAILURE;
        }
        item->data.u8 = srcMetadataData + localItem->data.offset;
    }

    METADATA_DEBUG_LOG("GetCameraMetadataItem end");
    return CAM_META_SUCCESS;
}

int CameraMetadata::FindCameraMetadataItemIndex(const common_metadata_header_t *src, uint32_t item, uint32_t *idx,
    bool isPrintLog)
{
    METADATA_DEBUG_LOG("FindCameraMetadataItemIndex start");
    METADATA_DEBUG_LOG("FindCameraMetadataItemIndex item: %{public}u", item);
    if (src == nullptr || idx == nullptr) {
        METADATA_ERR_LOG("FindCameraMetadataItemIndex src or index is null");
        return CAM_META_INVALID_PARAM;
    }

    camera_metadata_item_entry_t *searchItem = GetMetadataItems(src);
    uint32_t index;
    for (index = 0; index < src->item_count; index++, searchItem++) {
        if (searchItem->item == item) {
            break;
        }
    }

    if (index == src->item_count) {
        if (isPrintLog) {
            METADATA_ERR_LOG("FindCameraMetadataItemIndex item: %{public}u not found", item);
        }
        return CAM_META_ITEM_NOT_FOUND;
    }

    *idx = index;
    METADATA_DEBUG_LOG("FindCameraMetadataItemIndex index: %{public}u", index);
    METADATA_DEBUG_LOG("FindCameraMetadataItemIndex end");
    return CAM_META_SUCCESS;
}

int CameraMetadata::FindCameraMetadataItem(const common_metadata_header_t *src, uint32_t item,
    camera_metadata_item_t *metadataItem)
{
    uint32_t index = 0;
    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        name = "<unknown>";
    }
    METADATA_DEBUG_LOG("FindCameraMetadataItem item id: %{public}u, name: %{public}s", item, name);
    int ret = FindCameraMetadataItemIndex(src, item, &index);
    if (ret != CAM_META_SUCCESS) {
        return ret;
    }

    return GetCameraMetadataItem(src, index, metadataItem);
}

bool CameraMetadata::IsCameraMetadataItemExist(const common_metadata_header_t *src, uint32_t item)
{
    uint32_t index = 0;
    int ret = FindCameraMetadataItemIndex(src, item, &index, false);
    return ret == CAM_META_SUCCESS;
}

void SetOffset(camera_metadata_item_entry_t *metadataItems, camera_metadata_item_entry_t *item, size_t oldItemSize)
{
    if (metadataItems == nullptr) {
        METADATA_ERR_LOG("SetOffset metadataItems is null");
        return;
    }
    if (CalculateCameraMetadataItemDataSize(metadataItems->data_type, metadataItems->count) > 0 &&
        metadataItems->data.offset > item->data.offset) {
        metadataItems->data.offset -= oldItemSize;
    }
}

int CameraMetadata::MetadataExpandItemMem(common_metadata_header_t *dst, camera_metadata_item_entry_t *item,
    size_t oldItemSize)
{
    if (item == nullptr || dst == nullptr) {
        METADATA_ERR_LOG("MetadataExpandItemMem item is null or dst is null");
        return CAM_META_INVALID_PARAM;
    }
    uint8_t *dstMetadataData = GetMetadataData(dst);
    if (dstMetadataData == nullptr) {
        METADATA_ERR_LOG("MetadataExpandItemMem GetMetadataData failed");
        return CAM_META_FAILURE;
    }
    if (item->data.offset > UINT32_MAX - (uint32_t)oldItemSize ||
        item->data.offset + (uint32_t)oldItemSize > dst->data_count) {
        METADATA_ERR_LOG("MetadataExpandItemMem data.offset:%{public}u, oldItemSize:%{pulic}zu, "
            "dst->data_count:%{public}u", item->data.offset, oldItemSize, dst->data_count);
        return CAM_META_FAILURE;
    }
    uint8_t *start = dstMetadataData + item->data.offset;
    uint8_t *end = start + oldItemSize;
    size_t length = dst->data_count - item->data.offset - oldItemSize;
    if (length != 0) {
        int32_t ret = memmove_s(start, length, end, length);
        if (ret != EOK) {
            METADATA_ERR_LOG("MetadataExpandItemMem memory move failed");
            return CAM_META_FAILURE;
        }
    }
    dst->data_count -= oldItemSize;

    camera_metadata_item_entry_t *metadataItems = GetMetadataItems(dst);
    for (uint32_t i = 0; i < dst->item_count; i++, ++metadataItems) {
        SetOffset(metadataItems, item, oldItemSize);
    }

    return CAM_META_SUCCESS;
}

int CameraMetadata::copyMetadataMemory(common_metadata_header_t *dst, camera_metadata_item_entry_t *item,
    size_t dataPayloadSize, const void *data)
{
    uint8_t *dstMetadataData = GetMetadataData(dst);
    int32_t ret = CAM_META_SUCCESS;
    if (dstMetadataData == nullptr) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize GetMetadataData failed");
        return CAM_META_FAILURE;
    }
    if (dst->data_capacity < item->data.offset) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize Invalid data capacity and data offset failed");
        return CAM_META_FAILURE;
    }

    size_t remaind = dst->data_capacity - item->data.offset;
    if (remaind < dataPayloadSize) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize Insufficient capacity for copying");
        return CAM_META_FAILURE;
    }

    ret = memcpy_s(dstMetadataData + item->data.offset, remaind, data, dataPayloadSize);
    if (ret != EOK) {
        METADATA_ERR_LOG("UpdateCameraMetadataItemByIndex memory copy failed");
        return CAM_META_FAILURE;
    }
    return CAM_META_SUCCESS;
}

int CameraMetadata::UpdateameraMetadataItemSize(camera_metadata_item_entry_t *item, uint32_t dataCount,
    common_metadata_header_t *dst, const void *data)
{
    if (item == nullptr || dst == nullptr) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize item is null or dst is null");
        return CAM_META_FAILURE;
    } else if (item->data_type < META_TYPE_BYTE || item->data_type >= META_NUM_TYPES) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize invalid datatype:%{public}d", item->data_type);
        return CAM_META_FAILURE;
    }
    int32_t dataSize = CalculateCameraMetadataItemDataSize(item->data_type, dataCount);
    size_t dataPayloadSize = dataCount * OHOS_CAMERA_METADATA_TYPE_SIZE[item->data_type];
    int32_t oldItemSize = CalculateCameraMetadataItemDataSize(item->data_type, item->count);
    int32_t ret = CAM_META_SUCCESS;
    if (dataSize != oldItemSize) {
        if (dst->data_count > UINT32_MAX - (uint32_t)dataSize &&
            dst->data_count + (uint32_t)dataSize < (uint32_t)oldItemSize) {
            return CAM_META_FAILURE;
        }
        if (dst->data_capacity < (dst->data_count + (uint32_t)dataSize - (uint32_t)oldItemSize)) {
            METADATA_ERR_LOG("UpdateCameraMetadataItemByIndex data_capacity limit reached");
            return CAM_META_DATA_CAP_EXCEED;
        }
        if (oldItemSize != 0) {
            ret = MetadataExpandItemMem(dst, item, oldItemSize);
            if (ret != CAM_META_SUCCESS) {
                return ret;
            }
        }
        if (dataSize != 0) {
            item->data.offset = dst->data_count;
            ret = copyMetadataMemory(dst, item, dataPayloadSize, data);
            if (ret != CAM_META_SUCCESS) {
                return ret;
            }
            if (dst->data_count > UINT32_MAX - (uint32_t)dataSize) {
                return CAM_META_FAILURE;
            }
            dst->data_count += (uint32_t)dataSize;
        }
    } else if (dataSize != 0) {
        ret = copyMetadataMemory(dst, item, dataPayloadSize, data);
        if (ret != CAM_META_SUCCESS) {
            return ret;
        }
    }
    if (dataSize == 0) {
        ret = memcpy_s(item->data.value, ENTRY_DATA_SIZE, data, dataPayloadSize);
        if (ret != EOK) {
            METADATA_ERR_LOG("UpdateCameraMetadataItemByIndex memory copy failed");
            return CAM_META_FAILURE;
        }
    }
    return ret;
}

int CameraMetadata::UpdateCameraMetadataItemByIndex(common_metadata_header_t *dst, uint32_t index,
    const void *data, uint32_t dataCount, camera_metadata_item_t *updatedItem)
{
    METADATA_DEBUG_LOG("UpdateCameraMetadataItemByIndex start");
    if ((dst == nullptr) || (index >= dst->item_count)) {
        METADATA_ERR_LOG("UpdateCameraMetadataItemByIndex dst is null or invalid index");
        return CAM_META_INVALID_PARAM;
    }

    if (!dataCount || data == nullptr) {
        METADATA_ERR_LOG("UpdateCameraMetadataItemByIndex data is not valid. "
            "dataCount: %{public}u", dataCount);
        return CAM_META_INVALID_PARAM;
    }

    int32_t ret = CAM_META_SUCCESS;
    camera_metadata_item_entry_t *item = GetMetadataItems(dst) + index;

    ret = UpdateameraMetadataItemSize(item, dataCount, dst, data);
    if (ret != CAM_META_SUCCESS) {
        return ret;
    }

    item->count = dataCount;
    if (updatedItem != nullptr) {
        ret = GetCameraMetadataItem(dst, index, updatedItem);
        if (ret != CAM_META_SUCCESS) {
            return ret;
        }
    }

    METADATA_DEBUG_LOG("UpdateCameraMetadataItemByIndex end");
    return ret;
}

int CameraMetadata::UpdateCameraMetadataItem(common_metadata_header_t *dst, uint32_t item, const void *data,
    uint32_t dataCount, camera_metadata_item_t *updatedItem)
{
    METADATA_DEBUG_LOG("UpdateCameraMetadataItem item id: %{public}u, dataCount: %{public}u", item, dataCount);
    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        name = "<unknown>";
    }
    METADATA_DEBUG_LOG("UpdateCameraMetadataItem item id: %{public}u, name: %{public}s, "
        "dataCount: %{public}u", item, name, dataCount);
    if (!dataCount || data == nullptr) {
        METADATA_ERR_LOG("UpdateCameraMetadataItem data is not valid. item: %{public}u, "
            "dataCount: %{public}u", item, dataCount);
        return CAM_META_INVALID_PARAM;
    }

    uint32_t index = 0;
    int32_t ret = FindCameraMetadataItemIndex(dst, item, &index);
    if (ret != CAM_META_SUCCESS) {
        return ret;
    }

    return UpdateCameraMetadataItemByIndex(dst, index, data, dataCount, updatedItem);
}

int CameraMetadata::moveMetadataMemery(common_metadata_header_t *dst, camera_metadata_item_entry_t *itemToDelete,
    size_t dataBytes)
{
    uint8_t *dstMetadataData = GetMetadataData(dst);
    if (dstMetadataData == nullptr) {
        METADATA_ERR_LOG("UpdateameraMetadataItemSize GetMetadataData failed");
        return CAM_META_FAILURE;
    }
    int32_t ret = CAM_META_SUCCESS;
    uint8_t *start = dstMetadataData + itemToDelete->data.offset;
    uint8_t *end = start + dataBytes;
    size_t length = dst->data_count - itemToDelete->data.offset - dataBytes;
    if (length != 0) {
        ret = memmove_s(start, length, end, length);
        if (ret != EOK) {
            METADATA_ERR_LOG("DeleteCameraMetadataItemByIndex memory move failed");
            return CAM_META_FAILURE;
        }
    }
    return CAM_META_SUCCESS;
}

int CameraMetadata::DeleteCameraMetadataItemByIndex(common_metadata_header_t *dst, uint32_t index)
{
    METADATA_DEBUG_LOG("DeleteCameraMetadataItemByIndex start");
    if (dst == nullptr) {
        METADATA_ERR_LOG("DeleteCameraMetadataItemByIndex dst is null");
        return CAM_META_INVALID_PARAM;
    }

    if (index >= dst->item_count) {
        METADATA_ERR_LOG("DeleteCameraMetadataItemByIndex item not valid");
        return CAM_META_INVALID_PARAM;
    }

    int32_t ret = CAM_META_SUCCESS;
    camera_metadata_item_entry_t *itemToDelete = GetMetadataItems(dst) + index;
    int32_t dataBytes = CalculateCameraMetadataItemDataSize(itemToDelete->data_type, itemToDelete->count);
    if (dataBytes > 0) {
        ret = moveMetadataMemery(dst, itemToDelete, dataBytes);
        if (ret != CAM_META_SUCCESS) {
            return ret;
        }
        if (dst->data_count < (uint32_t)dataBytes) {
            return CAM_META_FAILURE;
        }
        dst->data_count -= (uint32_t)dataBytes;

        camera_metadata_item_entry_t *metadataItems = GetMetadataItems(dst);
        for (uint32_t i = 0; i < dst->item_count; i++, ++metadataItems) {
            if (CalculateCameraMetadataItemDataSize(
                metadataItems->data_type, metadataItems->count) > 0 &&
                metadataItems->data.offset > itemToDelete->data.offset &&
                metadataItems->data.offset > (uint32_t)dataBytes) {
                metadataItems->data.offset -= (uint32_t)dataBytes;
            }
        }
    } else if (dataBytes == CAM_META_FAILURE) {
        METADATA_ERR_LOG("DeleteCameraMetadataItemByIndex invalid datatype:%{public}d", itemToDelete->data_type);
        return CAM_META_FAILURE;
    }

    uint64_t length = sizeof(camera_metadata_item_entry_t) * (dst->item_count - index - 1);
    if (length != 0) {
        ret = memmove_s(itemToDelete, length, itemToDelete + 1, length);
        if (ret != EOK) {
            METADATA_ERR_LOG("DeleteCameraMetadataItemByIndex memory move failed");
            return CAM_META_FAILURE;
        }
    }
    dst->item_count -= 1;
    METADATA_DEBUG_LOG("DeleteCameraMetadataItemByIndex end");
    return ret;
}

int CameraMetadata::DeleteCameraMetadataItem(common_metadata_header_t *dst, uint32_t item)
{
    METADATA_DEBUG_LOG("DeleteCameraMetadataItem item: %{public}u", item);
    uint32_t index = 0;
    int32_t ret = FindCameraMetadataItemIndex(dst, item, &index);
    if (ret != CAM_META_SUCCESS) {
        return ret;
    }

    return DeleteCameraMetadataItemByIndex(dst, index);
}

void CameraMetadata::FreeCameraMetadataBuffer(common_metadata_header_t *dst)
{
    if (dst != nullptr) {
        free(dst);
    }
}

uint32_t CameraMetadata::GetCameraMetadataItemCount(const common_metadata_header_t *metadataHeader)
{
    if (!metadataHeader) {
        METADATA_ERR_LOG("GetCameraMetadataItemCount::metadataHeader is null");
        return 0;
    }
    return metadataHeader->item_count;
}

uint32_t CameraMetadata::GetCameraMetadataItemCapacity(const common_metadata_header_t *metadataHeader)
{
    if (!metadataHeader) {
        METADATA_ERR_LOG("GetCameraMetadataItemCapacity::metadataHeader is null");
        return 0;
    }
    return metadataHeader->item_capacity;
}

uint32_t CameraMetadata::GetCameraMetadataDataSize(const common_metadata_header_t *metadataHeader)
{
    if (metadataHeader == nullptr) {
        METADATA_ERR_LOG("GetCameraMetadataDataSize::metadataHeader is null");
        return 0;
    }
    return metadataHeader->data_capacity;
}

int32_t CameraMetadata::CopyCameraMetadataItems(common_metadata_header_t *newMetadata,
    const common_metadata_header_t *oldMetadata)
{
    if (newMetadata == nullptr || oldMetadata == nullptr) {
        return CAM_META_INVALID_PARAM;
    }

    int32_t ret;
    if (oldMetadata->item_count != 0) {
        ret = memcpy_s(GetMetadataItems(newMetadata), sizeof(camera_metadata_item_entry_t[newMetadata->item_capacity]),
            GetMetadataItems(oldMetadata), sizeof(camera_metadata_item_entry_t[oldMetadata->item_count]));
        if (ret != EOK) {
            METADATA_ERR_LOG("CopyCameraMetadataItems memory copy failed, ItemCapacity Size = %{public}u,"
                "ItemCount Size = %{public}u", newMetadata->item_capacity, oldMetadata->item_count);
            return CAM_META_FAILURE;
        }
    }

    if (oldMetadata->data_count != 0) {
        uint8_t *newMetadataData = GetMetadataData(newMetadata);
        uint8_t *oldMetadataData = GetMetadataData(oldMetadata);
        if (newMetadataData == nullptr || oldMetadataData == nullptr) {
            METADATA_ERR_LOG("UpdateameraMetadataItemSize GetMetadataData failed");
            return CAM_META_FAILURE;
        }
        ret = memcpy_s(newMetadataData, sizeof(uint8_t[newMetadata->data_capacity]), oldMetadataData,
            sizeof(uint8_t[oldMetadata->data_count]));
        if (ret != EOK) {
            METADATA_ERR_LOG("CopyCameraMetadataItems memory copy failed, DataCapacity Size = %{public}u,"
                "DataCount Size  = %{public}u", newMetadata->data_capacity, oldMetadata->data_count);
            return CAM_META_FAILURE;
        }
    }

    newMetadata->item_count = oldMetadata->item_count;
    newMetadata->data_count = oldMetadata->data_count;

    return CAM_META_SUCCESS;
}

std::string U8ItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.u8 == nullptr) {
        METADATA_ERR_LOG("U8ItemToString: entry.data.u8 is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.u8));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.u8 + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.u8 + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("U8ItemToString: get u8 item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string I32ItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.i32 == nullptr) {
        METADATA_ERR_LOG("I32ItemToString: entry.data.i32 is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.i32));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.i32 + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.i32 + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("I32ItemToString: get i32 item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string U32ItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.ui32 == nullptr) {
        METADATA_ERR_LOG("U32ItemToString: entry.data.ui32 is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.ui32));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.ui32 + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.ui32 + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("U32ItemToString: get u32 item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string I64ItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.i64 == nullptr) {
        METADATA_ERR_LOG("I64ItemToString: entry.data.i64 is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.i64));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.i64 + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.i64 + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("I64ItemToString: get i64 item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string FloatItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.f == nullptr) {
        METADATA_ERR_LOG("FloatItemToString: entry.data.f is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.f));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.f + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.f + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("FloatItemToString: get float item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string DoubleItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.d == nullptr) {
        METADATA_ERR_LOG("DoubleItemToString: entry.data.d is null");
        return st;
    }
    std::string dataStr = std::to_string(*(entry.data.d));
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string(*(entry.data.d + i));
        } else {
            dataStr += " " + std::to_string(*(entry.data.d + i));
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("DoubleItemToString: get double item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string RationalItemToString(int32_t item, const camera_metadata_item_t entry)
{
    std::string st = {};
    uint32_t count = entry.count;
    if (entry.data.r == nullptr) {
        METADATA_ERR_LOG("RationalItemToString: entry.data.r is null");
        return st;
    }
    std::string dataStr = std::to_string((*(entry.data.r)).numerator) + "/" +
        std::to_string((*(entry.data.r)).denominator);
    for (uint32_t i = 1; i < count; i++) {
        if ((i % WRAP_LENGTH) == 0) {
            dataStr += "]\n\t[" + std::to_string((*(entry.data.r + i)).numerator) + "/" +
                std::to_string((*(entry.data.r + i)).denominator);
        } else {
            dataStr += " " + std::to_string((*(entry.data.r + i)).numerator) + "/" +
                std::to_string((*(entry.data.r + i)).denominator);
        }
    }

    const char *name = GetCameraMetadataItemName(item);
    if (name == nullptr) {
        METADATA_ERR_LOG("RationalItemToString: get rational item name fail");
        return st;
    }
    std::string nameStr(name);

    st = nameStr + " (" + std::to_string(entry.index) + "): " +
        OHOS_CAMERA_METADATA_TYPE[entry.data_type] + "[" + std::to_string(count) + "]" + "\n\t[" + dataStr + "]";

    return st;
}

std::string CameraMetadata::MetadataItemDump(const common_metadata_header_t *metadataHeader, uint32_t item)
{
    camera_metadata_item_t entry;
    std::string st = {};

    int ret = FindCameraMetadataItem(metadataHeader, item, &entry);
    if (ret != 0) {
        METADATA_ERR_LOG("get item error and item = %{public}d", item);
        return st;
    }

    switch (entry.data_type) {
        case META_TYPE_BYTE:
            st = U8ItemToString(item, entry);
            break;
        case META_TYPE_INT32:
            st = I32ItemToString(item, entry);
            break;
        case META_TYPE_UINT32:
            st = U32ItemToString(item, entry);
            break;
        case META_TYPE_FLOAT:
            st = FloatItemToString(item, entry);
            break;
        case META_TYPE_INT64:
            st = I64ItemToString(item, entry);
            break;
        case META_TYPE_DOUBLE:
            st = DoubleItemToString(item, entry);
            break;
        case META_TYPE_RATIONAL:
            st = RationalItemToString(item, entry);
            break;
        default:
            METADATA_ERR_LOG("invalid param and item = %{public}d", item);
            break;
    }

    if (!st.empty()) {
        st += "\n";
    }
    return st;
}

std::string CameraMetadata::FormatCameraMetadataToString(const common_metadata_header_t *metadataHeader)
{
    std::string metaStr;
    if (metadataHeader == nullptr) {
        METADATA_ERR_LOG("metadataHeader is nullptr");
        return metaStr;
    }

    for (auto it = g_metadataTags.begin(); it != g_metadataTags.end(); it++) {
        metaStr += MetadataItemDump(metadataHeader, *it);
    }
    METADATA_DEBUG_LOG("metadataHeader item = %{public}s", metaStr.c_str());
    return metaStr;
}

int32_t CameraMetadata::GetAllVendorTags(std::vector<vendorTag_t>& tagVec)
{
    int32_t ret = LoadVendorTagImpl();
    if (ret != CAM_META_SUCCESS) {
        METADATA_ERR_LOG("LoadVendorTagImpl failed");
        return CAM_META_FAILURE;
    }
    g_vendorTagImpl->GetAllVendorTags(tagVec);
    return CAM_META_SUCCESS;
}
} // Camera