From 16708df49fe1e7ad0a473d6b7df0d835c96a36f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 2 Apr 2025 18:01:52 +0800 Subject: [PATCH 01/53] =?UTF-8?q?PixelMap=20ANI=20=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- bundle.json | 14 +- frameworks/kits/ani/BUILD.gn | 94 +++ .../kits/ani/ets/@ohos.multimedia.image.ets | 725 +++++++++++++++++ frameworks/kits/ani/ets/imageTest.ets | 161 ++++ .../ani/native/include/ani_image_module.h | 24 + .../kits/ani/native/include/image_ani_utils.h | 44 ++ .../ani/native/include/image_packer_ani.h | 36 + .../ani/native/include/image_source_ani.h | 36 + .../kits/ani/native/include/picture_ani.h | 36 + .../kits/ani/native/include/pixel_map_ani.h | 37 + .../kits/ani/native/src/ani_image_module.cpp | 64 ++ .../kits/ani/native/src/image_ani_utils.cpp | 233 ++++++ .../kits/ani/native/src/image_packer_ani.cpp | 235 ++++++ .../kits/ani/native/src/image_source_ani.cpp | 729 ++++++++++++++++++ .../kits/ani/native/src/picture_ani.cpp | 82 ++ .../kits/ani/native/src/pixel_map_ani.cpp | 339 ++++++++ 16 files changed, 2887 insertions(+), 2 deletions(-) create mode 100644 frameworks/kits/ani/BUILD.gn create mode 100644 frameworks/kits/ani/ets/@ohos.multimedia.image.ets create mode 100644 frameworks/kits/ani/ets/imageTest.ets create mode 100644 frameworks/kits/ani/native/include/ani_image_module.h create mode 100644 frameworks/kits/ani/native/include/image_ani_utils.h create mode 100644 frameworks/kits/ani/native/include/image_packer_ani.h create mode 100644 frameworks/kits/ani/native/include/image_source_ani.h create mode 100644 frameworks/kits/ani/native/include/picture_ani.h create mode 100644 frameworks/kits/ani/native/include/pixel_map_ani.h create mode 100644 frameworks/kits/ani/native/src/ani_image_module.cpp create mode 100644 frameworks/kits/ani/native/src/image_ani_utils.cpp create mode 100644 frameworks/kits/ani/native/src/image_packer_ani.cpp create mode 100644 frameworks/kits/ani/native/src/image_source_ani.cpp create mode 100644 frameworks/kits/ani/native/src/picture_ani.cpp create mode 100644 frameworks/kits/ani/native/src/pixel_map_ani.cpp diff --git a/bundle.json b/bundle.json index 06afb32b7..59aebc7de 100644 --- a/bundle.json +++ b/bundle.json @@ -59,7 +59,7 @@ "json", "ffrt", "openmax", - "os_account", + "runtime_core", "qos_manager", "eventhandler", "ets_runtime" @@ -71,7 +71,8 @@ "build": { "sub_component": [ "//foundation/multimedia/image_framework:image_framework", - "//foundation/multimedia/image_framework:plugins" + "//foundation/multimedia/image_framework:plugins", + "//foundation/multimedia/image_framework/frameworks/kits/ani:image_framework_ani" ], "inner_kits": [ { @@ -190,6 +191,15 @@ }, "name": "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/utils:image_utils" }, + { + "header": { + "header_base": "//foundation/multimedia/image_framework/frameworks/kits/ani/native/include/", + "header_files": [ + "pixel_map_ani.h" + ] + }, + "name": "//foundation/multimedia/image_framework/frameworks/kits/ani:image_ani" + }, { "header": { "header_base": "//foundation/multimedia/image_framework/interfaces/kits/native/include/", diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn new file mode 100644 index 000000000..345638a58 --- /dev/null +++ b/frameworks/kits/ani/BUILD.gn @@ -0,0 +1,94 @@ +# Copyright (C) 2025 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/multimedia/image_framework/ide/image_decode_config.gni") + +config("ani_config") { + include_dirs = [ "native/include" ] +} + +group("image_framework_ani") { + deps = [ + ":image_ani", + ":image_framework_abc_etc", + ] +} + +ohos_shared_library("image_ani") { + public_configs = [ ":ani_config" ] + if (!use_clang_android) { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } + include_dirs = [ "native/include" ] + sources = [ + "native/src/ani_image_module.cpp", + "native/src/image_ani_utils.cpp", + "native/src/image_packer_ani.cpp", + "native/src/image_source_ani.cpp", + "native/src/picture_ani.cpp", + "native/src/pixel_map_ani.cpp", + ] + deps = [ + "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/utils:image_utils", + "//foundation/multimedia/image_framework/interfaces/innerkits:image_native", + "//foundation/multimedia/image_framework/interfaces/kits/js/common:image", + ] + external_deps = [ + "ability_runtime:ability_runtime", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "runtime_core:ani", + "runtime_core:libarkruntime", + ] + subsystem_name = "multimedia" + part_name = "image_framework" + output_extension = "so" +} + +generate_static_abc("image_framework_abc") { + base_url = "./ets" + files = [ "./ets/@ohos.multimedia.image.ets" ] + dst_file = "$target_out_dir/image_framework.abc" + out_puts = [ "$target_out_dir/image_framework.abc" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/image_framework.abc" +} + +ohos_prebuilt_etc("image_framework_abc_etc") { + source = "$target_out_dir/image_framework.abc" + module_install_dir = "framework" + subsystem_name = "multimedia" + part_name = "image_framework" + deps = [ ":image_framework_abc" ] +} + +generate_static_abc("image_framework_test_abc") { + base_url = "./ets" + files = [ + "./ets/imageTest.ets", + "./ets/@ohos.multimedia.image.ets", + ] + dst_file = "$target_out_dir/image_framework_test.abc" + out_puts = [ "$target_out_dir/image_framework_test.abc" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/image_framework_test.abc" +} diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets new file mode 100644 index 000000000..626a5395b --- /dev/null +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -0,0 +1,725 @@ +/* + * Copyright (c) 2025 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. + */ + +export namespace image { + + loadLibrary("image_ani"); + + enum DecodingDynamicRange { + AUTO = 0, + SDR = 1, + HDR = 2 + } + + enum PropertyKeyAni { + BITS_PER_SAMPLE = 'BitsPerSample', + ORIENTATION = 'Orientation', + IMAGE_LENGTH = 'ImageLength', + IMAGE_WIDTH = 'ImageWidth', + GPS_LATITUDE = 'GPSLatitude', + GPS_LONGITUDE = 'GPSLongitude', + GPS_LATITUDE_REF = 'GPSLatitudeRef', + GPS_LONGITUDE_REF = 'GPSLongitudeRef', + DATE_TIME_ORIGINAL = 'DateTimeOriginal', + EXPOSURE_TIME = 'ExposureTime', + SCENE_TYPE = 'SceneType', + ISO_SPEED_RATINGS = 'ISOSpeedRatings', + F_NUMBER = 'FNumber', + DATE_TIME = 'DateTime', + GPS_TIME_STAMP = 'GPSTimeStamp', + GPS_DATE_STAMP = 'GPSDateStamp', + IMAGE_DESCRIPTION = 'ImageDescription', + MAKE = 'Make', + MODEL = 'Model', + PHOTO_MODE = 'PhotoMode', + SENSITIVITY_TYPE = 'SensitivityType', + STANDARD_OUTPUT_SENSITIVITY = 'StandardOutputSensitivity', + RECOMMENDED_EXPOSURE_INDEX = 'RecommendedExposureIndex', + ISO_SPEED = 'ISOSpeedRatings', + APERTURE_VALUE = 'ApertureValue', + EXPOSURE_BIAS_VALUE = 'ExposureBiasValue', + METERING_MODE = 'MeteringMode', + LIGHT_SOURCE = 'LightSource', + FLASH = 'Flash', + FOCAL_LENGTH = 'FocalLength', + USER_COMMENT = 'UserComment', + PIXEL_X_DIMENSION = 'PixelXDimension', + PIXEL_Y_DIMENSION = 'PixelYDimension', + WHITE_BALANCE = 'WhiteBalance', + FOCAL_LENGTH_IN_35_MM_FILM = 'FocalLengthIn35mmFilm', + CAPTURE_MODE = 'HwMnoteCaptureMode', + PHYSICAL_APERTURE = 'HwMnotePhysicalAperture', + ROLL_ANGLE = 'HwMnoteRollAngle', + PITCH_ANGLE = 'HwMnotePitchAngle', + SCENE_FOOD_CONF = 'HwMnoteSceneFoodConf', + SCENE_STAGE_CONF = 'HwMnoteSceneStageConf', + SCENE_BLUE_SKY_CONF = 'HwMnoteSceneBlueSkyConf', + SCENE_GREEN_PLANT_CONF = 'HwMnoteSceneGreenPlantConf', + SCENE_BEACH_CONF = 'HwMnoteSceneBeachConf', + SCENE_SNOW_CONF = 'HwMnoteSceneSnowConf', + SCENE_SUNSET_CONF = 'HwMnoteSceneSunsetConf', + SCENE_FLOWERS_CONF = 'HwMnoteSceneFlowersConf', + SCENE_NIGHT_CONF = 'HwMnoteSceneNightConf', + SCENE_TEXT_CONF = 'HwMnoteSceneTextConf', + FACE_COUNT = 'HwMnoteFaceCount', + FOCUS_MODE = 'HwMnoteFocusMode', + COMPRESSION = 'Compression', + PHOTOMETRIC_INTERPRETATION = 'PhotometricInterpretation', + STRIP_OFFSETS = 'StripOffsets', + SAMPLES_PER_PIXEL = 'SamplesPerPixel', + ROWS_PER_STRIP = 'RowsPerStrip', + STRIP_BYTE_COUNTS = 'StripByteCounts', + X_RESOLUTION = 'XResolution', + Y_RESOLUTION = 'YResolution', + PLANAR_CONFIGURATION = 'PlanarConfiguration', + RESOLUTION_UNIT = 'ResolutionUnit', + TRANSFER_FUNCTION = 'TransferFunction', + SOFTWARE = 'Software', + ARTIST = 'Artist', + WHITE_POINT = 'WhitePoint', + PRIMARY_CHROMATICITIES = 'PrimaryChromaticities', + YCBCR_COEFFICIENTS = 'YCbCrCoefficients', + YCBCR_SUB_SAMPLING = 'YCbCrSubSampling', + YCBCR_POSITIONING = 'YCbCrPositioning', + REFERENCE_BLACK_WHITE = 'ReferenceBlackWhite', + COPYRIGHT = 'Copyright', + JPEG_INTERCHANGE_FORMAT = 'JPEGInterchangeFormat', + JPEG_INTERCHANGE_FORMAT_LENGTH = 'JPEGInterchangeFormatLength', + EXPOSURE_PROGRAM = 'ExposureProgram', + SPECTRAL_SENSITIVITY = 'SpectralSensitivity', + OECF = 'OECF', + EXIF_VERSION = 'ExifVersion', + DATE_TIME_DIGITIZED = 'DateTimeDigitized', + COMPONENTS_CONFIGURATION = 'ComponentsConfiguration', + SHUTTER_SPEED = 'ShutterSpeedValue', + BRIGHTNESS_VALUE = 'BrightnessValue', + MAX_APERTURE_VALUE = 'MaxApertureValue', + SUBJECT_DISTANCE = 'SubjectDistance', + SUBJECT_AREA = 'SubjectArea', + MAKER_NOTE = 'MakerNote', + SUBSEC_TIME = 'SubsecTime', + SUBSEC_TIME_ORIGINAL = 'SubsecTimeOriginal', + SUBSEC_TIME_DIGITIZED = 'SubsecTimeDigitized', + FLASHPIX_VERSION = 'FlashpixVersion', + COLOR_SPACE = 'ColorSpace', + RELATED_SOUND_FILE = 'RelatedSoundFile', + FLASH_ENERGY = 'FlashEnergy', + SPATIAL_FREQUENCY_RESPONSE = 'SpatialFrequencyResponse', + FOCAL_PLANE_X_RESOLUTION = 'FocalPlaneXResolution', + FOCAL_PLANE_Y_RESOLUTION = 'FocalPlaneYResolution', + FOCAL_PLANE_RESOLUTION_UNIT = 'FocalPlaneResolutionUnit', + SUBJECT_LOCATION = 'SubjectLocation', + EXPOSURE_INDEX = 'ExposureIndex', + SENSING_METHOD = 'SensingMethod', + FILE_SOURCE = 'FileSource', + CFA_PATTERN = 'CFAPattern', + CUSTOM_RENDERED = 'CustomRendered', + EXPOSURE_MODE = 'ExposureMode', + DIGITAL_ZOOM_RATIO = 'DigitalZoomRatio', + SCENE_CAPTURE_TYPE = 'SceneCaptureType', + GAIN_CONTROL = 'GainControl', + CONTRAST = 'Contrast', + SATURATION = 'Saturation', + SHARPNESS = 'Sharpness', + DEVICE_SETTING_DESCRIPTION = 'DeviceSettingDescription', + SUBJECT_DISTANCE_RANGE = 'SubjectDistanceRange', + IMAGE_UNIQUE_ID = 'ImageUniqueID', + GPS_VERSION_ID = 'GPSVersionID', + GPS_ALTITUDE_REF = 'GPSAltitudeRef', + GPS_ALTITUDE = 'GPSAltitude', + GPS_SATELLITES = 'GPSSatellites', + GPS_STATUS = 'GPSStatus', + GPS_MEASURE_MODE = 'GPSMeasureMode', + GPS_DOP = 'GPSDOP', + GPS_SPEED_REF = 'GPSSpeedRef', + GPS_SPEED = 'GPSSpeed', + GPS_TRACK_REF = 'GPSTrackRef', + GPS_TRACK = 'GPSTrack', + GPS_IMG_DIRECTION_REF = 'GPSImgDirectionRef', + GPS_IMG_DIRECTION = 'GPSImgDirection', + GPS_MAP_DATUM = 'GPSMapDatum', + GPS_DEST_LATITUDE_REF = 'GPSDestLatitudeRef', + GPS_DEST_LATITUDE = 'GPSDestLatitude', + GPS_DEST_LONGITUDE_REF = 'GPSDestLongitudeRef', + GPS_DEST_LONGITUDE = 'GPSDestLongitude', + GPS_DEST_BEARING_REF = 'GPSDestBearingRef', + GPS_DEST_BEARING = 'GPSDestBearing', + GPS_DEST_DISTANCE_REF = 'GPSDestDistanceRef', + GPS_DEST_DISTANCE = 'GPSDestDistance', + GPS_PROCESSING_METHOD = 'GPSProcessingMethod', + GPS_AREA_INFORMATION = 'GPSAreaInformation', + GPS_DIFFERENTIAL = 'GPSDifferential', + BODY_SERIAL_NUMBER = 'BodySerialNumber', + CAMERA_OWNER_NAME = 'CameraOwnerName', + COMPOSITE_IMAGE = 'CompositeImage', + COMPRESSED_BITS_PER_PIXEL = 'CompressedBitsPerPixel', + DNG_VERSION = 'DNGVersion', + DEFAULT_CROP_SIZE = 'DefaultCropSize', + GAMMA = 'Gamma', + ISO_SPEED_LATITUDE_YYY = 'ISOSpeedLatitudeyyy', + ISO_SPEED_LATITUDE_ZZZ = 'ISOSpeedLatitudezzz', + LENS_MAKE = 'LensMake', + LENS_MODEL = 'LensModel', + LENS_SERIAL_NUMBER = 'LensSerialNumber', + LENS_SPECIFICATION = 'LensSpecification', + NEW_SUBFILE_TYPE = 'NewSubfileType', + OFFSET_TIME = 'OffsetTime', + OFFSET_TIME_DIGITIZED = 'OffsetTimeDigitized', + OFFSET_TIME_ORIGINAL = 'OffsetTimeOriginal', + SOURCE_EXPOSURE_TIMES_OF_COMPOSITE_IMAGE = 'SourceExposureTimesOfCompositeImage', + SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE = 'SourceImageNumberOfCompositeImage', + SUBFILE_TYPE = 'SubfileType', + GPS_H_POSITIONING_ERROR = 'GPSHPositioningError', + PHOTOGRAPHIC_SENSITIVITY = 'PhotographicSensitivity', + BURST_NUMBER = 'HwMnoteBurstNumber', + FACE_CONF = 'HwMnoteFaceConf', + FACE_LEYE_CENTER = 'HwMnoteFaceLeyeCenter', + FACE_MOUTH_CENTER = 'HwMnoteFaceMouthCenter', + FACE_POINTER = 'HwMnoteFacePointer', + FACE_RECT = 'HwMnoteFaceRect', + FACE_REYE_CENTER = 'HwMnoteFaceReyeCenter', + FACE_SMILE_SCORE = 'HwMnoteFaceSmileScore', + FACE_VERSION = 'HwMnoteFaceVersion', + FRONT_CAMERA = 'HwMnoteFrontCamera', + SCENE_POINTER = 'HwMnoteScenePointer', + SCENE_VERSION = 'HwMnoteSceneVersion', + IS_XMAGE_SUPPORTED = 'HwMnoteIsXmageSupported', + XMAGE_MODE = 'HwMnoteXmageMode', + XMAGE_LEFT = 'HwMnoteXmageLeft', + XMAGE_TOP = 'HwMnoteXmageTop', + XMAGE_RIGHT = 'HwMnoteXmageRight', + XMAGE_BOTTOM = 'HwMnoteXmageBottom', + CLOUD_ENHANCEMENT_MODE = 'HwMnoteCloudEnhancementMode', + WIND_SNAPSHOT_MODE = 'HwMnoteWindSnapshotMode', + GIF_LOOP_COUNT = 'GIFLoopCount' + } + + enum AntiAliasingLevel { + NONE = 0, + LOW = 1, + MEDIUM = 2, + HIGH = 3, + } + + enum HdrMetadataKey { + HDR_METADATA_TYPE = 0, + HDR_STATIC_METADATA = 1, + HDR_DYNAMIC_METADATA = 2, + HDR_GAINMAP_METADATA = 3, + } + + enum HdrMetadataType { + NONE = 0, + BASE = 1, + GAINMAP = 2, + ALTERNATE = 3, + } + + enum PackingDynamicRange { + AUTO = 0, + SDR = 1, + } + + enum ScaleMode { + FIT_TARGET_SIZE = 0, + CENTER_CROP = 1 + } + + enum AuxiliaryPictureType { + GAINMAP = 1, + DEPTH_MAP = 2, + UNREFOCUS_MAP = 3, + LINEAR_MAP = 4, + FRAGMENT_MAP = 5, + } + + enum MetadataType { + EXIF_METADATA = 1, + FRAGMENT_METADATA = 2, + } + + enum PixelMapFormat { + UNKNOWN = 0, + RGB_565 = 2, + RGBA_8888 = 3, + BGRA_8888 = 4, + RGB_888 = 5, + ALPHA_8 = 6, + RGBA_F16 = 7, + NV21 = 8, + NV12 = 9, + RGBA_1010102 = 10, + YCBCR_P010 = 11, + YCRCB_P010 = 12 + } + + enum AlphaType { + UNKNOWN = 0, + OPAQUE = 1, + PREMUL = 2, + UNPREMUL = 3 + } + + // common + export interface Size { + width: int, + height: int, + } + + class SizeInner implements Size { + constructor(w: int, h: int) { + this.width = w; + this.height = h; + } + width: int; + height: int; + } + + export interface Region { + size: Size; + x: int; + y: int; + } + + interface PositionArea { + pixels: ArrayBuffer; + offset: int; + stride: int; + region: Region; + } + + export interface ImageInfo { + size: Size; + density: int; + stride: int; + pixelFormat: int; + alphaType: int; + mimeType: string; + isHdr: boolean; + } + + class ImageInfoInner implements ImageInfo { + size: Size = { width: 0, height: 0 }; + density: int = 0; + stride: int = 0; + pixelFormat: int = 0; + alphaType: int = 0; + mimeType: string = " "; + isHdr: boolean = false; + } + // end common + + // pixelmap + export interface InitializationOptions { + size: Size; + srcPixelFormat?: Int; + pixelFormat?: Int; + editable?: boolean; + alphaType?: Int; + scaleMode?: Int; + } + + export class InitializationOptionsInner implements InitializationOptions { + size: Size = { width: 0, height: 0 }; + pixelFormat?: Int | undefined = 0; + srcPixelFormat?: Int | undefined = 0; + editable?: boolean | undefined = false; + alphaType?: Int | undefined = 0; + scaleMode?: Int | undefined = 0; + } + + export interface PixelMap { + createAlphaPixelmapSync(): PixelMap; + createAlphaPixelmap(): Promise; + getImageInfoSync(): ImageInfo; + getImageInfo(): Promise; + getBytesNumberPerRow(): int; + getPixelBytesNumber(): int; + readPixelsToBufferSync(buff: ArrayBuffer); + readPixelsToBuffer(buff: ArrayBuffer): Promise; + scaleSync(x: double, y: double): void; + scaleSync(x: double, y: double, level: int): void; + cropSync(region: Region): void; + crop(region: Region): Promise; + flipSync(horizontal: boolean, vertical: boolean): void; + release(): Promise; + } + + class PixelMapInner implements PixelMap { + private nativeObj: long = 0; + + constructor(context: long) { + if (this.nativeObj == 0) { + this.nativeObj = context; + } + } + + native nativeCreateAlphaPixelmap(): PixelMap; + + public createAlphaPixelmapSync(): PixelMap { + return this.nativeCreateAlphaPixelmap(); + } + + public createAlphaPixelmap(): Promise { + return new Promise((resolve: (v: PixelMap) => void, reject: (error: Object) => void) => { + const cb = (): PixelMap => { + return this.nativeCreateAlphaPixelmap(); + }; + taskpool.execute(cb) + .then((e: NullishType) => resolve(e as PixelMap)); + }); + } + + native getBytesNumberPerRow(): int; + + native nativeGetImageInfo(): ImageInfo; + + public getImageInfoSync(): ImageInfo { + return this.nativeGetImageInfo(); + } + + public getImageInfo(): Promise { + return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Object) => void) => { + const cb = (): ImageInfo => { + return this.nativeGetImageInfo(); + }; + taskpool.execute(cb) + .then((e: NullishType) => resolve(e as ImageInfo)); + }); + } + + native getPixelBytesNumber(): int; + + native nativeReadPixelsToBuffer(buff: ArrayBuffer): void; + + public readPixelsToBufferSync(buff: ArrayBuffer): void { + return this.nativeReadPixelsToBuffer(buff); + } + + public readPixelsToBuffer(buff: ArrayBuffer): Promise { + return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + const cb = (): boolean => { + this.nativeReadPixelsToBuffer(buff); + return true; + }; + taskpool.execute(cb) + .then((): void => resolve(Promise.resolve())); + }); + } + + native nativeScale(x: double, y: double, level: int): void; + + public scaleSync(x: double, y: double): void { + this.nativeScale(x, y, 0); + } + public scaleSync(x: double, y: double, level: int): void { + this.nativeScale(x, y, level); + } + + native nativeCrop(region: Region): void; + + public cropSync(region: Region): void { + this.nativeCrop(region); + } + public crop(region: Region): Promise { + return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + const cb = (): boolean => { + this.nativeCrop(region); + return true; + }; + taskpool.execute(cb) + .then((): void => resolve(Promise.resolve())); + }); + } + + native nativeFlip(horizontal: boolean, vertical: boolean): void; + + public flipSync(horizontal: boolean, vertical: boolean): void { + this.nativeFlip(horizontal, vertical); + } + + native nativeRelease(): void; + + public release(): Promise { + return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + const cb = (): boolean => { + this.nativeRelease(); + return true; + }; + taskpool.execute(cb) + .then((): void => resolve(Promise.resolve())); + }); + } + } + + export native function createPixelMapSync(options: InitializationOptions): PixelMap; + + // end pixelmap + + // imageSource + export interface SourceOptions { + sourceDensity: int; + sourcePixelFormat?: int; + sourceSize?: Size; + } + + interface ImagePropertyOptions { + index?: int; + defaultValue?: string; + } + + interface GetImagePropertyOptions { + index?: int; + defaultValue?: string; + } + + export interface DecodingOptions { + index?: Int; + sampleSize?: Int; + rotate?: Int; + editable?: Int; + desiredSize?: Size; + desiredRegion?: Region; + desiredPixelFormat?: Int; + fitDensity?: Int; + desiredColorSpace?: Int; + desiredDynamicRange?: Int; + resolutionQuality?: Int; + } + + export class DecodingOptionsInner implements DecodingOptions { + index?: Int | undefined = 0; + sampleSize?: Int | undefined = 1; + rotate?: Int | undefined = 0; + editable?: Int | undefined = 0; + desiredSize?: Size | undefined = { width: 100, height: 200 } + desiredRegion?: Region | undefined = { size: { width: 10, height: 20 }, x: 30, y: 40 }; + desiredPixelFormat?: Int | undefined = 3; + fitDensity?: Int | undefined = 1; + desiredColorSpace?: Int | undefined = 1; + desiredDynamicRange?: Int | undefined = 1; + resolutionQuality?: Int | undefined = 1; + } + + + export interface ImageSource { + getImageInfoSync(index: int): ImageInfo; + getImageInfo(index: int): Promise; + createPixelMapSync(options?: DecodingOptions): PixelMap; + createPixelMap(options?: DecodingOptions): Promise; + modifyImageProperty(key: string, value: string): void; + modifyImageProperties(records: Record): void; + getImageProperties(key: Array): Record; + release(): void; + } + + + export class ImageSourceInner implements ImageSource { + private nativeObj: long = 0; + + constructor(context: long) { + if (this.nativeObj == 0) { + this.nativeObj = context; + } + } + native nativeGetImageInfo(index: int): ImageInfo; + native nativeCreatePixelMap(options?: DecodingOptions): PixelMap; + private native modifyImageProperty(nativeObj: long, key: string, value: string): void; + native modifyImageProperties(records: Record): void; + native getImageProperties(key: Array): Record; + native release(): void; + + public createPixelMapSync(options?: DecodingOptions): PixelMap { + return this.nativeCreatePixelMap(options); + } + + public createPixelMap(options?: DecodingOptions): Promise { + return new Promise((resolve: (v: PixelMap) => void, reject: (error: Object) => void) => { + const cb = (): PixelMap => { + return this.nativeCreatePixelMap(options); + }; + taskpool.execute(cb) + .then((e: NullishType) => resolve(e as PixelMap)); + }); + } + + public modifyImageProperty(key: string, value: string): void { + this.modifyImageProperty(this.nativeObj, key, value); + return; + } + + public getImageInfoSync(index: int): ImageInfo { + return this.nativeGetImageInfo(index); + } + + public getImageInfo(index: int): Promise { + return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Object) => void) => { + const cb = (): ImageInfo => { + return this.nativeGetImageInfo(index); + }; + taskpool.execute(cb) + .then((e: NullishType) => resolve(e as ImageInfo)); + }); + } + } + + native function nativeCreateImageSourceByUri(uri: string): ImageSource; + native function nativeCreateImageSourceByFd(fd: Int): ImageSource; + + export function createImageSource(uri: string): ImageSource { + return nativeCreateImageSourceByUri(uri); + } + export function createImageSource(fd: Int): ImageSource { + return nativeCreateImageSourceByFd(fd); + } + // end imagesource + + //imagepacker + interface PackingOptionsForSequence { + frameCount: int; + delayTimeList: Array; + disposalTypes?: Array; + loopCount?: int; + } + + interface PackingOptionInterface { + format: string; + quality: Int; + bufferSize?: Int; + desiredDynamicRange?: Int; + needsPackProperties?: Int; + } + + export class PackingOption implements PackingOptionInterface { + format: string = ""; + quality: Int = 0; + bufferSize?: Int | undefined = 20971520; + desiredDynamicRange?: Int | undefined = 0; + needsPackProperties?: Int | undefined = 0; + } + + export interface ImagePacker { + packing(source: PixelMap, option: PackingOption): ArrayBuffer; + release(): void; + } + + class ImagePackerInner implements ImagePacker { + private nativeObj: long = 0; + + constructor(context: long) { + if (this.nativeObj == 0) { + this.nativeObj = context; + } + } + + native nativePackingWithPixelMap(source: PixelMap, option: PackingOption): ArrayBuffer; + + native nativeRelease(): void; + + public release(): void { + this.nativeRelease(); + } + + public packing(source: PixelMap, option: PackingOption): ArrayBuffer { + return this.nativePackingWithPixelMap(source, option); + } + supportedFormats: Array = new Array(""); + } + + export native function createImagePacker(): ImagePacker; + // end imagepcker + + // metadata + type HdrMetadataValue = HdrMetadataType | HdrStaticMetadata | ArrayBuffer | HdrGainmapMetadata; + + interface HdrStaticMetadata { + displayPrimariesX: Array; + displayPrimariesY: Array; + whitePointX: double; + whitePointY: double; + maxLuminance: double; + minLuminance: double; + maxContentLightLevel: double; + maxFrameAverageLightLevel: double; + } + + interface GainmapChannel { + gainmapMax: double; + gainmapMin: double; + gamma: double; + baseOffset: double; + alternateOffset: double; + } + + interface Metadata { + getProperties(key: Array): Promise> + setProperties(records: Record): Promise + getAllProperties(): Promise> + clone(): Promise + } + // END Meta + + interface HdrGainmapMetadata { + writerVersion: int; + miniVersion: int; + gainmapChannelCount: int; + useBaseColorFlag: boolean; + baseHeadroom: double; + alternateHeadroom: double; + channels: Array; + } + + // picture + interface Picture { + getMainPixelmap(): PixelMap; + } + + export class PictureInner implements Picture { + private nativeObj: long = 0; + + constructor(context: long) { + if (this.nativeObj == 0) { + this.nativeObj = context; + } + } + + native getMainPixelmap(): PixelMap; + } + + export native function createPicture(mainPixelmap: PixelMap): Picture; + + interface AuxiliaryPicture { + writePixelsFromBuffer(data: ArrayBuffer): Promise; + readPixelsToBuffer(): Promise; + getType(): AuxiliaryPictureType; + setMetadata(metadataType: MetadataType, metadata: Metadata): Promise + getMetadata(metadataType: MetadataType): Promise + getAuxiliaryPictureInfo(): AuxiliaryPictureInfo; + setAuxiliaryPictureInfo(info: AuxiliaryPictureInfo): void + release(): void + } + + interface AuxiliaryPictureInfo { + auxiliaryPictureType: AuxiliaryPictureType; + size: Size; + rowStride: number; + pixelFormat: PixelMapFormat; + colorSpace: int; + } + + interface DecodingOptionsForPicture { + desiredAuxiliaryPictures: Array; // Array + } +} // namespace \ No newline at end of file diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets new file mode 100644 index 000000000..2c8ca0511 --- /dev/null +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2025-2025 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. + */ + +import { image } from "../ets/@ohos.multimedia.image.ets"; + +function main() { + // test createPixemap & getImageInfo + console.log("Test PixelMap START"); + const opts: image.InitializationOptions = { + size: { width: 480, height: 360 }, + editable: true, + pixelFormat: 4, + }; + let pixelMap:image.PixelMap = image.createPixelMapSync(opts); + + if (pixelMap != undefined) { + console.log("Create PixelMap success"); + } + + const retImageInfo: image.ImageInfo = pixelMap.getImageInfoSync(); + console.log("Get image info: ", retImageInfo.size.width, retImageInfo.size.height, retImageInfo.pixelFormat, retImageInfo.mimeType); + pixelMap.getImageInfo() + .then((imageInfo: image.ImageInfo) => { + console.log("ASYNC Get image info: ", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.mimeType); + }); + + const rowBytes = pixelMap.getBytesNumberPerRow(); + console.log("PixelMap bytes per row: " + rowBytes); + const totalBytes = pixelMap.getPixelBytesNumber(); + console.log("PixelMap total bytes: " + totalBytes); + + if (retImageInfo.isHdr) { + console.log("Test PixelMap hdr "); + } else { + console.log("Test PixelMap not hdr "); + } + + pixelMap.scaleSync(2, 2); + const scaledInfo = pixelMap.getImageInfoSync(); + console.log("Scaled image info: ", scaledInfo.size.width, scaledInfo.size.height); + const region: image.Region = { + size: { width: 512, height: 512 }, + x: 0, + y: 0 + }; + pixelMap.cropSync(region); + const croppedInfo = pixelMap.getImageInfoSync(); + console.log("Cropped image info: ", croppedInfo.size.width, croppedInfo.size.height); + pixelMap.flipSync(true, true); + const flippedInfo = pixelMap.getImageInfoSync(); + console.log("Flipped image info: ", flippedInfo.size.width, flippedInfo.size.height); + + const alphaPixelMap = pixelMap.createAlphaPixelmapSync(); + if (alphaPixelMap != undefined) { + console.log("Create alpha PixelMap success"); + } + const alphaImageInfo = alphaPixelMap.getImageInfoSync(); + console.log("Alpha get image info: ", alphaImageInfo.size.width, alphaImageInfo.size.height, alphaImageInfo.pixelFormat, alphaImageInfo.alphaType); + pixelMap.createAlphaPixelmap() + .then((alphaPixelMap: image.PixelMap) => { + const alphaImageInfo = alphaPixelMap.getImageInfoSync(); + console.log("ASYNC Alpha get image info: ", alphaImageInfo.size.width, alphaImageInfo.size.height, alphaImageInfo.pixelFormat, alphaImageInfo.alphaType); + }) + + let imageSource: image.ImageSource = image.createImageSource("/data/local/tmp/test.png"); + if (imageSource != undefined) { + console.log("Create ImageSource by URI success"); + } + let imageSource2: image.ImageSource = image.createImageSource(1); + if (imageSource2 != undefined) { + console.log("Create ImageSource by FD success"); + } + + let imagesourceImageInfo: image.ImageInfo = imageSource.getImageInfoSync(1); + console.log("Test ImageSource.getImageInfoSync width: ", imagesourceImageInfo.size.width, imagesourceImageInfo.size.height, imagesourceImageInfo.pixelFormat, imagesourceImageInfo.density, imagesourceImageInfo.mimeType); + imageSource.getImageInfo(1) + .then((imageInfo: image.ImageInfo) => { + console.log("ASYNC ImageSource get image info:", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.density, imageInfo.mimeType); + }); + const decodeOpt: image.DecodingOptions = { + editable: 1, + }; + let pixelmap2: image.PixelMap = imageSource.createPixelMapSync(decodeOpt); + if (pixelmap2 != undefined) { + console.log("Create imageSource.createPixelMapSync success"); + } + imageSource.createPixelMap(decodeOpt) + .then((pixelmap2: image.PixelMap) => { + if (pixelmap2 != undefined) { + console.log("ASYNC Create imageSource PixelMap success") + } + }); + pixelmap2.release() + .then((): void => console.log("ASYNC Release PixelMap success")); + + imageSource.modifyImageProperty("Orientation", "Right-top"); + let map: Record = { + "Orientation": "Right-top", + "Software" : "", + "test" : "xxxxx", + }; + imageSource.modifyImageProperties(map); + let array:Array = new Array(4); + array[0] = "aa" + array[1] = "bb" + array[2] = "cc" + array[3] = "dd" + let propertys: Record = imageSource.getImageProperties(array); + console.log("Create imageSource.getImageProperties :" + propertys); + imageSource.release(); + + console.log("TEST ImagePacker begin"); + const imagePacker = image.createImagePacker(); + let packOpts: image.PackingOption = new image.PackingOption(); + packOpts.format = "image/jpeg"; + packOpts.quality = 90; + let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); + console.log("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); + imagePacker.release(); + + console.log("TEST pixelMap readPixelsToBuffer begin"); + let arrayBuffer: ArrayBuffer = new ArrayBuffer(opts.size.width * opts.size.height * 4); + pixelMap.readPixelsToBufferSync(arrayBuffer); + console.log("Read pixels to buffer success, size: " + arrayBuffer.byteLength); + pixelMap.readPixelsToBuffer(arrayBuffer) + .then((): void => console.log("ASYNC Read pixels to buffer success, size: " + arrayBuffer.byteLength)); + + console.log("TEST Picture begin"); + const picture = image.createPicture(pixelMap); + if (picture != undefined) { + console.log("Create picture success"); + } + const picturePixelMap = picture.getMainPixelmap(); + const pictureInfo = picturePixelMap.getImageInfoSync(); + console.log("Picture PixelMap image info: ", pictureInfo.size.width, pictureInfo.size.height, pictureInfo.pixelFormat, pictureInfo.alphaType); + + const regionAsync: image.Region = { + size: { width: 1, height: 1 }, + x: 256, + y: 256 + } + pixelMap.crop(regionAsync) + .then((): void => { + const croppedInfo = pixelMap.getImageInfoSync(); + console.log("ASYNC Cropped image info: ", croppedInfo.size.width, croppedInfo.size.height); + }); + + console.log("====== Sync methods completed ======") +} \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/ani_image_module.h b/frameworks/kits/ani/native/include/ani_image_module.h new file mode 100644 index 000000000..0691e6d63 --- /dev/null +++ b/frameworks/kits/ani/native/include/ani_image_module.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_ANI_IMAGE_MODULE_H +#define ANI_SRC_INCLUDE_ANI_IMAGE_MODULE_H + +#include "pixel_map_ani.h" +#include "image_source_ani.h" +#include "image_packer_ani.h" +#include "picture_ani.h" + +#endif // ANI_SRC_INCLUDE_ANI_IMAGE_MODULE_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/image_ani_utils.h b/frameworks/kits/ani/native/include/image_ani_utils.h new file mode 100644 index 000000000..eaa176dc7 --- /dev/null +++ b/frameworks/kits/ani/native/include/image_ani_utils.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_IMAGE_ANI_UTILS_H +#define ANI_SRC_INCLUDE_IMAGE_ANI_UTILS_H + +#include +#include "image_source_ani.h" +#include "pixel_map.h" +#include "pixel_map_ani.h" +#include "picture_ani.h" + +namespace OHOS { +namespace Media { + +class ImageAniUtils { +public: + static PixelMap* GetPixelMapFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); + static std::shared_ptr GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj); + static std::shared_ptr GetPictureFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); + static ani_object CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap); + static ani_object CreateAniPixelMap(ani_env* env, std::unique_ptr& pPixelMapAni); + static ani_object CreateAniImageSource(ani_env* env, std::unique_ptr& pImageSourceAni); + static ani_object CreateAniPicture(ani_env* env, std::unique_ptr& pPictureAni); + static ani_string GetAniString(ani_env *env, const std::string& str); +}; + +} // namespace Media +} // namespace OHOS + +#endif // ANI_SRC_INCLUDE_IMAGE_ANI_UTILS_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/image_packer_ani.h b/frameworks/kits/ani/native/include/image_packer_ani.h new file mode 100644 index 000000000..0449307f4 --- /dev/null +++ b/frameworks/kits/ani/native/include/image_packer_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_IMAGE_PACKER_ANI_H +#define ANI_SRC_INCLUDE_IMAGE_PACKER_ANI_H + +#include +#include "image_packer.h" + +namespace OHOS { +namespace Media { + +class ImagePackerAni { +public: + static ani_object CreateImagePackerAni([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj); + static ani_status Init(ani_env* env); + std::shared_ptr nativeImagePacker_ = nullptr; +}; + +} // namespace Media +} // namespace OHOS + +#endif // ANI_SRC_INCLUDE_IMAGE_PACKER_ANI_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/image_source_ani.h b/frameworks/kits/ani/native/include/image_source_ani.h new file mode 100644 index 000000000..b28b0ef52 --- /dev/null +++ b/frameworks/kits/ani/native/include/image_source_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_IMAGE_SOURCE_ANI_H +#define ANI_SRC_INCLUDE_IMAGE_SOURCE_ANI_H + +#include +#include "image_source.h" + +namespace OHOS { +namespace Media { + +class ImageSourceAni { +public: + static ani_object CreateImageSourceAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, + [[maybe_unused]] ani_object obj); + static ani_status Init(ani_env* env); + std::shared_ptr nativeImageSource_; +}; + +} // namespace Media +} // namespace OHOS + +#endif // ANI_SRC_INCLUDE_IMAGE_SOURCE_ANI_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/picture_ani.h b/frameworks/kits/ani/native/include/picture_ani.h new file mode 100644 index 000000000..d4d1fe34f --- /dev/null +++ b/frameworks/kits/ani/native/include/picture_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_PICTURE_ANI_H +#define ANI_SRC_INCLUDE_PICTURE_ANI_H + +#include +#include "picture.h" + +namespace OHOS { +namespace Media { + +class PictureAni { +public: + static ani_object CreatePictureAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, + [[maybe_unused]] ani_object obj); + static ani_status Init(ani_env* env); + std::shared_ptr nativePicture_; +}; + +} // namespace Media +} // namespace OHOS + +#endif // ANI_SRC_INCLUDE_PICTURE_ANI_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/include/pixel_map_ani.h b/frameworks/kits/ani/native/include/pixel_map_ani.h new file mode 100644 index 000000000..15718160b --- /dev/null +++ b/frameworks/kits/ani/native/include/pixel_map_ani.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef ANI_SRC_INCLUDE_PIXEL_MAP_ANI_H +#define ANI_SRC_INCLUDE_PIXEL_MAP_ANI_H + +#include +#include "pixel_map.h" + +namespace OHOS { +namespace Media { + +class PixelMapAni { +public: + static ani_object CreatePixelMapAni([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj); + static ani_object CreatePixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap); + static ani_status Init(ani_env* env); + std::shared_ptr nativePixelMap_; +}; + +} // namespace Media +} // namespace OHOS + +#endif // ANI_SRC_INCLUDE_PIXEL_MAP_ANI_H \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/ani_image_module.cpp b/frameworks/kits/ani/native/src/ani_image_module.cpp new file mode 100644 index 000000000..16e2c9ddb --- /dev/null +++ b/frameworks/kits/ani/native/src/ani_image_module.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2025 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 "ani_image_module.h" +#include "image_log.h" +#include "log_tags.h" +#include "media_errors.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "ANI_IMAGE_MODULE" + +ANI_EXPORT +ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + ani_env* env; + IMAGE_LOGD("ANI_Constructor in"); + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + IMAGE_LOGE("Unsupported ANI_VERSION_1"); + return ANI_ERROR; + } + static const char *staticClassName = "L@ohos/multimedia/image/image;"; + ani_class staticCls; + if (ANI_OK != env->FindClass(staticClassName, &staticCls)) { + IMAGE_LOGE("[ANI_Constructor] FindClass Not found "); + return ANI_ERROR; + } + std::array staticMethods = { + ani_native_function {"createPixelMapSync", nullptr, + reinterpret_cast(OHOS::Media::PixelMapAni::CreatePixelMapAni)}, + ani_native_function {"createImagePacker", nullptr, + reinterpret_cast(OHOS::Media::ImagePackerAni::CreateImagePackerAni)}, + ani_native_function {"nativeCreateImageSourceByUri", nullptr, + reinterpret_cast(OHOS::Media::ImageSourceAni::CreateImageSourceAni)}, + ani_native_function {"nativeCreateImageSourceByFd", nullptr, + reinterpret_cast(OHOS::Media::ImageSourceAni::CreateImageSourceAni)}, + ani_native_function {"createPicture", nullptr, + reinterpret_cast(OHOS::Media::PictureAni::CreatePictureAni)}, + }; + if (ANI_OK != env->Class_BindNativeMethods(staticCls, staticMethods.data(), staticMethods.size())) { + IMAGE_LOGE("Class_BindNativeMethods failed"); + return ANI_ERROR; + }; + OHOS::Media::PixelMapAni::Init(env); + OHOS::Media::ImagePackerAni::Init(env); + OHOS::Media::ImageSourceAni::Init(env); + OHOS::Media::PictureAni::Init(env); + *result = ANI_VERSION_1; + return ANI_OK; +} \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/image_ani_utils.cpp b/frameworks/kits/ani/native/src/image_ani_utils.cpp new file mode 100644 index 000000000..317fe0864 --- /dev/null +++ b/frameworks/kits/ani/native/src/image_ani_utils.cpp @@ -0,0 +1,233 @@ +/* +* Copyright (C) 2025 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 "image_ani_utils.h" +#include +#include +#include "pixel_map_ani.h" +#include "log_tags.h" +#include "media_errors.h" +#include "image_log.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "AniUtilsAni" + +namespace OHOS { +namespace Media { +using namespace std; + +PixelMap* ImageAniUtils::GetPixelMapFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + return ImageAniUtils::GetPixelMapFromEnvSp(env, obj).get(); +} + +shared_ptr ImageAniUtils::GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetPixelMapFromEnv] Object_GetField_Long fetch failed"); + return nullptr; + } + PixelMapAni* pixelmapAni = reinterpret_cast(nativeObj); + if (!pixelmapAni) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmapAni failed"); + return nullptr; + } + return pixelmapAni->nativePixelMap_; +} + +shared_ptr ImageAniUtils::GetPictureFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetPictureFromEnv] Object_GetField_Long fetch failed"); + return nullptr; + } + PictureAni* pictureAni = reinterpret_cast(nativeObj); + if (!pictureAni) { + IMAGE_LOGE("[GetPictureFromEnv] pictureAni failed"); + return nullptr; + } + return pictureAni->nativePicture_; +} + +static ani_object CreateAniImageInfo(ani_env* env) +{ + static const char* imageInfoClassName = "L@ohos/multimedia/image/image/ImageInfoInner;"; + ani_class imageInfoCls; + if (ANI_OK != env->FindClass(imageInfoClassName, &imageInfoCls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImageInfoInner;"); + return nullptr; + } + ani_method imageInfoCtor; + if (ANI_OK != env->Class_FindMethod(imageInfoCls, "", nullptr, &imageInfoCtor)) { + IMAGE_LOGE("Not found Class_FindMethod"); + return nullptr; + } + ani_object imageInfoValue; + if (ANI_OK != env->Object_New(imageInfoCls, imageInfoCtor, &imageInfoValue)) { + IMAGE_LOGE("New Context Fail"); + return nullptr; + } + return imageInfoValue; +} + +static bool SetImageInfoSize(ani_env* env, const ImageInfo& imgInfo, ani_object& imageInfoValue) +{ + ani_ref sizeref; + if (ANI_OK != env->Object_CallMethodByName_Ref(imageInfoValue, "size", + ":L@ohos/multimedia/image/image/Size;", &sizeref)) { + IMAGE_LOGE("Object_CallMethodByName_Ref failed"); + return false; + } + ani_object sizeObj = reinterpret_cast(sizeref); + if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "width", "I:V", + static_cast(imgInfo.size.width))) { + IMAGE_LOGE("Object_CallMethodByName_Void width failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "height", "I:V", + static_cast(imgInfo.size.height))) { + IMAGE_LOGE("Object_CallMethodByName_Void height failed"); + return false; + } + return true; +} + +ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap) +{ + if (pixelmap == nullptr) { + IMAGE_LOGE("[CreateImageInfoValueFromNative] pixelmap nullptr "); + return nullptr; + } + + ani_object imageInfoValue = CreateAniImageInfo(env); + if (imageInfoValue == nullptr) { + return nullptr; + } + + if (!SetImageInfoSize(env, imgInfo, imageInfoValue)) { + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "density", "I:V", + static_cast(imgInfo.baseDensity))) { + IMAGE_LOGE("Object_CallMethodByName_Void density failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "stride", "I:V", + static_cast(imgInfo.size.height))) { + IMAGE_LOGE("Object_CallMethodByName_Void stride failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "pixelFormat", "I:V", + static_cast(imgInfo.pixelFormat))) { + IMAGE_LOGE("Object_CallMethodByName_Void pixelFormat failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "alphaType", "I:V", + static_cast(imgInfo.alphaType))) { + IMAGE_LOGE("Object_CallMethodByName_Void alphaType failed"); + return nullptr; + } + ani_string encodeStr = ImageAniUtils::GetAniString(env, imgInfo.encodedFormat); + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "mimeType", + "Lstd/core/String;:V", encodeStr)) { + IMAGE_LOGE("Object_CallMethodByName_Void encodedFormat failed "); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "isHdr", "Z:V", pixelmap->IsHdr())) { + IMAGE_LOGE("Object_CallMethodByName_Void isHdr failed "); + return nullptr; + } + return imageInfoValue; +} + +ani_object ImageAniUtils::CreateAniPixelMap(ani_env* env, std::unique_ptr& pPixelMapAni) +{ + static const char* className = "L@ohos/multimedia/image/image/PixelMapInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PixelMapInner;"); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + IMAGE_LOGE("Not found "); + return nullptr; + } + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(pPixelMapAni.release()))) { + IMAGE_LOGE("New Context Fail"); + } + return aniValue; +} + +ani_object ImageAniUtils::CreateAniImageSource(ani_env* env, std::unique_ptr& pImageSourceAni) +{ + static const char* className = "L@ohos/multimedia/image/image/ImageSourceInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImageSourceInner;"); + return nullptr; + } + + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + IMAGE_LOGE("Not found "); + return nullptr; + } + + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(pImageSourceAni.release()))) { + IMAGE_LOGE("New Context Fail"); + } + return aniValue; +} + +ani_object ImageAniUtils::CreateAniPicture(ani_env* env, std::unique_ptr& pPictureAni) +{ + static const char* className = "L@ohos/multimedia/image/image/PictureInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PictureInner;"); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + IMAGE_LOGE("Not found "); + return nullptr; + } + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(pPictureAni.release()))) { + IMAGE_LOGE("New Context Fail"); + } + return aniValue; +} + +ani_string ImageAniUtils::GetAniString(ani_env *env, const string &str) +{ + ani_string aniMimeType = nullptr; + const char *utf8String = str.c_str(); + const ani_size stringLength = strlen(utf8String); + env->String_NewUTF8(utf8String, stringLength, &aniMimeType); + return aniMimeType; +} +} // Meida +} // OHOS \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/image_packer_ani.cpp b/frameworks/kits/ani/native/src/image_packer_ani.cpp new file mode 100644 index 000000000..9b1357397 --- /dev/null +++ b/frameworks/kits/ani/native/src/image_packer_ani.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2025 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 +#include +#include + +#include "image_ani_utils.h" +#include "image_packer_ani.h" +#include "image_log.h" +#include "log_tags.h" +#include "media_errors.h" +#include "pixel_map_ani.h" +#include "securec.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "ImagePackerAni" + +namespace OHOS { +namespace Media { +using namespace std; + +ani_object ImagePackerAni::CreateImagePackerAni([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj) +{ + std::unique_ptr imagePackerAni = std::make_unique(); + std::shared_ptr imagePacker = std::make_shared(); + imagePackerAni->nativeImagePacker_ = imagePacker; + + static const char* className = "L@ohos/multimedia/image/image/ImagePackerInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImagePacker;"); + return nullptr; + } + + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + IMAGE_LOGE("Not found Class_FindMethod"); + return nullptr; + } + + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(imagePackerAni.release()))) { + IMAGE_LOGE("New Context Fail"); + } + return aniValue; +} + +ImagePacker* GetImagePackerFromAniEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetImagePackerFromAniEnv] Object_GetField_Long fetch field "); + return nullptr; + } + ImagePackerAni* imagePackerAni = reinterpret_cast(nativeObj); + if (!imagePackerAni) { + IMAGE_LOGE("[GetImagePackerFromAniEnv] imagePackerAni field "); + return nullptr; + } + return (imagePackerAni->nativeImagePacker_).get(); +} + +std::string ANIUtils_ANIStringToStdString(ani_env *env, ani_string ani_str) +{ + ani_size strSize; + env->String_GetUTF8Size(ani_str, &strSize); + + std::vector buffer(strSize + 1); // +1 for null terminator + char* utfBuffer = buffer.data(); + + ani_size bytes_written = 0; + env->String_GetUTF8(ani_str, utfBuffer, strSize + 1, &bytes_written); + + utfBuffer[bytes_written] = '\0'; + std::string content = std::string(utfBuffer); + return content; +} + +bool ParsePackingOptions([[maybe_unused]] ani_env* env, ani_object para, PackOption &packOpts, uint32_t &outBufferSize) +{ + ani_ref tmptest; + if (ANI_OK != env->Object_CallMethodByName_Ref(para, "format", ":Lstd/core/String;", &tmptest)) { + IMAGE_LOGE("Object_CallMethodByName_Ref format failed"); + return false; + } + std::string retStr = ANIUtils_ANIStringToStdString(env, static_cast(tmptest)); + ani_status ret; + ani_ref qualityRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "quality", ":Lstd/core/Int;", &qualityRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild qualityRef:%{public}d", ret); + } + ani_int quality; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(qualityRef), + "unboxed", ":I", &quality)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild quality:%{public}d", ret); + } + ani_ref bufferSizeRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, + "bufferSize", ":Lstd/core/Int;", &bufferSizeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSizeRef:%{public}d", ret); + } + ani_int bufferSize; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(bufferSizeRef), + "unboxed", ":I", &bufferSize)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSize:%{public}d", ret); + } + ani_ref desiredDynamicRangeRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredDynamicRange", + ":Lstd/core/Int;", &desiredDynamicRangeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRangeRef:%{public}d", ret); + } + ani_int desiredDynamicRange; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredDynamicRangeRef), + "unboxed", ":I", &desiredDynamicRange)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRange:%{public}d", ret); + } + ani_ref needsPackPropertiesRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "needsPackProperties", + ":Lstd/core/Int;", &needsPackPropertiesRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild needsPackPropertiesRef:%{public}d", ret); + } + ani_int needsPackProperties; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(needsPackPropertiesRef), + "unboxed", ":I", &needsPackProperties)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild needsPackProperties:%{public}d", ret); + } + + packOpts.format = retStr; + packOpts.quality = static_cast(quality); + outBufferSize = bufferSize; + return true; +} + +ani_arraybuffer nativePackingWithPixelMap([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj, ani_object obj2, ani_object obj3) +{ + ImagePacker* imgPacker = GetImagePackerFromAniEnv(env, obj); + if (!imgPacker) { + IMAGE_LOGE("nativePackingWithPixelMap isPacker null "); + return nullptr; + } + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj2); + if (!pixelmap) { + IMAGE_LOGE("nativePackingWithPixelMap pixelmap null "); + return nullptr; + } + ani_class optsClass; + env->FindClass("L@ohos/multimedia/image/image/PackingOption;", &optsClass); + ani_boolean isOpts; + env->Object_InstanceOf(obj3, optsClass, &isOpts); + if (!isOpts) { + IMAGE_LOGE("nativePackingWithPixelMap pixelmap null "); + return nullptr; + } else { + IMAGE_LOGE("nativePackingWithPixelMap opts sucess "); + } + PackOption packOpts; + uint32_t bufferSize = 0; + if (!ParsePackingOptions(env, obj3, packOpts, bufferSize)) { + IMAGE_LOGE("ParsePackingOptions failed "); + return nullptr; + } + std::unique_ptr outBuffer = std::make_unique(bufferSize); + uint8_t* data = outBuffer.get(); + imgPacker->StartPacking(data, bufferSize, packOpts); + imgPacker->AddImage(*pixelmap); + int64_t packedSize = 0; + auto pacRes = imgPacker->FinalizePacking(packedSize); + if (pacRes) { + IMAGE_LOGE("FinalizePacking failed: %{public}d", pacRes); + return nullptr; + } + void* outData = static_cast(data); + ani_arraybuffer arrayBuffer; + env->CreateArrayBuffer(packedSize, &outData, &arrayBuffer); + return arrayBuffer; +} + +static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_long nativeObj {}; + bool ret; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[Release] Object_GetField_Long fetch field ret:%{public}d", ret); + return; + } + ImagePackerAni* imagePackerAni = reinterpret_cast(nativeObj); + if (imagePackerAni == nullptr) { + IMAGE_LOGE("[Release] get ImagePackerAni failed"); + } + imagePackerAni->nativeImagePacker_ = nullptr; + return; +} + +ani_status ImagePackerAni::Init(ani_env* env) +{ + static const char *className = "L@ohos/multimedia/image/image/ImagePackerInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImagePacker;"); + return ANI_ERROR; + } + std::array methods = { + ani_native_function {"nativePackingWithPixelMap", + "L@ohos/multimedia/image/image/PixelMap;L@ohos/multimedia/image/image/PackingOption;:Lescompat/ArrayBuffer;", + reinterpret_cast(OHOS::Media::nativePackingWithPixelMap)}, + ani_native_function {"nativeRelease", ":V", reinterpret_cast(OHOS::Media::Release)}, + }; + ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); + if (ANI_OK != ret) { + IMAGE_LOGE("[ImagePackerAni] Cannot bind native methods ret: %{public}d", ret); + return ANI_ERROR; + }; + return ANI_OK; +} +} // Media +} // OHOS \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp new file mode 100644 index 000000000..36c7d5285 --- /dev/null +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -0,0 +1,729 @@ +/* + * Copyright (C) 2025 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 +#include +#include +#include "image_source_ani.h" +#include "pixel_map_ani.h" +#include "image_ani_utils.h" +#include "log_tags.h" +#include "media_errors.h" +#include "image_log.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "ImageSourceAni" + +namespace OHOS { +namespace Media { +using namespace std; + +std::string ANIUtils_ANIStringToStdString2(ani_env *env, ani_string ani_str) +{ + ani_size strSize; + env->String_GetUTF8Size(ani_str, &strSize); + + std::vector buffer(strSize + 1); // +1 for null terminator + char* utfBuffer = buffer.data(); + + ani_size bytes_written = 0; + if (ANI_OK != env->String_GetUTF8(ani_str, utfBuffer, strSize + 1, &bytes_written)) { + IMAGE_LOGE("ANIUtils_ANIStringToStdString fail"); + return ""; + } + + utfBuffer[bytes_written] = '\0'; + std::string content = std::string(utfBuffer); + return content; +} + +ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, + [[maybe_unused]] ani_object obj) +{ + std::unique_ptr pImageSourceAni = std::make_unique(); + ani_class stringClass; + env->FindClass("Lstd/core/String;", &stringClass); + ani_boolean isString; + env->Object_InstanceOf(obj, stringClass, &isString); + if (isString) { + auto stringContent = ANIUtils_ANIStringToStdString2(env, static_cast(obj)); + IMAGE_LOGE("Object is String Object Content"); + SourceOptions opts; + uint32_t errorCode; + pImageSourceAni->nativeImageSource_ = ImageSource::CreateImageSource(stringContent, opts, errorCode); + if (pImageSourceAni->nativeImageSource_ == nullptr) { + IMAGE_LOGE("CreateImageSource failed'"); + } + } + + ani_class arrayBufferClass; + env->FindClass("Lescompat/ArrayBuffer;", &arrayBufferClass); + ani_boolean isArrayBuffer; + env->Object_InstanceOf(obj, arrayBufferClass, &isArrayBuffer); + if (isArrayBuffer) { + ani_int length; + env->Object_CallMethodByName_Int(obj, "getByteLength", nullptr, &length); + IMAGE_LOGI("Object is ArraryBuffer Length: %{public}d", length); + } + + ani_class intClass; + env->FindClass("Lstd/core/Int;", &intClass); + ani_boolean isInt; + env->Object_InstanceOf(obj, intClass, &isInt); + if (isInt) { + ani_int fd; + env->Object_CallMethodByName_Int(obj, "unboxed", ":I", &fd); + IMAGE_LOGI("fd: %{public}d", fd); + SourceOptions opts; + uint32_t errorCode; + pImageSourceAni->nativeImageSource_ = ImageSource::CreateImageSource(fd, opts, errorCode); + } + + if (pImageSourceAni->nativeImageSource_ == nullptr) { + IMAGE_LOGE("CreateImageSource failed'"); + } + return ImageAniUtils::CreateAniImageSource(env, pImageSourceAni); +} + +ani_object CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo) +{ + static const char* imageInfoClassName = "L@ohos/multimedia/image/image/ImageInfoInner;"; + ani_class imageInfoCls; + if (ANI_OK != env->FindClass(imageInfoClassName, &imageInfoCls)) { + IMAGE_LOGE("Not found %{public}s", imageInfoClassName); + return nullptr; + } + ani_method imageInfoCtor; + if (ANI_OK != env->Class_FindMethod(imageInfoCls, "", nullptr, &imageInfoCtor)) { + IMAGE_LOGE("Not found Class_FindMethod"); + return nullptr; + } + ani_object imageInfoValue; + if (ANI_OK !=env->Object_New(imageInfoCls, imageInfoCtor, &imageInfoValue)) { + IMAGE_LOGE("New Context Fail"); + } + ani_ref sizeref; + if (ANI_OK != env->Object_CallMethodByName_Ref(imageInfoValue, "size", + ":L@ohos/multimedia/image/image/Size;", &sizeref)) { + IMAGE_LOGE("Object_CallMethodByName_Ref failed"); + return nullptr; + } + ani_object sizeObj = reinterpret_cast(sizeref); + if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "width", "I:V", + static_cast(imgInfo.size.width))) { + IMAGE_LOGE("Object_CallMethodByName_Void width failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "height", "I:V", + static_cast(imgInfo.size.height))) { + IMAGE_LOGE("Object_CallMethodByName_Void height failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "density", "I:V", + static_cast(imgInfo.baseDensity))) { + IMAGE_LOGE("Object_CallMethodByName_Void density failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "stride", "I:V", + static_cast(imgInfo.size.height))) { + IMAGE_LOGE("Object_CallMethodByName_Void stride failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "pixelFormat", "I:V", + static_cast(imgInfo.pixelFormat))) { + IMAGE_LOGE("Object_CallMethodByName_Void pixelFormat failed"); + return nullptr; + } + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "alphaType", "I:V", + static_cast(imgInfo.alphaType))) { + IMAGE_LOGE("Object_CallMethodByName_Void alphaType failed"); + return nullptr; + } + ani_string encodeStr = ImageAniUtils::GetAniString(env, imgInfo.encodedFormat); + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "mimeType", + "Lstd/core/String;:V", encodeStr)) { + IMAGE_LOGE("Object_CallMethodByName_Void encodedFormat failed"); + return nullptr; + } + + return imageInfoValue; +} + +static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_int indexObj) +{ + ani_status ret; + IMAGE_LOGE("[GetImageInfo] Object_GetField_Long in"); + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetImageInfo] Object_GetField_Long fetch field"); + return nullptr; + } + IMAGE_LOGE("[GetImageInfo] Object_GetField_Long sucess "); + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + int index = reinterpret_cast(indexObj); + IMAGE_LOGE("[GetImageInfo] index: %{public}d", index); + ImageInfo imgInfo; + if (imageSourceAni != nullptr) { + IMAGE_LOGI("[GetImageInfo] get imageSourceAni success "); + } else { + IMAGE_LOGE("[GetImageInfo] imageSourceAni is nullptr "); + return nullptr; + } + return CreateImageInfoValueFromNative(env, imgInfo); +} + +bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) +{ + ani_boolean isUndefined; + env->Reference_IsUndefined(para, &isUndefined); + if (isUndefined) { + IMAGE_LOGE("ParseInitializationOptions isUndefined "); + return false; + } + + ani_status ret; + ani_ref indexRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "index", ":Lstd/core/Int;", &indexRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild indexRef:%{public}d", ret); + } + env->Reference_IsUndefined(indexRef, &isUndefined); + if (!isUndefined) { + ani_int index; + if (env->Object_CallMethodByName_Int(reinterpret_cast(indexRef), + "unboxed", ":I", &index) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild"); + } + IMAGE_LOGE("ParseDecodingOptions get index:%{public}d", index); + } + + ani_ref sampleRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "sampleSize", ":Lstd/core/Int;", &sampleRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild sampleRef:%{public}d", ret); + } + ani_int sample; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(sampleRef), + "unboxed", ":I", &sample)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild sample:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get sample:%{public}d", sample); + + ani_ref rotateRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "rotate", ":Lstd/core/Int;", &rotateRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild rotateRef:%{public}d", ret); + } + ani_int rotate; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(rotateRef), + "unboxed", ":I", &rotate)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild rotate:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get rotate:%{public}d", rotate); + + ani_ref editableRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "editable", ":Lstd/core/Int;", &editableRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild editableRef:%{public}d", ret); + } + ani_int editable; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(editableRef), + "unboxed", ":I", &editable)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild editable:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get editable:%{public}d", rotate); + + ani_ref size; + if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredSize", + ":L@ohos/multimedia/image/image/Size;", &size)) { + IMAGE_LOGE("Object_CallMethodByName_Ref size Faild"); + } + int32_t width; + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", &width)) { + IMAGE_LOGE("Object_CallMethodByName_Int width Faild"); + } + int32_t height; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), + "height", ":I", &height)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int height Faild :%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get width:%{public}d", width); + + ani_ref reginRef; + if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredRegion", + ":L@ohos/multimedia/image/image/Region;", ®inRef)) { + IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion Faild"); + } + if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast(reginRef), + "size", ":L@ohos/multimedia/image/image/Size;", &size)) { + IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion size Faild"); + } + width = 0; + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", &width)) { + IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion size width Faild"); + } + height = 0; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), + "height", ":I", &height)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion size height Faild :%{public}d", ret); + } + ani_ref xRef; + if (ANI_OK != env->Object_CallMethodByName_Ref(reinterpret_cast(reginRef), + "x", ":Lstd/core/Int;", &xRef)) { + IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion xRef Faild"); + } + ani_int x; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(xRef), "unboxed", ":I", &x)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion x Faild :%{public}d", ret); + } + ani_ref yRef; + if (ANI_OK != env->Object_CallMethodByName_Ref(reinterpret_cast(reginRef), + "y", ":Lstd/core/Int;", &yRef)) { + IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion yRef Faild"); + } + ani_int y; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(yRef), "unboxed", ":I", &y)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion y Faild :%{public}d", ret); + } + ani_ref desiredPixelFormatRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredPixelFormat", + ":Lstd/core/Int;", &desiredPixelFormatRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredPixelFormatRef:%{public}d", ret); + } + ani_int desiredPixelFormat; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredPixelFormatRef), + "unboxed", ":I", &desiredPixelFormat)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredPixelFormat:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get desiredPixelFormat:%{public}d", desiredPixelFormat); + ani_ref fitDensityRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, + "fitDensity", ":Lstd/core/Int;", &fitDensityRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild fitDensityRef:%{public}d", ret); + } + ani_int fitDensity; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(fitDensityRef), + "unboxed", ":I", &fitDensity)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild fitDensity:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get fitDensity:%{public}d", fitDensity); + ani_ref desiredColorSpaceRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredColorSpace", + ":Lstd/core/Int;", &desiredColorSpaceRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredColorSpaceRef:%{public}d", ret); + } + ani_int desiredColorSpace; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredColorSpaceRef), + "unboxed", ":I", &desiredColorSpace)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredColorSpace:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get desiredColorSpace:%{public}d", desiredColorSpace); + ani_ref desiredDynamicRangeRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredDynamicRange", + ":Lstd/core/Int;", &desiredDynamicRangeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredDynamicRangeRef:%{public}d", ret); + } + ani_int desiredDynamicRange; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredDynamicRangeRef), + "unboxed", ":I", &desiredDynamicRange)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRange:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get desiredDynamicRange:%{public}d", desiredDynamicRange); + ani_ref resolutionQualityRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "resolutionQuality", + ":Lstd/core/Int;", &resolutionQualityRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild resolutionQualityRef:%{public}d", ret); + } + ani_int resolutionQuality; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(resolutionQualityRef), + "unboxed", ":I", &resolutionQuality)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild resolutionQuality:%{public}d", ret); + } + IMAGE_LOGE("ParseDecodingOptions get resolutionQuality:%{public}d", resolutionQuality); + return true; +} + +static ani_object CreatePixelMap([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj, [[maybe_unused]]ani_object para) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[CreatePixelMap] Object_GetField_Long fetch field "); + return nullptr; + } + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + ImageInfo imgInfo; + imgInfo.encodedFormat = "abcdefg"; + if (imageSourceAni != nullptr) { + } else { + IMAGE_LOGE("[CreatePixelMap] imageSourceAni is nullptr"); + } + + DecodeOptions opts; + ParseDecodingOptions(env, para, opts); + + return PixelMapAni::CreatePixelMap(env, std::make_shared()); +} + +static void ModifyImageProperty([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, + ani_long longObj, ani_object key, ani_object value) +{ + IMAGE_LOGE("ModifyImageProperty in "); + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[ModifyImageProperty] Object_GetField_Long fetch field "); + return; + } + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + if (imageSourceAni == nullptr) { + IMAGE_LOGE("[ModifyImageProperty] get imageSourceAni failed"); + } + IMAGE_LOGE("[ModifyImageProperty] get imageSourceAni success"); + + ani_class stringClass; + env->FindClass("Lstd/core/String;", &stringClass); + ani_boolean isString; + env->Object_InstanceOf(key, stringClass, &isString); + std::string keyS = ""; + if (isString) { + keyS = ANIUtils_ANIStringToStdString2(env, static_cast(key)); + } + std::string valueS = ANIUtils_ANIStringToStdString2(env, static_cast(value)); + IMAGE_LOGI("ModifyImageProperty get key:%{public}s value:%{public}s", keyS.c_str(), valueS.c_str()); +} + + +template +static bool forEachMapEntry(ani_env *env, ani_object map_object, F &&callback) +{ + ani_ref keys; + if (ANI_OK != + env->Object_CallMethodByName_Ref(map_object, "keys", nullptr, &keys)) { + IMAGE_LOGE("Failed to get keys iterator"); + return false; + } + + bool success = true; + while (success) { + ani_ref next; + ani_boolean done; + + if (ANI_OK != env->Object_CallMethodByName_Ref( + static_cast(keys), "next", nullptr, &next)) { + IMAGE_LOGE("Failed to get next key"); + success = false; + break; + } + + if (ANI_OK != env->Object_GetFieldByName_Boolean( + static_cast(next), "done", &done)) { + IMAGE_LOGE("Failed to check iterator done"); + success = false; + break; + } + if (done) { + IMAGE_LOGE("[forEachMapEntry] done break"); + break; + } + + ani_ref key_value; + if (ANI_OK != env->Object_GetFieldByName_Ref(static_cast(next), + "value", &key_value)) { + IMAGE_LOGE("Failed to get key value"); + success = false; + break; + } + + ani_ref value_obj; + if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "$_get", nullptr, + &value_obj, key_value)) { + IMAGE_LOGE("Failed to get value for key"); + success = false; + break; + } + + if (!callback(key_value, value_obj)) { + success = false; + break; + } + } + return success; +} + + +class ANIIntanceHelper { +public: + ANIIntanceHelper() = default; + explicit ANIIntanceHelper(ani_env *aniEnv) { env = aniEnv; }; + bool Init() + { + if (ANI_OK != env->FindClass("Lstd/core/String;", &stringType)) { + IMAGE_LOGE("FindClass std/core/String FAILD"); + return false; + } + if (ANI_OK != env->FindClass("Lescompat/Record;", &recordType)) { + IMAGE_LOGE("FindClass Lescompat/Record; FAILD"); + return false; + } + if (ANI_OK != env->FindClass("Lstd/core/Numeric;", &numberType)) { + IMAGE_LOGE("Lstd/core/Numeric; FAILD"); + return false; + } + inited = true; + return true; + } + bool isString(ani_object obj) + { + if (!inited) { + return false; + } + ani_boolean is_string; + if (ANI_OK != env->Object_InstanceOf(static_cast(obj), + static_cast(stringType), &is_string)) { + IMAGE_LOGE("Call Object_InstanceOf Fail"); + return false; + } + return (bool)is_string; + } + bool isRecord(ani_object obj) + { + if (!inited) { + return false; + } + ani_boolean is_record; + if (ANI_OK != env->Object_InstanceOf(static_cast(obj), + static_cast(recordType), &is_record)) { + IMAGE_LOGE("Call Object_InstanceOf Fail"); + return false; + } + return (bool)is_record; + } + bool isNumber(ani_object obj) + { + if (!inited) { + return false; + } + ani_boolean is_number; + if (ANI_OK != env->Object_InstanceOf(static_cast(obj), + static_cast(numberType), &is_number)) { + IMAGE_LOGE("Call Object_InstanceOf Fail"); + return false; + } + return (bool)is_number; + } + bool isArray(ani_object obj) + { + if (!inited) { + return false; + } + ani_size arrayLength; + if (ANI_OK != + env->Array_GetLength(static_cast(obj), &arrayLength)) { + return false; + } + return true; + } +private: + ani_class stringType; + ani_class recordType; + ani_class numberType; + ani_env *env; + bool inited = false; +}; + +bool ProcMapEntry(ani_env *env, ani_ref key, ani_ref value, + ANIIntanceHelper &ih, std::map &input) +{ + if (!ih.isString(static_cast(key))) { + IMAGE_LOGE("[ProcMapEntry] key is not string"); + return false; + } + auto key_string = + ANIUtils_ANIStringToStdString2(env, static_cast(key)); + auto value_string = + ANIUtils_ANIStringToStdString2(env, static_cast(value)); + IMAGE_LOGI("[ProcMapEntry] ProcMapEntry key: %{public}s value:%{public}s", + key_string.c_str(), value_string.c_str()); + input[key_string] = value_string; + return true; +} + +static void ModifyImageProperties([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj, ani_object map_object) +{ + ani_long nativeObj {}; + bool ret; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[ModifyImageProperties] Object_GetField_Long fetch field ret:%{public}d", ret); + return; + } + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + if (imageSourceAni == nullptr) { + IMAGE_LOGE("[ModifyImageProperties] get imageSourceAni failed"); + } + IMAGE_LOGI("[ModifyImageProperties] get imageSourceAni success"); + + ANIIntanceHelper ih(env); + if (!ih.Init()) { + IMAGE_LOGE("ih init fail"); + return; + } + + std::map input; + forEachMapEntry(env, map_object, + [env, &ih, &input](ani_ref key, ani_ref value) -> bool { + return ProcMapEntry(env, key, value, ih, input); + }); + return; +} + +bool ParseArrayString([[maybe_unused]] ani_env* env, ani_object arrayObj, std::vector &strings) +{ + ani_double length; + if (ANI_OK != env->Object_GetPropertyByName_Double(arrayObj, "length", &length)) { + IMAGE_LOGE("Object_GetPropertyByName_Double length Failed"); + return false; + } + for (int i = 0; i < int(length); i++) { + ani_ref stringEntryRef; + if (ANI_OK != env->Object_CallMethodByName_Ref(arrayObj, "$_get", + "I:Lstd/core/Object;", &stringEntryRef, (ani_int)i)) { + IMAGE_LOGE("Object_GetPropertyByName_Double length Failed"); + return false; + } + strings.emplace_back(ANIUtils_ANIStringToStdString2(env, static_cast(stringEntryRef))); + } + return true; +} + +static ani_object GetImageProperties([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj, ani_object arrayObj) +{ + ani_long nativeObj {}; + bool ret; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetImageProperties] Object_GetField_Long fetch field ret:%{public}d", ret); + } + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + if (imageSourceAni == nullptr) { + IMAGE_LOGE("[GetImageProperties] get imageSourceAni failed"); + } + IMAGE_LOGI("[GetImageProperties] get imageSourceAni success"); + + std::vector strings; + ParseArrayString(env, arrayObj, strings); + for (const auto &s : strings) { + IMAGE_LOGE("Array String Content:%{public}s", s.c_str()); + } + std::map paras = { + {"aa", "11"}, + {"bb", "22"}, + }; + ani_status status; + ani_class recordCls; + status = env->FindClass("Lescompat/Record;", &recordCls); + if (status != ANI_OK) { + IMAGE_LOGE("FindClass failed status :%{public}u", status); + return nullptr; + } + ani_method ctor; + status = env->Class_FindMethod(recordCls, "", nullptr, &ctor); + if (status != ANI_OK) { + IMAGE_LOGE("Class_FindMethod failed status :%{public}u", status); + return nullptr; + } + ani_object argumentObject = {}; + if (ANI_OK != env->Object_New(recordCls, ctor, &argumentObject)) { + IMAGE_LOGE("Object_New Failed"); + return nullptr; + } + ani_method recordSetMethod; + status = env->Class_FindMethod(recordCls, "$_set", + "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod); + if (status != ANI_OK) { + IMAGE_LOGE("Class_FindMethod recordSetMethod Failed"); + return nullptr; + } + for (auto iter = paras.begin(); iter != paras.end(); ++iter) { + std::string key = iter->first; + std::string value = iter->second; + ani_string ani_key; + ani_string ani_value; + status = env->String_NewUTF8(key.c_str(), key.length(), &ani_key); + if (status != ANI_OK) { + IMAGE_LOGE("String_NewUTF8 key failed status :%{public}u", status); + return nullptr; + } + status = env->String_NewUTF8(value.c_str(), value.length(), &ani_value); + if (status != ANI_OK) { + IMAGE_LOGE("String_NewUTF8 value failed status : %{public}u", status); + return nullptr; + } + status = env->Object_CallMethod_Void(argumentObject, recordSetMethod, ani_key, ani_value); + if (status != ANI_OK) { + IMAGE_LOGE("Object_CallMethod_Void value failed status : %{public}u", status); + return nullptr; + } + } + return argumentObject; +} + +static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_long nativeObj {}; + bool ret; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[Release] Object_GetField_Long fetch field ret:%{public}d", ret); + return; + } + ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + if (imageSourceAni == nullptr) { + IMAGE_LOGE("[Release] get imageSourceAni failed"); + } + return; +} + +ani_status ImageSourceAni::Init(ani_env* env) +{ + static const char *className = "L@ohos/multimedia/image/image/ImageSourceInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found "); + return ANI_ERROR; + } + std::array methods = { + ani_native_function {"nativeGetImageInfo", "I:L@ohos/multimedia/image/image/ImageInfo;", + reinterpret_cast(OHOS::Media::GetImageInfo)}, + ani_native_function {"nativeCreatePixelMap", + "L@ohos/multimedia/image/image/DecodingOptions;:L@ohos/multimedia/image/image/PixelMap;", + reinterpret_cast(OHOS::Media::CreatePixelMap)}, + ani_native_function {"modifyImageProperty", "JLstd/core/String;Lstd/core/String;:V", + reinterpret_cast(OHOS::Media::ModifyImageProperty)}, + ani_native_function {"modifyImageProperties", "Lescompat/Record;:V", + reinterpret_cast(OHOS::Media::ModifyImageProperties)}, + ani_native_function {"getImageProperties", "Lescompat/Array;:Lescompat/Record;", + reinterpret_cast(OHOS::Media::GetImageProperties)}, + ani_native_function {"release", ":V", reinterpret_cast(OHOS::Media::Release)}, + }; + ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); + if (ANI_OK != ret) { + IMAGE_LOGE("[ImageSourceAni] Cannot bind native methods ret: %{public}d", ret); + return ANI_ERROR; + }; + return ANI_OK; +} +} // Media +} // OHOS diff --git a/frameworks/kits/ani/native/src/picture_ani.cpp b/frameworks/kits/ani/native/src/picture_ani.cpp new file mode 100644 index 000000000..619b8da29 --- /dev/null +++ b/frameworks/kits/ani/native/src/picture_ani.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2025 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 +#include + +#include "image_ani_utils.h" +#include "image_log.h" +#include "log_tags.h" +#include "media_errors.h" +#include "picture_ani.h" +#include "pixel_map_ani.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "PictureAni" + +namespace OHOS { +namespace Media { +using namespace std; + +ani_object PictureAni::CreatePictureAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, + [[maybe_unused]] ani_object obj) +{ + unique_ptr pPictureAni = std::make_unique(); + auto pixelMap = ImageAniUtils::GetPixelMapFromEnvSp(env, obj); + if (pixelMap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnvSp] pixelMap nullptr"); + return nullptr; + } + + pPictureAni->nativePicture_ = Picture::Create(pixelMap); + return ImageAniUtils::CreateAniPicture(env, pPictureAni); +} + + +static ani_object GetMainPixelmap([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + auto picture = ImageAniUtils::GetPictureFromEnv(env, obj); + if (picture == nullptr) { + IMAGE_LOGE("[GetPictureFromEnv] picture nullptr"); + return nullptr; + } + + return PixelMapAni::CreatePixelMap(env, picture->GetMainPixel()); +} + +ani_status PictureAni::Init(ani_env* env) +{ + static const char* className = "L@ohos/multimedia/image/image/PictureInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PictureInner;"); + return ANI_ERROR; + } + std::array methods = { + ani_native_function {"getMainPixelmap", ":L@ohos/multimedia/image/image/PixelMap;", + reinterpret_cast(OHOS::Media::GetMainPixelmap)}, + }; + ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); + if (ANI_OK != ret) { + IMAGE_LOGE("[Init] Class_BindNativeMethods failed: %{public}d", ret); + return ANI_ERROR; + }; + return ANI_OK; +} +} // Media +} // OHOS \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp new file mode 100644 index 000000000..3e92cbbc7 --- /dev/null +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2025 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 +#include +#include + +#include "image_ani_utils.h" +#include "image_log.h" +#include "log_tags.h" +#include "media_errors.h" +#include "pixel_map_ani.h" + +#undef LOG_DOMAIN +#define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE + +#undef LOG_TAG +#define LOG_TAG "PixelMapAni" + +namespace OHOS { +namespace Media { +using namespace std; + +bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object para, InitializationOptions &opts) +{ + ani_boolean isUndefined; + env->Reference_IsUndefined(para, &isUndefined); + if (isUndefined) { + IMAGE_LOGE("ParseInitializationOptions isUndefined "); + return false; + } + ani_class dateCls; + const char *className = "L@ohos/multimedia/image/image/Size;"; + if (ANI_OK != env->FindClass(className, &dateCls)) { + IMAGE_LOGE("Not found %{public}s", className); + return false; + } + ani_ref size; + if (ANI_OK != env->Object_CallMethodByName_Ref(para, "size", ":L@ohos/multimedia/image/image/Size;", &size)) { + IMAGE_LOGE("Object_GetFieldByName_Ref Failed"); + } + ani_status ret; + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), + "width", ":I", &opts.size.width)) { + IMAGE_LOGE("Object_CallMethodByName_Int width Failed"); + } + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), + "height", ":I", &opts.size.height)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int height Failed"); + } + ani_ref srcPixelFormatRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "srcPixelFormat", + ":Lstd/core/Int;", &srcPixelFormatRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed srcPixelFormatRef:%{public}d", ret); + } + ani_int srcPixelFormat; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(srcPixelFormatRef), + "unboxed", ":I", &srcPixelFormat)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed srcPixelFormat:%{public}d", ret); + } + ani_ref pixelFormatRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "pixelFormat", + ":Lstd/core/Int;", &pixelFormatRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed pixelFormatRef:%{public}d", ret); + } + ani_int pixelFormat; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(pixelFormatRef), + "unboxed", ":I", &pixelFormat)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed pixelFormat:%{public}d", ret); + } + opts.pixelFormat = static_cast(pixelFormat); + ani_ref editableRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, + "editable", ":Lstd/core/Boolean;", &editableRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed editableRef:%{public}d", ret); + } + ani_boolean editable; + if ((ret = env->Object_CallMethodByName_Boolean(reinterpret_cast(editableRef), + "unboxed", ":Z", &editable)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed editable:%{public}d", ret); + } + ani_ref alphaTypeRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "alphaType", ":Lstd/core/Int;", &alphaTypeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed alphaTypeRef:%{public}d", ret); + } + ani_int alphaType; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(alphaTypeRef), + "unboxed", ":I", &alphaType)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed alphaType:%{public}d", ret); + } + ani_ref scaleModeRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "scaleMode", ":Lstd/core/Int;", &scaleModeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed scaleModeRef:%{public}d", ret); + } + ani_int scaleMode; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(scaleModeRef), + "unboxed", ":I", &scaleMode)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed scaleMode:%{public}d", ret); + } + return true; +} + +bool ParseRegion([[maybe_unused]] ani_env* env, ani_object region, Rect& rect) +{ + ani_boolean undefined; + env->Reference_IsUndefined(region, &undefined); + if (undefined) { + IMAGE_LOGE("ParseRegion argument undefined"); + return false; + } + + ani_ref size; + if (ANI_OK != env->Object_CallMethodByName_Ref(region, "size", ":L@ohos/multimedia/image/image/Size;", + &size)) { + IMAGE_LOGE("Object_GetFieldByName_Ref Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", + &rect.width)) { + IMAGE_LOGE("Object_CallMethodByName_Int width Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "height", ":I", + &rect.height)) { + IMAGE_LOGE("Object_CallMethodByName_Int height Failed"); + return false; + } + + if (ANI_OK != env->Object_CallMethodByName_Int(region, "x", ":I", &rect.left)) { + IMAGE_LOGE("Object_CallMethodByName_Int x Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(region, "y", ":I", &rect.top)) { + IMAGE_LOGE("Object_CallMethodByName_Int y Failed"); + return false; + } + + return true; +} + +ani_object PixelMapAni::CreatePixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap) +{ + unique_ptr pPixelMapAni = make_unique(); + pPixelMapAni->nativePixelMap_ = pixelMap; + static const char* className = "L@ohos/multimedia/image/image/PixelMapInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PixelMapInner"); + return nullptr; + } + ani_method ctor; + if (ANI_OK != env->Class_FindMethod(cls, "", "J:V", &ctor)) { + IMAGE_LOGE("Not found ani_method"); + return nullptr; + } + ani_object aniValue; + if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast(pPixelMapAni.release()))) { + IMAGE_LOGE("New Context Fail"); + } + return aniValue; +} + +ani_object PixelMapAni::CreatePixelMapAni([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_class clazz, [[maybe_unused]] ani_object obj) +{ + unique_ptr pPixelMapAni = make_unique(); + InitializationOptions opts; + if (!ParseInitializationOptions(env, obj, opts)) { + IMAGE_LOGE("ParseInitializationOptions failed '"); + return nullptr; + } + + pPixelMapAni->nativePixelMap_ = PixelMap::Create(opts); + return ImageAniUtils::CreateAniPixelMap(env, pPixelMapAni); +} + +static ani_object CreateAlphaPixelmap([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + PixelMap* pixelMap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelMap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelMap nullptr"); + return nullptr; + } + + std::unique_ptr pPixelMapAni = std::make_unique(); + InitializationOptions opts; + opts.pixelFormat = PixelFormat::ALPHA_8; + pPixelMapAni->nativePixelMap_ = PixelMap::Create(*pixelMap, opts); + return ImageAniUtils::CreateAniPixelMap(env, pPixelMapAni); +} + +static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr "); + return nullptr; + } + ImageInfo imgInfo; + pixelmap->GetImageInfo(imgInfo); + return ImageAniUtils::CreateImageInfoValueFromNative(env, imgInfo, pixelmap); +} + +static ani_int GetBytesNumberPerRow([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr"); + return 0; + } + return pixelmap->GetRowBytes(); +} + +static ani_int GetPixelBytesNumber([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr"); + return 0; + } + return pixelmap->GetByteCount(); +} + +static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[nativeRelease] Object_GetField_Long fetch field"); + return; + } + PixelMapAni* pixelmapAni = reinterpret_cast(nativeObj); + pixelmapAni->nativePixelMap_ = nullptr; +} + +static void ReadPixelsToBuffer(ani_env* env, ani_object obj, ani_object param0) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[ReadPixelsToBuffer] pixelmap nullptr "); + return; + } + size_t bufferLength = 0; + void *dstbuffer = nullptr; + ani_arraybuffer arraybuffer = static_cast(param0); + if (ANI_OK != env->ArrayBuffer_GetInfo(arraybuffer, &dstbuffer, &bufferLength)) { + IMAGE_LOGE("[ReadPixelsToBuffer] ArrayBuffer_GetInfo failed"); + } + uint32_t ret = pixelmap->ReadPixels(bufferLength, static_cast(dstbuffer)); + if (ret != 0) { + IMAGE_LOGE("[ReadPixelsToBuffer] failed"); + } +} + +static void Scale([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_double x, ani_double y, + ani_int level) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr"); + return; + } + + pixelmap->scale(static_cast(x), static_cast(y), static_cast(level)); +} + +static void Crop([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_object region) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr"); + return; + } + + Rect rect; + if (!ParseRegion(env, region, rect)) { + IMAGE_LOGE("ParseRegion failed"); + return; + } + + pixelmap->crop(rect); +} + +static void Flip([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_boolean horizontal, + ani_boolean vertical) +{ + PixelMap* pixelmap = ImageAniUtils::GetPixelMapFromEnv(env, obj); + if (pixelmap == nullptr) { + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmap nullptr"); + return; + } + + pixelmap->flip(static_cast(horizontal), static_cast(vertical)); +} + +ani_status PixelMapAni::Init(ani_env* env) +{ + static const char *className = "L@ohos/multimedia/image/image/PixelMapInner;"; + ani_class cls; + if (ANI_OK != env->FindClass(className, &cls)) { + IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PixelMapInner;"); + return ANI_ERROR; + } + std::array methods = { + ani_native_function {"nativeCreateAlphaPixelmap", ":L@ohos/multimedia/image/image/PixelMap;", + reinterpret_cast(OHOS::Media::CreateAlphaPixelmap)}, + ani_native_function {"nativeGetImageInfo", ":L@ohos/multimedia/image/image/ImageInfo;", + reinterpret_cast(OHOS::Media::GetImageInfo)}, + ani_native_function {"getBytesNumberPerRow", ":I", reinterpret_cast(OHOS::Media::GetBytesNumberPerRow)}, + ani_native_function {"getPixelBytesNumber", ":I", reinterpret_cast(OHOS::Media::GetPixelBytesNumber)}, + ani_native_function {"nativeRelease", ":V", reinterpret_cast(OHOS::Media::Release)}, + ani_native_function {"nativeReadPixelsToBuffer", "Lescompat/ArrayBuffer;:V", + reinterpret_cast(OHOS::Media::ReadPixelsToBuffer)}, + ani_native_function {"nativeScale", "DDI:V", reinterpret_cast(OHOS::Media::Scale)}, + ani_native_function {"nativeCrop", "L@ohos/multimedia/image/image/Region;:V", + reinterpret_cast(OHOS::Media::Crop)}, + ani_native_function {"nativeFlip", "ZZ:V", reinterpret_cast(OHOS::Media::Flip)}, + }; + ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); + if (ANI_OK != ret) { + IMAGE_LOGE("[Init] Class_BindNativeMethods failed :%{public}d", ret); + return ANI_ERROR; + }; + return ANI_OK; +} +} // Media +} // OHOS \ No newline at end of file -- Gitee From c30e4279b4f984151e2e0128ff4cf205065a9734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 2 Apr 2025 18:06:50 +0800 Subject: [PATCH 02/53] =?UTF-8?q?=E5=9B=9E=E9=80=80=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- bundle.json | 1 + 1 file changed, 1 insertion(+) diff --git a/bundle.json b/bundle.json index 59aebc7de..b0412118b 100644 --- a/bundle.json +++ b/bundle.json @@ -59,6 +59,7 @@ "json", "ffrt", "openmax", + "os_account", "runtime_core", "qos_manager", "eventhandler", -- Gitee From 0f982560a1408fe4b284138372cfe1742fa387c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 3 Apr 2025 09:35:52 +0800 Subject: [PATCH 03/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20BUILD.gn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index 345638a58..9cd3dd0bc 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -46,9 +46,9 @@ ohos_shared_library("image_ani") { "native/src/pixel_map_ani.cpp", ] deps = [ - "//foundation/multimedia/image_framework/frameworks/innerkitsimpl/utils:image_utils", - "//foundation/multimedia/image_framework/interfaces/innerkits:image_native", - "//foundation/multimedia/image_framework/interfaces/kits/js/common:image", + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + "${image_subsystem}/interfaces/kits/js/common:image", ] external_deps = [ "ability_runtime:ability_runtime", -- Gitee From fa3fa57b8ffbc4660eb2f1973da1d1ac15c61d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Tue, 1 Apr 2025 17:56:41 +0800 Subject: [PATCH 04/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20property=20=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 34 ++- frameworks/kits/ani/ets/imageTest.ets | 40 ++-- .../kits/ani/native/include/image_ani_utils.h | 4 + .../ani/native/include/image_source_ani.h | 2 + .../kits/ani/native/src/image_ani_utils.cpp | 55 ++++- .../kits/ani/native/src/image_source_ani.cpp | 216 +++++++++--------- .../kits/ani/native/src/pixel_map_ani.cpp | 2 +- 7 files changed, 216 insertions(+), 137 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 626a5395b..1d4aca621 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -520,8 +520,8 @@ export namespace image { createPixelMapSync(options?: DecodingOptions): PixelMap; createPixelMap(options?: DecodingOptions): Promise; modifyImageProperty(key: string, value: string): void; - modifyImageProperties(records: Record): void; - getImageProperties(key: Array): Record; + modifyImageProperties(records: Record): Promise; + getImageProperties(key: Array): Promise>; release(): void; } @@ -534,11 +534,37 @@ export namespace image { this.nativeObj = context; } } + native nativeGetImageInfo(index: int): ImageInfo; native nativeCreatePixelMap(options?: DecodingOptions): PixelMap; private native modifyImageProperty(nativeObj: long, key: string, value: string): void; - native modifyImageProperties(records: Record): void; - native getImageProperties(key: Array): Record; + + native nativeModifyImageProperties(records: Record): void; + + modifyImageProperties(records: Record): Promise { + return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + const cb = (): boolean => { + this.nativeModifyImageProperties(records); + return true; + }; + taskpool.execute(cb) + .then((): void => resolve(Promise.resolve())); + }); + } + + native nativeGetImageProperties(key: Array): Record; + + public getImageProperties(key: Array): Promise> { + return new Promise>( + (resolve: (v: Record) => void, reject: (error: Object) => void) => { + const cb = (): Record => { + return this.nativeGetImageProperties(key); + }; + taskpool.execute(cb) + .then((e: NullishType) => resolve(e as Record)); + }); + } + native release(): void; public createPixelMapSync(options?: DecodingOptions): PixelMap { diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 2c8ca0511..120ee6fb9 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -83,11 +83,11 @@ function main() { console.log("Create ImageSource by FD success"); } - let imagesourceImageInfo: image.ImageInfo = imageSource.getImageInfoSync(1); - console.log("Test ImageSource.getImageInfoSync width: ", imagesourceImageInfo.size.width, imagesourceImageInfo.size.height, imagesourceImageInfo.pixelFormat, imagesourceImageInfo.density, imagesourceImageInfo.mimeType); - imageSource.getImageInfo(1) + let imagesourceImageInfo: image.ImageInfo = imageSource.getImageInfoSync(0); + console.log("Image source image info: ", imagesourceImageInfo.size.width, imagesourceImageInfo.size.height, imagesourceImageInfo.pixelFormat, imagesourceImageInfo.density, imagesourceImageInfo.mimeType); + imageSource.getImageInfo(0) .then((imageInfo: image.ImageInfo) => { - console.log("ASYNC ImageSource get image info:", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.density, imageInfo.mimeType); + console.log("ASYNC Image source image info:", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.density, imageInfo.mimeType); }); const decodeOpt: image.DecodingOptions = { editable: 1, @@ -106,20 +106,24 @@ function main() { .then((): void => console.log("ASYNC Release PixelMap success")); imageSource.modifyImageProperty("Orientation", "Right-top"); - let map: Record = { - "Orientation": "Right-top", - "Software" : "", - "test" : "xxxxx", - }; - imageSource.modifyImageProperties(map); - let array:Array = new Array(4); - array[0] = "aa" - array[1] = "bb" - array[2] = "cc" - array[3] = "dd" - let propertys: Record = imageSource.getImageProperties(array); - console.log("Create imageSource.getImageProperties :" + propertys); - imageSource.release(); + const map: Record = { + "Artist": "CQY", + "Make": "Huawei", + "Gamma": "0.9", + }; + imageSource.modifyImageProperties(map) + .then((): void => { + let array: Array = new Array(4); + array[0] = "Orientation"; + array[1] = "Artist"; + array[2] = "Make"; + array[3] = "Gamma"; + imageSource.getImageProperties(array) + .then((properties: Record): void => { + console.log("ASYNC Get image properties: " + properties); + }); + }) + // imageSource.release(); console.log("TEST ImagePacker begin"); const imagePacker = image.createImagePacker(); diff --git a/frameworks/kits/ani/native/include/image_ani_utils.h b/frameworks/kits/ani/native/include/image_ani_utils.h index eaa176dc7..33e952a8f 100644 --- a/frameworks/kits/ani/native/include/image_ani_utils.h +++ b/frameworks/kits/ani/native/include/image_ani_utils.h @@ -30,12 +30,16 @@ public: static PixelMap* GetPixelMapFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); static std::shared_ptr GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); + static ImageSourceAni* GetImageSourceAniFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); + static std::shared_ptr GetImageSourceFromEnv([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj); static std::shared_ptr GetPictureFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj); static ani_object CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap); static ani_object CreateAniPixelMap(ani_env* env, std::unique_ptr& pPixelMapAni); static ani_object CreateAniImageSource(ani_env* env, std::unique_ptr& pImageSourceAni); static ani_object CreateAniPicture(ani_env* env, std::unique_ptr& pPictureAni); static ani_string GetAniString(ani_env *env, const std::string& str); + static ani_method GetRecordSetMethod(ani_env* env, ani_object &argumentObj); }; } // namespace Media diff --git a/frameworks/kits/ani/native/include/image_source_ani.h b/frameworks/kits/ani/native/include/image_source_ani.h index b28b0ef52..8cd522941 100644 --- a/frameworks/kits/ani/native/include/image_source_ani.h +++ b/frameworks/kits/ani/native/include/image_source_ani.h @@ -28,6 +28,8 @@ public: [[maybe_unused]] ani_object obj); static ani_status Init(ani_env* env); std::shared_ptr nativeImageSource_; + std::string filePath_; + int fileDescriptor_; }; } // namespace Media diff --git a/frameworks/kits/ani/native/src/image_ani_utils.cpp b/frameworks/kits/ani/native/src/image_ani_utils.cpp index 317fe0864..e2dfcc25c 100644 --- a/frameworks/kits/ani/native/src/image_ani_utils.cpp +++ b/frameworks/kits/ani/native/src/image_ani_utils.cpp @@ -46,12 +46,34 @@ shared_ptr ImageAniUtils::GetPixelMapFromEnvSp([[maybe_unused]] ani_en } PixelMapAni* pixelmapAni = reinterpret_cast(nativeObj); if (!pixelmapAni) { - IMAGE_LOGE("[GetPixelMapFromEnv] pixelmapAni failed"); + IMAGE_LOGE("[GetPixelMapFromEnv] pixelmapAni nullptr"); return nullptr; } return pixelmapAni->nativePixelMap_; } +ImageSourceAni* ImageAniUtils::GetImageSourceAniFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) +{ + ani_status ret; + ani_long nativeObj {}; + if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { + IMAGE_LOGE("[GetImageSourceFromEnv] Object_GetField_Long fetch failed"); + return nullptr; + } + return reinterpret_cast(nativeObj); +} + +shared_ptr ImageAniUtils::GetImageSourceFromEnv([[maybe_unused]] ani_env* env, + [[maybe_unused]] ani_object obj) +{ + ImageSourceAni* imageSourceAni = ImageAniUtils::GetImageSourceAniFromEnv(env, obj); + if (!imageSourceAni) { + IMAGE_LOGE("[GetPictureFromEnv] imageSourceAni nullptr"); + return nullptr; + } + return imageSourceAni->nativeImageSource_; +} + shared_ptr ImageAniUtils::GetPictureFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) { ani_status ret; @@ -62,7 +84,7 @@ shared_ptr ImageAniUtils::GetPictureFromEnv([[maybe_unused]] ani_env* e } PictureAni* pictureAni = reinterpret_cast(nativeObj); if (!pictureAni) { - IMAGE_LOGE("[GetPictureFromEnv] pictureAni failed"); + IMAGE_LOGE("[GetPictureFromEnv] pictureAni nullptr"); return nullptr; } return pictureAni->nativePicture_; @@ -229,5 +251,34 @@ ani_string ImageAniUtils::GetAniString(ani_env *env, const string &str) env->String_NewUTF8(utf8String, stringLength, &aniMimeType); return aniMimeType; } + +ani_method ImageAniUtils::GetRecordSetMethod(ani_env* env, ani_object &argumentObj) +{ + ani_status status; + ani_class recordCls; + status = env->FindClass("Lescompat/Record;", &recordCls); + if (status != ANI_OK) { + IMAGE_LOGE("FindClass failed status :%{public}u", status); + return nullptr; + } + ani_method ctor; + status = env->Class_FindMethod(recordCls, "", nullptr, &ctor); + if (status != ANI_OK) { + IMAGE_LOGE("Class_FindMethod failed status :%{public}u", status); + return nullptr; + } + if (ANI_OK != env->Object_New(recordCls, ctor, &argumentObj)) { + IMAGE_LOGE("Object_New Failed"); + return nullptr; + } + ani_method recordSetMethod; + status = env->Class_FindMethod(recordCls, "$_set", + "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod); + if (status != ANI_OK) { + IMAGE_LOGE("Class_FindMethod recordSetMethod Failed"); + return nullptr; + } + return recordSetMethod; +} } // Meida } // OHOS \ No newline at end of file diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index 36c7d5285..ae460bc40 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -22,6 +22,7 @@ #include "log_tags.h" #include "media_errors.h" #include "image_log.h" +#include "string_ex.h" #undef LOG_DOMAIN #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE @@ -33,9 +34,11 @@ namespace OHOS { namespace Media { using namespace std; +static const string FILE_URL_PREFIX = "file://"; + std::string ANIUtils_ANIStringToStdString2(ani_env *env, ani_string ani_str) { - ani_size strSize; + ani_size strSize; env->String_GetUTF8Size(ani_str, &strSize); std::vector buffer(strSize + 1); // +1 for null terminator @@ -52,6 +55,15 @@ std::string ANIUtils_ANIStringToStdString2(ani_env *env, ani_string ani_str) return content; } +static string FileUrlToRawPath(const string &path) +{ + if (path.size() > FILE_URL_PREFIX.size() && + (path.compare(0, FILE_URL_PREFIX.size(), FILE_URL_PREFIX) == 0)) { + return path.substr(FILE_URL_PREFIX.size()); + } + return path; +} + ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, [[maybe_unused]] ani_object obj) { @@ -61,11 +73,13 @@ ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [ ani_boolean isString; env->Object_InstanceOf(obj, stringClass, &isString); if (isString) { - auto stringContent = ANIUtils_ANIStringToStdString2(env, static_cast(obj)); - IMAGE_LOGE("Object is String Object Content"); + string fileUrl = ANIUtils_ANIStringToStdString2(env, static_cast(obj)); + IMAGE_LOGI("Image source URI: %{public}s", fileUrl.c_str()); + pImageSourceAni->filePath_ = FileUrlToRawPath(fileUrl); SourceOptions opts; uint32_t errorCode; - pImageSourceAni->nativeImageSource_ = ImageSource::CreateImageSource(stringContent, opts, errorCode); + pImageSourceAni->nativeImageSource_ = + ImageSource::CreateImageSource(pImageSourceAni->filePath_, opts, errorCode); if (pImageSourceAni->nativeImageSource_ == nullptr) { IMAGE_LOGE("CreateImageSource failed'"); } @@ -88,7 +102,7 @@ ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [ if (isInt) { ani_int fd; env->Object_CallMethodByName_Int(obj, "unboxed", ":I", &fd); - IMAGE_LOGI("fd: %{public}d", fd); + IMAGE_LOGI("Image source fd: %{public}d", fd); SourceOptions opts; uint32_t errorCode; pImageSourceAni->nativeImageSource_ = ImageSource::CreateImageSource(fd, opts, errorCode); @@ -97,6 +111,7 @@ ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [ if (pImageSourceAni->nativeImageSource_ == nullptr) { IMAGE_LOGE("CreateImageSource failed'"); } + return ImageAniUtils::CreateAniImageSource(env, pImageSourceAni); } @@ -410,8 +425,7 @@ template static bool forEachMapEntry(ani_env *env, ani_object map_object, F &&callback) { ani_ref keys; - if (ANI_OK != - env->Object_CallMethodByName_Ref(map_object, "keys", nullptr, &keys)) { + if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "keys", ":Lescompat/IterableIterator;", &keys)) { IMAGE_LOGE("Failed to get keys iterator"); return false; } @@ -421,15 +435,13 @@ static bool forEachMapEntry(ani_env *env, ani_object map_object, F &&callback) ani_ref next; ani_boolean done; - if (ANI_OK != env->Object_CallMethodByName_Ref( - static_cast(keys), "next", nullptr, &next)) { + if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast(keys), "next", nullptr, &next)) { IMAGE_LOGE("Failed to get next key"); success = false; break; } - if (ANI_OK != env->Object_GetFieldByName_Boolean( - static_cast(next), "done", &done)) { + if (ANI_OK != env->Object_GetFieldByName_Boolean(static_cast(next), "done", &done)) { IMAGE_LOGE("Failed to check iterator done"); success = false; break; @@ -440,25 +452,20 @@ static bool forEachMapEntry(ani_env *env, ani_object map_object, F &&callback) } ani_ref key_value; - if (ANI_OK != env->Object_GetFieldByName_Ref(static_cast(next), - "value", &key_value)) { + if (ANI_OK != env->Object_GetFieldByName_Ref(static_cast(next), "value", &key_value)) { IMAGE_LOGE("Failed to get key value"); success = false; break; } ani_ref value_obj; - if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "$_get", nullptr, - &value_obj, key_value)) { + if (ANI_OK != env->Object_CallMethodByName_Ref(map_object, "$_get", nullptr, &value_obj, key_value)) { IMAGE_LOGE("Failed to get value for key"); success = false; break; } - if (!callback(key_value, value_obj)) { - success = false; - break; - } + callback(key_value, value_obj); } return success; } @@ -471,15 +478,15 @@ public: bool Init() { if (ANI_OK != env->FindClass("Lstd/core/String;", &stringType)) { - IMAGE_LOGE("FindClass std/core/String FAILD"); + IMAGE_LOGE("FindClass std/core/String failed"); return false; } if (ANI_OK != env->FindClass("Lescompat/Record;", &recordType)) { - IMAGE_LOGE("FindClass Lescompat/Record; FAILD"); + IMAGE_LOGE("FindClass Lescompat/Record; failed"); return false; } if (ANI_OK != env->FindClass("Lstd/core/Numeric;", &numberType)) { - IMAGE_LOGE("Lstd/core/Numeric; FAILD"); + IMAGE_LOGE("Lstd/core/Numeric; failed"); return false; } inited = true; @@ -493,7 +500,7 @@ public: ani_boolean is_string; if (ANI_OK != env->Object_InstanceOf(static_cast(obj), static_cast(stringType), &is_string)) { - IMAGE_LOGE("Call Object_InstanceOf Fail"); + IMAGE_LOGE("Call Object_InstanceOf failed"); return false; } return (bool)is_string; @@ -506,7 +513,7 @@ public: ani_boolean is_record; if (ANI_OK != env->Object_InstanceOf(static_cast(obj), static_cast(recordType), &is_record)) { - IMAGE_LOGE("Call Object_InstanceOf Fail"); + IMAGE_LOGE("Call Object_InstanceOf failed"); return false; } return (bool)is_record; @@ -544,57 +551,58 @@ private: bool inited = false; }; -bool ProcMapEntry(ani_env *env, ani_ref key, ani_ref value, - ANIIntanceHelper &ih, std::map &input) +bool ProcMapEntry(ani_env* env, ani_ref key, ani_ref value, ImageSourceAni* imageSourceAni, ANIIntanceHelper &ih) { + auto imageSource = imageSourceAni->nativeImageSource_; + if (imageSource == nullptr) { + IMAGE_LOGE("[ProcMapEntry] imageSource nullptr"); + return false; + } if (!ih.isString(static_cast(key))) { IMAGE_LOGE("[ProcMapEntry] key is not string"); return false; } - auto key_string = - ANIUtils_ANIStringToStdString2(env, static_cast(key)); - auto value_string = - ANIUtils_ANIStringToStdString2(env, static_cast(value)); - IMAGE_LOGI("[ProcMapEntry] ProcMapEntry key: %{public}s value:%{public}s", - key_string.c_str(), value_string.c_str()); - input[key_string] = value_string; + auto keyStr = ANIUtils_ANIStringToStdString2(env, static_cast(key)); + auto valueStr = ANIUtils_ANIStringToStdString2(env, static_cast(value)); + IMAGE_LOGI("[ProcMapEntry] ProcMapEntry key:%{public}s value:%{public}s", keyStr.c_str(), valueStr.c_str()); + + + if (!IsSameTextStr(imageSourceAni->filePath_, "")) { + imageSource->ModifyImageProperty(0, keyStr, valueStr, imageSourceAni->filePath_); + } else if (imageSourceAni->fileDescriptor_ != -1) { + imageSource->ModifyImageProperty(0, keyStr, valueStr, imageSourceAni->fileDescriptor_); + } else { + IMAGE_LOGE("There is no image source!"); + return false; + } return true; } -static void ModifyImageProperties([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_object obj, ani_object map_object) +static void ModifyImageProperties([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_object recordsObj) { - ani_long nativeObj {}; - bool ret; - if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { - IMAGE_LOGE("[ModifyImageProperties] Object_GetField_Long fetch field ret:%{public}d", ret); - return; - } - ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); + ImageSourceAni* imageSourceAni = ImageAniUtils::GetImageSourceAniFromEnv(env, obj); if (imageSourceAni == nullptr) { - IMAGE_LOGE("[ModifyImageProperties] get imageSourceAni failed"); + IMAGE_LOGE("[GetImageSourceFromEnv] imageSource nullptr"); + return; } - IMAGE_LOGI("[ModifyImageProperties] get imageSourceAni success"); - + ANIIntanceHelper ih(env); if (!ih.Init()) { - IMAGE_LOGE("ih init fail"); + IMAGE_LOGE("[ModifyImageProperties] ih init fail"); return; } - - std::map input; - forEachMapEntry(env, map_object, - [env, &ih, &input](ani_ref key, ani_ref value) -> bool { - return ProcMapEntry(env, key, value, ih, input); + + forEachMapEntry(env, recordsObj, + [env, &imageSourceAni, &ih](ani_ref key, ani_ref value) -> bool { + return ProcMapEntry(env, key, value, imageSourceAni, ih); }); - return; } bool ParseArrayString([[maybe_unused]] ani_env* env, ani_object arrayObj, std::vector &strings) { ani_double length; if (ANI_OK != env->Object_GetPropertyByName_Double(arrayObj, "length", &length)) { - IMAGE_LOGE("Object_GetPropertyByName_Double length Failed"); + IMAGE_LOGE("Object_GetPropecortyByName_Double length Failed"); return false; } for (int i = 0; i < int(length); i++) { @@ -609,57 +617,44 @@ bool ParseArrayString([[maybe_unused]] ani_env* env, ani_object arrayObj, std::v return true; } -static ani_object GetImageProperties([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_object obj, ani_object arrayObj) +static ani_object GetImageProperties([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, + ani_object arrayObj) { - ani_long nativeObj {}; - bool ret; - if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { - IMAGE_LOGE("[GetImageProperties] Object_GetField_Long fetch field ret:%{public}d", ret); - } - ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); - if (imageSourceAni == nullptr) { - IMAGE_LOGE("[GetImageProperties] get imageSourceAni failed"); - } - IMAGE_LOGI("[GetImageProperties] get imageSourceAni success"); - - std::vector strings; - ParseArrayString(env, arrayObj, strings); - for (const auto &s : strings) { - IMAGE_LOGE("Array String Content:%{public}s", s.c_str()); - } - std::map paras = { - {"aa", "11"}, - {"bb", "22"}, - }; - ani_status status; - ani_class recordCls; - status = env->FindClass("Lescompat/Record;", &recordCls); - if (status != ANI_OK) { - IMAGE_LOGE("FindClass failed status :%{public}u", status); + auto imageSource = ImageAniUtils::GetImageSourceFromEnv(env, obj); + if (imageSource == nullptr) { + IMAGE_LOGE("[GetImageProperties] imageSource nullptr"); return nullptr; } - ani_method ctor; - status = env->Class_FindMethod(recordCls, "", nullptr, &ctor); - if (status != ANI_OK) { - IMAGE_LOGE("Class_FindMethod failed status :%{public}u", status); - return nullptr; + + vector keyStrArray; + ParseArrayString(env, arrayObj, keyStrArray); + for (const auto &key : keyStrArray) { + cerr << "Array String Content: " << key << endl; } - ani_object argumentObject = {}; - if (ANI_OK != env->Object_New(recordCls, ctor, &argumentObject)) { - IMAGE_LOGE("Object_New Failed"); - return nullptr; + + vector> kVStrArray; + uint32_t errCode = SUCCESS; + for (auto keyStrIt = keyStrArray.begin(); keyStrIt != keyStrArray.end(); ++keyStrIt) { + string valueStr = ""; + errCode = imageSource->GetImagePropertyString(0, *keyStrIt, valueStr); + if (errCode == SUCCESS) { + kVStrArray.emplace_back(make_pair(*keyStrIt, valueStr)); + } else { + kVStrArray.emplace_back(make_pair(*keyStrIt, "")); + IMAGE_LOGE("errCode: %{public}u , exif key: %{public}s", errCode, keyStrIt->c_str()); + } } - ani_method recordSetMethod; - status = env->Class_FindMethod(recordCls, "$_set", - "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod); - if (status != ANI_OK) { - IMAGE_LOGE("Class_FindMethod recordSetMethod Failed"); - return nullptr; + + ani_object argumentObj = {}; + ani_method recordSetMethod = ImageAniUtils::GetRecordSetMethod(env, argumentObj); + if (recordSetMethod == nullptr) { + IMAGE_LOGE("[GetImageProperties] recordSetMethod nullptr"); } - for (auto iter = paras.begin(); iter != paras.end(); ++iter) { - std::string key = iter->first; - std::string value = iter->second; + + ani_status status; + for (auto iter = kVStrArray.begin(); iter != kVStrArray.end(); ++iter) { + string key = iter->first; + string value = iter->second; ani_string ani_key; ani_string ani_value; status = env->String_NewUTF8(key.c_str(), key.length(), &ani_key); @@ -672,28 +667,25 @@ static ani_object GetImageProperties([[maybe_unused]] ani_env* env, IMAGE_LOGE("String_NewUTF8 value failed status : %{public}u", status); return nullptr; } - status = env->Object_CallMethod_Void(argumentObject, recordSetMethod, ani_key, ani_value); + status = env->Object_CallMethod_Void(argumentObj, recordSetMethod, ani_key, ani_value); if (status != ANI_OK) { IMAGE_LOGE("Object_CallMethod_Void value failed status : %{public}u", status); return nullptr; } } - return argumentObject; + return argumentObj; } static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj) { + ani_status ret; ani_long nativeObj {}; - bool ret; if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { IMAGE_LOGE("[Release] Object_GetField_Long fetch field ret:%{public}d", ret); return; } ImageSourceAni* imageSourceAni = reinterpret_cast(nativeObj); - if (imageSourceAni == nullptr) { - IMAGE_LOGE("[Release] get imageSourceAni failed"); - } - return; + imageSourceAni->nativeImageSource_ = nullptr; } ani_status ImageSourceAni::Init(ani_env* env) @@ -706,16 +698,16 @@ ani_status ImageSourceAni::Init(ani_env* env) } std::array methods = { ani_native_function {"nativeGetImageInfo", "I:L@ohos/multimedia/image/image/ImageInfo;", - reinterpret_cast(OHOS::Media::GetImageInfo)}, + reinterpret_cast(OHOS::Media::GetImageInfo)}, ani_native_function {"nativeCreatePixelMap", "L@ohos/multimedia/image/image/DecodingOptions;:L@ohos/multimedia/image/image/PixelMap;", - reinterpret_cast(OHOS::Media::CreatePixelMap)}, + reinterpret_cast(OHOS::Media::CreatePixelMap)}, ani_native_function {"modifyImageProperty", "JLstd/core/String;Lstd/core/String;:V", - reinterpret_cast(OHOS::Media::ModifyImageProperty)}, - ani_native_function {"modifyImageProperties", "Lescompat/Record;:V", - reinterpret_cast(OHOS::Media::ModifyImageProperties)}, - ani_native_function {"getImageProperties", "Lescompat/Array;:Lescompat/Record;", - reinterpret_cast(OHOS::Media::GetImageProperties)}, + reinterpret_cast(OHOS::Media::ModifyImageProperty)}, + ani_native_function {"nativeModifyImageProperties", "Lescompat/Record;:V", + reinterpret_cast(OHOS::Media::ModifyImageProperties)}, + ani_native_function {"nativeGetImageProperties", "Lescompat/Array;:Lescompat/Record;", + reinterpret_cast(OHOS::Media::GetImageProperties)}, ani_native_function {"release", ":V", reinterpret_cast(OHOS::Media::Release)}, }; ani_status ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size()); diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp index 3e92cbbc7..df67ad75f 100644 --- a/frameworks/kits/ani/native/src/pixel_map_ani.cpp +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -238,7 +238,7 @@ static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object o ani_status ret; ani_long nativeObj {}; if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) { - IMAGE_LOGE("[nativeRelease] Object_GetField_Long fetch field"); + IMAGE_LOGE("[Release] Object_GetField_Long fetch field"); return; } PixelMapAni* pixelmapAni = reinterpret_cast(nativeObj); -- Gitee From 902e8247d8bf2e243a9a4c077e851ce4f752e5e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 2 Apr 2025 18:33:08 +0800 Subject: [PATCH 05/53] =?UTF-8?q?=E8=A1=A5=E9=BD=90=20enum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/ets/@ohos.multimedia.image.ets | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 1d4aca621..b0d9ed20b 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -272,6 +272,12 @@ export namespace image { UNPREMUL = 3 } + enum ResolutionQuality { + LOW = 1, + MEDIUM = 2, + HIGH = 3 + } + // common export interface Size { width: int, -- Gitee From 20286385b489d0350d959c51a13a0ff089e63fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Mon, 7 Apr 2025 20:07:22 +0800 Subject: [PATCH 06/53] =?UTF-8?q?ANI=20=E5=8D=87=E7=BA=A7=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/native/src/ani_image_module.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/frameworks/kits/ani/native/src/ani_image_module.cpp b/frameworks/kits/ani/native/src/ani_image_module.cpp index 16e2c9ddb..e0e271f7a 100644 --- a/frameworks/kits/ani/native/src/ani_image_module.cpp +++ b/frameworks/kits/ani/native/src/ani_image_module.cpp @@ -33,10 +33,9 @@ ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) IMAGE_LOGE("Unsupported ANI_VERSION_1"); return ANI_ERROR; } - static const char *staticClassName = "L@ohos/multimedia/image/image;"; - ani_class staticCls; - if (ANI_OK != env->FindClass(staticClassName, &staticCls)) { - IMAGE_LOGE("[ANI_Constructor] FindClass Not found "); + ani_namespace imageNamespace; + if (ANI_OK != env->FindNamespace("L@ohos/multimedia/image/image;", &imageNamespace)) { + IMAGE_LOGE("[ANI_Constructor] FindNamespace failed"); return ANI_ERROR; } std::array staticMethods = { @@ -51,8 +50,8 @@ ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) ani_native_function {"createPicture", nullptr, reinterpret_cast(OHOS::Media::PictureAni::CreatePictureAni)}, }; - if (ANI_OK != env->Class_BindNativeMethods(staticCls, staticMethods.data(), staticMethods.size())) { - IMAGE_LOGE("Class_BindNativeMethods failed"); + if (ANI_OK != env->Namespace_BindNativeFunctions(imageNamespace, staticMethods.data(), staticMethods.size())) { + IMAGE_LOGE("[ANI_Constructor] Namespace_BindNativeFunctions failed"); return ANI_ERROR; }; OHOS::Media::PixelMapAni::Init(env); -- Gitee From d1e423cf4b93e23f35dd1dddf95dcfe0a14038c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 9 Apr 2025 23:25:06 +0800 Subject: [PATCH 07/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=96=B0=E7=89=88=20AN?= =?UTF-8?q?I=20=E5=85=BC=E5=AE=B9=E6=80=A7=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/ets/imageTest.ets | 32 +++++++++++++++---- .../ani/native/include/image_packer_ani.h | 3 +- .../ani/native/include/image_source_ani.h | 3 +- .../kits/ani/native/include/picture_ani.h | 3 +- .../kits/ani/native/include/pixel_map_ani.h | 3 +- .../kits/ani/native/src/image_packer_ani.cpp | 3 +- .../kits/ani/native/src/image_source_ani.cpp | 3 +- .../kits/ani/native/src/picture_ani.cpp | 3 +- .../kits/ani/native/src/pixel_map_ani.cpp | 3 +- 9 files changed, 34 insertions(+), 22 deletions(-) diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 120ee6fb9..c1b7ed926 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -18,11 +18,14 @@ import { image } from "../ets/@ohos.multimedia.image.ets"; function main() { // test createPixemap & getImageInfo console.log("Test PixelMap START"); - const opts: image.InitializationOptions = { - size: { width: 480, height: 360 }, - editable: true, - pixelFormat: 4, - }; + const opts: image.InitializationOptions = { + size: { width: 480, height: 360 }, + srcPixelFormat: 4, + pixelFormat: 4, + editable: true, + alphaType: 2, + scaleMode: 0 + }; let pixelMap:image.PixelMap = image.createPixelMapSync(opts); if (pixelMap != undefined) { @@ -89,8 +92,25 @@ function main() { .then((imageInfo: image.ImageInfo) => { console.log("ASYNC Image source image info:", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.density, imageInfo.mimeType); }); + + const desiredSize: image.Size | undefined = { width: 60, height: 60 }; + const desiredRegion: image.Region | undefined = { + size: { width: 60, height: 60 }, + x: 0, + y: 0 + }; const decodeOpt: image.DecodingOptions = { - editable: 1, + index: 0, + sampleSize: 1, + rotate: 0, + editable: 1, + desiredSize, + desiredRegion, + desiredPixelFormat: 4, + fitDensity: 1, + desiredColorSpace: 1, + desiredDynamicRange: 1, + resolutionQuality: 100 }; let pixelmap2: image.PixelMap = imageSource.createPixelMapSync(decodeOpt); if (pixelmap2 != undefined) { diff --git a/frameworks/kits/ani/native/include/image_packer_ani.h b/frameworks/kits/ani/native/include/image_packer_ani.h index 0449307f4..2c50bf9ce 100644 --- a/frameworks/kits/ani/native/include/image_packer_ani.h +++ b/frameworks/kits/ani/native/include/image_packer_ani.h @@ -24,8 +24,7 @@ namespace Media { class ImagePackerAni { public: - static ani_object CreateImagePackerAni([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj); + static ani_object CreateImagePackerAni([[maybe_unused]] ani_env* env, ani_object obj); static ani_status Init(ani_env* env); std::shared_ptr nativeImagePacker_ = nullptr; }; diff --git a/frameworks/kits/ani/native/include/image_source_ani.h b/frameworks/kits/ani/native/include/image_source_ani.h index 8cd522941..aeb58d5e7 100644 --- a/frameworks/kits/ani/native/include/image_source_ani.h +++ b/frameworks/kits/ani/native/include/image_source_ani.h @@ -24,8 +24,7 @@ namespace Media { class ImageSourceAni { public: - static ani_object CreateImageSourceAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, - [[maybe_unused]] ani_object obj); + static ani_object CreateImageSourceAni([[maybe_unused]] ani_env* env, ani_object obj); static ani_status Init(ani_env* env); std::shared_ptr nativeImageSource_; std::string filePath_; diff --git a/frameworks/kits/ani/native/include/picture_ani.h b/frameworks/kits/ani/native/include/picture_ani.h index d4d1fe34f..9cc82d713 100644 --- a/frameworks/kits/ani/native/include/picture_ani.h +++ b/frameworks/kits/ani/native/include/picture_ani.h @@ -24,8 +24,7 @@ namespace Media { class PictureAni { public: - static ani_object CreatePictureAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, - [[maybe_unused]] ani_object obj); + static ani_object CreatePictureAni([[maybe_unused]] ani_env* env, ani_object obj); static ani_status Init(ani_env* env); std::shared_ptr nativePicture_; }; diff --git a/frameworks/kits/ani/native/include/pixel_map_ani.h b/frameworks/kits/ani/native/include/pixel_map_ani.h index 15718160b..f82a18ee4 100644 --- a/frameworks/kits/ani/native/include/pixel_map_ani.h +++ b/frameworks/kits/ani/native/include/pixel_map_ani.h @@ -24,8 +24,7 @@ namespace Media { class PixelMapAni { public: - static ani_object CreatePixelMapAni([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj); + static ani_object CreatePixelMapAni([[maybe_unused]] ani_env* env, ani_object obj); static ani_object CreatePixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap); static ani_status Init(ani_env* env); std::shared_ptr nativePixelMap_; diff --git a/frameworks/kits/ani/native/src/image_packer_ani.cpp b/frameworks/kits/ani/native/src/image_packer_ani.cpp index 9b1357397..0d35d72b8 100644 --- a/frameworks/kits/ani/native/src/image_packer_ani.cpp +++ b/frameworks/kits/ani/native/src/image_packer_ani.cpp @@ -35,8 +35,7 @@ namespace OHOS { namespace Media { using namespace std; -ani_object ImagePackerAni::CreateImagePackerAni([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_class clazz, [[maybe_unused]]ani_object obj) +ani_object ImagePackerAni::CreateImagePackerAni([[maybe_unused]] ani_env* env, ani_object obj) { std::unique_ptr imagePackerAni = std::make_unique(); std::shared_ptr imagePacker = std::make_shared(); diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index ae460bc40..b06b8965d 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -64,8 +64,7 @@ static string FileUrlToRawPath(const string &path) return path; } -ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, - [[maybe_unused]] ani_object obj) +ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, ani_object obj) { std::unique_ptr pImageSourceAni = std::make_unique(); ani_class stringClass; diff --git a/frameworks/kits/ani/native/src/picture_ani.cpp b/frameworks/kits/ani/native/src/picture_ani.cpp index 619b8da29..1afb6fd7e 100644 --- a/frameworks/kits/ani/native/src/picture_ani.cpp +++ b/frameworks/kits/ani/native/src/picture_ani.cpp @@ -33,8 +33,7 @@ namespace OHOS { namespace Media { using namespace std; -ani_object PictureAni::CreatePictureAni([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_class clazz, - [[maybe_unused]] ani_object obj) +ani_object PictureAni::CreatePictureAni([[maybe_unused]] ani_env* env, ani_object obj) { unique_ptr pPictureAni = std::make_unique(); auto pixelMap = ImageAniUtils::GetPixelMapFromEnvSp(env, obj); diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp index df67ad75f..08bae5d52 100644 --- a/frameworks/kits/ani/native/src/pixel_map_ani.cpp +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -172,8 +172,7 @@ ani_object PixelMapAni::CreatePixelMap([[maybe_unused]] ani_env* env, std::share return aniValue; } -ani_object PixelMapAni::CreatePixelMapAni([[maybe_unused]] ani_env* env, - [[maybe_unused]] ani_class clazz, [[maybe_unused]] ani_object obj) +ani_object PixelMapAni::CreatePixelMapAni([[maybe_unused]] ani_env* env, ani_object obj) { unique_ptr pPixelMapAni = make_unique(); InitializationOptions opts; -- Gitee From 69b7e5d4176ec5fb27c0749b5d06074143c01d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 9 Apr 2025 23:59:45 +0800 Subject: [PATCH 08/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20CodeCheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/native/src/image_source_ani.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index b06b8965d..43c34758a 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -72,7 +72,7 @@ ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, a ani_boolean isString; env->Object_InstanceOf(obj, stringClass, &isString); if (isString) { - string fileUrl = ANIUtils_ANIStringToStdString2(env, static_cast(obj)); + string fileUrl = ANIUtils_ANIStringToStdString2(env, static_cast(obj)); IMAGE_LOGI("Image source URI: %{public}s", fileUrl.c_str()); pImageSourceAni->filePath_ = FileUrlToRawPath(fileUrl); SourceOptions opts; @@ -565,7 +565,6 @@ bool ProcMapEntry(ani_env* env, ani_ref key, ani_ref value, ImageSourceAni* imag auto valueStr = ANIUtils_ANIStringToStdString2(env, static_cast(value)); IMAGE_LOGI("[ProcMapEntry] ProcMapEntry key:%{public}s value:%{public}s", keyStr.c_str(), valueStr.c_str()); - if (!IsSameTextStr(imageSourceAni->filePath_, "")) { imageSource->ModifyImageProperty(0, keyStr, valueStr, imageSourceAni->filePath_); } else if (imageSourceAni->fileDescriptor_ != -1) { @@ -627,10 +626,7 @@ static ani_object GetImageProperties([[maybe_unused]] ani_env* env, [[maybe_unus vector keyStrArray; ParseArrayString(env, arrayObj, keyStrArray); - for (const auto &key : keyStrArray) { - cerr << "Array String Content: " << key << endl; - } - + vector> kVStrArray; uint32_t errCode = SUCCESS; for (auto keyStrIt = keyStrArray.begin(); keyStrIt != keyStrArray.end(); ++keyStrIt) { @@ -645,7 +641,7 @@ static ani_object GetImageProperties([[maybe_unused]] ani_env* env, [[maybe_unus } ani_object argumentObj = {}; - ani_method recordSetMethod = ImageAniUtils::GetRecordSetMethod(env, argumentObj); + ani_method recordSetMethod = ImageAniUtils::GetRecordSetMethod(env, argumentObj); if (recordSetMethod == nullptr) { IMAGE_LOGE("[GetImageProperties] recordSetMethod nullptr"); } -- Gitee From 45fbe511202cad9074b872035f44ad058fbbe5b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 10 Apr 2025 00:01:12 +0800 Subject: [PATCH 09/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20CodeCheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/native/src/image_source_ani.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index 43c34758a..3c34ca3da 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -626,7 +626,7 @@ static ani_object GetImageProperties([[maybe_unused]] ani_env* env, [[maybe_unus vector keyStrArray; ParseArrayString(env, arrayObj, keyStrArray); - + vector> kVStrArray; uint32_t errCode = SUCCESS; for (auto keyStrIt = keyStrArray.begin(); keyStrIt != keyStrArray.end(); ++keyStrIt) { -- Gitee From 4c18b3f864bae62dd3bfd978ce77e69de1dba272 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 10 Apr 2025 17:08:06 +0800 Subject: [PATCH 10/53] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/native/src/image_packer_ani.cpp | 11 ++++++----- frameworks/kits/ani/native/src/image_source_ani.cpp | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/frameworks/kits/ani/native/src/image_packer_ani.cpp b/frameworks/kits/ani/native/src/image_packer_ani.cpp index 0d35d72b8..8a4c39e87 100644 --- a/frameworks/kits/ani/native/src/image_packer_ani.cpp +++ b/frameworks/kits/ani/native/src/image_packer_ani.cpp @@ -118,8 +118,8 @@ bool ParsePackingOptions([[maybe_unused]] ani_env* env, ani_object para, PackOpt } ani_int bufferSize; if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(bufferSizeRef), - "unboxed", ":I", &bufferSize)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSize:%{public}d", ret); + "unboxed", ":I", &bufferSize)) != ANI_OK || bufferSize <= 0) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSize or invalid bufferSize:%{public}d", ret); } ani_ref desiredDynamicRangeRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredDynamicRange", @@ -144,7 +144,7 @@ bool ParsePackingOptions([[maybe_unused]] ani_env* env, ani_object para, PackOpt packOpts.format = retStr; packOpts.quality = static_cast(quality); - outBufferSize = bufferSize; + outBufferSize = static_cast(bufferSize); return true; } @@ -204,9 +204,9 @@ static void Release([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object o ImagePackerAni* imagePackerAni = reinterpret_cast(nativeObj); if (imagePackerAni == nullptr) { IMAGE_LOGE("[Release] get ImagePackerAni failed"); + return; } imagePackerAni->nativeImagePacker_ = nullptr; - return; } ani_status ImagePackerAni::Init(ani_env* env) @@ -219,7 +219,8 @@ ani_status ImagePackerAni::Init(ani_env* env) } std::array methods = { ani_native_function {"nativePackingWithPixelMap", - "L@ohos/multimedia/image/image/PixelMap;L@ohos/multimedia/image/image/PackingOption;:Lescompat/ArrayBuffer;", + "L@ohos/multimedia/image/image/PixelMap;L@ohos/multimedia/image/image/PackingOption;" + ":Lescompat/ArrayBuffer;", reinterpret_cast(OHOS::Media::nativePackingWithPixelMap)}, ani_native_function {"nativeRelease", ":V", reinterpret_cast(OHOS::Media::Release)}, }; diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index 3c34ca3da..f03adf347 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -543,9 +543,9 @@ public: return true; } private: - ani_class stringType; - ani_class recordType; - ani_class numberType; + ani_class stringType = nullptr; + ani_class recordType = nullptr; + ani_class numberType = nullptr; ani_env *env; bool inited = false; }; -- Gitee From da4af9d05e1654609d8b4d18f6f92c7b19683d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 17 Apr 2025 22:18:18 +0800 Subject: [PATCH 11/53] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=94=B9=E5=9B=9E=E6=9E=9A=E4=B8=BE=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 47 ++++---- frameworks/kits/ani/ets/imageTest.ets | 13 +-- .../kits/ani/native/src/image_ani_utils.cpp | 106 ++++++++++++++++-- .../kits/ani/native/src/image_source_ani.cpp | 66 +---------- .../kits/ani/native/src/pixel_map_ani.cpp | 96 ++++++++-------- 5 files changed, 173 insertions(+), 155 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index b0d9ed20b..dc56f6974 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -206,7 +206,7 @@ export namespace image { GIF_LOOP_COUNT = 'GIFLoopCount' } - enum AntiAliasingLevel { + export enum AntiAliasingLevel { NONE = 0, LOW = 1, MEDIUM = 2, @@ -232,7 +232,7 @@ export namespace image { SDR = 1, } - enum ScaleMode { + export enum ScaleMode { FIT_TARGET_SIZE = 0, CENTER_CROP = 1 } @@ -250,8 +250,9 @@ export namespace image { FRAGMENT_METADATA = 2, } - enum PixelMapFormat { + export enum PixelMapFormat { UNKNOWN = 0, + ARGB_8888 = 1, RGB_565 = 2, RGBA_8888 = 3, BGRA_8888 = 4, @@ -262,10 +263,11 @@ export namespace image { NV12 = 9, RGBA_1010102 = 10, YCBCR_P010 = 11, - YCRCB_P010 = 12 + YCRCB_P010 = 12, + ASTC_4x4 = 102 } - enum AlphaType { + export enum AlphaType { UNKNOWN = 0, OPAQUE = 1, PREMUL = 2, @@ -310,8 +312,8 @@ export namespace image { size: Size; density: int; stride: int; - pixelFormat: int; - alphaType: int; + pixelFormat: PixelMapFormat; + alphaType: AlphaType; mimeType: string; isHdr: boolean; } @@ -320,9 +322,9 @@ export namespace image { size: Size = { width: 0, height: 0 }; density: int = 0; stride: int = 0; - pixelFormat: int = 0; - alphaType: int = 0; - mimeType: string = " "; + pixelFormat: PixelMapFormat = PixelMapFormat.UNKNOWN; + alphaType: AlphaType = AlphaType.UNKNOWN; + mimeType: string = ""; isHdr: boolean = false; } // end common @@ -330,20 +332,11 @@ export namespace image { // pixelmap export interface InitializationOptions { size: Size; - srcPixelFormat?: Int; - pixelFormat?: Int; + srcPixelFormat?: PixelMapFormat; + pixelFormat?: PixelMapFormat; editable?: boolean; - alphaType?: Int; - scaleMode?: Int; - } - - export class InitializationOptionsInner implements InitializationOptions { - size: Size = { width: 0, height: 0 }; - pixelFormat?: Int | undefined = 0; - srcPixelFormat?: Int | undefined = 0; - editable?: boolean | undefined = false; - alphaType?: Int | undefined = 0; - scaleMode?: Int | undefined = 0; + alphaType?: AlphaType; + scaleMode?: ScaleMode; } export interface PixelMap { @@ -356,7 +349,7 @@ export namespace image { readPixelsToBufferSync(buff: ArrayBuffer); readPixelsToBuffer(buff: ArrayBuffer): Promise; scaleSync(x: double, y: double): void; - scaleSync(x: double, y: double, level: int): void; + scaleSync(x: double, y: double, level: AntiAliasingLevel): void; cropSync(region: Region): void; crop(region: Region): Promise; flipSync(horizontal: boolean, vertical: boolean): void; @@ -425,12 +418,12 @@ export namespace image { }); } - native nativeScale(x: double, y: double, level: int): void; + native nativeScale(x: double, y: double, level: AntiAliasingLevel): void; public scaleSync(x: double, y: double): void { - this.nativeScale(x, y, 0); + this.nativeScale(x, y, AntiAliasingLevel.NONE); } - public scaleSync(x: double, y: double, level: int): void { + public scaleSync(x: double, y: double, level: AntiAliasingLevel): void { this.nativeScale(x, y, level); } diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index c1b7ed926..1b6b8e8aa 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -13,18 +13,17 @@ * limitations under the License. */ -import { image } from "../ets/@ohos.multimedia.image.ets"; +import { image } from "./@ohos.multimedia.image.ets"; function main() { // test createPixemap & getImageInfo console.log("Test PixelMap START"); const opts: image.InitializationOptions = { size: { width: 480, height: 360 }, - srcPixelFormat: 4, - pixelFormat: 4, + srcPixelFormat: image.PixelMapFormat.RGBA_8888, + pixelFormat: image.PixelMapFormat.BGRA_8888, editable: true, - alphaType: 2, - scaleMode: 0 + alphaType: image.AlphaType.UNPREMUL }; let pixelMap:image.PixelMap = image.createPixelMapSync(opts); @@ -33,10 +32,10 @@ function main() { } const retImageInfo: image.ImageInfo = pixelMap.getImageInfoSync(); - console.log("Get image info: ", retImageInfo.size.width, retImageInfo.size.height, retImageInfo.pixelFormat, retImageInfo.mimeType); + console.log("Get image info: ", retImageInfo.size.width, retImageInfo.size.height, retImageInfo.pixelFormat, retImageInfo.alphaType); pixelMap.getImageInfo() .then((imageInfo: image.ImageInfo) => { - console.log("ASYNC Get image info: ", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.mimeType); + console.log("ASYNC Get image info: ", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.alphaType); }); const rowBytes = pixelMap.getBytesNumberPerRow(); diff --git a/frameworks/kits/ani/native/src/image_ani_utils.cpp b/frameworks/kits/ani/native/src/image_ani_utils.cpp index e2dfcc25c..5cc848b30 100644 --- a/frameworks/kits/ani/native/src/image_ani_utils.cpp +++ b/frameworks/kits/ani/native/src/image_ani_utils.cpp @@ -133,13 +133,94 @@ static bool SetImageInfoSize(ani_env* env, const ImageInfo& imgInfo, ani_object& return true; } -ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap) +static string getPixelFormatItemName(PixelFormat format) { - if (pixelmap == nullptr) { - IMAGE_LOGE("[CreateImageInfoValueFromNative] pixelmap nullptr "); - return nullptr; + switch (format) { + case PixelFormat::ARGB_8888: + return "ARGB_8888"; + case PixelFormat::RGB_565: + return "RGB_565"; + case PixelFormat::RGBA_8888: + return "RGBA_8888"; + case PixelFormat::BGRA_8888: + return "BGRA_8888"; + case PixelFormat::RGB_888: + return "RGB_888"; + case PixelFormat::ALPHA_8: + return "ALPHA_8"; + case PixelFormat::RGBA_F16: + return "RGBA_F16"; + case PixelFormat::NV21: + return "NV21"; + case PixelFormat::NV12: + return "NV12"; + case PixelFormat::RGBA_1010102: + return "RGBA_1010102"; + case PixelFormat::YCBCR_P010: + return "YCBCR_P010"; + case PixelFormat::YCRCB_P010: + return "YCRCB_P010"; + case PixelFormat::ASTC_4x4: + return "ASTC_4x4"; + default: + return "UNKNOWN"; } +} +static ani_enum_item findPixelFormatEnumItem([[maybe_unused]] ani_env* env, PixelFormat format) +{ + ani_enum type; + if (ANI_OK != env->FindEnum("L@ohos/multimedia/image/image/PixelMapFormat;", &type)) { + IMAGE_LOGE("FindEnum for PixelMapFormat Failed"); + return {}; + } + + string itemName = getPixelFormatItemName(format); + + ani_enum_item enumItem; + if (ANI_OK != env->Enum_GetEnumItemByName(type, itemName.c_str(), &enumItem)) { + IMAGE_LOGE("Enum_GetEnumItemByName for PixelMapFormat Failed"); + return {}; + } + + return enumItem; +} + +static string getAlphaTypeItemName(AlphaType alphaType) +{ + switch (alphaType) { + case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE: + return "OPAQUE"; + case AlphaType::IMAGE_ALPHA_TYPE_PREMUL: + return "PREMUL"; + case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL: + return "UNPREMUL"; + default: + return "UNKNOWN"; + } +} + +static ani_enum_item findAlphaTypeEnumItem([[maybe_unused]] ani_env* env, AlphaType alphaType) +{ + ani_enum type; + if (ANI_OK != env->FindEnum("L@ohos/multimedia/image/image/AlphaType;", &type)) { + IMAGE_LOGE("FindEnum for AlphaType Failed"); + return {}; + } + + string itemName = getAlphaTypeItemName(alphaType); + + ani_enum_item enumItem; + if (ANI_OK != env->Enum_GetEnumItemByName(type, itemName.c_str(), &enumItem)) { + IMAGE_LOGE("Enum_GetEnumItemByName for AlphaType Failed"); + return {}; + } + + return enumItem; +} + +ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap) +{ ani_object imageInfoValue = CreateAniImageInfo(env); if (imageInfoValue == nullptr) { return nullptr; @@ -158,13 +239,13 @@ ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const Ima IMAGE_LOGE("Object_CallMethodByName_Void stride failed"); return nullptr; } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "pixelFormat", "I:V", - static_cast(imgInfo.pixelFormat))) { + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "pixelFormat", + "L@ohos/multimedia/image/image/PixelMapFormat;:V", findPixelFormatEnumItem(env, imgInfo.pixelFormat))) { IMAGE_LOGE("Object_CallMethodByName_Void pixelFormat failed"); return nullptr; } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "alphaType", "I:V", - static_cast(imgInfo.alphaType))) { + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "alphaType", + "L@ohos/multimedia/image/image/AlphaType;:V", findAlphaTypeEnumItem(env, imgInfo.alphaType))) { IMAGE_LOGE("Object_CallMethodByName_Void alphaType failed"); return nullptr; } @@ -174,9 +255,12 @@ ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const Ima IMAGE_LOGE("Object_CallMethodByName_Void encodedFormat failed "); return nullptr; } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "isHdr", "Z:V", pixelmap->IsHdr())) { - IMAGE_LOGE("Object_CallMethodByName_Void isHdr failed "); - return nullptr; + + if (pixelmap != nullptr) { + if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "isHdr", "Z:V", pixelmap->IsHdr())) { + IMAGE_LOGE("Object_CallMethodByName_Void isHdr failed "); + return nullptr; + } } return imageInfoValue; } diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index f03adf347..c1d5d7c2b 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -114,70 +114,6 @@ ani_object ImageSourceAni::CreateImageSourceAni([[maybe_unused]] ani_env* env, a return ImageAniUtils::CreateAniImageSource(env, pImageSourceAni); } -ani_object CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo) -{ - static const char* imageInfoClassName = "L@ohos/multimedia/image/image/ImageInfoInner;"; - ani_class imageInfoCls; - if (ANI_OK != env->FindClass(imageInfoClassName, &imageInfoCls)) { - IMAGE_LOGE("Not found %{public}s", imageInfoClassName); - return nullptr; - } - ani_method imageInfoCtor; - if (ANI_OK != env->Class_FindMethod(imageInfoCls, "", nullptr, &imageInfoCtor)) { - IMAGE_LOGE("Not found Class_FindMethod"); - return nullptr; - } - ani_object imageInfoValue; - if (ANI_OK !=env->Object_New(imageInfoCls, imageInfoCtor, &imageInfoValue)) { - IMAGE_LOGE("New Context Fail"); - } - ani_ref sizeref; - if (ANI_OK != env->Object_CallMethodByName_Ref(imageInfoValue, "size", - ":L@ohos/multimedia/image/image/Size;", &sizeref)) { - IMAGE_LOGE("Object_CallMethodByName_Ref failed"); - return nullptr; - } - ani_object sizeObj = reinterpret_cast(sizeref); - if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "width", "I:V", - static_cast(imgInfo.size.width))) { - IMAGE_LOGE("Object_CallMethodByName_Void width failed"); - return nullptr; - } - if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "height", "I:V", - static_cast(imgInfo.size.height))) { - IMAGE_LOGE("Object_CallMethodByName_Void height failed"); - return nullptr; - } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "density", "I:V", - static_cast(imgInfo.baseDensity))) { - IMAGE_LOGE("Object_CallMethodByName_Void density failed"); - return nullptr; - } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "stride", "I:V", - static_cast(imgInfo.size.height))) { - IMAGE_LOGE("Object_CallMethodByName_Void stride failed"); - return nullptr; - } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "pixelFormat", "I:V", - static_cast(imgInfo.pixelFormat))) { - IMAGE_LOGE("Object_CallMethodByName_Void pixelFormat failed"); - return nullptr; - } - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "alphaType", "I:V", - static_cast(imgInfo.alphaType))) { - IMAGE_LOGE("Object_CallMethodByName_Void alphaType failed"); - return nullptr; - } - ani_string encodeStr = ImageAniUtils::GetAniString(env, imgInfo.encodedFormat); - if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "mimeType", - "Lstd/core/String;:V", encodeStr)) { - IMAGE_LOGE("Object_CallMethodByName_Void encodedFormat failed"); - return nullptr; - } - - return imageInfoValue; -} - static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_int indexObj) { ani_status ret; @@ -198,7 +134,7 @@ static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] a IMAGE_LOGE("[GetImageInfo] imageSourceAni is nullptr "); return nullptr; } - return CreateImageInfoValueFromNative(env, imgInfo); + return ImageAniUtils::CreateImageInfoValueFromNative(env, imgInfo, nullptr); } bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp index 08bae5d52..71226581c 100644 --- a/frameworks/kits/ani/native/src/pixel_map_ani.cpp +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -33,10 +33,33 @@ namespace OHOS { namespace Media { using namespace std; -bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object para, InitializationOptions &opts) +ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) +{ + ani_status ret; + ani_ref enumRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(param, propertyGet.c_str(), enumType.c_str(), &enumRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int enumRef Failed: %{public}d", ret); + return 0; + } + ani_boolean undefined; + env->Reference_IsUndefined(enumRef, &undefined); + if (undefined) { + IMAGE_LOGI("Enum %{public}s is undefined", propertyGet.c_str()); + return 0; + } + + ani_int enumIndex; + if (ANI_OK != env->EnumItem_GetValue_Int(static_cast(enumRef), &enumIndex)) { + IMAGE_LOGE("EnumItem_GetValue_Int enumIndex Failed: %{public}d", ret); + return 0; + } + return enumIndex; +} + +bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object param, InitializationOptions &opts) { ani_boolean isUndefined; - env->Reference_IsUndefined(para, &isUndefined); + env->Reference_IsUndefined(param, &isUndefined); if (isUndefined) { IMAGE_LOGE("ParseInitializationOptions isUndefined "); return false; @@ -48,7 +71,7 @@ bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object para, return false; } ani_ref size; - if (ANI_OK != env->Object_CallMethodByName_Ref(para, "size", ":L@ohos/multimedia/image/image/Size;", &size)) { + if (ANI_OK != env->Object_CallMethodByName_Ref(param, "size", ":L@ohos/multimedia/image/image/Size;", &size)) { IMAGE_LOGE("Object_GetFieldByName_Ref Failed"); } ani_status ret; @@ -60,29 +83,12 @@ bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object para, "height", ":I", &opts.size.height)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int height Failed"); } - ani_ref srcPixelFormatRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "srcPixelFormat", - ":Lstd/core/Int;", &srcPixelFormatRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed srcPixelFormatRef:%{public}d", ret); - } - ani_int srcPixelFormat; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(srcPixelFormatRef), - "unboxed", ":I", &srcPixelFormat)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed srcPixelFormat:%{public}d", ret); - } - ani_ref pixelFormatRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "pixelFormat", - ":Lstd/core/Int;", &pixelFormatRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed pixelFormatRef:%{public}d", ret); - } - ani_int pixelFormat; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(pixelFormatRef), - "unboxed", ":I", &pixelFormat)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed pixelFormat:%{public}d", ret); - } - opts.pixelFormat = static_cast(pixelFormat); + opts.srcPixelFormat = PixelFormat(parseEnumFromStruct(env, param, "srcPixelFormat", + ":L@ohos/multimedia/image/image/PixelMapFormat;")); + opts.pixelFormat = PixelFormat(parseEnumFromStruct(env, param, "pixelFormat", + ":L@ohos/multimedia/image/image/PixelMapFormat;")); ani_ref editableRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(param, "editable", ":Lstd/core/Boolean;", &editableRef))) { IMAGE_LOGE("Object_CallMethodByName_Int Failed editableRef:%{public}d", ret); } @@ -91,24 +97,10 @@ bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object para, "unboxed", ":Z", &editable)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Failed editable:%{public}d", ret); } - ani_ref alphaTypeRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "alphaType", ":Lstd/core/Int;", &alphaTypeRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed alphaTypeRef:%{public}d", ret); - } - ani_int alphaType; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(alphaTypeRef), - "unboxed", ":I", &alphaType)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed alphaType:%{public}d", ret); - } - ani_ref scaleModeRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "scaleMode", ":Lstd/core/Int;", &scaleModeRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed scaleModeRef:%{public}d", ret); - } - ani_int scaleMode; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(scaleModeRef), - "unboxed", ":I", &scaleMode)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Failed scaleMode:%{public}d", ret); - } + opts.alphaType = AlphaType(parseEnumFromStruct(env, param, "alphaType", + ":L@ohos/multimedia/image/image/AlphaType;")); + opts.scaleMode = ScaleMode(parseEnumFromStruct(env, param, "scaleMode", + ":L@ohos/multimedia/image/image/ScaleMode;")); return true; } @@ -272,7 +264,20 @@ static void Scale([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj return; } - pixelmap->scale(static_cast(x), static_cast(y), static_cast(level)); + ani_int levelIntValue = 0; + ani_enum enumType; + if (ANI_OK != env->FindEnum("L@ohos/multimedia/image/image/AntiAliasingLevel;", &enumType)) { + IMAGE_LOGI("Find Enum AntiAliasingLevel Failed"); + } + ani_enum_item enumItem; + if (ANI_OK != env->Enum_GetEnumItemByIndex(enumType, level, &enumItem)) { + IMAGE_LOGI("Enum_GetEnumItemByIndex AntiAliasingLevel Failed"); + } + if (ANI_OK != env->EnumItem_GetValue_Int(enumItem, &levelIntValue)) { + IMAGE_LOGI("EnumItem_GetValue_Int AntiAliasingLevel Failed"); + } + + pixelmap->scale(static_cast(x), static_cast(y), AntiAliasingOption(levelIntValue)); } static void Crop([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj, ani_object region) @@ -322,7 +327,8 @@ ani_status PixelMapAni::Init(ani_env* env) ani_native_function {"nativeRelease", ":V", reinterpret_cast(OHOS::Media::Release)}, ani_native_function {"nativeReadPixelsToBuffer", "Lescompat/ArrayBuffer;:V", reinterpret_cast(OHOS::Media::ReadPixelsToBuffer)}, - ani_native_function {"nativeScale", "DDI:V", reinterpret_cast(OHOS::Media::Scale)}, + ani_native_function {"nativeScale", "DDL@ohos/multimedia/image/image/AntiAliasingLevel;:V", + reinterpret_cast(OHOS::Media::Scale)}, ani_native_function {"nativeCrop", "L@ohos/multimedia/image/image/Region;:V", reinterpret_cast(OHOS::Media::Crop)}, ani_native_function {"nativeFlip", "ZZ:V", reinterpret_cast(OHOS::Media::Flip)}, -- Gitee From ebb8652594fdc5a1176110d106046a9ffca099bc Mon Sep 17 00:00:00 2001 From: Philipp Shemetov Date: Thu, 17 Apr 2025 18:24:09 +0300 Subject: [PATCH 12/53] Change interface of Promise Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/IC1PKR Testing: All required pre-merge tests passed. Results are available in the ggwatcher. Change-Id: Ibda70868c1ec1e37ed4e7627ae1a4ba8cf851ea9 Signed-off-by: Philipp Shemetov --- .../kits/ani/ets/@ohos.multimedia.image.ets | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index b0d9ed20b..2faeccf38 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -379,7 +379,7 @@ export namespace image { } public createAlphaPixelmap(): Promise { - return new Promise((resolve: (v: PixelMap) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: PixelMap) => void, reject: (error: Error) => void) => { const cb = (): PixelMap => { return this.nativeCreateAlphaPixelmap(); }; @@ -397,7 +397,7 @@ export namespace image { } public getImageInfo(): Promise { - return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Error) => void) => { const cb = (): ImageInfo => { return this.nativeGetImageInfo(); }; @@ -415,7 +415,7 @@ export namespace image { } public readPixelsToBuffer(buff: ArrayBuffer): Promise { - return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: Promise) => void, reject: (error: Error) => void) => { const cb = (): boolean => { this.nativeReadPixelsToBuffer(buff); return true; @@ -440,7 +440,7 @@ export namespace image { this.nativeCrop(region); } public crop(region: Region): Promise { - return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: Promise) => void, reject: (error: Error) => void) => { const cb = (): boolean => { this.nativeCrop(region); return true; @@ -459,7 +459,7 @@ export namespace image { native nativeRelease(): void; public release(): Promise { - return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: Promise) => void, reject: (error: Error) => void) => { const cb = (): boolean => { this.nativeRelease(); return true; @@ -548,7 +548,7 @@ export namespace image { native nativeModifyImageProperties(records: Record): void; modifyImageProperties(records: Record): Promise { - return new Promise((resolve: (v: Promise) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: Promise) => void, reject: (error: Error) => void) => { const cb = (): boolean => { this.nativeModifyImageProperties(records); return true; @@ -562,7 +562,7 @@ export namespace image { public getImageProperties(key: Array): Promise> { return new Promise>( - (resolve: (v: Record) => void, reject: (error: Object) => void) => { + (resolve: (v: Record) => void, reject: (error: Error) => void) => { const cb = (): Record => { return this.nativeGetImageProperties(key); }; @@ -578,7 +578,7 @@ export namespace image { } public createPixelMap(options?: DecodingOptions): Promise { - return new Promise((resolve: (v: PixelMap) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: PixelMap) => void, reject: (error: Error) => void) => { const cb = (): PixelMap => { return this.nativeCreatePixelMap(options); }; @@ -597,7 +597,7 @@ export namespace image { } public getImageInfo(index: int): Promise { - return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Object) => void) => { + return new Promise((resolve: (v: ImageInfo) => void, reject: (error: Error) => void) => { const cb = (): ImageInfo => { return this.nativeGetImageInfo(index); }; -- Gitee From 332114f419751c3f973f0c4ceffae9c1c420b721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 12:04:59 +0800 Subject: [PATCH 13/53] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=95=B4=E6=95=B0?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=94=B9=E5=9B=9E=E6=9E=9A=E4=B8=BE=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 27 +--- frameworks/kits/ani/ets/imageTest.ets | 7 +- .../kits/ani/native/src/image_source_ani.cpp | 152 ++++++++---------- .../kits/ani/native/src/pixel_map_ani.cpp | 6 +- 4 files changed, 81 insertions(+), 111 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index dc56f6974..68c2c2a8c 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -13,6 +13,8 @@ * limitations under the License. */ +import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; + export namespace image { loadLibrary("image_ani"); @@ -470,7 +472,7 @@ export namespace image { // imageSource export interface SourceOptions { sourceDensity: int; - sourcePixelFormat?: int; + sourcePixelFormat?: PixelMapFormat; sourceSize?: Size; } @@ -491,28 +493,13 @@ export namespace image { editable?: Int; desiredSize?: Size; desiredRegion?: Region; - desiredPixelFormat?: Int; + desiredPixelFormat?: PixelMapFormat; fitDensity?: Int; - desiredColorSpace?: Int; - desiredDynamicRange?: Int; - resolutionQuality?: Int; + desiredColorSpace?: colorSpaceManager.ColorSpaceManager; + desiredDynamicRange?: DecodingDynamicRange; + resolutionQuality?: ResolutionQuality; } - export class DecodingOptionsInner implements DecodingOptions { - index?: Int | undefined = 0; - sampleSize?: Int | undefined = 1; - rotate?: Int | undefined = 0; - editable?: Int | undefined = 0; - desiredSize?: Size | undefined = { width: 100, height: 200 } - desiredRegion?: Region | undefined = { size: { width: 10, height: 20 }, x: 30, y: 40 }; - desiredPixelFormat?: Int | undefined = 3; - fitDensity?: Int | undefined = 1; - desiredColorSpace?: Int | undefined = 1; - desiredDynamicRange?: Int | undefined = 1; - resolutionQuality?: Int | undefined = 1; - } - - export interface ImageSource { getImageInfoSync(index: int): ImageInfo; getImageInfo(index: int): Promise; diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 1b6b8e8aa..0121800c4 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -105,11 +105,8 @@ function main() { editable: 1, desiredSize, desiredRegion, - desiredPixelFormat: 4, - fitDensity: 1, - desiredColorSpace: 1, - desiredDynamicRange: 1, - resolutionQuality: 100 + desiredPixelFormat: image.PixelMapFormat.RGBA_8888, + fitDensity: 1 }; let pixelmap2: image.PixelMap = imageSource.createPixelMapSync(decodeOpt); if (pixelmap2 != undefined) { diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index c1d5d7c2b..fe21c5edc 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -137,7 +137,68 @@ static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] a return ImageAniUtils::CreateImageInfoValueFromNative(env, imgInfo, nullptr); } -bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) +static ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) +{ + ani_status ret; + ani_ref enumRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(param, propertyGet.c_str(), enumType.c_str(), &enumRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int enumRef Failed: %{public}d", ret); + return 0; + } + ani_boolean undefined; + env->Reference_IsUndefined(enumRef, &undefined); + if (undefined) { + IMAGE_LOGI("Enum %{public}s is undefined", propertyGet.c_str()); + return 0; + } + + ani_int enumIndex; + if (ANI_OK != env->EnumItem_GetValue_Int(static_cast(enumRef), &enumIndex)) { + IMAGE_LOGE("EnumItem_GetValue_Int enumIndex Failed: %{public}d", ret); + return 0; + } + return enumIndex; +} + +static bool ParseRegion([[maybe_unused]] ani_env* env, ani_object region, Rect& rect) +{ + ani_boolean undefined; + env->Reference_IsUndefined(region, &undefined); + if (undefined) { + IMAGE_LOGE("ParseRegion argument undefined"); + return false; + } + + ani_ref size; + if (ANI_OK != env->Object_CallMethodByName_Ref(region, "size", ":L@ohos/multimedia/image/image/Size;", + &size)) { + IMAGE_LOGE("Object_GetFieldByName_Ref Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", + &rect.width)) { + IMAGE_LOGE("Object_CallMethodByName_Int width Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "height", ":I", + &rect.height)) { + IMAGE_LOGE("Object_CallMethodByName_Int height Failed"); + return false; + } + + if (ANI_OK != env->Object_CallMethodByName_Int(region, "x", ":I", &rect.left)) { + IMAGE_LOGE("Object_CallMethodByName_Int x Failed"); + return false; + } + if (ANI_OK != env->Object_CallMethodByName_Int(region, "y", ":I", &rect.top)) { + IMAGE_LOGE("Object_CallMethodByName_Int y Failed"); + return false; + } + + return true; +} + +static bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) { ani_boolean isUndefined; env->Reference_IsUndefined(para, &isUndefined); @@ -158,7 +219,6 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "unboxed", ":I", &index) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild"); } - IMAGE_LOGE("ParseDecodingOptions get index:%{public}d", index); } ani_ref sampleRef; @@ -170,7 +230,6 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "unboxed", ":I", &sample)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild sample:%{public}d", ret); } - IMAGE_LOGE("ParseDecodingOptions get sample:%{public}d", sample); ani_ref rotateRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "rotate", ":Lstd/core/Int;", &rotateRef))) { @@ -181,7 +240,6 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "unboxed", ":I", &rotate)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild rotate:%{public}d", ret); } - IMAGE_LOGE("ParseDecodingOptions get rotate:%{public}d", rotate); ani_ref editableRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "editable", ":Lstd/core/Int;", &editableRef))) { @@ -192,7 +250,6 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "unboxed", ":I", &editable)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild editable:%{public}d", ret); } - IMAGE_LOGE("ParseDecodingOptions get editable:%{public}d", rotate); ani_ref size; if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredSize", @@ -208,55 +265,17 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "height", ":I", &height)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int height Faild :%{public}d", ret); } - IMAGE_LOGE("ParseDecodingOptions get width:%{public}d", width); - ani_ref reginRef; + ani_ref regionRef; if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredRegion", - ":L@ohos/multimedia/image/image/Region;", ®inRef)) { + ":L@ohos/multimedia/image/image/Region;", ®ionRef)) { IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion Faild"); } - if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast(reginRef), - "size", ":L@ohos/multimedia/image/image/Size;", &size)) { - IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion size Faild"); - } - width = 0; - if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", &width)) { - IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion size width Faild"); - } - height = 0; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), - "height", ":I", &height)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion size height Faild :%{public}d", ret); - } - ani_ref xRef; - if (ANI_OK != env->Object_CallMethodByName_Ref(reinterpret_cast(reginRef), - "x", ":Lstd/core/Int;", &xRef)) { - IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion xRef Faild"); - } - ani_int x; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(xRef), "unboxed", ":I", &x)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion x Faild :%{public}d", ret); + if (!ParseRegion(env, static_cast(regionRef), opts.desiredRegion)) { + IMAGE_LOGE("Parse desiredRegion Faild"); } - ani_ref yRef; - if (ANI_OK != env->Object_CallMethodByName_Ref(reinterpret_cast(reginRef), - "y", ":Lstd/core/Int;", &yRef)) { - IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion yRef Faild"); - } - ani_int y; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(yRef), "unboxed", ":I", &y)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int desiredRegion y Faild :%{public}d", ret); - } - ani_ref desiredPixelFormatRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredPixelFormat", - ":Lstd/core/Int;", &desiredPixelFormatRef))) { - IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredPixelFormatRef:%{public}d", ret); - } - ani_int desiredPixelFormat; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredPixelFormatRef), - "unboxed", ":I", &desiredPixelFormat)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredPixelFormat:%{public}d", ret); - } - IMAGE_LOGE("ParseDecodingOptions get desiredPixelFormat:%{public}d", desiredPixelFormat); + opts.desiredPixelFormat = PixelFormat(parseEnumFromStruct(env, para, "desiredPixelFormat", + ":L@ohos/multimedia/image/image/PixelMapFormat;")); ani_ref fitDensityRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "fitDensity", ":Lstd/core/Int;", &fitDensityRef))) { @@ -267,40 +286,7 @@ bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, Decode "unboxed", ":I", &fitDensity)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild fitDensity:%{public}d", ret); } - IMAGE_LOGE("ParseDecodingOptions get fitDensity:%{public}d", fitDensity); - ani_ref desiredColorSpaceRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredColorSpace", - ":Lstd/core/Int;", &desiredColorSpaceRef))) { - IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredColorSpaceRef:%{public}d", ret); - } - ani_int desiredColorSpace; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredColorSpaceRef), - "unboxed", ":I", &desiredColorSpace)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredColorSpace:%{public}d", ret); - } - IMAGE_LOGE("ParseDecodingOptions get desiredColorSpace:%{public}d", desiredColorSpace); - ani_ref desiredDynamicRangeRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredDynamicRange", - ":Lstd/core/Int;", &desiredDynamicRangeRef))) { - IMAGE_LOGE("Object_CallMethodByName_Ref Faild desiredDynamicRangeRef:%{public}d", ret); - } - ani_int desiredDynamicRange; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredDynamicRangeRef), - "unboxed", ":I", &desiredDynamicRange)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRange:%{public}d", ret); - } - IMAGE_LOGE("ParseDecodingOptions get desiredDynamicRange:%{public}d", desiredDynamicRange); - ani_ref resolutionQualityRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "resolutionQuality", - ":Lstd/core/Int;", &resolutionQualityRef))) { - IMAGE_LOGE("Object_CallMethodByName_Ref Faild resolutionQualityRef:%{public}d", ret); - } - ani_int resolutionQuality; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(resolutionQualityRef), - "unboxed", ":I", &resolutionQuality)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild resolutionQuality:%{public}d", ret); - } - IMAGE_LOGE("ParseDecodingOptions get resolutionQuality:%{public}d", resolutionQuality); + return true; } diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp index 71226581c..d0fbe6f74 100644 --- a/frameworks/kits/ani/native/src/pixel_map_ani.cpp +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -33,7 +33,7 @@ namespace OHOS { namespace Media { using namespace std; -ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) +static ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) { ani_status ret; ani_ref enumRef; @@ -56,7 +56,7 @@ ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, st return enumIndex; } -bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object param, InitializationOptions &opts) +static bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object param, InitializationOptions &opts) { ani_boolean isUndefined; env->Reference_IsUndefined(param, &isUndefined); @@ -104,7 +104,7 @@ bool ParseInitializationOptions([[maybe_unused]] ani_env* env, ani_object param, return true; } -bool ParseRegion([[maybe_unused]] ani_env* env, ani_object region, Rect& rect) +static bool ParseRegion([[maybe_unused]] ani_env* env, ani_object region, Rect& rect) { ani_boolean undefined; env->Reference_IsUndefined(region, &undefined); -- Gitee From e32caf658bde534d9d84652ef27d11499285a125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 14:20:05 +0800 Subject: [PATCH 14/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/native/src/image_source_ani.cpp | 84 ++++++++++--------- .../kits/ani/native/src/pixel_map_ani.cpp | 2 +- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index fe21c5edc..5daad99db 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -137,7 +137,7 @@ static ani_object GetImageInfo([[maybe_unused]] ani_env* env, [[maybe_unused]] a return ImageAniUtils::CreateImageInfoValueFromNative(env, imgInfo, nullptr); } -static ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) +static ani_int parseEnumFromStruct(ani_env* env, ani_object ¶m, string propertyGet, string enumType) { ani_status ret; ani_ref enumRef; @@ -198,15 +198,49 @@ static bool ParseRegion([[maybe_unused]] ani_env* env, ani_object region, Rect& return true; } -static bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) +static bool ParseDecodingOptions2([[maybe_unused]] ani_env* env, ani_object ¶m, DecodeOptions &opts) { - ani_boolean isUndefined; - env->Reference_IsUndefined(para, &isUndefined); - if (isUndefined) { - IMAGE_LOGE("ParseInitializationOptions isUndefined "); - return false; + ani_status ret; + ani_ref size; + if (ANI_OK != env->Object_CallMethodByName_Ref(param, "desiredSize", + ":L@ohos/multimedia/image/image/Size;", &size)) { + IMAGE_LOGE("Object_CallMethodByName_Ref size Faild"); + } + if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", + &opts.desiredSize.width)) { + IMAGE_LOGE("Object_CallMethodByName_Int width Faild"); + } + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), "height", ":I", + &opts.desiredSize.height)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int height Faild :%{public}d", ret); } + ani_ref regionRef; + if (ANI_OK != env->Object_CallMethodByName_Ref(param, "desiredRegion", + ":L@ohos/multimedia/image/image/Region;", ®ionRef)) { + IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion Faild"); + } + if (!ParseRegion(env, static_cast(regionRef), opts.desiredRegion)) { + IMAGE_LOGE("Parse desiredRegion Faild"); + } + opts.desiredPixelFormat = PixelFormat(parseEnumFromStruct(env, param, "desiredPixelFormat", + ":L@ohos/multimedia/image/image/PixelMapFormat;")); + ani_ref fitDensityRef; + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(param, + "fitDensity", ":Lstd/core/Int;", &fitDensityRef))) { + IMAGE_LOGE("Object_CallMethodByName_Ref Faild fitDensityRef:%{public}d", ret); + } + ani_int fitDensity; + if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(fitDensityRef), + "unboxed", ":I", &fitDensity)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Faild fitDensity:%{public}d", ret); + } + return true; +} + +static bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, DecodeOptions &opts) +{ + ani_boolean isUndefined; ani_status ret; ani_ref indexRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "index", ":Lstd/core/Int;", &indexRef))) { @@ -251,40 +285,8 @@ static bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, IMAGE_LOGE("Object_CallMethodByName_Int Faild editable:%{public}d", ret); } - ani_ref size; - if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredSize", - ":L@ohos/multimedia/image/image/Size;", &size)) { - IMAGE_LOGE("Object_CallMethodByName_Ref size Faild"); - } - int32_t width; - if (ANI_OK != env->Object_CallMethodByName_Int(reinterpret_cast(size), "width", ":I", &width)) { - IMAGE_LOGE("Object_CallMethodByName_Int width Faild"); - } - int32_t height; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(size), - "height", ":I", &height)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int height Faild :%{public}d", ret); - } - - ani_ref regionRef; - if (ANI_OK != env->Object_CallMethodByName_Ref(para, "desiredRegion", - ":L@ohos/multimedia/image/image/Region;", ®ionRef)) { - IMAGE_LOGE("Object_CallMethodByName_Ref desiredRegion Faild"); - } - if (!ParseRegion(env, static_cast(regionRef), opts.desiredRegion)) { - IMAGE_LOGE("Parse desiredRegion Faild"); - } - opts.desiredPixelFormat = PixelFormat(parseEnumFromStruct(env, para, "desiredPixelFormat", - ":L@ohos/multimedia/image/image/PixelMapFormat;")); - ani_ref fitDensityRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, - "fitDensity", ":Lstd/core/Int;", &fitDensityRef))) { - IMAGE_LOGE("Object_CallMethodByName_Ref Faild fitDensityRef:%{public}d", ret); - } - ani_int fitDensity; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(fitDensityRef), - "unboxed", ":I", &fitDensity)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild fitDensity:%{public}d", ret); + if (!ParseDecodingOptions2(env, para, opts)) { + return false; } return true; diff --git a/frameworks/kits/ani/native/src/pixel_map_ani.cpp b/frameworks/kits/ani/native/src/pixel_map_ani.cpp index d0fbe6f74..1cb9564ba 100644 --- a/frameworks/kits/ani/native/src/pixel_map_ani.cpp +++ b/frameworks/kits/ani/native/src/pixel_map_ani.cpp @@ -33,7 +33,7 @@ namespace OHOS { namespace Media { using namespace std; -static ani_int parseEnumFromStruct([[maybe_unused]] ani_env* env, ani_object ¶m, string propertyGet, string enumType) +static ani_int parseEnumFromStruct(ani_env* env, ani_object ¶m, string propertyGet, string enumType) { ani_status ret; ani_ref enumRef; -- Gitee From 1ed185254bac0b8255cdf53a7bd264ba76899f22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 17:04:36 +0800 Subject: [PATCH 15/53] =?UTF-8?q?=E5=89=A9=E4=BD=99=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 61 +++++++++++++------ frameworks/kits/ani/ets/imageTest.ets | 9 +-- .../kits/ani/native/src/image_packer_ani.cpp | 34 +++++------ .../kits/ani/native/src/image_source_ani.cpp | 10 +-- 4 files changed, 70 insertions(+), 44 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 68c2c2a8c..802b2ed63 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -332,7 +332,7 @@ export namespace image { // end common // pixelmap - export interface InitializationOptions { + interface IInitializationOptions { size: Size; srcPixelFormat?: PixelMapFormat; pixelFormat?: PixelMapFormat; @@ -340,6 +340,15 @@ export namespace image { alphaType?: AlphaType; scaleMode?: ScaleMode; } + + export class InitializationOptions implements IInitializationOptions { + size: Size = { width: 0, height: 0 }; + srcPixelFormat?: PixelMapFormat = PixelMapFormat.UNKNOWN; + pixelFormat?: PixelMapFormat = PixelMapFormat.UNKNOWN; + editable?: boolean = false; + alphaType?: AlphaType = AlphaType.UNKNOWN; + scaleMode?: ScaleMode = ScaleMode.FIT_TARGET_SIZE; + } export interface PixelMap { createAlphaPixelmapSync(): PixelMap; @@ -486,20 +495,38 @@ export namespace image { defaultValue?: string; } - export interface DecodingOptions { - index?: Int; - sampleSize?: Int; - rotate?: Int; - editable?: Int; + interface IDecodingOptions { + index?: int; + sampleSize?: int; + rotate?: int; + editable?: boolean; desiredSize?: Size; desiredRegion?: Region; desiredPixelFormat?: PixelMapFormat; - fitDensity?: Int; + fitDensity?: int; desiredColorSpace?: colorSpaceManager.ColorSpaceManager; desiredDynamicRange?: DecodingDynamicRange; resolutionQuality?: ResolutionQuality; } + export class DecodingOptions implements IDecodingOptions { + index?: int | undefined = 0; + sampleSize?: int | undefined = 0; + rotate?: int | undefined = 0; + editable?: boolean | undefined = false; + desiredSize?: Size | undefined = { width: 0, height: 0 }; + desiredRegion?: Region | undefined = { + size: { width: 0, height: 0 }, + x: 0, + y: 0 + }; + desiredPixelFormat?: PixelMapFormat | undefined = PixelMapFormat.UNKNOWN; + fitDensity?: int | undefined = 0; + desiredColorSpace?: colorSpaceManager.ColorSpaceManager | undefined = undefined; + desiredDynamicRange?: DecodingDynamicRange | undefined = undefined; + resolutionQuality?: ResolutionQuality | undefined = undefined; + } + export interface ImageSource { getImageInfoSync(index: int): ImageInfo; getImageInfo(index: int): Promise; @@ -606,20 +633,20 @@ export namespace image { loopCount?: int; } - interface PackingOptionInterface { + interface IPackingOption { format: string; - quality: Int; - bufferSize?: Int; - desiredDynamicRange?: Int; - needsPackProperties?: Int; + quality: int; + bufferSize?: int; + desiredDynamicRange?: PackingDynamicRange; + needsPackProperties?: boolean; } - export class PackingOption implements PackingOptionInterface { + export class PackingOption implements IPackingOption { format: string = ""; - quality: Int = 0; - bufferSize?: Int | undefined = 20971520; - desiredDynamicRange?: Int | undefined = 0; - needsPackProperties?: Int | undefined = 0; + quality: int = 0; + bufferSize?: int | undefined = 20971520; + desiredDynamicRange?: PackingDynamicRange | undefined = PackingDynamicRange.AUTO; + needsPackProperties?: boolean | undefined = false; } export interface ImagePacker { diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 0121800c4..9344f59fb 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -102,7 +102,7 @@ function main() { index: 0, sampleSize: 1, rotate: 0, - editable: 1, + editable: true, desiredSize, desiredRegion, desiredPixelFormat: image.PixelMapFormat.RGBA_8888, @@ -143,9 +143,10 @@ function main() { console.log("TEST ImagePacker begin"); const imagePacker = image.createImagePacker(); - let packOpts: image.PackingOption = new image.PackingOption(); - packOpts.format = "image/jpeg"; - packOpts.quality = 90; + let packOpts: image.PackingOption = { + format: "image/jpeg", + quality: 90 + }; let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); console.log("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); imagePacker.release(); diff --git a/frameworks/kits/ani/native/src/image_packer_ani.cpp b/frameworks/kits/ani/native/src/image_packer_ani.cpp index 8a4c39e87..0d52f8951 100644 --- a/frameworks/kits/ani/native/src/image_packer_ani.cpp +++ b/frameworks/kits/ani/native/src/image_packer_ani.cpp @@ -102,44 +102,40 @@ bool ParsePackingOptions([[maybe_unused]] ani_env* env, ani_object para, PackOpt } std::string retStr = ANIUtils_ANIStringToStdString(env, static_cast(tmptest)); ani_status ret; - ani_ref qualityRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "quality", ":Lstd/core/Int;", &qualityRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild qualityRef:%{public}d", ret); - } ani_int quality; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(qualityRef), - "unboxed", ":I", &quality)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild quality:%{public}d", ret); + if ((ret = env->Object_CallMethodByName_Int(para, "quality", ":I", + &quality)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed quality:%{public}d", ret); } ani_ref bufferSizeRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, - "bufferSize", ":Lstd/core/Int;", &bufferSizeRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSizeRef:%{public}d", ret); + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "bufferSize", ":Lstd/core/Int;", + &bufferSizeRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed bufferSizeRef:%{public}d", ret); } ani_int bufferSize; if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(bufferSizeRef), "unboxed", ":I", &bufferSize)) != ANI_OK || bufferSize <= 0) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild bufferSize or invalid bufferSize:%{public}d", ret); + IMAGE_LOGE("Object_CallMethodByName_Int Failed bufferSize or invalid bufferSize:%{public}d", ret); } ani_ref desiredDynamicRangeRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "desiredDynamicRange", ":Lstd/core/Int;", &desiredDynamicRangeRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRangeRef:%{public}d", ret); + IMAGE_LOGE("Object_CallMethodByName_Int Failed desiredDynamicRangeRef:%{public}d", ret); } ani_int desiredDynamicRange; if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(desiredDynamicRangeRef), "unboxed", ":I", &desiredDynamicRange)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild desiredDynamicRange:%{public}d", ret); + IMAGE_LOGE("Object_CallMethodByName_Int Failed desiredDynamicRange:%{public}d", ret); } ani_ref needsPackPropertiesRef; if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "needsPackProperties", - ":Lstd/core/Int;", &needsPackPropertiesRef))) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild needsPackPropertiesRef:%{public}d", ret); + ":Lstd/core/Boolean;", &needsPackPropertiesRef))) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed needsPackPropertiesRef:%{public}d", ret); } - ani_int needsPackProperties; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(needsPackPropertiesRef), - "unboxed", ":I", &needsPackProperties)) != ANI_OK) { - IMAGE_LOGE("Object_CallMethodByName_Int Faild needsPackProperties:%{public}d", ret); + ani_boolean needsPackProperties; + if ((ret = env->Object_CallMethodByName_Boolean(reinterpret_cast(needsPackPropertiesRef), + "unboxed", ":Z", &needsPackProperties)) != ANI_OK) { + IMAGE_LOGE("Object_CallMethodByName_Int Failed needsPackProperties:%{public}d", ret); } packOpts.format = retStr; diff --git a/frameworks/kits/ani/native/src/image_source_ani.cpp b/frameworks/kits/ani/native/src/image_source_ani.cpp index 5daad99db..b10f14d6e 100644 --- a/frameworks/kits/ani/native/src/image_source_ani.cpp +++ b/frameworks/kits/ani/native/src/image_source_ani.cpp @@ -276,14 +276,16 @@ static bool ParseDecodingOptions([[maybe_unused]] ani_env* env, ani_object para, } ani_ref editableRef; - if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "editable", ":Lstd/core/Int;", &editableRef))) { + if (ANI_OK != (ret = env->Object_CallMethodByName_Ref(para, "editable", ":Lstd/core/Boolean;", + &editableRef))) { IMAGE_LOGE("Object_CallMethodByName_Ref Faild editableRef:%{public}d", ret); } - ani_int editable; - if ((ret = env->Object_CallMethodByName_Int(reinterpret_cast(editableRef), - "unboxed", ":I", &editable)) != ANI_OK) { + ani_boolean editable; + if ((ret = env->Object_CallMethodByName_Boolean(reinterpret_cast(editableRef), + "unboxed", ":Z", &editable)) != ANI_OK) { IMAGE_LOGE("Object_CallMethodByName_Int Faild editable:%{public}d", ret); } + opts.editable = static_cast(editable); if (!ParseDecodingOptions2(env, para, opts)) { return false; -- Gitee From 8de1d5a82b0540afc431f660b01bd36672812a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 17:14:19 +0800 Subject: [PATCH 16/53] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 44 ++----------------- frameworks/kits/ani/ets/imageTest.ets | 8 +++- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 802b2ed63..2d77bcc6d 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -229,7 +229,7 @@ export namespace image { ALTERNATE = 3, } - enum PackingDynamicRange { + export enum PackingDynamicRange { AUTO = 0, SDR = 1, } @@ -332,7 +332,7 @@ export namespace image { // end common // pixelmap - interface IInitializationOptions { + export interface InitializationOptions { size: Size; srcPixelFormat?: PixelMapFormat; pixelFormat?: PixelMapFormat; @@ -340,15 +340,6 @@ export namespace image { alphaType?: AlphaType; scaleMode?: ScaleMode; } - - export class InitializationOptions implements IInitializationOptions { - size: Size = { width: 0, height: 0 }; - srcPixelFormat?: PixelMapFormat = PixelMapFormat.UNKNOWN; - pixelFormat?: PixelMapFormat = PixelMapFormat.UNKNOWN; - editable?: boolean = false; - alphaType?: AlphaType = AlphaType.UNKNOWN; - scaleMode?: ScaleMode = ScaleMode.FIT_TARGET_SIZE; - } export interface PixelMap { createAlphaPixelmapSync(): PixelMap; @@ -495,7 +486,7 @@ export namespace image { defaultValue?: string; } - interface IDecodingOptions { + export interface DecodingOptions { index?: int; sampleSize?: int; rotate?: int; @@ -509,24 +500,6 @@ export namespace image { resolutionQuality?: ResolutionQuality; } - export class DecodingOptions implements IDecodingOptions { - index?: int | undefined = 0; - sampleSize?: int | undefined = 0; - rotate?: int | undefined = 0; - editable?: boolean | undefined = false; - desiredSize?: Size | undefined = { width: 0, height: 0 }; - desiredRegion?: Region | undefined = { - size: { width: 0, height: 0 }, - x: 0, - y: 0 - }; - desiredPixelFormat?: PixelMapFormat | undefined = PixelMapFormat.UNKNOWN; - fitDensity?: int | undefined = 0; - desiredColorSpace?: colorSpaceManager.ColorSpaceManager | undefined = undefined; - desiredDynamicRange?: DecodingDynamicRange | undefined = undefined; - resolutionQuality?: ResolutionQuality | undefined = undefined; - } - export interface ImageSource { getImageInfoSync(index: int): ImageInfo; getImageInfo(index: int): Promise; @@ -538,7 +511,6 @@ export namespace image { release(): void; } - export class ImageSourceInner implements ImageSource { private nativeObj: long = 0; @@ -633,7 +605,7 @@ export namespace image { loopCount?: int; } - interface IPackingOption { + export interface PackingOption { format: string; quality: int; bufferSize?: int; @@ -641,14 +613,6 @@ export namespace image { needsPackProperties?: boolean; } - export class PackingOption implements IPackingOption { - format: string = ""; - quality: int = 0; - bufferSize?: int | undefined = 20971520; - desiredDynamicRange?: PackingDynamicRange | undefined = PackingDynamicRange.AUTO; - needsPackProperties?: boolean | undefined = false; - } - export interface ImagePacker { packing(source: PixelMap, option: PackingOption): ArrayBuffer; release(): void; diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 9344f59fb..c721cc066 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -23,7 +23,8 @@ function main() { srcPixelFormat: image.PixelMapFormat.RGBA_8888, pixelFormat: image.PixelMapFormat.BGRA_8888, editable: true, - alphaType: image.AlphaType.UNPREMUL + alphaType: image.AlphaType.UNPREMUL, + scaleMode: image.ScaleMode.FIT_TARGET_SIZE }; let pixelMap:image.PixelMap = image.createPixelMapSync(opts); @@ -145,7 +146,10 @@ function main() { const imagePacker = image.createImagePacker(); let packOpts: image.PackingOption = { format: "image/jpeg", - quality: 90 + quality: 90, + bufferSize: 0, + PackingDynamicRange: image.PackingDynamicRange.AUTO, + needsPackProperties: false }; let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); console.log("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); -- Gitee From 729afebc26f670747659a5ff45d7e04f70b2fc4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 17:20:20 +0800 Subject: [PATCH 17/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/ets/imageTest.ets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index c721cc066..bb53d1cee 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -148,7 +148,7 @@ function main() { format: "image/jpeg", quality: 90, bufferSize: 0, - PackingDynamicRange: image.PackingDynamicRange.AUTO, + desiredDynamicRange: image.PackingDynamicRange.AUTO, needsPackProperties: false }; let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); -- Gitee From f9ce4dd417a8febfe227e4c9990ccf669c387361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 18 Apr 2025 17:36:59 +0800 Subject: [PATCH 18/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/ets/@ohos.multimedia.image.ets | 10 +++++++++- frameworks/kits/ani/ets/imageTest.ets | 10 +++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 2d77bcc6d..7d13942f8 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -605,7 +605,7 @@ export namespace image { loopCount?: int; } - export interface PackingOption { + interface IPackingOption { format: string; quality: int; bufferSize?: int; @@ -613,6 +613,14 @@ export namespace image { needsPackProperties?: boolean; } + export class PackingOption implements IPackingOption { + format: string = ""; + quality: int = 0; + bufferSize?: int = 20971520; + desiredDynamicRange?: PackingDynamicRange = PackingDynamicRange.AUTO; + needsPackProperties?: boolean = false; + } + export interface ImagePacker { packing(source: PixelMap, option: PackingOption): ArrayBuffer; release(): void; diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index bb53d1cee..4f705f781 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -144,13 +144,9 @@ function main() { console.log("TEST ImagePacker begin"); const imagePacker = image.createImagePacker(); - let packOpts: image.PackingOption = { - format: "image/jpeg", - quality: 90, - bufferSize: 0, - desiredDynamicRange: image.PackingDynamicRange.AUTO, - needsPackProperties: false - }; + let packOpts: image.PackingOption = new image.PackingOption(); + packOpts.format = "image/jpeg"; + packOpts.quality = 90; let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); console.log("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); imagePacker.release(); -- Gitee From 7a4d9ee5ca05b3c2e2a64c96b4ac49680d3f1125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 23 Apr 2025 21:19:01 +0800 Subject: [PATCH 19/53] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20supportedFormats=20?= =?UTF-8?q?=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../kits/ani/ets/@ohos.multimedia.image.ets | 3 ++- frameworks/kits/ani/ets/imageTest.ets | 27 ++++++++++--------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 7d13942f8..f073472ff 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -624,6 +624,7 @@ export namespace image { export interface ImagePacker { packing(source: PixelMap, option: PackingOption): ArrayBuffer; release(): void; + readonly supportedFormats: Array; } class ImagePackerInner implements ImagePacker { @@ -646,7 +647,7 @@ export namespace image { public packing(source: PixelMap, option: PackingOption): ArrayBuffer { return this.nativePackingWithPixelMap(source, option); } - supportedFormats: Array = new Array(""); + supportedFormats: Array = ["jpg", "png"]; } export native function createImagePacker(): ImagePacker; diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 4f705f781..6428d7207 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -33,10 +33,10 @@ function main() { } const retImageInfo: image.ImageInfo = pixelMap.getImageInfoSync(); - console.log("Get image info: ", retImageInfo.size.width, retImageInfo.size.height, retImageInfo.pixelFormat, retImageInfo.alphaType); + console.log(`Get image info: ${retImageInfo.size.width}, ${retImageInfo.size.height}, ${retImageInfo.pixelFormat}, ${retImageInfo.alphaType}`); pixelMap.getImageInfo() .then((imageInfo: image.ImageInfo) => { - console.log("ASYNC Get image info: ", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.alphaType); + console.log(`ASYNC Get image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.alphaType}`); }); const rowBytes = pixelMap.getBytesNumberPerRow(); @@ -45,14 +45,14 @@ function main() { console.log("PixelMap total bytes: " + totalBytes); if (retImageInfo.isHdr) { - console.log("Test PixelMap hdr "); + console.log("Test PixelMap HDR"); } else { - console.log("Test PixelMap not hdr "); + console.log("Test PixelMap not HDR"); } pixelMap.scaleSync(2, 2); const scaledInfo = pixelMap.getImageInfoSync(); - console.log("Scaled image info: ", scaledInfo.size.width, scaledInfo.size.height); + console.log(`Scaled image info: ${scaledInfo.size.width}, ${scaledInfo.size.height}`); const region: image.Region = { size: { width: 512, height: 512 }, x: 0, @@ -60,21 +60,21 @@ function main() { }; pixelMap.cropSync(region); const croppedInfo = pixelMap.getImageInfoSync(); - console.log("Cropped image info: ", croppedInfo.size.width, croppedInfo.size.height); + console.log(`Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); pixelMap.flipSync(true, true); const flippedInfo = pixelMap.getImageInfoSync(); - console.log("Flipped image info: ", flippedInfo.size.width, flippedInfo.size.height); + console.log(`Flipped image info: ${flippedInfo.size.width}, ${flippedInfo.size.height}`); const alphaPixelMap = pixelMap.createAlphaPixelmapSync(); if (alphaPixelMap != undefined) { console.log("Create alpha PixelMap success"); } const alphaImageInfo = alphaPixelMap.getImageInfoSync(); - console.log("Alpha get image info: ", alphaImageInfo.size.width, alphaImageInfo.size.height, alphaImageInfo.pixelFormat, alphaImageInfo.alphaType); + console.log(`Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); pixelMap.createAlphaPixelmap() .then((alphaPixelMap: image.PixelMap) => { const alphaImageInfo = alphaPixelMap.getImageInfoSync(); - console.log("ASYNC Alpha get image info: ", alphaImageInfo.size.width, alphaImageInfo.size.height, alphaImageInfo.pixelFormat, alphaImageInfo.alphaType); + console.log(`ASYNC Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); }) let imageSource: image.ImageSource = image.createImageSource("/data/local/tmp/test.png"); @@ -87,10 +87,10 @@ function main() { } let imagesourceImageInfo: image.ImageInfo = imageSource.getImageInfoSync(0); - console.log("Image source image info: ", imagesourceImageInfo.size.width, imagesourceImageInfo.size.height, imagesourceImageInfo.pixelFormat, imagesourceImageInfo.density, imagesourceImageInfo.mimeType); + console.log(`Image source image info: ${imagesourceImageInfo.size.width}, ${imagesourceImageInfo.size.height}, ${imagesourceImageInfo.pixelFormat}, ${imagesourceImageInfo.density}, ${imagesourceImageInfo.mimeType}`); imageSource.getImageInfo(0) .then((imageInfo: image.ImageInfo) => { - console.log("ASYNC Image source image info:", imageInfo.size.width, imageInfo.size.height, imageInfo.pixelFormat, imageInfo.density, imageInfo.mimeType); + console.log(`ASYNC Image source image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.density}, ${imageInfo.mimeType}`); }); const desiredSize: image.Size | undefined = { width: 60, height: 60 }; @@ -144,6 +144,7 @@ function main() { console.log("TEST ImagePacker begin"); const imagePacker = image.createImagePacker(); + console.log("ImagePacker supported formats: " + imagePacker.supportedFormats); let packOpts: image.PackingOption = new image.PackingOption(); packOpts.format = "image/jpeg"; packOpts.quality = 90; @@ -165,7 +166,7 @@ function main() { } const picturePixelMap = picture.getMainPixelmap(); const pictureInfo = picturePixelMap.getImageInfoSync(); - console.log("Picture PixelMap image info: ", pictureInfo.size.width, pictureInfo.size.height, pictureInfo.pixelFormat, pictureInfo.alphaType); + console.log(`Picture PixelMap image info: ${pictureInfo.size.width}, ${pictureInfo.size.height}, ${pictureInfo.pixelFormat}, ${pictureInfo.alphaType}`); const regionAsync: image.Region = { size: { width: 1, height: 1 }, @@ -175,7 +176,7 @@ function main() { pixelMap.crop(regionAsync) .then((): void => { const croppedInfo = pixelMap.getImageInfoSync(); - console.log("ASYNC Cropped image info: ", croppedInfo.size.width, croppedInfo.size.height); + console.log(`ASYNC Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); }); console.log("====== Sync methods completed ======") -- Gitee From c809e560f004f54d95347a55be7e8051a3bb91a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Sun, 27 Apr 2025 20:36:23 +0800 Subject: [PATCH 20/53] =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=99=A8=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/ets/@ohos.multimedia.image.ets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index f073472ff..b45411114 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -647,7 +647,7 @@ export namespace image { public packing(source: PixelMap, option: PackingOption): ArrayBuffer { return this.nativePackingWithPixelMap(source, option); } - supportedFormats: Array = ["jpg", "png"]; + supportedFormats: Array = new Array("jpg", "png"); } export native function createImagePacker(): ImagePacker; -- Gitee From ba66907f2079bb0875e7db72e9fb8b0c72f34a05 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Tue, 6 May 2025 11:29:58 +0800 Subject: [PATCH 21/53] add PixelMapImpl, ImageSourceImpl, ImagePackerImpl, PictureImpl Signed-off-by: zhaona45 --- bundle.json | 6 +- frameworks/kits/taihe/BUILD.gn | 119 ++ .../idl/ohos.multimedia.image.image.taihe | 563 ++++++++ .../taihe/idl/ohos.multimedia.image.taihe | 23 + .../kits/taihe/include/image_packer_taihe.h | 50 + .../kits/taihe/include/image_source_taihe.h | 69 + .../kits/taihe/include/image_taihe_utils.h | 52 + frameworks/kits/taihe/include/picture_taihe.h | 46 + .../kits/taihe/include/pixel_map_taihe.h | 67 + frameworks/kits/taihe/src/ani_constructor.cpp | 30 + .../kits/taihe/src/image_packer_taihe.cpp | 600 +++++++++ .../kits/taihe/src/image_source_taihe.cpp | 1182 +++++++++++++++++ .../kits/taihe/src/image_taihe_utils.cpp | 157 +++ frameworks/kits/taihe/src/picture_taihe.cpp | 123 ++ frameworks/kits/taihe/src/pixel_map_taihe.cpp | 494 +++++++ 15 files changed, 3580 insertions(+), 1 deletion(-) create mode 100644 frameworks/kits/taihe/BUILD.gn create mode 100644 frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe create mode 100644 frameworks/kits/taihe/idl/ohos.multimedia.image.taihe create mode 100644 frameworks/kits/taihe/include/image_packer_taihe.h create mode 100644 frameworks/kits/taihe/include/image_source_taihe.h create mode 100644 frameworks/kits/taihe/include/image_taihe_utils.h create mode 100644 frameworks/kits/taihe/include/picture_taihe.h create mode 100644 frameworks/kits/taihe/include/pixel_map_taihe.h create mode 100644 frameworks/kits/taihe/src/ani_constructor.cpp create mode 100644 frameworks/kits/taihe/src/image_packer_taihe.cpp create mode 100644 frameworks/kits/taihe/src/image_source_taihe.cpp create mode 100644 frameworks/kits/taihe/src/image_taihe_utils.cpp create mode 100644 frameworks/kits/taihe/src/picture_taihe.cpp create mode 100644 frameworks/kits/taihe/src/pixel_map_taihe.cpp diff --git a/bundle.json b/bundle.json index b0412118b..31e2fb901 100644 --- a/bundle.json +++ b/bundle.json @@ -73,7 +73,8 @@ "sub_component": [ "//foundation/multimedia/image_framework:image_framework", "//foundation/multimedia/image_framework:plugins", - "//foundation/multimedia/image_framework/frameworks/kits/ani:image_framework_ani" + "//foundation/multimedia/image_framework/frameworks/kits/taihe:image_framework_taihe", + "//foundation/multimedia/image_framework/frameworks/kits/taihe:image_framework_taihe_gen_only" ], "inner_kits": [ { @@ -201,6 +202,9 @@ }, "name": "//foundation/multimedia/image_framework/frameworks/kits/ani:image_ani" }, + { + "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:copy_image_taihe" + }, { "header": { "header_base": "//foundation/multimedia/image_framework/interfaces/kits/native/include/", diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn new file mode 100644 index 000000000..38ecb9e72 --- /dev/null +++ b/frameworks/kits/taihe/BUILD.gn @@ -0,0 +1,119 @@ +# Copyright (C) 2025 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//build/ohos/taihe_idl/taihe.gni") +import("//foundation/multimedia/image_framework/ide/image_decode_config.gni") + +subsystem_name = "multimedia" +part_name = "image_framework" +taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" + +copy_taihe_idl("copy_image_taihe") { + sources = [ + "${image_subsystem}/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe", + "${image_subsystem}/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe", + ] +} + +ohos_taihe("run_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + deps = [ ":copy_image_taihe" ] + outputs = [ + "$taihe_generated_file_path/src/ohos.multimedia.image.image.ani.cpp", + "$taihe_generated_file_path/src/ohos.multimedia.image.image.abi.c", + ] +} + +taihe_shared_library("image_taihe") { + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + + include_dirs = [ + "include", + "${image_subsystem}/interfaces/innerkits/include", + "${image_subsystem}/interfaces/kits/native/include/image", + "${image_subsystem}/plugins/common/libs/image/libextplugin/include/jpeg_yuv_decoder", + ] + + sources = get_target_outputs(":run_taihe") + sources += [ + "src/ani_constructor.cpp", + "src/image_packer_taihe.cpp", + "src/image_source_taihe.cpp", + "src/image_taihe_utils.cpp", + "src/picture_taihe.cpp", + "src/pixel_map_taihe.cpp", + "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", + ] + + cflags = [ "-DIMAGE_DEBUG_FLAG" ] + + deps = [ + ":run_taihe", + "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", + "$image_subsystem/frameworks/innerkitsimpl/utils:image_utils", + "$image_subsystem/interfaces/innerkits:image_native", + ] + + external_deps = [ + "c_utils:utils", + "graphic_2d:color_manager", + "graphic_2d:EGL", + "graphic_2d:librender_service_client", + "hilog:libhilog", + "hitrace:hitrace_meter", + "skia:libjpeg", + ] + + if (!use_clang_android && !use_clang_ios) { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } +} + +generate_static_abc("image_framework_taihe_abc") { + base_url = "$taihe_generated_file_path" + files = [ "$taihe_generated_file_path/@ohos.multimedia.image.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/image_framework_taihe_abc.abc" + dependencies = [ ":run_taihe" ] +} + +ohos_prebuilt_etc("image_framework_etc") { + source = "$target_out_dir/image_framework_taihe_abc.abc" + module_install_dir = "framework" + part_name = "$part_name" + subsystem_name = "$subsystem_name" + deps = [ + ":image_framework_taihe_abc" + ] +} + +group("image_framework_taihe") { + deps = [ + ":image_taihe", + ":image_framework_etc", + ] +} + +group("image_framework_taihe_gen_only") { + deps = [ ":run_taihe" ] +} \ No newline at end of file diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe new file mode 100644 index 000000000..2ab565941 --- /dev/null +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -0,0 +1,563 @@ +/* + * Copyright (C) 2025 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. + */ + +@!namespace("@ohos.multimedia.image", "image") + +@!sts_inject(""" +static { loadLibrary("image_taihe.z"); } +""") + +enum PixelMapFormat: i32 { + UNKNOWN = 0, + ARGB_8888 = 1, + RGB_565 = 2, + RGBA_8888 = 3, + BGRA_8888 = 4, + RGB_888 = 5, + ALPHA_8 = 6, + RGBA_F16 = 7, + NV21 = 8, + NV12 = 9, + RGBA_1010102 = 10, + YCBCR_P010 = 11, + YCRCB_P010 = 12, + ASTC_4x4 = 102 +} + +enum ResolutionQuality: i32 { + LOW = 1, + MEDIUM = 2, + HIGH = 3 +} + +struct Size { + width: i32; + height: i32; +} + +enum PropertyKey: String { + BITS_PER_SAMPLE = "BitsPerSample", + ORIENTATION = "Orientation", + IMAGE_LENGTH = "ImageLength", + IMAGE_WIDTH = "ImageWidth", + GPS_LATITUDE = "GPSLatitude", + GPS_LONGITUDE = "GPSLongitude", + GPS_LATITUDE_REF = "GPSLatitudeRef", + GPS_LONGITUDE_REF = "GPSLongitudeRef", + DATE_TIME_ORIGINAL = "DateTimeOriginal", + EXPOSURE_TIME = "ExposureTime", + SCENE_TYPE = "SceneType", + ISO_SPEED_RATINGS = "ISOSpeedRatings", + F_NUMBER = "FNumber", + DATE_TIME = "DateTime", + GPS_TIME_STAMP = "GPSTimeStamp", + GPS_DATE_STAMP = "GPSDateStamp", + IMAGE_DESCRIPTION = "ImageDescription", + MAKE = "Make", + MODEL = "Model", + PHOTO_MODE = "PhotoMode", + SENSITIVITY_TYPE = "SensitivityType", + STANDARD_OUTPUT_SENSITIVITY = "StandardOutputSensitivity", + RECOMMENDED_EXPOSURE_INDEX = "RecommendedExposureIndex", + ISO_SPEED = "ISOSpeedRatings", + APERTURE_VALUE = "ApertureValue", + EXPOSURE_BIAS_VALUE = "ExposureBiasValue", + METERING_MODE = "MeteringMode", + LIGHT_SOURCE = "LightSource", + FLASH = "Flash", + FOCAL_LENGTH = "FocalLength", + USER_COMMENT = "UserComment", + PIXEL_X_DIMENSION = "PixelXDimension", + PIXEL_Y_DIMENSION = "PixelYDimension", + WHITE_BALANCE = "WhiteBalance", + FOCAL_LENGTH_IN_35_MM_FILM = "FocalLengthIn35mmFilm", + CAPTURE_MODE = "HwMnoteCaptureMode", + PHYSICAL_APERTURE = "HwMnotePhysicalAperture", + ROLL_ANGLE = "HwMnoteRollAngle", + PITCH_ANGLE = "HwMnotePitchAngle", + SCENE_FOOD_CONF = "HwMnoteSceneFoodConf", + SCENE_STAGE_CONF = "HwMnoteSceneStageConf", + SCENE_BLUE_SKY_CONF = "HwMnoteSceneBlueSkyConf", + SCENE_GREEN_PLANT_CONF = "HwMnoteSceneGreenPlantConf", + SCENE_BEACH_CONF = "HwMnoteSceneBeachConf", + SCENE_SNOW_CONF = "HwMnoteSceneSnowConf", + SCENE_SUNSET_CONF = "HwMnoteSceneSunsetConf", + SCENE_FLOWERS_CONF = "HwMnoteSceneFlowersConf", + SCENE_NIGHT_CONF = "HwMnoteSceneNightConf", + SCENE_TEXT_CONF = "HwMnoteSceneTextConf", + FACE_COUNT = "HwMnoteFaceCount", + FOCUS_MODE = "HwMnoteFocusMode", + COMPRESSION = "Compression", + PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation", + STRIP_OFFSETS = "StripOffsets", + SAMPLES_PER_PIXEL = "SamplesPerPixel", + ROWS_PER_STRIP = "RowsPerStrip", + STRIP_BYTE_COUNTS = "StripByteCounts", + X_RESOLUTION = "XResolution", + Y_RESOLUTION = "YResolution", + PLANAR_CONFIGURATION = "PlanarConfiguration", + RESOLUTION_UNIT = "ResolutionUnit", + TRANSFER_FUNCTION = "TransferFunction", + SOFTWARE = "Software", + ARTIST = "Artist", + WHITE_POINT = "WhitePoint", + PRIMARY_CHROMATICITIES = "PrimaryChromaticities", + YCBCR_COEFFICIENTS = "YCbCrCoefficients", + YCBCR_SUB_SAMPLING = "YCbCrSubSampling", + YCBCR_POSITIONING = "YCbCrPositioning", + REFERENCE_BLACK_WHITE = "ReferenceBlackWhite", + COPYRIGHT = "Copyright", + JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat", + JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength", + EXPOSURE_PROGRAM = "ExposureProgram", + SPECTRAL_SENSITIVITY = "SpectralSensitivity", + OECF = "OECF", + EXIF_VERSION = "ExifVersion", + DATE_TIME_DIGITIZED = "DateTimeDigitized", + COMPONENTS_CONFIGURATION = "ComponentsConfiguration", + SHUTTER_SPEED = "ShutterSpeedValue", + BRIGHTNESS_VALUE = "BrightnessValue", + MAX_APERTURE_VALUE = "MaxApertureValue", + SUBJECT_DISTANCE = "SubjectDistance", + SUBJECT_AREA = "SubjectArea", + MAKER_NOTE = "MakerNote", + SUBSEC_TIME = "SubsecTime", + SUBSEC_TIME_ORIGINAL = "SubsecTimeOriginal", + SUBSEC_TIME_DIGITIZED = "SubsecTimeDigitized", + FLASHPIX_VERSION = "FlashpixVersion", + COLOR_SPACE = "ColorSpace", + RELATED_SOUND_FILE = "RelatedSoundFile", + FLASH_ENERGY = "FlashEnergy", + SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse", + FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution", + FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution", + FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit", + SUBJECT_LOCATION = "SubjectLocation", + EXPOSURE_INDEX = "ExposureIndex", + SENSING_METHOD = "SensingMethod", + FILE_SOURCE = "FileSource", + CFA_PATTERN = "CFAPattern", + CUSTOM_RENDERED = "CustomRendered", + EXPOSURE_MODE = "ExposureMode", + DIGITAL_ZOOM_RATIO = "DigitalZoomRatio", + SCENE_CAPTURE_TYPE = "SceneCaptureType", + GAIN_CONTROL = "GainControl", + CONTRAST = "Contrast", + SATURATION = "Saturation", + SHARPNESS = "Sharpness", + DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription", + SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange", + IMAGE_UNIQUE_ID = "ImageUniqueID", + GPS_VERSION_ID = "GPSVersionID", + GPS_ALTITUDE_REF = "GPSAltitudeRef", + GPS_ALTITUDE = "GPSAltitude", + GPS_SATELLITES = "GPSSatellites", + GPS_STATUS = "GPSStatus", + GPS_MEASURE_MODE = "GPSMeasureMode", + GPS_DOP = "GPSDOP", + GPS_SPEED_REF = "GPSSpeedRef", + GPS_SPEED = "GPSSpeed", + GPS_TRACK_REF = "GPSTrackRef", + GPS_TRACK = "GPSTrack", + GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef", + GPS_IMG_DIRECTION = "GPSImgDirection", + GPS_MAP_DATUM = "GPSMapDatum", + GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef", + GPS_DEST_LATITUDE = "GPSDestLatitude", + GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef", + GPS_DEST_LONGITUDE = "GPSDestLongitude", + GPS_DEST_BEARING_REF = "GPSDestBearingRef", + GPS_DEST_BEARING = "GPSDestBearing", + GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef", + GPS_DEST_DISTANCE = "GPSDestDistance", + GPS_PROCESSING_METHOD = "GPSProcessingMethod", + GPS_AREA_INFORMATION = "GPSAreaInformation", + GPS_DIFFERENTIAL = "GPSDifferential", + BODY_SERIAL_NUMBER = "BodySerialNumber", + CAMERA_OWNER_NAME = "CameraOwnerName", + COMPOSITE_IMAGE = "CompositeImage", + COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel", + DNG_VERSION = "DNGVersion", + DEFAULT_CROP_SIZE = "DefaultCropSize", + GAMMA = "Gamma", + ISO_SPEED_LATITUDE_YYY = "ISOSpeedLatitudeyyy", + ISO_SPEED_LATITUDE_ZZZ = "ISOSpeedLatitudezzz", + LENS_MAKE = "LensMake", + LENS_MODEL = "LensModel", + LENS_SERIAL_NUMBER = "LensSerialNumber", + LENS_SPECIFICATION = "LensSpecification", + NEW_SUBFILE_TYPE = "NewSubfileType", + OFFSET_TIME = "OffsetTime", + OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized", + OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal", + SOURCE_EXPOSURE_TIMES_OF_COMPOSITE_IMAGE = "SourceExposureTimesOfCompositeImage", + SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE = "SourceImageNumberOfCompositeImage", + SUBFILE_TYPE = "SubfileType", + GPS_H_POSITIONING_ERROR = "GPSHPositioningError", + PHOTOGRAPHIC_SENSITIVITY = "PhotographicSensitivity", + BURST_NUMBER = "HwMnoteBurstNumber", + FACE_CONF = "HwMnoteFaceConf", + FACE_LEYE_CENTER = "HwMnoteFaceLeyeCenter", + FACE_MOUTH_CENTER = "HwMnoteFaceMouthCenter", + FACE_POINTER = "HwMnoteFacePointer", + FACE_RECT = "HwMnoteFaceRect", + FACE_REYE_CENTER = "HwMnoteFaceReyeCenter", + FACE_SMILE_SCORE = "HwMnoteFaceSmileScore", + FACE_VERSION = "HwMnoteFaceVersion", + FRONT_CAMERA = "HwMnoteFrontCamera", + SCENE_POINTER = "HwMnoteScenePointer", + SCENE_VERSION = "HwMnoteSceneVersion", + IS_XMAGE_SUPPORTED = "HwMnoteIsXmageSupported", + XMAGE_MODE = "HwMnoteXmageMode", + XMAGE_LEFT = "HwMnoteXmageLeft", + XMAGE_TOP = "HwMnoteXmageTop", + XMAGE_RIGHT = "HwMnoteXmageRight", + XMAGE_BOTTOM = "HwMnoteXmageBottom", + CLOUD_ENHANCEMENT_MODE = "HwMnoteCloudEnhancementMode", + WIND_SNAPSHOT_MODE = "HwMnoteWindSnapshotMode", + GIF_LOOP_COUNT = "GIFLoopCount" +} + +enum ImageFormat: i32 { + YCBCR_422_SP = 1000, + JPEG = 2000 +} + +enum AlphaType: i32 { + UNKNOWN = 0, + OPAQUE = 1, + PREMUL = 2, + UNPREMUL = 3 +} + +enum DecodingDynamicRange: i32 { + AUTO = 0, + SDR = 1, + HDR = 2 +} + +enum PackingDynamicRange: i32 { + AUTO = 0, + SDR = 1, +} + +enum AntiAliasingLevel: i32 { + NONE = 0, + LOW = 1, + MEDIUM = 2, + HIGH = 3 +} + +enum ScaleMode: i32 { + FIT_TARGET_SIZE = 0, + CENTER_CROP = 1 +} + +enum ComponentType: i32 { + YUV_Y = 1, + YUV_U = 2, + YUV_V = 3, + JPEG = 4 +} + +enum AllocatorType: i32 { + AUTO = 0, + DMA = 1, + SHARE_MEMORY = 2, +} + +struct Region { + size: Size; + x: i32; + y: i32; +} + +// Can't use struct because struct is copied instead of referenced, so data changes to "pixels" in C++ will not be reflected in ArkTS +interface PositionArea { + @get GetPixels(): @arraybuffer Array; + @set SetPixels(pixels: @arraybuffer Array): void; + @get GetOffset(): i32; + @set SetOffset(offset: i32): void; + @get GetStride(): i32; + @set SetStride(stride: i32): void; + @get GetRegion(): Region; + @set SetRegion(region: Region): void; +} + +struct ImageInfo { + size: Size; + density: i32; + stride: i32; + pixelFormat: PixelMapFormat; + alphaType: AlphaType; + mimeType: String; + isHdr: bool; +} + +enum CropAndScaleStrategy: i32 { + SCALE_FIRST = 1, + CROP_FIRST = 2 +} + +struct PackingOption { + format: String; + quality: i32; + bufferSize: Optional; + desiredDynamicRange: Optional; + needsPackProperties: Optional; +} + +struct ImagePropertyOptions { + index: Optional; + defaultValue: Optional; +} + +struct DecodingOptions { + index: Optional; + sampleSize: Optional; + rotate: Optional; + editable: Optional; + desiredSize: Optional; + desiredRegion: Optional; + desiredPixelFormat: Optional; + photoDesiredPixelFormat: Optional; // not exposed to the user + fitDensity: Optional; + fillColor: Optional; // not exposed to the user + SVGResize: Optional; // not exposed to the user + desiredColorSpace: Optional<@sts_type("colorSpaceManager.ColorSpaceManager") Opaque>; + desiredDynamicRange: Optional; + resolutionQuality: Optional; + cropAndScaleStrategy: Optional; + reusePixelmap: Optional; // not exposed to the user +} + +struct Component { + @readonly componentType: ComponentType; + @readonly rowStride: i32; + @readonly pixelStride: i32; + @readonly byteBuffer: @arraybuffer Array; +} + +struct InitializationOptions { + size: Size; + srcPixelFormat: Optional; + pixelFormat: Optional; + editable: Optional; + alphaType: Optional; + scaleMode: Optional; +} + +struct SourceOptions { + sourceDensity: i32; + sourcePixelFormat: Optional; + sourceSize: Optional; +} + +enum AuxiliaryPictureType: i32 { + GAINMAP = 1, + DEPTH_MAP = 2, + UNREFOCUS_MAP = 3, + LINEAR_MAP = 4, + FRAGMENT_MAP = 5, +} + +struct AuxiliaryPictureInfo { + auxiliaryPictureType: AuxiliaryPictureType; + size: Size; + rowStride: i32; + pixelFormat: PixelMapFormat; + colorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque; +} + +union PropertyValue { + type_string: String; + @null type_null; +} + +interface PixelMap { + GetImplPtr(): i64; + + GetImageInfoSync(): ImageInfo; + + ReadPixelsToBufferSync(dst: @arraybuffer Array): void; + + ReadPixelsSync(area: PositionArea): void; + + WriteBufferToPixelsSync(src: @arraybuffer Array): void; + + @gen_async("createAlphaPixelmap") + @gen_promise("createAlphaPixelmap") + CreateAlphaPixelmapSync(): PixelMap; + + GetBytesNumberPerRow(): i32; + + GetPixelBytesNumber(): i32; + + @gen_async("scale") + @gen_promise("scale") + @overload("scaleSync") + ScaleSync(x: f32, y: f32): void; + + @gen_promise("scale") + @overload("scaleSync") + ScaleWithAntiAliasingSync(x: f32, y: f32, level: AntiAliasingLevel): void; + + @gen_async("crop") + @gen_promise("crop") + CropSync(region: Region): void; + + @gen_async("rotate") + @gen_promise("rotate") + RotateSync(angle: f32): void; + + @gen_async("flip") + @gen_promise("flip") + FlipSync(horizontal: bool, vertical: bool): void; + + @gen_async("opacity") + @gen_promise("opacity") + OpacitySync(rate: f32): void; + + SetMemoryNameSync(name: String): void; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; + + @get GetIsStrideAlignment(): bool; +} + +interface Picture { + GetImplPtr(): i64; + + GetMainPixelmap(): PixelMap; +} + +interface ImageSource { + GetImplPtr(): i64; + @gen_async("getImageInfo") + @gen_promise("getImageInfoPromiseWithIndex") + GetImageInfoSyncWithIndex(index: u32): ImageInfo; + + @gen_async("getImageInfo") + @gen_promise("getImageInfoPromise") + GetImageInfoSync(): ImageInfo; + + @!sts_inject_into_interface("getImageInfoSync(index: int | undefined): ImageInfo;") + @!sts_inject_into_class("""getImageInfoSync(index: int | undefined): ImageInfo { + if (index === undefined) { + return this.getImageInfoSync(); + } else { + return this.getImageInfoSyncWithIndex(index); + } + } + """) + + @!sts_inject_into_interface("getImageInfo(index: int | undefined): Promise;") + @!sts_inject_into_class("""getImageInfo(index: int | undefined): Promise { + if (index === undefined) { + return this.getImageInfoPromise(); + } else { + return this.getImageInfoPromiseWithIndex(index); + } + } + """) + + @gen_async("createPixelMap") + @gen_promise("createPixelMapPromiseWithOptions") + CreatePixelMapSyncWithOptions(options: DecodingOptions): PixelMap; + + @gen_async("createPixelMap") + @gen_promise("createPixelMapPromise") + CreatePixelMapSync(): PixelMap; + + @!sts_inject_into_interface("createPixelMapSync(options: DecodingOptions | undefined): PixelMap;") + @!sts_inject_into_class("""createPixelMapSync(options: DecodingOptions | undefined): PixelMap { + if (options === undefined) { + return this.createPixelMapSync(); + } else { + return this.createPixelMapSyncWithOptions(options); + } + } + """) + + @!sts_inject_into_interface("createPixelMap(options: DecodingOptions | undefined): Promise;") + @!sts_inject_into_class("""createPixelMap(options: DecodingOptions | undefined): Promise { + if (options === undefined) { + return this.createPixelMapPromise(); + } else { + return this.createPixelMapPromiseWithOptions(options); + } + } + """) + + @gen_promise("getImageProperty") + GetImagePropertySync(key: PropertyKey, options: Optional): String; + + @gen_promise("getImageProperties") + GetImagePropertiesSync(key: Array): @record Map; + + @gen_promise("modifyImageProperty") + ModifyImagePropertySync(key: PropertyKey, value: String): void; + + @gen_promise("modifyImageProperties") + ModifyImagePropertiesSync(records: @record Map): void; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; +} + +interface ImagePacker { + @gen_async("packing") + @gen_promise("packing") + PackingPixelMapSync(source: PixelMap, option: PackingOption): @arraybuffer Array; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; +} + +function MakeEmptySize(): Size; +function MakeEmptyImageInfo(): ImageInfo; + +@overload("createPixelMapSync") +function CreatePixelMapByBufferAndOptionsSync(colors: @arraybuffer Array, options: InitializationOptions): PixelMap; + +@overload("createPixelMapSync") +function CreatePixelMapByBufferSync(options: InitializationOptions): PixelMap; + +@overload("createPixelMapFromSurfaceSync") +function CreatePixelMapFromSurfaceByIdSync(surfaceId: String): PixelMap; + +@overload("createPixelMapFromSurfaceSync") +function CreatePixelMapFromSurfaceByIdAndRegionSync(surfaceId: String, region: Region): PixelMap; + +@overload("createImageSource") +function CreateImageSourceByUri(uri: String): ImageSource; + +@overload("createImageSource") +function CreateImageSourceByUriOption(uri: String, options: SourceOptions): ImageSource; + +@overload("createImageSource") +function CreateImageSourceByFd(fd: i32): ImageSource; + +@overload("createImageSource") +function CreateImageSourceByFdOption(fd: i32, options: SourceOptions): ImageSource; + +function CreateImagePacker(): ImagePacker; + +@overload("createPicture") +function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; \ No newline at end of file diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe new file mode 100644 index 000000000..8bc7dee08 --- /dev/null +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2025 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. + */ + +@!namespace("@ohos.multimedia.image") + +@!sts_inject(""" +import { AsyncCallback, BusinessError } from '@ohos.base'; +import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; +import type resourceManager from '@ohos.resourceManager'; +import type rpc from '@ohos.rpc'; +""") \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_packer_taihe.h b/frameworks/kits/taihe/include/image_packer_taihe.h new file mode 100644 index 000000000..0c4881332 --- /dev/null +++ b/frameworks/kits/taihe/include/image_packer_taihe.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_PACKER_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_PACKER_TAIHE_H + +#include "image_packer.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class ImagePackerImpl { +public: + ImagePackerImpl(); + explicit ImagePackerImpl(std::shared_ptr imagePacker); + ~ImagePackerImpl(); + + void PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options); + void PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options); + void PackPictureToFileSync(weak::Picture picture, int32_t fd, PackingOption const& options); + + array PackingPixelMapSync(weak::PixelMap source, PackingOption const& option); + array PackingPictureSync(weak::Picture picture, PackingOption const& options); + void ReleaseSync(); + + array GetSupportedFormats(); + +private: + std::shared_ptr nativeImagePacker_; + bool isRelease = false; +}; +} + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_PACKER_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h new file mode 100644 index 000000000..f6d5cb816 --- /dev/null +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_SOURCE_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_SOURCE_TAIHE_H + +#include "image_packer_taihe.h" +#include "image_source.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class ImageSourceImpl { +public: + ImageSourceImpl(); + explicit ImageSourceImpl(std::shared_ptr imageSource); + ~ImageSourceImpl(); + int64_t GetImplPtr(); + + ImageInfo GetImageInfoSyncWithIndex(uint32_t index); + ImageInfo GetImageInfoSync(); + PixelMap CreatePixelMapSyncWithOptions(DecodingOptions const& options); + PixelMap CreatePixelMapSync(); + PixelMap CreatePixelMapUsingAllocatorSync(optional_view options, + optional_view allocatorType); + array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); + array CreatePixelMapListSync(); + array GetDelayTimeListSync(); + string GetImagePropertySync(PropertyKey key, optional_view options); + map GetImagePropertiesSync(array_view key); + void ModifyImagePropertySync(PropertyKey key, string_view value); + void ModifyImagePropertiesSync(map_view records); + void ReleaseSync(); + + array GetSupportedFormats(); + + std::shared_ptr nativeImgSrc = nullptr; + std::shared_ptr GetIncrementalPixelMap() const + { + return navIncPixelMap_; + } + + static thread_local std::string filePath_; + static thread_local int fileDescriptor_; + static thread_local void* fileBuffer_; + static thread_local size_t fileBufferSize_; +private: + std::shared_ptr navIncPixelMap_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_SOURCE_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_taihe_utils.h b/frameworks/kits/taihe/include/image_taihe_utils.h new file mode 100644 index 000000000..cdbe6fb42 --- /dev/null +++ b/frameworks/kits/taihe/include/image_taihe_utils.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_UTILS_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_UTILS_H + +#include "image_source.h" +#include "image_type.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class ImageTaiheUtils { +public: + static void HicheckerReport(); + static void ThrowExceptionError(const std::string errMsg); + static void ThrowExceptionError(const int32_t errCode, const std::string errMsg); + struct ImagePropertyOptions { + uint32_t index = 0; + std::string defaultValueStr; + }; + + static bool GetPropertyInt(ani_env *env, ani_object obj, const std::string &name, int32_t &value); + static ani_object ToBusinessError(ani_env *env, int32_t code, const std::string &message); + + static OHOS::Media::SourceOptions ParseSourceOptions(SourceOptions const& options); + static ImageInfo ToTaiheImageInfo(const OHOS::Media::ImageInfo &src, bool isHdr); + static array ToTaiheArrayString(const std::vector &src); + static array CreateTaiheArrayBuffer(uint8_t* src, size_t srcLen); + + template + static bool GetEnumKeyByValue(ValueType value, typename EnumType::key_t &key); +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_UTILS_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/picture_taihe.h b/frameworks/kits/taihe/include/picture_taihe.h new file mode 100644 index 000000000..9a9952244 --- /dev/null +++ b/frameworks/kits/taihe/include/picture_taihe.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_H + +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "picture.h" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class PictureImpl { +public: + PictureImpl(); + explicit PictureImpl(std::shared_ptr picture); + ~PictureImpl(); + int64_t GetImplPtr(); + std::shared_ptr GetNativePtr(); + + PixelMap GetMainPixelmap(); + void Marshalling(uintptr_t sequence); + void Release(); + +private: + std::shared_ptr nativePicture_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h new file mode 100644 index 000000000..94ff224c8 --- /dev/null +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_PIXEL_MAP_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_PIXEL_MAP_TAIHE_H + +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "pixel_map.h" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; +using namespace OHOS; + +class PixelMapImpl { +public: + PixelMapImpl(); + explicit PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions); + explicit PixelMapImpl(InitializationOptions const& etsOptions); + explicit PixelMapImpl(std::shared_ptr pixelMap); + ~PixelMapImpl(); + + int64_t GetImplPtr(); + std::shared_ptr GetNativePtr(); + static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); + + ImageInfo GetImageInfoSync(); + void ReadPixelsToBufferSync(array_view dst); + void ReadPixelsSync(weak::PositionArea area); + void WriteBufferToPixelsSync(array_view src); + PixelMap CreateAlphaPixelmapSync(); + int32_t GetBytesNumberPerRow(); + int32_t GetPixelBytesNumber(); + void ScaleSync(float x, float y); + void ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel level); + void CropSync(Region const& region); + void RotateSync(float angle); + void FlipSync(bool horizontal, bool vertical); + void OpacitySync(float rate); + void SetMemoryNameSync(string_view name); + void ReleaseSync(); + bool GetIsStrideAlignment(); + +private: + std::shared_ptr nativePixelMap_ = nullptr; + bool aniEditable_ = true; + bool Is10BitFormat(Media::PixelFormat format); + void ParseInitializationOptions(InitializationOptions const& etsOptions, Media::InitializationOptions &options); + void Release(); +}; +} // namespace ANI::Image + +#endif diff --git a/frameworks/kits/taihe/src/ani_constructor.cpp b/frameworks/kits/taihe/src/ani_constructor.cpp new file mode 100644 index 000000000..ad28d0bf8 --- /dev/null +++ b/frameworks/kits/taihe/src/ani_constructor.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2025 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 "ohos.multimedia.image.image.ani.hpp" + +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_env *env; + if (ANI_OK != vm->GetEnv(ANI_VERSION_1, &env)) { + return ANI_ERROR; + } + if (ANI_OK != ohos::multimedia::image::image::ANIRegister(env)) { + std::cerr << "Error from ohos::multimedia::image::image::ANIRegister" << std::endl; + return ANI_ERROR; + } + *result = ANI_VERSION_1; + return ANI_OK; +} diff --git a/frameworks/kits/taihe/src/image_packer_taihe.cpp b/frameworks/kits/taihe/src/image_packer_taihe.cpp new file mode 100644 index 000000000..8a37ff111 --- /dev/null +++ b/frameworks/kits/taihe/src/image_packer_taihe.cpp @@ -0,0 +1,600 @@ +/* + * Copyright (C) 2025 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 "image_common.h" +#include "image_log.h" +#include "image_packer.h" +#include "image_packer_taihe.h" +#include "image_source_taihe.h" +#include "image_taihe_utils.h" +#include "image_trace.h" +#include "picture_taihe.h" +#include "pixel_map_taihe.h" +#include "media_errors.h" + +using namespace ANI::Image; + +namespace { + constexpr int32_t INVALID_FD = -1; + constexpr int32_t SIZE_256 = 256; + constexpr int32_t SIZE_512 = 512; + constexpr int32_t SIZE_1024 = 1024; + constexpr int32_t SIZE_1440 = 1440; + constexpr int32_t SIZE_1920 = 1920; + constexpr int64_t FILE_SIZE_300K = 300 * 1024; + constexpr int64_t FILE_SIZE_1M = 1 * 1024 * 1024; + constexpr int64_t FILE_SIZE_4M = 4 * 1024 * 1024; + constexpr int64_t FILE_SIZE_10M = 10 * 1024 * 1024; +} + +namespace ANI::Image { +const uint8_t BYTE_FULL = 0xFF; +const int32_t SIZE = 100; +const int32_t TYPE_IMAGE_SOURCE = 1; +const int32_t TYPE_PIXEL_MAP = 2; +const int32_t TYPE_PICTURE = 3; +const int32_t TYPE_ARRAY = 4; +const int64_t DEFAULT_BUFFER_SIZE = 25 * 1024 * 1024; // 25M is the maximum default packedSize + +struct ImagePackerTaiheContext { + OHOS::Media::PackOption packOption; + std::shared_ptr rImagePacker; + std::shared_ptr rImageSource; + std::shared_ptr rPixelMap; +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + std::shared_ptr rPicture; +#endif + std::shared_ptr>> rPixelMaps; + std::unique_ptr resultBuffer; + int32_t packType = TYPE_IMAGE_SOURCE; + int64_t resultBufferSize = 0; + int64_t packedSize = 0; + int fd = INVALID_FD; + bool needReturnErrorCode = true; +}; + +ImagePackerImpl::ImagePackerImpl() : nativeImagePacker_(nullptr) {} + +ImagePackerImpl::ImagePackerImpl(std::shared_ptr imagePacker) +{ + nativeImagePacker_ = imagePacker; +} + +ImagePackerImpl::~ImagePackerImpl() +{ + ReleaseSync(); +} + +static int64_t GetDefaultBufferSize(int32_t width, int32_t height) +{ + if (width <= SIZE_256 && height <= SIZE_256) { + return FILE_SIZE_300K; + } + if (width <= SIZE_512 && height <= SIZE_512) { + return FILE_SIZE_1M; + } + if (width <= SIZE_1024 && height <= SIZE_1024) { + return FILE_SIZE_4M; + } + if (width <= SIZE_1440 && height <= SIZE_1920) { + return FILE_SIZE_10M; + } + return DEFAULT_BUFFER_SIZE; +} + +static int64_t GetDefaultBufferSize(std::unique_ptr &context) +{ + if (context == nullptr) { + return DEFAULT_BUFFER_SIZE; + } + OHOS::Media::ImageInfo imageInfo {}; + if (context->packType == TYPE_IMAGE_SOURCE) { + if (context->rImageSource == nullptr) { + return DEFAULT_BUFFER_SIZE; + } + context->rImageSource->GetImageInfo(imageInfo); + } else if (context->packType == TYPE_PIXEL_MAP) { + if (context->rPixelMap == nullptr) { + return DEFAULT_BUFFER_SIZE; + } + context->rPixelMap->GetImageInfo(imageInfo); + } + if (imageInfo.size.width <= 0 || imageInfo.size.height <= 0) { + return DEFAULT_BUFFER_SIZE; + } + return GetDefaultBufferSize(imageInfo.size.width, imageInfo.size.height); +} + +static OHOS::Media::EncodeDynamicRange ParseDynamicRange(PackingOption const& options) +{ + uint32_t tmpNumber = 0; + if (!options.desiredDynamicRange.has_value()) { + return OHOS::Media::EncodeDynamicRange::SDR; + } else { + tmpNumber = static_cast(options.desiredDynamicRange->get_value()); + } + if (tmpNumber <= static_cast(OHOS::Media::EncodeDynamicRange::SDR)) { + return OHOS::Media::EncodeDynamicRange(tmpNumber); + } + return OHOS::Media::EncodeDynamicRange::SDR; +} + +static bool ParseNeedsPackProperties(PackingOption const& options) +{ + if (!options.needsPackProperties.has_value()) { + IMAGE_LOGD("No needsPackProperties in pack option"); + return false; + } + return options.needsPackProperties.value(); +} + +static int64_t ParseBufferSize(std::unique_ptr &context, PackingOption const& options) +{ + int64_t defaultSize = GetDefaultBufferSize(context); + if (!options.bufferSize.has_value()) { + IMAGE_LOGI("No bufferSize, Using default"); + return defaultSize; + } + int64_t tmpNumber = options.bufferSize.value(); + IMAGE_LOGD("BufferSize is %{public}" PRId64, tmpNumber); + if (tmpNumber < 0) { + return defaultSize; + } + return tmpNumber; +} + +static uint8_t ParsePackOptionOfQuality(PackingOption const& options) +{ + uint32_t tmpNumber = options.quality; + if (tmpNumber > SIZE) { + IMAGE_LOGE("Invalid quality"); + return BYTE_FULL; + } else { + return static_cast(tmpNumber & 0xff); + } +} + +static OHOS::Media::PackOption ParsePackOptions(PackingOption const& options) +{ + OHOS::Media::PackOption packOption; + packOption.format = std::string(options.format); + packOption.quality = ParsePackOptionOfQuality(options); + packOption.desiredDynamicRange = ParseDynamicRange(options); + IMAGE_LOGI("ParsePackOptions format:[%{public}s]", packOption.format.c_str()); + packOption.needsPackProperties = ParseNeedsPackProperties(options); + return packOption; +} + +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) +bool SetPicture(std::unique_ptr &context) +{ + IMAGE_LOGD("ImagePacker set picture"); + if (context->rPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Picture is nullptr"); + return false; + } + context->rImagePacker->AddPicture(*(context->rPicture)); + return true; +} +#endif + +bool SetArrayPixel(std::unique_ptr &context) +{ + IMAGE_LOGD("ImagePacker set pixelmap array"); + if (!context->rPixelMaps) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelmapList is nullptr"); + return false; + } + for (auto &pixelMap : *context->rPixelMaps.get()) { + context->rImagePacker->AddImage(*(pixelMap.get())); + } + return true; +} + +static bool FinalizePackToFile(std::unique_ptr &context) +{ + int64_t packedSize = 0; + auto packRes = context->rImagePacker->FinalizePacking(packedSize); + IMAGE_LOGD("packRes=%{public}d packedSize=%{public}" PRId64, packRes, packedSize); + if (packRes == OHOS::Media::SUCCESS && packedSize > 0) { + context->packedSize = packedSize; + return true; + } else { + ImageTaiheUtils::ThrowExceptionError(packRes, "PackedSize outside size"); + IMAGE_LOGE("Packing failed, packedSize outside size."); + if (context->packType == TYPE_PICTURE) { + ImageTaiheUtils::ThrowExceptionError(packRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ? + IMAGE_BAD_PARAMETER : IMAGE_ENCODE_FAILED, "PackToFile picture failed"); + } + return false; + } +} + +static bool PackToFileExec(std::unique_ptr &context) +{ + auto startRes = context->rImagePacker->StartPacking(context->fd, context->packOption); + if (startRes != OHOS::Media::SUCCESS) { + if (context->packType == TYPE_PICTURE) { + ImageTaiheUtils::ThrowExceptionError(startRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ? + IMAGE_BAD_PARAMETER : IMAGE_ENCODE_FAILED, "PackToFile start packing failed"); + return false; + } + ImageTaiheUtils::ThrowExceptionError(startRes, "Start packing failed"); + return false; + } + if (context->packType == TYPE_IMAGE_SOURCE) { + IMAGE_LOGI("ImagePacker set image source"); + if (!context->rImageSource) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource is nullptr"); + return false; + } + context->rImagePacker->AddImage(*(context->rImageSource)); + } else if (context->packType == TYPE_PIXEL_MAP) { + IMAGE_LOGD("ImagePacker set pixelmap"); + if (!context->rPixelMap) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Pixelmap is nullptr"); + return false; + } + context->rImagePacker->AddImage(*(context->rPixelMap)); +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + } else if (context->packType == TYPE_PICTURE) { + if (!SetPicture(context)) { + return false; + } +#endif + } else if (context->packType == TYPE_ARRAY) { + if (!SetArrayPixel(context)) { + return false; + } + } + return FinalizePackToFile(context); +} + +static bool CheckPackToFileContext(std::unique_ptr &context) +{ + if (context->rImagePacker == nullptr) { + TH_THROW(std::runtime_error, "ImagePacker is nullptr"); + return false; + } + if (context->packType == TYPE_IMAGE_SOURCE) { + if (context->rImageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource is nullptr"); + return false; + } + } else if (context->packType == TYPE_PIXEL_MAP) { + if (context->rPixelMap == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMap is nullptr"); + return false; + } +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + } else if (context->packType == TYPE_PICTURE) { + if (context->rPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Picture is nullptr"); + return false; + } +#endif + } else if (context->packType == TYPE_ARRAY) { + if (context->rPixelMaps == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMaps is nullptr"); + return false; + } + } + if (context->fd <= INVALID_FD) { + uint32_t errorCode = ((context->packType == TYPE_PICTURE || + context->packType == TYPE_ARRAY)) ? IMAGE_BAD_PARAMETER : OHOS::Media::ERR_IMAGE_INVALID_PARAMETER; + ImageTaiheUtils::ThrowExceptionError(errorCode, "Invaild fd"); + return false; + } + return true; +} + +void ImagePackerImpl::PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackImageSourceToFile"); + + ImageSourceImpl* imageSourceImpl = reinterpret_cast(source->GetImplPtr()); + if (imageSourceImpl == nullptr) { + return; + } + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rImageSource = imageSourceImpl->nativeImgSrc; + taiheContext->packType = TYPE_IMAGE_SOURCE; + taiheContext->rImagePacker = nativeImagePacker_; + taiheContext->packOption = ParsePackOptions(options); + taiheContext->fd = fd; + if (!CheckPackToFileContext(taiheContext)) { + return; + } + + ImageTaiheUtils::HicheckerReport(); + + if (!PackToFileExec(taiheContext)) { + IMAGE_LOGE("PackToFileExec Failed"); + } +} + +void ImagePackerImpl::PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPixelMapToFile"); + + PixelMapImpl* pixelMapImpl = reinterpret_cast(source->GetImplPtr()); + if (pixelMapImpl == nullptr) { + return; + } + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rPixelMap = pixelMapImpl->GetNativePtr(); + taiheContext->packType = TYPE_PIXEL_MAP; + taiheContext->rImagePacker = nativeImagePacker_; + taiheContext->packOption = ParsePackOptions(options); + taiheContext->fd = fd; + if (!CheckPackToFileContext(taiheContext)) { + return; + } + + ImageTaiheUtils::HicheckerReport(); + + if (!PackToFileExec(taiheContext)) { + IMAGE_LOGE("PackToFileExec Failed"); + } +} + +void ImagePackerImpl::PackPictureToFileSync(weak::Picture picture, int32_t fd, PackingOption const& options) +{ +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPictureToFile"); + + PictureImpl* pictureImpl = reinterpret_cast(picture->GetImplPtr()); + if (pictureImpl == nullptr) { + return; + } + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rPicture = pictureImpl->GetNativePtr(); + taiheContext->packType = TYPE_PIXEL_MAP; + taiheContext->rImagePacker = nativeImagePacker_; + taiheContext->packOption = ParsePackOptions(options); + taiheContext->fd = fd; + if (!CheckPackToFileContext(taiheContext)) { + return; + } + + ImageTaiheUtils::HicheckerReport(); + + if (!PackToFileExec(taiheContext)) { + IMAGE_LOGE("PackToFileExec Failed"); + } +#endif +} + +static void ThrowPackingError(std::unique_ptr &ctx, int32_t errorCode, const std::string msg) +{ + if (ctx == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImagePacker taihe context is nullptr"); + return; + } + if (ctx->needReturnErrorCode) { + ImageTaiheUtils::ThrowExceptionError(errorCode, msg); + } else { + ImageTaiheUtils::ThrowExceptionError(msg); + } +} + +static bool FinalizePacking(std::unique_ptr &context, int32_t innerEncodeErrorCode) +{ + int64_t packedSize = 0; + auto packRes = context->rImagePacker->FinalizePacking(packedSize); + IMAGE_LOGD("packedSize=%{public}" PRId64, packedSize); + if (packRes == OHOS::Media::SUCCESS) { + context->packedSize = packedSize; + return true; + } else if (packedSize == context->resultBufferSize) { + if (context->packType == TYPE_PICTURE) { + ThrowPackingError(context, IMAGE_ENCODE_FAILED, "output buffer is not enough"); + } else { + ThrowPackingError(context, OHOS::Media::ERR_IMAGE_TOO_LARGE, "output buffer is not enough"); + } + IMAGE_LOGE("output buffer is not enough."); + return false; + } else { + IMAGE_LOGE("Packing failed, packedSize outside size."); + ThrowPackingError(context, packRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ? + OHOS::Media::COMMON_ERR_INVALID_PARAMETER : innerEncodeErrorCode, "Packing failed"); + return false; + } +} + +static bool PackingExec(std::unique_ptr &context) +{ + IMAGE_LOGD("ImagePacker BufferSize %{public}" PRId64, context->resultBufferSize); + context->resultBuffer = std::make_unique( + (context->resultBufferSize <= 0) ? GetDefaultBufferSize(context) : context->resultBufferSize); + int32_t innerEncodeErrorCode = static_cast( + context->packType == TYPE_PICTURE ? IMAGE_ENCODE_FAILED : OHOS::Media::ERR_IMAGE_ENCODE_FAILED); + if (context->resultBuffer == nullptr) { + ThrowPackingError(context, innerEncodeErrorCode, "ImagePacker buffer alloc error"); + return false; + } + auto startRes = context->rImagePacker->StartPacking(context->resultBuffer.get(), + context->resultBufferSize, context->packOption); + if (startRes != OHOS::Media::SUCCESS) { + ThrowPackingError(context, startRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ? + OHOS::Media::COMMON_ERR_INVALID_PARAMETER : innerEncodeErrorCode, "Packing start packing failed"); + return false; + } + if (context->packType == TYPE_IMAGE_SOURCE) { + IMAGE_LOGI("ImagePacker set image source"); + if (context->rImageSource == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource is nullptr"); + return false; + } + context->rImagePacker->AddImage(*(context->rImageSource)); + } else if (context->packType == TYPE_PIXEL_MAP) { + IMAGE_LOGD("ImagePacker set pixelmap"); + if (context->rPixelMap == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Pixelmap is nullptr"); + return false; + } + context->rImagePacker->AddImage(*(context->rPixelMap)); +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + } else if (context->packType == TYPE_PICTURE) { + if (!SetPicture(context)) { + return false; + } +#endif + } else if (context->packType == TYPE_ARRAY) { + if (!SetArrayPixel(context)) { + return false; + } + } + return FinalizePacking(context, innerEncodeErrorCode); +} + +static array PackingComplete(std::unique_ptr &context) +{ + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("PackingComplete context is nullptr!"); + return array(0); + } + + array arrayBuffer = ImageTaiheUtils::CreateTaiheArrayBuffer(context->resultBuffer.get(), + context->packedSize); + if (arrayBuffer.empty()) { + ImageTaiheUtils::ThrowExceptionError("CreateTaiheArrayBuffer failed!"); + } + + context->resultBuffer = nullptr; + context->resultBufferSize = 0; + return arrayBuffer; +} + +static bool CheckPackingContext(std::unique_ptr &context) +{ + if (context->rImagePacker == nullptr) { + ThrowPackingError(context, OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "native ImagePacker is nullptr"); + return false; + } + if (context->packType == TYPE_IMAGE_SOURCE) { + if (context->rImageSource == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource is nullptr"); + return false; + } + } else if (context->packType == TYPE_PIXEL_MAP) { + if (context->rPixelMap == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMap is nullptr"); + return false; + } +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + } else if (context->packType == TYPE_PICTURE) { + if (context->rPicture == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Picture is nullptr"); + return false; + } +#endif + } else if (context->packType == TYPE_ARRAY) { + if (context->rPixelMaps == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMaps is nullptr"); + return false; + } + } + return true; +} + +static array Packing(std::unique_ptr& taiheContext) +{ + ImageTaiheUtils::HicheckerReport(); + + if (!CheckPackingContext(taiheContext)) { + return array(0); + } + + if (!PackingExec(taiheContext)) { + IMAGE_LOGE("PackingExec Failed"); + return array(0); + } + return PackingComplete(taiheContext); +} + +array ImagePackerImpl::PackingPixelMapSync(weak::PixelMap source, PackingOption const& option) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPixelMapSync"); + IMAGE_LOGI("PackingPixelMapSync IN"); + + std::unique_ptr taiheContext = std::make_unique(); + PixelMapImpl* pixelMapImpl = reinterpret_cast(source->GetImplPtr()); + if (pixelMapImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap pixelMapImpl."); + return array(0); + } + taiheContext->needReturnErrorCode = false; + + taiheContext->rImagePacker = nativeImagePacker_; + taiheContext->packType = TYPE_PIXEL_MAP; + taiheContext->rPixelMap = pixelMapImpl->GetNativePtr(); + taiheContext->packOption = ParsePackOptions(option); + taiheContext->resultBufferSize = ParseBufferSize(taiheContext, option); + + return Packing(taiheContext); +} + +array ImagePackerImpl::PackingPictureSync(weak::Picture picture, PackingOption const& options) +{ +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPictureSync"); + IMAGE_LOGI("PackingPictureSync IN"); + + std::unique_ptr taiheContext = std::make_unique(); + PictureImpl* pictureImpl = reinterpret_cast(picture->GetImplPtr()); + if (pictureImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Unwarp pictureImpl failed."); + return array(0); + } + taiheContext->needReturnErrorCode = true; + + taiheContext->rImagePacker = nativeImagePacker_; + taiheContext->packType = TYPE_PICTURE; + taiheContext->rPicture = pictureImpl->GetNativePtr(); + taiheContext->packOption = ParsePackOptions(options); + taiheContext->resultBufferSize = ParseBufferSize(taiheContext, options); + + return Packing(taiheContext); +#else + ImageTaiheUtils::ThrowExceptionError("Invalid type!"); +#endif +} + +void ImagePackerImpl::ReleaseSync() +{ + if (!isRelease) { + nativeImagePacker_ = nullptr; + isRelease = true; + } +} + +array ImagePackerImpl::GetSupportedFormats() +{ + std::set formats; + nativeImagePacker_->GetSupportedFormats(formats); + std::vector vec(formats.begin(), formats.end()); + return ImageTaiheUtils::ToTaiheArrayString(vec); +} + +ImagePacker CreateImagePacker() +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::CreateImagePacker"); + std::shared_ptr imagePacker = std::make_shared(); + return make_holder(imagePacker); +} +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreateImagePacker(CreateImagePacker); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp new file mode 100644 index 000000000..07a098c39 --- /dev/null +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -0,0 +1,1182 @@ +/* + * Copyright (C) 2025 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 "image_common.h" +#include "image_dfx.h" +#include "image_log.h" +#include "image_source_taihe.h" +#include "image_taihe_utils.h" +#include "image_trace.h" +#include "image_type.h" +#include "jpeg_decoder_yuv.h" +#include "media_errors.h" +#include "pixel_map_taihe.h" +#include "exif_metadata_formatter.h" + +using namespace ANI::Image; +using JpegYuvDecodeError = OHOS::ImagePlugin::JpegYuvDecodeError; + +namespace { + constexpr int INVALID_FD = -1; + constexpr uint32_t NUM_0 = 0; +} + +namespace ANI::Image { +static const std::string FILE_URL_PREFIX = "file://"; +thread_local std::string ImageSourceImpl::filePath_ = ""; +thread_local int ImageSourceImpl::fileDescriptor_ = -1; +thread_local void* ImageSourceImpl::fileBuffer_ = nullptr; +thread_local size_t ImageSourceImpl::fileBufferSize_ = 0; + +static std::mutex imageSourceCrossThreadMutex_; + +struct ImageSourceTaiheContext { + ImageSourceImpl *thisPtr; + uint32_t status; + std::string pathName = ""; + int fdIndex = INVALID_FD; + void* sourceBuffer = nullptr; + size_t sourceBufferSize = NUM_0; + std::string keyStr; + std::string valueStr; + std::vector keyStrArray; + std::vector> kVStrArray; + std::string defaultValueStr; + uint32_t index = 0; + bool isBatch = false; + OHOS::Media::DecodeOptions decodeOpts; + std::shared_ptr rImageSource; + std::shared_ptr rPixelMap; + std::string errMsg; + std::multimap errMsgArray; + std::unique_ptr>> pixelMaps; + std::unique_ptr> delayTimes; +}; + +static const std::map ERROR_CODE_MAP = { + {OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, Image_ErrorCode::IMAGE_BAD_PARAMETER}, + {OHOS::Media::COMMON_ERR_INVALID_PARAMETER, Image_ErrorCode::IMAGE_BAD_PARAMETER}, + {JpegYuvDecodeError::JpegYuvDecodeError_InvalidParameter, Image_ErrorCode::IMAGE_BAD_PARAMETER}, + {OHOS::Media::ERR_IMAGE_SOURCE_DATA, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {OHOS::Media::ERR_IMAGE_SOURCE_DATA_INCOMPLETE, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {OHOS::Media::ERR_IMAGE_GET_DATA_ABNORMAL, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {OHOS::Media::ERROR, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {JpegYuvDecodeError::JpegYuvDecodeError_BadImage, Image_ErrorCode::IMAGE_BAD_SOURCE}, + {OHOS::Media::ERR_IMAGE_MISMATCHED_FORMAT, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_MIMETYPE}, + {OHOS::Media::ERR_IMAGE_UNKNOWN_FORMAT, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_MIMETYPE}, + {OHOS::Media::ERR_IMAGE_DECODE_HEAD_ABNORMAL, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_MIMETYPE}, + {OHOS::Media::ERR_IMAGE_TOO_LARGE, Image_ErrorCode::IMAGE_SOURCE_TOO_LARGE}, + {OHOS::Media::ERR_MEDIA_INVALID_OPERATION, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_ALLOCATOR_TYPE}, + {OHOS::Media::IMAGE_RESULT_FORMAT_CONVERT_FAILED, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS}, + {OHOS::Media::ERR_MEDIA_FORMAT_UNSUPPORT, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS}, + {OHOS::Media::ERR_IMAGE_PIXELMAP_CREATE_FAILED, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS}, + {JpegYuvDecodeError::JpegYuvDecodeError_ConvertError, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS}, + {OHOS::Media::ERR_IMAGE_CROP, Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS}, + {OHOS::Media::ERR_IMAGE_DECODE_FAILED, Image_ErrorCode::IMAGE_DECODE_FAILED}, + {OHOS::Media::ERR_IMAGE_DECODE_ABNORMAL, Image_ErrorCode::IMAGE_DECODE_FAILED}, + {OHOS::Media::ERR_IMAGE_PLUGIN_CREATE_FAILED, Image_ErrorCode::IMAGE_DECODE_FAILED}, + {JpegYuvDecodeError::JpegYuvDecodeError_DecodeFailed, Image_ErrorCode::IMAGE_DECODE_FAILED}, + {JpegYuvDecodeError::JpegYuvDecodeError_MemoryNotEnoughToSaveResult, Image_ErrorCode::IMAGE_DECODE_FAILED}, + {OHOS::Media::ERR_IMAGE_MALLOC_ABNORMAL, Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED}, + {OHOS::Media::ERR_IMAGE_DATA_UNSUPPORT, Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED}, + {OHOS::Media::ERR_DMA_NOT_EXIST, Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED}, + {OHOS::Media::ERR_DMA_DATA_ABNORMAL, Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED}, + {OHOS::Media::ERR_SHAMEM_DATA_ABNORMAL, Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED} +}; + +static const std::map ERROR_CODE_MESSAGE_MAP = { + {Image_ErrorCode::IMAGE_BAD_PARAMETER, "Parameter error. Possible causes:" + "1.Mandatory parameters are left unspecified. 2.Incorrect parameter types. 3.Parameter verification failed."}, + {Image_ErrorCode::IMAGE_BAD_SOURCE, "Bad source. e.g.,1.Image has invalid width or height." + "2.Image source incomplete. 3.Read image data failed. 4. Codec create failed." + "5.The sourceOption specifies an odd width, causing the YUV420 PixelMap conversion to RGBA failed."}, + {Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_MIMETYPE, "Unsupported mimetype."}, + {Image_ErrorCode::IMAGE_SOURCE_TOO_LARGE, "Image too large."}, + {Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_ALLOCATOR_TYPE, "Unsupported allocator type. e.g.," + "use share memory to decode a HDR image as only DMA supported hdr metadata."}, + {Image_ErrorCode::IMAGE_SOURCE_UNSUPPORTED_OPTIONS, "Unsupported options. e.g.," + "1.Convert image into desired pixelFormat failed. 2.Crop pixelMap failed."}, + {Image_ErrorCode::IMAGE_DECODE_FAILED, "Decode failed. e.g.,Decode image header failed."}, + {Image_ErrorCode::IMAGE_SOURCE_ALLOC_FAILED, "Memory allocation failed."} +}; + +static Image_ErrorCode ConvertToErrorCode(int32_t errorCode) +{ + Image_ErrorCode apiErrorCode = Image_ErrorCode::IMAGE_DECODE_FAILED; + auto iter = ERROR_CODE_MAP.find(errorCode); + if (iter != ERROR_CODE_MAP.end()) { + apiErrorCode = iter->second; + } + return apiErrorCode; +} + +static std::string GetErrorCodeMsg(Image_ErrorCode apiErrorCode) +{ + std::string errMsg = "Decode failed."; + auto iter = ERROR_CODE_MESSAGE_MAP.find(apiErrorCode); + if (iter != ERROR_CODE_MESSAGE_MAP.end()) { + errMsg = iter->second; + } + return errMsg; +} + +ImageSourceImpl::ImageSourceImpl() {} + +ImageSourceImpl::ImageSourceImpl(std::shared_ptr imageSource) +{ + nativeImgSrc = imageSource; +} + +ImageSourceImpl::~ImageSourceImpl() +{ + ReleaseSync(); +} + +int64_t ImageSourceImpl::GetImplPtr() +{ + return reinterpret_cast(this); +} + +ImageInfo ImageSourceImpl::GetImageInfoSyncWithIndex(uint32_t index) +{ + OHOS::Media::ImageInfo imageinfo; + bool isHdr = false; + if (nativeImgSrc != nullptr) { + index = index >= NUM_0 ? index : NUM_0; + nativeImgSrc->GetImageInfo(index, imageinfo); + isHdr = nativeImgSrc->IsHdrImage(); + } else { + ImageTaiheUtils::ThrowExceptionError("nativeImgSrc is nullptr"); + } + return ImageTaiheUtils::ToTaiheImageInfo(imageinfo, isHdr); +} + +ImageInfo ImageSourceImpl::GetImageInfoSync() +{ + uint32_t index = 0; + return GetImageInfoSyncWithIndex(index); +} + +static bool ParseRotate(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst, std::string &errMsg) +{ + if (options.rotate.has_value()) { + dst.rotateNewDegrees = options.rotate.value(); + if (dst.rotateNewDegrees >= 0 && dst.rotateNewDegrees <= 360) { // 360 is the maximum rotation angle. + dst.rotateDegrees = static_cast(dst.rotateNewDegrees); + IMAGE_LOGD("rotateDegrees: %{public}f", dst.rotateDegrees); + } else { + IMAGE_LOGD("Invalid rotate %{public}d", dst.rotateNewDegrees); + errMsg = "DecodeOptions mismatch"; + return false; + } + } + return true; +} + +static OHOS::Media::Rect ParseDesiredRegion(DecodingOptions const& options) +{ + OHOS::Media::Rect rect {}; + if (options.desiredRegion.has_value()) { + auto ®ion = options.desiredRegion.value(); + rect.left = region.x; + rect.top = region.y; + rect.width = region.size.width; + rect.height = region.size.height; + IMAGE_LOGD("desiredRegion: %{public}d, %{public}d, %{public}d, %{public}d", + rect.left, rect.top, rect.width, rect.height); + } + return rect; +} + +static bool IsAstc(int32_t val) +{ + if (val >= static_cast(OHOS::Media::PixelFormat::ASTC_4x4) && + val <= static_cast(OHOS::Media::PixelFormat::ASTC_8x8)) { + return true; + } + return false; +} + +static bool IsSupportPixelFormat(int32_t val) +{ + if (IsAstc(val)) { + return true; + } + if (val >= static_cast(OHOS::Media::PixelFormat::UNKNOWN) && + val < static_cast(OHOS::Media::PixelFormat::EXTERNAL_MAX)) { + return true; + } + + return false; +} + +static OHOS::Media::PixelFormat ParsePixelFormat(int32_t val) +{ + if (IsAstc(val)) { + return OHOS::Media::PixelFormat(val); + } + if (val < static_cast(OHOS::Media::PixelFormat::EXTERNAL_MAX)) { + return OHOS::Media::PixelFormat(val); + } + + return OHOS::Media::PixelFormat::UNKNOWN; +} + +static bool ParsePixelFormat(optional val, OHOS::Media::PixelFormat &dst, const std::string &name, + std::string &errMsg) +{ + if (!val.has_value()) { + IMAGE_LOGD("no %{public}s", name.c_str()); + } else { + int32_t pixelFormat = val->get_value(); + if (IsSupportPixelFormat(pixelFormat)) { + dst = ParsePixelFormat(pixelFormat); + IMAGE_LOGD("PixelFormat: %{public}d", dst); + } else { + IMAGE_LOGD("Invalid %{public}s %{public}d", name.c_str(), pixelFormat); + errMsg = "DecodeOptions mismatch"; + return false; + } + } + return true; +} + +static void ParseDesiredColorSpace(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst) +{ + if (options.desiredColorSpace.has_value()) { + IMAGE_LOGD("desiredColorSpace parse finished"); + return; + } +} + +static OHOS::Media::DecodeDynamicRange ParseDynamicRange(DecodingOptions const& options) +{ + if (options.desiredDynamicRange.has_value()) { + int32_t desiredDynamicRange = options.desiredDynamicRange->get_value(); + if (desiredDynamicRange <= static_cast(OHOS::Media::DecodeDynamicRange::HDR)) { + IMAGE_LOGD("desiredDynamicRange: %{public}d", desiredDynamicRange); + return OHOS::Media::DecodeDynamicRange(desiredDynamicRange); + } + } + return OHOS::Media::DecodeDynamicRange::SDR; +} + +static OHOS::Media::ResolutionQuality ParseResolutionQuality(DecodingOptions const& options) +{ + if (options.resolutionQuality.has_value()) { + int32_t resolutionQuality = options.resolutionQuality->get_value(); + if (resolutionQuality <= static_cast(OHOS::Media::ResolutionQuality::HIGH) && + (resolutionQuality >= static_cast(OHOS::Media::ResolutionQuality::UNKNOWN))) { + IMAGE_LOGD("resolutionQuality: %{public}d", resolutionQuality); + return OHOS::Media::ResolutionQuality(resolutionQuality); + } + } + return OHOS::Media::ResolutionQuality::UNKNOWN; +} + +static inline bool IsCropStrategyVaild(int32_t strategy) +{ + return strategy >= static_cast(OHOS::Media::CropAndScaleStrategy::SCALE_FIRST) && + strategy <= static_cast(OHOS::Media::CropAndScaleStrategy::CROP_FIRST); +} + +static void ParseCropAndScaleStrategy(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst) +{ + if (options.cropAndScaleStrategy.has_value() && IsCropStrategyVaild(options.cropAndScaleStrategy->get_value())) { + IMAGE_LOGI("The strategy has taken effect"); + dst.cropAndScaleStrategy = OHOS::Media::CropAndScaleStrategy(options.cropAndScaleStrategy->get_value()); + IMAGE_LOGD("cropAndScaleStrategy: %{public}d", dst.cropAndScaleStrategy); + return; + } + IMAGE_LOGI("default cropAndScaleStrategy"); +} + +static void ParseReusePixelMap(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst) +{ + if (options.reusePixelmap.has_value()) { + PixelMap etsPixelMap = options.reusePixelmap.value(); + std::shared_ptr rPixelMap = PixelMapImpl::GetPixelMap(etsPixelMap); + if (rPixelMap != nullptr) { + dst.reusePixelmap = rPixelMap; + IMAGE_LOGD("reusePixelmap parse finished"); + } + } +} + +static bool ParseDecodeOptions2(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst, std::string &errMsg) +{ + if (!ParsePixelFormat(options.desiredPixelFormat, dst.desiredPixelFormat, "desiredPixelFormat", errMsg) || + !ParsePixelFormat(options.photoDesiredPixelFormat, dst.photoDesiredPixelFormat, + "photoDesiredPixelFormat", errMsg)) { + return false; + } + + if (options.fitDensity.has_value()) { + dst.fitDensity = options.fitDensity.value(); + IMAGE_LOGD("fitDensity: %{public}d", dst.fitDensity); + } + + if (options.fillColor.has_value()) { + dst.SVGOpts.fillColor.isValidColor = true; + dst.SVGOpts.fillColor.color = options.fillColor.value(); + IMAGE_LOGD("fillColor: %{public}d", dst.SVGOpts.fillColor.color); + } + + if (options.SVGResize.has_value()) { + dst.SVGOpts.SVGResize.isValidPercentage = true; + dst.SVGOpts.SVGResize.resizePercentage = options.SVGResize.value(); + IMAGE_LOGD("SVGResize: %{public}d", dst.SVGOpts.SVGResize.resizePercentage); + } + + ParseDesiredColorSpace(options, dst); + if (dst.desiredColorSpaceInfo == nullptr) { + IMAGE_LOGD("no desiredColorSpace"); + } + + dst.desiredDynamicRange = ParseDynamicRange(options); + dst.resolutionQuality = ParseResolutionQuality(options); + ParseCropAndScaleStrategy(options, dst); + ParseReusePixelMap(options, dst); + return true; +} + +static bool ParseDecodeOptions(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst, uint32_t &index, + std::string &errMsg) +{ + if (options.index.has_value()) { + index = options.index.value(); + IMAGE_LOGD("index: %{public}d", index); + } + + if (options.sampleSize.has_value()) { + dst.sampleSize = options.sampleSize.value(); + IMAGE_LOGD("sampleSize: %{public}d", dst.sampleSize); + } + + CHECK_ERROR_RETURN_RET_LOG(!ParseRotate(options, dst, errMsg), false, "%{public}s ParseRotate failed", __func__); + + if (options.editable.has_value()) { + dst.editable = options.editable.value(); + IMAGE_LOGD("editable: %{public}d", dst.editable); + } + + if (options.desiredSize.has_value()) { + dst.desiredSize.width = options.desiredSize.value().width; + dst.desiredSize.height = options.desiredSize.value().height; + IMAGE_LOGD("desiredSize: %{public}d, %{public}d", dst.desiredSize.width, dst.desiredSize.height); + } + + dst.desiredRegion = ParseDesiredRegion(options); + return ParseDecodeOptions2(options, dst, errMsg); +} + +static std::shared_ptr CreatePixelMapInner(ImageSourceImpl *const thisPtr, + std::shared_ptr imageSource, uint32_t index, OHOS::Media::DecodeOptions decodeOpts, + uint32_t &status) +{ + if (thisPtr == nullptr || imageSource == nullptr) { + IMAGE_LOGE("Invailed args"); + status = OHOS::Media::ERROR; + } + + std::shared_ptr pixelMap; + auto incPixelMap = (thisPtr == nullptr) ? nullptr : thisPtr->GetIncrementalPixelMap(); + if (incPixelMap != nullptr) { + IMAGE_LOGD("Get Incremental PixelMap!!!"); + pixelMap = incPixelMap; + } else { + decodeOpts.invokeType = OHOS::Media::JS_INTERFACE; + pixelMap = (imageSource == nullptr) ? nullptr : imageSource->CreatePixelMapEx((index >= NUM_0) ? index : NUM_0, + decodeOpts, status); + } + + if (status != OHOS::Media::SUCCESS || pixelMap == nullptr) { + IMAGE_LOGE("Create PixelMap error"); + } + + return pixelMap; +} + +static void CreatePixelMapExecute(std::unique_ptr &taiheContext) +{ + IMAGE_LOGD("CreatePixelMapExecute IN"); + if (taiheContext == nullptr) { + IMAGE_LOGE("%{public}s taiheContext is nullptr", __func__); + return; + } + + if (taiheContext->errMsg.size() > 0) { + IMAGE_LOGE("%{public}s errMsg: %{public}s", __func__, taiheContext->errMsg.c_str()); + return; + } + + taiheContext->rPixelMap = CreatePixelMapInner(taiheContext->thisPtr, taiheContext->rImageSource, + taiheContext->index, taiheContext->decodeOpts, taiheContext->status); + + if (taiheContext->status != OHOS::Media::SUCCESS) { + taiheContext->errMsg = "Create PixelMap error"; + IMAGE_LOGE("Create PixelMap error"); + } + IMAGE_LOGD("CreatePixelMapExecute OUT"); +} + +static PixelMap CreatePixelMapComplete(std::unique_ptr &taiheContext) +{ + IMAGE_LOGD("CreatePixelMapComplete IN"); + if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->rPixelMap != nullptr) { + return make_holder(taiheContext->rPixelMap); + } + IMAGE_LOGD("CreatePixelMapComplete OUT"); + ImageTaiheUtils::ThrowExceptionError(taiheContext->errMsg); + return make_holder(); +} + +PixelMap ImageSourceImpl::CreatePixelMapSyncWithOptions(DecodingOptions const& options) +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rImageSource = nativeImgSrc; + if (taiheContext->rImageSource == nullptr) { + IMAGE_LOGE("%{public}s nativeImgSrc is nullptr", __func__); + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "nativeImgSrc is nullptr"); + return make_holder(); + } + + taiheContext->thisPtr = this; + if (taiheContext->thisPtr == nullptr) { + IMAGE_LOGE("%{public}s thisPtr is nullptr", __func__); + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "thisPtr is nullptr"); + return make_holder(); + } + + if (!ParseDecodeOptions(options, taiheContext->decodeOpts, taiheContext->index, + taiheContext->errMsg)) { + IMAGE_LOGE("%{public}s ParseDecodeOptions failed", __func__); + } + + ImageTaiheUtils::HicheckerReport(); + CreatePixelMapExecute(taiheContext); + return CreatePixelMapComplete(taiheContext); +} + +PixelMap ImageSourceImpl::CreatePixelMapSync() +{ + DecodingOptions options {}; + return CreatePixelMapSyncWithOptions(options); +} + +static void CreatePixelMapUsingAllocatorSyncExecute(std::unique_ptr &taiheContext) +{ + if (taiheContext == nullptr) { + IMAGE_LOGE("%{public}s taiheContext is nullptr", __func__); + return; + } + + taiheContext->rPixelMap = CreatePixelMapInner(taiheContext->thisPtr, taiheContext->rImageSource, + taiheContext->index, taiheContext->decodeOpts, taiheContext->status); + if (taiheContext->status != OHOS::Media::SUCCESS) { + Image_ErrorCode apiErrorCode = ConvertToErrorCode(taiheContext->status); + std::string apiErrorMsg = GetErrorCodeMsg(apiErrorCode); + taiheContext->errMsgArray.emplace(apiErrorCode, apiErrorMsg); + } +} + +static PixelMap CreatePixelMapUsingAllocatorSyncComplete(std::unique_ptr &taiheContext) +{ + if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->rPixelMap != nullptr) { + return make_holder(taiheContext->rPixelMap); + } + for (const auto &[errorCode, errMsg] : taiheContext->errMsgArray) { + ImageTaiheUtils::ThrowExceptionError(errorCode, errMsg); + } + return make_holder(); +} + +PixelMap ImageSourceImpl::CreatePixelMapUsingAllocatorSync(optional_view options, + optional_view allocatorType) +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rImageSource = nativeImgSrc; + if (taiheContext->rImageSource == nullptr) { + IMAGE_LOGE("%{public}s nativeImgSrc is nullptr", __func__); + return make_holder(); + } + + taiheContext->thisPtr = this; + if (taiheContext->thisPtr == nullptr) { + IMAGE_LOGE("%{public}s thisPtr is nullptr", __func__); + return make_holder(); + } + + DecodingOptions opts = options.value_or(DecodingOptions {}); + if (!ParseDecodeOptions(opts, taiheContext->decodeOpts, taiheContext->index, + taiheContext->errMsg)) { + IMAGE_LOGE("DecodeOptions mismatch."); + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "DecodeOptions mismatch."); + return make_holder(); + } + + int32_t allocatorTypeInner = allocatorType.value_or(AllocatorType::key_t::AUTO); + if (!taiheContext->rImageSource->IsSupportAllocatorType(taiheContext->decodeOpts, allocatorTypeInner)) { + IMAGE_LOGE("Unsupported allocator type."); + ImageTaiheUtils::ThrowExceptionError(IMAGE_SOURCE_UNSUPPORTED_ALLOCATOR_TYPE, "Unsupported allocator type."); + return make_holder(); + } + + CreatePixelMapUsingAllocatorSyncExecute(taiheContext); + return CreatePixelMapUsingAllocatorSyncComplete(taiheContext); +} + +static bool CheckAsyncContext(std::unique_ptr &taiheContext, bool check) +{ + if (taiheContext == nullptr) { + IMAGE_LOGE("context is nullptr"); + return false; + } + + if (check) { + if (taiheContext->errMsg.size() > 0) { + IMAGE_LOGE("mismatch args"); + taiheContext->status = OHOS::Media::ERROR; + return false; + } + + if (taiheContext->rImageSource == nullptr) { + IMAGE_LOGE("empty context rImageSource"); + taiheContext->status = OHOS::Media::ERROR; + return false; + } + } + + return true; +} + +static void CreatePixelMapListSyncWithOptionsExecute(std::unique_ptr &taiheContext) +{ + if (!CheckAsyncContext(taiheContext, true)) { + IMAGE_LOGE("check taiheContext fail"); + return; + } + + taiheContext->pixelMaps = nullptr; + uint32_t errorCode = 0; + uint32_t frameCount = taiheContext->rImageSource->GetFrameCount(errorCode); + if ((errorCode == OHOS::Media::SUCCESS) && (taiheContext->index >= NUM_0) && (taiheContext->index < frameCount)) { + taiheContext->decodeOpts.invokeType = OHOS::Media::JS_INTERFACE; + taiheContext->pixelMaps = taiheContext->rImageSource->CreatePixelMapList(taiheContext->decodeOpts, errorCode); + } + + if ((errorCode == OHOS::Media::SUCCESS) && taiheContext->pixelMaps != nullptr) { + taiheContext->status = OHOS::Media::SUCCESS; + } else { + IMAGE_LOGE("Create PixelMap List error, error=%{public}u", errorCode); + taiheContext->errMsg = "Create PixelMap List error"; + taiheContext->status = (errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR; + } +} + +static array CreatePixelMapListSyncWithOptionsComplete(std::unique_ptr &taiheContext) +{ + if (!CheckAsyncContext(taiheContext, false)) { + IMAGE_LOGE("check taiheContext fail"); + return array(nullptr, 0); + } + + std::vector result; + if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->pixelMaps != nullptr) { + IMAGE_LOGD("CreatePixelMapListSyncWithOptionsComplete array"); + for (auto &pixelMap : *taiheContext->pixelMaps.get()) { + result.emplace_back(make_holder(std::move(pixelMap))); + } + } + return array(result); +} + +array ImageSourceImpl::CreatePixelMapListSyncWithOptions(DecodingOptions const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::CreatePixelMapListSyncWithOptions"); + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rImageSource = nativeImgSrc; + if (taiheContext->rImageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr"); + return array(nullptr, 0); + } + + taiheContext->thisPtr = this; + if (taiheContext->thisPtr == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "thisPtr is nullptr"); + return array(nullptr, 0); + } + + if (!ParseDecodeOptions(options, taiheContext->decodeOpts, taiheContext->index, + taiheContext->errMsg)) { + IMAGE_LOGE("DecodeOptions mismatch."); + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "DecodeOptions mismatch."); + return array(nullptr, 0); + } + + ImageTaiheUtils::HicheckerReport(); + CreatePixelMapListSyncWithOptionsExecute(taiheContext); + return CreatePixelMapListSyncWithOptionsComplete(taiheContext); +} + +array ImageSourceImpl::CreatePixelMapListSync() +{ + return CreatePixelMapListSyncWithOptions({}); +} + +array ImageSourceImpl::GetDelayTimeListSync() +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDelayTimeListSync"); + + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); + return array(0); + } + + uint32_t errorCode = 0; + auto delayTimes = nativeImgSrc->GetDelayTime(errorCode); + if ((errorCode != OHOS::Media::SUCCESS) || (delayTimes == nullptr)) { + IMAGE_LOGE("Get DelayTime error, error=%{public}u", errorCode); + ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, + "Get DelayTime error"); + return array(0); + } else { + return array(taihe::copy_data_t{}, delayTimes->data(), delayTimes->size()); + } +} + +static bool ParsePropertyOptions(std::unique_ptr &context, + optional_view &options) +{ + if (!options->index.has_value()) { + IMAGE_LOGD("no index"); + return false; + } + context->index = options->index.value(); + if (!options->defaultValue.has_value()) { + IMAGE_LOGD("no defaultValue"); + } else { + context->defaultValueStr = options->defaultValue.value(); + } + return true; +} + +static void GenerateErrMsg(std::unique_ptr &context, std::string &errMsg) +{ + if (context == nullptr) { + return; + } + switch (context->status) { + case OHOS::Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT: + errMsg = "The image does not support EXIF decoding."; + break; + case OHOS::Media::ERROR: + errMsg = "The operation failed."; + break; + case OHOS::Media::ERR_IMAGE_DATA_UNSUPPORT: + errMsg = "The image data is not supported."; + break; + case OHOS::Media::ERR_IMAGE_SOURCE_DATA: + errMsg = "The image source data is incorrect."; + break; + case OHOS::Media::ERR_IMAGE_SOURCE_DATA_INCOMPLETE: + errMsg = "The image source data is incomplete."; + break; + case OHOS::Media::ERR_IMAGE_MISMATCHED_FORMAT: + errMsg = "The image format does not mastch."; + break; + case OHOS::Media::ERR_IMAGE_UNKNOWN_FORMAT: + errMsg = "Unknown image format."; + break; + case OHOS::Media::ERR_IMAGE_INVALID_PARAMETER: + errMsg = "Invalid image parameter."; + break; + case OHOS::Media::ERR_IMAGE_DECODE_FAILED: + errMsg = "Failed to decode the image."; + break; + case OHOS::Media::ERR_IMAGE_PLUGIN_CREATE_FAILED: + errMsg = "Failed to create the image plugin."; + break; + case OHOS::Media::ERR_IMAGE_DECODE_HEAD_ABNORMAL: + errMsg = "Failed to decode the image header."; + break; + case OHOS::Media::ERR_MEDIA_VALUE_INVALID: + errMsg = "The EXIF value is invalid."; + break; + default: + errMsg = "There is unknown error happened."; + } +} + +string ImageSourceImpl::GetImagePropertySync(PropertyKey key, optional_view options) +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetImagePropertySync"); + + std::unique_ptr context = std::make_unique(); + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "empty native rImageSource"); + return context->valueStr; + } + + if (options.has_value() && !ParsePropertyOptions(context, options)) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PropertyOptions mismatch"); + return context->valueStr; + } + + context->keyStr = std::string(key.get_value()); + context->status = nativeImgSrc->GetImagePropertyString(context->index, context->keyStr, context->valueStr); + if (context->status != OHOS::Media::SUCCESS) { + if (!context->defaultValueStr.empty()) { + return context->defaultValueStr; + } + std::string errMsg; + GenerateErrMsg(context, errMsg); + ImageTaiheUtils::ThrowExceptionError(context->status, errMsg); + } + return context->valueStr; +} + +static void GetImagePropertiesExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("empty context"); + return; + } + uint32_t status = OHOS::Media::SUCCESS; + for (auto keyStrIt = context->keyStrArray.begin(); keyStrIt != context->keyStrArray.end(); ++keyStrIt) { + std::string valueStr = ""; + status = context->rImageSource->GetImagePropertyString(0, *keyStrIt, valueStr); + if (status == OHOS::Media::SUCCESS) { + context->kVStrArray.emplace_back(std::make_pair(*keyStrIt, valueStr)); + } else { + context->kVStrArray.emplace_back(std::make_pair(*keyStrIt, "")); + context->errMsgArray.insert(std::make_pair(status, *keyStrIt)); + IMAGE_LOGE("errCode: %{public}u , exif key: %{public}s", status, keyStrIt->c_str()); + } + } + context->status = context->kVStrArray.size() == context->errMsgArray.size() ? + OHOS::Media::ERROR : OHOS::Media::SUCCESS; +} + +static PropertyValue CreatePropertyValue(const std::string& valueStr) +{ + if (!valueStr.empty()) { + return PropertyValue::make_type_string(valueStr); + } else { + return PropertyValue::make_type_null(); + } +} + +map CreatePropertiesRecord( + std::vector> recordParameters) +{ + map result; + for (size_t index = 0; index < recordParameters.size(); ++index) { + PropertyKey::key_t key; + if (!ImageTaiheUtils::GetEnumKeyByValue(recordParameters[index].first, key)) { + IMAGE_LOGE("Get current record parameter failed"); + continue; + } + PropertyValue value = CreatePropertyValue(recordParameters[index].second); + result.emplace(PropertyKey(key), value); + } + + IMAGE_LOGD("Get record parameters info success."); + return result; +} + +void CreateObtainErrorArray(std::multimap errMsgArray) +{ + for (auto it = errMsgArray.begin(); it != errMsgArray.end(); ++it) { + std::string errMsg; + int32_t errCode = it->first; + if (errCode == OHOS::Media::ERR_IMAGE_DECODE_ABNORMAL) { + errMsg = "The image source data is incorrect! exif key: " + it->second; + } else if (errCode == OHOS::Media::ERR_IMAGE_UNKNOWN_FORMAT) { + errMsg = "Unknown image format! exif key: " + it->second; + } else if (errCode == OHOS::Media::ERR_IMAGE_DECODE_FAILED) { + errMsg = "Failed to decode the image! exif key: " + it->second; + } else { + errCode = OHOS::Media::ERROR; + errMsg = "There is generic taihe failure! exif key: " + it->second; + } + ImageTaiheUtils::ThrowExceptionError(errCode, errMsg); + } + + IMAGE_LOGD("Create obtain error array success."); +} + +std::vector GetStringArrayArgument(array_view key) +{ + std::vector keyStrArray; + + for (uint32_t i = 0; i < key.size(); i++) { + keyStrArray.emplace_back(key[i].get_value()); + } + + IMAGE_LOGD("Get string argument success."); + return keyStrArray; +} + +map ImageSourceImpl::GetImagePropertiesSync(array_view key) +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetImagePropertiesSync"); + + map result; + std::unique_ptr context = std::make_unique(); + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "empty native rImageSource"); + return result; + } + context->rImageSource = nativeImgSrc; + context->keyStrArray = GetStringArrayArgument(key); + if (context->keyStrArray.size() == 0) return result; + + GetImagePropertiesExecute(context); + + if (context->status == OHOS::Media::SUCCESS) { + result = CreatePropertiesRecord(context->kVStrArray); + } else { + CreateObtainErrorArray(context->errMsgArray); + } + return result; +} + +void CreateModifyErrorArray(std::multimap errMsgArray) +{ + for (auto it = errMsgArray.begin(); it != errMsgArray.end(); ++it) { + if (it->first == OHOS::Media::ERR_MEDIA_WRITE_PARCEL_FAIL) { + ImageTaiheUtils::ThrowExceptionError(it->first, + "Create Fd without write permission! exif key: " + it->second); + } else if (it->first == OHOS::Media::ERR_MEDIA_OUT_OF_RANGE) { + ImageTaiheUtils::ThrowExceptionError(it->first, + "The given buffer size is too small to add new exif data! exif key: " + it->second); + } else if (it->first == OHOS::Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT) { + ImageTaiheUtils::ThrowExceptionError(it->first, + "The image does not support EXIF decoding. exif key: " + it->second); + } else if (it->first == OHOS::Media::ERR_MEDIA_VALUE_INVALID) { + ImageTaiheUtils::ThrowExceptionError(it->first, it->second); + } else { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, + "There is generic taihe failure! exif key: " + it->second); + } + } + + IMAGE_LOGD("Create modify error array success."); +} + +static void ModifyImagePropertyComplete(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("context is nullptr"); + return; + } + + if (context->status == OHOS::Media::SUCCESS) { + IMAGE_LOGI("ModifyImageProperty success."); + return; + } + + if (context->isBatch) { + CreateModifyErrorArray(context->errMsgArray); + } else { + if (context->status == OHOS::Media::ERR_MEDIA_WRITE_PARCEL_FAIL) { + if (context->fdIndex != INVALID_FD) { + ImageTaiheUtils::ThrowExceptionError(context->status, "Create Fd without write permission!"); + } else { + ImageTaiheUtils::ThrowExceptionError(context->status, + "The EXIF data failed to be written to the file."); + } + } else if (context->status == OHOS::Media::ERR_MEDIA_OUT_OF_RANGE) { + ImageTaiheUtils::ThrowExceptionError(context->status, + "The given buffer size is too small to add new exif data!"); + } else if (context->status == OHOS::Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT) { + ImageTaiheUtils::ThrowExceptionError(context->status, + "The exif data format is not standard, so modify it failed!"); + } else if (context->status == OHOS::Media::ERR_MEDIA_VALUE_INVALID) { + ImageTaiheUtils::ThrowExceptionError(context->status, context->errMsg); + } else { + ImageTaiheUtils::ThrowExceptionError(context->status, + "There is generic taihe failure!"); + } + } +} + +static uint32_t CheckExifDataValue(const std::string &key, const std::string &value, std::string &errorInfo) +{ + auto status = static_cast(OHOS::Media::ExifMetadatFormatter::Validate(key, value)); + if (status != OHOS::Media::SUCCESS) { + errorInfo = key + " has invalid exif value: "; + errorInfo.append(value); + } + return status; +} + +static void ModifyImagePropertyExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("empty context"); + return; + } + IMAGE_LOGD("ModifyImagePropertyExecute CheckExifDataValue"); + uint32_t status = CheckExifDataValue(context->keyStr, context->valueStr, context->errMsg); + IMAGE_LOGD("ModifyImagePropertyExecute Check ret status: %{public}d", status); + if (status != OHOS::Media::SUCCESS) { + IMAGE_LOGE("There is invalid exif data parameter"); + context->status = status; + return; + } + context->status = context->rImageSource->ModifyImagePropertyEx(context->index, context->keyStr, context->valueStr); +} + +void ImageSourceImpl::ModifyImagePropertySync(PropertyKey key, string_view value) +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::ModifyImagePropertySync"); + + std::unique_ptr context = std::make_unique(); + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "empty native rImageSource"); + return; + } + context->rImageSource = nativeImgSrc; + + context->keyStr = std::string(key.get_value()); + context->valueStr = std::string(value); + + context->pathName = ImageSourceImpl::filePath_; + context->fdIndex = ImageSourceImpl::fileDescriptor_; + context->sourceBuffer = ImageSourceImpl::fileBuffer_; + context->sourceBufferSize = ImageSourceImpl::fileBufferSize_; + + ModifyImagePropertyExecute(context); + ModifyImagePropertyComplete(context); +} + +static void ModifyImagePropertiesExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("empty context"); + return; + } + uint32_t status = OHOS::Media::SUCCESS; + for (auto recordIterator = context->kVStrArray.begin(); recordIterator != context->kVStrArray.end(); + ++recordIterator) { + IMAGE_LOGD("CheckExifDataValue"); + status = CheckExifDataValue(recordIterator->first, recordIterator->second, context->errMsg); + IMAGE_LOGD("Check ret status: %{public}d", status); + if (status != OHOS::Media::SUCCESS) { + IMAGE_LOGE("There is invalid exif data parameter"); + context->errMsgArray.insert(std::make_pair(status, context->errMsg)); + continue; + } + status = context->rImageSource->ModifyImagePropertyEx(0, recordIterator->first, recordIterator->second); + if (status != OHOS::Media::SUCCESS) { + context->errMsgArray.insert(std::make_pair(status, recordIterator->first)); + } + } + context->status = context->errMsgArray.size() > 0 ? OHOS::Media::ERROR : OHOS::Media::SUCCESS; +} + +std::vector> GetRecordArgument(map_view records) +{ + std::vector> kVStrArray; + + for (const auto& [key, value] : records) { + std::string valueStr; + if (value.holds_type_string()) { + valueStr = std::string(value.get_type_string_ref()); + } else if (value.holds_type_null()) { + valueStr = ""; + } + kVStrArray.push_back(std::make_pair(std::string(key.get_value()), valueStr)); + } + + IMAGE_LOGD("Get record argument success."); + return kVStrArray; +} + +void ImageSourceImpl::ModifyImagePropertiesSync(map_view records) +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::ModifyImagePropertiesSync"); + + std::unique_ptr context = std::make_unique(); + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "empty native rImageSource"); + return; + } + context->rImageSource = nativeImgSrc; + + context->kVStrArray = GetRecordArgument(records); + if (context->kVStrArray.size() == 0) return; + context->isBatch = true; + + context->pathName = ImageSourceImpl::filePath_; + context->fdIndex = ImageSourceImpl::fileDescriptor_; + context->sourceBuffer = ImageSourceImpl::fileBuffer_; + context->sourceBufferSize = ImageSourceImpl::fileBufferSize_; + + ModifyImagePropertiesExecute(context); + ModifyImagePropertyComplete(context); +} + +void ImageSourceImpl::ReleaseSync() +{ + if (!isRelease) { + if (nativeImgSrc != nullptr) { + nativeImgSrc = nullptr; + } + isRelease = true; + } +} + +array ImageSourceImpl::GetSupportedFormats() +{ + std::set formats; + nativeImgSrc->GetSupportedFormats(formats); + std::vector vec(formats.begin(), formats.end()); + return ImageTaiheUtils::ToTaiheArrayString(vec); +} + +static std::string FileUrlToRawPath(const std::string &path) +{ + if (path.size() > FILE_URL_PREFIX.size() && + (path.compare(0, FILE_URL_PREFIX.size(), FILE_URL_PREFIX) == 0)) { + return path.substr(FILE_URL_PREFIX.size()); + } + return path; +} + +ImageSource CreateImageSourceByUriOption(string_view uri, SourceOptions const& options) +{ + OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(options); + uint32_t errorCode = OHOS::Media::ERR_MEDIA_INVALID_VALUE; + std::string rawPath = FileUrlToRawPath(std::string(uri)); + + std::shared_ptr imageSource = + OHOS::Media::ImageSource::CreateImageSource(rawPath, opts, errorCode); + if (imageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByUriOption error"); + return make_holder(nullptr); + } + { + std::lock_guard lock(imageSourceCrossThreadMutex_); + ImageSourceImpl::filePath_ = rawPath; + ImageSourceImpl::fileDescriptor_ = INVALID_FD; + ImageSourceImpl::fileBuffer_ = nullptr; + ImageSourceImpl::fileBufferSize_ = NUM_0; + } + return make_holder(imageSource); +} + +ImageSource CreateImageSourceByUri(string_view uri) +{ + SourceOptions opts {}; + return CreateImageSourceByUriOption(uri, opts); +} + +ImageSource CreateImageSourceByFdOption(double fd, SourceOptions const& options) +{ + int32_t fdInt = static_cast(fd); + OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(options); + uint32_t errorCode = OHOS::Media::ERR_MEDIA_INVALID_VALUE; + std::shared_ptr imageSource = + OHOS::Media::ImageSource::CreateImageSource(fdInt, opts, errorCode); + if (imageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByFdOption error"); + return make_holder(nullptr); + } + { + std::lock_guard lock(imageSourceCrossThreadMutex_); + ImageSourceImpl::filePath_ = ""; + ImageSourceImpl::fileDescriptor_ = fdInt; + ImageSourceImpl::fileBuffer_ = nullptr; + ImageSourceImpl::fileBufferSize_ = NUM_0; + } + return make_holder(imageSource); +} + +ImageSource CreateImageSourceByFd(int32_t fd) +{ + SourceOptions opts {}; + return CreateImageSourceByFdOption(fd, opts); +} + +ImageSource CreateImageSourceByArrayBufferOption(array_view buf, SourceOptions const& options) +{ + OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(options); + uint32_t errorCode = OHOS::Media::ERR_MEDIA_INVALID_VALUE; + uint8_t *bufPtr = const_cast(buf.data()); + std::shared_ptr imageSource = + OHOS::Media::ImageSource::CreateImageSource(bufPtr, buf.size(), opts, errorCode); + if (imageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByArrayBufferOption error"); + return make_holder(nullptr); + } + { + std::lock_guard lock(imageSourceCrossThreadMutex_); + ImageSourceImpl::filePath_ = ""; + ImageSourceImpl::fileDescriptor_ = INVALID_FD; + ImageSourceImpl::fileBuffer_ = bufPtr; + ImageSourceImpl::fileBufferSize_ = buf.size(); + } + return make_holder(imageSource); +} + +ImageSource CreateImageSourceByArrayBuffer(array_view buf) +{ + SourceOptions opts {}; + return CreateImageSourceByArrayBufferOption(buf, opts); +} + +ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, optional_view options) +{ + int32_t fd; + int32_t offset; + int32_t length; + ani_env *env = ::taihe::get_env(); + ani_object rawfileObj = reinterpret_cast(rawfile); + if (!ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "fd", fd) || + !ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "offset", offset) || + !ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "length", length)) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "GetPropertyInt failed"); + return make_holder(nullptr); + } + SourceOptions etsOpts = options.value_or(SourceOptions {}); + OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(etsOpts); + + uint32_t errorCode = OHOS::Media::ERR_MEDIA_INVALID_VALUE; + int32_t fileSize = offset + length; + std::shared_ptr imageSource = OHOS::Media::ImageSource::CreateImageSource(fd, + offset, fileSize, opts, errorCode); + if (imageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByRawFileDescriptorOption error"); + return make_holder(nullptr); + } + { + std::lock_guard lock(imageSourceCrossThreadMutex_); + ImageSourceImpl::filePath_ = ""; + ImageSourceImpl::fileDescriptor_ = INVALID_FD; + ImageSourceImpl::fileBuffer_ = nullptr; + ImageSourceImpl::fileBufferSize_ = NUM_0; + } + return make_holder(imageSource); +} +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreateImageSourceByUri(CreateImageSourceByUri); +TH_EXPORT_CPP_API_CreateImageSourceByUriOption(CreateImageSourceByUriOption); +TH_EXPORT_CPP_API_CreateImageSourceByFd(CreateImageSourceByFd); +TH_EXPORT_CPP_API_CreateImageSourceByFdOption(CreateImageSourceByFdOption); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_taihe_utils.cpp b/frameworks/kits/taihe/src/image_taihe_utils.cpp new file mode 100644 index 000000000..dbd3829af --- /dev/null +++ b/frameworks/kits/taihe/src/image_taihe_utils.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "image_taihe_utils.h" + +namespace ANI::Image { +constexpr char CLASS_NAME_BUSINESSERROR[] = "L@ohos/base/BusinessError;"; + +void ImageTaiheUtils::HicheckerReport() +{ +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) && defined(HICHECKER_ENABLE) + uint32_t pid = getpid(); + uint32_t tid = gettid(); + std::string cautionMsg = "Trigger: pid = " + std::to_string(pid) + ", tid = " + std::to_string(tid); + HiviewDFX::HiChecker::NotifySlowProcess(cautionMsg); +#endif +} + +void ImageTaiheUtils::ThrowExceptionError(const std::string errMsg) +{ + IMAGE_LOGE("errMsg: %{pubilc}s", errMsg.c_str()); + taihe::set_error(errMsg); +} + +void ImageTaiheUtils::ThrowExceptionError(const int32_t errCode, const std::string errMsg) +{ + IMAGE_LOGE("errCode: %{pubilc}d, errMsg: %{pubilc}s", errCode, errMsg.c_str()); + taihe::set_business_error(errCode, errMsg); +} + +bool ImageTaiheUtils::GetPropertyInt(ani_env *env, ani_object obj, const std::string &name, int32_t &value) +{ + CHECK_ERROR_RETURN_RET_LOG(env == nullptr || obj == nullptr, false, "%{public}s param is nullptr", __func__); + ani_int result; + env->Object_GetPropertyByName_Int(obj, name.c_str(), &result); + value = static_cast(result); + return true; +} + +ani_object ImageTaiheUtils::ToBusinessError(ani_env *env, int32_t code, const std::string &message) +{ + ani_object err {}; + ani_class cls {}; + CHECK_ERROR_RETURN_RET_LOG(ANI_OK != env->FindClass(CLASS_NAME_BUSINESSERROR, &cls), err, + "find class %{public}s failed", CLASS_NAME_BUSINESSERROR); + ani_method ctor {}; + CHECK_ERROR_RETURN_RET_LOG(ANI_OK != env->Class_FindMethod(cls, "", ":V", &ctor), err, + "find method BusinessError constructor failed"); + ani_object error {}; + CHECK_ERROR_RETURN_RET_LOG(ANI_OK != env->Object_New(cls, ctor, &error), err, + "new object %{public}s failed", CLASS_NAME_BUSINESSERROR); + CHECK_ERROR_RETURN_RET_LOG( + ANI_OK != env->Object_SetPropertyByName_Double(error, "code", static_cast(code)), err, + "set property BusinessError.code failed"); + ani_string messageRef {}; + CHECK_ERROR_RETURN_RET_LOG(ANI_OK != env->String_NewUTF8(message.c_str(), message.size(), &messageRef), err, + "new message string failed"); + CHECK_ERROR_RETURN_RET_LOG( + ANI_OK != env->Object_SetPropertyByName_Ref(error, "message", static_cast(messageRef)), err, + "set property BusinessError.message failed"); + return error; +} + +OHOS::Media::SourceOptions ImageTaiheUtils::ParseSourceOptions(SourceOptions const& options) +{ + OHOS::Media::SourceOptions opts {}; + opts.baseDensity = options.sourceDensity; + OHOS::Media::PixelFormat pixelFormat = OHOS::Media::PixelFormat::UNKNOWN; + if (options.sourcePixelFormat.has_value()) { + pixelFormat = static_cast(options.sourcePixelFormat->get_value()); + } + opts.pixelFormat = pixelFormat; + OHOS::Media::Size size {}; + if (options.sourceSize.has_value()) { + size.width = options.sourceSize.value().width; + size.height = options.sourceSize.value().height; + } + opts.size = size; + return opts; +} + +ImageInfo ImageTaiheUtils::ToTaiheImageInfo(const OHOS::Media::ImageInfo &src, bool isHdr) +{ + Size size { + .width = src.size.width, + .height = src.size.height, + }; + + PixelMapFormat::key_t pixelFormatKey; + GetEnumKeyByValue(static_cast(src.pixelFormat), pixelFormatKey); + AlphaType::key_t alphaTypeKey; + GetEnumKeyByValue(static_cast(src.alphaType), alphaTypeKey); + + ImageInfo result { + .size = size, + .pixelFormat = PixelMapFormat(pixelFormatKey), + .alphaType = AlphaType(alphaTypeKey), + .mimeType = src.encodedFormat, + .isHdr = isHdr, + }; + return result; +} + +array ImageTaiheUtils::ToTaiheArrayString(const std::vector &src) +{ + std::vector<::taihe::string> vec; + for (const auto &item : src) { + vec.emplace_back(item); + } + return array(vec); +} + +array ImageTaiheUtils::CreateTaiheArrayBuffer(uint8_t* src, size_t srcLen) +{ + if (src == nullptr || srcLen == 0) { + return array(0); + } + return array(copy_data_t{}, src, srcLen); +} + +template +bool ImageTaiheUtils::GetEnumKeyByValue(ValueType value, typename EnumType::key_t &key) +{ + for (size_t index = 0; index < std::size(EnumType::table); ++index) { + if (EnumType::table[index] == value) { + key = static_cast(index); + return true; + } + } + return false; +} + +template +bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename ImageFormat::key_t &key); + +template +bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename PixelMapFormat::key_t &key); + +template +bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename AlphaType::key_t &key); + +template +bool ImageTaiheUtils::GetEnumKeyByValue(std::string value, typename PropertyKey::key_t &key); +} // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/picture_taihe.cpp b/frameworks/kits/taihe/src/picture_taihe.cpp new file mode 100644 index 000000000..ceb14d8c4 --- /dev/null +++ b/frameworks/kits/taihe/src/picture_taihe.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2025 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 "image_common.h" +#include "image_log.h" +#include "image_taihe_utils.h" +#include "picture_taihe.h" +#include "pixel_map_taihe.h" +#include "media_errors.h" +#include "message_parcel.h" + +using namespace ANI::Image; + +namespace ANI::Image { + +PictureImpl::PictureImpl() : nativePicture_(nullptr), isRelease(false) {} + +PictureImpl::PictureImpl(std::shared_ptr picture) +{ + nativePicture_ = picture; +} + +PictureImpl::~PictureImpl() +{ + Release(); +} + +int64_t PictureImpl::GetImplPtr() +{ + return reinterpret_cast(this); +} + +std::shared_ptr PictureImpl::GetNativePtr() +{ + return nativePicture_; +} + +PixelMap PictureImpl::GetMainPixelmap() +{ + if (nativePicture_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Native picture is nullptr!"); + return make_holder(nullptr); + } + auto pixelmap = nativePicture_->GetMainPixel(); + if (pixelmap == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Get main pixelmap failed, pixelmap is nullptr!"); + return make_holder(nullptr); + } + return make_holder(pixelmap); +} + +void PictureImpl::Marshalling(uintptr_t sequence) +{ +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + ani_env *env = ::taihe::get_env(); + if (env == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Ani unwarp messageParcel failed."); + return; + } + ani_object sequenceObj = reinterpret_cast(sequence); + ani_long nativePtr; + if (ANI_OK != env->Object_GetFieldByName_Long(sequenceObj, "nativePtr", &nativePtr)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Marshalling picture unwrap failed."); + return; + } + OHOS::MessageParcel* messageParcel = reinterpret_cast(nativePtr); + if (messageParcel == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IPC, "Marshalling picture to parcel failed."); + return; + } + bool st = nativePicture_->Marshalling(*messageParcel); + if (!st) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IPC, "Marshalling picture to parcel failed."); + } +#endif +} + +void PictureImpl::Release() +{ + if (!isRelease) { + if (nativePicture_ != nullptr) { + nativePicture_ = nullptr; + } + isRelease = true; + } +} + +Picture CreatePictureByPixelMap(weak::PixelMap mainPixelmap) +{ + IMAGE_LOGI("CreatePicture IN"); + PixelMapImpl* pixelMapImpl = reinterpret_cast(mainPixelmap->GetImplPtr()); + if (pixelMapImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Pixelmap instance is nullptr!"); + return make_holder(nullptr); + } + auto nativePixelMap = pixelMapImpl->GetNativePtr(); + if (nativePixelMap == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Get native pixelmap failed!"); + return make_holder(nullptr); + } + auto picture = OHOS::Media::Picture::Create(nativePixelMap); + if (picture == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Create picture failed!"); + return make_holder(nullptr); + } + IMAGE_LOGI("CreatePicture OUT"); + return make_holder(std::move(picture)); +} +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreatePictureByPixelMap(CreatePictureByPixelMap); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp new file mode 100644 index 000000000..8d7afc396 --- /dev/null +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "image_taihe_utils.h" +#include "media_errors.h" +#include "pixel_map_taihe.h" +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) +#include +#include "pixel_map_from_surface.h" +#include "sync_fence.h" +#include "transaction/rs_interfaces.h" +#endif + +namespace ANI::Image { + +Size MakeEmptySize() +{ + return {0, 0}; +} + +ImageInfo MakeEmptyImageInfo() +{ + return {MakeEmptySize(), 0, 0, PixelMapFormat(PixelMapFormat::key_t::UNKNOWN), + AlphaType(AlphaType::key_t::UNKNOWN), "", false}; +} + +PixelMap CreatePixelMapByBufferAndOptionsSync(array_view colors, InitializationOptions const& options) +{ + return make_holder(colors, options); +} + +PixelMap CreatePixelMapByBufferSync(InitializationOptions const& options) +{ + return make_holder(options); +} + +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) +static bool GetSurfaceSize(std::string const& surfaceId, Media::Rect& region) +{ + if (region.width <= 0 || region.height <= 0) { + sptr surface = SurfaceUtils::GetInstance()->GetSurface(std::stoull(surfaceId)); + if (surface == nullptr) { + IMAGE_LOGE("[PixelMap ANI] GetSurfaceSize: GetSurface failed"); + return false; + } + sptr fence = SyncFence::InvalidFence(); + // 4 * 4 idetity matrix + float matrix[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + sptr surfaceBuffer = nullptr; + GSError ret = surface->GetLastFlushedBuffer(surfaceBuffer, fence, matrix); + if (ret != GSERROR_OK || surfaceBuffer == nullptr) { + IMAGE_LOGE("[PixelMap ANI] GetSurfaceSize: GetLastFlushedBuffer fail, ret = %{public}d", ret); + return false; + } + region.width = surfaceBuffer->GetWidth(); + region.height = surfaceBuffer->GetHeight(); + } + return true; +} + +static PixelMap CreatePixelMapFromSurface(std::string const& surfaceId, Media::Rect& region) +{ + if (!std::regex_match(surfaceId, std::regex("\\d+"))) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Empty or invalid surfaceId"); + return make_holder(); + } + if (!GetSurfaceSize(surfaceId, region)) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Get surface size failed"); + return make_holder(); + } + + auto &rsClient = Rosen::RSInterfaces::GetInstance(); + OHOS::Rect r = { + .x = region.left, + .y = region.top, + .w = region.width, + .h = region.height, + }; + std::shared_ptr pixelMap = rsClient.CreatePixelMapFromSurfaceId(std::stoull(surfaceId), r); +#ifndef EXT_PIXEL + if (pixelMap == nullptr) { + pixelMap = CreatePixelMapFromSurfaceId(std::stoull(surfaceId), region); + } +#endif + return make_holder(std::move(pixelMap)); +} +#endif + +PixelMap CreatePixelMapFromSurfaceByIdSync(string_view etsSurfaceId) +{ +#if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM) + return make_holder(); +#else + std::string surfaceId(etsSurfaceId); + Media::Rect region; + IMAGE_LOGD("[PixelMap ANI] createPixelMapFromSurfaceByIdSync: id=%{public}s", surfaceId.c_str()); + return CreatePixelMapFromSurface(surfaceId, region); +#endif +} + +PixelMap CreatePixelMapFromSurfaceByIdAndRegionSync(string_view etsSurfaceId, + ohos::multimedia::image::image::Region const& etsRegion) +{ +#if defined(IOS_PLATFORM) || defined(ANDROID_PLATFORM) + return make_holder(); +#else + std::string surfaceId(etsSurfaceId); + Media::Rect region = {etsRegion.x, etsRegion.y, etsRegion.size.width, etsRegion.size.height}; + IMAGE_LOGD("[PixelMap ANI] createPixelMapFromSurfaceByIdAndRegionSync: id=%{public}s, area=%{public}d,%{public}d," + "%{public}d,%{public}d", surfaceId.c_str(), region.left, region.top, region.width, region.height); + if (region.width <= 0 || region.height <= 0) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Invalid region"); + return make_holder(); + } + return CreatePixelMapFromSurface(surfaceId, region); +#endif +} + +PixelMapImpl::PixelMapImpl() {} + +PixelMapImpl::PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions) +{ + Media::InitializationOptions options; + ParseInitializationOptions(etsOptions, options); + if (!Is10BitFormat(options.pixelFormat)) { + nativePixelMap_ = Media::PixelMap::Create(reinterpret_cast(colors.data()), + colors.size() / sizeof(uint32_t), options); + } + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, + "Create PixelMap by buffer and options failed"); + } +} + +PixelMapImpl::PixelMapImpl(InitializationOptions const& etsOptions) +{ + Media::InitializationOptions options; + ParseInitializationOptions(etsOptions, options); + if (Is10BitFormat(options.pixelFormat)) { + options.useDMA = true; + } + nativePixelMap_ = Media::PixelMap::Create(options); + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Create PixelMap by options failed"); + } +} + +PixelMapImpl::PixelMapImpl(std::shared_ptr pixelMap) +{ + nativePixelMap_ = pixelMap; + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Create PixelMap failed"); + } +} + +PixelMapImpl::~PixelMapImpl() +{ + Release(); +} + +int64_t PixelMapImpl::GetImplPtr() +{ + return reinterpret_cast(this); +} + +std::shared_ptr PixelMapImpl::GetNativePtr() +{ + return nativePixelMap_; +} + +std::shared_ptr PixelMapImpl::GetPixelMap(PixelMap etsPixelMap) +{ + PixelMapImpl *pixelMapImpl = reinterpret_cast(etsPixelMap->GetImplPtr()); + if (pixelMapImpl == nullptr) { + IMAGE_LOGE("%{public}s etsPixelMap is nullptr", __func__); + return nullptr; + } + return pixelMapImpl->GetNativePtr(); +} + +ImageInfo PixelMapImpl::GetImageInfoSync() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return MakeEmptyImageInfo(); + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return MakeEmptyImageInfo(); + } + + Media::ImageInfo imageInfo; + nativePixelMap_->GetImageInfo(imageInfo); + ImageInfo result = ImageTaiheUtils::ToTaiheImageInfo(imageInfo, nativePixelMap_->IsHdr()); + result.density = imageInfo.baseDensity; + result.stride = nativePixelMap_->GetRowStride(); + return result; +} + +void PixelMapImpl::ReadPixelsToBufferSync(array_view dst) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + uint32_t status = nativePixelMap_->ReadPixels(dst.size(), dst.data()); + if (status != Media::SUCCESS) { + IMAGE_LOGE("[PixelMap ANI] ReadPixels failed"); + } +} + +void PixelMapImpl::ReadPixelsSync(weak::PositionArea area) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + ohos::multimedia::image::image::Region etsRegion = area->GetRegion(); + Media::Rect region = {etsRegion.x, etsRegion.y, etsRegion.size.width, etsRegion.size.height}; + array etsPixels = area->GetPixels(); + uint32_t status = nativePixelMap_->ReadPixels(etsPixels.size(), area->GetOffset(), area->GetStride(), region, + etsPixels.data()); + if (status == Media::SUCCESS) { + area->SetPixels(etsPixels); + } else { + IMAGE_LOGE("[PixelMap ANI] ReadPixels by region failed"); + } +} + +void PixelMapImpl::WriteBufferToPixelsSync(array_view src) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + uint32_t status = nativePixelMap_->WritePixels(src.data(), src.size()); + if (status != Media::SUCCESS) { + IMAGE_LOGE("[PixelMap ANI] WritePixels failed"); + } +} + +PixelMap PixelMapImpl::CreateAlphaPixelmapSync() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return make_holder(); + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return make_holder(); + } + + Media::InitializationOptions options; + options.pixelFormat = Media::PixelFormat::ALPHA_8; + auto alphaPixelMap = Media::PixelMap::Create(*nativePixelMap_, options); + return make_holder(std::move(alphaPixelMap)); +} + +int32_t PixelMapImpl::GetBytesNumberPerRow() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return 0; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return 0; + } + + return nativePixelMap_->GetRowBytes(); +} + +int32_t PixelMapImpl::GetPixelBytesNumber() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return 0; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return 0; + } + + return nativePixelMap_->GetByteCount(); +} + +void PixelMapImpl::ScaleSync(float x, float y) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + nativePixelMap_->scale(x, y); +} + +void PixelMapImpl::ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel level) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + nativePixelMap_->scale(x, y, Media::AntiAliasingOption(level.get_value())); +} + +void PixelMapImpl::CropSync(ohos::multimedia::image::image::Region const& region) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + Media::Rect rect = {region.x, region.y, region.size.width, region.size.height}; + uint32_t status = nativePixelMap_->crop(rect); + if (status != Media::SUCCESS) { + IMAGE_LOGE("[PixelMap ANI] crop failed"); + } +} + +void PixelMapImpl::RotateSync(float angle) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + nativePixelMap_->rotate(angle); +} + +void PixelMapImpl::FlipSync(bool horizontal, bool vertical) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + nativePixelMap_->flip(horizontal, vertical); +} + +void PixelMapImpl::OpacitySync(float rate) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + uint32_t status = nativePixelMap_->SetAlpha(rate); + if (status != Media::SUCCESS) { + IMAGE_LOGE("[PixelMap ANI] SetAlpha failed"); + } +} + +void PixelMapImpl::SetMemoryNameSync(string_view name) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + uint32_t status = nativePixelMap_->SetMemoryName(std::string(name)); + if (status == Media::ERR_MEMORY_NOT_SUPPORT) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEMORY_NOT_SUPPORT, "Set memory name not supported"); + } else if (status == Media::COMMON_ERR_INVALID_PARAMETER) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Memory name size out of range"); + } +} + +void PixelMapImpl::ReleaseSync() +{ + if (nativePixelMap_ != nullptr) { + if (!nativePixelMap_->IsModifiable()) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Unable to release the PixelMap " + "because it's locked or unmodifiable"); + } else { + IMAGE_LOGD("[PixelMap ANI] Releasing PixelMap with ID: %{public}d", nativePixelMap_->GetUniqueId()); + nativePixelMap_.reset(); + } + } +} + +bool PixelMapImpl::GetIsStrideAlignment() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + return false; + } + + return nativePixelMap_->IsStrideAlignment(); +} + +bool PixelMapImpl::Is10BitFormat(Media::PixelFormat format) +{ + return format == Media::PixelFormat::RGBA_1010102 || format == Media::PixelFormat::YCBCR_P010 || + format == Media::PixelFormat::YCRCB_P010; +} + +void PixelMapImpl::ParseInitializationOptions(InitializationOptions const& etsOptions, + Media::InitializationOptions &options) +{ + options.size = {etsOptions.size.width, etsOptions.size.height}; + if (etsOptions.srcPixelFormat) { + options.srcPixelFormat = Media::PixelFormat(etsOptions.srcPixelFormat->get_value()); + } + if (etsOptions.pixelFormat) { + options.pixelFormat = Media::PixelFormat(etsOptions.pixelFormat->get_value()); + } + if (etsOptions.editable) { + options.editable = *etsOptions.editable; + } + if (etsOptions.alphaType) { + options.alphaType = Media::AlphaType(etsOptions.alphaType->get_value()); + } + if (etsOptions.scaleMode) { + options.scaleMode = Media::ScaleMode(etsOptions.scaleMode->get_value()); + } +} + +void PixelMapImpl::Release() +{ + if (nativePixelMap_ != nullptr) { + nativePixelMap_.reset(); + } +} + +} // namespace ANI::Image + +TH_EXPORT_CPP_API_MakeEmptySize(ANI::Image::MakeEmptySize); +TH_EXPORT_CPP_API_MakeEmptyImageInfo(ANI::Image::MakeEmptyImageInfo); +TH_EXPORT_CPP_API_CreatePixelMapByBufferAndOptionsSync(ANI::Image::CreatePixelMapByBufferAndOptionsSync); +TH_EXPORT_CPP_API_CreatePixelMapByBufferSync(ANI::Image::CreatePixelMapByBufferSync); +TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdSync(ANI::Image::CreatePixelMapFromSurfaceByIdSync); +TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdAndRegionSync(ANI::Image::CreatePixelMapFromSurfaceByIdAndRegionSync); \ No newline at end of file -- Gitee From 679b2ed7dca8c2e4936ee11daf4cfb56a3d120ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Tue, 20 May 2025 14:58:38 +0800 Subject: [PATCH 22/53] =?UTF-8?q?=E8=A1=A5=E9=BD=90=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- bundle.json | 9 +++++++++ .../kits/taihe/idl/ohos.multimedia.image.image.taihe | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/bundle.json b/bundle.json index 31e2fb901..3fbcd03b1 100644 --- a/bundle.json +++ b/bundle.json @@ -202,6 +202,15 @@ }, "name": "//foundation/multimedia/image_framework/frameworks/kits/ani:image_ani" }, + { + "header": { + "header_base": "//foundation/multimedia/image_framework/frameworks/kits/taihe/include/", + "header_files": [ + "pixel_map_taihe.h" + ] + }, + "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:image_taihe" + }, { "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:copy_image_taihe" }, diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 2ab565941..8c0a3aebe 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -389,8 +389,12 @@ union PropertyValue { interface PixelMap { GetImplPtr(): i64; + @gen_async("getImageInfo") + @gen_promise("getImageInfo") GetImageInfoSync(): ImageInfo; + @gen_async("readPixelsToBuffer") + @gen_promise("readPixelsToBuffer") ReadPixelsToBufferSync(dst: @arraybuffer Array): void; ReadPixelsSync(area: PositionArea): void; -- Gitee From 3a288bc87b7d6b11128e42d79f8ad2077451ae14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Tue, 20 May 2025 16:00:45 +0800 Subject: [PATCH 23/53] =?UTF-8?q?=E6=9A=B4=E9=9C=B2=E5=A4=B4=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index 38ecb9e72..504fdfc9e 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -20,6 +20,10 @@ subsystem_name = "multimedia" part_name = "image_framework" taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" +config("taihe_config") { + include_dirs = [ "include" ] +} + copy_taihe_idl("copy_image_taihe") { sources = [ "${image_subsystem}/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe", @@ -78,6 +82,8 @@ taihe_shared_library("image_taihe") { "skia:libjpeg", ] + public_configs = [ ":taihe_config" ] + if (!use_clang_android && !use_clang_ios) { branch_protector_ret = "pac_ret" sanitize = { -- Gitee From e21fbac69a210b3e705efb4ed268e0bb33027d9d Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Tue, 13 May 2025 13:55:24 +0800 Subject: [PATCH 24/53] 1. add ImageReceiverImpl, ImageImpl, ImageCreatorImpl 2. add new api for existing interfaces Signed-off-by: zhaona45 --- bundle.json | 8 +- frameworks/kits/taihe/BUILD.gn | 17 +- .../idl/ohos.multimedia.image.image.taihe | 130 ++++- .../taihe/include/auxiliary_picture_taihe.h | 44 ++ .../kits/taihe/include/image_creator_taihe.h | 45 ++ .../kits/taihe/include/image_receiver_taihe.h | 96 ++++ frameworks/kits/taihe/include/image_taihe.h | 49 ++ .../kits/taihe/include/image_taihe_utils.h | 3 +- .../kits/taihe/include/pixel_map_taihe.h | 9 +- .../taihe/src/auxiliary_picture_taihe.cpp | 261 ++++++++++ .../kits/taihe/src/image_creator_taihe.cpp | 148 ++++++ .../kits/taihe/src/image_receiver_taihe.cpp | 482 ++++++++++++++++++ .../kits/taihe/src/image_source_taihe.cpp | 31 +- frameworks/kits/taihe/src/image_taihe.cpp | 114 +++++ .../kits/taihe/src/image_taihe_utils.cpp | 20 +- frameworks/kits/taihe/src/picture_taihe.cpp | 2 +- frameworks/kits/taihe/src/pixel_map_taihe.cpp | 25 + 17 files changed, 1455 insertions(+), 29 deletions(-) create mode 100644 frameworks/kits/taihe/include/auxiliary_picture_taihe.h create mode 100644 frameworks/kits/taihe/include/image_creator_taihe.h create mode 100644 frameworks/kits/taihe/include/image_receiver_taihe.h create mode 100644 frameworks/kits/taihe/include/image_taihe.h create mode 100644 frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp create mode 100644 frameworks/kits/taihe/src/image_creator_taihe.cpp create mode 100644 frameworks/kits/taihe/src/image_receiver_taihe.cpp create mode 100644 frameworks/kits/taihe/src/image_taihe.cpp diff --git a/bundle.json b/bundle.json index 3fbcd03b1..83ea197c7 100644 --- a/bundle.json +++ b/bundle.json @@ -202,18 +202,20 @@ }, "name": "//foundation/multimedia/image_framework/frameworks/kits/ani:image_ani" }, + { + "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:copy_image_taihe" + }, { "header": { "header_base": "//foundation/multimedia/image_framework/frameworks/kits/taihe/include/", "header_files": [ + "image_taihe.h", + "picture_taihe.h", "pixel_map_taihe.h" ] }, "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:image_taihe" }, - { - "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:copy_image_taihe" - }, { "header": { "header_base": "//foundation/multimedia/image_framework/interfaces/kits/native/include/", diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index 504fdfc9e..f59f66bd3 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -20,7 +20,8 @@ subsystem_name = "multimedia" part_name = "image_framework" taihe_generated_file_path = "$taihe_file_path/out/$subsystem_name/$part_name" -config("taihe_config") { +config("image_taihe_config") { + visibility = [ ":*" ] include_dirs = [ "include" ] } @@ -45,6 +46,8 @@ taihe_shared_library("image_taihe") { subsystem_name = "$subsystem_name" part_name = "$part_name" + public_configs = [ ":image_taihe_config" ] + include_dirs = [ "include", "${image_subsystem}/interfaces/innerkits/include", @@ -55,15 +58,22 @@ taihe_shared_library("image_taihe") { sources = get_target_outputs(":run_taihe") sources += [ "src/ani_constructor.cpp", + "src/auxiliary_picture_taihe.cpp", + "src/image_creator_taihe.cpp", "src/image_packer_taihe.cpp", + "src/image_receiver_taihe.cpp", "src/image_source_taihe.cpp", + "src/image_taihe.cpp", "src/image_taihe_utils.cpp", "src/picture_taihe.cpp", "src/pixel_map_taihe.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] - cflags = [ "-DIMAGE_DEBUG_FLAG" ] + cflags = [ + "-DIMAGE_DEBUG_FLAG", + "-DIMAGE_COLORSPACE_FLAG", + ] deps = [ ":run_taihe", @@ -74,6 +84,7 @@ taihe_shared_library("image_taihe") { external_deps = [ "c_utils:utils", + "eventhandler:libeventhandler", "graphic_2d:color_manager", "graphic_2d:EGL", "graphic_2d:librender_service_client", @@ -82,8 +93,6 @@ taihe_shared_library("image_taihe") { "skia:libjpeg", ] - public_configs = [ ":taihe_config" ] - if (!use_clang_android && !use_clang_ios) { branch_protector_ret = "pac_ret" sanitize = { diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 8c0a3aebe..45365854e 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -441,12 +441,33 @@ interface PixelMap { ReleaseSync(): void; @get GetIsStrideAlignment(): bool; + + @set SetCaptureId(captureId: i32): void; + @get GetCaptureId(): i32; + + @set SetTimestamp(timestamp: i64): void; + @get GetTimestamp(): i64; } interface Picture { GetImplPtr(): i64; GetMainPixelmap(): PixelMap; + + Marshalling(sequence: @sts_type("rpc.MessageSequence") Opaque): void; + + Release(): void; +} + +interface AuxiliaryPicture { + @gen_promise("readPixelsToBuffer") + ReadPixelsToBufferSync(): @arraybuffer Array; + + GetAuxiliaryPictureInfo(): AuxiliaryPictureInfo; + + SetAuxiliaryPictureInfo(info: AuxiliaryPictureInfo): void; + + Release(): void; } interface ImageSource { @@ -507,6 +528,13 @@ interface ImageSource { } """) + @gen_promise("createPixelMapUsingAllocator") + CreatePixelMapUsingAllocatorSync(options: Optional, allocatorType: Optional): PixelMap; + + @gen_async("getDelayTimeList") + @gen_promise("getDelayTimeList") + GetDelayTimeListSync(): Array; + @gen_promise("getImageProperty") GetImagePropertySync(key: PropertyKey, options: Optional): String; @@ -522,6 +550,8 @@ interface ImageSource { @gen_async("release") @gen_promise("release") ReleaseSync(): void; + + @get GetSupportedFormats(): Array; } interface ImagePacker { @@ -529,6 +559,81 @@ interface ImagePacker { @gen_promise("packing") PackingPixelMapSync(source: PixelMap, option: PackingOption): @arraybuffer Array; + @gen_async("packToFile") + @gen_promise("packToFile") + PackImageSourceToFileSync(source: ImageSource, fd: i32, options: PackingOption): void; + + @gen_async("packToFile") + @gen_promise("packToFile") + PackPixelMapToFileSync(source: PixelMap, fd: i32, options: PackingOption): void; + + @gen_promise("packToFile") + PackPictureToFileSync(picture: Picture, fd: i32, options: PackingOption): void; + + @gen_promise("packing") + PackingPictureSync(picture: Picture, options: PackingOption): @arraybuffer Array; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; + + @get GetSupportedFormats(): Array; +} + +interface Image { + @get("size") GetSize(): Size; + @get("format") GetFormat(): i32; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; +} + +interface ImageReceiver { + @get GetSize(): Size; + @get GetCapacity(): i32; + @get GetFormat(): ImageFormat; + + @gen_async("getReceivingSurfaceId") + @gen_promise("getReceivingSurfaceId") + GetReceivingSurfaceIdSync(): String; + + @gen_async("readLatestImage") + @gen_promise("readLatestImage") + ReadLatestImageSync(): Image; + + @!sts_inject_into_interface("on(type: string, callback: (err: BusinessError, data: undefined)=> void): void;") + @!sts_inject_into_class("""on(type: string, callback: (err: BusinessError, data: undefined)=> void): void { + if (type === 'imageArrival') { + this.onImageArrival(callback); + } else { + throw new Error(`Unknown type: ${type}`); + } + } + """) + + @!sts_inject_into_interface("off(type: string, callback?: (err: BusinessError, data: undefined)=> void): void;") + @!sts_inject_into_class("""off(type: string, callback?: (err: BusinessError, data: undefined)=> void): void { + if (type === 'imageArrival') { + this.offImageArrival(callback); + } else { + throw new Error(`Unknown type: ${type}`); + } + } + """) + + OnImageArrival(callback: (err: @sts_type("BusinessError") Opaque, data: @sts_type("undefined") Opaque)=> void): void; + OffImageArrival(callback: Optional<(err: @sts_type("BusinessError") Opaque, data: @sts_type("undefined") Opaque)=> void>): void; + + @gen_async("release") + @gen_promise("release") + ReleaseSync(): void; +} + +interface ImageCreator { + @get("capacity") GetCapacity(): i32; + @get("format") GetFormat(): ImageFormat; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; @@ -561,7 +666,30 @@ function CreateImageSourceByFd(fd: i32): ImageSource; @overload("createImageSource") function CreateImageSourceByFdOption(fd: i32, options: SourceOptions): ImageSource; +@overload("createImageSource") +function CreateImageSourceByArrayBuffer(buf: @arraybuffer Array): ImageSource; + +@overload("createImageSource") +function CreateImageSourceByArrayBufferOption(buf: @arraybuffer Array, options: SourceOptions): ImageSource; + +@overload("createImageSource") +function CreateImageSourceByRawFileDescriptorOption(rawfile: @sts_type("resourceManager.RawFileDescriptor") Opaque, options: Optional): ImageSource; + function CreateImagePacker(): ImagePacker; +@overload("createImageCreator") +function CreateImageCreator(width: i32, height: i32, format: i32, capacity: i32): ImageCreator; + +@overload("createImageCreator") +function CreateImageCreatorBySize(size: Size, format: ImageFormat, capacity: i32): ImageCreator; + +@overload("createImageReceiver") +function CreateImageReceiver(width: i32, height: i32, format: i32, capacity: i32): ImageReceiver; + +@overload("createImageReceiver") +function CreateImageReceiverBySize(size: Size, format: ImageFormat, capacity: i32): ImageReceiver; + @overload("createPicture") -function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; \ No newline at end of file +function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; + +function CreateAuxiliaryPicture(buffer: @arraybuffer Array, size: Size, type: AuxiliaryPictureType): AuxiliaryPicture; \ No newline at end of file diff --git a/frameworks/kits/taihe/include/auxiliary_picture_taihe.h b/frameworks/kits/taihe/include/auxiliary_picture_taihe.h new file mode 100644 index 000000000..51d1a9dbd --- /dev/null +++ b/frameworks/kits/taihe/include/auxiliary_picture_taihe.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_AUXILIARY_PICTURE_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_AUXILIARY_PICTURE_TAIHE_H + +#include "auxiliary_picture.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class AuxiliaryPictureImpl { +public: + AuxiliaryPictureImpl(); + explicit AuxiliaryPictureImpl(std::shared_ptr auxiliaryPicture); + ~AuxiliaryPictureImpl(); + + array ReadPixelsToBufferSync(); + AuxiliaryPictureInfo GetAuxiliaryPictureInfo(); + void SetAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info); + void Release(); + +private: + std::shared_ptr nativeAuxiliaryPicture_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_AUXILIARY_PICTURE_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_creator_taihe.h b/frameworks/kits/taihe/include/image_creator_taihe.h new file mode 100644 index 000000000..45413093d --- /dev/null +++ b/frameworks/kits/taihe/include/image_creator_taihe.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_CREATOR_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_CREATOR_TAIHE_H + +#include "image_creator.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class ImageCreatorImpl { +public: + ImageCreatorImpl(); + explicit ImageCreatorImpl(std::shared_ptr imageCreator); + ~ImageCreatorImpl(); + + int32_t GetCapacity(); + ImageFormat GetFormat(); + + void ReleaseSync(); + +private: + std::shared_ptr imageCreator_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_CREATOR_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_receiver_taihe.h b/frameworks/kits/taihe/include/image_receiver_taihe.h new file mode 100644 index 000000000..c2df2147d --- /dev/null +++ b/frameworks/kits/taihe/include/image_receiver_taihe.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_RECEIVER_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_RECEIVER_TAIHE_H + +#include "event_handler.h" +#include "image_receiver.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +struct ImageReceiverTaiheContext; +using CallbackResult = std::variant; +using CompleteCallback = CallbackResult (*)(std::shared_ptr &); + +class ImageReceiverImpl { +public: + ImageReceiverImpl(); + explicit ImageReceiverImpl(std::shared_ptr imageReceiver); + ~ImageReceiverImpl(); + + static bool AniSendEvent(const std::function cb, std::string &name); + static void OnProcessSendEvent(std::shared_ptr &context); + + Size GetSize(); + int32_t GetCapacity(); + ImageFormat GetFormat(); + + string GetReceivingSurfaceIdSync(); + struct Image ReadLatestImageSync(); + void OnImageArrival(callback_view callback); + void OffImageArrival(optional_view> callback); + void ReleaseSync(); + +#ifdef IMAGE_DEBUG_FLAG + bool isCallBackTest = false; +#endif + +private: + void UnRegisterReceiverListener(); + void NativeRelease(); + + std::shared_ptr imageReceiver_; + bool isRelease = false; + static std::shared_ptr mainHandler_; +}; + +struct ImageReceiverTaiheContext { + ani_env *env = nullptr; + CompleteCallback callBack = nullptr; + CallbackResult result; + std::shared_ptr taiheCallback = nullptr; + std::string name; + ImageReceiverImpl *receiverImpl_ = nullptr; + uint32_t status = OHOS::Media::ERROR; +}; + +struct ImageReceiverCommonArgs { + const std::string name; + CompleteCallback callBack; +}; + +class ImageReceiverAvaliableListener : public OHOS::Media::SurfaceBufferAvaliableListener { +public: + ~ImageReceiverAvaliableListener() override + { + context = nullptr; + } + + void OnSurfaceBufferAvaliable() override + { + ImageReceiverImpl::OnProcessSendEvent(context); + } + + std::shared_ptr context = nullptr; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_RECEIVER_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_taihe.h b/frameworks/kits/taihe/include/image_taihe.h new file mode 100644 index 000000000..36b441316 --- /dev/null +++ b/frameworks/kits/taihe/include/image_taihe.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_H + +#include "image_holder_manager.h" +#include "native_image.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class ImageImpl { +public: + ImageImpl(); + explicit ImageImpl(std::shared_ptr nativeImage); + ~ImageImpl(); + + static struct Image Create(std::shared_ptr nativeImage); + void ReleaseSync(); + + Size GetSize(); + int32_t GetFormat(); + +private: + static OHOS::Media::ImageHolderManager sNativeImageHolder_; + std::shared_ptr nativeImage_; + bool isTestImage_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_taihe_utils.h b/frameworks/kits/taihe/include/image_taihe_utils.h index cdbe6fb42..ceb46cac9 100644 --- a/frameworks/kits/taihe/include/image_taihe_utils.h +++ b/frameworks/kits/taihe/include/image_taihe_utils.h @@ -36,13 +36,14 @@ public: std::string defaultValueStr; }; - static bool GetPropertyInt(ani_env *env, ani_object obj, const std::string &name, int32_t &value); + static bool GetPropertyDouble(ani_env *env, ani_object obj, const std::string &name, double &value); static ani_object ToBusinessError(ani_env *env, int32_t code, const std::string &message); static OHOS::Media::SourceOptions ParseSourceOptions(SourceOptions const& options); static ImageInfo ToTaiheImageInfo(const OHOS::Media::ImageInfo &src, bool isHdr); static array ToTaiheArrayString(const std::vector &src); static array CreateTaiheArrayBuffer(uint8_t* src, size_t srcLen); + static uintptr_t GetUndefinedPtr(ani_env *env); template static bool GetEnumKeyByValue(ValueType value, typename EnumType::key_t &key); diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index 94ff224c8..d172040d4 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -37,6 +37,7 @@ public: int64_t GetImplPtr(); std::shared_ptr GetNativePtr(); static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); + static PixelMap CreatePixelMap(std::shared_ptr pixelMap); ImageInfo GetImageInfoSync(); void ReadPixelsToBufferSync(array_view dst); @@ -47,13 +48,17 @@ public: int32_t GetPixelBytesNumber(); void ScaleSync(float x, float y); void ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel level); - void CropSync(Region const& region); + void CropSync(ohos::multimedia::image::image::Region const& region); void RotateSync(float angle); void FlipSync(bool horizontal, bool vertical); void OpacitySync(float rate); void SetMemoryNameSync(string_view name); void ReleaseSync(); bool GetIsStrideAlignment(); + void SetCaptureId(int32_t captureId); + int32_t GetCaptureId(); + void SetTimestamp(int64_t timestamp); + int64_t GetTimestamp(); private: std::shared_ptr nativePixelMap_ = nullptr; @@ -61,6 +66,8 @@ private: bool Is10BitFormat(Media::PixelFormat format); void ParseInitializationOptions(InitializationOptions const& etsOptions, Media::InitializationOptions &options); void Release(); + int64_t timestamp_ = 0; + int32_t captureId_ = 0; }; } // namespace ANI::Image diff --git a/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp new file mode 100644 index 000000000..044973704 --- /dev/null +++ b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2025 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 + +#include "auxiliary_picture_taihe.h" +#include "image_common.h" +#include "image_log.h" +#include "image_taihe_utils.h" +#include "image_type.h" +#include "image_utils.h" +#include "media_errors.h" +#include "pixel_map.h" +using namespace ANI::Image; + +namespace ANI::Image { + +struct AuxiliaryPictureTaiheContext { + uint32_t status; + AuxiliaryPictureImpl *nConstructor; + void *arrayBuffer; + size_t arrayBufferSize; + std::shared_ptr rAuxiliaryPicture; + OHOS::Media::AuxiliaryPictureInfo auxiliaryPictureInfo; +}; + +AuxiliaryPictureImpl::AuxiliaryPictureImpl() {} + +AuxiliaryPictureImpl::AuxiliaryPictureImpl(std::shared_ptr auxiliaryPicture) +{ + nativeAuxiliaryPicture_ = auxiliaryPicture; +} + +AuxiliaryPictureImpl::~AuxiliaryPictureImpl() +{ + Release(); +} + +static bool ReadPixelsToBufferSyncExecute(std::unique_ptr &context) +{ + OHOS::Media::AuxiliaryPictureInfo info = context->rAuxiliaryPicture->GetAuxiliaryPictureInfo(); + context->arrayBufferSize = + info.size.width * info.size.height * OHOS::Media::ImageUtils::GetPixelBytes(info.pixelFormat); + context->arrayBuffer = new uint8_t[context->arrayBufferSize]; + if (context->arrayBuffer != nullptr) { + context->status = context->rAuxiliaryPicture->ReadPixels( + context->arrayBufferSize, static_cast(context->arrayBuffer)); + } else { + context->status = OHOS::Media::ERR_MEDIA_MALLOC_FAILED; + ImageTaiheUtils::ThrowExceptionError(IMAGE_ALLOC_FAILED, "Memory alloc failed."); + return false; + } + return true; +} + +static array ReadPixelsToBufferSyncComplete(std::unique_ptr &context) +{ + array result = array(nullptr, 0); + if (context->status == OHOS::Media::SUCCESS) { + result = ImageTaiheUtils::CreateTaiheArrayBuffer(static_cast(context->arrayBuffer), + context->arrayBufferSize); + } else { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Fail to create taihe arraybuffer!"); + return array(nullptr, 0); + } + + delete[] static_cast(context->arrayBuffer); + context->arrayBuffer = nullptr; + context->arrayBufferSize = 0; + return result; +} + +array AuxiliaryPictureImpl::ReadPixelsToBufferSync() +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rAuxiliaryPicture = nativeAuxiliaryPicture_; + if (taiheContext->rAuxiliaryPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native auxiliary picture."); + return array(nullptr, 0); + } + if (!ReadPixelsToBufferSyncExecute(taiheContext)) { + return array(nullptr, 0); + } + return ReadPixelsToBufferSyncComplete(taiheContext); +} + +AuxiliaryPictureInfo MakeEmptyAuxiliaryPictureInfo() +{ + return {AuxiliaryPictureType(static_cast(OHOS::Media::AuxiliaryPictureType::NONE)), + {0, 0}, 0, PixelMapFormat(PixelMapFormat::key_t::UNKNOWN), 0}; +} + +static AuxiliaryPictureInfo ToTaiheAuxiliaryPictureInfo(const OHOS::Media::AuxiliaryPictureInfo &src) +{ + AuxiliaryPictureType::key_t auxiliaryPictureTypeKey; + ImageTaiheUtils::GetEnumKeyByValue(static_cast(src.auxiliaryPictureType), + auxiliaryPictureTypeKey); + + Size size { + .width = src.size.width, + .height = src.size.height, + }; + + PixelMapFormat::key_t pixelFormatKey; + ImageTaiheUtils::GetEnumKeyByValue(static_cast(src.pixelFormat), pixelFormatKey); + + AuxiliaryPictureInfo result { + .auxiliaryPictureType = AuxiliaryPictureType(auxiliaryPictureTypeKey), + .size = size, + .rowStride = static_cast(src.rowStride), + .pixelFormat = PixelMapFormat(pixelFormatKey), + }; + return result; +} + +AuxiliaryPictureInfo AuxiliaryPictureImpl::GetAuxiliaryPictureInfo() +{ + if (nativeAuxiliaryPicture_ != nullptr) { + AuxiliaryPictureInfo info = ToTaiheAuxiliaryPictureInfo(nativeAuxiliaryPicture_->GetAuxiliaryPictureInfo()); + return info; + } else { + ImageTaiheUtils::ThrowExceptionError("Native auxiliarypicture is nullptr!"); + return MakeEmptyAuxiliaryPictureInfo(); + } +} + +static OHOS::Media::AuxiliaryPictureType ParseAuxiliaryPictureType(int32_t val) +{ + if (val >= static_cast(OHOS::Media::AuxiliaryPictureType::GAINMAP) + && val <= static_cast(OHOS::Media::AuxiliaryPictureType::FRAGMENT_MAP)) { + return OHOS::Media::AuxiliaryPictureType(val); + } + return OHOS::Media::AuxiliaryPictureType::NONE; +} + +static bool ParseSize(Size const& size) +{ + if (size.width <= 0 || size.height <= 0) { + return false; + } + return true; +} + +static OHOS::Media::PixelFormat ParsePixelFormat(int32_t val) +{ + if (val >= static_cast(OHOS::Media::PixelFormat::ARGB_8888) && + val <= static_cast(OHOS::Media::PixelFormat::CMYK)) { + return OHOS::Media::PixelFormat(val); + } + return OHOS::Media::PixelFormat::UNKNOWN; +} + +static OHOS::Media::ColorSpace ParseColorSpace(uintptr_t val) +{ + return OHOS::Media::ColorSpace::UNKNOWN; +} + +static bool ParseAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info, AuxiliaryPictureTaiheContext* taiheContext) +{ + taiheContext->auxiliaryPictureInfo.auxiliaryPictureType = ParseAuxiliaryPictureType(info.auxiliaryPictureType); + if (!ParseSize(info.size)) { + IMAGE_LOGE("Invalid size in auxiliaryPictureInfo"); + return false; + } + taiheContext->auxiliaryPictureInfo.size.width = info.size.width; + taiheContext->auxiliaryPictureInfo.size.height = info.size.height; + if (info.rowStride < 0) { + IMAGE_LOGE("Invalid rowStride in auxiliaryPictureInfo"); + return false; + } + taiheContext->auxiliaryPictureInfo.rowStride = info.rowStride; + taiheContext->auxiliaryPictureInfo.pixelFormat = ParsePixelFormat(info.pixelFormat); + taiheContext->auxiliaryPictureInfo.colorSpace = ParseColorSpace(info.colorSpace); + return true; +} + +void AuxiliaryPictureImpl::SetAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info) +{ + std::unique_ptr context = std::make_unique(); + if (nativeAuxiliaryPicture_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native auxiliarypicture"); + return; + } + if (!ParseAuxiliaryPictureInfo(info, context.get())) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Parameter error."); + IMAGE_LOGE("AuxiliaryPictureInfo mismatch"); + return; + } + + uint32_t res = nativeAuxiliaryPicture_->SetAuxiliaryPictureInfo(context->auxiliaryPictureInfo); + if (res != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Set auxiliary picture info failed."); + } +} + +void AuxiliaryPictureImpl::Release() +{ + if (!isRelease) { + if (nativeAuxiliaryPicture_ != nullptr) { + nativeAuxiliaryPicture_ = nullptr; + } + isRelease = true; + } +} + +static std::unique_ptr CreateAuxiliaryPictureExec(array_view buffer, + OHOS::Media::Size size, OHOS::Media::AuxiliaryPictureType type) +{ + OHOS::Media::InitializationOptions opts; + opts.size = size; + opts.editable = true; + opts.useDMA = true; + auto colors = reinterpret_cast(buffer.data()); + if (colors == nullptr) { + return nullptr; + } + auto tmpPixelmap = OHOS::Media::PixelMap::Create(colors, buffer.size(), opts); + std::shared_ptr pixelmap = std::move(tmpPixelmap); + auto picture = OHOS::Media::AuxiliaryPicture::Create(pixelmap, type, size); + return picture; +} + +AuxiliaryPicture CreateAuxiliaryPicture(array_view buffer, const Size &size, AuxiliaryPictureType type) +{ + if (buffer.empty()) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid arraybuffer."); + return make_holder(nullptr); + } + OHOS::Media::Size ohSize = {size.width, size.height}; + if (size.width <= 0 || size.height <= 0) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid size."); + return make_holder(nullptr); + } + OHOS::Media::AuxiliaryPictureType ohType = ParseAuxiliaryPictureType(type.get_value()); + if (ohType == OHOS::Media::AuxiliaryPictureType::NONE) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid auxiliary picture type."); + return make_holder(nullptr); + } + auto auxiliaryPicture = CreateAuxiliaryPictureExec(buffer, ohSize, ohType); + if (auxiliaryPicture == nullptr) { + IMAGE_LOGE("Fail to create auxiliary picture."); + return make_holder(nullptr); + } + return make_holder(std::move(auxiliaryPicture)); +} + +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreateAuxiliaryPicture(CreateAuxiliaryPicture); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_creator_taihe.cpp b/frameworks/kits/taihe/src/image_creator_taihe.cpp new file mode 100644 index 000000000..4a385141b --- /dev/null +++ b/frameworks/kits/taihe/src/image_creator_taihe.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2025 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 "image_creator_manager.h" +#include "image_creator_taihe.h" +#include "image_log.h" +#include "image_taihe_utils.h" +#include "media_errors.h" + +using namespace ANI::Image; + +namespace { + constexpr int32_t TEST_WIDTH = 8192; + constexpr int32_t TEST_HEIGHT = 8; + constexpr int32_t TEST_FORMAT = 4; + constexpr int32_t TEST_CAPACITY = 8; +} + +namespace ANI::Image { +static bool g_isCreatorTest = false; +const int ARGS4 = 4; +const int PARAM0 = 0; +const int PARAM1 = 1; +const int PARAM2 = 2; +const int PARAM3 = 3; + +ImageCreatorImpl::ImageCreatorImpl() : imageCreator_(nullptr), isRelease(false) {} + +ImageCreatorImpl::ImageCreatorImpl(std::shared_ptr imageCreator) +{ + if (imageCreator != nullptr && !g_isCreatorTest) { + imageCreator_ = imageCreator; + } +} + +ImageCreatorImpl::~ImageCreatorImpl() +{ + if (!isRelease) { + ReleaseSync(); + isRelease = true; + } +} + +int32_t ImageCreatorImpl::GetCapacity() +{ + if (g_isCreatorTest) { + return TEST_CAPACITY; + } + if (imageCreator_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Native instance is nullptr"); + return 0; + } + if (imageCreator_->iraContext_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Image creator context is nullptr"); + return 0; + } + return imageCreator_->iraContext_->GetCapicity(); +} + +ImageFormat ImageCreatorImpl::GetFormat() +{ + if (g_isCreatorTest) { + return ImageFormat(static_cast(TEST_FORMAT)); + } + if (imageCreator_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Native instance is nullptr"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + if (imageCreator_->iraContext_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Image creator context is nullptr"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + ImageFormat::key_t key; + if (!ImageTaiheUtils::GetEnumKeyByValue(imageCreator_->iraContext_->GetFormat(), key)) { + ImageTaiheUtils::ThrowExceptionError("GetEnumKeyByValue failed"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + return ImageFormat(key); +} + +void ImageCreatorImpl::ReleaseSync() +{ + if (imageCreator_ != nullptr) { + imageCreator_->~ImageCreator(); + imageCreator_ = nullptr; + } +} + +static bool isTest(const int32_t* args, const int32_t len) +{ + if ((args[PARAM0] == TEST_WIDTH) && + (args[PARAM1] == TEST_HEIGHT) && + (args[PARAM2] == TEST_FORMAT) && + (args[PARAM3] == TEST_CAPACITY) && + (len == ARGS4)) { + return true; + } + return false; +} + +ImageCreator CreateImageCreatorInner(int32_t width, int32_t height, int32_t format, int32_t capacity) +{ + int32_t args[ARGS4] = {0}; + args[PARAM0] = width; + args[PARAM1] = height; + args[PARAM2] = format; + args[PARAM3] = capacity; + + int32_t len = sizeof(args) / sizeof(args[PARAM0]); + if (isTest(args, len)) { + g_isCreatorTest = true; + } + if (!g_isCreatorTest) { + auto imageCreator = OHOS::Media::ImageCreator::CreateImageCreator(args[PARAM0], + args[PARAM1], args[PARAM2], args[PARAM3]); + if (imageCreator != nullptr) { + return make_holder(imageCreator); + } + ImageTaiheUtils::ThrowExceptionError("Create image creator failed."); + } + return make_holder(nullptr); +} + +ImageCreator CreateImageCreator(int32_t width, int32_t height, int32_t format, int32_t capacity) +{ + return CreateImageCreatorInner(width, height, format, capacity); +} + +ImageCreator CreateImageCreatorBySize(Size const& size, ImageFormat format, int32_t capacity) +{ + return CreateImageCreatorInner(size.width, size.height, format.get_value(), capacity); +} +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreateImageCreator(CreateImageCreator); +TH_EXPORT_CPP_API_CreateImageCreatorBySize(CreateImageCreatorBySize); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_receiver_taihe.cpp b/frameworks/kits/taihe/src/image_receiver_taihe.cpp new file mode 100644 index 000000000..0f353aa53 --- /dev/null +++ b/frameworks/kits/taihe/src/image_receiver_taihe.cpp @@ -0,0 +1,482 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "image_receiver_taihe.h" +#include "image_taihe.h" +#include "image_taihe_utils.h" + +using namespace ANI::Image; + +namespace ANI::Image { +static constexpr int32_t NUM_0 = 0; +static const char* EMPTY_STRING = ""; + +struct ImageEnum { + std::string name; + int32_t numVal; + std::string strVal; +}; + +static std::vector sImageFormatMap = { + {"CAMERA_APP_INNER", 4, ""}, + {"JPEG", 2000, ""}, +}; + +std::shared_ptr ImageReceiverImpl::mainHandler_ = nullptr; + +ImageReceiverImpl::ImageReceiverImpl() : imageReceiver_(nullptr) {} + +ImageReceiverImpl::ImageReceiverImpl(std::shared_ptr imageReceiver) +{ + imageReceiver_ = imageReceiver; +} + +ImageReceiverImpl::~ImageReceiverImpl() +{ + if (!isRelease) { + NativeRelease(); + isRelease = true; + } +} + +void ImageReceiverImpl::UnRegisterReceiverListener() +{ + if (imageReceiver_ != nullptr) { + imageReceiver_->UnRegisterBufferAvaliableListener(); + } +} + +void ImageReceiverImpl::NativeRelease() +{ + imageReceiver_ = nullptr; +} + +bool ImageReceiverImpl::AniSendEvent(const std::function cb, std::string &name) +{ + if (cb == nullptr) { + return false; + } + + if (!mainHandler_) { + std::shared_ptr runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); + if (!runner) { + return false; + } + mainHandler_ = std::make_shared(runner); + } + + if (!mainHandler_->PostTask(cb, name, 0, OHOS::AppExecFwk::EventQueue::Priority::IMMEDIATE, {})) { + return false; + } + return true; +} + +Size ImageReceiverImpl::GetSize() +{ + if (imageReceiver_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverImpl is nullptr"); + return Size{0, 0}; + } + if (imageReceiver_->iraContext_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverContext is nullptr"); + return Size{0, 0}; + } + return Size{imageReceiver_->iraContext_->GetWidth(), imageReceiver_->iraContext_->GetHeight()}; +} + +int32_t ImageReceiverImpl::GetCapacity() +{ + if (imageReceiver_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverImpl is nullptr"); + return 0; + } + if (imageReceiver_->iraContext_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverContext is nullptr"); + return 0; + } + return imageReceiver_->iraContext_->GetCapicity(); +} + +ImageFormat ImageReceiverImpl::GetFormat() +{ + if (imageReceiver_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverImpl is nullptr"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + if (imageReceiver_->iraContext_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverContext is nullptr"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + ImageFormat::key_t key; + if (!ImageTaiheUtils::GetEnumKeyByValue(imageReceiver_->iraContext_->GetFormat(), key)) { + ImageTaiheUtils::ThrowExceptionError("GetEnumKeyByValue failed"); + return ImageFormat(static_cast(OHOS::Media::ImageFormat::UNKNOWN)); + } + return ImageFormat(key); +} + +static bool CheckFormat(int32_t format) +{ + for (auto imgEnum : sImageFormatMap) { + if (imgEnum.numVal == format) { + return true; + } + } + return false; +} + +static void CommonProcessSendEvent(std::shared_ptr &context) +{ + context->result = context->callBack(context); +} + +static string GetReceivingSurfaceIdSyncProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) +{ + if (receiverImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); + return EMPTY_STRING; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); + return EMPTY_STRING; + } + + context->name = args.name; + context->callBack = args.callBack; + context->receiverImpl_ = receiverImpl; + + CommonProcessSendEvent(context); + if (context->status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent failed"); + return EMPTY_STRING; + } + + if (std::holds_alternative(context->result)) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent result is empty"); + return EMPTY_STRING; + } + + return std::get(context->result); +} + +string ImageReceiverImpl::GetReceivingSurfaceIdSync() +{ + ImageReceiverCommonArgs args = { + .name = "GetReceivingSurfaceIdSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + auto native = context->receiverImpl_->imageReceiver_; + if (native == nullptr || native->iraContext_ == nullptr) { + IMAGE_LOGE("Native instance or imageReceiverContext is nullptr"); + context->status = OHOS::Media::COMMON_ERR_INVALID_PARAMETER; + return std::monostate{}; + } + context->status = OHOS::Media::SUCCESS; + return ::taihe::string(native->iraContext_->GetReceiverKey()); + }; + + return GetReceivingSurfaceIdSyncProcess(args, this); +} + +#ifdef IMAGE_SAVE_BUFFER_TO_PIC +static void DoCallBackTest(OHOS::sptr surfaceBuffer1) +{ + if (surfaceBuffer1 == nullptr) { + IMAGE_LOGE("surfaceBuffer1 is null"); + return; + } + + ImageReceiverManager& imageReceiverManager = ImageReceiverManager::getInstance(); + shared_ptr imageReceiver1 = imageReceiverManager.getImageReceiverByKeyId("1"); + if (imageReceiver1 == nullptr || imageReceiver1->iraContext_ == nullptr) { + return; + } + IMAGE_LOGE("DoCallBackTest format %{public}d", imageReceiver1->iraContext_->GetFormat()); + + InitializationOptions opts; + opts.size.width = surfaceBuffer1->GetWidth(); + opts.size.height = surfaceBuffer1->GetHeight(); + opts.pixelFormat = OHOS::Media::PixelFormat::BGRA_8888; + opts.alphaType = OHOS::Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN; + opts.scaleMode = OHOS::Media::ScaleMode::CENTER_CROP; + opts.editable = true; + IMAGE_LOGE("DoCallBackTest Width %{public}d", opts.size.width); + IMAGE_LOGE("DoCallBackTest Height %{public}d", opts.size.height); + int fd = open("/data/receiver/test.jpg", O_RDWR | O_CREAT); + imageReceiver1->SaveBufferAsImage(fd, surfaceBuffer1, opts); +} +#endif + +static struct Image ReadLatestImageSyncProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) +{ + if (receiverImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); + return make_holder(nullptr); + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); + return make_holder(nullptr); + } + + context->name = args.name; + context->callBack = args.callBack; + context->receiverImpl_ = receiverImpl; + + CommonProcessSendEvent(context); + if (context->status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent failed"); + return make_holder(nullptr); + } + + if (std::holds_alternative(context->result)) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent result is empty"); + return make_holder(nullptr); + } + + return std::get(context->result); +} + +struct Image ImageReceiverImpl::ReadLatestImageSync() +{ + ImageReceiverCommonArgs args = { + .name = "ReadLatestImageSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + auto native = context->receiverImpl_->imageReceiver_; + if (native == nullptr) { + IMAGE_LOGE("Native instance is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + + std::shared_ptr nativeImage = native->LastNativeImage(); + if (nativeImage == nullptr) { + IMAGE_LOGE("LastNativeImage is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } +#ifdef IMAGE_DEBUG_FLAG + if (context->receiverImpl_->isCallBackTest) { + context->receiverImpl_->isCallBackTest = false; +#ifdef IMAGE_SAVE_BUFFER_TO_PIC + DoCallBackTest(nativeImage->GetBuffer()); +#endif + } +#endif + struct Image image = ImageImpl::Create(nativeImage); + context->status = OHOS::Media::SUCCESS; + return image; + }; + + return ReadLatestImageSyncProcess(args, this); +} + +static void DoCallBack(std::shared_ptr &context) +{ + auto localContext = std::make_unique>(context); + if (context == nullptr || context->env == nullptr) { + IMAGE_LOGE("%{public}s, localContext is nullptr", __func__); + localContext.release(); + return; + } + + std::shared_ptr> cacheCallback = + std::reinterpret_pointer_cast>(context->taiheCallback); + ani_object err = ImageTaiheUtils::ToBusinessError(context->env, NUM_0, "Callback is OK"); + (*cacheCallback)(reinterpret_cast(err), ImageTaiheUtils::GetUndefinedPtr(context->env)); + localContext.release(); +} + +void ImageReceiverImpl::OnProcessSendEvent(std::shared_ptr &context) +{ + auto task = [context] () mutable { + DoCallBack(context); + }; + ImageReceiverImpl::AniSendEvent(task, context->name); +} + +static void OnImageArrivalProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl, + callback_view callback) +{ + if (receiverImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); + return; + } + + context->env = taihe::get_env(); + context->name = args.name; + context->callBack = args.callBack; + context->receiverImpl_ = receiverImpl; + std::shared_ptr> taiheCallback = + std::make_shared>(callback); + context->taiheCallback = std::reinterpret_pointer_cast(taiheCallback); + + args.callBack(context); +} + +void ImageReceiverImpl::OnImageArrival(callback_view callback) +{ + ImageReceiverCommonArgs args = { + .name = "OnImageArrival", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + auto native = context->receiverImpl_->imageReceiver_; + if (native == nullptr) { + IMAGE_LOGE("Native instance is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + std::shared_ptr listener = std::make_shared(); + listener->context = context; + + native->RegisterBufferAvaliableListener( + (std::shared_ptr &)listener); + + listener->context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + + OnImageArrivalProcess(args, this, callback); +} + +static void OffImageArrivalProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) +{ + if (receiverImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); + return; + } + + context->name = args.name; + context->callBack = args.callBack; + context->receiverImpl_ = receiverImpl; + + args.callBack(context); +} + +void ImageReceiverImpl::OffImageArrival(optional_view> callback) +{ + ImageReceiverCommonArgs args = { + .name = "OffImageArrival", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + if (context == nullptr || context->receiverImpl_ == nullptr) { + IMAGE_LOGE("context or receiverImpl is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + context->receiverImpl_->imageReceiver_->UnRegisterBufferAvaliableListener(); + context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + + OffImageArrivalProcess(args, this); +} + +static void ReleaseSyncProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) +{ + if (receiverImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); + return; + } + + context->name = args.name; + context->callBack = args.callBack; + context->receiverImpl_ = receiverImpl; + + CommonProcessSendEvent(context); + if (context->status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent failed"); + return; + } +} + +void ImageReceiverImpl::ReleaseSync() +{ + ImageReceiverCommonArgs args = { + .name = "ReleaseSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + if (context == nullptr || context->receiverImpl_ == nullptr) { + IMAGE_LOGE("context or receiverImpl is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + + context->receiverImpl_->UnRegisterReceiverListener(); + context->receiverImpl_->NativeRelease(); + context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + + ReleaseSyncProcess(args, this); +} + +ImageReceiver CreateImageReceiver(int32_t width, int32_t height, int32_t format, int32_t capacity) +{ + if (!CheckFormat(format)) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Invalid format"); + return make_holder(nullptr); + } + + std::shared_ptr imageReceiver = OHOS::Media::ImageReceiver::CreateImageReceiver( + width, height, format, capacity); + if (imageReceiver == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Create native image receiver failed"); + return make_holder(nullptr); + } + return make_holder(imageReceiver); +} + +ImageReceiver CreateImageReceiverBySize(Size const& size, ImageFormat format, int32_t capacity) +{ + return CreateImageReceiver(size.width, size.height, format.get_value(), capacity); +} +} // namespace ANI::Image + +TH_EXPORT_CPP_API_CreateImageReceiver(CreateImageReceiver); +TH_EXPORT_CPP_API_CreateImageReceiverBySize(CreateImageReceiverBySize); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index 07a098c39..695202dea 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -437,7 +437,7 @@ static PixelMap CreatePixelMapComplete(std::unique_ptr { IMAGE_LOGD("CreatePixelMapComplete IN"); if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->rPixelMap != nullptr) { - return make_holder(taiheContext->rPixelMap); + return PixelMapImpl::CreatePixelMap(taiheContext->rPixelMap); } IMAGE_LOGD("CreatePixelMapComplete OUT"); ImageTaiheUtils::ThrowExceptionError(taiheContext->errMsg); @@ -496,7 +496,7 @@ static void CreatePixelMapUsingAllocatorSyncExecute(std::unique_ptr &taiheContext) { if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->rPixelMap != nullptr) { - return make_holder(taiheContext->rPixelMap); + return PixelMapImpl::CreatePixelMap(taiheContext->rPixelMap); } for (const auto &[errorCode, errMsg] : taiheContext->errMsgArray) { ImageTaiheUtils::ThrowExceptionError(errorCode, errMsg); @@ -598,7 +598,7 @@ static array CreatePixelMapListSyncWithOptionsComplete(std::unique_ptr if (taiheContext->status == OHOS::Media::SUCCESS && taiheContext->pixelMaps != nullptr) { IMAGE_LOGD("CreatePixelMapListSyncWithOptionsComplete array"); for (auto &pixelMap : *taiheContext->pixelMaps.get()) { - result.emplace_back(make_holder(std::move(pixelMap))); + result.emplace_back(PixelMapImpl::CreatePixelMap(std::move(pixelMap))); } } return array(result); @@ -1143,24 +1143,24 @@ ImageSource CreateImageSourceByArrayBuffer(array_view buf) ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, optional_view options) { - int32_t fd; - int32_t offset; - int32_t length; + double fd; + double offset; + double length; ani_env *env = ::taihe::get_env(); ani_object rawfileObj = reinterpret_cast(rawfile); - if (!ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "fd", fd) || - !ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "offset", offset) || - !ImageTaiheUtils::GetPropertyInt(env, rawfileObj, "length", length)) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "GetPropertyInt failed"); + if (!ImageTaiheUtils::GetPropertyDouble(env, rawfileObj, "fd", fd) || + !ImageTaiheUtils::GetPropertyDouble(env, rawfileObj, "offset", offset) || + !ImageTaiheUtils::GetPropertyDouble(env, rawfileObj, "length", length)) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "GetPropertyDouble failed"); return make_holder(nullptr); } SourceOptions etsOpts = options.value_or(SourceOptions {}); OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(etsOpts); uint32_t errorCode = OHOS::Media::ERR_MEDIA_INVALID_VALUE; - int32_t fileSize = offset + length; - std::shared_ptr imageSource = OHOS::Media::ImageSource::CreateImageSource(fd, - offset, fileSize, opts, errorCode); + int32_t fileSize = static_cast(offset) + static_cast(length); + std::shared_ptr imageSource = OHOS::Media::ImageSource::CreateImageSource( + static_cast(fd), static_cast(offset), fileSize, opts, errorCode); if (imageSource == nullptr) { ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByRawFileDescriptorOption error"); return make_holder(nullptr); @@ -1179,4 +1179,7 @@ ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, option TH_EXPORT_CPP_API_CreateImageSourceByUri(CreateImageSourceByUri); TH_EXPORT_CPP_API_CreateImageSourceByUriOption(CreateImageSourceByUriOption); TH_EXPORT_CPP_API_CreateImageSourceByFd(CreateImageSourceByFd); -TH_EXPORT_CPP_API_CreateImageSourceByFdOption(CreateImageSourceByFdOption); \ No newline at end of file +TH_EXPORT_CPP_API_CreateImageSourceByFdOption(CreateImageSourceByFdOption); +TH_EXPORT_CPP_API_CreateImageSourceByArrayBuffer(CreateImageSourceByArrayBuffer); +TH_EXPORT_CPP_API_CreateImageSourceByArrayBufferOption(CreateImageSourceByArrayBufferOption); +TH_EXPORT_CPP_API_CreateImageSourceByRawFileDescriptorOption(CreateImageSourceByRawFileDescriptorOption); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_taihe.cpp b/frameworks/kits/taihe/src/image_taihe.cpp new file mode 100644 index 000000000..2bc829fd5 --- /dev/null +++ b/frameworks/kits/taihe/src/image_taihe.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "image_taihe.h" +#include "image_taihe_utils.h" +#include "media_errors.h" + +using namespace ANI::Image; + +namespace { + constexpr int NUM0 = 0; + const std::string MY_NAME = "ImageTaihe"; + constexpr int32_t TEST_WIDTH = 8192; + constexpr int32_t TEST_HEIGHT = 8; + constexpr int32_t TEST_FORMAT = 12; +} + +namespace ANI::Image { +OHOS::Media::ImageHolderManager ImageImpl::sNativeImageHolder_; + +ImageImpl::ImageImpl() : nativeImage_(nullptr), isRelease(false) {} + +ImageImpl::ImageImpl(std::shared_ptr nativeImage) +{ + if (nativeImage == nullptr) { + IMAGE_LOGE("nativeImage is nullptr"); + ImageTaiheUtils::ThrowExceptionError("nativeImage is nullptr"); + return; + } + + auto id = sNativeImageHolder_.save(nativeImage); + nativeImage->SetId(id); + nativeImage_ = sNativeImageHolder_.get(id); + isTestImage_ = false; + if (nativeImage_ == nullptr) { + if (MY_NAME.compare(id.c_str()) == 0) { + isTestImage_ = true; + } else { + IMAGE_LOGE("Failed to get native image"); + ImageTaiheUtils::ThrowExceptionError("Failed to get native image"); + return; + } + } +} + +ImageImpl::~ImageImpl() +{ + ReleaseSync(); +} + +struct Image ImageImpl::Create(std::shared_ptr nativeImage) +{ + return make_holder(nativeImage); +} + +void ImageImpl::ReleaseSync() +{ + if (!isRelease) { + if (nativeImage_ != nullptr) { + nativeImage_ = nullptr; + } + isRelease = true; + } +} + +Size ImageImpl::GetSize() +{ + Size result {NUM0, NUM0}; + if (isTestImage_) { + result.width = TEST_WIDTH; + result.height = TEST_HEIGHT; + return result; + } + if (nativeImage_ == nullptr) { + IMAGE_LOGE("Image surface buffer is nullptr"); + return result; + } + + if (nativeImage_->GetSize(result.width, result.height) != OHOS::Media::SUCCESS) { + IMAGE_LOGE("Image native get size failed"); + } + return result; +} + +int32_t ImageImpl::GetFormat() +{ + int32_t format = NUM0; + if (isTestImage_) { + return TEST_FORMAT; + } + if (nativeImage_ == nullptr) { + IMAGE_LOGE("Image surface buffer is nullptr"); + return format; + } + + if (nativeImage_->GetFormat(format) != OHOS::Media::SUCCESS) { + IMAGE_LOGE("Image native get format failed"); + } + return format; +} +} // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_taihe_utils.cpp b/frameworks/kits/taihe/src/image_taihe_utils.cpp index dbd3829af..5202bc332 100644 --- a/frameworks/kits/taihe/src/image_taihe_utils.cpp +++ b/frameworks/kits/taihe/src/image_taihe_utils.cpp @@ -41,12 +41,12 @@ void ImageTaiheUtils::ThrowExceptionError(const int32_t errCode, const std::stri taihe::set_business_error(errCode, errMsg); } -bool ImageTaiheUtils::GetPropertyInt(ani_env *env, ani_object obj, const std::string &name, int32_t &value) +bool ImageTaiheUtils::GetPropertyDouble(ani_env *env, ani_object obj, const std::string &name, double &value) { CHECK_ERROR_RETURN_RET_LOG(env == nullptr || obj == nullptr, false, "%{public}s param is nullptr", __func__); - ani_int result; - env->Object_GetPropertyByName_Int(obj, name.c_str(), &result); - value = static_cast(result); + ani_double result; + env->Object_GetPropertyByName_Double(obj, name.c_str(), &result); + value = static_cast(result); return true; } @@ -131,6 +131,14 @@ array ImageTaiheUtils::CreateTaiheArrayBuffer(uint8_t* src, size_t srcL return array(copy_data_t{}, src, srcLen); } +uintptr_t ImageTaiheUtils::GetUndefinedPtr(ani_env *env) +{ + ani_ref undefinedRef {}; + env->GetUndefined(&undefinedRef); + ani_object undefinedObj = static_cast(undefinedRef); + return reinterpret_cast(undefinedObj); +} + template bool ImageTaiheUtils::GetEnumKeyByValue(ValueType value, typename EnumType::key_t &key) { @@ -154,4 +162,8 @@ bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typen template bool ImageTaiheUtils::GetEnumKeyByValue(std::string value, typename PropertyKey::key_t &key); + +template +bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, + typename AuxiliaryPictureType::key_t &key); } // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/picture_taihe.cpp b/frameworks/kits/taihe/src/picture_taihe.cpp index ceb14d8c4..bb06e6ab6 100644 --- a/frameworks/kits/taihe/src/picture_taihe.cpp +++ b/frameworks/kits/taihe/src/picture_taihe.cpp @@ -58,7 +58,7 @@ PixelMap PictureImpl::GetMainPixelmap() ImageTaiheUtils::ThrowExceptionError("Get main pixelmap failed, pixelmap is nullptr!"); return make_holder(nullptr); } - return make_holder(pixelmap); + return PixelMapImpl::CreatePixelMap(pixelmap); } void PictureImpl::Marshalling(uintptr_t sequence) diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index 8d7afc396..4213676ed 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -196,6 +196,11 @@ std::shared_ptr PixelMapImpl::GetPixelMap(PixelMap etsPixelMap) return pixelMapImpl->GetNativePtr(); } +PixelMap PixelMapImpl::CreatePixelMap(std::shared_ptr pixelMap) +{ + return make_holder(pixelMap); +} + ImageInfo PixelMapImpl::GetImageInfoSync() { if (nativePixelMap_ == nullptr) { @@ -450,6 +455,26 @@ bool PixelMapImpl::GetIsStrideAlignment() return nativePixelMap_->IsStrideAlignment(); } +void PixelMapImpl::SetCaptureId(int32_t captureId) +{ + captureId_ = captureId; +} + +int32_t PixelMapImpl::GetCaptureId() +{ + return captureId_; +} + +void PixelMapImpl::SetTimestamp(int64_t timestamp) +{ + timestamp_ = timestamp; +} + +int64_t PixelMapImpl::GetTimestamp() +{ + return timestamp_; +} + bool PixelMapImpl::Is10BitFormat(Media::PixelFormat format) { return format == Media::PixelFormat::RGBA_1010102 || format == Media::PixelFormat::YCBCR_P010 || -- Gitee From 0a7011c12f620f39557ce354b497c6d5b1e0efec Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Thu, 22 May 2025 16:23:33 +0800 Subject: [PATCH 25/53] ArkTS 1.2 1. add createPixelMapList 2. Fix codecheck Signed-off-by: zhaona45 Change-Id: I97c5c993e3aedee4a3571c0e4128ed5ab81407b7 --- frameworks/kits/taihe/BUILD.gn | 1 + .../idl/ohos.multimedia.image.image.taihe | 11 +++++- .../taihe/idl/ohos.multimedia.image.taihe | 1 - .../kits/taihe/include/image_source_taihe.h | 3 +- .../kits/taihe/include/pixel_map_taihe.h | 15 ++++---- .../taihe/src/auxiliary_picture_taihe.cpp | 35 ++++++++++++++----- .../kits/taihe/src/image_creator_taihe.cpp | 2 +- .../kits/taihe/src/image_receiver_taihe.cpp | 33 +++++++++++------ .../kits/taihe/src/image_source_taihe.cpp | 22 ++++++++---- .../kits/taihe/src/image_taihe_utils.cpp | 4 +-- frameworks/kits/taihe/src/picture_taihe.cpp | 10 +++--- 11 files changed, 95 insertions(+), 42 deletions(-) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index f59f66bd3..f8b4ba31c 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -85,6 +85,7 @@ taihe_shared_library("image_taihe") { external_deps = [ "c_utils:utils", "eventhandler:libeventhandler", + "graphic_2d:ani_color_space_object_convertor", "graphic_2d:color_manager", "graphic_2d:EGL", "graphic_2d:librender_service_client", diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 45365854e..159142e0b 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -328,7 +328,7 @@ struct DecodingOptions { index: Optional; sampleSize: Optional; rotate: Optional; - editable: Optional; + editable: Optional; desiredSize: Optional; desiredRegion: Optional; desiredPixelFormat: Optional; @@ -531,6 +531,15 @@ interface ImageSource { @gen_promise("createPixelMapUsingAllocator") CreatePixelMapUsingAllocatorSync(options: Optional, allocatorType: Optional): PixelMap; + @gen_async("createPixelMapList") + CreatePixelMapListSync(): Array; + + @gen_async("createPixelMapList") + CreatePixelMapListSyncWithOptions(options: DecodingOptions): Array; + + @gen_promise("createPixelMapList") + CreatePixelMapListSyncWithOptionalOptions(options: Optional): Array; + @gen_async("getDelayTimeList") @gen_promise("getDelayTimeList") GetDelayTimeListSync(): Array; diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe index 8bc7dee08..3b939be40 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.taihe @@ -16,7 +16,6 @@ @!namespace("@ohos.multimedia.image") @!sts_inject(""" -import { AsyncCallback, BusinessError } from '@ohos.base'; import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; import type resourceManager from '@ohos.resourceManager'; import type rpc from '@ohos.rpc'; diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h index f6d5cb816..42ee6c9aa 100644 --- a/frameworks/kits/taihe/include/image_source_taihe.h +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -39,8 +39,9 @@ public: PixelMap CreatePixelMapSync(); PixelMap CreatePixelMapUsingAllocatorSync(optional_view options, optional_view allocatorType); - array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); array CreatePixelMapListSync(); + array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); + array CreatePixelMapListSyncWithOptionalOptions(optional_view options); array GetDelayTimeListSync(); string GetImagePropertySync(PropertyKey key, optional_view options); map GetImagePropertiesSync(array_view key); diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index d172040d4..b2ce30ad7 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -31,13 +31,13 @@ public: PixelMapImpl(); explicit PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions); explicit PixelMapImpl(InitializationOptions const& etsOptions); - explicit PixelMapImpl(std::shared_ptr pixelMap); + explicit PixelMapImpl(std::shared_ptr pixelMap); ~PixelMapImpl(); int64_t GetImplPtr(); - std::shared_ptr GetNativePtr(); - static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); - static PixelMap CreatePixelMap(std::shared_ptr pixelMap); + std::shared_ptr GetNativePtr(); + static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); + static PixelMap CreatePixelMap(std::shared_ptr pixelMap); ImageInfo GetImageInfoSync(); void ReadPixelsToBufferSync(array_view dst); @@ -61,10 +61,11 @@ public: int64_t GetTimestamp(); private: - std::shared_ptr nativePixelMap_ = nullptr; + std::shared_ptr nativePixelMap_ = nullptr; bool aniEditable_ = true; - bool Is10BitFormat(Media::PixelFormat format); - void ParseInitializationOptions(InitializationOptions const& etsOptions, Media::InitializationOptions &options); + bool Is10BitFormat(OHOS::Media::PixelFormat format); + void ParseInitializationOptions(InitializationOptions const& etsOptions, + OHOS::Media::InitializationOptions &options); void Release(); int64_t timestamp_ = 0; int32_t captureId_ = 0; diff --git a/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp index 044973704..fec86b56c 100644 --- a/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp +++ b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp @@ -15,6 +15,7 @@ #include +#include "ani_color_space_object_convertor.h" #include "auxiliary_picture_taihe.h" #include "image_common.h" #include "image_log.h" @@ -30,10 +31,13 @@ namespace ANI::Image { struct AuxiliaryPictureTaiheContext { uint32_t status; AuxiliaryPictureImpl *nConstructor; + std::shared_ptr rPixelmap; + std::shared_ptr auxPicture; void *arrayBuffer; size_t arrayBufferSize; std::shared_ptr rAuxiliaryPicture; OHOS::Media::AuxiliaryPictureInfo auxiliaryPictureInfo; + std::shared_ptr AuxColorSpace = nullptr; }; AuxiliaryPictureImpl::AuxiliaryPictureImpl() {} @@ -162,9 +166,21 @@ static OHOS::Media::PixelFormat ParsePixelFormat(int32_t val) return OHOS::Media::PixelFormat::UNKNOWN; } -static OHOS::Media::ColorSpace ParseColorSpace(uintptr_t val) +static bool ParseColorSpace(uintptr_t val, AuxiliaryPictureTaiheContext* taiheContext) { - return OHOS::Media::ColorSpace::UNKNOWN; +#ifdef IMAGE_COLORSPACE_FLAG + ani_object obj = reinterpret_cast(val); + taiheContext->AuxColorSpace = OHOS::ColorManager::GetColorSpaceByAniObject(get_env(), obj); + if (taiheContext->AuxColorSpace == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ColorSpace mismatch"); + return false; + } + taiheContext->rPixelmap->InnerSetColorSpace(*(taiheContext->AuxColorSpace)); + return true; +#else + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_INVALID_OPERATION, "Unsupported operation"); +#endif + return false; } static bool ParseAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info, AuxiliaryPictureTaiheContext* taiheContext) @@ -182,7 +198,9 @@ static bool ParseAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info, Auxiliar } taiheContext->auxiliaryPictureInfo.rowStride = info.rowStride; taiheContext->auxiliaryPictureInfo.pixelFormat = ParsePixelFormat(info.pixelFormat); - taiheContext->auxiliaryPictureInfo.colorSpace = ParseColorSpace(info.colorSpace); + + taiheContext->rPixelmap = taiheContext->auxPicture->GetContentPixel(); + ParseColorSpace(info.colorSpace, taiheContext); return true; } @@ -193,13 +211,14 @@ void AuxiliaryPictureImpl::SetAuxiliaryPictureInfo(AuxiliaryPictureInfo const& i ImageTaiheUtils::ThrowExceptionError("Empty native auxiliarypicture"); return; } + context->auxPicture = nativeAuxiliaryPicture_; if (!ParseAuxiliaryPictureInfo(info, context.get())) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Parameter error."); IMAGE_LOGE("AuxiliaryPictureInfo mismatch"); return; } - uint32_t res = nativeAuxiliaryPicture_->SetAuxiliaryPictureInfo(context->auxiliaryPictureInfo); + uint32_t res = context->auxPicture->SetAuxiliaryPictureInfo(context->auxiliaryPictureInfo); if (res != OHOS::Media::SUCCESS) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Set auxiliary picture info failed."); } @@ -236,22 +255,22 @@ AuxiliaryPicture CreateAuxiliaryPicture(array_view buffer, const Size & { if (buffer.empty()) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid arraybuffer."); - return make_holder(nullptr); + return make_holder(); } OHOS::Media::Size ohSize = {size.width, size.height}; if (size.width <= 0 || size.height <= 0) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid size."); - return make_holder(nullptr); + return make_holder(); } OHOS::Media::AuxiliaryPictureType ohType = ParseAuxiliaryPictureType(type.get_value()); if (ohType == OHOS::Media::AuxiliaryPictureType::NONE) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid auxiliary picture type."); - return make_holder(nullptr); + return make_holder(); } auto auxiliaryPicture = CreateAuxiliaryPictureExec(buffer, ohSize, ohType); if (auxiliaryPicture == nullptr) { IMAGE_LOGE("Fail to create auxiliary picture."); - return make_holder(nullptr); + return make_holder(); } return make_holder(std::move(auxiliaryPicture)); } diff --git a/frameworks/kits/taihe/src/image_creator_taihe.cpp b/frameworks/kits/taihe/src/image_creator_taihe.cpp index 4a385141b..1a2e4cf6e 100644 --- a/frameworks/kits/taihe/src/image_creator_taihe.cpp +++ b/frameworks/kits/taihe/src/image_creator_taihe.cpp @@ -130,7 +130,7 @@ ImageCreator CreateImageCreatorInner(int32_t width, int32_t height, int32_t form } ImageTaiheUtils::ThrowExceptionError("Create image creator failed."); } - return make_holder(nullptr); + return make_holder(); } ImageCreator CreateImageCreator(int32_t width, int32_t height, int32_t format, int32_t capacity) diff --git a/frameworks/kits/taihe/src/image_receiver_taihe.cpp b/frameworks/kits/taihe/src/image_receiver_taihe.cpp index 0f353aa53..f109e443a 100644 --- a/frameworks/kits/taihe/src/image_receiver_taihe.cpp +++ b/frameworks/kits/taihe/src/image_receiver_taihe.cpp @@ -228,13 +228,13 @@ static struct Image ReadLatestImageSyncProcess(ImageReceiverCommonArgs &args, Im { if (receiverImpl == nullptr) { ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); - return make_holder(nullptr); + return make_holder(); } std::shared_ptr context = std::make_shared(); if (context == nullptr) { ImageTaiheUtils::ThrowExceptionError("ImageReceiverTaiheContext is nullptr"); - return make_holder(nullptr); + return make_holder(); } context->name = args.name; @@ -244,12 +244,12 @@ static struct Image ReadLatestImageSyncProcess(ImageReceiverCommonArgs &args, Im CommonProcessSendEvent(context); if (context->status != OHOS::Media::SUCCESS) { ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent failed"); - return make_holder(nullptr); + return make_holder(); } if (std::holds_alternative(context->result)) { ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent result is empty"); - return make_holder(nullptr); + return make_holder(); } return std::get(context->result); @@ -285,6 +285,11 @@ struct Image ImageReceiverImpl::ReadLatestImageSync() } #endif struct Image image = ImageImpl::Create(nativeImage); + if (::taihe::has_error()) { + IMAGE_LOGE("ImageImpl::Create failed!"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } context->status = OHOS::Media::SUCCESS; return image; }; @@ -396,8 +401,12 @@ void ImageReceiverImpl::OffImageArrival(optional_view &context) -> CallbackResult { - if (context == nullptr || context->receiverImpl_ == nullptr) { - IMAGE_LOGE("context or receiverImpl is nullptr"); + if (context == nullptr) { + IMAGE_LOGE("context is nullptr"); + return std::monostate{}; + } + if (context->receiverImpl_ == nullptr) { + IMAGE_LOGE("receiverImpl is nullptr"); context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; return std::monostate{}; } @@ -441,8 +450,12 @@ void ImageReceiverImpl::ReleaseSync() }; args.callBack = [](std::shared_ptr &context) -> CallbackResult { - if (context == nullptr || context->receiverImpl_ == nullptr) { - IMAGE_LOGE("context or receiverImpl is nullptr"); + if (context == nullptr) { + IMAGE_LOGE("context is nullptr"); + return std::monostate{}; + } + if (context->receiverImpl_ == nullptr) { + IMAGE_LOGE("receiverImpl is nullptr"); context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; return std::monostate{}; } @@ -460,14 +473,14 @@ ImageReceiver CreateImageReceiver(int32_t width, int32_t height, int32_t format, { if (!CheckFormat(format)) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Invalid format"); - return make_holder(nullptr); + return make_holder(); } std::shared_ptr imageReceiver = OHOS::Media::ImageReceiver::CreateImageReceiver( width, height, format, capacity); if (imageReceiver == nullptr) { ImageTaiheUtils::ThrowExceptionError("Create native image receiver failed"); - return make_holder(nullptr); + return make_holder(); } return make_holder(imageReceiver); } diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index 695202dea..130d59584 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ani_color_space_object_convertor.h" #include "image_common.h" #include "image_dfx.h" #include "image_log.h" @@ -257,8 +258,12 @@ static bool ParsePixelFormat(optional val, OHOS::Media::PixelFor static void ParseDesiredColorSpace(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst) { if (options.desiredColorSpace.has_value()) { + ani_object desiredColorSpaceObj = reinterpret_cast(options.desiredColorSpace.value()); + dst.desiredColorSpaceInfo = OHOS::ColorManager::GetColorSpaceByAniObject(get_env(), desiredColorSpaceObj); IMAGE_LOGD("desiredColorSpace parse finished"); - return; + } + if (dst.desiredColorSpaceInfo == nullptr) { + IMAGE_LOGD("no desiredColorSpace"); } } @@ -637,6 +642,11 @@ array ImageSourceImpl::CreatePixelMapListSync() return CreatePixelMapListSyncWithOptions({}); } +array ImageSourceImpl::CreatePixelMapListSyncWithOptionalOptions(optional_view options) +{ + return CreatePixelMapListSyncWithOptions(options.value_or(DecodingOptions {})); +} + array ImageSourceImpl::GetDelayTimeListSync() { OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDelayTimeListSync"); @@ -1069,7 +1079,7 @@ ImageSource CreateImageSourceByUriOption(string_view uri, SourceOptions const& o OHOS::Media::ImageSource::CreateImageSource(rawPath, opts, errorCode); if (imageSource == nullptr) { ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByUriOption error"); - return make_holder(nullptr); + return make_holder(); } { std::lock_guard lock(imageSourceCrossThreadMutex_); @@ -1096,7 +1106,7 @@ ImageSource CreateImageSourceByFdOption(double fd, SourceOptions const& options) OHOS::Media::ImageSource::CreateImageSource(fdInt, opts, errorCode); if (imageSource == nullptr) { ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByFdOption error"); - return make_holder(nullptr); + return make_holder(); } { std::lock_guard lock(imageSourceCrossThreadMutex_); @@ -1123,7 +1133,7 @@ ImageSource CreateImageSourceByArrayBufferOption(array_view buf, Source OHOS::Media::ImageSource::CreateImageSource(bufPtr, buf.size(), opts, errorCode); if (imageSource == nullptr) { ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByArrayBufferOption error"); - return make_holder(nullptr); + return make_holder(); } { std::lock_guard lock(imageSourceCrossThreadMutex_); @@ -1152,7 +1162,7 @@ ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, option !ImageTaiheUtils::GetPropertyDouble(env, rawfileObj, "offset", offset) || !ImageTaiheUtils::GetPropertyDouble(env, rawfileObj, "length", length)) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "GetPropertyDouble failed"); - return make_holder(nullptr); + return make_holder(); } SourceOptions etsOpts = options.value_or(SourceOptions {}); OHOS::Media::SourceOptions opts = ImageTaiheUtils::ParseSourceOptions(etsOpts); @@ -1163,7 +1173,7 @@ ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, option static_cast(fd), static_cast(offset), fileSize, opts, errorCode); if (imageSource == nullptr) { ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByRawFileDescriptorOption error"); - return make_holder(nullptr); + return make_holder(); } { std::lock_guard lock(imageSourceCrossThreadMutex_); diff --git a/frameworks/kits/taihe/src/image_taihe_utils.cpp b/frameworks/kits/taihe/src/image_taihe_utils.cpp index 5202bc332..b0f1c14be 100644 --- a/frameworks/kits/taihe/src/image_taihe_utils.cpp +++ b/frameworks/kits/taihe/src/image_taihe_utils.cpp @@ -31,13 +31,13 @@ void ImageTaiheUtils::HicheckerReport() void ImageTaiheUtils::ThrowExceptionError(const std::string errMsg) { - IMAGE_LOGE("errMsg: %{pubilc}s", errMsg.c_str()); + IMAGE_LOGE("errMsg: %{public}s", errMsg.c_str()); taihe::set_error(errMsg); } void ImageTaiheUtils::ThrowExceptionError(const int32_t errCode, const std::string errMsg) { - IMAGE_LOGE("errCode: %{pubilc}d, errMsg: %{pubilc}s", errCode, errMsg.c_str()); + IMAGE_LOGE("errCode: %{public}d, errMsg: %{public}s", errCode, errMsg.c_str()); taihe::set_business_error(errCode, errMsg); } diff --git a/frameworks/kits/taihe/src/picture_taihe.cpp b/frameworks/kits/taihe/src/picture_taihe.cpp index bb06e6ab6..f9136c3d5 100644 --- a/frameworks/kits/taihe/src/picture_taihe.cpp +++ b/frameworks/kits/taihe/src/picture_taihe.cpp @@ -51,12 +51,12 @@ PixelMap PictureImpl::GetMainPixelmap() { if (nativePicture_ == nullptr) { ImageTaiheUtils::ThrowExceptionError("Native picture is nullptr!"); - return make_holder(nullptr); + return make_holder(); } auto pixelmap = nativePicture_->GetMainPixel(); if (pixelmap == nullptr) { ImageTaiheUtils::ThrowExceptionError("Get main pixelmap failed, pixelmap is nullptr!"); - return make_holder(nullptr); + return make_holder(); } return PixelMapImpl::CreatePixelMap(pixelmap); } @@ -103,17 +103,17 @@ Picture CreatePictureByPixelMap(weak::PixelMap mainPixelmap) PixelMapImpl* pixelMapImpl = reinterpret_cast(mainPixelmap->GetImplPtr()); if (pixelMapImpl == nullptr) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Pixelmap instance is nullptr!"); - return make_holder(nullptr); + return make_holder(); } auto nativePixelMap = pixelMapImpl->GetNativePtr(); if (nativePixelMap == nullptr) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Get native pixelmap failed!"); - return make_holder(nullptr); + return make_holder(); } auto picture = OHOS::Media::Picture::Create(nativePixelMap); if (picture == nullptr) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Create picture failed!"); - return make_holder(nullptr); + return make_holder(); } IMAGE_LOGI("CreatePicture OUT"); return make_holder(std::move(picture)); -- Gitee From 4d5a9c75e729e358af5521e83b3378fc5125a300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 29 May 2025 12:03:31 +0800 Subject: [PATCH 26/53] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=90=91=E4=B8=8B?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=20ANI=20=E6=96=B9=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- bundle.json | 1 + frameworks/kits/taihe/BUILD.gn | 3 +- .../idl/ohos.multimedia.image.image.taihe | 5 +- .../kits/taihe/include/pixel_map_taihe.h | 1 + .../kits/taihe/include/pixel_map_taihe_ani.h | 37 ++++++++++ frameworks/kits/taihe/src/pixel_map_taihe.cpp | 20 +++++- .../kits/taihe/src/pixel_map_taihe_ani.cpp | 69 +++++++++++++++++++ 7 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 frameworks/kits/taihe/include/pixel_map_taihe_ani.h create mode 100644 frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp diff --git a/bundle.json b/bundle.json index 83ea197c7..e6bc4682c 100644 --- a/bundle.json +++ b/bundle.json @@ -211,6 +211,7 @@ "header_files": [ "image_taihe.h", "picture_taihe.h", + "pixel_map_taihe_ani.h", "pixel_map_taihe.h" ] }, diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index f8b4ba31c..fd8b9d6af 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -66,6 +66,7 @@ taihe_shared_library("image_taihe") { "src/image_taihe.cpp", "src/image_taihe_utils.cpp", "src/picture_taihe.cpp", + "src/pixel_map_taihe_ani.cpp", "src/pixel_map_taihe.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] @@ -125,8 +126,8 @@ ohos_prebuilt_etc("image_framework_etc") { group("image_framework_taihe") { deps = [ - ":image_taihe", ":image_framework_etc", + ":image_taihe", ] } diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 159142e0b..b2944a68c 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -655,7 +655,10 @@ function MakeEmptyImageInfo(): ImageInfo; function CreatePixelMapByBufferAndOptionsSync(colors: @arraybuffer Array, options: InitializationOptions): PixelMap; @overload("createPixelMapSync") -function CreatePixelMapByBufferSync(options: InitializationOptions): PixelMap; +function CreatePixelMapByOptionsSync(options: InitializationOptions): PixelMap; + +// For legacy ANI backward compatibility +function CreatePixelMapByPtr(ptr: i64): PixelMap; @overload("createPixelMapFromSurfaceSync") function CreatePixelMapFromSurfaceByIdSync(surfaceId: String): PixelMap; diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index b2ce30ad7..5dfa5a544 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -32,6 +32,7 @@ public: explicit PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions); explicit PixelMapImpl(InitializationOptions const& etsOptions); explicit PixelMapImpl(std::shared_ptr pixelMap); + explicit PixelMapImpl(int64_t aniPtr); ~PixelMapImpl(); int64_t GetImplPtr(); diff --git a/frameworks/kits/taihe/include/pixel_map_taihe_ani.h b/frameworks/kits/taihe/include/pixel_map_taihe_ani.h new file mode 100644 index 000000000..2e7d5a3a0 --- /dev/null +++ b/frameworks/kits/taihe/include/pixel_map_taihe_ani.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_PIXEL_MAP_TAIHE_ANI_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_PIXEL_MAP_TAIHE_ANI_H + +#include +#include "pixel_map.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { + +class PixelMapTaiheAni { +public: + static ani_object CreateEtsPixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap); + static std::shared_ptr GetNativePixelMap([[maybe_unused]] ani_env* env, ani_object obj); + std::shared_ptr nativePixelMap_; +}; + +} // namespace Media +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index 4213676ed..58b784556 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -16,6 +16,7 @@ #include "image_log.h" #include "image_taihe_utils.h" #include "media_errors.h" +#include "pixel_map_taihe_ani.h" #include "pixel_map_taihe.h" #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) #include @@ -42,11 +43,16 @@ PixelMap CreatePixelMapByBufferAndOptionsSync(array_view colors, Initia return make_holder(colors, options); } -PixelMap CreatePixelMapByBufferSync(InitializationOptions const& options) +PixelMap CreatePixelMapByOptionsSync(InitializationOptions const& options) { return make_holder(options); } +PixelMap CreatePixelMapByPtr(int64_t ptr) +{ + return make_holder(ptr); +} + #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) static bool GetSurfaceSize(std::string const& surfaceId, Media::Rect& region) { @@ -171,6 +177,15 @@ PixelMapImpl::PixelMapImpl(std::shared_ptr pixelMap) } } +PixelMapImpl::PixelMapImpl(int64_t aniPtr) +{ + Media::PixelMapTaiheAni* pixelMapAni = reinterpret_cast(aniPtr); + nativePixelMap_ = pixelMapAni->nativePixelMap_; + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::COMMON_ERR_INVALID_PARAMETER, "Create PixelMap failed"); + } +} + PixelMapImpl::~PixelMapImpl() { Release(); @@ -514,6 +529,7 @@ void PixelMapImpl::Release() TH_EXPORT_CPP_API_MakeEmptySize(ANI::Image::MakeEmptySize); TH_EXPORT_CPP_API_MakeEmptyImageInfo(ANI::Image::MakeEmptyImageInfo); TH_EXPORT_CPP_API_CreatePixelMapByBufferAndOptionsSync(ANI::Image::CreatePixelMapByBufferAndOptionsSync); -TH_EXPORT_CPP_API_CreatePixelMapByBufferSync(ANI::Image::CreatePixelMapByBufferSync); +TH_EXPORT_CPP_API_CreatePixelMapByOptionsSync(ANI::Image::CreatePixelMapByOptionsSync); +TH_EXPORT_CPP_API_CreatePixelMapByPtr(ANI::Image::CreatePixelMapByPtr); TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdSync(ANI::Image::CreatePixelMapFromSurfaceByIdSync); TH_EXPORT_CPP_API_CreatePixelMapFromSurfaceByIdAndRegionSync(ANI::Image::CreatePixelMapFromSurfaceByIdAndRegionSync); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp new file mode 100644 index 000000000..3d61d6af2 --- /dev/null +++ b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2025 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 "pixel_map_taihe_ani.h" +#include "pixel_map_taihe.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { +using namespace ANI::Image; + +ani_object PixelMapTaiheAni::CreateEtsPixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap) +{ + std::unique_ptr pixelMapAni = std::make_unique(); + pixelMapAni->nativePixelMap_ = pixelMap; + + ani_namespace imageNamespace; + if (env->FindNamespace("L@ohos/multimedia/image/image;", &imageNamespace) != ANI_OK) { + return nullptr; + } + ani_function createFunc; + if (env->Namespace_FindFunction(imageNamespace, "createPixelMapByPtr", nullptr, &createFunc) != ANI_OK) { + return nullptr; + } + ani_ref pixelMapObj; + if (env->Function_Call_Ref(createFunc, &pixelMapObj, reinterpret_cast(pixelMapAni.release())) != ANI_OK) { + return nullptr; + } + + return reinterpret_cast(pixelMapObj); +} + +std::shared_ptr PixelMapTaiheAni::GetNativePixelMap([[maybe_unused]] ani_env* env, ani_object obj) +{ + ani_class pixelMapCls; + if (env->FindClass("L@ohos/multimedia/image/image/PixelMap;", &pixelMapCls) != ANI_OK) { + return nullptr; + } + ani_method getMethod; + if (env->Class_FindMethod(pixelMapCls, "getImplPtr", ":J", &getMethod) != ANI_OK) { + return nullptr; + } + ani_long implPtr; + if ( env->Object_CallMethod_Long(obj, getMethod, &implPtr) != ANI_OK) { + return nullptr; + } + + PixelMapImpl* pixelMapImpl = reinterpret_cast(implPtr); + if (pixelMapImpl == nullptr) { + return nullptr; + } + return pixelMapImpl->GetNativePtr(); +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file -- Gitee From c52dc75497285225299ec04fb43e268f8c42c1e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 29 May 2025 16:04:44 +0800 Subject: [PATCH 27/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp index 3d61d6af2..83361cc12 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp @@ -54,7 +54,7 @@ std::shared_ptr PixelMapTaiheAni::GetNativePixelMap([[maybe_unused]] a return nullptr; } ani_long implPtr; - if ( env->Object_CallMethod_Long(obj, getMethod, &implPtr) != ANI_OK) { + if (env->Object_CallMethod_Long(obj, getMethod, &implPtr) != ANI_OK) { return nullptr; } -- Gitee From f3135d2dc5df4ffed870950bd5c200dfd0380462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 4 Jun 2025 11:30:23 +0800 Subject: [PATCH 28/53] =?UTF-8?q?=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F?= =?UTF-8?q?=E9=A3=8E=E9=99=A9=E6=95=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp index 83361cc12..46be55269 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp @@ -36,7 +36,9 @@ ani_object PixelMapTaiheAni::CreateEtsPixelMap([[maybe_unused]] ani_env* env, st return nullptr; } ani_ref pixelMapObj; - if (env->Function_Call_Ref(createFunc, &pixelMapObj, reinterpret_cast(pixelMapAni.release())) != ANI_OK) { + if (env->Function_Call_Ref(createFunc, &pixelMapObj, reinterpret_cast(pixelMapAni.get())) == ANI_OK) { + pixelMapAni.release(); + } else { return nullptr; } -- Gitee From 9b8eafdd10618d1c184ee8217478a2efafc8ac7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 12 Jun 2025 18:36:03 +0800 Subject: [PATCH 29/53] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../idl/ohos.multimedia.image.image.taihe | 7 + .../kits/taihe/include/pixel_map_taihe.h | 18 +-- frameworks/kits/taihe/src/pixel_map_taihe.cpp | 124 +++++++++++++++--- 3 files changed, 124 insertions(+), 25 deletions(-) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index b2944a68c..dd5068316 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -409,6 +409,8 @@ interface PixelMap { GetPixelBytesNumber(): i32; + GetDensity(): i32; + @gen_async("scale") @gen_promise("scale") @overload("scaleSync") @@ -436,10 +438,15 @@ interface PixelMap { SetMemoryNameSync(name: String): void; + @gen_promise("convertPixelFormat") + ConvertPixelFormatSync(targetPixelFormat: PixelMapFormat): void; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; + @get GetIsEditable(): bool; + @get GetIsStrideAlignment(): bool; @set SetCaptureId(captureId: i32): void; diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index 5dfa5a544..585cd73eb 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -31,14 +31,14 @@ public: PixelMapImpl(); explicit PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions); explicit PixelMapImpl(InitializationOptions const& etsOptions); - explicit PixelMapImpl(std::shared_ptr pixelMap); + explicit PixelMapImpl(std::shared_ptr pixelMap); explicit PixelMapImpl(int64_t aniPtr); ~PixelMapImpl(); int64_t GetImplPtr(); - std::shared_ptr GetNativePtr(); - static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); - static PixelMap CreatePixelMap(std::shared_ptr pixelMap); + std::shared_ptr GetNativePtr(); + static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); + static PixelMap CreatePixelMap(std::shared_ptr pixelMap); ImageInfo GetImageInfoSync(); void ReadPixelsToBufferSync(array_view dst); @@ -47,6 +47,7 @@ public: PixelMap CreateAlphaPixelmapSync(); int32_t GetBytesNumberPerRow(); int32_t GetPixelBytesNumber(); + int32_t GetDensity(); void ScaleSync(float x, float y); void ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel level); void CropSync(ohos::multimedia::image::image::Region const& region); @@ -54,7 +55,9 @@ public: void FlipSync(bool horizontal, bool vertical); void OpacitySync(float rate); void SetMemoryNameSync(string_view name); + void ConvertPixelFormatSync(PixelMapFormat targetPixelFormat); void ReleaseSync(); + bool GetIsEditable(); bool GetIsStrideAlignment(); void SetCaptureId(int32_t captureId); int32_t GetCaptureId(); @@ -62,11 +65,10 @@ public: int64_t GetTimestamp(); private: - std::shared_ptr nativePixelMap_ = nullptr; + std::shared_ptr nativePixelMap_ = nullptr; bool aniEditable_ = true; - bool Is10BitFormat(OHOS::Media::PixelFormat format); - void ParseInitializationOptions(InitializationOptions const& etsOptions, - OHOS::Media::InitializationOptions &options); + bool Is10BitFormat(Media::PixelFormat format); + void ParseInitializationOptions(InitializationOptions const& etsOptions, Media::InitializationOptions &options); void Release(); int64_t timestamp_ = 0; int32_t captureId_ = 0; diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index 58b784556..08c6b2aa3 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -13,11 +13,14 @@ * limitations under the License. */ +#include "pixel_map_taihe.h" + +#include "image_format_convert.h" #include "image_log.h" #include "image_taihe_utils.h" +#include "image_utils.h" #include "media_errors.h" #include "pixel_map_taihe_ani.h" -#include "pixel_map_taihe.h" #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) #include #include "pixel_map_from_surface.h" @@ -27,6 +30,13 @@ namespace ANI::Image { +enum class FormatType : int8_t { + UNKNOWN, + YUV, + RGB, + ASTC +}; + Size MakeEmptySize() { return {0, 0}; @@ -205,7 +215,7 @@ std::shared_ptr PixelMapImpl::GetPixelMap(PixelMap etsPixelMap) { PixelMapImpl *pixelMapImpl = reinterpret_cast(etsPixelMap->GetImplPtr()); if (pixelMapImpl == nullptr) { - IMAGE_LOGE("%{public}s etsPixelMap is nullptr", __func__); + IMAGE_LOGE("[%{public}s] etsPixelMap is nullptr", __func__); return nullptr; } return pixelMapImpl->GetNativePtr(); @@ -219,7 +229,7 @@ PixelMap PixelMapImpl::CreatePixelMap(std::shared_ptr pixelMap) ImageInfo PixelMapImpl::GetImageInfoSync() { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return MakeEmptyImageInfo(); } if (!aniEditable_) { @@ -238,7 +248,7 @@ ImageInfo PixelMapImpl::GetImageInfoSync() void PixelMapImpl::ReadPixelsToBufferSync(array_view dst) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -255,7 +265,7 @@ void PixelMapImpl::ReadPixelsToBufferSync(array_view dst) void PixelMapImpl::ReadPixelsSync(weak::PositionArea area) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -278,7 +288,7 @@ void PixelMapImpl::ReadPixelsSync(weak::PositionArea area) void PixelMapImpl::WriteBufferToPixelsSync(array_view src) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -295,7 +305,7 @@ void PixelMapImpl::WriteBufferToPixelsSync(array_view src) PixelMap PixelMapImpl::CreateAlphaPixelmapSync() { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return make_holder(); } if (!aniEditable_) { @@ -312,7 +322,7 @@ PixelMap PixelMapImpl::CreateAlphaPixelmapSync() int32_t PixelMapImpl::GetBytesNumberPerRow() { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return 0; } if (!aniEditable_) { @@ -326,7 +336,7 @@ int32_t PixelMapImpl::GetBytesNumberPerRow() int32_t PixelMapImpl::GetPixelBytesNumber() { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return 0; } if (!aniEditable_) { @@ -337,10 +347,24 @@ int32_t PixelMapImpl::GetPixelBytesNumber() return nativePixelMap_->GetByteCount(); } +int32_t PixelMapImpl::GetDensity() +{ + if (nativePixelMap_ == nullptr) { + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); + return 0; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return 0; + } + + return nativePixelMap_->GetBaseDensity(); +} + void PixelMapImpl::ScaleSync(float x, float y) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -354,7 +378,7 @@ void PixelMapImpl::ScaleSync(float x, float y) void PixelMapImpl::ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel level) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -368,7 +392,7 @@ void PixelMapImpl::ScaleWithAntiAliasingSync(float x, float y, AntiAliasingLevel void PixelMapImpl::CropSync(ohos::multimedia::image::image::Region const& region) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -386,7 +410,7 @@ void PixelMapImpl::CropSync(ohos::multimedia::image::image::Region const& region void PixelMapImpl::RotateSync(float angle) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -400,7 +424,7 @@ void PixelMapImpl::RotateSync(float angle) void PixelMapImpl::FlipSync(bool horizontal, bool vertical) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -414,7 +438,7 @@ void PixelMapImpl::FlipSync(bool horizontal, bool vertical) void PixelMapImpl::OpacitySync(float rate) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -431,7 +455,7 @@ void PixelMapImpl::OpacitySync(float rate) void PixelMapImpl::SetMemoryNameSync(string_view name) { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return; } if (!aniEditable_) { @@ -447,6 +471,62 @@ void PixelMapImpl::SetMemoryNameSync(string_view name) } } +static FormatType FormatTypeOf(Media::PixelFormat pixelForamt) +{ + switch (pixelForamt) { + case Media::PixelFormat::ARGB_8888: + case Media::PixelFormat::RGB_565: + case Media::PixelFormat::RGBA_8888: + case Media::PixelFormat::BGRA_8888: + case Media::PixelFormat::RGB_888: + case Media::PixelFormat::RGBA_F16: + case Media::PixelFormat::RGBA_1010102: + return FormatType::RGB; + case Media::PixelFormat::NV21: + case Media::PixelFormat::NV12: + case Media::PixelFormat::YCBCR_P010: + case Media::PixelFormat::YCRCB_P010: + return FormatType::YUV; + case Media::PixelFormat::ASTC_4x4: + return FormatType::ASTC; + default: + return FormatType::UNKNOWN; + } +} + +void PixelMapImpl::ConvertPixelFormatSync(PixelMapFormat targetPixelFormat) +{ + if (nativePixelMap_ == nullptr) { + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); + return; + } + + Media::PixelFormat srcFormat = nativePixelMap_->GetPixelFormat(); + Media::PixelFormat dstFormat = Media::PixelFormat(targetPixelFormat.get_value()); + if (FormatTypeOf(srcFormat) == FormatType::UNKNOWN || FormatTypeOf(dstFormat) == FormatType::UNKNOWN) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INVALID_PARAMETER, + "Source or target pixel format is not supported or invalid"); + return; + } + + uint32_t status = Media::ImageFormatConvert::ConvertImageFormat(nativePixelMap_, dstFormat); + if (status == Media::SUCCESS) { + Media::ImageUtils::FlushSurfaceBuffer(nativePixelMap_.get()); + } else if (status == Media::ERR_IMAGE_INVALID_PARAMETER) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INVALID_PARAMETER, "Invalid parameter"); + } else if (status == Media::ERR_IMAGE_SOURCE_DATA_INCOMPLETE) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_SOURCE_DATA_INCOMPLETE, + "Image source data is incomplete"); + } else if (status == Media::IMAGE_RESULT_CREATE_FORMAT_CONVERT_FAILED) { + ImageTaiheUtils::ThrowExceptionError(Media::IMAGE_RESULT_CREATE_FORMAT_CONVERT_FAILED, "Conversion failed"); + } else if (status == Media::ERR_MEDIA_FORMAT_UNSUPPORT) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_FORMAT_UNSUPPORT, + "The target pixel format to be converted is not supported"); + } else if (status == Media::ERR_IMAGE_PIXELMAP_CREATE_FAILED) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_PIXELMAP_CREATE_FAILED, "Failed to create PixelMap"); + } +} + void PixelMapImpl::ReleaseSync() { if (nativePixelMap_ != nullptr) { @@ -460,10 +540,20 @@ void PixelMapImpl::ReleaseSync() } } +bool PixelMapImpl::GetIsEditable() +{ + if (nativePixelMap_ == nullptr) { + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); + return false; + } + + return nativePixelMap_->IsEditable(); +} + bool PixelMapImpl::GetIsStrideAlignment() { if (nativePixelMap_ == nullptr) { - ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Native PixelMap is nullptr"); + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); return false; } -- Gitee From cdb6bfbcd087debc455bdba86b1e583ea6efd751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Mon, 16 Jun 2025 12:05:57 +0800 Subject: [PATCH 30/53] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- .../idl/ohos.multimedia.image.image.taihe | 4 ++ .../kits/taihe/include/pixel_map_taihe.h | 2 + frameworks/kits/taihe/src/pixel_map_taihe.cpp | 49 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index dd5068316..5929811c1 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -441,6 +441,10 @@ interface PixelMap { @gen_promise("convertPixelFormat") ConvertPixelFormatSync(targetPixelFormat: PixelMapFormat): void; + GetColorSpace(): @sts_type("colorSpaceManager.ColorSpaceManager") Opaque; + + SetColorSpace(colorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque): void; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index 585cd73eb..60a3dabc5 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -56,6 +56,8 @@ public: void OpacitySync(float rate); void SetMemoryNameSync(string_view name); void ConvertPixelFormatSync(PixelMapFormat targetPixelFormat); + uintptr_t GetColorSpace(); + void SetColorSpace(uintptr_t colorSpace); 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 08c6b2aa3..547bd96de 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -15,12 +15,14 @@ #include "pixel_map_taihe.h" +#include "ani_color_space_object_convertor.h" #include "image_format_convert.h" #include "image_log.h" #include "image_taihe_utils.h" #include "image_utils.h" #include "media_errors.h" #include "pixel_map_taihe_ani.h" +#include "taihe/runtime.hpp" #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) #include #include "pixel_map_from_surface.h" @@ -527,6 +529,53 @@ void PixelMapImpl::ConvertPixelFormatSync(PixelMapFormat targetPixelFormat) } } +uintptr_t PixelMapImpl::GetColorSpace() +{ +#ifdef IMAGE_COLORSPACE_FLAG + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_DATA_ABNORMAL, "Invalid native PixelMap"); + return 0; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return 0; + } + + auto grColorSpace = nativePixelMap_->InnerGetGrColorSpacePtr(); + if (grColorSpace == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_DATA_UNSUPPORT, "No color space in PixelMap"); + return 0; + } + return reinterpret_cast(ColorManager::CreateAniColorSpaceObject(get_env(), grColorSpace)); +#else + ImageTaiheUtils::ThrowExceptionError(Media::ERR_INVALID_OPERATION, "Unsupported operation"); + return 0; +#endif +} + +void PixelMapImpl::SetColorSpace(uintptr_t colorSpace) +{ +#ifdef IMAGE_COLORSPACE_FLAG + if (nativePixelMap_ == nullptr) { + IMAGE_LOGE("[%{public}s] Native PixelMap is nullptr", __func__); + return; + } + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "PixelMap has crossed threads"); + return; + } + + auto grColorSpace = ColorManager::GetColorSpaceByAniObject(get_env(), reinterpret_cast(colorSpace)); + if (grColorSpace == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INVALID_PARAMETER, "Color space mismatch"); + return; + } + nativePixelMap_->InnerSetColorSpace(*grColorSpace); +#else + ImageTaiheUtils::ThrowExceptionError(Media::ERR_INVALID_OPERATION, "Unsupported operation"); +#endif +} + void PixelMapImpl::ReleaseSync() { if (nativePixelMap_ != nullptr) { -- Gitee From 65177ba6ee35efeb2679ae8b96aa9ca22e9df22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Mon, 16 Jun 2025 15:37:25 +0800 Subject: [PATCH 31/53] =?UTF-8?q?=E5=91=BD=E5=90=8D=E7=A9=BA=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/include/pixel_map_taihe.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index 60a3dabc5..59be8cbc0 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -31,14 +31,14 @@ public: PixelMapImpl(); explicit PixelMapImpl(array_view const& colors, InitializationOptions const& etsOptions); explicit PixelMapImpl(InitializationOptions const& etsOptions); - explicit PixelMapImpl(std::shared_ptr pixelMap); + explicit PixelMapImpl(std::shared_ptr pixelMap); explicit PixelMapImpl(int64_t aniPtr); ~PixelMapImpl(); int64_t GetImplPtr(); - std::shared_ptr GetNativePtr(); - static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); - static PixelMap CreatePixelMap(std::shared_ptr pixelMap); + std::shared_ptr GetNativePtr(); + static std::shared_ptr GetPixelMap(PixelMap etsPixelMap); + static PixelMap CreatePixelMap(std::shared_ptr pixelMap); ImageInfo GetImageInfoSync(); void ReadPixelsToBufferSync(array_view dst); @@ -67,10 +67,11 @@ public: int64_t GetTimestamp(); private: - std::shared_ptr nativePixelMap_ = nullptr; + std::shared_ptr nativePixelMap_ = nullptr; bool aniEditable_ = true; - bool Is10BitFormat(Media::PixelFormat format); - void ParseInitializationOptions(InitializationOptions const& etsOptions, Media::InitializationOptions &options); + bool Is10BitFormat(OHOS::Media::PixelFormat format); + void ParseInitializationOptions(InitializationOptions const& etsOptions, + OHOS::Media::InitializationOptions &options); void Release(); int64_t timestamp_ = 0; int32_t captureId_ = 0; -- Gitee From e9a2abe6e6fe66f3ff9d8eafc926fd2ac1c04e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Tue, 17 Jun 2025 09:53:56 +0800 Subject: [PATCH 32/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 5929811c1..96fe5dacd 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -662,6 +662,8 @@ interface ImageCreator { function MakeEmptySize(): Size; function MakeEmptyImageInfo(): ImageInfo; +@gen_async("createPixelMap") +@gen_promise("createPixelMap") @overload("createPixelMapSync") function CreatePixelMapByBufferAndOptionsSync(colors: @arraybuffer Array, options: InitializationOptions): PixelMap; -- Gitee From 3853a559c1734a11326693fc20f9f1eded69a374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 18 Jun 2025 15:31:39 +0800 Subject: [PATCH 33/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=BC=82=E6=AD=A5?= =?UTF-8?q?=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 96fe5dacd..57f149a93 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -397,6 +397,8 @@ interface PixelMap { @gen_promise("readPixelsToBuffer") ReadPixelsToBufferSync(dst: @arraybuffer Array): void; + @gen_async("readPixels") + @gen_promise("readPixels") ReadPixelsSync(area: PositionArea): void; WriteBufferToPixelsSync(src: @arraybuffer Array): void; -- Gitee From 56c1e5c7362a81fb223437a2e6b8b381f2331281 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Fri, 13 Jun 2025 10:13:27 +0800 Subject: [PATCH 34/53] Add ArkTS1.2 support for the remaining interfaces Signed-off-by: zhaona45 Change-Id: Idd74061ccf7a3ff80be3ad01c3c5cbb2d126278a --- bundle.json | 6 +- frameworks/kits/taihe/BUILD.gn | 5 +- .../idl/ohos.multimedia.image.image.taihe | 233 +++++++++- .../taihe/include/auxiliary_picture_taihe.h | 11 +- .../kits/taihe/include/image_creator_taihe.h | 46 ++ .../kits/taihe/include/image_packer_taihe.h | 12 +- .../kits/taihe/include/image_receiver_taihe.h | 2 +- .../kits/taihe/include/image_source_taihe.h | 9 + .../taihe/include/image_source_taihe_ani.h | 36 ++ frameworks/kits/taihe/include/image_taihe.h | 12 +- .../kits/taihe/include/image_taihe_utils.h | 7 +- .../kits/taihe/include/metadata_taihe.h | 50 +++ frameworks/kits/taihe/include/picture_taihe.h | 8 + .../kits/taihe/include/picture_taihe_ani.h | 36 ++ .../kits/taihe/include/pixel_map_taihe.h | 2 + .../taihe/src/auxiliary_picture_taihe.cpp | 140 +++++- .../kits/taihe/src/image_creator_taihe.cpp | 311 +++++++++++-- .../kits/taihe/src/image_packer_taihe.cpp | 421 +++++++++++++----- .../kits/taihe/src/image_receiver_taihe.cpp | 73 ++- .../kits/taihe/src/image_source_taihe.cpp | 271 ++++++++++- .../kits/taihe/src/image_source_taihe_ani.cpp | 52 +++ frameworks/kits/taihe/src/image_taihe.cpp | 172 ++++++- .../kits/taihe/src/image_taihe_utils.cpp | 22 +- frameworks/kits/taihe/src/metadata_taihe.cpp | 292 ++++++++++++ frameworks/kits/taihe/src/picture_taihe.cpp | 238 +++++++++- .../kits/taihe/src/picture_taihe_ani.cpp | 50 +++ frameworks/kits/taihe/src/pixel_map_taihe.cpp | 71 +++ 27 files changed, 2356 insertions(+), 232 deletions(-) create mode 100644 frameworks/kits/taihe/include/image_source_taihe_ani.h create mode 100644 frameworks/kits/taihe/include/metadata_taihe.h create mode 100644 frameworks/kits/taihe/include/picture_taihe_ani.h create mode 100644 frameworks/kits/taihe/src/image_source_taihe_ani.cpp create mode 100644 frameworks/kits/taihe/src/metadata_taihe.cpp create mode 100644 frameworks/kits/taihe/src/picture_taihe_ani.cpp diff --git a/bundle.json b/bundle.json index e6bc4682c..1dabcdd18 100644 --- a/bundle.json +++ b/bundle.json @@ -209,10 +209,12 @@ "header": { "header_base": "//foundation/multimedia/image_framework/frameworks/kits/taihe/include/", "header_files": [ + "image_source_taihe_ani.h", "image_taihe.h", "picture_taihe.h", - "pixel_map_taihe_ani.h", - "pixel_map_taihe.h" + "picture_taihe_ani.h", + "pixel_map_taihe.h", + "pixel_map_taihe_ani.h" ] }, "name": "//foundation/multimedia/image_framework/frameworks/kits/taihe:image_taihe" diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index fd8b9d6af..6e41f4282 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -63,11 +63,14 @@ taihe_shared_library("image_taihe") { "src/image_packer_taihe.cpp", "src/image_receiver_taihe.cpp", "src/image_source_taihe.cpp", + "src/image_source_taihe_ani.cpp", "src/image_taihe.cpp", "src/image_taihe_utils.cpp", + "src/metadata_taihe.cpp", "src/picture_taihe.cpp", - "src/pixel_map_taihe_ani.cpp", + "src/picture_taihe_ani.cpp", "src/pixel_map_taihe.cpp", + "src/pixel_map_taihe_ani.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index b2944a68c..6a5d34cf6 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -319,6 +319,13 @@ struct PackingOption { needsPackProperties: Optional; } +struct PackingOptionsForSequence { + frameCount: i32; + delayTimeList: Array; + disposalTypes: Optional>; + loopCount: Optional; +} + struct ImagePropertyOptions { index: Optional; defaultValue: Optional; @@ -365,6 +372,49 @@ struct SourceOptions { sourceSize: Optional; } +struct HdrStaticMetadata { + displayPrimariesX: Array; + displayPrimariesY: Array; + whitePointX: f32; + whitePointY: f32; + maxLuminance: f32; + minLuminance: f32; + maxContentLightLevel: f32; + maxFrameAverageLightLevel: f32; +} + +struct GainmapChannel { + gainmapMax: f32; + gainmapMin: f32; + gamma: f32; + baseOffset: f32; + alternateOffset: f32; +} + +struct HdrGainmapMetadata { + writerVersion: i32; + miniVersion: i32; + gainmapChannelCount: i32; + useBaseColorFlag: bool; + baseHeadroom: f32; + alternateHeadroom: f32; + channels: Array; +} + +enum HdrMetadataKey: i32 { + HDR_METADATA_TYPE = 0, + HDR_STATIC_METADATA = 1, + HDR_DYNAMIC_METADATA = 2, + HDR_GAINMAP_METADATA = 3, +} + +enum HdrMetadataType: i32 { + NONE = 0, + BASE = 1, + GAINMAP = 2, + ALTERNATE = 3, +} + enum AuxiliaryPictureType: i32 { GAINMAP = 1, DEPTH_MAP = 2, @@ -373,6 +423,22 @@ enum AuxiliaryPictureType: i32 { FRAGMENT_MAP = 5, } +enum MetadataType: i32 { + EXIF_METADATA = 1, + FRAGMENT_METADATA = 2, +} + +enum FragmentMapPropertyKey: String { + X_IN_ORIGINAL = "XInOriginal", + Y_IN_ORIGINAL = "YInOriginal", + WIDTH = "FragmentImageWidth", + HEIGHT = "FragmentImageHeight" +} + +struct DecodingOptionsForPicture { + desiredAuxiliaryPictures: Array; +} + struct AuxiliaryPictureInfo { auxiliaryPictureType: AuxiliaryPictureType; size: Size; @@ -381,6 +447,13 @@ struct AuxiliaryPictureInfo { colorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque; } +union HdrMetadataValue { + metadataType: HdrMetadataType; + staticMetadataArrayBuffer: HdrStaticMetadata; + arrayBuffer: @arraybuffer Array; + gainmapMetadata: HdrGainmapMetadata; +} + union PropertyValue { type_string: String; @null type_null; @@ -399,6 +472,8 @@ interface PixelMap { ReadPixelsSync(area: PositionArea): void; + @gen_async("writeBufferToPixels") + @gen_promise("writeBufferToPixels") WriteBufferToPixelsSync(src: @arraybuffer Array): void; @gen_async("createAlphaPixelmap") @@ -434,6 +509,13 @@ interface PixelMap { @gen_promise("opacity") OpacitySync(rate: f32): void; + @gen_promise("toSdr") + ToSdrSync(): void; + + @gen_async("applyColorSpace") + @gen_promise("applyColorSpace") + ApplyColorSpaceSync(targetColorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque): void; + SetMemoryNameSync(name: String): void; @gen_async("release") @@ -449,20 +531,58 @@ interface PixelMap { @get GetTimestamp(): i64; } +union GainMap { + type_gainMap: PixelMap; + @null type_null; +} + +union AuxPicture { + type_auxPicture: AuxiliaryPicture; + @null type_null; +} + interface Picture { GetImplPtr(): i64; GetMainPixelmap(): PixelMap; + @gen_promise("getHdrComposedPixelmap") + GetHdrComposedPixelmapSync(): PixelMap; + + GetGainmapPixelmap(): GainMap; + + SetAuxiliaryPicture(type: AuxiliaryPictureType, auxiliaryPicture: AuxiliaryPicture): void; + + GetAuxiliaryPicture(type: AuxiliaryPictureType): AuxPicture; + + @gen_promise("setMetadata") + SetMetadataSync(metadataType: MetadataType, metadata: Metadata): void; + + @gen_promise("getMetadata") + GetMetadataSync(metadataType: MetadataType): Metadata; + Marshalling(sequence: @sts_type("rpc.MessageSequence") Opaque): void; Release(): void; } interface AuxiliaryPicture { + GetImplPtr(): i64; + + @gen_promise("writePixelsFromBuffer") + WritePixelsFromBufferSync(data: @arraybuffer Array): void; + @gen_promise("readPixelsToBuffer") ReadPixelsToBufferSync(): @arraybuffer Array; + GetType(): AuxiliaryPictureType; + + @gen_promise("setMetadata") + SetMetadataSync(metadataType: MetadataType, metadata: Metadata): void; + + @gen_promise("getMetadata") + GetMetadataSync(metadataType: MetadataType): Metadata; + GetAuxiliaryPictureInfo(): AuxiliaryPictureInfo; SetAuxiliaryPictureInfo(info: AuxiliaryPictureInfo): void; @@ -470,6 +590,22 @@ interface AuxiliaryPicture { Release(): void; } +interface Metadata { + GetImplPtr(): i64; + + @gen_promise("getProperties") + GetPropertiesSync(key: Array): @record Map; + + @gen_promise("setProperties") + SetPropertiesSync(records: @record Map): void; + + @gen_promise("getAllProperties") + GetAllPropertiesSync(): @record Map; + + @gen_promise("clone") + CloneSync(): Metadata; +} + interface ImageSource { GetImplPtr(): i64; @gen_async("getImageInfo") @@ -544,6 +680,13 @@ interface ImageSource { @gen_promise("getDelayTimeList") GetDelayTimeListSync(): Array; + @gen_promise("getDisposalTypeList") + GetDisposalTypeListSync(): Array; + + @gen_async("getFrameCount") + @gen_promise("getFrameCount") + GetFrameCountSync(): i32; + @gen_promise("getImageProperty") GetImagePropertySync(key: PropertyKey, options: Optional): String; @@ -556,17 +699,29 @@ interface ImageSource { @gen_promise("modifyImageProperties") ModifyImagePropertiesSync(records: @record Map): void; + @gen_async("updateData") + @gen_promise("updateData") + UpdateDataSync(buf: @arraybuffer Array, isFinished: bool, offset: i32, length: i32): void; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; + @gen_promise("createPicture") + CreatePictureSync(options: Optional): Picture; + @get GetSupportedFormats(): Array; } interface ImagePacker { - @gen_async("packing") - @gen_promise("packing") - PackingPixelMapSync(source: PixelMap, option: PackingOption): @arraybuffer Array; + @gen_promise("packToData") + PackImageSourceToDataSync(source: ImageSource, options: PackingOption): @arraybuffer Array; + + @gen_promise("packToData") + PackPixelMapToDataSync(source: PixelMap, options: PackingOption): @arraybuffer Array; + + @gen_promise("packToDataFromPixelmapSequence") + PackToDataFromPixelmapSequenceSync(pixelmapSequence: Array, options: PackingOptionsForSequence): @arraybuffer Array; @gen_async("packToFile") @gen_promise("packToFile") @@ -576,6 +731,9 @@ interface ImagePacker { @gen_promise("packToFile") PackPixelMapToFileSync(source: PixelMap, fd: i32, options: PackingOption): void; + @gen_promise("packToFileFromPixelmapSequence") + PackToFileFromPixelmapSequenceSync(pixelmapSequence: Array, fd: i32, options: PackingOptionsForSequence): void; + @gen_promise("packToFile") PackPictureToFileSync(picture: Picture, fd: i32, options: PackingOption): void; @@ -590,8 +748,16 @@ interface ImagePacker { } interface Image { + @get("clipRect") GetClipRect(): Region; + GetImplPtr(): i64; + @get("size") GetSize(): Size; @get("format") GetFormat(): i32; + @get("timestamp") GetTimestamp(): i64; + + @gen_async("getComponent") + @gen_promise("getComponent") + GetComponentSync(componentType: ComponentType): Component; @gen_async("release") @gen_promise("release") @@ -611,6 +777,10 @@ interface ImageReceiver { @gen_promise("readLatestImage") ReadLatestImageSync(): Image; + @gen_async("readNextImage") + @gen_promise("readNextImage") + ReadNextImageSync(): Image; + @!sts_inject_into_interface("on(type: string, callback: (err: BusinessError, data: undefined)=> void): void;") @!sts_inject_into_class("""on(type: string, callback: (err: BusinessError, data: undefined)=> void): void { if (type === 'imageArrival') { @@ -643,6 +813,37 @@ interface ImageCreator { @get("capacity") GetCapacity(): i32; @get("format") GetFormat(): ImageFormat; + @gen_async("queueImage") + @gen_promise("queueImage") + QueueImageSync(image: Image): void; + + @gen_async("dequeueImage") + @gen_promise("dequeueImage") + DequeueImageSync(): Image; + + @!sts_inject_into_interface("on(type: string, callback: (err: BusinessError, data: undefined)=> void): void;") + @!sts_inject_into_class("""on(type: string, callback: (err: BusinessError, data: undefined)=> void): void { + if (type === 'imageRelease') { + this.onImageRelease(callback); + } else { + throw new Error(`Unknown type: ${type}`); + } + } + """) + + @!sts_inject_into_interface("off(type: string, callback?: (err: BusinessError, data: undefined)=> void): void;") + @!sts_inject_into_class("""off(type: string, callback?: (err: BusinessError, data: undefined)=> void): void { + if (type === 'imageRelease') { + this.offImageRelease(callback); + } else { + throw new Error(`Unknown type: ${type}`); + } + } + """) + + OnImageRelease(callback: (err: @sts_type("BusinessError") Opaque, data: @sts_type("undefined") Opaque)=> void): void; + OffImageRelease(callback: Optional<(err: @sts_type("BusinessError") Opaque, data: @sts_type("undefined") Opaque)=> void>): void; + @gen_async("release") @gen_promise("release") ReleaseSync(): void; @@ -684,24 +885,30 @@ function CreateImageSourceByArrayBuffer(buf: @arraybuffer Array): ImageSourc @overload("createImageSource") function CreateImageSourceByArrayBufferOption(buf: @arraybuffer Array, options: SourceOptions): ImageSource; +@overload("CreateIncrementalSource") +function CreateIncrementalSourceByArrayBuffer(buf: @arraybuffer Array): ImageSource; + +@overload("CreateIncrementalSource") +function CreateIncrementalSourceByArrayBufferOption(buf: @arraybuffer Array, options: Optional): ImageSource; + @overload("createImageSource") function CreateImageSourceByRawFileDescriptorOption(rawfile: @sts_type("resourceManager.RawFileDescriptor") Opaque, options: Optional): ImageSource; -function CreateImagePacker(): ImagePacker; - -@overload("createImageCreator") -function CreateImageCreator(width: i32, height: i32, format: i32, capacity: i32): ImageCreator; +// For legacy ANI backward compatibility +function CreateImageSourceByPtr(ptr: i64): ImageSource; -@overload("createImageCreator") -function CreateImageCreatorBySize(size: Size, format: ImageFormat, capacity: i32): ImageCreator; +function CreateImagePacker(): ImagePacker; -@overload("createImageReceiver") -function CreateImageReceiver(width: i32, height: i32, format: i32, capacity: i32): ImageReceiver; +function CreateImageCreator(size: Size, format: ImageFormat, capacity: i32): ImageCreator; -@overload("createImageReceiver") -function CreateImageReceiverBySize(size: Size, format: ImageFormat, capacity: i32): ImageReceiver; +function CreateImageReceiver(size: Size, format: ImageFormat, capacity: i32): ImageReceiver; @overload("createPicture") function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; +// For legacy ANI backward compatibility +function CreatePictureByPtr(ptr: i64): Picture; + +function CreatePictureFromParcel(sequence: @sts_type("rpc.MessageSequence") Opaque): Picture; + function CreateAuxiliaryPicture(buffer: @arraybuffer Array, size: Size, type: AuxiliaryPictureType): AuxiliaryPicture; \ No newline at end of file diff --git a/frameworks/kits/taihe/include/auxiliary_picture_taihe.h b/frameworks/kits/taihe/include/auxiliary_picture_taihe.h index 51d1a9dbd..042bf48ac 100644 --- a/frameworks/kits/taihe/include/auxiliary_picture_taihe.h +++ b/frameworks/kits/taihe/include/auxiliary_picture_taihe.h @@ -29,8 +29,17 @@ public: AuxiliaryPictureImpl(); explicit AuxiliaryPictureImpl(std::shared_ptr auxiliaryPicture); ~AuxiliaryPictureImpl(); - + int64_t GetImplPtr(); + std::shared_ptr GetNativeAuxiliaryPic() + { + return nativeAuxiliaryPicture_; + } + + void WritePixelsFromBufferSync(array_view data); array ReadPixelsToBufferSync(); + AuxiliaryPictureType GetType(); + void SetMetadataSync(MetadataType metadataType, weak::Metadata metadata); + Metadata GetMetadataSync(MetadataType metadataType); AuxiliaryPictureInfo GetAuxiliaryPictureInfo(); void SetAuxiliaryPictureInfo(AuxiliaryPictureInfo const& info); void Release(); diff --git a/frameworks/kits/taihe/include/image_creator_taihe.h b/frameworks/kits/taihe/include/image_creator_taihe.h index 45413093d..fcaa3b0ee 100644 --- a/frameworks/kits/taihe/include/image_creator_taihe.h +++ b/frameworks/kits/taihe/include/image_creator_taihe.h @@ -16,7 +16,9 @@ #ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_CREATOR_TAIHE_H #define FRAMEWORKS_KITS_TAIHE_INCLUDE_IMAGE_CREATOR_TAIHE_H +#include "event_handler.h" #include "image_creator.h" +#include "image_taihe.h" #include "ohos.multimedia.image.image.proj.hpp" #include "ohos.multimedia.image.image.impl.hpp" #include "taihe/runtime.hpp" @@ -25,20 +27,64 @@ namespace ANI::Image { using namespace taihe; using namespace ohos::multimedia::image::image; +struct ImageCreatorTaiheContext; +using CallbackResult = std::variant; +using CompleteCallback = CallbackResult (*)(std::shared_ptr &); + class ImageCreatorImpl { public: ImageCreatorImpl(); explicit ImageCreatorImpl(std::shared_ptr imageCreator); ~ImageCreatorImpl(); + static bool AniSendEvent(const std::function cb, std::string &name); + static void OnProcessSendEvent(std::shared_ptr &context); + int32_t GetCapacity(); ImageFormat GetFormat(); + void QueueImageSync(weak::Image image); + + struct Image DequeueImageSync(); + + void OnImageRelease(::taihe::callback_view callback); + + void OffImageRelease(::taihe::optional_view<::taihe::callback> callback); + void ReleaseSync(); private: std::shared_ptr imageCreator_; bool isRelease = false; + static std::shared_ptr mainHandler_; +}; + +struct ImageCreatorTaiheContext { + CompleteCallback callBack = nullptr; + CallbackResult result; + std::shared_ptr taiheCallback = nullptr; + std::string name; + ImageCreatorImpl *imageCreatorImpl_ = nullptr; + ImageImpl *imageImpl_ = nullptr; + uint32_t status = OHOS::Media::ERROR; +}; + +struct ImageCreatorCommonArgs { + const std::string name; + CompleteCallback callBack; +}; + +class ImageCreatorReleaseListener : public OHOS::Media::SurfaceBufferReleaseListener { +public: + ~ImageCreatorReleaseListener() override + { + context = nullptr; + } + void OnSurfaceBufferRelease() override + { + ImageCreatorImpl::OnProcessSendEvent(context); + } + std::shared_ptr context = nullptr; }; } // namespace ANI::Image diff --git a/frameworks/kits/taihe/include/image_packer_taihe.h b/frameworks/kits/taihe/include/image_packer_taihe.h index 0c4881332..1bd57bcfd 100644 --- a/frameworks/kits/taihe/include/image_packer_taihe.h +++ b/frameworks/kits/taihe/include/image_packer_taihe.h @@ -31,12 +31,22 @@ public: explicit ImagePackerImpl(std::shared_ptr imagePacker); ~ImagePackerImpl(); + array Packing(int32_t packType, int64_t source, PackingOption const& options, bool needReturnError); + void PackToFile(int32_t packType, int64_t source, int32_t fd, PackingOption const& options); + void PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options); void PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options); + void PackToFileFromPixelmapSequenceSync(array_view pixelmapSequence, int32_t fd, + PackingOptionsForSequence const& options); void PackPictureToFileSync(weak::Picture picture, int32_t fd, PackingOption const& options); - array PackingPixelMapSync(weak::PixelMap source, PackingOption const& option); array PackingPictureSync(weak::Picture picture, PackingOption const& options); + + array PackImageSourceToDataSync(weak::ImageSource source, PackingOption const& options); + array PackPixelMapToDataSync(weak::PixelMap source, PackingOption const& options); + array PackToDataFromPixelmapSequenceSync(array_view pixelmapSequence, + PackingOptionsForSequence const& options); + void ReleaseSync(); array GetSupportedFormats(); diff --git a/frameworks/kits/taihe/include/image_receiver_taihe.h b/frameworks/kits/taihe/include/image_receiver_taihe.h index c2df2147d..6e3b04491 100644 --- a/frameworks/kits/taihe/include/image_receiver_taihe.h +++ b/frameworks/kits/taihe/include/image_receiver_taihe.h @@ -45,6 +45,7 @@ public: string GetReceivingSurfaceIdSync(); struct Image ReadLatestImageSync(); + struct Image ReadNextImageSync(); void OnImageArrival(callback_view callback); void OffImageArrival(optional_view> callback); void ReleaseSync(); @@ -63,7 +64,6 @@ private: }; struct ImageReceiverTaiheContext { - ani_env *env = nullptr; CompleteCallback callBack = nullptr; CallbackResult result; std::shared_ptr taiheCallback = nullptr; diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h index 42ee6c9aa..d98ddb9c6 100644 --- a/frameworks/kits/taihe/include/image_source_taihe.h +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -30,6 +30,9 @@ class ImageSourceImpl { public: ImageSourceImpl(); explicit ImageSourceImpl(std::shared_ptr imageSource); + ImageSourceImpl(std::shared_ptr imageSource, + std::shared_ptr incPixelMap); + ImageSourceImpl(int64_t aniPtr); ~ImageSourceImpl(); int64_t GetImplPtr(); @@ -43,11 +46,17 @@ public: array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); array CreatePixelMapListSyncWithOptionalOptions(optional_view options); array GetDelayTimeListSync(); + array GetDisposalTypeListSync(); + int32_t GetFrameCountSync(); string GetImagePropertySync(PropertyKey key, optional_view options); map GetImagePropertiesSync(array_view key); void ModifyImagePropertySync(PropertyKey key, string_view value); void ModifyImagePropertiesSync(map_view records); + void UpdateDataSync(array_view buf, bool isFinished, int32_t offset, int32_t length); void ReleaseSync(); +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + Picture CreatePictureSync(optional_view options); +#endif array GetSupportedFormats(); diff --git a/frameworks/kits/taihe/include/image_source_taihe_ani.h b/frameworks/kits/taihe/include/image_source_taihe_ani.h new file mode 100644 index 000000000..c190dbc43 --- /dev/null +++ b/frameworks/kits/taihe/include/image_source_taihe_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORK_KITS_TAIHE_INCLUDE_IMAGE_SOURCE_TAIHE_ANI_H +#define FRAMEWORK_KITS_TAIHE_INCLUDE_IMAGE_SOURCE_TAIHE_ANI_H + +#include +#include "image_source.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { + +class ImageSourceTaiheAni { +public: + static ani_object CreateEtsImageSource(ani_env *env, std::shared_ptr imageSource); + std::shared_ptr nativeImgSrc; +}; + +} // namespace Media +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/frameworks/kits/taihe/include/image_taihe.h b/frameworks/kits/taihe/include/image_taihe.h index 36b441316..53ed3c004 100644 --- a/frameworks/kits/taihe/include/image_taihe.h +++ b/frameworks/kits/taihe/include/image_taihe.h @@ -32,17 +32,27 @@ public: explicit ImageImpl(std::shared_ptr nativeImage); ~ImageImpl(); + int64_t GetImplPtr(); + std::shared_ptr GetIncrementalImage() const + { + return nativeImage_; + } + + Component GetComponentSync(ComponentType componentType); + static struct Image Create(std::shared_ptr nativeImage); void ReleaseSync(); + void NativeRelease(); + ohos::multimedia::image::image::Region GetClipRect(); Size GetSize(); int32_t GetFormat(); + int64_t GetTimestamp(); private: static OHOS::Media::ImageHolderManager sNativeImageHolder_; std::shared_ptr nativeImage_; bool isTestImage_; - bool isRelease = false; }; } // namespace ANI::Image diff --git a/frameworks/kits/taihe/include/image_taihe_utils.h b/frameworks/kits/taihe/include/image_taihe_utils.h index ceb46cac9..48a8e0bbe 100644 --- a/frameworks/kits/taihe/include/image_taihe_utils.h +++ b/frameworks/kits/taihe/include/image_taihe_utils.h @@ -29,8 +29,8 @@ using namespace ohos::multimedia::image::image; class ImageTaiheUtils { public: static void HicheckerReport(); - static void ThrowExceptionError(const std::string errMsg); - static void ThrowExceptionError(const int32_t errCode, const std::string errMsg); + static void ThrowExceptionError(const std::string &errMsg); + static void ThrowExceptionError(const int32_t errCode, const std::string &errMsg); struct ImagePropertyOptions { uint32_t index = 0; std::string defaultValueStr; @@ -47,6 +47,9 @@ public: template static bool GetEnumKeyByValue(ValueType value, typename EnumType::key_t &key); + + template + static bool IsValidPtr(T data); }; } // namespace ANI::Image diff --git a/frameworks/kits/taihe/include/metadata_taihe.h b/frameworks/kits/taihe/include/metadata_taihe.h new file mode 100644 index 000000000..fc6c1cbca --- /dev/null +++ b/frameworks/kits/taihe/include/metadata_taihe.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORKS_KITS_TAIHE_INCLUDE_METADATA_TAIHE_H +#define FRAMEWORKS_KITS_TAIHE_INCLUDE_METADATA_TAIHE_H + +#include "metadata.h" +#include "ohos.multimedia.image.image.proj.hpp" +#include "ohos.multimedia.image.image.impl.hpp" +#include "taihe/runtime.hpp" + +namespace ANI::Image { +using namespace taihe; +using namespace ohos::multimedia::image::image; + +class MetadataImpl { +public: + MetadataImpl(); + explicit MetadataImpl(std::shared_ptr imageMetadata); + ~MetadataImpl(); + + int64_t GetImplPtr(); + std::shared_ptr GetNativeMetadata(); + + map GetPropertiesSync(array_view key); + void SetPropertiesSync(map_view records); + map GetAllPropertiesSync(); + Metadata CloneSync(); + + void Release(); + +private: + std::shared_ptr nativeMetadata_; + bool isRelease = false; +}; +} // namespace ANI::Image + +#endif // FRAMEWORKS_KITS_TAIHE_INCLUDE_METADATA_TAIHE_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/picture_taihe.h b/frameworks/kits/taihe/include/picture_taihe.h index 9a9952244..e928f2b4f 100644 --- a/frameworks/kits/taihe/include/picture_taihe.h +++ b/frameworks/kits/taihe/include/picture_taihe.h @@ -29,11 +29,19 @@ class PictureImpl { public: PictureImpl(); explicit PictureImpl(std::shared_ptr picture); + PictureImpl(int64_t aniPtr); ~PictureImpl(); int64_t GetImplPtr(); std::shared_ptr GetNativePtr(); + static Picture CreatePicture(std::shared_ptr picture); PixelMap GetMainPixelmap(); + PixelMap GetHdrComposedPixelmapSync(); + GainMap GetGainmapPixelmap(); + void SetAuxiliaryPicture(AuxiliaryPictureType type, weak::AuxiliaryPicture auxiliaryPicture); + AuxPicture GetAuxiliaryPicture(AuxiliaryPictureType type); + void SetMetadataSync(MetadataType metadataType, weak::Metadata metadata); + Metadata GetMetadataSync(MetadataType metadataType); void Marshalling(uintptr_t sequence); void Release(); diff --git a/frameworks/kits/taihe/include/picture_taihe_ani.h b/frameworks/kits/taihe/include/picture_taihe_ani.h new file mode 100644 index 000000000..4bb87a149 --- /dev/null +++ b/frameworks/kits/taihe/include/picture_taihe_ani.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2025 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. + */ + +#ifndef FRAMEWORK_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_ANI_H +#define FRAMEWORK_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_ANI_H + +#include +#include "picture.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { + +class PictureTaiheAni { +public: + static ani_object CreateEtsPicture(ani_env *env, std::shared_ptr picture); + std::shared_ptr nativePicture_; +}; + +} // namespace Media +} // namespace OHOS + +#endif // FRAMEWORK_KITS_TAIHE_INCLUDE_PICTURE_TAIHE_ANI_H \ No newline at end of file diff --git a/frameworks/kits/taihe/include/pixel_map_taihe.h b/frameworks/kits/taihe/include/pixel_map_taihe.h index 5dfa5a544..cb95ac7cc 100644 --- a/frameworks/kits/taihe/include/pixel_map_taihe.h +++ b/frameworks/kits/taihe/include/pixel_map_taihe.h @@ -54,6 +54,8 @@ public: void FlipSync(bool horizontal, bool vertical); void OpacitySync(float rate); void SetMemoryNameSync(string_view name); + void ToSdrSync(); + void ApplyColorSpaceSync(uintptr_t targetColorSpace); void ReleaseSync(); bool GetIsStrideAlignment(); void SetCaptureId(int32_t captureId); diff --git a/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp index fec86b56c..bcb393f4b 100644 --- a/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp +++ b/frameworks/kits/taihe/src/auxiliary_picture_taihe.cpp @@ -23,6 +23,7 @@ #include "image_type.h" #include "image_utils.h" #include "media_errors.h" +#include "metadata_taihe.h" #include "pixel_map.h" using namespace ANI::Image; @@ -37,6 +38,8 @@ struct AuxiliaryPictureTaiheContext { size_t arrayBufferSize; std::shared_ptr rAuxiliaryPicture; OHOS::Media::AuxiliaryPictureInfo auxiliaryPictureInfo; + std::shared_ptr imageMetadata; + OHOS::Media::MetadataType metadataType = OHOS::Media::MetadataType::EXIF; std::shared_ptr AuxColorSpace = nullptr; }; @@ -52,6 +55,29 @@ AuxiliaryPictureImpl::~AuxiliaryPictureImpl() Release(); } +int64_t AuxiliaryPictureImpl::GetImplPtr() +{ + return reinterpret_cast(this); +} + +void AuxiliaryPictureImpl::WritePixelsFromBufferSync(array_view data) +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->rAuxiliaryPicture = nativeAuxiliaryPicture_; + if (taiheContext->rAuxiliaryPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native auxiliary picture."); + return; + } + taiheContext->arrayBuffer = static_cast(data.data()); + taiheContext->arrayBufferSize = data.size(); + if (taiheContext->arrayBuffer == nullptr || taiheContext->arrayBufferSize == 0) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid args."); + IMAGE_LOGE("Fail to get buffer info"); + } + taiheContext->rAuxiliaryPicture->WritePixels( + static_cast(taiheContext->arrayBuffer), taiheContext->arrayBufferSize); +} + static bool ReadPixelsToBufferSyncExecute(std::unique_ptr &context) { OHOS::Media::AuxiliaryPictureInfo info = context->rAuxiliaryPicture->GetAuxiliaryPictureInfo(); @@ -86,6 +112,90 @@ static array ReadPixelsToBufferSyncComplete(std::unique_ptr(OHOS::Media::AuxiliaryPictureType::NONE)); + } + AuxiliaryPictureType::key_t auxPictureTypeKey; + auto auxType = nativeAuxiliaryPicture_->GetType(); + IMAGE_LOGD("AuxiliaryPictureImpl::GetType %{public}d", auxType); + if (ImageTaiheUtils::GetEnumKeyByValue(static_cast(auxType), auxPictureTypeKey)) { + return AuxiliaryPictureType(auxPictureTypeKey); + } else { + IMAGE_LOGE("Get auxiliary picture type failed"); + return AuxiliaryPictureType(static_cast( + OHOS::Media::AuxiliaryPictureType::NONE)); + } +} + +static bool CheckMetadataType(std::unique_ptr const& context) +{ + if (context == nullptr || context->rAuxiliaryPicture == nullptr) { + IMAGE_LOGE("Auxiliary picture is null"); + return false; + } + return !(context->rAuxiliaryPicture->GetType() != OHOS::Media::AuxiliaryPictureType::FRAGMENT_MAP && + context->metadataType == OHOS::Media::MetadataType::FRAGMENT); +} + +void AuxiliaryPictureImpl::SetMetadataSync(MetadataType metadataType, weak::Metadata metadata) +{ + std::unique_ptr context = std::make_unique(); + context->rAuxiliaryPicture = nativeAuxiliaryPicture_; + if (context->rAuxiliaryPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native auxiliary picture."); + return; + } + if (metadataType >= static_cast(OHOS::Media::MetadataType::EXIF) + && metadataType <= static_cast(OHOS::Media::MetadataType::FRAGMENT)) { + context->metadataType = OHOS::Media::MetadataType(metadataType.get_value()); + } else { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid args metadata type."); + return; + } + if (!CheckMetadataType(context)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_METADATA, "Unsupported metadata"); + return; + } + MetadataImpl* metadataImpl = reinterpret_cast(metadata->GetImplPtr()); + if (metadataImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Failed to unwrap MetadataImpl"); + return; + } + context->imageMetadata = metadataImpl->GetNativeMetadata(); + if (context->imageMetadata == nullptr) { + IMAGE_LOGE("Empty native metadata"); + } + context->rAuxiliaryPicture->SetMetadata(context->metadataType, context->imageMetadata); + IMAGE_LOGD("[AuxiliaryPicture]SetMetadata OUT"); +} + +Metadata AuxiliaryPictureImpl::GetMetadataSync(MetadataType metadataType) +{ + std::unique_ptr context = std::make_unique(); + context->rAuxiliaryPicture = nativeAuxiliaryPicture_; + if (context->rAuxiliaryPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native auxiliary picture."); + return make_holder(); + } + if (metadataType >= static_cast(OHOS::Media::MetadataType::EXIF) + && metadataType <= static_cast(OHOS::Media::MetadataType::FRAGMENT)) { + context->metadataType = OHOS::Media::MetadataType(metadataType.get_value()); + } else { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Invalid args metadata type."); + return make_holder(); + } + if (!CheckMetadataType(context) || context->metadataType == OHOS::Media::MetadataType::EXIF) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_METADATA, "Unsupported metadata"); + return make_holder(); + } + context->imageMetadata = context->rAuxiliaryPicture->GetMetadata(context->metadataType); + IMAGE_LOGD("[AuxiliaryPicture]GetMetadata OUT"); + return make_holder(std::move(context->imageMetadata)); +} + array AuxiliaryPictureImpl::ReadPixelsToBufferSync() { std::unique_ptr taiheContext = std::make_unique(); @@ -106,34 +216,46 @@ AuxiliaryPictureInfo MakeEmptyAuxiliaryPictureInfo() {0, 0}, 0, PixelMapFormat(PixelMapFormat::key_t::UNKNOWN), 0}; } -static AuxiliaryPictureInfo ToTaiheAuxiliaryPictureInfo(const OHOS::Media::AuxiliaryPictureInfo &src) +static AuxiliaryPictureInfo ToTaiheAuxiliaryPictureInfo(const OHOS::Media::AuxiliaryPictureInfo &src, + std::shared_ptr &auxiliaryPicture) { + AuxiliaryPictureInfo result = MakeEmptyAuxiliaryPictureInfo(); AuxiliaryPictureType::key_t auxiliaryPictureTypeKey; ImageTaiheUtils::GetEnumKeyByValue(static_cast(src.auxiliaryPictureType), auxiliaryPictureTypeKey); + result.auxiliaryPictureType = AuxiliaryPictureType(auxiliaryPictureTypeKey); Size size { .width = src.size.width, .height = src.size.height, }; + result.size = size; + result.rowStride = static_cast(src.rowStride); PixelMapFormat::key_t pixelFormatKey; ImageTaiheUtils::GetEnumKeyByValue(static_cast(src.pixelFormat), pixelFormatKey); + result.pixelFormat = PixelMapFormat(pixelFormatKey); - AuxiliaryPictureInfo result { - .auxiliaryPictureType = AuxiliaryPictureType(auxiliaryPictureTypeKey), - .size = size, - .rowStride = static_cast(src.rowStride), - .pixelFormat = PixelMapFormat(pixelFormatKey), - }; + if (auxiliaryPicture == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "Invalid pixelmap"); + return result; + } + + auto grCS = auxiliaryPicture->GetContentPixel()->InnerGetGrColorSpacePtr(); + if (grCS == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_UNSUPPORT, "No colorspace in pixelmap"); + return result; + } + ani_object colorSpaceObj = OHOS::ColorManager::CreateAniColorSpaceObject(get_env(), grCS); + result.colorSpace = reinterpret_cast(colorSpaceObj); return result; } AuxiliaryPictureInfo AuxiliaryPictureImpl::GetAuxiliaryPictureInfo() { if (nativeAuxiliaryPicture_ != nullptr) { - AuxiliaryPictureInfo info = ToTaiheAuxiliaryPictureInfo(nativeAuxiliaryPicture_->GetAuxiliaryPictureInfo()); - return info; + return ToTaiheAuxiliaryPictureInfo( + nativeAuxiliaryPicture_->GetAuxiliaryPictureInfo(), nativeAuxiliaryPicture_); } else { ImageTaiheUtils::ThrowExceptionError("Native auxiliarypicture is nullptr!"); return MakeEmptyAuxiliaryPictureInfo(); diff --git a/frameworks/kits/taihe/src/image_creator_taihe.cpp b/frameworks/kits/taihe/src/image_creator_taihe.cpp index 1a2e4cf6e..2499b4796 100644 --- a/frameworks/kits/taihe/src/image_creator_taihe.cpp +++ b/frameworks/kits/taihe/src/image_creator_taihe.cpp @@ -30,12 +30,8 @@ namespace { namespace ANI::Image { static bool g_isCreatorTest = false; -const int ARGS4 = 4; -const int PARAM0 = 0; -const int PARAM1 = 1; -const int PARAM2 = 2; -const int PARAM3 = 3; +std::shared_ptr ImageCreatorImpl::mainHandler_ = nullptr; ImageCreatorImpl::ImageCreatorImpl() : imageCreator_(nullptr), isRelease(false) {} ImageCreatorImpl::ImageCreatorImpl(std::shared_ptr imageCreator) @@ -98,51 +94,296 @@ void ImageCreatorImpl::ReleaseSync() } } -static bool isTest(const int32_t* args, const int32_t len) +bool ImageCreatorImpl::AniSendEvent(const std::function cb, std::string &name) { - if ((args[PARAM0] == TEST_WIDTH) && - (args[PARAM1] == TEST_HEIGHT) && - (args[PARAM2] == TEST_FORMAT) && - (args[PARAM3] == TEST_CAPACITY) && - (len == ARGS4)) { - return true; + if (cb == nullptr) { + IMAGE_LOGE("%{public}s callback is nullptr", __func__); + return false; } - return false; + + if (!mainHandler_) { + std::shared_ptr runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); + if (!runner) { + IMAGE_LOGE("%{public}s EventRunner is nullptr", __func__); + return false; + } + mainHandler_ = std::make_shared(runner); + } + + if (mainHandler_ == nullptr) { + IMAGE_LOGE("%{public}s mainHandler_ is still nullptr", __func__); + return false; + } + + if (!mainHandler_->PostTask(cb, name, 0, OHOS::AppExecFwk::EventQueue::Priority::IMMEDIATE, {})) { + IMAGE_LOGE("%{public}s PostTask failed", __func__); + return false; + } + return true; } -ImageCreator CreateImageCreatorInner(int32_t width, int32_t height, int32_t format, int32_t capacity) +static void DoCallBack(std::shared_ptr &context) { - int32_t args[ARGS4] = {0}; - args[PARAM0] = width; - args[PARAM1] = height; - args[PARAM2] = format; - args[PARAM3] = capacity; + auto localContext = std::make_unique>(context); + if (context == nullptr) { + IMAGE_LOGE("%{public}s, localContext is nullptr", __func__); + localContext.release(); + return; + } - int32_t len = sizeof(args) / sizeof(args[PARAM0]); - if (isTest(args, len)) { - g_isCreatorTest = true; + std::shared_ptr> cacheCallback = + std::reinterpret_pointer_cast>(context->taiheCallback); + ani_object err = ImageTaiheUtils::ToBusinessError(taihe::get_env(), 0, "Callback is OK"); + (*cacheCallback)(reinterpret_cast(err), ImageTaiheUtils::GetUndefinedPtr(taihe::get_env())); + localContext.release(); +} + +void ImageCreatorImpl::OnProcessSendEvent(std::shared_ptr &context) +{ + auto task = [context]() mutable { + DoCallBack(context); + }; + ImageCreatorImpl::AniSendEvent(task, context->name); +} + +static void QueueImageSyncProcess(ImageCreatorCommonArgs &args, ImageImpl *const imageImpl, + ImageCreatorImpl *const imageCreatorImpl) +{ + if (imageCreatorImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("imageCreatorImpl is nullptr"); + return; } - if (!g_isCreatorTest) { - auto imageCreator = OHOS::Media::ImageCreator::CreateImageCreator(args[PARAM0], - args[PARAM1], args[PARAM2], args[PARAM3]); - if (imageCreator != nullptr) { - return make_holder(imageCreator); + + if (imageImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("imageImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageCreatorTaiheContext is nullptr"); + return; + } + + context->name = args.name; + context->imageCreatorImpl_ = imageCreatorImpl; + context->imageImpl_ = imageImpl; + + args.callBack(context); + if (context->status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(context->status, "CommonProcessSendEvent failed"); + return; + } +} + +void ImageCreatorImpl::QueueImageSync(weak::Image image) +{ + ImageCreatorCommonArgs args = { + .name = "QueueImageSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + if (context->imageCreatorImpl_ == nullptr) { + IMAGE_LOGE("imageCreatorImpl is nullptr"); + return std::monostate{}; + } + auto imageCreatorNative = context->imageCreatorImpl_->imageCreator_; + if (imageCreatorNative == nullptr) { + IMAGE_LOGE("imageCreator is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + + if (context->imageImpl_ == nullptr) { + IMAGE_LOGE("imageImpl is nullptr"); + return std::monostate{}; + } + auto imageNative = context->imageImpl_->GetIncrementalImage(); + if (imageNative == nullptr) { + IMAGE_LOGE("imageNatice is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + + if (OHOS::Media::SUCCESS != imageNative->CombineYUVComponents()) { + IMAGE_LOGE("QueueImage try to combine componests"); } - ImageTaiheUtils::ThrowExceptionError("Create image creator failed."); + imageCreatorNative->QueueNativeImage(imageNative); + context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + + auto imageImpl = reinterpret_cast(image->GetImplPtr()); + QueueImageSyncProcess(args, imageImpl, this); +} + +static struct Image DequeueImageSyncProcess(ImageCreatorCommonArgs &args, ImageCreatorImpl *const imageCreatorImpl) +{ + if (imageCreatorImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("imageCreatorImpl is nullptr"); + return make_holder(); } - return make_holder(); + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageCreatorTaiheContext is nullptr"); + return make_holder(); + } + + context->name = args.name; + context->imageCreatorImpl_ = imageCreatorImpl; + + context->result = args.callBack(context); + if (context->status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(context->status, "CommonProcessSendEvent failed"); + return make_holder(); + } + + if (std::holds_alternative(context->result)) { + ImageTaiheUtils::ThrowExceptionError("CommonProcessSendEvent result is empty"); + return make_holder(); + } + + return std::get(context->result); +} + +struct Image ImageCreatorImpl::DequeueImageSync() +{ + ImageCreatorCommonArgs args = { + .name = "DequeueImageSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + if (context->imageCreatorImpl_ == nullptr) { + IMAGE_LOGE("imageCreatorImpl is nullptr"); + return std::monostate{}; + } + auto imageCreatorNative = context->imageCreatorImpl_->imageCreator_; + if (imageCreatorNative == nullptr) { + IMAGE_LOGE("imageCreator is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + + auto imageNative = imageCreatorNative->DequeueNativeImage(); + if (imageNative == nullptr) { + IMAGE_LOGE("DequeueImageSync imageNatice is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + struct Image image = ImageImpl::Create(imageNative); + context->status = OHOS::Media::SUCCESS; + return image; + }; + + return DequeueImageSyncProcess(args, this); } -ImageCreator CreateImageCreator(int32_t width, int32_t height, int32_t format, int32_t capacity) +static void OnImageReleaseProcess(ImageCreatorCommonArgs &args, ImageCreatorImpl *creatorImpl, + ::taihe::callback_view callback) { - return CreateImageCreatorInner(width, height, format, capacity); + if (creatorImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("creatorImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageCreatorTaiheContext is nullptr"); + return; + } + + context->name = args.name; + context->callBack = args.callBack; + context->imageCreatorImpl_ = creatorImpl; + std::shared_ptr> taiheCallback = + std::make_shared>(callback); + context->taiheCallback = std::reinterpret_pointer_cast(taiheCallback); + + args.callBack(context); } -ImageCreator CreateImageCreatorBySize(Size const& size, ImageFormat format, int32_t capacity) +void ImageCreatorImpl::OnImageRelease(::taihe::callback_view callback) { - return CreateImageCreatorInner(size.width, size.height, format.get_value(), capacity); + ImageCreatorCommonArgs args = { + .name = "OnImageRelease", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + auto native = context->imageCreatorImpl_->imageCreator_; + if (native == nullptr) { + IMAGE_LOGE("Native instance is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + std::shared_ptr listener = std::make_shared(); + listener->context = context; + + native->RegisterBufferReleaseListener((std::shared_ptr &)listener); + + listener->context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + + OnImageReleaseProcess(args, this, callback); +} + +static void OffImageReleaseProcess(ImageCreatorCommonArgs &args, ImageCreatorImpl *creatorImpl) +{ + if (creatorImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("creatorImpl is nullptr"); + return; + } + + std::shared_ptr context = std::make_shared(); + if (context == nullptr) { + ImageTaiheUtils::ThrowExceptionError("ImageCreatorTaiheContext is nullptr"); + return; + } + + context->name = args.name; + context->callBack = args.callBack; + context->imageCreatorImpl_ = creatorImpl; + + args.callBack(context); +} + +void ImageCreatorImpl::OffImageRelease(::taihe::optional_view<::taihe::callback> callback) +{ + ImageCreatorCommonArgs args = { + .name = "OffImageRelease", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + if (context->imageCreatorImpl_ == nullptr || context->imageCreatorImpl_->imageCreator_ == nullptr) { + IMAGE_LOGE("imageCreatorImpl is nullptr"); + return std::monostate{}; + } + context->imageCreatorImpl_->imageCreator_->UnRegisterBufferReleaseListener(); + context->status = OHOS::Media::SUCCESS; + return std::monostate{}; + }; + OffImageReleaseProcess(args, this); +} + +ImageCreator CreateImageCreator(Size const& size, ImageFormat format, int32_t capacity) +{ + int width = size.width; + int height = size.height; + if ((width == TEST_WIDTH) && (height == TEST_HEIGHT) && + (format.get_value() == TEST_FORMAT) && (capacity == TEST_CAPACITY)) { + g_isCreatorTest = true; + } + if (!g_isCreatorTest) { + auto imageCreator = OHOS::Media::ImageCreator::CreateImageCreator(width, height, format.get_value(), capacity); + return make_holder(imageCreator); + } + return make_holder(); } } // namespace ANI::Image -TH_EXPORT_CPP_API_CreateImageCreator(CreateImageCreator); -TH_EXPORT_CPP_API_CreateImageCreatorBySize(CreateImageCreatorBySize); \ No newline at end of file +TH_EXPORT_CPP_API_CreateImageCreator(CreateImageCreator); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_packer_taihe.cpp b/frameworks/kits/taihe/src/image_packer_taihe.cpp index 8a37ff111..ca45a656b 100644 --- a/frameworks/kits/taihe/src/image_packer_taihe.cpp +++ b/frameworks/kits/taihe/src/image_packer_taihe.cpp @@ -47,6 +47,8 @@ const int32_t TYPE_PIXEL_MAP = 2; const int32_t TYPE_PICTURE = 3; const int32_t TYPE_ARRAY = 4; const int64_t DEFAULT_BUFFER_SIZE = 25 * 1024 * 1024; // 25M is the maximum default packedSize +const int MASK_3 = 0x3; +const int MASK_16 = 0xffff; struct ImagePackerTaiheContext { OHOS::Media::PackOption packOption; @@ -63,6 +65,7 @@ struct ImagePackerTaiheContext { int64_t packedSize = 0; int fd = INVALID_FD; bool needReturnErrorCode = true; + uint32_t frameCount; }; ImagePackerImpl::ImagePackerImpl() : nativeImagePacker_(nullptr) {} @@ -155,6 +158,96 @@ static int64_t ParseBufferSize(std::unique_ptr &context return tmpNumber; } +static bool HandlePixelMapList(std::unique_ptr& context) +{ + if (context->frameCount == 0) { + IMAGE_LOGE("Parameter input error, invalid frameCount"); + return false; + } + if (context->rPixelMaps == nullptr || context->rPixelMaps->empty()) { + IMAGE_LOGE("Parameter input error, pixelmaplist is empty"); + return false; + } + uint32_t pixelMapListLength = context->rPixelMaps->size(); + if (pixelMapListLength > context->frameCount) { + for (uint32_t i = pixelMapListLength; i > context->frameCount; i--) { + context->rPixelMaps->pop_back(); + } + } else if (pixelMapListLength < context->frameCount) { + for (uint32_t i = pixelMapListLength; i < context->frameCount; i++) { + context->rPixelMaps->push_back((*context->rPixelMaps)[pixelMapListLength - 1]); + } + } + return true; +} + +static bool ParsePackOptionOfDelayTimes(std::unique_ptr& context, + PackingOptionsForSequence const& options) +{ + int32_t num; + uint32_t len = options.delayTimeList.size(); + for (size_t i = 0; i < len; i++) { + num = options.delayTimeList[i]; + if (num <= 0 || num > MASK_16) { + IMAGE_LOGE("Invalid delayTime, out of range"); + return false; + } + context->packOption.delayTimes.push_back(static_cast(num) & static_cast(MASK_16)); + } + if (len < context->frameCount) { + for (uint32_t i = len; i < context->frameCount; i++) { + context->packOption.delayTimes.push_back(static_cast(num) & static_cast(MASK_16)); + } + } + return true; +} + +static bool ParsePackOptionOfFrameCount(std::unique_ptr& context, + PackingOptionsForSequence const& options) +{ + context->frameCount = options.frameCount; + if (!HandlePixelMapList(context)) { + return false; + } + return ParsePackOptionOfDelayTimes(context, options); +} + +static bool ParsePackOptionOfDisposalTypes(std::unique_ptr& context, + PackingOptionsForSequence const& options, OHOS::Media::PackOption* opts) +{ + if (options.disposalTypes.has_value()) { + int32_t num; + uint32_t len = options.disposalTypes.value().size(); + for (size_t i = 0; i < len; i++) { + num = options.disposalTypes.value()[i]; + if (num < 0 || num > MASK_3) { + IMAGE_LOGE("Invalid disposalTypes, out of range"); + return false; + } + opts->disposalTypes.push_back(static_cast(num) & static_cast(MASK_3)); + } + } + return true; +} + +static bool ParsePackOptionOfLoop(std::unique_ptr& context, + PackingOptionsForSequence const& options) +{ + context->packOption.format = "image/gif"; + int32_t tmpNumber = 0; + if (options.loopCount.has_value()) { + tmpNumber = options.loopCount.value(); + } else { + tmpNumber = 1; + } + if (tmpNumber < 0 || tmpNumber > MASK_16) { + IMAGE_LOGE("Invalid loopCount"); + return false; + } + context->packOption.loop = static_cast(tmpNumber) & static_cast(MASK_16); + return ParsePackOptionOfFrameCount(context, options); +} + static uint8_t ParsePackOptionOfQuality(PackingOption const& options) { uint32_t tmpNumber = options.quality; @@ -177,6 +270,53 @@ static OHOS::Media::PackOption ParsePackOptions(PackingOption const& options) return packOption; } +static std::shared_ptr GetImageSourceFromTaihe(int64_t source) +{ + ImageSourceImpl* imageSourceImpl = reinterpret_cast(source); + if (imageSourceImpl == nullptr) { + IMAGE_LOGE("GetImageSourceFromTaihe imageSourceImpl is nullptr"); + ImageTaiheUtils::ThrowExceptionError("Fail to unwrap imageSourceImpl."); + return nullptr; + } + return imageSourceImpl->nativeImgSrc; +} + +static std::shared_ptr GetPixelMap(int64_t source) +{ + PixelMapImpl* pixelMapImpl = reinterpret_cast(source); + if (pixelMapImpl == nullptr) { + IMAGE_LOGE("GetPixelMap pixelMapImpl is nullptr"); + ImageTaiheUtils::ThrowExceptionError("Fail to unwrap pixelMapImpl."); + return nullptr; + } + return pixelMapImpl->GetNativePtr(); +} + +static std::shared_ptr GetPicture(int64_t source) +{ + PictureImpl* pictureImpl = reinterpret_cast(source); + if (pictureImpl == nullptr) { + IMAGE_LOGE("GetPicture pictureImpl is nullptr"); + ImageTaiheUtils::ThrowExceptionError("Fail to unwrap pictureImpl."); + return nullptr; + } + return pictureImpl->GetNativePtr(); +} + +static std::shared_ptr>> GetPixelMaps( + array_view pixelmapSequence) +{ + auto PixelMaps = std::make_shared>>(); + for (uint32_t i = 0; i < pixelmapSequence.size(); ++i) { + std::shared_ptr pixelMap; + if (ImageTaiheUtils::IsValidPtr(pixelmapSequence[i])) { + pixelMap = GetPixelMap(pixelmapSequence[i]->GetImplPtr()); + } + PixelMaps->push_back(pixelMap); + } + return PixelMaps; +} + #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) bool SetPicture(std::unique_ptr &context) { @@ -212,12 +352,12 @@ static bool FinalizePackToFile(std::unique_ptr &context context->packedSize = packedSize; return true; } else { - ImageTaiheUtils::ThrowExceptionError(packRes, "PackedSize outside size"); - IMAGE_LOGE("Packing failed, packedSize outside size."); if (context->packType == TYPE_PICTURE) { ImageTaiheUtils::ThrowExceptionError(packRes == OHOS::Media::ERR_IMAGE_INVALID_PARAMETER ? IMAGE_BAD_PARAMETER : IMAGE_ENCODE_FAILED, "PackToFile picture failed"); } + ImageTaiheUtils::ThrowExceptionError(packRes, "PackedSize outside size"); + IMAGE_LOGE("Packing failed, packedSize outside size."); return false; } } @@ -262,90 +402,120 @@ static bool PackToFileExec(std::unique_ptr &context) return FinalizePackToFile(context); } -static bool CheckPackToFileContext(std::unique_ptr &context) +static bool ParserPackToFileArguments(int32_t packType, int64_t source, int32_t fd, PackingOption const& options, + std::unique_ptr& context) { - if (context->rImagePacker == nullptr) { - TH_THROW(std::runtime_error, "ImagePacker is nullptr"); - return false; - } + context->packType = packType; if (context->packType == TYPE_IMAGE_SOURCE) { + context->rImageSource = GetImageSourceFromTaihe(source); if (context->rImageSource == nullptr) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource is nullptr"); + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "ImageSource mismatch"); return false; } } else if (context->packType == TYPE_PIXEL_MAP) { + context->rPixelMap = GetPixelMap(source); if (context->rPixelMap == nullptr) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMap is nullptr"); + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Pixelmap is released"); return false; } #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) } else if (context->packType == TYPE_PICTURE) { + context->rPicture = GetPicture(source); if (context->rPicture == nullptr) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "Picture is nullptr"); + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Picture mismatch"); return false; } #endif - } else if (context->packType == TYPE_ARRAY) { - if (context->rPixelMaps == nullptr) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "PixelMaps is nullptr"); - return false; - } } + + uint32_t errorCode = context->packType == TYPE_PICTURE ? + IMAGE_BAD_PARAMETER : OHOS::Media::ERR_IMAGE_INVALID_PARAMETER; + context->fd = fd; if (context->fd <= INVALID_FD) { - uint32_t errorCode = ((context->packType == TYPE_PICTURE || - context->packType == TYPE_ARRAY)) ? IMAGE_BAD_PARAMETER : OHOS::Media::ERR_IMAGE_INVALID_PARAMETER; - ImageTaiheUtils::ThrowExceptionError(errorCode, "Invaild fd"); + ImageTaiheUtils::ThrowExceptionError(errorCode, "fd mismatch"); return false; } + context->packOption = ParsePackOptions(options); return true; } -void ImagePackerImpl::PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options) +static bool ParserPackToFileArgumentsArray(array_view pixelmapSequence, int32_t fd, + PackingOptionsForSequence const& options, std::unique_ptr& context) { - OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackImageSourceToFile"); - - ImageSourceImpl* imageSourceImpl = reinterpret_cast(source->GetImplPtr()); - if (imageSourceImpl == nullptr) { - return; + context->rPixelMaps = GetPixelMaps(pixelmapSequence); + if (context->rPixelMaps == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMap mismatch"); + return false; + } + uint32_t errorCode = IMAGE_BAD_PARAMETER; + context->fd = fd; + if (context->fd <= INVALID_FD) { + ImageTaiheUtils::ThrowExceptionError(errorCode, "fd mismatch"); + return false; } - std::unique_ptr taiheContext = std::make_unique(); - taiheContext->rImageSource = imageSourceImpl->nativeImgSrc; - taiheContext->packType = TYPE_IMAGE_SOURCE; - taiheContext->rImagePacker = nativeImagePacker_; - taiheContext->packOption = ParsePackOptions(options); - taiheContext->fd = fd; - if (!CheckPackToFileContext(taiheContext)) { + if (!ParsePackOptionOfLoop(context, options)) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PackOptions mismatch"); + return false; + } + if (!ParsePackOptionOfDisposalTypes(context, options, &(context->packOption))) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PackOptions mismatch"); + return false; + } + return true; +} + +void ImagePackerImpl::PackToFile(int32_t packType, int64_t source, int32_t fd, PackingOption const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackToFile"); + + std::unique_ptr context = std::make_unique(); + context->rImagePacker = nativeImagePacker_; + if (!ParserPackToFileArguments(packType, source, fd, options, context)) { + IMAGE_LOGE("ParserPackToFileArguments Failed"); return; } ImageTaiheUtils::HicheckerReport(); - if (!PackToFileExec(taiheContext)) { + if (!PackToFileExec(context)) { IMAGE_LOGE("PackToFileExec Failed"); } } -void ImagePackerImpl::PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options) +void ImagePackerImpl::PackImageSourceToFileSync(weak::ImageSource source, int32_t fd, PackingOption const& options) { - OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPixelMapToFile"); + if (!ImageTaiheUtils::IsValidPtr(source)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe ImageSource"); + return; + } + PackToFile(TYPE_IMAGE_SOURCE, source->GetImplPtr(), fd, options); +} - PixelMapImpl* pixelMapImpl = reinterpret_cast(source->GetImplPtr()); - if (pixelMapImpl == nullptr) { +void ImagePackerImpl::PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, PackingOption const& options) +{ + if (!ImageTaiheUtils::IsValidPtr(source)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe PixelMap"); return; } - std::unique_ptr taiheContext = std::make_unique(); - taiheContext->rPixelMap = pixelMapImpl->GetNativePtr(); - taiheContext->packType = TYPE_PIXEL_MAP; - taiheContext->rImagePacker = nativeImagePacker_; - taiheContext->packOption = ParsePackOptions(options); - taiheContext->fd = fd; - if (!CheckPackToFileContext(taiheContext)) { + PackToFile(TYPE_PIXEL_MAP, source->GetImplPtr(), fd, options); +} + +void ImagePackerImpl::PackToFileFromPixelmapSequenceSync(array_view pixelmapSequence, int32_t fd, + PackingOptionsForSequence const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackImageSourceToFile"); + + std::unique_ptr context = std::make_unique(); + context->rImagePacker = nativeImagePacker_; + context->packType = TYPE_ARRAY; + if (!ParserPackToFileArgumentsArray(pixelmapSequence, fd, options, context)) { + IMAGE_LOGE("ParserPackToFileArguments Failed"); return; } ImageTaiheUtils::HicheckerReport(); - if (!PackToFileExec(taiheContext)) { + if (!PackToFileExec(context)) { IMAGE_LOGE("PackToFileExec Failed"); } } @@ -353,27 +523,11 @@ void ImagePackerImpl::PackPixelMapToFileSync(weak::PixelMap source, int32_t fd, void ImagePackerImpl::PackPictureToFileSync(weak::Picture picture, int32_t fd, PackingOption const& options) { #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) - OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackPictureToFile"); - - PictureImpl* pictureImpl = reinterpret_cast(picture->GetImplPtr()); - if (pictureImpl == nullptr) { - return; - } - std::unique_ptr taiheContext = std::make_unique(); - taiheContext->rPicture = pictureImpl->GetNativePtr(); - taiheContext->packType = TYPE_PIXEL_MAP; - taiheContext->rImagePacker = nativeImagePacker_; - taiheContext->packOption = ParsePackOptions(options); - taiheContext->fd = fd; - if (!CheckPackToFileContext(taiheContext)) { + if (!ImageTaiheUtils::IsValidPtr(picture)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe Picture"); return; } - - ImageTaiheUtils::HicheckerReport(); - - if (!PackToFileExec(taiheContext)) { - IMAGE_LOGE("PackToFileExec Failed"); - } + PackToFile(TYPE_PICTURE, picture->GetImplPtr(), fd, options); #endif } @@ -478,99 +632,136 @@ static array PackingComplete(std::unique_ptr & return arrayBuffer; } -static bool CheckPackingContext(std::unique_ptr &context) +static bool ParserPackingArguments(int32_t packType, int64_t source, PackingOption const& options, + std::unique_ptr& context) { - if (context->rImagePacker == nullptr) { - ThrowPackingError(context, OHOS::Media::ERR_IMAGE_INVALID_PARAMETER, "native ImagePacker is nullptr"); - return false; + context->packType = packType; + if (context->packType == TYPE_PICTURE) { + context->needReturnErrorCode = true; } if (context->packType == TYPE_IMAGE_SOURCE) { + context->rImageSource = GetImageSourceFromTaihe(source); if (context->rImageSource == nullptr) { - ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource is nullptr"); + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "ImageSource mismatch"); return false; } } else if (context->packType == TYPE_PIXEL_MAP) { + context->rPixelMap = GetPixelMap(source); if (context->rPixelMap == nullptr) { - ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMap is nullptr"); + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Pixelmap is released"); return false; } #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) } else if (context->packType == TYPE_PICTURE) { + context->rPicture = GetPicture(source); if (context->rPicture == nullptr) { - ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Picture is nullptr"); - return false; - } -#endif - } else if (context->packType == TYPE_ARRAY) { - if (context->rPixelMaps == nullptr) { - ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMaps is nullptr"); + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Picture mismatch"); return false; } } +#endif + context->packOption = ParsePackOptions(options); + context->resultBufferSize = ParseBufferSize(context, options); return true; } -static array Packing(std::unique_ptr& taiheContext) +static bool ParserPackingArgumentsArray(array_view pixelmapSequence, + PackingOptionsForSequence const& options, std::unique_ptr& context) { - ImageTaiheUtils::HicheckerReport(); + context->rPixelMaps = GetPixelMaps(pixelmapSequence); + if (context->rPixelMaps == nullptr) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PixelMaps mismatch"); + return false; + } + + if (!ParsePackOptionOfLoop(context, options)) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PackOptions mismatch"); + return false; + } + context->resultBufferSize = DEFAULT_BUFFER_SIZE; + if (!ParsePackOptionOfDisposalTypes(context, options, &(context->packOption))) { + ThrowPackingError(context, OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "PackOptions mismatch"); + return false; + } + return true; +} - if (!CheckPackingContext(taiheContext)) { +array ImagePackerImpl::Packing(int32_t packType, int64_t source, PackingOption const& options, + bool needReturnError) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::Packing"); + IMAGE_LOGI("PackingFromTaihe IN"); + + std::unique_ptr context = std::make_unique(); + context->needReturnErrorCode = needReturnError; + context->rImagePacker = nativeImagePacker_; + if (!ParserPackingArguments(packType, source, options, context)) { + IMAGE_LOGE("ParserPackingArguments Failed"); return array(0); } - if (!PackingExec(taiheContext)) { + ImageTaiheUtils::HicheckerReport(); + + if (!PackingExec(context)) { IMAGE_LOGE("PackingExec Failed"); return array(0); } - return PackingComplete(taiheContext); + return PackingComplete(context); } -array ImagePackerImpl::PackingPixelMapSync(weak::PixelMap source, PackingOption const& option) +array ImagePackerImpl::PackingPictureSync(weak::Picture picture, PackingOption const& options) { - OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPixelMapSync"); - IMAGE_LOGI("PackingPixelMapSync IN"); - - std::unique_ptr taiheContext = std::make_unique(); - PixelMapImpl* pixelMapImpl = reinterpret_cast(source->GetImplPtr()); - if (pixelMapImpl == nullptr) { - ImageTaiheUtils::ThrowExceptionError("fail to unwrap pixelMapImpl."); +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + if (!ImageTaiheUtils::IsValidPtr(picture)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe Picture"); return array(0); } - taiheContext->needReturnErrorCode = false; - - taiheContext->rImagePacker = nativeImagePacker_; - taiheContext->packType = TYPE_PIXEL_MAP; - taiheContext->rPixelMap = pixelMapImpl->GetNativePtr(); - taiheContext->packOption = ParsePackOptions(option); - taiheContext->resultBufferSize = ParseBufferSize(taiheContext, option); + return Packing(TYPE_PICTURE, picture->GetImplPtr(), options, true); +#else + ImageTaiheUtils::ThrowExceptionError("Invalid type!"); +#endif +} - return Packing(taiheContext); +array ImagePackerImpl::PackImageSourceToDataSync(weak::ImageSource source, PackingOption const& options) +{ + if (!ImageTaiheUtils::IsValidPtr(source)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe ImageSource"); + return array(0); + } + return Packing(TYPE_IMAGE_SOURCE, source->GetImplPtr(), options, true); } -array ImagePackerImpl::PackingPictureSync(weak::Picture picture, PackingOption const& options) +array ImagePackerImpl::PackPixelMapToDataSync(weak::PixelMap source, PackingOption const& options) { -#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) - OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackingPictureSync"); - IMAGE_LOGI("PackingPictureSync IN"); + if (!ImageTaiheUtils::IsValidPtr(source)) { + ImageTaiheUtils::ThrowExceptionError("fail to unwrap taihe PixelMap"); + return array(0); + } + return Packing(TYPE_PIXEL_MAP, source->GetImplPtr(), options, true); +} - std::unique_ptr taiheContext = std::make_unique(); - PictureImpl* pictureImpl = reinterpret_cast(picture->GetImplPtr()); - if (pictureImpl == nullptr) { - ImageTaiheUtils::ThrowExceptionError("Unwarp pictureImpl failed."); +array ImagePackerImpl::PackToDataFromPixelmapSequenceSync(array_view pixelmapSequence, + PackingOptionsForSequence const& options) +{ + OHOS::Media::ImageTrace imageTrace("ImagePackerTaihe::PackToDataFromPixelmapSequenceSync"); + IMAGE_LOGI("PackToDataFromPixelmapSequenceSync IN"); + + std::unique_ptr context = std::make_unique(); + context->needReturnErrorCode = true; + context->rImagePacker = nativeImagePacker_; + context->packType = TYPE_ARRAY; + if (!ParserPackingArgumentsArray(pixelmapSequence, options, context)) { + IMAGE_LOGE("ParserPackingArguments Failed"); return array(0); } - taiheContext->needReturnErrorCode = true; - taiheContext->rImagePacker = nativeImagePacker_; - taiheContext->packType = TYPE_PICTURE; - taiheContext->rPicture = pictureImpl->GetNativePtr(); - taiheContext->packOption = ParsePackOptions(options); - taiheContext->resultBufferSize = ParseBufferSize(taiheContext, options); + ImageTaiheUtils::HicheckerReport(); - return Packing(taiheContext); -#else - ImageTaiheUtils::ThrowExceptionError("Invalid type!"); -#endif + if (!PackingExec(context)) { + IMAGE_LOGE("PackingExec Failed"); + return array(0); + } + return PackingComplete(context); } void ImagePackerImpl::ReleaseSync() diff --git a/frameworks/kits/taihe/src/image_receiver_taihe.cpp b/frameworks/kits/taihe/src/image_receiver_taihe.cpp index f109e443a..4308633dc 100644 --- a/frameworks/kits/taihe/src/image_receiver_taihe.cpp +++ b/frameworks/kits/taihe/src/image_receiver_taihe.cpp @@ -67,18 +67,26 @@ void ImageReceiverImpl::NativeRelease() bool ImageReceiverImpl::AniSendEvent(const std::function cb, std::string &name) { if (cb == nullptr) { + IMAGE_LOGE("%{public}s callback is nullptr", __func__); return false; } if (!mainHandler_) { std::shared_ptr runner = OHOS::AppExecFwk::EventRunner::GetMainEventRunner(); if (!runner) { + IMAGE_LOGE("%{public}s EventRunner is nullptr", __func__); return false; } mainHandler_ = std::make_shared(runner); } + if (mainHandler_ == nullptr) { + IMAGE_LOGE("%{public}s mainHandler_ is still nullptr", __func__); + return false; + } + if (!mainHandler_->PostTask(cb, name, 0, OHOS::AppExecFwk::EventQueue::Priority::IMMEDIATE, {})) { + IMAGE_LOGE("%{public}s PostTask failed", __func__); return false; } return true; @@ -224,7 +232,7 @@ static void DoCallBackTest(OHOS::sptr surfaceBuffer1) } #endif -static struct Image ReadLatestImageSyncProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) +static struct Image ReadImageSyncProcess(ImageReceiverCommonArgs &args, ImageReceiverImpl *const receiverImpl) { if (receiverImpl == nullptr) { ImageTaiheUtils::ThrowExceptionError("receiverImpl is nullptr"); @@ -283,10 +291,46 @@ struct Image ImageReceiverImpl::ReadLatestImageSync() DoCallBackTest(nativeImage->GetBuffer()); #endif } +#endif + struct Image image = ImageImpl::Create(nativeImage); + context->status = OHOS::Media::SUCCESS; + return image; + }; + + return ReadImageSyncProcess(args, this); +} + +struct Image ImageReceiverImpl::ReadNextImageSync() +{ + ImageReceiverCommonArgs args = { + .name = "ReadNextImageSync", + .callBack = nullptr, + }; + + args.callBack = [](std::shared_ptr &context) -> CallbackResult { + auto native = context->receiverImpl_->imageReceiver_; + if (native == nullptr) { + IMAGE_LOGE("Native instance is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } + std::shared_ptr nativeImage = native->NextNativeImage(); + if (nativeImage == nullptr) { + IMAGE_LOGE("NextNativeImage is nullptr"); + context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; + return std::monostate{}; + } +#ifdef IMAGE_DEBUG_FLAG + if (context->receiverImpl_->isCallBackTest) { + context->receiverImpl_->isCallBackTest = false; +#ifdef IMAGE_SAVE_BUFFER_TO_PIC + DoCallBackTest(nativeImage->GetBuffer()); +#endif + } #endif struct Image image = ImageImpl::Create(nativeImage); if (::taihe::has_error()) { - IMAGE_LOGE("ImageImpl::Create failed!"); + IMAGE_LOGE("%{public}s ImageImpl::Create failed!", context->name.c_str()); context->status = OHOS::Media::ERR_IMAGE_INIT_ABNORMAL; return std::monostate{}; } @@ -294,13 +338,13 @@ struct Image ImageReceiverImpl::ReadLatestImageSync() return image; }; - return ReadLatestImageSyncProcess(args, this); + return ReadImageSyncProcess(args, this); } static void DoCallBack(std::shared_ptr &context) { auto localContext = std::make_unique>(context); - if (context == nullptr || context->env == nullptr) { + if (context == nullptr) { IMAGE_LOGE("%{public}s, localContext is nullptr", __func__); localContext.release(); return; @@ -308,14 +352,14 @@ static void DoCallBack(std::shared_ptr &context) std::shared_ptr> cacheCallback = std::reinterpret_pointer_cast>(context->taiheCallback); - ani_object err = ImageTaiheUtils::ToBusinessError(context->env, NUM_0, "Callback is OK"); - (*cacheCallback)(reinterpret_cast(err), ImageTaiheUtils::GetUndefinedPtr(context->env)); + ani_object err = ImageTaiheUtils::ToBusinessError(taihe::get_env(), NUM_0, "Callback is OK"); + (*cacheCallback)(reinterpret_cast(err), ImageTaiheUtils::GetUndefinedPtr(taihe::get_env())); localContext.release(); } void ImageReceiverImpl::OnProcessSendEvent(std::shared_ptr &context) { - auto task = [context] () mutable { + auto task = [context]() mutable { DoCallBack(context); }; ImageReceiverImpl::AniSendEvent(task, context->name); @@ -335,7 +379,6 @@ static void OnImageArrivalProcess(ImageReceiverCommonArgs &args, ImageReceiverIm return; } - context->env = taihe::get_env(); context->name = args.name; context->callBack = args.callBack; context->receiverImpl_ = receiverImpl; @@ -469,27 +512,21 @@ void ImageReceiverImpl::ReleaseSync() ReleaseSyncProcess(args, this); } -ImageReceiver CreateImageReceiver(int32_t width, int32_t height, int32_t format, int32_t capacity) +ImageReceiver CreateImageReceiver(Size const& size, ImageFormat format, int32_t capacity) { - if (!CheckFormat(format)) { + if (!CheckFormat(format.get_value())) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::COMMON_ERR_INVALID_PARAMETER, "Invalid format"); return make_holder(); } std::shared_ptr imageReceiver = OHOS::Media::ImageReceiver::CreateImageReceiver( - width, height, format, capacity); + size.width, size.height, format.get_value(), capacity); if (imageReceiver == nullptr) { ImageTaiheUtils::ThrowExceptionError("Create native image receiver failed"); return make_holder(); } return make_holder(imageReceiver); } - -ImageReceiver CreateImageReceiverBySize(Size const& size, ImageFormat format, int32_t capacity) -{ - return CreateImageReceiver(size.width, size.height, format.get_value(), capacity); -} } // namespace ANI::Image -TH_EXPORT_CPP_API_CreateImageReceiver(CreateImageReceiver); -TH_EXPORT_CPP_API_CreateImageReceiverBySize(CreateImageReceiverBySize); \ No newline at end of file +TH_EXPORT_CPP_API_CreateImageReceiver(CreateImageReceiver); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index 130d59584..2ef647e0f 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -18,11 +18,13 @@ #include "image_dfx.h" #include "image_log.h" #include "image_source_taihe.h" +#include "image_source_taihe_ani.h" #include "image_taihe_utils.h" #include "image_trace.h" #include "image_type.h" #include "jpeg_decoder_yuv.h" #include "media_errors.h" +#include "picture_taihe.h" #include "pixel_map_taihe.h" #include "exif_metadata_formatter.h" @@ -55,6 +57,12 @@ struct ImageSourceTaiheContext { std::vector keyStrArray; std::vector> kVStrArray; std::string defaultValueStr; + void *updataBuffer = nullptr; + size_t updataBufferSize = NUM_0; + uint32_t updataBufferOffset = NUM_0; + uint32_t updataLength = NUM_0; + bool isCompleted = false; + bool isSuccess = false; uint32_t index = 0; bool isBatch = false; OHOS::Media::DecodeOptions decodeOpts; @@ -64,6 +72,10 @@ struct ImageSourceTaiheContext { std::multimap errMsgArray; std::unique_ptr>> pixelMaps; std::unique_ptr> delayTimes; +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + OHOS::Media::DecodingOptionsForPicture decodingOptsForPicture; + std::shared_ptr rPicture; +#endif }; static const std::map ERROR_CODE_MAP = { @@ -141,6 +153,23 @@ ImageSourceImpl::ImageSourceImpl(std::shared_ptr image nativeImgSrc = imageSource; } +ImageSourceImpl::ImageSourceImpl(std::shared_ptr imageSource, + std::shared_ptr incPixelMap) +{ + nativeImgSrc = imageSource; + navIncPixelMap_ = incPixelMap; +} + +ImageSourceImpl::ImageSourceImpl(int64_t aniPtr) +{ + OHOS::Media::ImageSourceTaiheAni *imageSourceAni = reinterpret_cast(aniPtr); + if (imageSourceAni != nullptr && imageSourceAni->nativeImgSrc != nullptr) { + nativeImgSrc = imageSourceAni->nativeImgSrc; + } else { + ImageTaiheUtils::ThrowExceptionError("aniPtr is invalid or nativeImgSrc is nullptr"); + } +} + ImageSourceImpl::~ImageSourceImpl() { ReleaseSync(); @@ -157,7 +186,10 @@ ImageInfo ImageSourceImpl::GetImageInfoSyncWithIndex(uint32_t index) bool isHdr = false; if (nativeImgSrc != nullptr) { index = index >= NUM_0 ? index : NUM_0; - nativeImgSrc->GetImageInfo(index, imageinfo); + uint32_t ret = nativeImgSrc->GetImageInfo(index, imageinfo); + if (ret != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError("Inner GetImageInfo failed"); + } isHdr = nativeImgSrc->IsHdrImage(); } else { ImageTaiheUtils::ThrowExceptionError("nativeImgSrc is nullptr"); @@ -384,7 +416,7 @@ static bool ParseDecodeOptions(DecodingOptions const& options, OHOS::Media::Deco IMAGE_LOGD("desiredSize: %{public}d, %{public}d", dst.desiredSize.width, dst.desiredSize.height); } - dst.desiredRegion = ParseDesiredRegion(options); + dst.CropRect = ParseDesiredRegion(options); return ParseDecodeOptions2(options, dst, errMsg); } @@ -605,6 +637,10 @@ static array CreatePixelMapListSyncWithOptionsComplete(std::unique_ptr for (auto &pixelMap : *taiheContext->pixelMaps.get()) { result.emplace_back(PixelMapImpl::CreatePixelMap(std::move(pixelMap))); } + } else { + std::string errMsg = (taiheContext->errMsg.size() > 0) ? taiheContext->errMsg : "error status, no message"; + IMAGE_LOGD("Operation failed code:%{public}d, msg:%{public}s", taiheContext->status, errMsg.c_str()); + ImageTaiheUtils::ThrowExceptionError(taiheContext->status, errMsg); } return array(result); } @@ -621,15 +657,13 @@ array ImageSourceImpl::CreatePixelMapListSyncWithOptions(DecodingOptio taiheContext->thisPtr = this; if (taiheContext->thisPtr == nullptr) { - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "thisPtr is nullptr"); - return array(nullptr, 0); + taiheContext->errMsg = "thisPtr is nullptr"; + IMAGE_LOGE("%{public}s thisPtr is nullptr", __func__); } if (!ParseDecodeOptions(options, taiheContext->decodeOpts, taiheContext->index, taiheContext->errMsg)) { - IMAGE_LOGE("DecodeOptions mismatch."); - ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "DecodeOptions mismatch."); - return array(nullptr, 0); + IMAGE_LOGE("%{public}s DecodeOptions mismatch.", __func__); } ImageTaiheUtils::HicheckerReport(); @@ -663,9 +697,50 @@ array ImageSourceImpl::GetDelayTimeListSync() ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, "Get DelayTime error"); return array(0); - } else { - return array(taihe::copy_data_t{}, delayTimes->data(), delayTimes->size()); } + + return array(taihe::copy_data_t{}, delayTimes->data(), delayTimes->size()); +} + +array ImageSourceImpl::GetDisposalTypeListSync() +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDisposalTypeListSync"); + + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); + return array(0); + } + + uint32_t errorCode = 0; + auto disposalTypeList = nativeImgSrc->GetDisposalType(errorCode); + if ((errorCode != OHOS::Media::SUCCESS) || (disposalTypeList == nullptr)) { + IMAGE_LOGE("Get DisposalType error, error=%{public}u", errorCode); + ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, + "Get DisposalType error"); + return array(0); + } + + return array(taihe::copy_data_t{}, disposalTypeList->data(), disposalTypeList->size()); +} + +int32_t ImageSourceImpl::GetFrameCountSync() +{ + OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetFrameCountSync"); + + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); + return 0; + } + + uint32_t errorCode = 0; + auto frameCount = nativeImgSrc->GetFrameCount(errorCode); + if (errorCode != OHOS::Media::SUCCESS) { + IMAGE_LOGE("Get FrameCount error, error=%{public}u", errorCode); + ImageTaiheUtils::ThrowExceptionError(errorCode, "Get FrameCount error"); + return 0; + } + + return frameCount; } static bool ParsePropertyOptions(std::unique_ptr &context, @@ -867,7 +942,7 @@ map ImageSourceImpl::GetImagePropertiesSync(array_vi void CreateModifyErrorArray(std::multimap errMsgArray) { - for (auto it = errMsgArray.begin(); it != errMsgArray.end(); ++it) { + for (auto it = errMsgArray.rbegin(); it != errMsgArray.rend(); ++it) { if (it->first == OHOS::Media::ERR_MEDIA_WRITE_PARCEL_FAIL) { ImageTaiheUtils::ThrowExceptionError(it->first, "Create Fd without write permission! exif key: " + it->second); @@ -1042,6 +1117,67 @@ void ImageSourceImpl::ModifyImagePropertiesSync(map_view &context) +{ + if (context == nullptr) { + IMAGE_LOGE("empty context"); + return; + } + + uint8_t *buffer = static_cast(context->updataBuffer); + if (context->updataBufferOffset < context->updataBufferSize) { + buffer = buffer + context->updataBufferOffset; + } + + uint32_t lastSize = context->updataBufferSize - context->updataBufferOffset; + uint32_t size = context->updataLength < lastSize ? context->updataLength : lastSize; + + uint32_t res = context->rImageSource->UpdateData(buffer, size, + context->isCompleted); + context->isSuccess = res == 0; + if (context->isSuccess && context->thisPtr != nullptr) { + auto incPixelMap = context->thisPtr->GetIncrementalPixelMap(); + if (incPixelMap != nullptr) { + uint8_t decodeProgress = 0; + uint32_t err = incPixelMap->PromoteDecoding(decodeProgress); + if (!(err == OHOS::Media::SUCCESS || + (err == OHOS::Media::ERR_IMAGE_SOURCE_DATA_INCOMPLETE && !context->isCompleted))) { + IMAGE_LOGE("UpdateData PromoteDecoding error"); + context->isSuccess = false; + } + if (context->isCompleted) { + incPixelMap->DetachFromDecoding(); + } + } + } +} + +void ImageSourceImpl::UpdateDataSync(array_view buf, bool isFinished, int32_t offset, int32_t length) +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->thisPtr = this; + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError("empty native rImageSource"); + return; + } + taiheContext->rImageSource = nativeImgSrc; + if (buf.empty()) { + ImageTaiheUtils::ThrowExceptionError("empty buf"); + return; + } + taiheContext->updataBuffer = buf.data(); + taiheContext->updataBufferSize = buf.size(); + + taiheContext->isCompleted = isFinished; + taiheContext->updataBufferOffset = offset; + taiheContext->updataLength = length; + + UpdateDataExecute(taiheContext); + if (!taiheContext->isSuccess) { + ImageTaiheUtils::ThrowExceptionError("UpdateDataExecute error"); + } +} + void ImageSourceImpl::ReleaseSync() { if (!isRelease) { @@ -1052,6 +1188,78 @@ void ImageSourceImpl::ReleaseSync() } } +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) +static bool ParseDecodingOptionsForPicture(DecodingOptionsForPicture const& options, + OHOS::Media::DecodingOptionsForPicture &dst) +{ + for (size_t i = 0; i < options.desiredAuxiliaryPictures.size(); i++) { + int32_t type = options.desiredAuxiliaryPictures[i]; + if (type <= static_cast(OHOS::Media::AuxiliaryPictureType::FRAGMENT_MAP)) { + dst.desireAuxiliaryPictures.insert(static_cast(type)); + IMAGE_LOGD("desireAuxiliaryPictures[%{public}zu]: %{public}d", i, type); + } else { + IMAGE_LOGE("unknown auxiliary picture type: %{public}d", type); + return false; + } + } + return true; +} + +static void CreatePictureExecute(std::unique_ptr &context) +{ + IMAGE_LOGD("CreatePictureExecute IN"); + uint32_t errorCode; + context->rPicture = context->rImageSource->CreatePicture(context->decodingOptsForPicture, errorCode); + if (context->rPicture != nullptr) { + context->status = OHOS::Media::SUCCESS; + } else { + context->status = errorCode; + } + IMAGE_LOGD("CreatePictureExecute OUT"); +} + +static Picture CreatePictureComplete(std::unique_ptr &context) +{ + IMAGE_LOGD("CreatePictureComplete IN"); + if (context->status != OHOS::Media::SUCCESS) { + std::pair errorMsg(static_cast(IMAGE_DECODE_FAILED), "Create Picture error"); + context->errMsgArray.insert(errorMsg); + for (const auto &[errorCode, errMsg] : context->errMsgArray) { + ImageTaiheUtils::ThrowExceptionError(errorCode, errMsg); + } + } + IMAGE_LOGD("CreatePictureComplete OUT"); + return PictureImpl::CreatePicture(context->rPicture); +} + +Picture ImageSourceImpl::CreatePictureSync(optional_view options) +{ + std::unique_ptr taiheContext = std::make_unique(); + taiheContext->thisPtr = this; + if (nativeImgSrc == nullptr) { + ImageTaiheUtils::ThrowExceptionError("empty native rImageSource"); + return make_holder(); + } + taiheContext->rImageSource = nativeImgSrc; + + if (!options.has_value()) { + for (int32_t type = static_cast(OHOS::Media::AuxiliaryPictureType::GAINMAP); + type <= static_cast(OHOS::Media::AuxiliaryPictureType::FRAGMENT_MAP); type++) { + taiheContext->decodingOptsForPicture.desireAuxiliaryPictures.insert( + OHOS::Media::AuxiliaryPictureType(type)); + } + } else { + if (!ParseDecodingOptionsForPicture(options.value(), taiheContext->decodingOptsForPicture)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "DecodingOptionsForPicture mismatch"); + return make_holder(); + } + } + + CreatePictureExecute(taiheContext); + return CreatePictureComplete(taiheContext); +} +#endif + array ImageSourceImpl::GetSupportedFormats() { std::set formats; @@ -1151,6 +1359,39 @@ ImageSource CreateImageSourceByArrayBuffer(array_view buf) return CreateImageSourceByArrayBufferOption(buf, opts); } +ImageSource CreateIncrementalSourceByArrayBufferOption(array_view buf, optional_view options) +{ + OHOS::Media::IncrementalSourceOptions incOpts; + SourceOptions etsOpts = options.value_or(SourceOptions {}); + incOpts.sourceOptions = ImageTaiheUtils::ParseSourceOptions(etsOpts); + + incOpts.incrementalMode = OHOS::Media::IncrementalMode::INCREMENTAL_DATA; + uint32_t errorCode = 0; + std::shared_ptr imageSource = + OHOS::Media::ImageSource::CreateIncrementalImageSource(incOpts, errorCode); + if (imageSource == nullptr) { + ImageTaiheUtils::ThrowExceptionError("CreateImageSourceByArrayBufferOption error"); + return make_holder(); + } + + OHOS::Media::DecodeOptions decodeOpts; + std::shared_ptr navIncPixelMap = + imageSource->CreateIncrementalPixelMap(0, decodeOpts, errorCode); + + if (errorCode != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError("CreateIncrementalPixelMap error"); + return make_holder(); + } + + return make_holder(imageSource, navIncPixelMap); +} + +ImageSource CreateIncrementalSourceByArrayBuffer(array_view buf) +{ + optional_view optionalView; + return CreateIncrementalSourceByArrayBufferOption(buf, optionalView); +} + ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, optional_view options) { double fd; @@ -1184,6 +1425,11 @@ ImageSource CreateImageSourceByRawFileDescriptorOption(uintptr_t rawfile, option } return make_holder(imageSource); } + +ImageSource CreateImageSourceByPtr(int64_t ptr) +{ + return taihe::make_holder(ptr); +} } // namespace ANI::Image TH_EXPORT_CPP_API_CreateImageSourceByUri(CreateImageSourceByUri); @@ -1192,4 +1438,7 @@ TH_EXPORT_CPP_API_CreateImageSourceByFd(CreateImageSourceByFd); TH_EXPORT_CPP_API_CreateImageSourceByFdOption(CreateImageSourceByFdOption); TH_EXPORT_CPP_API_CreateImageSourceByArrayBuffer(CreateImageSourceByArrayBuffer); TH_EXPORT_CPP_API_CreateImageSourceByArrayBufferOption(CreateImageSourceByArrayBufferOption); -TH_EXPORT_CPP_API_CreateImageSourceByRawFileDescriptorOption(CreateImageSourceByRawFileDescriptorOption); \ No newline at end of file +TH_EXPORT_CPP_API_CreateImageSourceByRawFileDescriptorOption(CreateImageSourceByRawFileDescriptorOption); +TH_EXPORT_CPP_API_CreateIncrementalSourceByArrayBuffer(CreateIncrementalSourceByArrayBuffer); +TH_EXPORT_CPP_API_CreateIncrementalSourceByArrayBufferOption(CreateIncrementalSourceByArrayBufferOption); +TH_EXPORT_CPP_API_CreateImageSourceByPtr(CreateImageSourceByPtr); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_source_taihe_ani.cpp b/frameworks/kits/taihe/src/image_source_taihe_ani.cpp new file mode 100644 index 000000000..01d83f37b --- /dev/null +++ b/frameworks/kits/taihe/src/image_source_taihe_ani.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "image_source_taihe_ani.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { +ani_object ImageSourceTaiheAni::CreateEtsImageSource(ani_env *env, std::shared_ptr imageSource) +{ + std::unique_ptr imageSourceAni = std::make_unique(); + imageSourceAni->nativeImgSrc = imageSource; + + ani_namespace imageNamespace; + if (env->FindNamespace("L@ohos/multimedia/image/image;", &imageNamespace) != ANI_OK) { + IMAGE_LOGE("%{public}s FindNamespace failed", __func__); + return nullptr; + } + + ani_function createFunc; + if (env->Namespace_FindFunction(imageNamespace, "createImageSourceByPtr", nullptr, &createFunc) != ANI_OK) { + IMAGE_LOGE("%{public}s Namespace_FindFunction failed", __func__); + return nullptr; + } + + ani_ref imageSourceObj; + if (env->Function_Call_Ref(createFunc, &imageSourceObj, + reinterpret_cast(imageSourceAni.get())) != ANI_OK) { + IMAGE_LOGE("%{public}s Function_Call_Ref failed", __func__); + return nullptr; + } + + imageSourceAni.release(); + return reinterpret_cast(imageSourceObj); +} + +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_taihe.cpp b/frameworks/kits/taihe/src/image_taihe.cpp index 2bc829fd5..f9725ce8e 100644 --- a/frameworks/kits/taihe/src/image_taihe.cpp +++ b/frameworks/kits/taihe/src/image_taihe.cpp @@ -13,6 +13,9 @@ * limitations under the License. */ +#include + +#include "image_format.h" #include "image_log.h" #include "image_taihe.h" #include "image_taihe_utils.h" @@ -31,7 +34,7 @@ namespace { namespace ANI::Image { OHOS::Media::ImageHolderManager ImageImpl::sNativeImageHolder_; -ImageImpl::ImageImpl() : nativeImage_(nullptr), isRelease(false) {} +ImageImpl::ImageImpl() : nativeImage_(nullptr) {} ImageImpl::ImageImpl(std::shared_ptr nativeImage) { @@ -58,7 +61,70 @@ ImageImpl::ImageImpl(std::shared_ptr nativeImage) ImageImpl::~ImageImpl() { - ReleaseSync(); + NativeRelease(); +} + +static inline bool IsEqual(const int32_t& check, OHOS::Media::ImageFormat format) +{ + return (check == int32_t(format)); +} +static inline bool IsEqual(const int32_t& check, OHOS::Media::ComponentType type) +{ + return (check == int32_t(type)); +} +static inline bool IsYUVComponent(const int32_t& type) +{ + return (IsEqual(type, OHOS::Media::ComponentType::YUV_Y) || + IsEqual(type, OHOS::Media::ComponentType::YUV_U) || + IsEqual(type, OHOS::Media::ComponentType::YUV_V)); +} +static inline bool IsYUV422SPImage(int32_t format) +{ + return (IsEqual(format, OHOS::Media::ImageFormat::YCBCR_422_SP) || + (format == int32_t(OHOS::GRAPHIC_PIXEL_FMT_YCBCR_422_SP))); +} +static inline bool CheckComponentType(const int32_t& type, int32_t format) +{ + return ((IsYUV422SPImage(format) && IsYUVComponent(type)) || + (!IsYUV422SPImage(format) && IsEqual(type, OHOS::Media::ComponentType::JPEG))); +} + +static Component MakeEmptyComponent() +{ + return {ComponentType(ComponentType::key_t::YUV_Y), 0, 0, array(0)}; +} + +static Component MakeComponent(int32_t type, OHOS::Media::NativeComponent *nativeComponent) +{ + ComponentType::key_t componentTypeKey; + ImageTaiheUtils::GetEnumKeyByValue(static_cast(type), componentTypeKey); + if (nativeComponent == nullptr) { + IMAGE_LOGE("nativeComponent is nullptr"); + return {ComponentType(componentTypeKey), 0, 0, array(0)}; + } + uint8_t *buffer = nullptr; + if (nativeComponent->virAddr != nullptr) { + buffer = nativeComponent->virAddr; + } else { + buffer = nativeComponent->raw.data(); + } + if (buffer == nullptr || nativeComponent->size == 0) { + IMAGE_LOGE("Invalid buffer"); + return MakeEmptyComponent(); + } + + Component result { + .componentType = ComponentType(componentTypeKey), + .rowStride = nativeComponent->rowStride, + .pixelStride = nativeComponent->pixelStride, + .byteBuffer = ImageTaiheUtils::CreateTaiheArrayBuffer(buffer, nativeComponent->size), + }; + return result; +} + +int64_t ImageImpl::GetImplPtr() +{ + return reinterpret_cast(this); } struct Image ImageImpl::Create(std::shared_ptr nativeImage) @@ -68,31 +134,95 @@ struct Image ImageImpl::Create(std::shared_ptr nativeI void ImageImpl::ReleaseSync() { - if (!isRelease) { - if (nativeImage_ != nullptr) { - nativeImage_ = nullptr; - } - isRelease = true; + NativeRelease(); +} + +void ImageImpl::NativeRelease() +{ + if (nativeImage_ != nullptr) { + sNativeImageHolder_.release(nativeImage_->GetId()); + nativeImage_->release(); + nativeImage_ = nullptr; } } +static ohos::multimedia::image::image::Region BuildRegion(int32_t width, int32_t height, int32_t x, int32_t y) +{ + Size size {width, height}; + ohos::multimedia::image::image::Region result = {size, x, y}; + return result; +} + +ohos::multimedia::image::image::Region ImageImpl::GetClipRect() +{ + ohos::multimedia::image::image::Region errResult = BuildRegion(NUM0, NUM0, NUM0, NUM0); + if (isTestImage_) { + return BuildRegion(TEST_WIDTH, TEST_HEIGHT, NUM0, NUM0); + } + if (nativeImage_ == nullptr) { + IMAGE_LOGE("Image surface buffer is nullptr"); + return errResult; + } + + int32_t width = NUM0; + int32_t height = NUM0; + if (nativeImage_->GetSize(width, height) != OHOS::Media::SUCCESS) { + IMAGE_LOGE("Image native get size failed"); + return errResult; + } + return BuildRegion(width, height, NUM0, NUM0); +} + Size ImageImpl::GetSize() { - Size result {NUM0, NUM0}; + int width = NUM0; + int height = NUM0; if (isTestImage_) { - result.width = TEST_WIDTH; - result.height = TEST_HEIGHT; - return result; + return {TEST_WIDTH, TEST_HEIGHT}; } if (nativeImage_ == nullptr) { IMAGE_LOGE("Image surface buffer is nullptr"); - return result; + return {width, height}; } - if (nativeImage_->GetSize(result.width, result.height) != OHOS::Media::SUCCESS) { + if (nativeImage_->GetSize(width, height) != OHOS::Media::SUCCESS) { IMAGE_LOGE("Image native get size failed"); } - return result; + return {width, height}; +} + +Component ImageImpl::GetComponentSync(ComponentType componentType) +{ + int32_t argc = componentType.get_value(); + if (nativeImage_ == nullptr && !isTestImage_) { + IMAGE_LOGE("native is nullptr"); + return MakeEmptyComponent(); + } + + int32_t format = NUM0; + if (isTestImage_) { + const int32_t TEST_FORMAT = 12; + format = TEST_FORMAT; + } else { + nativeImage_->GetFormat(format); + } + + if (!CheckComponentType(argc, format)) { + IMAGE_LOGE("Unsupport component type 0 value: %{public}d", argc); + return MakeEmptyComponent(); + } + + if (isTestImage_) { + return MakeComponent(argc, nullptr); + } + + OHOS::Media::NativeComponent *nativeComponent = nativeImage_->GetComponent(argc); + if (nativeComponent == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "nativeComponent is nullptr"); + return MakeEmptyComponent(); + } + + return MakeComponent(argc, nativeComponent); } int32_t ImageImpl::GetFormat() @@ -111,4 +241,18 @@ int32_t ImageImpl::GetFormat() } return format; } + +int64_t ImageImpl::GetTimestamp() +{ + int64_t result = 0; + if (nativeImage_ == nullptr) { + IMAGE_LOGE("Image native is nullptr"); + return result; + } + + if (nativeImage_->GetTimestamp(result) != OHOS::Media::SUCCESS) { + IMAGE_LOGE("Image native get timestamp failed"); + } + return result; +} } // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/image_taihe_utils.cpp b/frameworks/kits/taihe/src/image_taihe_utils.cpp index b0f1c14be..fd4443fb3 100644 --- a/frameworks/kits/taihe/src/image_taihe_utils.cpp +++ b/frameworks/kits/taihe/src/image_taihe_utils.cpp @@ -29,13 +29,13 @@ void ImageTaiheUtils::HicheckerReport() #endif } -void ImageTaiheUtils::ThrowExceptionError(const std::string errMsg) +void ImageTaiheUtils::ThrowExceptionError(const std::string &errMsg) { IMAGE_LOGE("errMsg: %{public}s", errMsg.c_str()); taihe::set_error(errMsg); } -void ImageTaiheUtils::ThrowExceptionError(const int32_t errCode, const std::string errMsg) +void ImageTaiheUtils::ThrowExceptionError(const int32_t errCode, const std::string &errMsg) { IMAGE_LOGE("errCode: %{public}d, errMsg: %{public}s", errCode, errMsg.c_str()); taihe::set_business_error(errCode, errMsg); @@ -151,6 +151,12 @@ bool ImageTaiheUtils::GetEnumKeyByValue(ValueType value, typename EnumType::key_ return false; } +template +bool ImageTaiheUtils::IsValidPtr(T data) +{ + return !data.is_error(); +} + template bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename ImageFormat::key_t &key); @@ -166,4 +172,16 @@ bool ImageTaiheUtils::GetEnumKeyByValue(std::string va template bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename AuxiliaryPictureType::key_t &key); + +template +bool ImageTaiheUtils::GetEnumKeyByValue(int32_t value, typename ComponentType::key_t &key); + +template +bool ImageTaiheUtils::IsValidPtr(weak::PixelMap data); + +template +bool ImageTaiheUtils::IsValidPtr(weak::ImageSource data); + +template +bool ImageTaiheUtils::IsValidPtr(weak::Picture data); } // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/metadata_taihe.cpp b/frameworks/kits/taihe/src/metadata_taihe.cpp new file mode 100644 index 000000000..30aaee77c --- /dev/null +++ b/frameworks/kits/taihe/src/metadata_taihe.cpp @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2025 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 "media_errors.h" +#include "metadata_taihe.h" +#include "image_common.h" +#include "image_log.h" +#include "image_taihe_utils.h" + +using namespace ANI::Image; + +namespace ANI::Image { + +struct MetadataTaiheContext { + uint32_t status; + std::shared_ptr rMetadata; + std::vector keyStrArray; + std::multimap errMsgArray; + std::vector> kVStrArray; +}; + +MetadataImpl::MetadataImpl() {} + +MetadataImpl::MetadataImpl(std::shared_ptr imageMetadata) +{ + nativeMetadata_ = imageMetadata; + if (nativeMetadata_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Failed to set nativeMetadata_ with null. Maybe a reentrancy error"); + } +} + +MetadataImpl::~MetadataImpl() +{ + Release(); +} + +int64_t MetadataImpl::GetImplPtr() +{ + return reinterpret_cast(this); +} + +std::shared_ptr MetadataImpl::GetNativeMetadata() +{ + return nativeMetadata_; +} + +static std::vector GetKeyStrArray(array_view const& key) +{ + std::vector keyStrArray; + for (const auto& str : key) { + keyStrArray.emplace_back(str); + } + return keyStrArray; +} + +static void GetPropertiesSyncExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("Empty context"); + return; + } + uint32_t status = OHOS::Media::SUCCESS; + for (auto keyStrIt = context->keyStrArray.begin(); keyStrIt != context->keyStrArray.end(); ++keyStrIt) { + std::string valueStr = ""; + status = static_cast(context->rMetadata->GetValue(*keyStrIt, valueStr)); + if (status == OHOS::Media::SUCCESS) { + context->kVStrArray.emplace_back(std::make_pair(*keyStrIt, valueStr)); + } else { + context->kVStrArray.emplace_back(std::make_pair(*keyStrIt, "")); + context->errMsgArray.insert(std::make_pair(status, *keyStrIt)); + IMAGE_LOGE("ErrCode: %{public}u , exif key: %{public}s", status, keyStrIt->c_str()); + } + } + context->status = + context->kVStrArray.size() == context->errMsgArray.size() ? OHOS::Media::ERROR : OHOS::Media::SUCCESS; +} + +static PropertyValue CreatePropertyValue(std::string const& valueStr) +{ + if (!valueStr.empty()) { + return PropertyValue::make_type_string(valueStr); + } else { + return PropertyValue::make_type_null(); + } +} + +static map CreatePropertiesRecord( + std::vector> const& kVStrArray) +{ + map result; + for (size_t index = 0; index < kVStrArray.size(); ++index) { + string key = kVStrArray[index].first; + PropertyValue value = CreatePropertyValue(kVStrArray[index].second); + result.emplace(key, value); + } + IMAGE_LOGD("Get record parameters info success."); + return result; +} + +static bool FragmentValueIsError(std::multimap const& errMsgArray) +{ + static std::set fragmentKeys = { + "XInOriginal", "YInOriginal", "FragmentImageWidth", "FragmentImageHeight" + }; + for (const auto &errMsg : errMsgArray) { + if (fragmentKeys.find(errMsg.second) != fragmentKeys.end()) { + return true; + } + } + return false; +} + +static void CreateErrorArray(std::unique_ptr const& context) +{ + std::string errkey = ""; + if (context->errMsgArray.empty()) { + return; + } + for (const auto &errMsg : context->errMsgArray) { + errkey += errMsg.second + " "; + } + if (context->rMetadata->GetType() == OHOS::Media::MetadataType::FRAGMENT && + FragmentValueIsError(context->errMsgArray)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "The input value is incorrect!"); + } else { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_METADATA, + "The input data is incorrect! error key: " + errkey); + } +} + +static map GetPropertiesSyncComplete(std::unique_ptr const& context) +{ + map result; + if (context == nullptr) { + IMAGE_LOGE("Context is nullptr"); + return result; + } + if (context->status == OHOS::Media::SUCCESS) { + result = CreatePropertiesRecord(context->kVStrArray); + } else { + CreateErrorArray(context); + } + return result; +} + +map MetadataImpl::GetPropertiesSync(array_view key) +{ + std::unique_ptr context = std::make_unique(); + context->rMetadata = nativeMetadata_; + map result; + if (context->rMetadata == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native metadata."); + return result; + } + context->keyStrArray = GetKeyStrArray(key); + GetPropertiesSyncExecute(context); + result = GetPropertiesSyncComplete(context); + return result; +} + +static std::vector> GetKVStrArray(map_view const& records) +{ + std::vector> kVStrArray; + for (const auto& [key, value] : records) { + std::string valueStr; + if (value.holds_type_string()) { + valueStr = std::string(value.get_type_string_ref()); + } else if (value.holds_type_null()) { + valueStr = ""; + } + kVStrArray.emplace_back(key, valueStr); + } + IMAGE_LOGD("Get record argument success."); + return kVStrArray; +} + +static void SetPropertiesSyncExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("Empty context"); + return; + } + uint32_t status = OHOS::Media::SUCCESS; + for (auto kVStrIt = context->kVStrArray.begin(); kVStrIt != context->kVStrArray.end(); ++kVStrIt) { + IMAGE_LOGD("CheckExifDataValue"); + status = context->rMetadata->SetValue(kVStrIt->first, kVStrIt->second); + IMAGE_LOGD("Check ret status: %{public}d", status); + if (!status) { + IMAGE_LOGE("There is invalid exif data parameter"); + context->errMsgArray.insert(std::make_pair(status, kVStrIt->first)); + } + } + context->status = context->errMsgArray.size() > 0 ? OHOS::Media::ERROR : OHOS::Media::SUCCESS; +} + +static void SetPropertiesComplete(std::unique_ptr const& context) +{ + if (context == nullptr) { + IMAGE_LOGE("Empty context"); + return; + } + CreateErrorArray(context); +} + +void MetadataImpl::SetPropertiesSync(map_view records) +{ + std::unique_ptr context = std::make_unique(); + context->rMetadata = nativeMetadata_; + if (context->rMetadata == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native metadata."); + return; + } + context->kVStrArray = GetKVStrArray(records); + SetPropertiesSyncExecute(context); + SetPropertiesComplete(context); +} + +static void GetAllPropertiesSyncExecute(std::unique_ptr &context) +{ + if (context == nullptr) { + IMAGE_LOGE("Empty context"); + return; + } + OHOS::Media::ImageMetadata::PropertyMapPtr allKey = context->rMetadata->GetAllProperties(); + for (const auto &entry : *allKey) { + context->kVStrArray.emplace_back(std::make_pair(entry.first, entry.second)); + } + context->status = OHOS::Media::SUCCESS; +} + +static map GetAllPropertiesSyncComplete(std::unique_ptr const& context) +{ + map result; + if (context == nullptr) { + IMAGE_LOGE("Context is nullptr"); + return result; + } + if (context->status == OHOS::Media::SUCCESS) { + result = CreatePropertiesRecord(context->kVStrArray); + } else { + CreateErrorArray(context); + } + return result; +} + +map MetadataImpl::GetAllPropertiesSync() +{ + std::unique_ptr context = std::make_unique(); + context->rMetadata = nativeMetadata_; + map result; + if (context->rMetadata == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native metadata."); + return result; + } + GetAllPropertiesSyncExecute(context); + result = GetAllPropertiesSyncComplete(context); + return result; +} + +Metadata MetadataImpl::CloneSync() +{ + if (nativeMetadata_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native metadata."); + return make_holder(); + } + auto metadata = nativeMetadata_->CloneMetadata(); + return make_holder(std::move(metadata)); +} + +void MetadataImpl::Release() +{ + if (!isRelease) { + if (nativeMetadata_ != nullptr) { + nativeMetadata_ = nullptr; + } + isRelease = true; + } +} + +} // namespace ANI::Image \ No newline at end of file diff --git a/frameworks/kits/taihe/src/picture_taihe.cpp b/frameworks/kits/taihe/src/picture_taihe.cpp index f9136c3d5..bdeacada6 100644 --- a/frameworks/kits/taihe/src/picture_taihe.cpp +++ b/frameworks/kits/taihe/src/picture_taihe.cpp @@ -13,13 +13,17 @@ * limitations under the License. */ +#include "auxiliary_picture_taihe.h" #include "image_common.h" #include "image_log.h" #include "image_taihe_utils.h" +#include "image_type.h" #include "picture_taihe.h" +#include "picture_taihe_ani.h" #include "pixel_map_taihe.h" #include "media_errors.h" #include "message_parcel.h" +#include "metadata_taihe.h" using namespace ANI::Image; @@ -30,6 +34,19 @@ PictureImpl::PictureImpl() : nativePicture_(nullptr), isRelease(false) {} PictureImpl::PictureImpl(std::shared_ptr picture) { nativePicture_ = picture; + if (nativePicture_ == nullptr) { + IMAGE_LOGE("Failed to set nativePicture_ with null. Maybe a reentrancy error"); + } +} + +PictureImpl::PictureImpl(int64_t aniPtr) +{ + OHOS::Media::PictureTaiheAni *pictureAni = reinterpret_cast(aniPtr); + if (pictureAni != nullptr && pictureAni->nativePicture_ != nullptr) { + nativePicture_ = pictureAni->nativePicture_; + } else { + ImageTaiheUtils::ThrowExceptionError("aniPtr is invalid or nativePicture_ is nullptr"); + } } PictureImpl::~PictureImpl() @@ -47,6 +64,11 @@ std::shared_ptr PictureImpl::GetNativePtr() return nativePicture_; } +Picture PictureImpl::CreatePicture(std::shared_ptr picture) +{ + return make_holder(picture); +} + PixelMap PictureImpl::GetMainPixelmap() { if (nativePicture_ == nullptr) { @@ -61,17 +83,188 @@ PixelMap PictureImpl::GetMainPixelmap() return PixelMapImpl::CreatePixelMap(pixelmap); } -void PictureImpl::Marshalling(uintptr_t sequence) +PixelMap PictureImpl::GetHdrComposedPixelmapSync() +{ + IMAGE_LOGD("GetHdrComposedPixelMap IN"); + if (nativePicture_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native pixelmap"); + return make_holder(); + } + if (nativePicture_->GetAuxiliaryPicture(OHOS::Media::AuxiliaryPictureType::GAINMAP) == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_OPERATION, "There is no GAINMAP"); + return make_holder(); + } + if (nativePicture_->GetMainPixel()->GetAllocatorType() != OHOS::Media::AllocatorType::DMA_ALLOC) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_OPERATION, "Unsupported operations"); + return make_holder(); + } + + auto tmpixel = nativePicture_->GetHdrComposedPixelMap(); + if (tmpixel == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Get hdr composed pixelMap failed"); + return make_holder(); + } + return PixelMapImpl::CreatePixelMap(std::move(tmpixel)); +} + +GainMap PictureImpl::GetGainmapPixelmap() +{ + IMAGE_LOGD("GetGainmapPixelmap"); + + if (nativePicture_ != nullptr) { + auto gainpixelmap = nativePicture_->GetGainmapPixelMap(); + return GainMap::make_type_gainMap(PixelMapImpl::CreatePixelMap(gainpixelmap)); + } else { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_MEDIA_UNKNOWN, "Picture is a null pointer"); + return GainMap::make_type_null(); + } +} + +static OHOS::Media::AuxiliaryPictureType ParseAuxiliaryPictureType(int32_t val) +{ + if (val >= static_cast(OHOS::Media::AuxiliaryPictureType::GAINMAP) + && val<= static_cast(OHOS::Media::AuxiliaryPictureType::FRAGMENT_MAP)) { + return OHOS::Media::AuxiliaryPictureType(val); + } + + return OHOS::Media::AuxiliaryPictureType::NONE; +} + +void PictureImpl::SetAuxiliaryPicture(AuxiliaryPictureType type, weak::AuxiliaryPicture auxiliaryPicture) +{ + IMAGE_LOGD("SetAuxiliaryPictureSync IN"); + + OHOS::Media::AuxiliaryPictureType auxType = ParseAuxiliaryPictureType(type.get_value()); + if (auxType == OHOS::Media::AuxiliaryPictureType::NONE) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, + "The type does not match the auxiliary picture type!"); + return; + } + + AuxiliaryPictureImpl* auxiliaryPictureImpl = + reinterpret_cast(auxiliaryPicture->GetImplPtr()); + if (auxiliaryPictureImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Fail to unwrap AuxiliaryPictureImpl!"); + return; + } + + if (nativePicture_ != nullptr) { + auto auxiliaryPicturePtr = auxiliaryPictureImpl->GetNativeAuxiliaryPic(); + if (auxiliaryPicturePtr != nullptr) { + if (auxType != auxiliaryPicturePtr->GetAuxiliaryPictureInfo().auxiliaryPictureType) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, + "The type does not match the auxiliary picture type!"); + } else { + nativePicture_->SetAuxiliaryPicture(auxiliaryPicturePtr); + } + } else { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, + "Native auxiliary picture is nullptr!"); + } + } else { + ImageTaiheUtils::ThrowExceptionError("native picture is nullptr!"); + } +} + +AuxPicture PictureImpl::GetAuxiliaryPicture(AuxiliaryPictureType type) +{ + AuxPicture result = AuxPicture::make_type_null(); + + IMAGE_LOGD("GetAuxiliaryPicture IN"); + OHOS::Media::AuxiliaryPictureType auxType = ParseAuxiliaryPictureType(type.get_value()); + if (auxType == OHOS::Media::AuxiliaryPictureType::NONE) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, + "The type does not match the auxiliary picture type!"); + } + + if (nativePicture_ != nullptr) { + auto auxiliaryPic = nativePicture_->GetAuxiliaryPicture(auxType); + if (auxiliaryPic != nullptr) { + result = AuxPicture::make_type_auxPicture( + make_holder(std::move(auxiliaryPic))); + } else { + ImageTaiheUtils::ThrowExceptionError("native auxiliary picture is nullptr!"); + } + } else { + ImageTaiheUtils::ThrowExceptionError("native picture is nullptr!"); + } + + return result; +} + +void PictureImpl::SetMetadataSync(MetadataType metadataType, weak::Metadata metadata) +{ + IMAGE_LOGD("SetMetadata IN"); + if (nativePicture_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native picture"); + return; + } + + OHOS::Media::MetadataType type; + uint32_t typeValue = metadataType.get_value(); + if (typeValue == static_cast(OHOS::Media::MetadataType::EXIF)) { + type = OHOS::Media::MetadataType(typeValue); + } else { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_METADATA, "Unsupport MetadataType"); + return; + } + + MetadataImpl* metadataImpl = reinterpret_cast(metadata->GetImplPtr()); + if (metadataImpl == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Fail to unwrap MetadataImpl."); + return; + } + std::shared_ptr imageMetadata = metadataImpl->GetNativeMetadata(); + + int32_t status = nativePicture_->SetExifMetadata( + std::reinterpret_pointer_cast(imageMetadata)); + if (status != OHOS::Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Set Metadata failed!"); + } +} + +Metadata PictureImpl::GetMetadataSync(MetadataType metadataType) +{ + IMAGE_LOGD("GetMetadata IN"); + if (nativePicture_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError("Empty native picture"); + return make_holder(); + } + + uint32_t typeValue = metadataType.get_value(); + if (typeValue != static_cast(OHOS::Media::MetadataType::EXIF)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_UNSUPPORTED_METADATA, "Unsupport MetadataType"); + return make_holder(); + } + + auto imageMetadata = std::reinterpret_pointer_cast(nativePicture_->GetExifMetadata()); + if (imageMetadata == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERROR, "Get Metadata failed!"); + return make_holder(); + } + return make_holder(imageMetadata); +} + +static bool UnwarpMessageParcel(const uintptr_t& sequence, ani_long& nativePtr) { -#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) ani_env *env = ::taihe::get_env(); if (env == nullptr) { - ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Ani unwarp messageParcel failed."); - return; + IMAGE_LOGE("%{pubilc}s Get ani env failed.", __func__); + return false; } ani_object sequenceObj = reinterpret_cast(sequence); - ani_long nativePtr; if (ANI_OK != env->Object_GetFieldByName_Long(sequenceObj, "nativePtr", &nativePtr)) { + IMAGE_LOGE("%{pubilc}s Get messageParcel nativePtr failed.", __func__); + return false; + } + return true; +} + +void PictureImpl::Marshalling(uintptr_t sequence) +{ +#if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) + ani_long nativePtr; + if (!UnwarpMessageParcel(sequence, nativePtr)) { ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Marshalling picture unwrap failed."); return; } @@ -118,6 +311,39 @@ Picture CreatePictureByPixelMap(weak::PixelMap mainPixelmap) IMAGE_LOGI("CreatePicture OUT"); return make_holder(std::move(picture)); } + +Picture CreatePictureFromParcel(uintptr_t sequence) +{ + IMAGE_LOGD("Call CreatePictureFromParcel"); + + ani_long nativePtr; + if (!UnwarpMessageParcel(sequence, nativePtr)) { + ImageTaiheUtils::ThrowExceptionError(IMAGE_BAD_PARAMETER, "Fail to unwrap messageSequence"); + return make_holder(); + } + OHOS::MessageParcel* messageParcel = reinterpret_cast(nativePtr); + if (messageParcel == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IPC, "Get parcel failed"); + return make_holder(); + } + + OHOS::Media::PICTURE_ERR error; + auto picture = OHOS::Media::Picture::Unmarshalling(*messageParcel, error); + if (picture == nullptr) { + ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IPC, "Unmarshalling picture failed"); + return make_holder(); + } + std::shared_ptr picturePtr(picture); + return make_holder(std::move(picturePtr)); +} + +Picture CreatePictureByPtr(int64_t aniPtr) +{ + return make_holder(aniPtr); +} + } // namespace ANI::Image -TH_EXPORT_CPP_API_CreatePictureByPixelMap(CreatePictureByPixelMap); \ No newline at end of file +TH_EXPORT_CPP_API_CreatePictureByPixelMap(CreatePictureByPixelMap); +TH_EXPORT_CPP_API_CreatePictureFromParcel(CreatePictureFromParcel); +TH_EXPORT_CPP_API_CreatePictureByPtr(CreatePictureByPtr); \ No newline at end of file diff --git a/frameworks/kits/taihe/src/picture_taihe_ani.cpp b/frameworks/kits/taihe/src/picture_taihe_ani.cpp new file mode 100644 index 000000000..6bc9b95c1 --- /dev/null +++ b/frameworks/kits/taihe/src/picture_taihe_ani.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2025 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 "image_log.h" +#include "picture_taihe_ani.h" + +// This file is for legacy ANI backward compatibility + +namespace OHOS { +namespace Media { +ani_object PictureTaiheAni::CreateEtsPicture(ani_env *env, std::shared_ptr picture) +{ + std::unique_ptr pictureAni = std::make_unique(); + pictureAni->nativePicture_ = picture; + + ani_namespace imageNamespace; + if (env->FindNamespace("L@ohos/multimedia/image/image;", &imageNamespace) != ANI_OK) { + IMAGE_LOGE("%{public}s FindNamespace failed", __func__); + return nullptr; + } + + ani_function createFunc; + if (env->Namespace_FindFunction(imageNamespace, "createPictureByPtr", nullptr, &createFunc) != ANI_OK) { + IMAGE_LOGE("%{public}s Namespace_FindFunction failed", __func__); + return nullptr; + } + + ani_ref pictureObj; + if (env->Function_Call_Ref(createFunc, &pictureObj, reinterpret_cast(pictureAni.get())) != ANI_OK) { + IMAGE_LOGE("%{public}s Function_Call_Ref failed", __func__); + return nullptr; + } + + pictureAni.release(); + return reinterpret_cast(pictureObj); +} +} // namespace Media +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index 58b784556..25c872799 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ani_color_space_object_convertor.h" #include "image_log.h" #include "image_taihe_utils.h" #include "media_errors.h" @@ -447,6 +448,76 @@ void PixelMapImpl::SetMemoryNameSync(string_view name) } } +void PixelMapImpl::ToSdrSync() +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "Internal error."); + return; + } + + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "Pixelmap is not editable"); + return; + } + + uint32_t status = nativePixelMap_->ToSdr(); + if (status != Media::SUCCESS) { + if (status == Media::ERR_MEDIA_INVALID_OPERATION) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "The pixelmap is not hdr."); + } else if (status == Media::IMAGE_RESULT_GET_SURFAC_FAILED) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "Alloc new memory failed."); + } else if (status == Media::ERR_RESOURCE_UNAVAILABLE) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "Pixelmap is not editable"); + } else { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_MEDIA_INVALID_OPERATION, "Internal error."); + } + } +} + +static uint32_t ParseColorSpace(std::shared_ptr &colorSpace, + uintptr_t targetColorSpace) +{ +#ifdef IMAGE_COLORSPACE_FLAG + ani_object obj = reinterpret_cast(targetColorSpace); + colorSpace = OHOS::ColorManager::GetColorSpaceByAniObject(get_env(), obj); + if (colorSpace == nullptr) { + return Media::ERR_IMAGE_INVALID_PARAMETER; + } + return Media::SUCCESS; +#else + return Media::ERR_IMAGE_DATA_UNSUPPORT; +#endif +} + +void PixelMapImpl::ApplyColorSpaceSync(uintptr_t targetColorSpace) +{ + if (nativePixelMap_ == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INIT_ABNORMAL, "Internal error."); + return; + } + + if (!aniEditable_) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_RESOURCE_UNAVAILABLE, "Pixelmap is not editable"); + return; + } + std::shared_ptr colorSpace; + uint32_t status = ParseColorSpace(colorSpace, targetColorSpace); + if (status != Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(status, "ParseColorSpace failed"); + return; + } + + if (colorSpace == nullptr) { + ImageTaiheUtils::ThrowExceptionError(Media::ERR_IMAGE_INIT_ABNORMAL, "ApplyColorSpace Null native ref"); + return; + } + status = nativePixelMap_->ApplyColorSpace(*colorSpace); + if (status != Media::SUCCESS) { + ImageTaiheUtils::ThrowExceptionError(status, "ApplyColorSpace has failed!"); + return; + } +} + void PixelMapImpl::ReleaseSync() { if (nativePixelMap_ != nullptr) { -- Gitee From f4d45c766fe8f65fc1c242de272e7aa2aa94e366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 18 Jun 2025 17:45:37 +0800 Subject: [PATCH 35/53] =?UTF-8?q?=E6=9B=BF=E6=8D=A2=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E7=AD=BE=E5=90=8D=E6=9E=84=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 1 + frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index fd8b9d6af..790caac34 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -92,6 +92,7 @@ taihe_shared_library("image_taihe") { "graphic_2d:librender_service_client", "hilog:libhilog", "hitrace:hitrace_meter", + "runtime_core:ani_helpers", "skia:libjpeg", ] diff --git a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp index 83361cc12..5da8a3a5c 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe_ani.cpp @@ -14,6 +14,8 @@ */ #include "pixel_map_taihe_ani.h" + +#include #include "pixel_map_taihe.h" // This file is for legacy ANI backward compatibility @@ -21,14 +23,16 @@ namespace OHOS { namespace Media { using namespace ANI::Image; +using namespace arkts; ani_object PixelMapTaiheAni::CreateEtsPixelMap([[maybe_unused]] ani_env* env, std::shared_ptr pixelMap) { std::unique_ptr pixelMapAni = std::make_unique(); pixelMapAni->nativePixelMap_ = pixelMap; + ani_signature::Namespace ns = ani_signature::Builder::BuildNamespace("@ohos.multimedia.image.image"); ani_namespace imageNamespace; - if (env->FindNamespace("L@ohos/multimedia/image/image;", &imageNamespace) != ANI_OK) { + if (env->FindNamespace(ns.Descriptor().c_str(), &imageNamespace) != ANI_OK) { return nullptr; } ani_function createFunc; @@ -45,12 +49,15 @@ ani_object PixelMapTaiheAni::CreateEtsPixelMap([[maybe_unused]] ani_env* env, st std::shared_ptr PixelMapTaiheAni::GetNativePixelMap([[maybe_unused]] ani_env* env, ani_object obj) { + ani_signature::Type cls = ani_signature::Builder::BuildClass("@ohos.multimedia.image.image.PixelMap"); ani_class pixelMapCls; - if (env->FindClass("L@ohos/multimedia/image/image/PixelMap;", &pixelMapCls) != ANI_OK) { + if (env->FindClass(cls.Descriptor().c_str(), &pixelMapCls) != ANI_OK) { return nullptr; } + ani_signature::SignatureBuilder sb{}; ani_method getMethod; - if (env->Class_FindMethod(pixelMapCls, "getImplPtr", ":J", &getMethod) != ANI_OK) { + sb.SetReturnLong(); + if (env->Class_FindMethod(pixelMapCls, "getImplPtr", sb.BuildSignatureDescriptor().c_str(), &getMethod) != ANI_OK) { return nullptr; } ani_long implPtr; -- Gitee From fbed6c91e8f4210a9a9e76f41a1dc300e0cc84d7 Mon Sep 17 00:00:00 2001 From: kurnevichstanislav Date: Mon, 16 Jun 2025 20:30:15 +0300 Subject: [PATCH 36/53] Migrate to hybrid libarkruntime.so Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICGHB6 Signed-off-by: kurnevichstanislav Change-Id: Icde56ad4ec719a57363e88c7571d1b8e31e00f8c --- interfaces/kits/js/common/BUILD.gn | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interfaces/kits/js/common/BUILD.gn b/interfaces/kits/js/common/BUILD.gn index c45669728..d218cf667 100644 --- a/interfaces/kits/js/common/BUILD.gn +++ b/interfaces/kits/js/common/BUILD.gn @@ -276,7 +276,6 @@ if (use_clang_ios) { "ability_runtime:runtime", "c_utils:utils", "drivers_interface_display:display_commontype_idl_headers", - "ets_runtime:libark_jsruntime", "eventhandler:libeventhandler", "graphic_2d:2d_graphics", "graphic_2d:EGL", @@ -294,6 +293,11 @@ if (use_clang_ios) { "napi:ace_napi", "resource_management:librawfile", ] + if (defined(ark_hybrid) && ark_hybrid) { + external_deps += [ "runtime_core:libarkruntime" ] + } else { + external_deps += [ "ets_runtime:libark_jsruntime" ] + } public_external_deps = [ "graphic_2d:color_manager" ] -- Gitee From 5a78a1153a1f9317de987c22e5c70779802a4926 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Fri, 20 Jun 2025 09:44:18 +0800 Subject: [PATCH 37/53] Temporary revert int to number Signed-off-by: zhaona45 --- .../idl/ohos.multimedia.image.image.taihe | 120 +++++++++--------- .../kits/taihe/include/image_source_taihe.h | 4 +- .../kits/taihe/src/image_source_taihe.cpp | 24 ++-- 3 files changed, 76 insertions(+), 72 deletions(-) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 6a5d34cf6..e272d345f 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -43,8 +43,8 @@ enum ResolutionQuality: i32 { } struct Size { - width: i32; - height: i32; + width: f64; + height: f64; } enum PropertyKey: String { @@ -280,8 +280,8 @@ enum AllocatorType: i32 { struct Region { size: Size; - x: i32; - y: i32; + x: f64; + y: f64; } // Can't use struct because struct is copied instead of referenced, so data changes to "pixels" in C++ will not be reflected in ArkTS @@ -298,8 +298,8 @@ interface PositionArea { struct ImageInfo { size: Size; - density: i32; - stride: i32; + density: f64; + stride: f64; pixelFormat: PixelMapFormat; alphaType: AlphaType; mimeType: String; @@ -313,34 +313,34 @@ enum CropAndScaleStrategy: i32 { struct PackingOption { format: String; - quality: i32; - bufferSize: Optional; + quality: f64; + bufferSize: Optional; desiredDynamicRange: Optional; needsPackProperties: Optional; } struct PackingOptionsForSequence { - frameCount: i32; - delayTimeList: Array; - disposalTypes: Optional>; - loopCount: Optional; + frameCount: f64; + delayTimeList: Array; + disposalTypes: Optional>; + loopCount: Optional; } struct ImagePropertyOptions { - index: Optional; + index: Optional; defaultValue: Optional; } struct DecodingOptions { - index: Optional; - sampleSize: Optional; - rotate: Optional; + index: Optional; + sampleSize: Optional; + rotate: Optional; editable: Optional; desiredSize: Optional; desiredRegion: Optional; desiredPixelFormat: Optional; photoDesiredPixelFormat: Optional; // not exposed to the user - fitDensity: Optional; + fitDensity: Optional; fillColor: Optional; // not exposed to the user SVGResize: Optional; // not exposed to the user desiredColorSpace: Optional<@sts_type("colorSpaceManager.ColorSpaceManager") Opaque>; @@ -352,8 +352,8 @@ struct DecodingOptions { struct Component { @readonly componentType: ComponentType; - @readonly rowStride: i32; - @readonly pixelStride: i32; + @readonly rowStride: f64; + @readonly pixelStride: f64; @readonly byteBuffer: @arraybuffer Array; } @@ -367,37 +367,37 @@ struct InitializationOptions { } struct SourceOptions { - sourceDensity: i32; + sourceDensity: f64; sourcePixelFormat: Optional; sourceSize: Optional; } struct HdrStaticMetadata { - displayPrimariesX: Array; - displayPrimariesY: Array; - whitePointX: f32; - whitePointY: f32; - maxLuminance: f32; - minLuminance: f32; - maxContentLightLevel: f32; - maxFrameAverageLightLevel: f32; + displayPrimariesX: Array; + displayPrimariesY: Array; + whitePointX: f64; + whitePointY: f64; + maxLuminance: f64; + minLuminance: f64; + maxContentLightLevel: f64; + maxFrameAverageLightLevel: f64; } struct GainmapChannel { - gainmapMax: f32; - gainmapMin: f32; - gamma: f32; - baseOffset: f32; - alternateOffset: f32; + gainmapMax: f64; + gainmapMin: f64; + gamma: f64; + baseOffset: f64; + alternateOffset: f64; } struct HdrGainmapMetadata { - writerVersion: i32; - miniVersion: i32; - gainmapChannelCount: i32; + writerVersion: f64; + miniVersion: f64; + gainmapChannelCount: f64; useBaseColorFlag: bool; - baseHeadroom: f32; - alternateHeadroom: f32; + baseHeadroom: f64; + alternateHeadroom: f64; channels: Array; } @@ -442,7 +442,7 @@ struct DecodingOptionsForPicture { struct AuxiliaryPictureInfo { auxiliaryPictureType: AuxiliaryPictureType; size: Size; - rowStride: i32; + rowStride: f64; pixelFormat: PixelMapFormat; colorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque; } @@ -610,14 +610,14 @@ interface ImageSource { GetImplPtr(): i64; @gen_async("getImageInfo") @gen_promise("getImageInfoPromiseWithIndex") - GetImageInfoSyncWithIndex(index: u32): ImageInfo; + GetImageInfoSyncWithIndex(index: f64): ImageInfo; @gen_async("getImageInfo") @gen_promise("getImageInfoPromise") GetImageInfoSync(): ImageInfo; - @!sts_inject_into_interface("getImageInfoSync(index: int | undefined): ImageInfo;") - @!sts_inject_into_class("""getImageInfoSync(index: int | undefined): ImageInfo { + @!sts_inject_into_interface("getImageInfoSync(index: double | undefined): ImageInfo;") + @!sts_inject_into_class("""getImageInfoSync(index: double | undefined): ImageInfo { if (index === undefined) { return this.getImageInfoSync(); } else { @@ -626,8 +626,8 @@ interface ImageSource { } """) - @!sts_inject_into_interface("getImageInfo(index: int | undefined): Promise;") - @!sts_inject_into_class("""getImageInfo(index: int | undefined): Promise { + @!sts_inject_into_interface("getImageInfo(index: double | undefined): Promise;") + @!sts_inject_into_class("""getImageInfo(index: double | undefined): Promise { if (index === undefined) { return this.getImageInfoPromise(); } else { @@ -678,14 +678,14 @@ interface ImageSource { @gen_async("getDelayTimeList") @gen_promise("getDelayTimeList") - GetDelayTimeListSync(): Array; + GetDelayTimeListSync(): Array; @gen_promise("getDisposalTypeList") - GetDisposalTypeListSync(): Array; + GetDisposalTypeListSync(): Array; @gen_async("getFrameCount") @gen_promise("getFrameCount") - GetFrameCountSync(): i32; + GetFrameCountSync(): f64; @gen_promise("getImageProperty") GetImagePropertySync(key: PropertyKey, options: Optional): String; @@ -701,7 +701,7 @@ interface ImageSource { @gen_async("updateData") @gen_promise("updateData") - UpdateDataSync(buf: @arraybuffer Array, isFinished: bool, offset: i32, length: i32): void; + UpdateDataSync(buf: @arraybuffer Array, isFinished: bool, offset: f64, length: f64): void; @gen_async("release") @gen_promise("release") @@ -725,17 +725,17 @@ interface ImagePacker { @gen_async("packToFile") @gen_promise("packToFile") - PackImageSourceToFileSync(source: ImageSource, fd: i32, options: PackingOption): void; + PackImageSourceToFileSync(source: ImageSource, fd: f64, options: PackingOption): void; @gen_async("packToFile") @gen_promise("packToFile") - PackPixelMapToFileSync(source: PixelMap, fd: i32, options: PackingOption): void; + PackPixelMapToFileSync(source: PixelMap, fd: f64, options: PackingOption): void; @gen_promise("packToFileFromPixelmapSequence") - PackToFileFromPixelmapSequenceSync(pixelmapSequence: Array, fd: i32, options: PackingOptionsForSequence): void; + PackToFileFromPixelmapSequenceSync(pixelmapSequence: Array, fd: f64, options: PackingOptionsForSequence): void; @gen_promise("packToFile") - PackPictureToFileSync(picture: Picture, fd: i32, options: PackingOption): void; + PackPictureToFileSync(picture: Picture, fd: f64, options: PackingOption): void; @gen_promise("packing") PackingPictureSync(picture: Picture, options: PackingOption): @arraybuffer Array; @@ -752,8 +752,8 @@ interface Image { GetImplPtr(): i64; @get("size") GetSize(): Size; - @get("format") GetFormat(): i32; - @get("timestamp") GetTimestamp(): i64; + @get("format") GetFormat(): f64; + @get("timestamp") GetTimestamp(): f64; @gen_async("getComponent") @gen_promise("getComponent") @@ -766,7 +766,7 @@ interface Image { interface ImageReceiver { @get GetSize(): Size; - @get GetCapacity(): i32; + @get GetCapacity(): f64; @get GetFormat(): ImageFormat; @gen_async("getReceivingSurfaceId") @@ -810,7 +810,7 @@ interface ImageReceiver { } interface ImageCreator { - @get("capacity") GetCapacity(): i32; + @get("capacity") GetCapacity(): f64; @get("format") GetFormat(): ImageFormat; @gen_async("queueImage") @@ -874,10 +874,10 @@ function CreateImageSourceByUri(uri: String): ImageSource; function CreateImageSourceByUriOption(uri: String, options: SourceOptions): ImageSource; @overload("createImageSource") -function CreateImageSourceByFd(fd: i32): ImageSource; +function CreateImageSourceByFd(fd: f64): ImageSource; @overload("createImageSource") -function CreateImageSourceByFdOption(fd: i32, options: SourceOptions): ImageSource; +function CreateImageSourceByFdOption(fd: f64, options: SourceOptions): ImageSource; @overload("createImageSource") function CreateImageSourceByArrayBuffer(buf: @arraybuffer Array): ImageSource; @@ -899,9 +899,9 @@ function CreateImageSourceByPtr(ptr: i64): ImageSource; function CreateImagePacker(): ImagePacker; -function CreateImageCreator(size: Size, format: ImageFormat, capacity: i32): ImageCreator; +function CreateImageCreator(size: Size, format: ImageFormat, capacity: f64): ImageCreator; -function CreateImageReceiver(size: Size, format: ImageFormat, capacity: i32): ImageReceiver; +function CreateImageReceiver(size: Size, format: ImageFormat, capacity: f64): ImageReceiver; @overload("createPicture") function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h index d98ddb9c6..5c06fccf7 100644 --- a/frameworks/kits/taihe/include/image_source_taihe.h +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -45,8 +45,8 @@ public: array CreatePixelMapListSync(); array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); array CreatePixelMapListSyncWithOptionalOptions(optional_view options); - array GetDelayTimeListSync(); - array GetDisposalTypeListSync(); + array GetDelayTimeListSync(); + array GetDisposalTypeListSync(); int32_t GetFrameCountSync(); string GetImagePropertySync(PropertyKey key, optional_view options); map GetImagePropertiesSync(array_view key); diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index 2ef647e0f..bb70fa35c 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -394,6 +394,10 @@ static bool ParseDecodeOptions(DecodingOptions const& options, OHOS::Media::Deco std::string &errMsg) { if (options.index.has_value()) { + if (options.index.value() < 0) { + errMsg = "index is invalid value!"; + return false; + } index = options.index.value(); IMAGE_LOGD("index: %{public}d", index); } @@ -681,13 +685,13 @@ array ImageSourceImpl::CreatePixelMapListSyncWithOptionalOptions(optio return CreatePixelMapListSyncWithOptions(options.value_or(DecodingOptions {})); } -array ImageSourceImpl::GetDelayTimeListSync() +array ImageSourceImpl::GetDelayTimeListSync() { OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDelayTimeListSync"); if (nativeImgSrc == nullptr) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); - return array(0); + return array(0); } uint32_t errorCode = 0; @@ -696,19 +700,19 @@ array ImageSourceImpl::GetDelayTimeListSync() IMAGE_LOGE("Get DelayTime error, error=%{public}u", errorCode); ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, "Get DelayTime error"); - return array(0); + return array(0); } - - return array(taihe::copy_data_t{}, delayTimes->data(), delayTimes->size()); + std::vector result(delayTimes->begin(), delayTimes->end()); + return array(taihe::copy_data_t{}, result.begin(), result.size()); } -array ImageSourceImpl::GetDisposalTypeListSync() +array ImageSourceImpl::GetDisposalTypeListSync() { OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDisposalTypeListSync"); if (nativeImgSrc == nullptr) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); - return array(0); + return array(0); } uint32_t errorCode = 0; @@ -717,10 +721,10 @@ array ImageSourceImpl::GetDisposalTypeListSync() IMAGE_LOGE("Get DisposalType error, error=%{public}u", errorCode); ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, "Get DisposalType error"); - return array(0); + return array(0); } - - return array(taihe::copy_data_t{}, disposalTypeList->data(), disposalTypeList->size()); + std::vector result(disposalTypeList->begin(), disposalTypeList->end()); + return array(taihe::copy_data_t{}, result.begin(), result.size()); } int32_t ImageSourceImpl::GetFrameCountSync() -- Gitee From 5e61d194d58dd81f9f98f6f51e9c94c5bc084811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 25 Jun 2025 17:45:16 +0800 Subject: [PATCH 38/53] =?UTF-8?q?=E5=A4=AA=E5=92=8C=E6=8B=86=E5=88=86?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 63 ++++++++++++++++--- .../idl/ohos.multimedia.image.image.taihe | 2 +- 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index cc5115995..b93265efb 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -41,13 +41,11 @@ ohos_taihe("run_taihe") { ] } -taihe_shared_library("image_taihe") { +taihe_shared_library("image_taihe_core") { taihe_generated_file_path = "$taihe_generated_file_path" subsystem_name = "$subsystem_name" part_name = "$part_name" - public_configs = [ ":image_taihe_config" ] - include_dirs = [ "include", "${image_subsystem}/interfaces/innerkits/include", @@ -63,14 +61,11 @@ taihe_shared_library("image_taihe") { "src/image_packer_taihe.cpp", "src/image_receiver_taihe.cpp", "src/image_source_taihe.cpp", - "src/image_source_taihe_ani.cpp", "src/image_taihe.cpp", "src/image_taihe_utils.cpp", "src/metadata_taihe.cpp", "src/picture_taihe.cpp", - "src/picture_taihe_ani.cpp", "src/pixel_map_taihe.cpp", - "src/pixel_map_taihe_ani.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] @@ -82,10 +77,59 @@ taihe_shared_library("image_taihe") { deps = [ ":run_taihe", "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", - "$image_subsystem/frameworks/innerkitsimpl/utils:image_utils", - "$image_subsystem/interfaces/innerkits:image_native", + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + ] + + external_deps = [ + "c_utils:utils", + "eventhandler:libeventhandler", + "graphic_2d:ani_color_space_object_convertor", + "graphic_2d:color_manager", + "graphic_2d:EGL", + "graphic_2d:librender_service_client", + "hilog:libhilog", + "hitrace:hitrace_meter", + "skia:libjpeg", + ] + + if (!use_clang_android && !use_clang_ios) { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } +} + +# APIs exposed to external modules +ohos_shared_library("image_taihe") { + output_name = "libimage_taihe" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + + public_configs = [ ":image_taihe_config" ] + + include_dirs = [ + "$taihe_toolchain_path/include", + "$taihe_generated_file_path/include", ] + sources = [ + "src/image_source_taihe_ani.cpp", + "src/picture_taihe_ani.cpp", + "src/pixel_map_taihe_ani.cpp", + ] + + cflags = [ + "-DIMAGE_DEBUG_FLAG", + "-DIMAGE_COLORSPACE_FLAG", + ] + + deps = [ ":image_taihe_core" ] + external_deps = [ "c_utils:utils", "eventhandler:libeventhandler", @@ -95,6 +139,7 @@ taihe_shared_library("image_taihe") { "graphic_2d:librender_service_client", "hilog:libhilog", "hitrace:hitrace_meter", + "runtime_core:ani", "runtime_core:ani_helpers", "skia:libjpeg", ] @@ -131,7 +176,7 @@ ohos_prebuilt_etc("image_framework_etc") { group("image_framework_taihe") { deps = [ ":image_framework_etc", - ":image_taihe", + ":image_taihe_core", ] } diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 2f6b68527..e46338c93 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -16,7 +16,7 @@ @!namespace("@ohos.multimedia.image", "image") @!sts_inject(""" -static { loadLibrary("image_taihe.z"); } +static { loadLibrary("image_taihe_core.z"); } """) enum PixelMapFormat: i32 { -- Gitee From 02506c425ab79f718c430f7d587874c0f42bb3aa Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Wed, 25 Jun 2025 17:00:39 +0800 Subject: [PATCH 39/53] Temporary add negative number check Signed-off-by: zhaona45 Change-Id: Icc20b638ef2a8683dfd511c9236f286c03cb17fd --- frameworks/kits/taihe/include/image_source_taihe.h | 2 +- frameworks/kits/taihe/src/image_source_taihe.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h index 5c06fccf7..e6cd19038 100644 --- a/frameworks/kits/taihe/include/image_source_taihe.h +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -36,7 +36,7 @@ public: ~ImageSourceImpl(); int64_t GetImplPtr(); - ImageInfo GetImageInfoSyncWithIndex(uint32_t index); + ImageInfo GetImageInfoSyncWithIndex(int32_t index); ImageInfo GetImageInfoSync(); PixelMap CreatePixelMapSyncWithOptions(DecodingOptions const& options); PixelMap CreatePixelMapSync(); diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index bb70fa35c..24c821bce 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -180,7 +180,7 @@ int64_t ImageSourceImpl::GetImplPtr() return reinterpret_cast(this); } -ImageInfo ImageSourceImpl::GetImageInfoSyncWithIndex(uint32_t index) +ImageInfo ImageSourceImpl::GetImageInfoSyncWithIndex(int32_t index) { OHOS::Media::ImageInfo imageinfo; bool isHdr = false; @@ -199,13 +199,17 @@ ImageInfo ImageSourceImpl::GetImageInfoSyncWithIndex(uint32_t index) ImageInfo ImageSourceImpl::GetImageInfoSync() { - uint32_t index = 0; + int32_t index = 0; return GetImageInfoSyncWithIndex(index); } static bool ParseRotate(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst, std::string &errMsg) { if (options.rotate.has_value()) { + if (options.rotate.value() < 0) { + errMsg = "rotate is invalid value!"; + return false; + } dst.rotateNewDegrees = options.rotate.value(); if (dst.rotateNewDegrees >= 0 && dst.rotateNewDegrees <= 360) { // 360 is the maximum rotation angle. dst.rotateDegrees = static_cast(dst.rotateNewDegrees); -- Gitee From facc9205c07c9f91bc83bed1bd70e4af42802387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 25 Jun 2025 19:30:49 +0800 Subject: [PATCH 40/53] =?UTF-8?q?ANI=20=E6=8B=86=E5=88=86=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 42 ++++++++++++++++++- .../kits/ani/ets/@ohos.multimedia.image.ets | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index 9cd3dd0bc..d61489aad 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -21,11 +21,50 @@ config("ani_config") { group("image_framework_ani") { deps = [ - ":image_ani", + ":image_ani_core", ":image_framework_abc_etc", ] } +ohos_shared_library("image_ani_core") { + if (!use_clang_android) { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } + shlib_type = "ani" + include_dirs = [ "native/include" ] + sources = [ + "native/src/ani_image_module.cpp", + "native/src/image_ani_utils.cpp", + "native/src/image_packer_ani.cpp", + "native/src/image_source_ani.cpp", + "native/src/picture_ani.cpp", + "native/src/pixel_map_ani.cpp", + ] + deps = [ + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + "${image_subsystem}/interfaces/kits/js/common:image", + ] + external_deps = [ + "ability_runtime:ability_runtime", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "runtime_core:ani", + "runtime_core:libarkruntime", + ] + subsystem_name = "multimedia" + part_name = "image_framework" + output_extension = "so" +} + +# APIs exposed to external modules ohos_shared_library("image_ani") { public_configs = [ ":ani_config" ] if (!use_clang_android) { @@ -46,6 +85,7 @@ ohos_shared_library("image_ani") { "native/src/pixel_map_ani.cpp", ] deps = [ + ":image_ani_core", "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", "${image_subsystem}/interfaces/innerkits:image_native", "${image_subsystem}/interfaces/kits/js/common:image", diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 7e8008567..42b5bf657 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -17,7 +17,7 @@ import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; export namespace image { - loadLibrary("image_ani"); + loadLibrary("image_ani_core"); enum DecodingDynamicRange { AUTO = 0, -- Gitee From 1e5bdc9ae32f76c552d6e1021777a9d58d6e9453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 25 Jun 2025 20:03:30 +0800 Subject: [PATCH 41/53] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index d61489aad..69df77a35 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -35,7 +35,6 @@ ohos_shared_library("image_ani_core") { debug = false } } - shlib_type = "ani" include_dirs = [ "native/include" ] sources = [ "native/src/ani_image_module.cpp", -- Gitee From 20e8d47c5bbf789d83dd198bf2deb1dd135b4919 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Tue, 24 Jun 2025 09:25:55 +0800 Subject: [PATCH 42/53] 1. Fix ExifMetadatFormatter static variable lifetime Signed-off-by: zhaona45 Change-Id: I9798dc74aed7007e0125f12f2185cdd1aad5e12e --- .../include/exif_metadata_formatter.h | 82 +- .../accessor/src/exif_metadata_formatter.cpp | 717 +++++++++--------- 2 files changed, 404 insertions(+), 395 deletions(-) diff --git a/frameworks/innerkitsimpl/accessor/include/exif_metadata_formatter.h b/frameworks/innerkitsimpl/accessor/include/exif_metadata_formatter.h index 020d7febc..5333e5fda 100644 --- a/frameworks/innerkitsimpl/accessor/include/exif_metadata_formatter.h +++ b/frameworks/innerkitsimpl/accessor/include/exif_metadata_formatter.h @@ -31,6 +31,8 @@ using ValueFormatDelegate = std::pair Format(const std::string &keyName, const std::string &value); static int32_t Validate(const std::string &keyName, const std::string &value); static bool IsModifyAllowed(const std::string &keyName); @@ -40,6 +42,12 @@ public: static bool IsSensitiveInfo(const std::string &keyName); private: + ExifMetadatFormatter(); + void InitDelegates(); + void InitValueRangeValidateConfig(); + void InitValueFormatConvertConfig(); + void InitValueTemplateConfig(); + static int32_t ValidateValueRange(const std::string &keyName, const std::string &value); static void ConvertRangeValue(const std::string &keyName, std::string &value); static void ExtractValue(const std::string &keyName, std::string &value); @@ -73,43 +81,43 @@ private: static std::string GetFractionFromStr(const std::string &decimal, bool &isOutRange); static bool ValidDecimalRationalFormat(std::string &value); static bool ValidConvertRationalFormat(std::string &value); - static ValueFormatDelegate doubleIntToOneRationalWithComma; - static ValueFormatDelegate doubleIntWithBlank; - static ValueFormatDelegate doubleIntWithComma; - static ValueFormatDelegate doubleValueToRational; - static ValueFormatDelegate tribleIntWithBlank; - static ValueFormatDelegate tribleIntWithComma; - static ValueFormatDelegate fourIntWithBlank; - static ValueFormatDelegate fourIntWithComma; - static ValueFormatDelegate singleInt; - static ValueFormatDelegate singleRational; - static ValueFormatDelegate singleIntToRational; - static ValueFormatDelegate singleDecimalToRational; - static ValueFormatDelegate tribleRationalWithBlank; - static ValueFormatDelegate tribleIntToRationalWithBlank; - static ValueFormatDelegate tribleIntToRationalWithComma; - static ValueFormatDelegate tribleDecimalToRationalWithBlank; - static ValueFormatDelegate tribleDecimalToRatiionalWithComma; - static ValueFormatDelegate tribleMixToRationalWithComma; - static ValueFormatDelegate fourRationalWithBlank; - static ValueFormatDelegate fourIntToRationalWithBlank; - static ValueFormatDelegate fourIntToRationalWithComma; - static ValueFormatDelegate decimal4Ratiional4; - static ValueFormatDelegate fourDecimalToRationalWithComma; - static ValueFormatDelegate dateTimeValidation; - static ValueFormatDelegate dateValidation; - static ValueFormatDelegate tribleIntToRationalWithColon; - static ValueFormatDelegate fourIntWithDot; - static ValueFormatDelegate fourDecimalToRationalWithBlank; - static ValueFormatDelegate sixDecimalToRationalWithBlank; - static ValueFormatDelegate sixDecimalToRationalWithComma; - static ValueFormatDelegate timeStamp; - static ValueFormatDelegate version; - static ValueFormatDelegate channel; - static std::multimap valueFormatConvertConfig; - static std::multimap valueFormatValidateConfig; - static std::multimap valueTemplateConfig; - static std::map> valueRangeValidateConfig; + ValueFormatDelegate doubleIntToOneRationalWithComma_; + ValueFormatDelegate doubleIntWithBlank_; + ValueFormatDelegate doubleIntWithComma_; + ValueFormatDelegate doubleValueToRational_; + ValueFormatDelegate tribleIntWithBlank_; + ValueFormatDelegate tribleIntWithComma_; + ValueFormatDelegate fourIntWithBlank_; + ValueFormatDelegate fourIntWithComma_; + ValueFormatDelegate singleInt_; + ValueFormatDelegate singleRational_; + ValueFormatDelegate singleIntToRational_; + ValueFormatDelegate singleDecimalToRational_; + ValueFormatDelegate tribleRationalWithBlank_; + ValueFormatDelegate tribleIntToRationalWithBlank_; + ValueFormatDelegate tribleIntToRationalWithComma_; + ValueFormatDelegate tribleDecimalToRationalWithBlank_; + ValueFormatDelegate tribleDecimalToRatiionalWithComma_; + ValueFormatDelegate tribleMixToRationalWithComma_; + ValueFormatDelegate fourRationalWithBlank_; + ValueFormatDelegate fourIntToRationalWithBlank_; + ValueFormatDelegate fourIntToRationalWithComma_; + ValueFormatDelegate decimal4Ratiional4_; + ValueFormatDelegate fourDecimalToRationalWithComma_; + ValueFormatDelegate dateTimeValidation_; + ValueFormatDelegate dateValidation_; + ValueFormatDelegate tribleIntToRationalWithColon_; + ValueFormatDelegate fourIntWithDot_; + ValueFormatDelegate fourDecimalToRationalWithBlank_; + ValueFormatDelegate sixDecimalToRationalWithBlank_; + ValueFormatDelegate sixDecimalToRationalWithComma_; + ValueFormatDelegate timeStamp_; + ValueFormatDelegate version_; + ValueFormatDelegate channel_; + std::multimap valueFormatConvertConfig_; + std::multimap valueFormatValidateConfig_; + std::multimap valueTemplateConfig_; + std::map> valueRangeValidateConfig_; }; } // namespace Media } // namespace OHOS diff --git a/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp b/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp index 0f2cb6ea1..ccf930db7 100644 --- a/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp +++ b/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp @@ -544,50 +544,276 @@ constexpr TagDetails exifSensitivityType[] = { {7, "Standard output sensitivity (SOS) and recommended exposure index (REI) and ISO speed"}, }; +ExifMetadatFormatter &ExifMetadatFormatter::GetInstance() +{ + static ExifMetadatFormatter instance; + return instance; +} + +ExifMetadatFormatter::ExifMetadatFormatter() +{ + InitDelegates(); + InitValueRangeValidateConfig(); + InitValueFormatConvertConfig(); + InitValueTemplateConfig(); +} + // configuratioin for value range validation. For example GPSLatitudeRef the value must be 'N' or 'S'. -std::map> ExifMetadatFormatter::valueRangeValidateConfig = { - { "Orientation", std::make_tuple(exifOrientation, std::size(exifOrientation)) }, - { "GPSLatitudeRef", std::make_tuple(exifGPSLatitudeRef, std::size(exifGPSLatitudeRef)) }, - { "GPSDestLatitudeRef", std::make_tuple(exifGPSLatitudeRef, std::size(exifGPSLatitudeRef)) }, - { "GPSLongitudeRef", std::make_tuple(exifGPSLongitudeRef, std::size(exifGPSLongitudeRef)) }, - { "GPSDestLongitudeRef", std::make_tuple(exifGPSLongitudeRef, std::size(exifGPSLongitudeRef)) }, - { "WhiteBalance", std::make_tuple(exifWhiteBalance, std::size(exifWhiteBalance)) }, - { "Flash", std::make_tuple(exifFlash, std::size(exifFlash)) }, - { "LightSource", std::make_tuple(exifLightSource, std::size(exifLightSource)) }, - { "MeteringMode", std::make_tuple(exifMeteringMode, std::size(exifMeteringMode)) }, - { "SceneType", std::make_tuple(exifSceneType, std::size(exifSceneType)) }, - { "Compression", std::make_tuple(exifCompression, std::size(exifCompression)) }, - { "PhotometricInterpretation", - std::make_tuple(exifPhotometricInterpretation, std::size(exifPhotometricInterpretation)) }, - { "PlanarConfiguration", std::make_tuple(exifPlanarConfiguration, std::size(exifPlanarConfiguration)) }, - { "ResolutionUnit", std::make_tuple(exifUnit, std::size(exifUnit)) }, - { "YCbCrPositioning", std::make_tuple(exifYCbCrPositioning, std::size(exifYCbCrPositioning)) }, - { "ExposureProgram", std::make_tuple(exifExposureProgram, std::size(exifExposureProgram)) }, - { "ColorSpace", std::make_tuple(exifColorSpace, std::size(exifColorSpace)) }, - { "FocalPlaneResolutionUnit", std::make_tuple(exifUnit, std::size(exifUnit)) }, - { "SensingMethod", std::make_tuple(tiffSensingMethod, std::size(tiffSensingMethod)) }, - { "CustomRendered", std::make_tuple(exifCustomRendered, std::size(exifCustomRendered)) }, - { "ExposureMode", std::make_tuple(exifExposureMode, std::size(exifExposureMode)) }, - { "SceneCaptureType", std::make_tuple(exifSceneCaptureType, std::size(exifSceneCaptureType)) }, - { "GainControl", std::make_tuple(exifGainControl, std::size(exifGainControl)) }, - { "Contrast", std::make_tuple(exifNormalSoftHard, std::size(exifNormalSoftHard)) }, - { "Saturation", std::make_tuple(exifSaturation, std::size(exifSaturation)) }, - { "Sharpness", std::make_tuple(exifNormalSoftHard, std::size(exifNormalSoftHard)) }, - { "SubjectDistanceRange", std::make_tuple(exifSubjectDistanceRange, std::size(exifSubjectDistanceRange)) }, - { "GPSAltitudeRef", std::make_tuple(exifGPSAltitudeRef, std::size(exifGPSAltitudeRef)) }, - { "NewSubfileType", std::make_tuple(exifNewSubfileType, std::size(exifNewSubfileType)) }, - { "SubfileType", std::make_tuple(exifSubfileType, std::size(exifSubfileType)) }, - { "GPSStatus", std::make_tuple(exifGpsStatus, std::size(exifGpsStatus)) }, - { "GPSMeasureMode", std::make_tuple(exifGPSMeasureMode, std::size(exifGPSMeasureMode)) }, - { "GPSSpeedRef", std::make_tuple(exifGPSSpeedRef, std::size(exifGPSSpeedRef)) }, - { "GPSImgDirectionRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, - { "GPSTrackRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, - { "GPSDestBearingRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, - { "GPSDestDistanceRef", std::make_tuple(exifGPSDestDistanceRef, std::size(exifGPSDestDistanceRef)) }, - { "GPSDifferential", std::make_tuple(exifGPSDifferential, std::size(exifGPSDifferential)) }, - { "CompositeImage", std::make_tuple(exifCompositeImage, std::size(exifCompositeImage)) }, - { "SensitivityType", std::make_tuple(exifSensitivityType, std::size(exifSensitivityType)) }, -}; +void ExifMetadatFormatter::InitValueRangeValidateConfig() +{ + valueRangeValidateConfig_ = std::map>{ + { "Orientation", std::make_tuple(exifOrientation, std::size(exifOrientation)) }, + { "GPSLatitudeRef", std::make_tuple(exifGPSLatitudeRef, std::size(exifGPSLatitudeRef)) }, + { "GPSDestLatitudeRef", std::make_tuple(exifGPSLatitudeRef, std::size(exifGPSLatitudeRef)) }, + { "GPSLongitudeRef", std::make_tuple(exifGPSLongitudeRef, std::size(exifGPSLongitudeRef)) }, + { "GPSDestLongitudeRef", std::make_tuple(exifGPSLongitudeRef, std::size(exifGPSLongitudeRef)) }, + { "WhiteBalance", std::make_tuple(exifWhiteBalance, std::size(exifWhiteBalance)) }, + { "Flash", std::make_tuple(exifFlash, std::size(exifFlash)) }, + { "LightSource", std::make_tuple(exifLightSource, std::size(exifLightSource)) }, + { "MeteringMode", std::make_tuple(exifMeteringMode, std::size(exifMeteringMode)) }, + { "SceneType", std::make_tuple(exifSceneType, std::size(exifSceneType)) }, + { "Compression", std::make_tuple(exifCompression, std::size(exifCompression)) }, + { "PhotometricInterpretation", + std::make_tuple(exifPhotometricInterpretation, std::size(exifPhotometricInterpretation)) }, + { "PlanarConfiguration", std::make_tuple(exifPlanarConfiguration, std::size(exifPlanarConfiguration)) }, + { "ResolutionUnit", std::make_tuple(exifUnit, std::size(exifUnit)) }, + { "YCbCrPositioning", std::make_tuple(exifYCbCrPositioning, std::size(exifYCbCrPositioning)) }, + { "ExposureProgram", std::make_tuple(exifExposureProgram, std::size(exifExposureProgram)) }, + { "ColorSpace", std::make_tuple(exifColorSpace, std::size(exifColorSpace)) }, + { "FocalPlaneResolutionUnit", std::make_tuple(exifUnit, std::size(exifUnit)) }, + { "SensingMethod", std::make_tuple(tiffSensingMethod, std::size(tiffSensingMethod)) }, + { "CustomRendered", std::make_tuple(exifCustomRendered, std::size(exifCustomRendered)) }, + { "ExposureMode", std::make_tuple(exifExposureMode, std::size(exifExposureMode)) }, + { "SceneCaptureType", std::make_tuple(exifSceneCaptureType, std::size(exifSceneCaptureType)) }, + { "GainControl", std::make_tuple(exifGainControl, std::size(exifGainControl)) }, + { "Contrast", std::make_tuple(exifNormalSoftHard, std::size(exifNormalSoftHard)) }, + { "Saturation", std::make_tuple(exifSaturation, std::size(exifSaturation)) }, + { "Sharpness", std::make_tuple(exifNormalSoftHard, std::size(exifNormalSoftHard)) }, + { "SubjectDistanceRange", std::make_tuple(exifSubjectDistanceRange, std::size(exifSubjectDistanceRange)) }, + { "GPSAltitudeRef", std::make_tuple(exifGPSAltitudeRef, std::size(exifGPSAltitudeRef)) }, + { "NewSubfileType", std::make_tuple(exifNewSubfileType, std::size(exifNewSubfileType)) }, + { "SubfileType", std::make_tuple(exifSubfileType, std::size(exifSubfileType)) }, + { "GPSStatus", std::make_tuple(exifGpsStatus, std::size(exifGpsStatus)) }, + { "GPSMeasureMode", std::make_tuple(exifGPSMeasureMode, std::size(exifGPSMeasureMode)) }, + { "GPSSpeedRef", std::make_tuple(exifGPSSpeedRef, std::size(exifGPSSpeedRef)) }, + { "GPSImgDirectionRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, + { "GPSTrackRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, + { "GPSDestBearingRef", std::make_tuple(exifGPSDirRef, std::size(exifGPSDirRef)) }, + { "GPSDestDistanceRef", std::make_tuple(exifGPSDestDistanceRef, std::size(exifGPSDestDistanceRef)) }, + { "GPSDifferential", std::make_tuple(exifGPSDifferential, std::size(exifGPSDifferential)) }, + { "CompositeImage", std::make_tuple(exifCompositeImage, std::size(exifCompositeImage)) }, + { "SensitivityType", std::make_tuple(exifSensitivityType, std::size(exifSensitivityType)) }, + }; +} + +// configuration for value format validation. For example BitPerSample the value format should be 9 9 9 or 9,9,9 +void ExifMetadatFormatter::InitValueFormatConvertConfig() +{ + valueFormatConvertConfig_ = { + {"BitsPerSample", tribleIntWithBlank_}, + {"BitsPerSample", tribleIntWithComma_}, + {"CompressedBitsPerPixel", singleRational_}, + {"CompressedBitsPerPixel", singleIntToRational_}, + {"CompressedBitsPerPixel", singleDecimalToRational_}, + {"GPSLatitude", doubleIntToOneRationalWithComma_}, + {"GPSLatitude", tribleRationalWithBlank_}, + {"GPSLatitude", tribleIntToRationalWithBlank_}, + {"GPSLatitude", tribleIntToRationalWithComma_}, + {"GPSLatitude", tribleMixToRationalWithComma_}, + {"GPSLongitude", doubleIntToOneRationalWithComma_}, + {"GPSLongitude", tribleRationalWithBlank_}, + {"GPSLongitude", tribleIntToRationalWithBlank_}, + {"GPSLongitude", tribleIntToRationalWithComma_}, + {"GPSLongitude", tribleMixToRationalWithComma_}, + {"ApertureValue", singleRational_}, + {"ApertureValue", singleIntToRational_}, + {"ApertureValue", singleDecimalToRational_}, + {"DateTimeOriginal", dateTimeValidation_}, + {"DateTimeOriginal", dateValidation_}, + {"DateTime", dateTimeValidation_}, + {"DateTime", dateValidation_}, + {"ExposureBiasValue", singleRational_}, + {"ExposureBiasValue", singleIntToRational_}, + {"ExposureBiasValue", singleDecimalToRational_}, + {"ExposureTime", singleRational_}, + {"ExposureTime", singleIntToRational_}, + {"ExposureTime", singleDecimalToRational_}, + {"FNumber", singleRational_}, + {"FNumber", singleIntToRational_}, + {"FNumber", singleDecimalToRational_}, + {"FocalLength", singleRational_}, + {"FocalLength", singleIntToRational_}, + {"FocalLength", singleDecimalToRational_}, + {"GPSTimeStamp", tribleRationalWithBlank_}, + {"GPSTimeStamp", tribleIntToRationalWithBlank_}, + {"GPSTimeStamp", tribleIntToRationalWithColon_}, + {"GPSTimeStamp", timeStamp_}, + {"GPSDateStamp", dateValidation_}, + {"XResolution", singleRational_}, + {"XResolution", singleIntToRational_}, + {"XResolution", singleDecimalToRational_}, + {"YResolution", singleRational_}, + {"YResolution", singleIntToRational_}, + {"YResolution", singleDecimalToRational_}, + {"WhitePoint", singleRational_}, + {"WhitePoint", singleIntToRational_}, + {"WhitePoint", singleDecimalToRational_}, + {"WhitePoint", doubleValueToRational_}, + {"PrimaryChromaticities", singleRational_}, + {"PrimaryChromaticities", singleIntToRational_}, + {"PrimaryChromaticities", singleDecimalToRational_}, + {"YCbCrCoefficients", tribleRationalWithBlank_}, + {"YCbCrCoefficients", tribleIntToRationalWithBlank_}, + {"YCbCrCoefficients", tribleIntToRationalWithComma_}, + {"YCbCrCoefficients", tribleDecimalToRationalWithBlank_}, + {"YCbCrCoefficients", tribleDecimalToRatiionalWithComma_}, + {"ReferenceBlackWhite", singleRational_}, + {"ReferenceBlackWhite", singleIntToRational_}, + {"ReferenceBlackWhite", singleDecimalToRational_}, + {"ReferenceBlackWhite", sixDecimalToRationalWithComma_}, + {"ShutterSpeedValue", singleRational_}, + {"ShutterSpeedValue", singleIntToRational_}, + {"ShutterSpeedValue", singleDecimalToRational_}, + {"BrightnessValue", singleRational_}, + {"BrightnessValue", singleIntToRational_}, + {"BrightnessValue", singleDecimalToRational_}, + {"MaxApertureValue", singleRational_}, + {"MaxApertureValue", singleIntToRational_}, + {"MaxApertureValue", singleDecimalToRational_}, + {"SubjectDistance", singleRational_}, + {"SubjectDistance", singleIntToRational_}, + {"SubjectDistance", singleDecimalToRational_}, + {"FlashEnergy", singleRational_}, + {"FlashEnergy", singleIntToRational_}, + {"FlashEnergy", singleDecimalToRational_}, + {"FocalPlaneXResolution", singleRational_}, + {"FocalPlaneXResolution", singleIntToRational_}, + {"FocalPlaneXResolution", singleDecimalToRational_}, + {"FocalPlaneYResolution", singleRational_}, + {"FocalPlaneYResolution", singleIntToRational_}, + {"FocalPlaneYResolution", singleDecimalToRational_}, + {"ExposureIndex", singleRational_}, + {"ExposureIndex", singleIntToRational_}, + {"ExposureIndex", singleDecimalToRational_}, + {"DigitalZoomRatio", singleRational_}, + {"DigitalZoomRatio", singleIntToRational_}, + {"DigitalZoomRatio", singleDecimalToRational_}, + {"GPSAltitude", singleRational_}, + {"GPSAltitude", singleIntToRational_}, + {"GPSAltitude", singleDecimalToRational_}, + {"GPSDOP", singleRational_}, + {"GPSDOP", singleIntToRational_}, + {"GPSDOP", singleDecimalToRational_}, + {"GPSSpeed", singleRational_}, + {"GPSSpeed", singleIntToRational_}, + {"GPSSpeed", singleDecimalToRational_}, + {"GPSTrack", singleRational_}, + {"GPSTrack", singleIntToRational_}, + {"GPSTrack", singleDecimalToRational_}, + {"GPSImgDirection", singleRational_}, + {"GPSImgDirection", singleIntToRational_}, + {"GPSImgDirection", singleDecimalToRational_}, + {"GPSDestLatitude", tribleRationalWithBlank_}, + {"GPSDestLatitude", tribleIntToRationalWithBlank_}, + {"GPSDestLatitude", tribleIntToRationalWithComma_}, + {"GPSDestLongitude", tribleRationalWithBlank_}, + {"GPSDestLongitude", tribleIntToRationalWithBlank_}, + {"GPSDestLongitude", tribleIntToRationalWithComma_}, + {"GPSDestBearing", singleRational_}, + {"GPSDestBearing", singleIntToRational_}, + {"GPSDestBearing", singleDecimalToRational_}, + {"GPSDestDistance", singleRational_}, + {"GPSDestDistance", singleIntToRational_}, + {"GPSDestDistance", singleDecimalToRational_}, + {"GPSVersionID", fourIntWithDot_}, + {"CompressedBitsPerPixel", singleRational_}, + {"CompressedBitsPerPixel", singleIntToRational_}, + {"CompressedBitsPerPixel", singleDecimalToRational_}, + {"DNGVersion", fourIntWithBlank_}, + {"DNGVersion", fourIntWithComma_}, + {"DefaultCropSize", doubleIntWithBlank_}, + {"DefaultCropSize", doubleIntWithComma_}, + {"Gamma", singleRational_}, + {"Gamma", singleIntToRational_}, + {"Gamma", singleDecimalToRational_}, + {"GPSHPositioningError", singleRational_}, + {"GPSHPositioningError", singleIntToRational_}, + {"GPSHPositioningError", singleDecimalToRational_}, + {"LensSpecification", fourRationalWithBlank_}, + {"LensSpecification", fourIntToRationalWithBlank_}, + {"LensSpecification", fourIntToRationalWithComma_}, + {"LensSpecification", fourDecimalToRationalWithBlank_}, + {"LensSpecification", fourDecimalToRationalWithComma_}, + {"ReferenceBlackWhite", sixDecimalToRationalWithBlank_}, + {"SubjectLocation", doubleIntWithBlank_}, + {"SubjectLocation", doubleIntWithComma_}, + {"ImageLength", singleInt_}, + {"ImageWidth", singleInt_}, + {"ISOSpeedRatings", singleInt_}, + {"StandardOutputSensitivity", singleInt_}, + {"RecommendedExposureIndex", singleInt_}, + {"ISOSpeed", singleInt_}, + {"PixelXDimension", singleInt_}, + {"PixelYDimension", singleInt_}, + {"FocalLengthIn35mmFilm", singleInt_}, + {"StripOffsets", singleInt_}, + {"SamplesPerPixel", singleInt_}, + {"RowsPerStrip", singleInt_}, + {"StripByteCounts", singleInt_}, + {"ExifVersion", singleInt_}, + {"ExifVersion", version_}, + {"ISOSpeedLatitudeyyy", singleInt_}, + {"ISOSpeedLatitudezzz", singleInt_}, + {"ComponentsConfiguration", singleInt_}, + {"ComponentsConfiguration", channel_}, + {"PhotographicSensitivity", singleInt_}, + {"FlashpixVersion", singleInt_}, + {"FlashpixVersion", version_}, + {"PhotoMode", singleInt_}, + {"JPEGProc", singleInt_}, + {"HwMnoteCaptureMode", singleInt_}, + {"HwMnoteIsXmageSupported", singleInt_}, + {"HwMnoteXmageMode", singleInt_}, + {"HwMnoteXmageLeft", singleInt_}, + {"HwMnoteXmageTop", singleInt_}, + {"HwMnoteXmageRight", singleInt_}, + {"HwMnoteXmageBottom", singleInt_}, + {"HwMnoteCloudEnhancementMode", singleInt_}, + {"HwMnoteAiEdit", singleInt_}, + {"DateTimeDigitized", dateTimeValidation_}, + {"DateTimeDigitized", dateValidation_}, + {"OffsetTime", dateTimeValidation_}, + {"OffsetTime", dateValidation_}, + {"SubjectArea", doubleIntWithBlank_}, + {"SubjectArea", doubleIntWithComma_}, + {"SourceImageNumberOfCompositeImage", doubleIntWithBlank_}, + {"SourceImageNumberOfCompositeImage", doubleIntWithComma_}, + {"YCbCrSubSampling", doubleIntWithBlank_}, + {"YCbCrSubSampling", doubleIntWithComma_}, + {"MovingPhotoVersion", singleInt_}, + {"MicroVideoPresentationTimestampUS", singleInt_}, + }; +} + +void ExifMetadatFormatter::InitValueTemplateConfig() +{ + valueTemplateConfig_ = { + {"ExposureTime", "(\\d+/\\d+) sec\\."}, + {"ExposureTime", "(\\d+\\.\\d+|\\d+) sec\\."}, + {"FNumber", "f/(\\d+\\.\\d+)"}, + {"ApertureValue", "(\\d+\\.\\d+) EV \\(f/\\d+\\.\\d+\\)"}, + {"ExposureBiasValue", "(\\d+\\.\\d+) EV"}, + {"FocalLength", "(\\d+\\.\\d+) mm"}, + {"ShutterSpeedValue", "(\\d+\\.\\d+) EV \\(\\d+/\\d+ sec\\.\\)"}, + {"BrightnessValue", "(\\d+\\.\\d+) EV \\(\\d+\\.\\d+ cd/m\\^\\d+\\)"}, + {"MaxApertureValue", "(\\d+\\.\\d+) EV \\(f/\\d+\\.\\d+\\)"}, + {"SubjectDistance", "(\\d+\\.\\d+) m"}, + {"SubjectArea", "\\(x,y\\) = \\((\\d+,\\d+)\\)"}, + {"ExifVersion", "Exif Version ([0-9]{1,2}\\.[0-9]{1,2})"}, + {"FlashpixVersion", "FlashPix Version ([0-9]{1,2}\\.[0-9]{1,2})"}, + {"Copyright", "^(.*) \\(Photographer\\) \\- \\[None\\] \\(Editor\\)$"}, + }; +} const size_t DECIMAL_BASE = 10; const std::string COMMA_REGEX("\\,"), COLON_REGEX("\\:"), DOT_REGEX("\\."); @@ -964,332 +1190,124 @@ bool ExifMetadatFormatter::ValidRegexWithChannelFormat(std::string &value, const return true; } -bool ExifMetadatFormatter::ValidRegexWithGpsOneRationalFormat(std::string &value, const std::string ®ex) +void ExifMetadatFormatter::InitDelegates() { - IMAGE_LOGD("validate gps with one rational."); - if (!ValidRegex(value, regex)) { - return false; - } - std::vector vec; - SplitStr(value, ",", vec); - if (vec.size() != GPS_DEGREE_SIZE) { - IMAGE_LOGD("Gps degree data size is invalid."); - return false; - } - value = vec[0] + "/" + vec[1] + " 0/1 0/1"; - return true; -} + singleInt_ = std::make_pair(ValidRegex, SINGLE_INT_REGEX); -ValueFormatDelegate ExifMetadatFormatter::singleInt = - std::make_pair(ExifMetadatFormatter::ValidRegex, SINGLE_INT_REGEX); + // regex validation for two integer like DefaultCropSize 9 9 the format is [0-9]+ [0-9]+ + doubleIntWithBlank_ = std::make_pair(ValidRegex, DOUBLE_INT_WITH_BLANK_REGEX); -// regex validation for two integer like DefaultCropSize 9 9 the format is [0-9]+ [0-9]+ -ValueFormatDelegate ExifMetadatFormatter::doubleIntWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegex, DOUBLE_INT_WITH_BLANK_REGEX); + // regex validation for two integer with comma like BitPerSample 9,9 the format is [0-9]+,[0-9]+,[0-9]+ + doubleIntWithComma_ = std::make_pair(ValidRegexWithComma, DOUBLE_INT_WITH_COMMA_REGEX); -// regex validation for two integer with comma like BitPerSample 9,9 the format is [0-9]+,[0-9]+,[0-9]+ -ValueFormatDelegate ExifMetadatFormatter::doubleIntWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithComma, DOUBLE_INT_WITH_COMMA_REGEX); + // regex validation for three integer like BitPerSample 9 9 9 the format is [0-9]+ [0-9]+ [0-9]+ + tribleIntWithBlank_ = std::make_pair(ValidRegex, TRIBLE_INT_WITH_BLANK_REGEX); -// regex validation for three integer like BitPerSample 9 9 9 the format is [0-9]+ [0-9]+ [0-9]+ -ValueFormatDelegate ExifMetadatFormatter::tribleIntWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegex, TRIBLE_INT_WITH_BLANK_REGEX); + // regex validation for three integer with comma like BitPerSample 9,9,0 the format is [0-9]+,[0-9]+,[0-9]+,[0-9]+ + tribleIntWithComma_ = std::make_pair(ValidRegexWithComma, TRIBLE_INT_WITH_COMMA_REGEX); -// regex validation for three integer with comma like BitPerSample 9,9,0 the format is [0-9]+,[0-9]+,[0-9]+,[0-9]+ -ValueFormatDelegate ExifMetadatFormatter::tribleIntWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithComma, TRIBLE_INT_WITH_COMMA_REGEX); + // regex validation for four integer like DNGVersion 9 9 9 9 the format is [0-9]+ [0-9]+ [0-9]+ [0-9]+ + fourIntWithBlank_ = std::make_pair(ValidRegex, FOUR_INT_WITH_BLANK_REGEX); -// regex validation for four integer like DNGVersion 9 9 9 9 the format is [0-9]+ [0-9]+ [0-9]+ [0-9]+ -ValueFormatDelegate ExifMetadatFormatter::fourIntWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegex, FOUR_INT_WITH_BLANK_REGEX); + // regex validation for four integer with comma like DNGVersion tag encodes the DNG four-tier version number + fourIntWithComma_ = std::make_pair(ValidRegexWithComma, FOUR_INT_WITH_COMMA_REGEX); -// regex validation for four integer with comma like DNGVersion tag encodes the DNG four-tier version number -ValueFormatDelegate ExifMetadatFormatter::fourIntWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithComma, FOUR_INT_WITH_COMMA_REGEX); + // regex validation for one rational like ApertureValue 4/1 the format is [0-9]+/[1-9][0-9] + singleRational_ = std::make_pair(ValidRegex, SINGLE_RATIONAL_REGEX); -// regex validation for one rational like ApertureValue 4/1 the format is [0-9]+/[1-9][0-9] -ValueFormatDelegate ExifMetadatFormatter::singleRational = - std::make_pair(ExifMetadatFormatter::ValidRegex, SINGLE_RATIONAL_REGEX); + // regex validation for integer and convert it to rational like ApertureValue 4 --> 4/1 + singleIntToRational_ = std::make_pair(ValidRegexWithRationalFormat, SINGLE_INT_REGEX); -// regex validation for integer and convert it to rational like ApertureValue 4 --> 4/1 -ValueFormatDelegate ExifMetadatFormatter::singleIntToRational = - std::make_pair(ExifMetadatFormatter::ValidRegexWithRationalFormat, SINGLE_INT_REGEX); + singleDecimalToRational_ = std::make_pair(ValidRegexWithDecimalRationalFormat, SINGLE_DECIMAL_REGEX); -ValueFormatDelegate ExifMetadatFormatter::singleDecimalToRational = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, SINGLE_DECIMAL_REGEX); + doubleIntToOneRationalWithComma_ = std::make_pair(ValidRegexWithGpsOneRationalFormat, DOUBLE_INT_WITH_COMMA_REGEX); -ValueFormatDelegate ExifMetadatFormatter::doubleIntToOneRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithGpsOneRationalFormat, DOUBLE_INT_WITH_COMMA_REGEX); + doubleValueToRational_ = std::make_pair(ValidRegxAndConvertRationalFormat, DOUBLE_VALUE_REGEX); -ValueFormatDelegate ExifMetadatFormatter::doubleValueToRational = - std::make_pair(ExifMetadatFormatter::ValidRegxAndConvertRationalFormat, DOUBLE_VALUE_REGEX); + // regex validation for three rational like GPSLatitude 39/1 54/1 20/1 + tribleRationalWithBlank_ = std::make_pair(ValidRegex, TRIBLE_RATIONAL_WITH_BLANK_REGEX); -// regex validation for three rational like GPSLatitude 39/1 54/1 20/1 -ValueFormatDelegate ExifMetadatFormatter::tribleRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegex, TRIBLE_RATIONAL_WITH_BLANK_REGEX); + // regex validation for three integer and convert to three rational like GPSLatitude 39 54 20 --> 39/1 54/1 20/1 + tribleIntToRationalWithBlank_ = std::make_pair(ValidRegexWithRationalFormat, TRIBLE_INT_WITH_BLANK_REGEX); -// regex validation for three integer and convert to three rational like GPSLatitude 39 54 20 --> 39/1 54/1 20/1 -ValueFormatDelegate ExifMetadatFormatter::tribleIntToRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegexWithRationalFormat, TRIBLE_INT_WITH_BLANK_REGEX); + // regex validation for three integer with comma like GPSLatitude 39,54,20 --> 39/1 54/1 20/1 + tribleIntToRationalWithComma_ = std::make_pair(ValidRegexWithCommaRationalFormat, TRIBLE_INT_WITH_COMMA_REGEX); -// regex validation for three integer with comma like GPSLatitude 39,54,20 --> 39/1 54/1 20/1 -ValueFormatDelegate ExifMetadatFormatter::tribleIntToRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithCommaRationalFormat, TRIBLE_INT_WITH_COMMA_REGEX); + // regex validation for three decimal like YCbCrCoefficients 39.0 54 20.0 --> 39/1 54/1 20/1 + tribleDecimalToRationalWithBlank_ = + std::make_pair(ValidRegexWithDecimalRationalFormat, TRIBLE_DECIMAL_WITH_BLANK_REGEX); -// regex validation for three decimal like YCbCrCoefficients 39.0 54 20.0 --> 39/1 54/1 20/1 -ValueFormatDelegate ExifMetadatFormatter::tribleDecimalToRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, TRIBLE_DECIMAL_WITH_BLANK_REGEX); + // regex validation for three decimal like YCbCrCoefficients 39.0,54,20.0 --> 39.0 54 20.0 --> 39/1 54/1 20/1 + tribleDecimalToRatiionalWithComma_ = + std::make_pair(ValidRegxWithCommaDecimalRationalFormat, TRIBLE_DECIMAL_WITH_COMMA_REGEX); -// regex validation for three decimal like YCbCrCoefficients 39.0,54,20.0 --> 39.0 54 20.0 --> 39/1 54/1 20/1 -ValueFormatDelegate ExifMetadatFormatter::tribleDecimalToRatiionalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegxWithCommaDecimalRationalFormat, TRIBLE_DECIMAL_WITH_COMMA_REGEX); + // regex validation for three decimal like GPS 10, 20, 20.123 --> 10 20 20.123 --> 10/1 20/1 20.123/1 + tribleMixToRationalWithComma_ = + std::make_pair(ValidRegxWithCommaDecimalRationalFormat, TRIBLE_MIX_WITH_COMMA_REGEX); -// regex validation for three decimal like GPS 10, 20, 20.123 --> 10 20 20.123 --> 10/1 20/1 20.123/1 -ValueFormatDelegate ExifMetadatFormatter::tribleMixToRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegxWithCommaDecimalRationalFormat, TRIBLE_MIX_WITH_COMMA_REGEX); + // regex validation for four rational like LensSpecification 1/1 3/2 1/1 2/1 + fourRationalWithBlank_ = std::make_pair(ValidRegex, FOUR_RATIONAL_WITH_BLANK_REGEX); -// regex validation for four rational like LensSpecification 1/1 3/2 1/1 2/1 -ValueFormatDelegate ExifMetadatFormatter::fourRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegex, FOUR_RATIONAL_WITH_BLANK_REGEX); + // regex validation for four integer and convert to four rational like LensSpecification 1 3 1 2 --> 1/1 3/2 1/1 2/1 + fourIntToRationalWithBlank_ = std::make_pair(ValidRegexWithRationalFormat, FOUR_INT_WITH_BLANK_REGEX); -// regex validation for four integer and convert to four rational like LensSpecification 1 3 1 2 --> 1/1 3/2 1/1 2/1 -ValueFormatDelegate ExifMetadatFormatter::fourIntToRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegexWithRationalFormat, FOUR_INT_WITH_BLANK_REGEX); + // regex validation for four integer like LensSpecification 1,3,1,2 --> 1/1 3/2 1/1 2/1 + fourIntToRationalWithComma_ = std::make_pair(ValidRegexWithCommaRationalFormat, FOUR_INT_WITH_COMMA_REGEX); -// regex validation for four integer like LensSpecification 1,3,1,2 --> 1/1 3/2 1/1 2/1 -ValueFormatDelegate ExifMetadatFormatter::fourIntToRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithCommaRationalFormat, FOUR_INT_WITH_COMMA_REGEX); + // regex validation for four decimal like LensSpecification 1.0 3.0 1.0 2.0 --> 1/1 3/1 2/1 + fourDecimalToRationalWithBlank_ = + std::make_pair(ValidRegexWithDecimalRationalFormat, FOUR_DECIMAL_WITH_BLANK_REGEX); -// regex validation for four decimal like LensSpecification 1.0 3.0 1.0 2.0 --> 1/1 3/1 2/1 -ValueFormatDelegate ExifMetadatFormatter::fourDecimalToRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, FOUR_DECIMAL_WITH_BLANK_REGEX); + // regex validation for four decimal like LensSpecification 1.0,3.0,1.0,2.0 --> 1/1 3/1 2/1 + fourDecimalToRationalWithComma_ = + std::make_pair(ValidRegxWithCommaDecimalRationalFormat, FOUR_DECIMAL_WITH_COMMA_REGEX); -// regex validation for four decimal like LensSpecification 1.0,3.0,1.0,2.0 --> 1/1 3/1 2/1 -ValueFormatDelegate ExifMetadatFormatter::fourDecimalToRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegxWithCommaDecimalRationalFormat, FOUR_DECIMAL_WITH_COMMA_REGEX); + // regex validation for datetime format like DateTimeOriginal 2022:06:02 15:51:34 + dateTimeValidation_ = std::make_pair(ValidRegex, DATETIME_REGEX); -// regex validation for datetime format like DateTimeOriginal 2022:06:02 15:51:34 -ValueFormatDelegate ExifMetadatFormatter::dateTimeValidation = - std::make_pair(ExifMetadatFormatter::ValidRegex, DATETIME_REGEX); + // regex validation for datetime format like DateTimeOriginal 2022:06:02 + dateValidation_ = std::make_pair(ValidRegex, DATE_REGEX); -// regex validation for datetime format like DateTimeOriginal 2022:06:02 -ValueFormatDelegate ExifMetadatFormatter::dateValidation = std::make_pair(ExifMetadatFormatter::ValidRegex, DATE_REGEX); + // regex validation for three integer like GPSLatitude 39,54,21 --> 39/1 54/1 21/1 + tribleIntToRationalWithColon_ = + std::make_pair(ValidRegexWithColonRationalFormat, TRIBLE_INT_WITH_COLON_REGEX); -// regex validation for three integer like GPSLatitude 39,54,21 --> 39/1 54/1 21/1 -ValueFormatDelegate ExifMetadatFormatter::tribleIntToRationalWithColon = - std::make_pair(ExifMetadatFormatter::ValidRegexWithColonRationalFormat, TRIBLE_INT_WITH_COLON_REGEX); + timeStamp_ = std::make_pair(ValidRegexWithDecimalRationalFormat, TIMESTAMP_REGEX); -ValueFormatDelegate ExifMetadatFormatter::timeStamp = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, TIMESTAMP_REGEX); + // regex validation for fou integer with pointer like GPSVersionID + fourIntWithDot_ = std::make_pair(ValidRegexWithDot, TRIBLE_INT_WITH_DOT_REGEX); -// regex validation for fou integer with pointer like GPSVersionID -ValueFormatDelegate ExifMetadatFormatter::fourIntWithDot = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDot, TRIBLE_INT_WITH_DOT_REGEX); + sixDecimalToRationalWithBlank_ = std::make_pair(ValidRegexWithDecimalRationalFormat, SIX_DECIMAL_WITH_BLANK_REGEX); -ValueFormatDelegate ExifMetadatFormatter::sixDecimalToRationalWithBlank = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, SIX_DECIMAL_WITH_BLANK_REGEX); + sixDecimalToRationalWithComma_ = std::make_pair(ValidRegexWithDecimalRationalFormat, SIX_DECIMAL_WITH_COMMA_REGEX); -ValueFormatDelegate ExifMetadatFormatter::sixDecimalToRationalWithComma = - std::make_pair(ExifMetadatFormatter::ValidRegexWithDecimalRationalFormat, SIX_DECIMAL_WITH_COMMA_REGEX); + version_ = std::make_pair(ValidRegexWithVersionFormat, VERSION_REGEX); -ValueFormatDelegate ExifMetadatFormatter::version = - std::make_pair(ExifMetadatFormatter::ValidRegexWithVersionFormat, VERSION_REGEX); - -ValueFormatDelegate ExifMetadatFormatter::channel = - std::make_pair(ExifMetadatFormatter::ValidRegexWithChannelFormat, CHANNEL_REGEX); + channel_ = std::make_pair(ValidRegexWithChannelFormat, CHANNEL_REGEX); +} -// configuration for value format validation. For example BitPerSample the value format should be 9 9 9 or 9,9,9 -std::multimap ExifMetadatFormatter::valueFormatConvertConfig = { - {"BitsPerSample", tribleIntWithBlank}, - {"BitsPerSample", tribleIntWithComma}, - {"CompressedBitsPerPixel", singleRational}, - {"CompressedBitsPerPixel", singleIntToRational}, - {"CompressedBitsPerPixel", singleDecimalToRational}, - {"GPSLatitude", doubleIntToOneRationalWithComma}, - {"GPSLatitude", tribleRationalWithBlank}, - {"GPSLatitude", tribleIntToRationalWithBlank}, - {"GPSLatitude", tribleIntToRationalWithComma}, - {"GPSLatitude", tribleMixToRationalWithComma}, - {"GPSLongitude", doubleIntToOneRationalWithComma}, - {"GPSLongitude", tribleRationalWithBlank}, - {"GPSLongitude", tribleIntToRationalWithBlank}, - {"GPSLongitude", tribleIntToRationalWithComma}, - {"GPSLongitude", tribleMixToRationalWithComma}, - {"ApertureValue", singleRational}, - {"ApertureValue", singleIntToRational}, - {"ApertureValue", singleDecimalToRational}, - {"DateTimeOriginal", dateTimeValidation}, - {"DateTimeOriginal", dateValidation}, - {"DateTime", dateTimeValidation}, - {"DateTime", dateValidation}, - {"ExposureBiasValue", singleRational}, - {"ExposureBiasValue", singleIntToRational}, - {"ExposureBiasValue", singleDecimalToRational}, - {"ExposureTime", singleRational}, - {"ExposureTime", singleIntToRational}, - {"ExposureTime", singleDecimalToRational}, - {"FNumber", singleRational}, - {"FNumber", singleIntToRational}, - {"FNumber", singleDecimalToRational}, - {"FocalLength", singleRational}, - {"FocalLength", singleIntToRational}, - {"FocalLength", singleDecimalToRational}, - {"GPSTimeStamp", tribleRationalWithBlank}, - {"GPSTimeStamp", tribleIntToRationalWithBlank}, - {"GPSTimeStamp", tribleIntToRationalWithColon}, - {"GPSTimeStamp", timeStamp}, - {"GPSDateStamp", dateValidation}, - {"XResolution", singleRational}, - {"XResolution", singleIntToRational}, - {"XResolution", singleDecimalToRational}, - {"YResolution", singleRational}, - {"YResolution", singleIntToRational}, - {"YResolution", singleDecimalToRational}, - {"WhitePoint", singleRational}, - {"WhitePoint", singleIntToRational}, - {"WhitePoint", singleDecimalToRational}, - {"WhitePoint", doubleValueToRational}, - {"PrimaryChromaticities", singleRational}, - {"PrimaryChromaticities", singleIntToRational}, - {"PrimaryChromaticities", singleDecimalToRational}, - {"YCbCrCoefficients", tribleRationalWithBlank}, - {"YCbCrCoefficients", tribleIntToRationalWithBlank}, - {"YCbCrCoefficients", tribleIntToRationalWithComma}, - {"YCbCrCoefficients", tribleDecimalToRationalWithBlank}, - {"YCbCrCoefficients", tribleDecimalToRatiionalWithComma}, - {"ReferenceBlackWhite", singleRational}, - {"ReferenceBlackWhite", singleIntToRational}, - {"ReferenceBlackWhite", singleDecimalToRational}, - {"ReferenceBlackWhite", sixDecimalToRationalWithComma}, - {"ShutterSpeedValue", singleRational}, - {"ShutterSpeedValue", singleIntToRational}, - {"ShutterSpeedValue", singleDecimalToRational}, - {"BrightnessValue", singleRational}, - {"BrightnessValue", singleIntToRational}, - {"BrightnessValue", singleDecimalToRational}, - {"MaxApertureValue", singleRational}, - {"MaxApertureValue", singleIntToRational}, - {"MaxApertureValue", singleDecimalToRational}, - {"SubjectDistance", singleRational}, - {"SubjectDistance", singleIntToRational}, - {"SubjectDistance", singleDecimalToRational}, - {"FlashEnergy", singleRational}, - {"FlashEnergy", singleIntToRational}, - {"FlashEnergy", singleDecimalToRational}, - {"FocalPlaneXResolution", singleRational}, - {"FocalPlaneXResolution", singleIntToRational}, - {"FocalPlaneXResolution", singleDecimalToRational}, - {"FocalPlaneYResolution", singleRational}, - {"FocalPlaneYResolution", singleIntToRational}, - {"FocalPlaneYResolution", singleDecimalToRational}, - {"ExposureIndex", singleRational}, - {"ExposureIndex", singleIntToRational}, - {"ExposureIndex", singleDecimalToRational}, - {"DigitalZoomRatio", singleRational}, - {"DigitalZoomRatio", singleIntToRational}, - {"DigitalZoomRatio", singleDecimalToRational}, - {"GPSAltitude", singleRational}, - {"GPSAltitude", singleIntToRational}, - {"GPSAltitude", singleDecimalToRational}, - {"GPSDOP", singleRational}, - {"GPSDOP", singleIntToRational}, - {"GPSDOP", singleDecimalToRational}, - {"GPSSpeed", singleRational}, - {"GPSSpeed", singleIntToRational}, - {"GPSSpeed", singleDecimalToRational}, - {"GPSTrack", singleRational}, - {"GPSTrack", singleIntToRational}, - {"GPSTrack", singleDecimalToRational}, - {"GPSImgDirection", singleRational}, - {"GPSImgDirection", singleIntToRational}, - {"GPSImgDirection", singleDecimalToRational}, - {"GPSDestLatitude", tribleRationalWithBlank}, - {"GPSDestLatitude", tribleIntToRationalWithBlank}, - {"GPSDestLatitude", tribleIntToRationalWithComma}, - {"GPSDestLongitude", tribleRationalWithBlank}, - {"GPSDestLongitude", tribleIntToRationalWithBlank}, - {"GPSDestLongitude", tribleIntToRationalWithComma}, - {"GPSDestBearing", singleRational}, - {"GPSDestBearing", singleIntToRational}, - {"GPSDestBearing", singleDecimalToRational}, - {"GPSDestDistance", singleRational}, - {"GPSDestDistance", singleIntToRational}, - {"GPSDestDistance", singleDecimalToRational}, - {"GPSVersionID", fourIntWithDot}, - {"CompressedBitsPerPixel", singleRational}, - {"CompressedBitsPerPixel", singleIntToRational}, - {"CompressedBitsPerPixel", singleDecimalToRational}, - {"DNGVersion", fourIntWithBlank}, - {"DNGVersion", fourIntWithComma}, - {"DefaultCropSize", doubleIntWithBlank}, - {"DefaultCropSize", doubleIntWithComma}, - {"Gamma", singleRational}, - {"Gamma", singleIntToRational}, - {"Gamma", singleDecimalToRational}, - {"GPSHPositioningError", singleRational}, - {"GPSHPositioningError", singleIntToRational}, - {"GPSHPositioningError", singleDecimalToRational}, - {"LensSpecification", fourRationalWithBlank}, - {"LensSpecification", fourIntToRationalWithBlank}, - {"LensSpecification", fourIntToRationalWithComma}, - {"LensSpecification", fourDecimalToRationalWithBlank}, - {"LensSpecification", fourDecimalToRationalWithComma}, - {"ReferenceBlackWhite", sixDecimalToRationalWithBlank}, - {"SubjectLocation", doubleIntWithBlank}, - {"SubjectLocation", doubleIntWithComma}, - {"ImageLength", singleInt}, - {"ImageWidth", singleInt}, - {"ISOSpeedRatings", singleInt}, - {"StandardOutputSensitivity", singleInt}, - {"RecommendedExposureIndex", singleInt}, - {"ISOSpeed", singleInt}, - {"PixelXDimension", singleInt}, - {"PixelYDimension", singleInt}, - {"FocalLengthIn35mmFilm", singleInt}, - {"StripOffsets", singleInt}, - {"SamplesPerPixel", singleInt}, - {"RowsPerStrip", singleInt}, - {"StripByteCounts", singleInt}, - {"ExifVersion", singleInt}, - {"ExifVersion", version}, - {"ISOSpeedLatitudeyyy", singleInt}, - {"ISOSpeedLatitudezzz", singleInt}, - {"ComponentsConfiguration", singleInt}, - {"ComponentsConfiguration", channel}, - {"PhotographicSensitivity", singleInt}, - {"FlashpixVersion", singleInt}, - {"FlashpixVersion", version}, - {"PhotoMode", singleInt}, - {"JPEGProc", singleInt}, - {"HwMnoteCaptureMode", singleInt}, - {"HwMnoteIsXmageSupported", singleInt}, - {"HwMnoteXmageMode", singleInt}, - {"HwMnoteXmageLeft", singleInt}, - {"HwMnoteXmageTop", singleInt}, - {"HwMnoteXmageRight", singleInt}, - {"HwMnoteXmageBottom", singleInt}, - {"HwMnoteCloudEnhancementMode", singleInt}, - {"HwMnoteAiEdit", singleInt}, - {"DateTimeDigitized", dateTimeValidation}, - {"DateTimeDigitized", dateValidation}, - {"OffsetTime", dateTimeValidation}, - {"OffsetTime", dateValidation}, - {"SubjectArea", doubleIntWithBlank}, - {"SubjectArea", doubleIntWithComma}, - {"SourceImageNumberOfCompositeImage", doubleIntWithBlank}, - {"SourceImageNumberOfCompositeImage", doubleIntWithComma}, - {"YCbCrSubSampling", doubleIntWithBlank}, - {"YCbCrSubSampling", doubleIntWithComma}, - {"MovingPhotoVersion", singleInt}, - {"MicroVideoPresentationTimestampUS", singleInt}, -}; +bool ExifMetadatFormatter::ValidRegexWithGpsOneRationalFormat(std::string &value, const std::string ®ex) +{ + IMAGE_LOGD("validate gps with one rational."); + if (!ValidRegex(value, regex)) { + return false; + } + std::vector vec; + SplitStr(value, ",", vec); + if (vec.size() != GPS_DEGREE_SIZE) { + IMAGE_LOGD("Gps degree data size is invalid."); + return false; + } + value = vec[0] + "/" + vec[1] + " 0/1 0/1"; + return true; +} // validate the value range. For example GPSLatitudeRef the value must be 'N' or 'S'. int32_t ExifMetadatFormatter::ValidateValueRange(const std::string &keyName, const std::string &value) { // 1. to find if any value range validation configuratiion according to exif tag in std::map container - auto iter = valueRangeValidateConfig.find(keyName); - if (iter == valueRangeValidateConfig.end()) { + auto iter = ExifMetadatFormatter::GetInstance().valueRangeValidateConfig_.find(keyName); + if (iter == ExifMetadatFormatter::GetInstance().valueRangeValidateConfig_.end()) { // if no range validation for key default is success. return Media::SUCCESS; } @@ -1338,8 +1356,8 @@ void ExifMetadatFormatter::ConvertRangeValue(const std::string &keyName, std::st value = "3"; return; } - auto iter = valueRangeValidateConfig.find(keyName); - if (iter == valueRangeValidateConfig.end()) { + auto iter = ExifMetadatFormatter::GetInstance().valueRangeValidateConfig_.find(keyName); + if (iter == ExifMetadatFormatter::GetInstance().valueRangeValidateConfig_.end()) { return; } @@ -1376,31 +1394,14 @@ bool ExifMetadatFormatter::IsForbiddenValue(const std::string &value) return false; } -std::multimap ExifMetadatFormatter::valueTemplateConfig = { - {"ExposureTime", "(\\d+/\\d+) sec\\."}, - {"ExposureTime", "(\\d+\\.\\d+|\\d+) sec\\."}, - {"FNumber", "f/(\\d+\\.\\d+)"}, - {"ApertureValue", "(\\d+\\.\\d+) EV \\(f/\\d+\\.\\d+\\)"}, - {"ExposureBiasValue", "(\\d+\\.\\d+) EV"}, - {"FocalLength", "(\\d+\\.\\d+) mm"}, - {"ShutterSpeedValue", "(\\d+\\.\\d+) EV \\(\\d+/\\d+ sec\\.\\)"}, - {"BrightnessValue", "(\\d+\\.\\d+) EV \\(\\d+\\.\\d+ cd/m\\^\\d+\\)"}, - {"MaxApertureValue", "(\\d+\\.\\d+) EV \\(f/\\d+\\.\\d+\\)"}, - {"SubjectDistance", "(\\d+\\.\\d+) m"}, - {"SubjectArea", "\\(x,y\\) = \\((\\d+,\\d+)\\)"}, - {"ExifVersion", "Exif Version ([0-9]{1,2}\\.[0-9]{1,2})"}, - {"FlashpixVersion", "FlashPix Version ([0-9]{1,2}\\.[0-9]{1,2})"}, - {"Copyright", "^(.*) \\(Photographer\\) \\- \\[None\\] \\(Editor\\)$"}, -}; - void ExifMetadatFormatter::ExtractValue(const std::string &keyName, std::string &value) { - auto it = ExifMetadatFormatter::valueTemplateConfig.find(keyName); - if (it == ExifMetadatFormatter::valueTemplateConfig.end()) { + auto it = ExifMetadatFormatter::GetInstance().valueTemplateConfig_.find(keyName); + if (it == ExifMetadatFormatter::GetInstance().valueTemplateConfig_.end()) { return; } - for (; it != ExifMetadatFormatter::valueTemplateConfig.end() && - it != ExifMetadatFormatter::valueTemplateConfig.upper_bound(keyName); + for (; it != ExifMetadatFormatter::GetInstance().valueTemplateConfig_.end() && + it != ExifMetadatFormatter::GetInstance().valueTemplateConfig_.upper_bound(keyName); it++) { std::regex pattern(it->second); for (std::sregex_iterator i = std::sregex_iterator(value.begin(), value.end(), pattern); @@ -1425,16 +1426,16 @@ int32_t ExifMetadatFormatter::ConvertValueFormat(const std::string &keyName, std IMAGE_LOGD("ConvertValueFormat keyName is [%{public}s] value is [%{public}s].", keyName.c_str(), value.c_str()); } - auto it = ExifMetadatFormatter::valueFormatConvertConfig.find(keyName); - if (it == ExifMetadatFormatter::valueFormatConvertConfig.end()) { + auto it = ExifMetadatFormatter::GetInstance().valueFormatConvertConfig_.find(keyName); + if (it == ExifMetadatFormatter::GetInstance().valueFormatConvertConfig_.end()) { IMAGE_LOGD("No format validation needed. Defaulting to success."); return Media::SUCCESS; } IMAGE_LOGD("Validating value format. Key: %{public}s", keyName.c_str()); // get first iterator according to keyName - for (; it != ExifMetadatFormatter::valueFormatConvertConfig.end() && - it != ExifMetadatFormatter::valueFormatConvertConfig.upper_bound(keyName); + for (; it != ExifMetadatFormatter::GetInstance().valueFormatConvertConfig_.end() && + it != ExifMetadatFormatter::GetInstance().valueFormatConvertConfig_.upper_bound(keyName); it++) { IMAGE_LOGD("Validating value format in loop. Key: %{public}s, Regex: %{public}s", (it->first).c_str(), (it->second).second.c_str()); -- Gitee From 04cff3e34a9c58035a4c81e657b04709e0ced7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 26 Jun 2025 17:06:06 +0800 Subject: [PATCH 43/53] =?UTF-8?q?Revert=20"=E7=A7=BB=E9=99=A4=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E9=80=89=E9=A1=B9"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 1e5bdc9ae32f76c552d6e1021777a9d58d6e9453. Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index 69df77a35..d61489aad 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -35,6 +35,7 @@ ohos_shared_library("image_ani_core") { debug = false } } + shlib_type = "ani" include_dirs = [ "native/include" ] sources = [ "native/src/ani_image_module.cpp", -- Gitee From 917e123f2833ba71417862c6858349b0939d9519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 26 Jun 2025 17:06:12 +0800 Subject: [PATCH 44/53] =?UTF-8?q?Revert=20"ANI=20=E6=8B=86=E5=88=86?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E7=9B=AE=E6=A0=87"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit facc9205c07c9f91bc83bed1bd70e4af42802387. Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 42 +------------------ .../kits/ani/ets/@ohos.multimedia.image.ets | 2 +- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index d61489aad..9cd3dd0bc 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -21,50 +21,11 @@ config("ani_config") { group("image_framework_ani") { deps = [ - ":image_ani_core", + ":image_ani", ":image_framework_abc_etc", ] } -ohos_shared_library("image_ani_core") { - if (!use_clang_android) { - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - } - shlib_type = "ani" - include_dirs = [ "native/include" ] - sources = [ - "native/src/ani_image_module.cpp", - "native/src/image_ani_utils.cpp", - "native/src/image_packer_ani.cpp", - "native/src/image_source_ani.cpp", - "native/src/picture_ani.cpp", - "native/src/pixel_map_ani.cpp", - ] - deps = [ - "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", - "${image_subsystem}/interfaces/innerkits:image_native", - "${image_subsystem}/interfaces/kits/js/common:image", - ] - external_deps = [ - "ability_runtime:ability_runtime", - "c_utils:utils", - "hilog:libhilog", - "hitrace:hitrace_meter", - "ipc:ipc_core", - "runtime_core:ani", - "runtime_core:libarkruntime", - ] - subsystem_name = "multimedia" - part_name = "image_framework" - output_extension = "so" -} - -# APIs exposed to external modules ohos_shared_library("image_ani") { public_configs = [ ":ani_config" ] if (!use_clang_android) { @@ -85,7 +46,6 @@ ohos_shared_library("image_ani") { "native/src/pixel_map_ani.cpp", ] deps = [ - ":image_ani_core", "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", "${image_subsystem}/interfaces/innerkits:image_native", "${image_subsystem}/interfaces/kits/js/common:image", diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 42b5bf657..7e8008567 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -17,7 +17,7 @@ import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; export namespace image { - loadLibrary("image_ani_core"); + loadLibrary("image_ani"); enum DecodingDynamicRange { AUTO = 0, -- Gitee From 2acbf7ea9c9d8b706fe42d0b086df4d847cc0888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 26 Jun 2025 17:06:14 +0800 Subject: [PATCH 45/53] =?UTF-8?q?Revert=20"=E5=A4=AA=E5=92=8C=E6=8B=86?= =?UTF-8?q?=E5=88=86=E7=BC=96=E8=AF=91=E7=9B=AE=E6=A0=87"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5e61d194d58dd81f9f98f6f51e9c94c5bc084811. Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 63 +++---------------- .../idl/ohos.multimedia.image.image.taihe | 2 +- 2 files changed, 10 insertions(+), 55 deletions(-) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index b93265efb..cc5115995 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -41,11 +41,13 @@ ohos_taihe("run_taihe") { ] } -taihe_shared_library("image_taihe_core") { +taihe_shared_library("image_taihe") { taihe_generated_file_path = "$taihe_generated_file_path" subsystem_name = "$subsystem_name" part_name = "$part_name" + public_configs = [ ":image_taihe_config" ] + include_dirs = [ "include", "${image_subsystem}/interfaces/innerkits/include", @@ -61,11 +63,14 @@ taihe_shared_library("image_taihe_core") { "src/image_packer_taihe.cpp", "src/image_receiver_taihe.cpp", "src/image_source_taihe.cpp", + "src/image_source_taihe_ani.cpp", "src/image_taihe.cpp", "src/image_taihe_utils.cpp", "src/metadata_taihe.cpp", "src/picture_taihe.cpp", + "src/picture_taihe_ani.cpp", "src/pixel_map_taihe.cpp", + "src/pixel_map_taihe_ani.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] @@ -77,59 +82,10 @@ taihe_shared_library("image_taihe_core") { deps = [ ":run_taihe", "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", - "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", - "${image_subsystem}/interfaces/innerkits:image_native", - ] - - external_deps = [ - "c_utils:utils", - "eventhandler:libeventhandler", - "graphic_2d:ani_color_space_object_convertor", - "graphic_2d:color_manager", - "graphic_2d:EGL", - "graphic_2d:librender_service_client", - "hilog:libhilog", - "hitrace:hitrace_meter", - "skia:libjpeg", - ] - - if (!use_clang_android && !use_clang_ios) { - branch_protector_ret = "pac_ret" - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - } -} - -# APIs exposed to external modules -ohos_shared_library("image_taihe") { - output_name = "libimage_taihe" - subsystem_name = "$subsystem_name" - part_name = "$part_name" - - public_configs = [ ":image_taihe_config" ] - - include_dirs = [ - "$taihe_toolchain_path/include", - "$taihe_generated_file_path/include", + "$image_subsystem/frameworks/innerkitsimpl/utils:image_utils", + "$image_subsystem/interfaces/innerkits:image_native", ] - sources = [ - "src/image_source_taihe_ani.cpp", - "src/picture_taihe_ani.cpp", - "src/pixel_map_taihe_ani.cpp", - ] - - cflags = [ - "-DIMAGE_DEBUG_FLAG", - "-DIMAGE_COLORSPACE_FLAG", - ] - - deps = [ ":image_taihe_core" ] - external_deps = [ "c_utils:utils", "eventhandler:libeventhandler", @@ -139,7 +95,6 @@ ohos_shared_library("image_taihe") { "graphic_2d:librender_service_client", "hilog:libhilog", "hitrace:hitrace_meter", - "runtime_core:ani", "runtime_core:ani_helpers", "skia:libjpeg", ] @@ -176,7 +131,7 @@ ohos_prebuilt_etc("image_framework_etc") { group("image_framework_taihe") { deps = [ ":image_framework_etc", - ":image_taihe_core", + ":image_taihe", ] } diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index e46338c93..2f6b68527 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -16,7 +16,7 @@ @!namespace("@ohos.multimedia.image", "image") @!sts_inject(""" -static { loadLibrary("image_taihe_core.z"); } +static { loadLibrary("image_taihe.z"); } """) enum PixelMapFormat: i32 { -- Gitee From 464638a6d83d3d91e3243718474258ec63e4651f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Fri, 27 Jun 2025 19:18:15 +0800 Subject: [PATCH 46/53] =?UTF-8?q?ANI=20=E6=8B=86=E5=88=86=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 41 ++++++++++- .../kits/ani/ets/@ohos.multimedia.image.ets | 2 +- frameworks/kits/ani/ets/imageTest.ets | 69 +++++++++---------- frameworks/kits/taihe/BUILD.gn | 63 ++++++++++++++--- .../idl/ohos.multimedia.image.image.taihe | 2 +- 5 files changed, 128 insertions(+), 49 deletions(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index 9cd3dd0bc..69df77a35 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -21,11 +21,49 @@ config("ani_config") { group("image_framework_ani") { deps = [ - ":image_ani", + ":image_ani_core", ":image_framework_abc_etc", ] } +ohos_shared_library("image_ani_core") { + if (!use_clang_android) { + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } + include_dirs = [ "native/include" ] + sources = [ + "native/src/ani_image_module.cpp", + "native/src/image_ani_utils.cpp", + "native/src/image_packer_ani.cpp", + "native/src/image_source_ani.cpp", + "native/src/picture_ani.cpp", + "native/src/pixel_map_ani.cpp", + ] + deps = [ + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + "${image_subsystem}/interfaces/kits/js/common:image", + ] + external_deps = [ + "ability_runtime:ability_runtime", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "runtime_core:ani", + "runtime_core:libarkruntime", + ] + subsystem_name = "multimedia" + part_name = "image_framework" + output_extension = "so" +} + +# APIs exposed to external modules ohos_shared_library("image_ani") { public_configs = [ ":ani_config" ] if (!use_clang_android) { @@ -46,6 +84,7 @@ ohos_shared_library("image_ani") { "native/src/pixel_map_ani.cpp", ] deps = [ + ":image_ani_core", "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", "${image_subsystem}/interfaces/innerkits:image_native", "${image_subsystem}/interfaces/kits/js/common:image", diff --git a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets index 7e8008567..42b5bf657 100644 --- a/frameworks/kits/ani/ets/@ohos.multimedia.image.ets +++ b/frameworks/kits/ani/ets/@ohos.multimedia.image.ets @@ -17,7 +17,7 @@ import type colorSpaceManager from '@ohos.graphics.colorSpaceManager'; export namespace image { - loadLibrary("image_ani"); + loadLibrary("image_ani_core"); enum DecodingDynamicRange { AUTO = 0, diff --git a/frameworks/kits/ani/ets/imageTest.ets b/frameworks/kits/ani/ets/imageTest.ets index 6428d7207..960e68575 100644 --- a/frameworks/kits/ani/ets/imageTest.ets +++ b/frameworks/kits/ani/ets/imageTest.ets @@ -17,7 +17,7 @@ import { image } from "./@ohos.multimedia.image.ets"; function main() { // test createPixemap & getImageInfo - console.log("Test PixelMap START"); + console.println("Test PixelMap START"); const opts: image.InitializationOptions = { size: { width: 480, height: 360 }, srcPixelFormat: image.PixelMapFormat.RGBA_8888, @@ -29,30 +29,30 @@ function main() { let pixelMap:image.PixelMap = image.createPixelMapSync(opts); if (pixelMap != undefined) { - console.log("Create PixelMap success"); + console.println("Create PixelMap success"); } const retImageInfo: image.ImageInfo = pixelMap.getImageInfoSync(); - console.log(`Get image info: ${retImageInfo.size.width}, ${retImageInfo.size.height}, ${retImageInfo.pixelFormat}, ${retImageInfo.alphaType}`); + console.println(`Get image info: ${retImageInfo.size.width}, ${retImageInfo.size.height}, ${retImageInfo.pixelFormat}, ${retImageInfo.alphaType}`); pixelMap.getImageInfo() .then((imageInfo: image.ImageInfo) => { - console.log(`ASYNC Get image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.alphaType}`); + console.println(`ASYNC Get image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.alphaType}`); }); const rowBytes = pixelMap.getBytesNumberPerRow(); - console.log("PixelMap bytes per row: " + rowBytes); + console.println("PixelMap bytes per row: " + rowBytes); const totalBytes = pixelMap.getPixelBytesNumber(); - console.log("PixelMap total bytes: " + totalBytes); + console.println("PixelMap total bytes: " + totalBytes); if (retImageInfo.isHdr) { - console.log("Test PixelMap HDR"); + console.println("Test PixelMap HDR"); } else { - console.log("Test PixelMap not HDR"); + console.println("Test PixelMap not HDR"); } pixelMap.scaleSync(2, 2); const scaledInfo = pixelMap.getImageInfoSync(); - console.log(`Scaled image info: ${scaledInfo.size.width}, ${scaledInfo.size.height}`); + console.println(`Scaled image info: ${scaledInfo.size.width}, ${scaledInfo.size.height}`); const region: image.Region = { size: { width: 512, height: 512 }, x: 0, @@ -60,37 +60,33 @@ function main() { }; pixelMap.cropSync(region); const croppedInfo = pixelMap.getImageInfoSync(); - console.log(`Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); + console.println(`Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); pixelMap.flipSync(true, true); const flippedInfo = pixelMap.getImageInfoSync(); - console.log(`Flipped image info: ${flippedInfo.size.width}, ${flippedInfo.size.height}`); + console.println(`Flipped image info: ${flippedInfo.size.width}, ${flippedInfo.size.height}`); const alphaPixelMap = pixelMap.createAlphaPixelmapSync(); if (alphaPixelMap != undefined) { - console.log("Create alpha PixelMap success"); + console.println("Create alpha PixelMap success"); } const alphaImageInfo = alphaPixelMap.getImageInfoSync(); - console.log(`Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); + console.println(`Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); pixelMap.createAlphaPixelmap() .then((alphaPixelMap: image.PixelMap) => { const alphaImageInfo = alphaPixelMap.getImageInfoSync(); - console.log(`ASYNC Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); + console.println(`ASYNC Alpha get image info: ${alphaImageInfo.size.width}, ${alphaImageInfo.size.height}, ${alphaImageInfo.pixelFormat}, ${alphaImageInfo.alphaType}`); }) let imageSource: image.ImageSource = image.createImageSource("/data/local/tmp/test.png"); if (imageSource != undefined) { - console.log("Create ImageSource by URI success"); - } - let imageSource2: image.ImageSource = image.createImageSource(1); - if (imageSource2 != undefined) { - console.log("Create ImageSource by FD success"); + console.println("Create ImageSource by URI success"); } let imagesourceImageInfo: image.ImageInfo = imageSource.getImageInfoSync(0); - console.log(`Image source image info: ${imagesourceImageInfo.size.width}, ${imagesourceImageInfo.size.height}, ${imagesourceImageInfo.pixelFormat}, ${imagesourceImageInfo.density}, ${imagesourceImageInfo.mimeType}`); + console.println(`Image source image info: ${imagesourceImageInfo.size.width}, ${imagesourceImageInfo.size.height}, ${imagesourceImageInfo.pixelFormat}, ${imagesourceImageInfo.density}, ${imagesourceImageInfo.mimeType}`); imageSource.getImageInfo(0) .then((imageInfo: image.ImageInfo) => { - console.log(`ASYNC Image source image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.density}, ${imageInfo.mimeType}`); + console.println(`ASYNC Image source image info: ${imageInfo.size.width}, ${imageInfo.size.height}, ${imageInfo.pixelFormat}, ${imageInfo.density}, ${imageInfo.mimeType}`); }); const desiredSize: image.Size | undefined = { width: 60, height: 60 }; @@ -111,16 +107,16 @@ function main() { }; let pixelmap2: image.PixelMap = imageSource.createPixelMapSync(decodeOpt); if (pixelmap2 != undefined) { - console.log("Create imageSource.createPixelMapSync success"); + console.println("Create imageSource.createPixelMapSync success"); } imageSource.createPixelMap(decodeOpt) .then((pixelmap2: image.PixelMap) => { if (pixelmap2 != undefined) { - console.log("ASYNC Create imageSource PixelMap success") + console.println("ASYNC Create imageSource PixelMap success") } }); pixelmap2.release() - .then((): void => console.log("ASYNC Release PixelMap success")); + .then((): void => console.println("ASYNC Release PixelMap success")); imageSource.modifyImageProperty("Orientation", "Right-top"); const map: Record = { @@ -137,36 +133,35 @@ function main() { array[3] = "Gamma"; imageSource.getImageProperties(array) .then((properties: Record): void => { - console.log("ASYNC Get image properties: " + properties); + console.println("ASYNC Get image properties: " + properties); }); }) - // imageSource.release(); - console.log("TEST ImagePacker begin"); + console.println("TEST ImagePacker begin"); const imagePacker = image.createImagePacker(); - console.log("ImagePacker supported formats: " + imagePacker.supportedFormats); + console.println("ImagePacker supported formats: " + imagePacker.supportedFormats); let packOpts: image.PackingOption = new image.PackingOption(); packOpts.format = "image/jpeg"; packOpts.quality = 90; let packBuffer: ArrayBuffer = imagePacker.packing(pixelMap, packOpts); - console.log("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); + console.println("TEST ImagePacker end, bufferSize: " + packBuffer.byteLength); imagePacker.release(); - console.log("TEST pixelMap readPixelsToBuffer begin"); + console.println("TEST pixelMap readPixelsToBuffer begin"); let arrayBuffer: ArrayBuffer = new ArrayBuffer(opts.size.width * opts.size.height * 4); pixelMap.readPixelsToBufferSync(arrayBuffer); - console.log("Read pixels to buffer success, size: " + arrayBuffer.byteLength); + console.println("Read pixels to buffer success, size: " + arrayBuffer.byteLength); pixelMap.readPixelsToBuffer(arrayBuffer) - .then((): void => console.log("ASYNC Read pixels to buffer success, size: " + arrayBuffer.byteLength)); + .then((): void => console.println("ASYNC Read pixels to buffer success, size: " + arrayBuffer.byteLength)); - console.log("TEST Picture begin"); + console.println("TEST Picture begin"); const picture = image.createPicture(pixelMap); if (picture != undefined) { - console.log("Create picture success"); + console.println("Create picture success"); } const picturePixelMap = picture.getMainPixelmap(); const pictureInfo = picturePixelMap.getImageInfoSync(); - console.log(`Picture PixelMap image info: ${pictureInfo.size.width}, ${pictureInfo.size.height}, ${pictureInfo.pixelFormat}, ${pictureInfo.alphaType}`); + console.println(`Picture PixelMap image info: ${pictureInfo.size.width}, ${pictureInfo.size.height}, ${pictureInfo.pixelFormat}, ${pictureInfo.alphaType}`); const regionAsync: image.Region = { size: { width: 1, height: 1 }, @@ -176,8 +171,8 @@ function main() { pixelMap.crop(regionAsync) .then((): void => { const croppedInfo = pixelMap.getImageInfoSync(); - console.log(`ASYNC Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); + console.println(`ASYNC Cropped image info: ${croppedInfo.size.width}, ${croppedInfo.size.height}`); }); - console.log("====== Sync methods completed ======") + console.println("====== Sync methods completed ======") } \ No newline at end of file diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index cc5115995..b93265efb 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -41,13 +41,11 @@ ohos_taihe("run_taihe") { ] } -taihe_shared_library("image_taihe") { +taihe_shared_library("image_taihe_core") { taihe_generated_file_path = "$taihe_generated_file_path" subsystem_name = "$subsystem_name" part_name = "$part_name" - public_configs = [ ":image_taihe_config" ] - include_dirs = [ "include", "${image_subsystem}/interfaces/innerkits/include", @@ -63,14 +61,11 @@ taihe_shared_library("image_taihe") { "src/image_packer_taihe.cpp", "src/image_receiver_taihe.cpp", "src/image_source_taihe.cpp", - "src/image_source_taihe_ani.cpp", "src/image_taihe.cpp", "src/image_taihe_utils.cpp", "src/metadata_taihe.cpp", "src/picture_taihe.cpp", - "src/picture_taihe_ani.cpp", "src/pixel_map_taihe.cpp", - "src/pixel_map_taihe_ani.cpp", "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", ] @@ -82,10 +77,59 @@ taihe_shared_library("image_taihe") { deps = [ ":run_taihe", "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", - "$image_subsystem/frameworks/innerkitsimpl/utils:image_utils", - "$image_subsystem/interfaces/innerkits:image_native", + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + ] + + external_deps = [ + "c_utils:utils", + "eventhandler:libeventhandler", + "graphic_2d:ani_color_space_object_convertor", + "graphic_2d:color_manager", + "graphic_2d:EGL", + "graphic_2d:librender_service_client", + "hilog:libhilog", + "hitrace:hitrace_meter", + "skia:libjpeg", + ] + + if (!use_clang_android && !use_clang_ios) { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + } +} + +# APIs exposed to external modules +ohos_shared_library("image_taihe") { + output_name = "libimage_taihe" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + + public_configs = [ ":image_taihe_config" ] + + include_dirs = [ + "$taihe_toolchain_path/include", + "$taihe_generated_file_path/include", ] + sources = [ + "src/image_source_taihe_ani.cpp", + "src/picture_taihe_ani.cpp", + "src/pixel_map_taihe_ani.cpp", + ] + + cflags = [ + "-DIMAGE_DEBUG_FLAG", + "-DIMAGE_COLORSPACE_FLAG", + ] + + deps = [ ":image_taihe_core" ] + external_deps = [ "c_utils:utils", "eventhandler:libeventhandler", @@ -95,6 +139,7 @@ taihe_shared_library("image_taihe") { "graphic_2d:librender_service_client", "hilog:libhilog", "hitrace:hitrace_meter", + "runtime_core:ani", "runtime_core:ani_helpers", "skia:libjpeg", ] @@ -131,7 +176,7 @@ ohos_prebuilt_etc("image_framework_etc") { group("image_framework_taihe") { deps = [ ":image_framework_etc", - ":image_taihe", + ":image_taihe_core", ] } diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index 2f6b68527..e46338c93 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -16,7 +16,7 @@ @!namespace("@ohos.multimedia.image", "image") @!sts_inject(""" -static { loadLibrary("image_taihe.z"); } +static { loadLibrary("image_taihe_core.z"); } """) enum PixelMapFormat: i32 { -- Gitee From ded160a93d3d1f3fe68ee6cae36bf008c5af1f86 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Mon, 30 Jun 2025 10:01:05 +0800 Subject: [PATCH 47/53] Revert Image ArkTS1.2 number to int Signed-off-by: zhaona45 Change-Id: Ibbed9c073fc7760f451f98afcc2df3c2193f3616 --- .../idl/ohos.multimedia.image.image.taihe | 90 +++++++++---------- .../kits/taihe/include/image_source_taihe.h | 4 +- .../kits/taihe/src/image_source_taihe.cpp | 28 +++--- 3 files changed, 57 insertions(+), 65 deletions(-) diff --git a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe index ffd0ea550..87da42ae9 100644 --- a/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe +++ b/frameworks/kits/taihe/idl/ohos.multimedia.image.image.taihe @@ -43,8 +43,8 @@ enum ResolutionQuality: i32 { } struct Size { - width: f64; - height: f64; + width: i32; + height: i32; } enum PropertyKey: String { @@ -280,8 +280,8 @@ enum AllocatorType: i32 { struct Region { size: Size; - x: f64; - y: f64; + x: i32; + y: i32; } // Can't use struct because struct is copied instead of referenced, so data changes to "pixels" in C++ will not be reflected in ArkTS @@ -298,8 +298,8 @@ interface PositionArea { struct ImageInfo { size: Size; - density: f64; - stride: f64; + density: i32; + stride: i32; pixelFormat: PixelMapFormat; alphaType: AlphaType; mimeType: String; @@ -313,34 +313,34 @@ enum CropAndScaleStrategy: i32 { struct PackingOption { format: String; - quality: f64; - bufferSize: Optional; + quality: i32; + bufferSize: Optional; desiredDynamicRange: Optional; needsPackProperties: Optional; } struct PackingOptionsForSequence { - frameCount: f64; - delayTimeList: Array; - disposalTypes: Optional>; - loopCount: Optional; + frameCount: i32; + delayTimeList: Array; + disposalTypes: Optional>; + loopCount: Optional; } struct ImagePropertyOptions { - index: Optional; + index: Optional; defaultValue: Optional; } struct DecodingOptions { - index: Optional; - sampleSize: Optional; - rotate: Optional; + index: Optional; + sampleSize: Optional; + rotate: Optional; editable: Optional; desiredSize: Optional; desiredRegion: Optional; desiredPixelFormat: Optional; photoDesiredPixelFormat: Optional; // not exposed to the user - fitDensity: Optional; + fitDensity: Optional; fillColor: Optional; // not exposed to the user SVGResize: Optional; // not exposed to the user desiredColorSpace: Optional<@sts_type("colorSpaceManager.ColorSpaceManager") Opaque>; @@ -352,8 +352,8 @@ struct DecodingOptions { struct Component { @readonly componentType: ComponentType; - @readonly rowStride: f64; - @readonly pixelStride: f64; + @readonly rowStride: i32; + @readonly pixelStride: i32; @readonly byteBuffer: @arraybuffer Array; } @@ -367,7 +367,7 @@ struct InitializationOptions { } struct SourceOptions { - sourceDensity: f64; + sourceDensity: i32; sourcePixelFormat: Optional; sourceSize: Optional; } @@ -392,9 +392,9 @@ struct GainmapChannel { } struct HdrGainmapMetadata { - writerVersion: f64; - miniVersion: f64; - gainmapChannelCount: f64; + writerVersion: i32; + miniVersion: i32; + gainmapChannelCount: i32; useBaseColorFlag: bool; baseHeadroom: f64; alternateHeadroom: f64; @@ -442,7 +442,7 @@ struct DecodingOptionsForPicture { struct AuxiliaryPictureInfo { auxiliaryPictureType: AuxiliaryPictureType; size: Size; - rowStride: f64; + rowStride: i32; pixelFormat: PixelMapFormat; colorSpace: @sts_type("colorSpaceManager.ColorSpaceManager") Opaque; } @@ -623,14 +623,14 @@ interface ImageSource { GetImplPtr(): i64; @gen_async("getImageInfo") @gen_promise("getImageInfoPromiseWithIndex") - GetImageInfoSyncWithIndex(index: f64): ImageInfo; + GetImageInfoSyncWithIndex(index: i32): ImageInfo; @gen_async("getImageInfo") @gen_promise("getImageInfoPromise") GetImageInfoSync(): ImageInfo; - @!sts_inject_into_interface("getImageInfoSync(index: double | undefined): ImageInfo;") - @!sts_inject_into_class("""getImageInfoSync(index: double | undefined): ImageInfo { + @!sts_inject_into_interface("getImageInfoSync(index: int | undefined): ImageInfo;") + @!sts_inject_into_class("""getImageInfoSync(index: int | undefined): ImageInfo { if (index === undefined) { return this.getImageInfoSync(); } else { @@ -639,8 +639,8 @@ interface ImageSource { } """) - @!sts_inject_into_interface("getImageInfo(index: double | undefined): Promise;") - @!sts_inject_into_class("""getImageInfo(index: double | undefined): Promise { + @!sts_inject_into_interface("getImageInfo(index: int | undefined): Promise;") + @!sts_inject_into_class("""getImageInfo(index: int | undefined): Promise { if (index === undefined) { return this.getImageInfoPromise(); } else { @@ -691,14 +691,14 @@ interface ImageSource { @gen_async("getDelayTimeList") @gen_promise("getDelayTimeList") - GetDelayTimeListSync(): Array; + GetDelayTimeListSync(): Array; @gen_promise("getDisposalTypeList") - GetDisposalTypeListSync(): Array; + GetDisposalTypeListSync(): Array; @gen_async("getFrameCount") @gen_promise("getFrameCount") - GetFrameCountSync(): f64; + GetFrameCountSync(): i32; @gen_promise("getImageProperty") GetImagePropertySync(key: PropertyKey, options: Optional): String; @@ -714,7 +714,7 @@ interface ImageSource { @gen_async("updateData") @gen_promise("updateData") - UpdateDataSync(buf: @arraybuffer Array, isFinished: bool, offset: f64, length: f64): void; + UpdateDataSync(buf: @arraybuffer Array, isFinished: bool, offset: i32, length: i32): void; @gen_async("release") @gen_promise("release") @@ -738,17 +738,17 @@ interface ImagePacker { @gen_async("packToFile") @gen_promise("packToFile") - PackImageSourceToFileSync(source: ImageSource, fd: f64, options: PackingOption): void; + PackImageSourceToFileSync(source: ImageSource, fd: i32, options: PackingOption): void; @gen_async("packToFile") @gen_promise("packToFile") - PackPixelMapToFileSync(source: PixelMap, fd: f64, options: PackingOption): void; + PackPixelMapToFileSync(source: PixelMap, fd: i32, options: PackingOption): void; @gen_promise("packToFileFromPixelmapSequence") - PackToFileFromPixelmapSequenceSync(pixelmapSequence: Array, fd: f64, options: PackingOptionsForSequence): void; + PackToFileFromPixelmapSequenceSync(pixelmapSequence: Array, fd: i32, options: PackingOptionsForSequence): void; @gen_promise("packToFile") - PackPictureToFileSync(picture: Picture, fd: f64, options: PackingOption): void; + PackPictureToFileSync(picture: Picture, fd: i32, options: PackingOption): void; @gen_promise("packing") PackingPictureSync(picture: Picture, options: PackingOption): @arraybuffer Array; @@ -765,8 +765,8 @@ interface Image { GetImplPtr(): i64; @get("size") GetSize(): Size; - @get("format") GetFormat(): f64; - @get("timestamp") GetTimestamp(): f64; + @get("format") GetFormat(): i32; + @get("timestamp") GetTimestamp(): i64; @gen_async("getComponent") @gen_promise("getComponent") @@ -779,7 +779,7 @@ interface Image { interface ImageReceiver { @get GetSize(): Size; - @get GetCapacity(): f64; + @get GetCapacity(): i32; @get GetFormat(): ImageFormat; @gen_async("getReceivingSurfaceId") @@ -823,7 +823,7 @@ interface ImageReceiver { } interface ImageCreator { - @get("capacity") GetCapacity(): f64; + @get("capacity") GetCapacity(): i32; @get("format") GetFormat(): ImageFormat; @gen_async("queueImage") @@ -889,10 +889,10 @@ function CreateImageSourceByUri(uri: String): ImageSource; function CreateImageSourceByUriOption(uri: String, options: SourceOptions): ImageSource; @overload("createImageSource") -function CreateImageSourceByFd(fd: f64): ImageSource; +function CreateImageSourceByFd(fd: i32): ImageSource; @overload("createImageSource") -function CreateImageSourceByFdOption(fd: f64, options: SourceOptions): ImageSource; +function CreateImageSourceByFdOption(fd: i32, options: SourceOptions): ImageSource; @overload("createImageSource") function CreateImageSourceByArrayBuffer(buf: @arraybuffer Array): ImageSource; @@ -914,9 +914,9 @@ function CreateImageSourceByPtr(ptr: i64): ImageSource; function CreateImagePacker(): ImagePacker; -function CreateImageCreator(size: Size, format: ImageFormat, capacity: f64): ImageCreator; +function CreateImageCreator(size: Size, format: ImageFormat, capacity: i32): ImageCreator; -function CreateImageReceiver(size: Size, format: ImageFormat, capacity: f64): ImageReceiver; +function CreateImageReceiver(size: Size, format: ImageFormat, capacity: i32): ImageReceiver; @overload("createPicture") function CreatePictureByPixelMap(mainPixelmap : PixelMap): Picture; diff --git a/frameworks/kits/taihe/include/image_source_taihe.h b/frameworks/kits/taihe/include/image_source_taihe.h index e6cd19038..fd390e743 100644 --- a/frameworks/kits/taihe/include/image_source_taihe.h +++ b/frameworks/kits/taihe/include/image_source_taihe.h @@ -45,8 +45,8 @@ public: array CreatePixelMapListSync(); array CreatePixelMapListSyncWithOptions(DecodingOptions const& options); array CreatePixelMapListSyncWithOptionalOptions(optional_view options); - array GetDelayTimeListSync(); - array GetDisposalTypeListSync(); + array GetDelayTimeListSync(); + array GetDisposalTypeListSync(); int32_t GetFrameCountSync(); string GetImagePropertySync(PropertyKey key, optional_view options); map GetImagePropertiesSync(array_view key); diff --git a/frameworks/kits/taihe/src/image_source_taihe.cpp b/frameworks/kits/taihe/src/image_source_taihe.cpp index 24c821bce..2b28da0bb 100644 --- a/frameworks/kits/taihe/src/image_source_taihe.cpp +++ b/frameworks/kits/taihe/src/image_source_taihe.cpp @@ -206,10 +206,6 @@ ImageInfo ImageSourceImpl::GetImageInfoSync() static bool ParseRotate(DecodingOptions const& options, OHOS::Media::DecodeOptions &dst, std::string &errMsg) { if (options.rotate.has_value()) { - if (options.rotate.value() < 0) { - errMsg = "rotate is invalid value!"; - return false; - } dst.rotateNewDegrees = options.rotate.value(); if (dst.rotateNewDegrees >= 0 && dst.rotateNewDegrees <= 360) { // 360 is the maximum rotation angle. dst.rotateDegrees = static_cast(dst.rotateNewDegrees); @@ -398,10 +394,6 @@ static bool ParseDecodeOptions(DecodingOptions const& options, OHOS::Media::Deco std::string &errMsg) { if (options.index.has_value()) { - if (options.index.value() < 0) { - errMsg = "index is invalid value!"; - return false; - } index = options.index.value(); IMAGE_LOGD("index: %{public}d", index); } @@ -689,13 +681,13 @@ array ImageSourceImpl::CreatePixelMapListSyncWithOptionalOptions(optio return CreatePixelMapListSyncWithOptions(options.value_or(DecodingOptions {})); } -array ImageSourceImpl::GetDelayTimeListSync() +array ImageSourceImpl::GetDelayTimeListSync() { OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDelayTimeListSync"); if (nativeImgSrc == nullptr) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); - return array(0); + return array(0); } uint32_t errorCode = 0; @@ -704,19 +696,19 @@ array ImageSourceImpl::GetDelayTimeListSync() IMAGE_LOGE("Get DelayTime error, error=%{public}u", errorCode); ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, "Get DelayTime error"); - return array(0); + return array(0); } - std::vector result(delayTimes->begin(), delayTimes->end()); - return array(taihe::copy_data_t{}, result.begin(), result.size()); + + return array(taihe::copy_data_t{}, delayTimes->data(), delayTimes->size()); } -array ImageSourceImpl::GetDisposalTypeListSync() +array ImageSourceImpl::GetDisposalTypeListSync() { OHOS::Media::ImageTrace imageTrace("ImageSourceImpl::GetDisposalTypeListSync"); if (nativeImgSrc == nullptr) { ImageTaiheUtils::ThrowExceptionError(OHOS::Media::ERR_IMAGE_DATA_ABNORMAL, "nativeImgSrc is nullptr."); - return array(0); + return array(0); } uint32_t errorCode = 0; @@ -725,10 +717,10 @@ array ImageSourceImpl::GetDisposalTypeListSync() IMAGE_LOGE("Get DisposalType error, error=%{public}u", errorCode); ImageTaiheUtils::ThrowExceptionError((errorCode != OHOS::Media::SUCCESS) ? errorCode : OHOS::Media::ERROR, "Get DisposalType error"); - return array(0); + return array(0); } - std::vector result(disposalTypeList->begin(), disposalTypeList->end()); - return array(taihe::copy_data_t{}, result.begin(), result.size()); + + return array(taihe::copy_data_t{}, disposalTypeList->data(), disposalTypeList->size()); } int32_t ImageSourceImpl::GetFrameCountSync() -- Gitee From 76ba1b87fdcd8edf22406d7cea454ab3ef0761b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Wed, 2 Jul 2025 22:29:50 +0800 Subject: [PATCH 48/53] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20BUILD.gn=20=E7=9A=84?= =?UTF-8?q?=20ANI=20=E7=BC=96=E8=AF=91=E7=9B=AE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 183 +++++++++++++++------------------ 1 file changed, 81 insertions(+), 102 deletions(-) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index b93265efb..07f1d2384 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -41,118 +41,97 @@ ohos_taihe("run_taihe") { ] } -taihe_shared_library("image_taihe_core") { - taihe_generated_file_path = "$taihe_generated_file_path" - subsystem_name = "$subsystem_name" - part_name = "$part_name" - - include_dirs = [ - "include", - "${image_subsystem}/interfaces/innerkits/include", - "${image_subsystem}/interfaces/kits/native/include/image", - "${image_subsystem}/plugins/common/libs/image/libextplugin/include/jpeg_yuv_decoder", - ] - - sources = get_target_outputs(":run_taihe") - sources += [ - "src/ani_constructor.cpp", - "src/auxiliary_picture_taihe.cpp", - "src/image_creator_taihe.cpp", - "src/image_packer_taihe.cpp", - "src/image_receiver_taihe.cpp", - "src/image_source_taihe.cpp", - "src/image_taihe.cpp", - "src/image_taihe_utils.cpp", - "src/metadata_taihe.cpp", - "src/picture_taihe.cpp", - "src/pixel_map_taihe.cpp", - "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", - ] - - cflags = [ - "-DIMAGE_DEBUG_FLAG", - "-DIMAGE_COLORSPACE_FLAG", - ] - - deps = [ - ":run_taihe", - "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", - "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", - "${image_subsystem}/interfaces/innerkits:image_native", - ] - - external_deps = [ - "c_utils:utils", - "eventhandler:libeventhandler", - "graphic_2d:ani_color_space_object_convertor", - "graphic_2d:color_manager", - "graphic_2d:EGL", - "graphic_2d:librender_service_client", - "hilog:libhilog", - "hitrace:hitrace_meter", - "skia:libjpeg", - ] - - if (!use_clang_android && !use_clang_ios) { - branch_protector_ret = "pac_ret" - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false +template("image_taihe_shared_library") { + target_name = invoker.target_name + extra_sources = [] + if (defined(invoker.extra_sources)) { + extra_sources = invoker.extra_sources + } + + taihe_shared_library(target_name) { + forward_variables_from(invoker, "*", + [ + "target_name", + "extra_sources", + ] + ) + + taihe_generated_file_path = "$taihe_generated_file_path" + subsystem_name = "$subsystem_name" + part_name = "$part_name" + + include_dirs = [ + "include", + "${image_subsystem}/interfaces/innerkits/include", + "${image_subsystem}/interfaces/kits/native/include/image", + "${image_subsystem}/plugins/common/libs/image/libextplugin/include/jpeg_yuv_decoder", + ] + + sources = get_target_outputs(":run_taihe") + sources += [ + "src/auxiliary_picture_taihe.cpp", + "src/image_creator_taihe.cpp", + "src/image_packer_taihe.cpp", + "src/image_receiver_taihe.cpp", + "src/image_source_taihe.cpp", + "src/image_taihe.cpp", + "src/image_taihe_utils.cpp", + "src/metadata_taihe.cpp", + "src/picture_taihe.cpp", + "src/pixel_map_taihe.cpp", + "${image_subsystem}/frameworks/innerkitsimpl/accessor/src/exif_metadata_formatter.cpp", + ] + extra_sources + + deps = [ + ":run_taihe", + "${image_subsystem}/frameworks/innerkitsimpl/egl_image:egl_image", + "${image_subsystem}/frameworks/innerkitsimpl/utils:image_utils", + "${image_subsystem}/interfaces/innerkits:image_native", + ] + + external_deps = [ + "c_utils:utils", + "eventhandler:libeventhandler", + "graphic_2d:ani_color_space_object_convertor", + "graphic_2d:color_manager", + "graphic_2d:EGL", + "graphic_2d:librender_service_client", + "hilog:libhilog", + "hitrace:hitrace_meter", + "runtime_core:ani_helpers", + "skia:libjpeg", + ] + + cflags = [ + "-DIMAGE_DEBUG_FLAG", + "-DIMAGE_COLORSPACE_FLAG", + ] + + if (!use_clang_android && !use_clang_ios) { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } } } } -# APIs exposed to external modules -ohos_shared_library("image_taihe") { - output_name = "libimage_taihe" - subsystem_name = "$subsystem_name" - part_name = "$part_name" - - public_configs = [ ":image_taihe_config" ] - - include_dirs = [ - "$taihe_toolchain_path/include", - "$taihe_generated_file_path/include", - ] +image_taihe_shared_library("image_taihe_core") { + extra_sources = [ "src/ani_constructor.cpp" ] +} - sources = [ +# APIs exposed to external modules +image_taihe_shared_library("image_taihe") { + extra_sources = [ "src/image_source_taihe_ani.cpp", "src/picture_taihe_ani.cpp", "src/pixel_map_taihe_ani.cpp", ] - cflags = [ - "-DIMAGE_DEBUG_FLAG", - "-DIMAGE_COLORSPACE_FLAG", - ] - - deps = [ ":image_taihe_core" ] - - external_deps = [ - "c_utils:utils", - "eventhandler:libeventhandler", - "graphic_2d:ani_color_space_object_convertor", - "graphic_2d:color_manager", - "graphic_2d:EGL", - "graphic_2d:librender_service_client", - "hilog:libhilog", - "hitrace:hitrace_meter", - "runtime_core:ani", - "runtime_core:ani_helpers", - "skia:libjpeg", - ] - - if (!use_clang_android && !use_clang_ios) { - branch_protector_ret = "pac_ret" - sanitize = { - cfi = true - cfi_cross_dso = true - cfi_vcall_icall_only = true - debug = false - } - } + public_configs = [ ":image_taihe_config" ] } generate_static_abc("image_framework_taihe_abc") { -- Gitee From 453c8c8390426660b97f27be594e0a06f5b843dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Thu, 3 Jul 2025 09:29:20 +0800 Subject: [PATCH 49/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20ANI=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/ani/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/kits/ani/BUILD.gn b/frameworks/kits/ani/BUILD.gn index 69df77a35..de6b16b9f 100644 --- a/frameworks/kits/ani/BUILD.gn +++ b/frameworks/kits/ani/BUILD.gn @@ -76,7 +76,6 @@ ohos_shared_library("image_ani") { } include_dirs = [ "native/include" ] sources = [ - "native/src/ani_image_module.cpp", "native/src/image_ani_utils.cpp", "native/src/image_packer_ani.cpp", "native/src/image_source_ani.cpp", -- Gitee From 4d1d73a624bd2a8a518102da4137736e1cd149a0 Mon Sep 17 00:00:00 2001 From: ttliang Date: Sun, 6 Jul 2025 20:07:36 +0800 Subject: [PATCH 50/53] Revert "Migrate to hybrid libarkruntime.so" This reverts commit fbed6c91e8f4210a9a9e76f41a1dc300e0cc84d7. Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/ICK0YW Signed-off-by: ttliang Change-Id: I94e5ded7920920fd2d78a4090f50d654c4780094 --- interfaces/kits/js/common/BUILD.gn | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/interfaces/kits/js/common/BUILD.gn b/interfaces/kits/js/common/BUILD.gn index d218cf667..c45669728 100644 --- a/interfaces/kits/js/common/BUILD.gn +++ b/interfaces/kits/js/common/BUILD.gn @@ -276,6 +276,7 @@ if (use_clang_ios) { "ability_runtime:runtime", "c_utils:utils", "drivers_interface_display:display_commontype_idl_headers", + "ets_runtime:libark_jsruntime", "eventhandler:libeventhandler", "graphic_2d:2d_graphics", "graphic_2d:EGL", @@ -293,11 +294,6 @@ if (use_clang_ios) { "napi:ace_napi", "resource_management:librawfile", ] - if (defined(ark_hybrid) && ark_hybrid) { - external_deps += [ "runtime_core:libarkruntime" ] - } else { - external_deps += [ "ets_runtime:libark_jsruntime" ] - } public_external_deps = [ "graphic_2d:color_manager" ] -- Gitee From 2ca09457763c9615b2dde8daf74d95eb7b1dae9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Sat, 12 Jul 2025 20:31:46 +0800 Subject: [PATCH 51/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index 07f1d2384..224efe45c 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -96,6 +96,8 @@ template("image_taihe_shared_library") { "graphic_2d:color_manager", "graphic_2d:EGL", "graphic_2d:librender_service_client", + "graphic_surface:surface", + "graphic_surface:sync_fence", "hilog:libhilog", "hitrace:hitrace_meter", "runtime_core:ani_helpers", -- Gitee From 12faf6b3343c9b7e066e97b6423a0d6e87ba91e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Sat, 12 Jul 2025 21:48:35 +0800 Subject: [PATCH 52/53] =?UTF-8?q?=E5=88=A0=E9=99=A4=E9=9D=9E=E5=BF=85?= =?UTF-8?q?=E8=A6=81=E5=A4=B4=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/src/pixel_map_taihe.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/kits/taihe/src/pixel_map_taihe.cpp b/frameworks/kits/taihe/src/pixel_map_taihe.cpp index 3241911ba..203fd74eb 100644 --- a/frameworks/kits/taihe/src/pixel_map_taihe.cpp +++ b/frameworks/kits/taihe/src/pixel_map_taihe.cpp @@ -26,7 +26,6 @@ #if !defined(IOS_PLATFORM) && !defined(ANDROID_PLATFORM) #include #include "pixel_map_from_surface.h" -#include "sync_fence.h" #include "transaction/rs_interfaces.h" #endif -- Gitee From ed633c6b50d52e50b406b8b17e69263f3669ff05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=B9=94=E5=BC=82?= Date: Sun, 13 Jul 2025 21:33:12 +0800 Subject: [PATCH 53/53] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈乔异 --- frameworks/kits/taihe/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/kits/taihe/BUILD.gn b/frameworks/kits/taihe/BUILD.gn index 224efe45c..3c458f51e 100644 --- a/frameworks/kits/taihe/BUILD.gn +++ b/frameworks/kits/taihe/BUILD.gn @@ -95,6 +95,7 @@ template("image_taihe_shared_library") { "graphic_2d:ani_color_space_object_convertor", "graphic_2d:color_manager", "graphic_2d:EGL", + "graphic_2d:librender_service_base", "graphic_2d:librender_service_client", "graphic_surface:surface", "graphic_surface:sync_fence", -- Gitee