• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "exif_info.h"
17 
18 #include <algorithm>
19 #include <cstdio>
20 #include <memory>
21 #include <unistd.h>
22 #include <charconv>
23 
24 #include "exif_maker_note.h"
25 #include "image_log.h"
26 #include "media_errors.h"
27 #include "securec.h"
28 #include "string_ex.h"
29 
30 #undef LOG_DOMAIN
31 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_PLUGIN
32 
33 #undef LOG_TAG
34 #define LOG_TAG "exifInfo"
35 
36 namespace OHOS {
37 namespace ImagePlugin {
38 namespace {
39     static constexpr int PARSE_EXIF_SUCCESS = 0;
40     static constexpr int PARSE_EXIF_DATA_ERROR = 10001;
41     static constexpr int PARSE_EXIF_IFD_ERROR = 10002;
42     static constexpr int BUFFER_POSITION_4 = 4;
43     static constexpr int BUFFER_POSITION_5 = 5;
44     static constexpr int BUFFER_POSITION_6 = 6;
45     static constexpr int BUFFER_POSITION_7 = 7;
46     static constexpr int BUFFER_POSITION_8 = 8;
47     static constexpr int BUFFER_POSITION_9 = 9;
48     static constexpr int BUFFER_POSITION_12 = 12;
49     static constexpr int BUFFER_POSITION_13 = 13;
50     static constexpr int LENGTH_OFFSET_2 = 2;
51     static constexpr int BYTE_COUNTS_12 = 12;
52     static constexpr int MOVE_OFFSET_8 = 8;
53     static constexpr int MOVE_OFFSET_16 = 16;
54     static constexpr int MOVE_OFFSET_24 = 24;
55     static constexpr int CONSTANT_0 = 0;
56     static constexpr int CONSTANT_1 = 1;
57     static constexpr int CONSTANT_2 = 2;
58     static constexpr int CONSTANT_3 = 3;
59     static constexpr int CONSTANT_4 = 4;
60     static constexpr int FILE_HEADER_LENGTH = 2;
61     static constexpr unsigned long MAX_FILE_SIZE = 1000 * 1000 * 1000;
62     static constexpr unsigned long GPS_DIGIT_NUMBER = 1e6;
63     static constexpr uint32_t GPS_DMS_COUNT = 3;
64     static constexpr double GPS_MAX_LATITUDE = 90.0;
65     static constexpr double GPS_MIN_LATITUDE = 0.0;
66     static constexpr double GPS_MAX_LONGITUDE = 180.0;
67     static constexpr double GPS_MIN_LONGITUDE = 0.0;
68     static constexpr uint32_t ERROR_PARSE_EXIF_FAILED = 1;
69     static constexpr uint32_t ERROR_NO_EXIF_TAGS = 2;
70     static constexpr ExifTag TAG_SENSITIVITY_TYPE = static_cast<ExifTag>(0x8830);
71     static constexpr ExifTag TAG_STANDARD_OUTPUT_SENSITIVITY = static_cast<ExifTag>(0x8831);
72     static constexpr ExifTag TAG_RECOMMENDED_EXPOSURE_INDEX = static_cast<ExifTag>(0x8832);
73     static constexpr size_t SIZE_1 = 1;
74     static constexpr size_t SIZE_2 = 2;
75     static constexpr size_t SIZE_3 = 3;
76 
77     /* raw EXIF header data */
78     static const unsigned char EXIF_HEADER[] = {
79         0xff, 0xd8, 0xff, 0xe1
80     };
81     /* Offset of tiff begin from jpeg file begin */
82     static constexpr uint32_t TIFF_OFFSET_FROM_FILE_BEGIN = 12;
83     static constexpr int PERMISSION_GPS_TYPE = 1;
84 
85     static const struct TagEntry {
86         /*! Tag ID. There may be duplicate tags when the same number is used for
87          * different meanings in different IFDs. */
88         ExifTag tag;
89         const std::string name;
90         const uint16_t number;
91     } EXIF_TAG_TABLE[] = {
92         {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", 0x0000},
93         {EXIF_TAG_INTEROPERABILITY_INDEX, "InteroperabilityIndex", 0x0001},
94         {EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef", 0x0001},
95         {EXIF_TAG_INTEROPERABILITY_VERSION, "InteroperabilityVersion", 0x0002},
96         {EXIF_TAG_GPS_LATITUDE, "GPSLatitude", 0x0002},
97         {EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", 0x0003},
98         {EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", 0x0004},
99         {EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", 0x0005},
100         {EXIF_TAG_GPS_ALTITUDE, "GPSAltitude", 0x0006},
101         {EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", 0x0007},
102         {EXIF_TAG_GPS_SATELLITES, "GPSSatellites", 0x0008},
103         {EXIF_TAG_GPS_STATUS, "GPSStatus", 0x0009},
104         {EXIF_TAG_GPS_MEASURE_MODE, "GPSMeasureMode", 0x000a},
105         {EXIF_TAG_GPS_DOP, "GPSDOP", 0x000b},
106         {EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", 0x000c},
107         {EXIF_TAG_GPS_SPEED, "GPSSpeed", 0x000d},
108         {EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", 0x000e},
109         {EXIF_TAG_GPS_TRACK, "GPSTrack", 0x000f},
110         {EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", 0x0010},
111         {EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", 0x0011},
112         {EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", 0x0012},
113         {EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", 0x0013},
114         {EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", 0x0014},
115         {EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", 0x0015},
116         {EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", 0x0016},
117         {EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", 0x0017},
118         {EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", 0x0018},
119         {EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", 0x0019},
120         {EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", 0x001a},
121         {EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", 0x001b},
122         {EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", 0x001c},
123         {EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", 0x001d},
124         {EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", 0x001e},
125         {EXIF_TAG_GPS_H_POSITIONING_ERROR, "GPSHPositioningError", 0x001f},
126         /* Not in EXIF 2.2 */
127         {EXIF_TAG_NEW_SUBFILE_TYPE, "NewSubfileType", 0x00fe},
128         {EXIF_TAG_IMAGE_WIDTH, "ImageWidth", 0x0100},
129         {EXIF_TAG_IMAGE_LENGTH, "ImageLength", 0x0101},
130         {EXIF_TAG_BITS_PER_SAMPLE, "BitsPerSample", 0x0102},
131         {EXIF_TAG_COMPRESSION, "Compression", 0x0103},
132         {EXIF_TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation", 0x0106},
133         /* Not in EXIF 2.2 */
134         {EXIF_TAG_FILL_ORDER, "FillOrder", 0x010a},
135         /* Not in EXIF 2.2 */
136         {EXIF_TAG_DOCUMENT_NAME, "DocumentName", 0x010d},
137         {EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription", 0x010e},
138         {EXIF_TAG_MAKE, "Make", 0x010f},
139         {EXIF_TAG_MODEL, "Model", 0x0110},
140         {EXIF_TAG_STRIP_OFFSETS, "StripOffsets", 0x0111},
141         {EXIF_TAG_ORIENTATION, "Orientation", 0x0112},
142         {EXIF_TAG_SAMPLES_PER_PIXEL, "SamplesPerPixel", 0x0115},
143         {EXIF_TAG_ROWS_PER_STRIP, "RowsPerStrip", 0x0116},
144         {EXIF_TAG_STRIP_BYTE_COUNTS, "StripByteCounts", 0x0117},
145         {EXIF_TAG_X_RESOLUTION, "XResolution", 0x011a},
146         {EXIF_TAG_Y_RESOLUTION, "YResolution", 0x011b},
147         {EXIF_TAG_PLANAR_CONFIGURATION, "PlanarConfiguration", 0x011c},
148         {EXIF_TAG_RESOLUTION_UNIT, "ResolutionUnit", 0x0128},
149         {EXIF_TAG_TRANSFER_FUNCTION, "TransferFunction", 0x012d},
150         {EXIF_TAG_SOFTWARE, "Software", 0x0131},
151         {EXIF_TAG_DATE_TIME, "DateTime", 0x0132},
152         {EXIF_TAG_ARTIST, "Artist", 0x013b},
153         {EXIF_TAG_WHITE_POINT, "WhitePoint", 0x013e},
154         {EXIF_TAG_PRIMARY_CHROMATICITIES, "PrimaryChromaticities", 0x013f},
155         /* Not in EXIF 2.2 */
156         {EXIF_TAG_SUB_IFDS, "SubIFDs", 0x014a},
157         /* Not in EXIF 2.2 */
158         {EXIF_TAG_TRANSFER_RANGE, "TransferRange", 0x0156},
159         /* Not in EXIF 2.2 */
160         {EXIF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEGInterchangeFormat", 0x0201},
161         {EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, "JPEGInterchangeFormatLength", 0x0202},
162         {EXIF_TAG_YCBCR_COEFFICIENTS, "YCbCrCoefficients", 0x0211},
163         {EXIF_TAG_YCBCR_SUB_SAMPLING, "YCbCrSubSampling", 0x0212},
164         {EXIF_TAG_YCBCR_POSITIONING, "YCbCrPositioning", 0x0213},
165         {EXIF_TAG_REFERENCE_BLACK_WHITE, "ReferenceBlackWhite", 0x0214},
166         /* Not in EXIF 2.2 */
167         {EXIF_TAG_XML_PACKET, "XMLPacket", 0x02bc},
168         /* Not in EXIF 2.2 */
169         {EXIF_TAG_RELATED_IMAGE_FILE_FORMAT, "RelatedImageFileFormat", 0x1000},
170         /* Not in EXIF 2.2 */
171         {EXIF_TAG_RELATED_IMAGE_WIDTH, "RelatedImageWidth", 0x1001},
172         /* Not in EXIF 2.2 */
173         {EXIF_TAG_RELATED_IMAGE_LENGTH, "RelatedImageLength", 0x1002},
174         /* Not in EXIF 2.2 */
175         {EXIF_TAG_CFA_REPEAT_PATTERN_DIM, "CFARepeatPatternDim", 0x828d},
176         /* Not in EXIF 2.2 */
177         {EXIF_TAG_CFA_PATTERN, "CFAPattern", 0x828e},
178         /* Not in EXIF 2.2 */
179         {EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", 0x828f},
180         {EXIF_TAG_COPYRIGHT, "Copyright", 0x8298},
181         {EXIF_TAG_EXPOSURE_TIME, "ExposureTime", 0x829a},
182         {EXIF_TAG_FNUMBER, "FNumber", 0x829d},
183         /* Not in EXIF 2.2 */
184         {EXIF_TAG_IPTC_NAA, "IPTC/NAA", 0x83bb},
185         /* Not in EXIF 2.2 */
186         {EXIF_TAG_IMAGE_RESOURCES, "ImageResources", 0x8649},
187         {EXIF_TAG_EXIF_IFD_POINTER, "ExifIfdPointer", 0x8769},
188         /* Not in EXIF 2.2 */
189         {EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile", 0x8773},
190         {EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", 0x8822},
191         {EXIF_TAG_SPECTRAL_SENSITIVITY, "SpectralSensitivity", 0x8824},
192         {EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer", 0x8825},
193         {EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings", 0x8827},
194         {EXIF_TAG_OECF, "OECF", 0x8828},
195         /* Not in EXIF 2.2 */
196         {EXIF_TAG_TIME_ZONE_OFFSET, "TimeZoneOffset", 0x882a},
197         {TAG_SENSITIVITY_TYPE, "SensitivityType", 0x8830},
198         {TAG_STANDARD_OUTPUT_SENSITIVITY, "StandardOutputSensitivity", 0x8831},
199         {TAG_RECOMMENDED_EXPOSURE_INDEX, "RecommendedExposureIndex", 0x8832},
200         {EXIF_TAG_EXIF_VERSION, "ExifVersion", 0x9000},
201         {EXIF_TAG_DATE_TIME_ORIGINAL, "DateTimeOriginal", 0x9003},
202         {EXIF_TAG_DATE_TIME_DIGITIZED, "DateTimeDigitized", 0x9004},
203         {EXIF_TAG_COMPONENTS_CONFIGURATION, "ComponentsConfiguration", 0x9101},
204         {EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, "CompressedBitsPerPixel", 0x9102},
205         {EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue", 0x9201},
206         {EXIF_TAG_APERTURE_VALUE, "ApertureValue", 0x9202},
207         {EXIF_TAG_BRIGHTNESS_VALUE, "BrightnessValue", 0x9203},
208         {EXIF_TAG_EXPOSURE_BIAS_VALUE, "ExposureBiasValue", 0x9204},
209         {EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", 0x9205},
210         {EXIF_TAG_SUBJECT_DISTANCE, "SubjectDistance", 0x9206},
211         {EXIF_TAG_METERING_MODE, "MeteringMode", 0x9207},
212         {EXIF_TAG_LIGHT_SOURCE, "LightSource", 0x9208},
213         {EXIF_TAG_FLASH, "Flash", 0x9209},
214         {EXIF_TAG_FOCAL_LENGTH, "FocalLength", 0x920a},
215         {EXIF_TAG_SUBJECT_AREA, "SubjectArea", 0x9214},
216         /* Not in EXIF 2.2 */
217         {EXIF_TAG_TIFF_EP_STANDARD_ID, "TIFF/EPStandardID", 0x9216},
218         {EXIF_TAG_MAKER_NOTE, "MakerNote", 0x927c},
219         {EXIF_TAG_USER_COMMENT, "UserComment", 0x9286},
220         {EXIF_TAG_SUB_SEC_TIME, "SubsecTime", 0x9290},
221         {EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "SubSecTimeOriginal", 0x9291},
222         {EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "SubSecTimeDigitized", 0x9292},
223         /* Not in EXIF 2.2 (Microsoft extension) */
224         {EXIF_TAG_XP_TITLE, "XPTitle", 0x9c9b},
225         /* Not in EXIF 2.2 (Microsoft extension) */
226         {EXIF_TAG_XP_COMMENT, "XPComment", 0x9c9c},
227         /* Not in EXIF 2.2 (Microsoft extension) */
228         {EXIF_TAG_XP_AUTHOR, "XPAuthor", 0x9c9d},
229         /* Not in EXIF 2.2 (Microsoft extension) */
230         {EXIF_TAG_XP_KEYWORDS, "XPKeywords", 0x9c9e},
231         /* Not in EXIF 2.2 (Microsoft extension) */
232         {EXIF_TAG_XP_SUBJECT, "XPSubject", 0x9c9f},
233         {EXIF_TAG_FLASH_PIX_VERSION, "FlashpixVersion", 0xa000},
234         {EXIF_TAG_COLOR_SPACE, "ColorSpace", 0xa001},
235         {EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", 0xa002},
236         {EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", 0xa003},
237         {EXIF_TAG_RELATED_SOUND_FILE, "RelatedSoundFile", 0xa004},
238         {EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer", 0xa005},
239         {EXIF_TAG_FLASH_ENERGY, "FlashEnergy", 0xa20b},
240         {EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE, "SpatialFrequencyResponse", 0xa20c},
241         {EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, "FocalPlaneXResolution", 0xa20e},
242         {EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, "FocalPlaneYResolution", 0xa20f},
243         {EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, "FocalPlaneResolutionUnit", 0xa210},
244         {EXIF_TAG_SUBJECT_LOCATION, "SubjectLocation", 0xa214},
245         {EXIF_TAG_EXPOSURE_INDEX, "ExposureIndex", 0xa215},
246         {EXIF_TAG_SENSING_METHOD, "SensingMethod", 0xa217},
247         {EXIF_TAG_FILE_SOURCE, "FileSource", 0xa300},
248         {EXIF_TAG_SCENE_TYPE, "SceneType", 0xa301},
249         {EXIF_TAG_NEW_CFA_PATTERN, "CFAPattern", 0xa302},
250         {EXIF_TAG_CUSTOM_RENDERED, "CustomRendered", 0xa401},
251         {EXIF_TAG_EXPOSURE_MODE, "ExposureMode", 0xa402},
252         {EXIF_TAG_WHITE_BALANCE, "WhiteBalance", 0xa403},
253         {EXIF_TAG_DIGITAL_ZOOM_RATIO, "DigitalZoomRatio", 0xa404},
254         {EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm", 0xa405},
255         {EXIF_TAG_SCENE_CAPTURE_TYPE, "SceneCaptureType", 0xa406},
256         {EXIF_TAG_GAIN_CONTROL, "GainControl", 0xa407},
257         {EXIF_TAG_CONTRAST, "Contrast", 0xa408},
258         {EXIF_TAG_SATURATION, "Saturation", 0xa409},
259         {EXIF_TAG_SHARPNESS, "Sharpness", 0xa40a},
260         {EXIF_TAG_DEVICE_SETTING_DESCRIPTION, "DeviceSettingDescription", 0xa40b},
261         {EXIF_TAG_SUBJECT_DISTANCE_RANGE, "SubjectDistanceRange", 0xa40c},
262         {EXIF_TAG_IMAGE_UNIQUE_ID, "ImageUniqueID", 0xa420},
263         /* EXIF 2.3 */
264         {EXIF_TAG_CAMERA_OWNER_NAME, "CameraOwnerName", 0xa430},
265         /* EXIF 2.3 */
266         {EXIF_TAG_BODY_SERIAL_NUMBER, "BodySerialNumber", 0xa431},
267         /* EXIF 2.3 */
268         {EXIF_TAG_LENS_SPECIFICATION, "LensSpecification", 0xa432},
269         /* EXIF 2.3 */
270         {EXIF_TAG_LENS_MAKE, "LensMake", 0xa433},
271         /* EXIF 2.3 */
272         {EXIF_TAG_LENS_MODEL, "LensModel", 0xa434},
273         /* EXIF 2.3 */
274         {EXIF_TAG_LENS_SERIAL_NUMBER, "LensSerialNumber", 0xa435},
275         /* EXIF 2.32 */
276         {EXIF_TAG_COMPOSITE_IMAGE, "CompositeImage", 0xa460},
277         /* EXIF 2.32 */
278         {EXIF_TAG_SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE, "SourceImageNumberOfCompositeImage", 0xa461},
279         /* EXIF 2.32 */
280         {EXIF_TAG_SOURCE_EXPOSURE_TIMES_OF_COMPOSITE_IMAGE, "SourceExposureTimesOfCompositeImage", 0xa462},
281         /* EXIF 2.3 */
282         {EXIF_TAG_GAMMA, "Gamma", 0xa500},
283         /* Not in EXIF 2.2 */
284         {EXIF_TAG_PRINT_IMAGE_MATCHING, "PrintImageMatching", 0xc4a5},
285         /* Not in EXIF 2.2 (from the Microsoft HD Photo specification) */
286         {EXIF_TAG_PADDING, "Padding", 0xea1c},
287         {static_cast<ExifTag>(0xffff), "", 0xffff}};
288 }
289 
290 const std::string EXIFInfo::DEFAULT_EXIF_VALUE = "default_exif_value";
291 
292 const std::string DATE_TIME_ORIGINAL = "DateTimeOriginal";
293 const std::string DATE_TIME_ORIGINAL_MEDIA = "DateTimeOriginalForMedia";
294 const std::string TAG_ORIENTATION_STRING = "Orientation";
295 const std::string TAG_ORIENTATION_INT = "OrientationInt";
296 const std::map<ExifTag, std::string> TAG_MAP = {
297     {ExifTag::EXIF_TAG_BITS_PER_SAMPLE, "BitsPerSample"},
298     {ExifTag::EXIF_TAG_ORIENTATION, TAG_ORIENTATION_STRING},
299     {ExifTag::EXIF_TAG_IMAGE_LENGTH, "ImageLength"},
300     {ExifTag::EXIF_TAG_IMAGE_WIDTH, "ImageWidth"},
301     {ExifTag::EXIF_TAG_GPS_LATITUDE, "GPSLatitude"},
302     {ExifTag::EXIF_TAG_GPS_LONGITUDE, "GPSLongitude"},
303     {ExifTag::EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef"},
304     {ExifTag::EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef"},
305     {ExifTag::EXIF_TAG_DATE_TIME_ORIGINAL, DATE_TIME_ORIGINAL},
306     {ExifTag::EXIF_TAG_EXPOSURE_TIME, "ExposureTime"},
307     {ExifTag::EXIF_TAG_FNUMBER, "FNumber"},
308     {ExifTag::EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings"},
309     {ExifTag::EXIF_TAG_SCENE_TYPE, "SceneType"},
310     {ExifTag::EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, "CompressedBitsPerPixel"},
311     {ExifTag::EXIF_TAG_DATE_TIME, "DateTime"},
312     {ExifTag::EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp"},
313     {ExifTag::EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp"},
314     {ExifTag::EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription"},
315     {ExifTag::EXIF_TAG_MAKE, "Make"},
316     {ExifTag::EXIF_TAG_MODEL, "Model"},
317     {ExifTag::EXIF_TAG_JPEG_PROC, "PhotoMode"},
318     {ExifTag::EXIF_TAG_SENSITIVITY_TYPE, "SensitivityType"},
319     {ExifTag::EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, "StandardOutputSensitivity"},
320     {ExifTag::EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX, "RecommendedExposureIndex"},
321     {ExifTag::EXIF_TAG_ISO_SPEED, "ISOSpeedRatings"},
322     {ExifTag::EXIF_TAG_APERTURE_VALUE, "ApertureValue"},
323     {ExifTag::EXIF_TAG_EXPOSURE_BIAS_VALUE, "ExposureBiasValue"},
324     {ExifTag::EXIF_TAG_METERING_MODE, "MeteringMode"},
325     {ExifTag::EXIF_TAG_LIGHT_SOURCE, "LightSource"},
326     {ExifTag::EXIF_TAG_FLASH, "Flash"},
327     {ExifTag::EXIF_TAG_FOCAL_LENGTH, "FocalLength"},
328     {ExifTag::EXIF_TAG_USER_COMMENT, "UserComment"},
329     {ExifTag::EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension"},
330     {ExifTag::EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension"},
331     {ExifTag::EXIF_TAG_WHITE_BALANCE, "WhiteBalance"},
332     {ExifTag::EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm"},
333     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_CAPTURE_MODE), "HwMnoteCaptureMode"},
334     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_PHYSICAL_APERTURE), "HwMnotePhysicalAperture"},
335 };
336 
337 const static std::map<ExifTag, std::string> TAG_MAKER_NOTE_MAP = {
338     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_ROLL_ANGLE), "HwMnoteRollAngle"},
339     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_PITCH_ANGLE), "HwMnotePitchAngle"},
340     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_FOOD_CONF), "HwMnoteSceneFoodConf"},
341     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_STAGE_CONF), "HwMnoteSceneStageConf"},
342     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_BLUE_SKY_CONF), "HwMnoteSceneBlueSkyConf"},
343     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_GREEN_PLANT_CONF), "HwMnoteSceneGreenPlantConf"},
344     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_BEACH_CONF), "HwMnoteSceneBeachConf"},
345     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_SNOW_CONF), "HwMnoteSceneSnowConf"},
346     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_SUNSET_CONF), "HwMnoteSceneSunsetConf"},
347     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_FLOWERS_CONF), "HwMnoteSceneFlowersConf"},
348     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_NIGHT_CONF), "HwMnoteSceneNightConf"},
349     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_SCENE_TEXT_CONF), "HwMnoteSceneTextConf"},
350     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_FACE_COUNT), "HwMnoteFaceCount"},
351     {static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_FOCUS_MODE), "HwMnoteFocusMode"},
352 };
353 
354 static const std::map<std::string, uint32_t> ORIENTATION_INT_MAP = {
355     {"Top-left", 0},
356     {"Bottom-right", 180},
357     {"Right-top", 90},
358     {"Left-bottom", 270},
359 };
360 
EXIFInfo()361 EXIFInfo::EXIFInfo()
362     : bitsPerSample_(DEFAULT_EXIF_VALUE),
363       orientation_(DEFAULT_EXIF_VALUE),
364       imageLength_(DEFAULT_EXIF_VALUE),
365       imageWidth_(DEFAULT_EXIF_VALUE),
366       gpsLatitude_(DEFAULT_EXIF_VALUE),
367       gpsLongitude_(DEFAULT_EXIF_VALUE),
368       gpsLatitudeRef_(DEFAULT_EXIF_VALUE),
369       gpsLongitudeRef_(DEFAULT_EXIF_VALUE),
370       dateTimeOriginal_(DEFAULT_EXIF_VALUE),
371       exposureTime_(DEFAULT_EXIF_VALUE),
372       fNumber_(DEFAULT_EXIF_VALUE),
373       isoSpeedRatings_(DEFAULT_EXIF_VALUE),
374       sceneType_(DEFAULT_EXIF_VALUE),
375       compressedBitsPerPixel_(DEFAULT_EXIF_VALUE),
376       dateTime_(DEFAULT_EXIF_VALUE),
377       gpsTimeStamp_(DEFAULT_EXIF_VALUE),
378       gpsDateStamp_(DEFAULT_EXIF_VALUE),
379       imageDescription_(DEFAULT_EXIF_VALUE),
380       make_(DEFAULT_EXIF_VALUE),
381       model_(DEFAULT_EXIF_VALUE),
382       photoMode_(DEFAULT_EXIF_VALUE),
383       sensitivityType_(DEFAULT_EXIF_VALUE),
384       standardOutputSensitivity_(DEFAULT_EXIF_VALUE),
385       recommendedExposureIndex_(DEFAULT_EXIF_VALUE),
386       apertureValue_(DEFAULT_EXIF_VALUE),
387       exposureBiasValue_(DEFAULT_EXIF_VALUE),
388       meteringMode_(DEFAULT_EXIF_VALUE),
389       lightSource_(DEFAULT_EXIF_VALUE),
390       flash_(DEFAULT_EXIF_VALUE),
391       focalLength_(DEFAULT_EXIF_VALUE),
392       userComment_(DEFAULT_EXIF_VALUE),
393       pixelXDimension_(DEFAULT_EXIF_VALUE),
394       pixelYDimension_(DEFAULT_EXIF_VALUE),
395       whiteBalance_(DEFAULT_EXIF_VALUE),
396       focalLengthIn35mmFilm_(DEFAULT_EXIF_VALUE),
397       hwMnoteCaptureMode_(DEFAULT_EXIF_VALUE),
398       hwMnotePhysicalAperture_(DEFAULT_EXIF_VALUE),
399       hwMnoteRollAngle_(DEFAULT_EXIF_VALUE),
400       hwMnotePitchAngle_(DEFAULT_EXIF_VALUE),
401       hwMnoteSceneFoodConf_(DEFAULT_EXIF_VALUE),
402       hwMnoteSceneStageConf_(DEFAULT_EXIF_VALUE),
403       hwMnoteSceneBlueSkyConf_(DEFAULT_EXIF_VALUE),
404       hwMnoteSceneGreenPlantConf_(DEFAULT_EXIF_VALUE),
405       hwMnoteSceneBeachConf_(DEFAULT_EXIF_VALUE),
406       hwMnoteSceneSnowConf_(DEFAULT_EXIF_VALUE),
407       hwMnoteSceneSunsetConf_(DEFAULT_EXIF_VALUE),
408       hwMnoteSceneFlowersConf_(DEFAULT_EXIF_VALUE),
409       hwMnoteSceneNightConf_(DEFAULT_EXIF_VALUE),
410       hwMnoteSceneTextConf_(DEFAULT_EXIF_VALUE),
411       hwMnoteFaceCount_(DEFAULT_EXIF_VALUE),
412       hwMnoteFocusMode_(DEFAULT_EXIF_VALUE),
413       imageFileDirectory_(EXIF_IFD_COUNT),
414       exifData_(nullptr),
415       isExifDataParsed_(false)
416 {
417     for (auto i = TAG_MAP.begin(); i != TAG_MAP.end(); i++) {
418         exifTags_.EnsureInsert(i->first, DEFAULT_EXIF_VALUE);
419     }
420 }
421 
~EXIFInfo()422 EXIFInfo::~EXIFInfo()
423 {
424     if (exifData_ != nullptr) {
425         exif_data_unref(exifData_);
426         exifData_ = nullptr;
427     }
428 }
429 
DumpTagsMap(SafeMap<ExifTag,std::string> & tags)430 static void inline DumpTagsMap(SafeMap<ExifTag, std::string> &tags)
431 {
432     auto callbackIt = [](const ExifTag &key, std::string &value) {
433         bool cond = TAG_MAP.count(key) == 0;
434         CHECK_DEBUG_RETURN_LOG(cond, "DumpTagsMap %{public}d.", key);
435         std::string name = TAG_MAP.at(key);
436         IMAGE_LOGD("DumpTagsMap %{public}s(%{public}d).", name.c_str(), key);
437     };
438     tags.Iterate(callbackIt);
439 }
440 
ParseExifData(const unsigned char * buf,unsigned len)441 int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len)
442 {
443     IMAGE_LOGD("ParseExifData ENTER");
444     if (exifData_ != nullptr) {
445         exif_data_unref(exifData_);
446         exifData_ = nullptr;
447     }
448     exifData_ = exif_data_new();
449     if (!exifData_) {
450         return PARSE_EXIF_DATA_ERROR;
451     }
452     exif_data_unset_option(exifData_, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
453     exif_data_load_data (exifData_, buf, len);
454     exif_data_foreach_content(exifData_,
455         [](ExifContent *ec, void *userData) {
456             ExifIfd ifd = exif_content_get_ifd(ec);
457             (static_cast<EXIFInfo*>(userData))->imageFileDirectory_ = ifd;
458             if (ifd == EXIF_IFD_COUNT) {
459                 IMAGE_LOGD("GetIfd ERROR");
460                 return;
461             }
462             exif_content_foreach_entry(ec,
463                 [](ExifEntry *ee, void* userData) {
464                     if (ee == nullptr) {
465                         return;
466                     }
467                     char tagValueChar[1024];
468                     exif_entry_get_value(ee, tagValueChar, sizeof(tagValueChar));
469                     std::string tagValueStr(&tagValueChar[0], &tagValueChar[strlen(tagValueChar)]);
470                     if ((static_cast<EXIFInfo*>(userData))->CheckExifEntryValid(exif_entry_get_ifd(ee), ee->tag)) {
471                         (static_cast<EXIFInfo*>(userData))->SetExifTagValues(ee->tag, tagValueStr);
472                     }
473                 }, userData);
474         }, this);
475 
476     bool cond = imageFileDirectory_ == EXIF_IFD_COUNT;
477     CHECK_ERROR_RETURN_RET(cond, PARSE_EXIF_IFD_ERROR);
478     ExifMakerNote exifMakerNote;
479     if (exifMakerNote.Parser(exifData_, buf, len) == Media::SUCCESS) {
480         SetExifTagValues(static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_CAPTURE_MODE),
481             exifMakerNote.hwCaptureMode);
482         SetExifTagValues(static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_PHYSICAL_APERTURE),
483             exifMakerNote.hwPhysicalAperture);
484     }
485     makerInfoTagValueMap = exifMakerNote.makerTagValueMap;
486     isExifDataParsed_ = true;
487     DumpTagsMap(exifTags_);
488     return PARSE_EXIF_SUCCESS;
489 }
490 
ParseExifData(const std::string & data)491 int EXIFInfo::ParseExifData(const std::string &data)
492 {
493     return ParseExifData((const unsigned char *)data.data(), data.length());
494 }
495 
IsExifDataParsed()496 bool EXIFInfo::IsExifDataParsed()
497 {
498     return isExifDataParsed_;
499 }
500 
SetExifTagValues(const ExifTag & tag,const std::string & value)501 void EXIFInfo::SetExifTagValues(const ExifTag &tag, const std::string &value)
502 {
503     exifTags_.EnsureInsert(tag, value);
504     if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
505         bitsPerSample_ = value;
506     } else if (tag == EXIF_TAG_ORIENTATION) {
507         orientation_ = value;
508     } else if (tag == EXIF_TAG_IMAGE_LENGTH) {
509         imageLength_ = value;
510     } else if (tag == EXIF_TAG_IMAGE_WIDTH) {
511         imageWidth_ = value;
512     } else if (tag == EXIF_TAG_GPS_LATITUDE) {
513         gpsLatitude_ = value;
514     } else if (tag == EXIF_TAG_GPS_LONGITUDE) {
515         gpsLongitude_ = value;
516     } else if (tag == EXIF_TAG_GPS_LATITUDE_REF) {
517         gpsLatitudeRef_ = value;
518     } else if (tag == EXIF_TAG_GPS_LONGITUDE_REF) {
519         gpsLongitudeRef_ = value;
520     } else if (tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
521         dateTimeOriginal_ = value;
522     } else if (tag == EXIF_TAG_EXPOSURE_TIME) {
523         exposureTime_ = value;
524     } else if (tag == EXIF_TAG_FNUMBER) {
525         fNumber_ = value;
526     } else if (tag == EXIF_TAG_ISO_SPEED_RATINGS) {
527         isoSpeedRatings_ = value;
528     } else if (tag == EXIF_TAG_SCENE_TYPE) {
529         sceneType_ = value;
530     } else if (tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
531         compressedBitsPerPixel_ = value;
532     } else {
533         SetExifTagValuesEx(tag, value);
534     }
535 }
536 
SetExifTagValuesEx(const ExifTag & tag,const std::string & value)537 void EXIFInfo::SetExifTagValuesEx(const ExifTag &tag, const std::string &value)
538 {
539     if (tag == EXIF_TAG_DATE_TIME) {
540         dateTime_ = value;
541     } else if (tag == EXIF_TAG_GPS_TIME_STAMP) {
542         gpsTimeStamp_ = value;
543     } else if (tag == EXIF_TAG_GPS_DATE_STAMP) {
544         gpsDateStamp_ = value;
545     } else if (tag == EXIF_TAG_IMAGE_DESCRIPTION) {
546         imageDescription_ = value;
547     } else if (tag == EXIF_TAG_MAKE) {
548         make_ = value;
549     } else if (tag == EXIF_TAG_MODEL) {
550         model_ = value;
551     } else if (tag == EXIF_TAG_JPEG_PROC) {
552         photoMode_ = value;
553     } else if (tag == TAG_SENSITIVITY_TYPE) {
554         sensitivityType_ = value;
555     } else if (tag == TAG_STANDARD_OUTPUT_SENSITIVITY) {
556         standardOutputSensitivity_ = value;
557     } else if (tag == TAG_RECOMMENDED_EXPOSURE_INDEX) {
558         recommendedExposureIndex_ = value;
559     } else if (tag == EXIF_TAG_APERTURE_VALUE) {
560         apertureValue_ = value;
561     } else if (tag == EXIF_TAG_EXPOSURE_BIAS_VALUE) {
562         exposureBiasValue_ = value;
563     } else if (tag == EXIF_TAG_METERING_MODE) {
564         meteringMode_ = value;
565     } else if (tag == EXIF_TAG_LIGHT_SOURCE) {
566         lightSource_ = value;
567     } else if (tag == EXIF_TAG_FLASH) {
568         flash_ = value;
569     } else if (tag == EXIF_TAG_FOCAL_LENGTH) {
570         focalLength_ = value;
571     } else if (tag == EXIF_TAG_USER_COMMENT) {
572         userComment_ = value;
573     } else if (tag == EXIF_TAG_PIXEL_X_DIMENSION) {
574         pixelXDimension_ = value;
575     } else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
576         pixelYDimension_ = value;
577     } else if (tag == EXIF_TAG_WHITE_BALANCE) {
578         whiteBalance_ = value;
579     } else if (tag == EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM) {
580         focalLengthIn35mmFilm_ = value;
581     } else {
582         IMAGE_LOGD("No match tag name!");
583     }
584 }
585 
GetFileInfoByPath(const std::string & path,FILE ** file,unsigned long & fileLength,unsigned char ** fileBuf)586 uint32_t EXIFInfo::GetFileInfoByPath(const std::string &path, FILE **file, unsigned long &fileLength,
587     unsigned char **fileBuf)
588 {
589     *file = fopen(path.c_str(), "rb");
590     if (*file == nullptr) {
591         IMAGE_LOGD("Error creating file %{public}s", path.c_str());
592         return Media::ERR_MEDIA_IO_ABNORMAL;
593     }
594 
595     // read jpeg file to buff
596     fileLength = GetFileSize(*file);
597     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
598         IMAGE_LOGD("Get file size failed.");
599         (void)fclose(*file);
600         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
601     }
602 
603     *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
604     if (*fileBuf == nullptr) {
605         IMAGE_LOGD("Allocate buf for %{public}s failed.", path.c_str());
606         (void)fclose(*file);
607         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
608     }
609 
610     if (fread(*fileBuf, fileLength, 1, *file) != 1) {
611         IMAGE_LOGD("Read %{public}s failed.", path.c_str());
612         ReleaseSource(fileBuf, file);
613         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
614     }
615 
616     if (fileLength < FILE_HEADER_LENGTH || !((*fileBuf)[0] == 0xFF && (*fileBuf)[1] == 0xD8)) {
617         IMAGE_LOGD("%{public}s is not jpeg file.", path.c_str());
618         ReleaseSource(fileBuf, file);
619         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
620     }
621     return Media::SUCCESS;
622 }
623 
ModifyExifData(const ExifTag & tag,const std::string & value,const std::string & path)624 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path)
625 {
626     FILE *file = nullptr;
627     unsigned long fileLength;
628     unsigned char *fileBuf = nullptr;
629     uint32_t res = GetFileInfoByPath(path, &file, fileLength, &fileBuf);
630     if (res != Media::SUCCESS) {
631         return res;
632     }
633 
634     ExifData *ptrExifData = nullptr;
635     bool isNewExifData = false;
636     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
637         ReleaseSource(&fileBuf, &file);
638         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
639     }
640     (void)fclose(file);
641     file = nullptr;
642 
643     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
644     if (!isNewExifData && orginExifDataLength == 0) {
645         IMAGE_LOGD("There is no orginExifDataLength node in %{public}s.", path.c_str());
646         exif_data_unref(ptrExifData);
647         free(fileBuf);
648         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
649     }
650 
651     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
652     FILE *newFile = fopen(path.c_str(), "wb+");
653     if (newFile == nullptr) {
654         IMAGE_LOGD("Error create new file %{public}s", path.c_str());
655         ReleaseSource(&fileBuf, &newFile);
656         return Media::ERR_MEDIA_IO_ABNORMAL;
657     }
658     ExifEntry *entry = nullptr;
659     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
660         ReleaseSource(&fileBuf, &newFile);
661         exif_data_unref(ptrExifData);
662         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
663     }
664     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, newFile)) {
665         ReleaseSource(&fileBuf, &newFile);
666         exif_data_unref(ptrExifData);
667         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
668     }
669     ReleaseSource(&fileBuf, &newFile);
670     exif_data_unref(ptrExifData);
671     return Media::SUCCESS;
672 }
673 
GetFileInfoByFd(int localFd,FILE ** file,unsigned long & fileLength,unsigned char ** fileBuf)674 uint32_t EXIFInfo::GetFileInfoByFd(int localFd, FILE **file, unsigned long &fileLength, unsigned char **fileBuf)
675 {
676     *file = fdopen(localFd, "wb+");
677     if (*file == nullptr) {
678         IMAGE_LOGD("Error creating file %{public}d", localFd);
679         return Media::ERR_MEDIA_IO_ABNORMAL;
680     }
681 
682     // read jpeg file to buff
683     fileLength = GetFileSize(*file);
684     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
685         IMAGE_LOGD("Get file size failed.");
686         (void)fclose(*file);
687         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
688     }
689 
690     *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
691     if (*fileBuf == nullptr) {
692         IMAGE_LOGD("Allocate buf for %{public}d failed.", localFd);
693         (void)fclose(*file);
694         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
695     }
696 
697     // Set current position to begin of file.
698     (void)fseek(*file, 0L, 0);
699     if (fread(*fileBuf, fileLength, 1, *file) != 1) {
700         IMAGE_LOGD("Read %{public}d failed.", localFd);
701         ReleaseSource(fileBuf, file);
702         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
703     }
704 
705     if (fileLength < FILE_HEADER_LENGTH || !((*fileBuf)[0] == 0xFF && (*fileBuf)[1] == 0xD8)) {
706         IMAGE_LOGD("%{public}d is not jpeg file.", localFd);
707         ReleaseSource(fileBuf, file);
708         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
709     }
710     return Media::SUCCESS;
711 }
712 
ModifyExifData(const ExifTag & tag,const std::string & value,const int fd)713 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const int fd)
714 {
715     const int localFd = dup(fd);
716     FILE *file = nullptr;
717     unsigned long fileLength;
718     unsigned char *fileBuf = nullptr;
719     uint32_t res = GetFileInfoByFd(localFd, &file, fileLength, &fileBuf);
720     if (res != Media::SUCCESS) {
721         return res;
722     }
723 
724     ExifData *ptrExifData = nullptr;
725     bool isNewExifData = false;
726     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
727         ReleaseSource(&fileBuf, &file);
728         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
729     }
730 
731     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
732     if (!isNewExifData && orginExifDataLength == 0) {
733         IMAGE_LOGD("There is no orginExifDataLength node in %{public}d.", localFd);
734         ReleaseSource(&fileBuf, &file);
735         exif_data_unref(ptrExifData);
736         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
737     }
738 
739     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
740     // Set current position to begin of new file.
741     (void)fseek(file, 0L, 0);
742     ExifEntry *entry = nullptr;
743     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
744         ReleaseSource(&fileBuf, &file);
745         exif_data_unref(ptrExifData);
746         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
747     }
748 
749     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, file)) {
750         ReleaseSource(&fileBuf, &file);
751         exif_data_unref(ptrExifData);
752         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
753     }
754     ReleaseSource(&fileBuf, &file);
755     exif_data_unref(ptrExifData);
756     return Media::SUCCESS;
757 }
758 
ReleaseExifDataBuffer(unsigned char * exifDataBuf)759 void ReleaseExifDataBuffer(unsigned char* exifDataBuf)
760 {
761     if (exifDataBuf != nullptr) {
762         free(exifDataBuf);
763         exifDataBuf = nullptr;
764     }
765 }
766 
CheckInputDataValid(unsigned char * data,uint32_t size)767 uint32_t EXIFInfo::CheckInputDataValid(unsigned char *data, uint32_t size)
768 {
769     if (data == nullptr) {
770         IMAGE_LOGD("buffer is nullptr.");
771         return Media::ERR_IMAGE_SOURCE_DATA;
772     }
773 
774     if (size == 0) {
775         IMAGE_LOGD("buffer size is 0.");
776         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
777     }
778 
779     if (!(data[0] == 0xFF && data[1] == 0xD8)) {
780         IMAGE_LOGD("This is not jpeg file.");
781         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
782     }
783     return Media::SUCCESS;
784 }
785 
ModifyExifData(const ExifTag & tag,const std::string & value,unsigned char * data,uint32_t size)786 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value,
787     unsigned char *data, uint32_t size)
788 {
789     uint32_t checkInputRes = CheckInputDataValid(data, size);
790     bool cond = checkInputRes != Media::SUCCESS;
791     CHECK_ERROR_RETURN_RET(cond, checkInputRes);
792 
793     ExifData *ptrExifData = nullptr;
794     bool isNewExifData = false;
795     if (!CreateExifData(data, size, &ptrExifData, isNewExifData)) {
796         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
797     }
798 
799     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, data);
800     if (!isNewExifData && orginExifDataLength == 0) {
801         IMAGE_LOGD("There is no orginExifDataLength node in buffer.");
802         exif_data_unref(ptrExifData);
803         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
804     }
805 
806     ExifByteOrder order = GetExifByteOrder(isNewExifData, data);
807     ExifEntry *entry = nullptr;
808     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
809         exif_data_unref(ptrExifData);
810         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
811     }
812 
813     unsigned char* exifDataBuf = nullptr;
814     unsigned int exifDataBufLength = 0;
815     exif_data_save_data(ptrExifData, &exifDataBuf, &exifDataBufLength);
816     if (exifDataBuf == nullptr) {
817         IMAGE_LOGD("Get Exif Data Buf failed!");
818         exif_data_unref(ptrExifData);
819         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
820     }
821 
822     if (size == 0 || size > MAX_FILE_SIZE) {
823         IMAGE_LOGD("Buffer size is out of range.");
824         exif_data_unref(ptrExifData);
825         ReleaseExifDataBuffer(exifDataBuf);
826         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
827     }
828     unsigned char *tempBuf = static_cast<unsigned char *>(malloc(size));
829     if (tempBuf == nullptr) {
830         IMAGE_LOGD("Allocate temp buffer ailed.");
831         exif_data_unref(ptrExifData);
832         ReleaseExifDataBuffer(exifDataBuf);
833         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
834     }
835 
836     // Write EXIF header to buffer
837     uint32_t index = 0;
838     if (sizeof(EXIF_HEADER) >= size) {
839         IMAGE_LOGD("There is not enough space for EXIF header!");
840         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
841         return Media::ERR_MEDIA_OUT_OF_RANGE;
842     }
843 
844     for (size_t i = 0; i < sizeof(EXIF_HEADER); i++) {
845         tempBuf[index++] = EXIF_HEADER[i];
846     }
847 
848     // Write EXIF block length in big-endian order
849     unsigned char highBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8);
850     if (index >= size) {
851         IMAGE_LOGD("There is not enough space for writing EXIF block length!");
852         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
853         return Media::ERR_MEDIA_OUT_OF_RANGE;
854     }
855     tempBuf[index++] = highBit;
856 
857     unsigned char lowBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) & 0xff);
858     if (index >= size) {
859         IMAGE_LOGD("There is not enough space for writing EXIF block length!");
860         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
861         return Media::ERR_MEDIA_OUT_OF_RANGE;
862     }
863     tempBuf[index++] = lowBit;
864 
865     // Write EXIF data block
866     if ((index +  exifDataBufLength) >= size) {
867         IMAGE_LOGD("There is not enough space for writing EXIF data block!");
868         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
869         return Media::ERR_MEDIA_OUT_OF_RANGE;
870     }
871     for (unsigned int i = 0; i < exifDataBufLength; i++) {
872         tempBuf[index++] = exifDataBuf[i];
873     }
874 
875     // Write JPEG image data, skipping the non-EXIF header
876     if ((index + size - orginExifDataLength - sizeof(EXIF_HEADER) - MOVE_OFFSET_8) > size) {
877         IMAGE_LOGD("There is not enough space for writing JPEG image data!");
878         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
879         return Media::ERR_MEDIA_OUT_OF_RANGE;
880     }
881 
882     for (unsigned int i = 0; i < (size - orginExifDataLength - sizeof(EXIF_HEADER)); i++) {
883         tempBuf[index++] = data[orginExifDataLength + sizeof(EXIF_HEADER) + i];
884     }
885 
886     for (unsigned int i = 0; i < size; i++) {
887         data[i] = tempBuf[i];
888     }
889 
890     ParseExifData(data, static_cast<unsigned int>(index));
891     ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
892     return Media::SUCCESS;
893 }
894 
ReleaseExifData(unsigned char * tempBuf,ExifData * ptrExifData,unsigned char * exifDataBuf)895 void EXIFInfo::ReleaseExifData(unsigned char *tempBuf, ExifData *ptrExifData, unsigned char* exifDataBuf)
896 {
897     if (tempBuf != nullptr) {
898         free(tempBuf);
899         tempBuf = nullptr;
900     }
901     exif_data_unref(ptrExifData);
902     ReleaseExifDataBuffer(exifDataBuf);
903 }
904 
InitExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag)905 ExifEntry* EXIFInfo::InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag)
906 {
907     ExifEntry *entry;
908     bool cond = false;
909     cond = ifd < EXIF_IFD_0 || ifd >= EXIF_IFD_COUNT;
910     CHECK_ERROR_RETURN_RET(cond, nullptr);
911     /* Return an existing tag if one exists */
912     if (!(entry = exif_content_get_entry(exif->ifd[ifd], tag))) {
913         /* Allocate a new entry */
914         entry = exif_entry_new();
915         cond = entry == nullptr;
916         CHECK_DEBUG_RETURN_RET_LOG(cond, nullptr, "Create new entry failed!");
917         entry->tag = tag; // tag must be set before calling exif_content_add_entry
918         /* Attach the ExifEntry to an IFD */
919         exif_content_add_entry (exif->ifd[ifd], entry);
920 
921         /* Allocate memory for the entry and fill with default data */
922         exif_entry_initialize (entry, tag);
923 
924         /* Ownership of the ExifEntry has now been passed to the IFD.
925          * One must be very careful in accessing a structure after
926          * unref'ing it; in this case, we know "entry" won't be freed
927          * because the reference count was bumped when it was added to
928          * the IFD.
929          */
930         exif_entry_unref(entry);
931     }
932     return entry;
933 }
EXIFInfoBufferCheck(ExifEntry * exifEntry,size_t len)934 static void EXIFInfoBufferCheck(ExifEntry *exifEntry, size_t len)
935 {
936     if (exifEntry == nullptr || (exifEntry->size >= len)) {
937         return;
938     }
939     /* Create a memory allocator to manage this ExifEntry */
940     ExifMem *exifMem = exif_mem_new_default();
941     bool cond = exifMem == nullptr;
942     CHECK_DEBUG_RETURN_LOG(cond, "Create mem failed!");
943     auto buf = exif_mem_realloc(exifMem, exifEntry->data, len);
944     if (buf != nullptr) {
945         exifEntry->data = static_cast<unsigned char*>(buf);
946         exifEntry->size = len;
947     }
948     exif_mem_unref(exifMem);
949 }
950 
CreateExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag,size_t len,ExifFormat format)951 ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag,
952     size_t len, ExifFormat format)
953 {
954     void *buf;
955     ExifEntry *exifEntry;
956     bool cond = false;
957     cond = ifd < EXIF_IFD_0 || ifd >= EXIF_IFD_COUNT;
958     CHECK_DEBUG_RETURN_RET_LOG(cond, nullptr, "Invalid IFD.");
959     if ((exifEntry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
960         EXIFInfoBufferCheck(exifEntry, len);
961         return exifEntry;
962     }
963 
964     /* Create a memory allocator to manage this ExifEntry */
965     ExifMem *exifMem = exif_mem_new_default();
966     cond = exifMem == nullptr;
967     CHECK_DEBUG_RETURN_RET_LOG(cond, nullptr, "Create mem failed!");
968 
969     /* Create a new ExifEntry using our allocator */
970     exifEntry = exif_entry_new_mem (exifMem);
971     cond = exifEntry == nullptr;
972     CHECK_DEBUG_RETURN_RET_LOG(cond, nullptr, "Create entry by mem failed!");
973 
974     /* Allocate memory to use for holding the tag data */
975     buf = exif_mem_alloc(exifMem, len);
976     cond = buf == nullptr;
977     CHECK_DEBUG_RETURN_RET_LOG(cond, nullptr, "Allocate memory failed!");
978 
979     /* Fill in the entry */
980     exifEntry->data = static_cast<unsigned char*>(buf);
981     exifEntry->size = len;
982     exifEntry->tag = tag;
983     exifEntry->components = len;
984     exifEntry->format = format;
985 
986     /* Attach the ExifEntry to an IFD */
987     exif_content_add_entry (exif->ifd[ifd], exifEntry);
988 
989     /* The ExifMem and ExifEntry are now owned elsewhere */
990     exif_mem_unref(exifMem);
991     exif_entry_unref(exifEntry);
992 
993     return exifEntry;
994 }
995 
GetExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag,size_t len)996 ExifEntry* EXIFInfo::GetExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len)
997 {
998     ExifEntry *exifEntry;
999     if ((exifEntry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
1000         EXIFInfoBufferCheck(exifEntry, len);
1001         return exifEntry;
1002     }
1003     return nullptr;
1004 }
1005 
GetFileSize(FILE * fp)1006 unsigned long EXIFInfo::GetFileSize(FILE *fp)
1007 {
1008     long int position;
1009     long size;
1010 
1011     /* Save the current position. */
1012     position = ftell(fp);
1013 
1014     /* Jump to the end of the file. */
1015     (void)fseek(fp, 0L, SEEK_END);
1016 
1017     /* Get the end position. */
1018     size = ftell(fp);
1019 
1020     /* Jump back to the original position. */
1021     (void)fseek(fp, position, SEEK_SET);
1022 
1023     return static_cast<unsigned long>(size);
1024 }
1025 
CreateExifData(unsigned char * buf,unsigned long length,ExifData ** ptrData,bool & isNewExifData)1026 bool EXIFInfo::CreateExifData(unsigned char *buf, unsigned long length, ExifData **ptrData, bool &isNewExifData)
1027 {
1028     bool cond = false;
1029     cond = buf == nullptr;
1030     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Create exif data but buf is null");
1031     if ((buf[BUFFER_POSITION_6] == 'E' && buf[BUFFER_POSITION_7] == 'x' &&
1032         buf[BUFFER_POSITION_8] == 'i' && buf[BUFFER_POSITION_9] == 'f')) {
1033         *ptrData = exif_data_new_from_data(buf, static_cast<unsigned int>(length));
1034         cond = !(*ptrData);
1035         CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Create exif data from file failed.");
1036         isNewExifData = false;
1037         IMAGE_LOGD("Create exif data from buffer.");
1038     } else {
1039         *ptrData = exif_data_new();
1040         cond = !(*ptrData);
1041         CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Create exif data failed.");
1042         /* Set the image options */
1043         exif_data_set_option(*ptrData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
1044         exif_data_set_data_type(*ptrData, EXIF_DATA_TYPE_COMPRESSED);
1045         exif_data_set_byte_order(*ptrData, EXIF_BYTE_ORDER_INTEL);
1046 
1047         /* Create the mandatory EXIF fields with default data */
1048         exif_data_fix(*ptrData);
1049         isNewExifData = true;
1050         IMAGE_LOGD("Create new exif data.");
1051     }
1052     return true;
1053 }
1054 
GetOrginExifDataLength(const bool & isNewExifData,unsigned char * buf)1055 unsigned int EXIFInfo::GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf)
1056 {
1057     unsigned int orginExifDataLength = 0;
1058     if (!isNewExifData) {
1059         orginExifDataLength = static_cast<unsigned int>(buf[BUFFER_POSITION_5]) |
1060             static_cast<unsigned int>(buf[BUFFER_POSITION_4] << MOVE_OFFSET_8);
1061     }
1062     return orginExifDataLength;
1063 }
1064 
GetExifByteOrder(const bool & isNewExifData,unsigned char * buf)1065 ExifByteOrder EXIFInfo::GetExifByteOrder(const bool &isNewExifData, unsigned char *buf)
1066 {
1067     if (isNewExifData) {
1068         return EXIF_BYTE_ORDER_INTEL;
1069     } else {
1070         if (buf[BUFFER_POSITION_12] == 'M' && buf[BUFFER_POSITION_13] == 'M') {
1071             return EXIF_BYTE_ORDER_MOTOROLA;
1072         } else {
1073             return EXIF_BYTE_ORDER_INTEL;
1074         }
1075     }
1076 }
1077 
GCD(int a,int b)1078 static int GCD(int a, int b)
1079 {
1080     if (b == 0) {
1081         return a;
1082     }
1083     return GCD(b, a % b);
1084 }
1085 
ConvertToInt(const std::string & str,int & value)1086 static bool ConvertToInt(const std::string& str, int& value)
1087 {
1088     auto [ptr, errCode] = std::from_chars(str.data(), str.data() + str.size(), value);
1089     bool ret = errCode == std::errc{} && (ptr == str.data() + str.size());
1090     return ret;
1091 }
1092 
ConvertToDouble(const std::string & str,double & value)1093 static bool ConvertToDouble(const std::string& str, double& value)
1094 {
1095     errno = 0;
1096     char* endPtr = nullptr;
1097     value = strtod(str.c_str(), &endPtr);
1098     if (errno == ERANGE && *endPtr != '\0') {
1099         return false;
1100     }
1101     return true;
1102 }
1103 
GetFractionFromStr(const std::string & decimal,ExifRational & result)1104 static bool GetFractionFromStr(const std::string &decimal, ExifRational &result)
1105 {
1106     int intPart = 0;
1107     std::string intPartStr = decimal.substr(0, decimal.find("."));
1108     if (!ConvertToInt(intPartStr, intPart)) {
1109         IMAGE_LOGE("%{public}s failed, value out of range", __func__);
1110         return false;
1111     }
1112 
1113     double decPart = 0.0;
1114     std::string decPartStr = decimal.substr(decimal.find("."));
1115     if (!ConvertToDouble(decPartStr, decPart)) {
1116         IMAGE_LOGE("%{public}s failed, value out of range", __func__);
1117         return false;
1118     }
1119 
1120     int numerator = decPart * pow(10, decimal.length() - decimal.find(".") - 1);
1121     int denominator = pow(10, decimal.length() - decimal.find(".") - 1);
1122 
1123     int gcdVal = GCD(numerator, denominator);
1124     bool cond = gcdVal == 0;
1125     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "gcdVal is zero");
1126     numerator /= gcdVal;
1127     denominator /= gcdVal;
1128 
1129     numerator += intPart * denominator;
1130 
1131     result.numerator = static_cast<ExifLong>(numerator);
1132     result.denominator = static_cast<ExifLong>(denominator);
1133     return true;
1134 }
1135 
ExifIntValueByFormat(unsigned char * b,ExifByteOrder order,ExifFormat format,long value)1136 static void ExifIntValueByFormat(unsigned char *b, ExifByteOrder order, ExifFormat format, long value)
1137 {
1138     switch (format) {
1139         case EXIF_FORMAT_SHORT:
1140             exif_set_short(b, order, (ExifShort)value);
1141             break;
1142         case EXIF_FORMAT_SSHORT:
1143             exif_set_sshort(b, order, (ExifSShort)value);
1144             break;
1145         case EXIF_FORMAT_LONG:
1146             exif_set_long(b, order, (ExifLong)value);
1147             break;
1148         case EXIF_FORMAT_SLONG:
1149             exif_set_slong(b, order, (ExifSLong)value);
1150             break;
1151         case EXIF_FORMAT_BYTE:
1152         case EXIF_FORMAT_SRATIONAL:
1153         case EXIF_FORMAT_UNDEFINED:
1154         case EXIF_FORMAT_ASCII:
1155         case EXIF_FORMAT_RATIONAL:
1156         default:
1157             IMAGE_LOGD("ExifIntValueByFormat unsupported format %{public}d.", format);
1158             break;
1159     }
1160 }
1161 
ConvertStringToDouble(const std::string & str,double & number)1162 static bool ConvertStringToDouble(const std::string &str, double &number)
1163 {
1164     char* end = nullptr;
1165     number = std::strtod(str.c_str(), &end);
1166     return end != str.c_str() && *end == '\0' && number != HUGE_VAL;
1167 }
1168 
IsValidGpsData(const std::vector<std::string> & dataVec,const ExifTag & tag)1169 static bool IsValidGpsData(const std::vector<std::string> &dataVec, const ExifTag &tag)
1170 {
1171     bool cond = false;
1172     cond = dataVec.size() != SIZE_3 || (tag != EXIF_TAG_GPS_LATITUDE && tag != EXIF_TAG_GPS_LONGITUDE);
1173     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Gps dms data size is invalid.");
1174     double degree = 0.0;
1175     double minute = 0.0;
1176     double second = 0.0;
1177     if (!ConvertStringToDouble(dataVec[CONSTANT_0], degree) ||
1178         !ConvertStringToDouble(dataVec[CONSTANT_1], minute) ||
1179         !ConvertStringToDouble(dataVec[CONSTANT_2], second)) {
1180         IMAGE_LOGE("Convert gps data to double type failed.");
1181         return false;
1182     }
1183     constexpr uint32_t timePeriod = 60;
1184     double latOrLong = degree + minute / timePeriod + second / (timePeriod * timePeriod);
1185     cond = (tag == EXIF_TAG_GPS_LATITUDE && (latOrLong > GPS_MAX_LATITUDE || latOrLong < GPS_MIN_LATITUDE)) ||
1186             (tag == EXIF_TAG_GPS_LONGITUDE && (latOrLong > GPS_MAX_LONGITUDE || latOrLong < GPS_MIN_LONGITUDE));
1187     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Gps latitude or longitude is out of range.");
1188     return true;
1189 }
1190 
ConvertGpsDataToRationals(const std::vector<std::string> & dataVec,std::vector<ExifRational> & exifRationals)1191 static bool ConvertGpsDataToRationals(const std::vector<std::string> &dataVec,
1192     std::vector<ExifRational> &exifRationals)
1193 {
1194     bool cond = !(dataVec.size() == SIZE_3 && exifRationals.size() == SIZE_3);
1195     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Data size is invalid.");
1196 
1197     int32_t degree = static_cast<int32_t>(atoi(dataVec[CONSTANT_0].c_str()));
1198     int32_t minute = static_cast<int32_t>(atoi(dataVec[CONSTANT_1].c_str()));
1199     double secondDouble = 0.0;
1200     ConvertStringToDouble(dataVec[CONSTANT_2], secondDouble);
1201     int32_t second = static_cast<int32_t>(secondDouble * GPS_DIGIT_NUMBER);
1202 
1203     exifRationals[CONSTANT_0].numerator = static_cast<ExifLong>(degree);
1204     exifRationals[CONSTANT_0].denominator = static_cast<ExifLong>(1);
1205     exifRationals[CONSTANT_1].numerator = static_cast<ExifLong>(minute);
1206     exifRationals[CONSTANT_1].denominator = static_cast<ExifLong>(1);
1207     exifRationals[CONSTANT_2].numerator = static_cast<ExifLong>(second);
1208     exifRationals[CONSTANT_2].denominator = static_cast<ExifLong>(GPS_DIGIT_NUMBER);
1209     return true;
1210 }
1211 
SetGpsRationals(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<ExifRational> & exifRationals)1212 bool EXIFInfo::SetGpsRationals(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order,
1213     const ExifTag &tag, const std::vector<ExifRational> &exifRationals)
1214 {
1215     if (exifRationals.size() != SIZE_3) {
1216         IMAGE_LOGD("ExifRationals size is invalid.");
1217         return false;
1218     }
1219     *ptrEntry = GetExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24);
1220     if ((*ptrEntry) == nullptr) {
1221         IMAGE_LOGD("Get exif entry failed.");
1222         return false;
1223     }
1224     exif_set_rational((*ptrEntry)->data, order, exifRationals[CONSTANT_0]);
1225     exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_8, order, exifRationals[CONSTANT_1]);
1226     exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_16, order, exifRationals[CONSTANT_2]);
1227     return true;
1228 }
1229 
SetGpsDegreeRational(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<std::string> & dataVec)1230 bool EXIFInfo::SetGpsDegreeRational(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order, const ExifTag &tag,
1231     const std::vector<std::string> &dataVec)
1232 {
1233     if (dataVec.size() != SIZE_2) {
1234         IMAGE_LOGD("Gps degree data size is invalid.");
1235         return false;
1236     }
1237     ExifRational exifRational;
1238     exifRational.numerator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_0].c_str()));
1239     exifRational.denominator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_1].c_str()));
1240     *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_8, EXIF_FORMAT_RATIONAL);
1241     bool cond = (*ptrEntry) == nullptr;
1242     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1243     exif_set_rational((*ptrEntry)->data, order, exifRational);
1244     return true;
1245 }
1246 
CreateExifEntryOfBitsPerSample(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1247 bool EXIFInfo::CreateExifEntryOfBitsPerSample(const ExifTag &tag, ExifData *data, const std::string &value,
1248     ExifByteOrder order, ExifEntry **ptrEntry)
1249 {
1250     *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_BITS_PER_SAMPLE);
1251     bool cond = (*ptrEntry) == nullptr;
1252     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1253     std::vector<std::string> bitsVec;
1254     SplitStr(value, ",", bitsVec);
1255     if (bitsVec.size() > CONSTANT_4) {
1256         IMAGE_LOGD("BITS_PER_SAMPLE Invalid value %{public}s", value.c_str());
1257         return false;
1258     }
1259     if (bitsVec.size() != 0) {
1260         for (size_t i = 0; i < bitsVec.size(); i++) {
1261             exif_set_short((*ptrEntry)->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str()));
1262         }
1263     }
1264     return true;
1265 }
1266 
GetExifIfdByExifTag(const ExifTag & tag)1267 ExifIfd EXIFInfo::GetExifIfdByExifTag(const ExifTag &tag)
1268 {
1269     static std::vector exifIfd0Vec{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1270         EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME};
1271     static std::vector exifIfdExifVec{EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH,
1272         EXIF_TAG_ISO_SPEED_RATINGS, EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE,
1273         EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX,
1274         EXIF_TAG_SENSITIVITY_TYPE, EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT,
1275         EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1276         EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1277     static std::vector exifIfdGpsVec{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF,
1278         EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE};
1279     if (std::find(exifIfd0Vec.begin(), exifIfd0Vec.end(), tag) != exifIfd0Vec.end()) {
1280         return EXIF_IFD_0;
1281     } else if (std::find(exifIfdExifVec.begin(), exifIfdExifVec.end(), tag) != exifIfdExifVec.end()) {
1282         return EXIF_IFD_EXIF;
1283     } else if (std::find(exifIfdGpsVec.begin(), exifIfdGpsVec.end(), tag) != exifIfdGpsVec.end()) {
1284         return EXIF_IFD_GPS;
1285     }
1286     return EXIF_IFD_COUNT;
1287 }
1288 
GetExifFormatByExifTag(const ExifTag & tag)1289 ExifFormat EXIFInfo::GetExifFormatByExifTag(const ExifTag &tag)
1290 {
1291     static std::vector exifFormatAscii{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1292         EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF,
1293         EXIF_TAG_GPS_LONGITUDE_REF};
1294     static std::vector exifFormatRational{EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE, EXIF_TAG_APERTURE_VALUE};
1295     static std::vector exifFormatSRational{EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME, EXIF_TAG_FNUMBER,
1296         EXIF_TAG_FOCAL_LENGTH};
1297     if (std::find(exifFormatAscii.begin(), exifFormatAscii.end(), tag) != exifFormatAscii.end()) {
1298         return EXIF_FORMAT_ASCII;
1299     } else if (std::find(exifFormatRational.begin(), exifFormatRational.end(), tag) != exifFormatRational.end()) {
1300         return EXIF_FORMAT_RATIONAL;
1301     } else if (std::find(exifFormatSRational.begin(), exifFormatSRational.end(), tag) != exifFormatSRational.end()) {
1302         return EXIF_FORMAT_SRATIONAL;
1303     } else if (tag == EXIF_TAG_SCENE_TYPE || tag == EXIF_TAG_USER_COMMENT) {
1304         return EXIF_FORMAT_UNDEFINED;
1305     } else if (tag == EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY) {
1306         return EXIF_FORMAT_LONG;
1307     }
1308     return EXIF_FORMAT_UNDEFINED;
1309 }
1310 
GetExifNameByExifTag(const ExifTag & tag)1311 std::string EXIFInfo::GetExifNameByExifTag(const ExifTag &tag)
1312 {
1313     for (uint32_t i = 0; i < sizeof(EXIF_TAG_TABLE) / sizeof(EXIF_TAG_TABLE[0]); i++) {
1314         if (EXIF_TAG_TABLE[i].tag != tag) {
1315             return EXIF_TAG_TABLE[i].name;
1316         }
1317     }
1318     return "";
1319 }
CreateExifEntryOfRationalExif(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry,const std::string & separator,size_t sepSize)1320 bool EXIFInfo::CreateExifEntryOfRationalExif(const ExifTag &tag, ExifData *data, const std::string &value,
1321     ExifByteOrder order, ExifEntry **ptrEntry, const std::string& separator, size_t sepSize)
1322 {
1323     std::vector<std::string> longVec;
1324     SplitStr(value, separator, longVec);
1325     if (longVec.size() != sepSize) {
1326         IMAGE_LOGD("%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(), value.c_str());
1327         return false;
1328     }
1329     ExifRational longRational;
1330     longRational.numerator = static_cast<ExifLong>(atoi(longVec[0].c_str()));
1331     longRational.denominator = static_cast<ExifLong>(atoi(longVec[1].c_str()));
1332     *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, sizeof(longRational), GetExifFormatByExifTag(tag));
1333     bool cond = (*ptrEntry) == nullptr;
1334     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.", GetExifNameByExifTag(tag).c_str());
1335     exif_set_rational((*ptrEntry)->data, order, longRational);
1336     return true;
1337 }
1338 
CreateExifEntryOfGpsTimeStamp(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1339 bool EXIFInfo::CreateExifEntryOfGpsTimeStamp(const ExifTag &tag, ExifData *data, const std::string &value,
1340     ExifByteOrder order, ExifEntry **ptrEntry)
1341 {
1342     std::vector<std::string> longVec;
1343     SplitStr(value, ":", longVec);
1344     if (longVec.size() != CONSTANT_3) {
1345         IMAGE_LOGD("GPS time stamp Invalid value %{public}s", value.c_str());
1346         return false;
1347     }
1348     *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24, EXIF_FORMAT_SRATIONAL);
1349     bool cond = (*ptrEntry) == nullptr;
1350     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get GPS time stamp exif entry failed.");
1351     exif_set_long((*ptrEntry)->data, order, static_cast<ExifSLong>(atoi(longVec[CONSTANT_0].c_str())));
1352     exif_set_long((*ptrEntry)->data + MOVE_OFFSET_8, order,
1353                   static_cast<ExifSLong>(atoi(longVec[CONSTANT_1].c_str())));
1354     exif_set_long((*ptrEntry)->data + MOVE_OFFSET_16, order,
1355                   static_cast<ExifSLong>(atoi(longVec[CONSTANT_2].c_str())));
1356     return true;
1357 }
1358 
CreateExifEntryOfCompressedBitsPerPixel(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1359 bool EXIFInfo::CreateExifEntryOfCompressedBitsPerPixel(const ExifTag &tag, ExifData *data, const std::string &value,
1360     ExifByteOrder order, ExifEntry **ptrEntry)
1361 {
1362     *ptrEntry = InitExifTag(data, EXIF_IFD_EXIF, tag);
1363     bool cond = false;
1364     cond = (*ptrEntry) == nullptr;
1365     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1366     ExifRational rat;
1367     cond = !GetFractionFromStr(value, rat);
1368     CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get fraction from value failed.");
1369     exif_set_rational((*ptrEntry)->data, order, rat);
1370     return true;
1371 }
1372 
CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1373 bool EXIFInfo::CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag &tag, ExifData *data, const std::string &value,
1374     ExifByteOrder order, ExifEntry **ptrEntry)
1375 {
1376     std::vector<std::string> longVec;
1377     SplitStr(value, ",", longVec);
1378     if (longVec.size() == CONSTANT_2) {
1379         return SetGpsDegreeRational(data, ptrEntry, order, tag, longVec);
1380     }
1381     if (longVec.size() != CONSTANT_3 || !IsValidGpsData(longVec, tag)) {
1382         IMAGE_LOGD("%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(),
1383             value.c_str());
1384         return false;
1385     }
1386     std::vector<ExifRational> longRational(GPS_DMS_COUNT);
1387     return ConvertGpsDataToRationals(longVec, longRational) &&
1388         SetGpsRationals(data, ptrEntry, order, tag, longRational);
1389 }
1390 
CreateExifEntry(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1391 bool EXIFInfo::CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
1392     ExifByteOrder order, ExifEntry **ptrEntry)
1393 {
1394     static std::vector vector1{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1395         EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH, EXIF_TAG_ISO_SPEED_RATINGS,
1396         EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE, EXIF_TAG_PIXEL_X_DIMENSION,
1397         EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_SENSITIVITY_TYPE};
1398     static std::vector vector2{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL,
1399         EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT, EXIF_TAG_DATE_TIME_ORIGINAL,
1400         EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF};
1401     static std::vector vector3{EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1402         EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1403     bool cond = false;
1404     if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
1405         return CreateExifEntryOfBitsPerSample(tag, data, value, order, ptrEntry);
1406     } else if (std::find(vector1.begin(), vector1.end(), tag) != vector1.end()) {
1407         *ptrEntry = InitExifTag(data, GetExifIfdByExifTag(tag), tag);
1408         cond = (*ptrEntry) == nullptr;
1409         CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.",
1410                                    GetExifNameByExifTag(tag).c_str());
1411         ExifIntValueByFormat((*ptrEntry)->data, order, (*ptrEntry)->format, atoi(value.c_str()));
1412         return true;
1413     } else if (std::find(vector2.begin(), vector2.end(), tag) != vector2.end()) {
1414         *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, value.length(), GetExifFormatByExifTag(tag));
1415         cond = (*ptrEntry) == nullptr || (*ptrEntry)->size < value.length();
1416         CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.",
1417                                    GetExifNameByExifTag(tag).c_str());
1418         if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
1419             IMAGE_LOGD("%{public}s memcpy error", GetExifNameByExifTag(tag).c_str());
1420         }
1421         return true;
1422     } else if (tag == EXIF_TAG_GPS_LATITUDE || tag == EXIF_TAG_GPS_LONGITUDE) {
1423         return CreateExifEntryOfGpsLatitudeOrLongitude(tag, data, value, order, ptrEntry);
1424     } else if (std::find(vector3.begin(), vector3.end(), tag) != vector3.end()) {
1425         return CreateExifEntryOfRationalExif(tag, data, value, order, ptrEntry, "/", static_cast<size_t>(CONSTANT_2));
1426     } else if (tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1427         return CreateExifEntryOfCompressedBitsPerPixel(tag, data, value, order, ptrEntry);
1428     } else if (tag == EXIF_TAG_GPS_TIME_STAMP) {
1429         return CreateExifEntryOfGpsTimeStamp(tag, data, value, order, ptrEntry);
1430     }
1431     return true;
1432 }
1433 
WriteExifDataToFile(ExifData * data,unsigned int orginExifDataLength,unsigned long fileLength,unsigned char * buf,FILE * fp)1434 bool EXIFInfo::WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
1435     unsigned char *buf, FILE *fp)
1436 {
1437     unsigned char* exifDataBuf = nullptr;
1438     unsigned int exifDataBufLength = 0;
1439     exif_data_save_data(data, &exifDataBuf, &exifDataBufLength);
1440     if (exifDataBuf == nullptr) {
1441         IMAGE_LOGD("Get Exif Data Buf failed!");
1442         return false;
1443     }
1444 
1445     // Write EXIF header
1446     if (fwrite(EXIF_HEADER, sizeof(EXIF_HEADER), 1, fp) != 1) {
1447         IMAGE_LOGD("Error writing EXIF header to file!");
1448         ReleaseExifDataBuffer(exifDataBuf);
1449         return false;
1450     }
1451 
1452     // Write EXIF block length in big-endian order
1453     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, fp) < 0) {
1454         IMAGE_LOGD("Error writing EXIF block length to file!");
1455         ReleaseExifDataBuffer(exifDataBuf);
1456         return false;
1457     }
1458 
1459     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, fp) < 0) {
1460         IMAGE_LOGD("Error writing EXIF block length to file!");
1461         ReleaseExifDataBuffer(exifDataBuf);
1462         return false;
1463     }
1464 
1465     // Write EXIF data block
1466     if (fwrite(exifDataBuf, exifDataBufLength, 1, fp) != 1) {
1467         IMAGE_LOGD("Error writing EXIF data block to file!");
1468         ReleaseExifDataBuffer(exifDataBuf);
1469         return false;
1470     }
1471     // Write JPEG image data, skipping the non-EXIF header
1472     unsigned int dataOffset = orginExifDataLength + sizeof(EXIF_HEADER);
1473     if (fwrite(buf + dataOffset, fileLength - dataOffset, 1, fp) != 1) {
1474         IMAGE_LOGD("Error writing JPEG image data to file!");
1475         ReleaseExifDataBuffer(exifDataBuf);
1476         return false;
1477     }
1478 
1479     UpdateCacheExifData(fp);
1480     ReleaseExifDataBuffer(exifDataBuf);
1481     return true;
1482 }
1483 
ReleaseSource(unsigned char ** ptrBuf,FILE ** ptrFile)1484 void EXIFInfo::ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile)
1485 {
1486     if (ptrBuf != nullptr && *ptrBuf != nullptr) {
1487         free(*ptrBuf);
1488         *ptrBuf = nullptr;
1489         ptrBuf = nullptr;
1490     }
1491 
1492     if (ptrFile != nullptr && *ptrFile != nullptr) {
1493         fclose(*ptrFile);
1494         *ptrFile = nullptr;
1495         ptrFile = nullptr;
1496     }
1497 }
1498 
UpdateCacheExifData(FILE * fp)1499 void EXIFInfo::UpdateCacheExifData(FILE *fp)
1500 {
1501     unsigned long fileLength = GetFileSize(fp);
1502     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
1503         IMAGE_LOGD("Get file size failed.");
1504         return;
1505     }
1506 
1507     unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
1508     if (fileBuf == nullptr) {
1509         IMAGE_LOGD("Allocate buf failed.");
1510         return;
1511     }
1512 
1513     // Set current position to begin of file.
1514     (void)fseek(fp, 0L, 0);
1515     if (fread(fileBuf, fileLength, 1, fp) != 1) {
1516         IMAGE_LOGD("Read new file failed.");
1517         free(fileBuf);
1518         fileBuf = nullptr;
1519         return;
1520     }
1521 
1522     ParseExifData(fileBuf, static_cast<unsigned int>(fileLength));
1523     free(fileBuf);
1524     fileBuf = nullptr;
1525 }
1526 
GetFilterArea(const uint8_t * buf,const uint32_t & bufSize,const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1527 uint32_t EXIFInfo::GetFilterArea(const uint8_t *buf,
1528                                  const uint32_t &bufSize,
1529                                  const int &privacyType,
1530                                  std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1531 {
1532     std::unique_ptr<ByteOrderedBuffer> byteOrderedBuffer = std::make_unique<ByteOrderedBuffer>(buf, bufSize);
1533     byteOrderedBuffer->GenerateDEArray();
1534     if (byteOrderedBuffer->directoryEntryArray_.size() == 0) {
1535         IMAGE_LOGD("Read Exif info range failed.");
1536         return ERROR_PARSE_EXIF_FAILED;
1537     }
1538 
1539     GetAreaFromExifEntries(privacyType, byteOrderedBuffer->directoryEntryArray_, ranges);
1540     bool cond = ranges.size() == 0;
1541     CHECK_DEBUG_RETURN_RET_LOG(cond, ERROR_NO_EXIF_TAGS, "There is no exif info need filtered in this image.");
1542 
1543     return Media::SUCCESS;
1544 }
1545 
GetAreaFromExifEntries(const int & privacyType,const std::vector<DirectoryEntry> & entryArray,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1546 void EXIFInfo::GetAreaFromExifEntries(const int &privacyType,
1547                                       const std::vector<DirectoryEntry> &entryArray,
1548                                       std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1549 {
1550     if (privacyType == PERMISSION_GPS_TYPE) {
1551         for (size_t i = 0; i < entryArray.size(); i++) {
1552             if (entryArray[i].ifd == EXIF_IFD_GPS) {
1553                 std::pair<uint32_t, uint32_t> range =
1554                     std::make_pair(entryArray[i].valueOffset, entryArray[i].valueLength);
1555                 ranges.push_back(range);
1556             }
1557         }
1558     }
1559 }
1560 
ByteOrderedBuffer(const uint8_t * fileBuf,uint32_t bufferLength)1561 ByteOrderedBuffer::ByteOrderedBuffer(const uint8_t *fileBuf, uint32_t bufferLength)
1562     : buf_(fileBuf), bufferLength_(bufferLength)
1563 {
1564     if (bufferLength >= BUFFER_POSITION_12 && bufferLength >= BUFFER_POSITION_13) {
1565         if (fileBuf[BUFFER_POSITION_12] == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') {
1566             byteOrder_ = EXIF_BYTE_ORDER_MOTOROLA;
1567         } else {
1568             byteOrder_ = EXIF_BYTE_ORDER_INTEL;
1569         }
1570     }
1571 }
1572 
~ByteOrderedBuffer()1573 ByteOrderedBuffer::~ByteOrderedBuffer() {}
1574 
GenerateDEArray()1575 void ByteOrderedBuffer::GenerateDEArray()
1576 {
1577     // Move current position to begin of IFD0 offset segment
1578     curPosition_ = TIFF_OFFSET_FROM_FILE_BEGIN + CONSTANT_4;
1579     int32_t ifd0Offset = ReadInt32();
1580     if (ifd0Offset < 0) {
1581         IMAGE_LOGD("Get IFD0 offset failed!");
1582         return;
1583     }
1584     // Transform tiff offset to position of file
1585     ifd0Offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(ifd0Offset));
1586     // Move current position to begin of IFD0 segment
1587     curPosition_ = static_cast<uint32_t>(ifd0Offset);
1588 
1589     bool cond = curPosition_ + CONSTANT_2 > bufferLength_;
1590     CHECK_DEBUG_RETURN_LOG(cond, "There is no data from the offset: %{public}d.", curPosition_);
1591     GetDataRangeFromIFD(EXIF_IFD_0);
1592 }
1593 
GetDataRangeFromIFD(const ExifIfd & ifd)1594 void ByteOrderedBuffer::GetDataRangeFromIFD(const ExifIfd &ifd)
1595 {
1596     handledIfdOffsets_.push_back(curPosition_);
1597     int16_t entryCount = ReadShort();
1598     if (static_cast<uint32_t>(curPosition_ + BYTE_COUNTS_12 * entryCount) > bufferLength_ || entryCount <= 0) {
1599         IMAGE_LOGD(" The size of entries is either too big or negative.");
1600         return;
1601     }
1602     GetDataRangeFromDE(ifd, entryCount);
1603 
1604     if (Peek() + CONSTANT_4 <= bufferLength_) {
1605         int32_t nextIfdOffset = ReadInt32();
1606         if (nextIfdOffset == 0) {
1607             IMAGE_LOGD("Stop reading file since this IFD is finished");
1608             return;
1609         }
1610         // Transform tiff offset to position of file
1611         if (nextIfdOffset != -1) {
1612             nextIfdOffset = static_cast<int32_t>(TransformTiffOffsetToFilePos(nextIfdOffset));
1613         }
1614         // Check if the next IFD offset
1615         // 1. Exists within the boundaries of the buffer
1616         // 2. Does not point to a previously read IFD.
1617         if (nextIfdOffset > 0L && static_cast<uint32_t>(nextIfdOffset) < bufferLength_) {
1618             if (!IsIFDhandled(nextIfdOffset)) {
1619                 curPosition_ = static_cast<uint32_t>(nextIfdOffset);
1620                 ExifIfd nextIfd = GetNextIfdFromLinkList(ifd);
1621                 GetDataRangeFromIFD(nextIfd);
1622             } else {
1623                 IMAGE_LOGD("Stop reading buffer since re-reading an IFD at %{public}d.", nextIfdOffset);
1624             }
1625         } else {
1626             IMAGE_LOGD("Stop reading file since a wrong offset at %{public}d.", nextIfdOffset);
1627         }
1628     }
1629 }
1630 
GetDataRangeFromDE(const ExifIfd & ifd,const int16_t & count)1631 void ByteOrderedBuffer::GetDataRangeFromDE(const ExifIfd &ifd, const int16_t &count)
1632 {
1633     for (int16_t i = 0; i < count; i++) {
1634         uint16_t tagNumber = ReadUnsignedShort();
1635         uint16_t dataFormat = ReadUnsignedShort();
1636         int32_t numberOfComponents = ReadInt32();
1637         uint32_t nextEntryOffset = Peek() + CONSTANT_4;
1638 
1639         uint32_t byteCount = 0;
1640         bool valid = SetDEDataByteCount(tagNumber, dataFormat, numberOfComponents, byteCount);
1641         if (!valid) {
1642             curPosition_ = static_cast<uint32_t>(nextEntryOffset);
1643             continue;
1644         }
1645 
1646         // Read a value from data field or seek to the value offset which is stored in data
1647         // field if the size of the entry value is bigger than 4.
1648         // If the size of the entry value is less than 4, value is stored in value offset area.
1649         if (byteCount > CONSTANT_4) {
1650             int32_t offset = ReadInt32();
1651             // Transform tiff offset to position of file
1652             if (offset != -1) {
1653                 offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(offset));
1654             }
1655             if ((static_cast<uint32_t>(offset) + byteCount) <= bufferLength_) {
1656                 curPosition_ = static_cast<uint32_t>(offset);
1657             } else {
1658                 // Skip if invalid data offset.
1659                 IMAGE_LOGI("Skip the tag entry since data offset is invalid: %{public}d.", offset);
1660                 curPosition_ = nextEntryOffset;
1661                 continue;
1662             }
1663         }
1664 
1665         // Recursively parse IFD when a IFD pointer tag appears
1666         if (IsIFDPointerTag(tagNumber)) {
1667             ExifIfd ifdOfIFDPointerTag = GetIFDOfIFDPointerTag(tagNumber);
1668             ParseIFDPointerTag(ifdOfIFDPointerTag, dataFormat);
1669             curPosition_ = nextEntryOffset;
1670             continue;
1671         }
1672 
1673         uint32_t bytesOffset = Peek();
1674         uint32_t bytesLength = byteCount;
1675         DirectoryEntry directoryEntry = {static_cast<ExifTag>(tagNumber), static_cast<ExifFormat>(dataFormat),
1676                                          numberOfComponents, bytesOffset, bytesLength, ifd};
1677         directoryEntryArray_.push_back(directoryEntry);
1678 
1679         // Seek to next tag offset
1680         if (Peek() != nextEntryOffset) {
1681             curPosition_ = nextEntryOffset;
1682         }
1683     }
1684 }
1685 
TransformTiffOffsetToFilePos(const uint32_t & offset)1686 uint32_t ByteOrderedBuffer::TransformTiffOffsetToFilePos(const uint32_t &offset)
1687 {
1688     return offset + TIFF_OFFSET_FROM_FILE_BEGIN;
1689 }
1690 
SetDEDataByteCount(const uint16_t & tagNumber,const uint16_t & dataFormat,const int32_t & numberOfComponents,uint32_t & count)1691 bool ByteOrderedBuffer::SetDEDataByteCount(const uint16_t &tagNumber,
1692                                            const uint16_t &dataFormat,
1693                                            const int32_t &numberOfComponents,
1694                                            uint32_t &count)
1695 {
1696     if (IsValidTagNumber(tagNumber)) {
1697         IMAGE_LOGD("Skip the tag entry since tag number is not defined: %{public}d.", tagNumber);
1698     } else if (dataFormat <= 0 || exif_format_get_size(static_cast<ExifFormat>(dataFormat)) == 0) {
1699         IMAGE_LOGD("Skip the tag entry since data format is invalid: %{public}d.", dataFormat);
1700     } else {
1701         count = static_cast<uint32_t>(numberOfComponents) *
1702                 static_cast<uint32_t>(exif_format_get_size(static_cast<ExifFormat>(dataFormat)));
1703         if (count < 0) {
1704             IMAGE_LOGD("Skip the tag entry since the number of components is invalid: %{public}d.",
1705                 numberOfComponents);
1706         } else {
1707             return true;
1708         }
1709     }
1710     return false;
1711 }
1712 
ParseIFDPointerTag(const ExifIfd & ifd,const uint16_t & dataFormat)1713 void ByteOrderedBuffer::ParseIFDPointerTag(const ExifIfd &ifd, const uint16_t &dataFormat)
1714 {
1715     uint32_t offset = 0U;
1716     // Get offset from data field
1717     switch (static_cast<ExifFormat>(dataFormat)) {
1718         case EXIF_FORMAT_SHORT: {
1719             offset = static_cast<uint32_t>(ReadUnsignedShort());
1720             break;
1721         }
1722         case EXIF_FORMAT_SSHORT: {
1723             offset = ReadShort();
1724             break;
1725         }
1726         case EXIF_FORMAT_LONG: {
1727             offset = ReadUnsignedInt32();
1728             break;
1729         }
1730         case EXIF_FORMAT_SLONG: {
1731             offset = static_cast<uint32_t>(ReadInt32());
1732             break;
1733         }
1734         default: {
1735             // Nothing to do
1736             break;
1737         }
1738     }
1739     // Transform tiff offset to position of file
1740     offset = TransformTiffOffsetToFilePos(offset);
1741     // Check if the next IFD offset
1742     // 1. Exists within the boundaries of the buffer
1743     // 2. Does not point to a previously read IFD.
1744     if (offset > 0L && offset < bufferLength_) {
1745         if (!IsIFDhandled(offset)) {
1746             curPosition_ = offset;
1747             GetDataRangeFromIFD(ifd);
1748         } else {
1749             IMAGE_LOGD("Skip jump into the IFD since it has already been read at %{public}d.", offset);
1750         }
1751     } else {
1752         IMAGE_LOGD("Skip jump into the IFD since its offset is invalid: %{public}d.", offset);
1753     }
1754 }
1755 
IsValidTagNumber(const uint16_t & tagNumber)1756 bool ByteOrderedBuffer::IsValidTagNumber(const uint16_t &tagNumber)
1757 {
1758     bool cond = false;
1759     for (uint32_t i = 0; (IsSameTextStr(EXIF_TAG_TABLE[i].name, "")); i++) {
1760         cond = EXIF_TAG_TABLE[i].number == tagNumber;
1761         CHECK_ERROR_RETURN_RET(cond, true);
1762     }
1763     return false;
1764 }
1765 
IsIFDhandled(const uint32_t & position)1766 bool ByteOrderedBuffer::IsIFDhandled(const uint32_t &position)
1767 {
1768     if (handledIfdOffsets_.size() == 0) {
1769         IMAGE_LOGD("There is no handled IFD!");
1770         return false;
1771     }
1772 
1773     for (size_t i = 0; i < handledIfdOffsets_.size(); i++) {
1774         if (handledIfdOffsets_[i] == position) {
1775             return true;
1776         }
1777     }
1778     return false;
1779 }
1780 
IsIFDPointerTag(const uint16_t & tagNumber)1781 bool ByteOrderedBuffer::IsIFDPointerTag(const uint16_t &tagNumber)
1782 {
1783     bool ret = false;
1784     switch (static_cast<ExifTag>(tagNumber)) {
1785         case EXIF_TAG_SUB_IFDS:
1786         case EXIF_TAG_EXIF_IFD_POINTER:
1787         case EXIF_TAG_GPS_INFO_IFD_POINTER:
1788         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
1789             ret = true;
1790             break;
1791         default:
1792             break;
1793     }
1794     return ret;
1795 }
1796 
GetIFDOfIFDPointerTag(const uint16_t & tagNumber)1797 ExifIfd ByteOrderedBuffer::GetIFDOfIFDPointerTag(const uint16_t &tagNumber)
1798 {
1799     ExifIfd ifd = EXIF_IFD_COUNT;
1800     switch (static_cast<ExifTag>(tagNumber)) {
1801         case EXIF_TAG_EXIF_IFD_POINTER: {
1802             ifd = EXIF_IFD_EXIF;
1803             break;
1804         }
1805         case EXIF_TAG_GPS_INFO_IFD_POINTER: {
1806             ifd = EXIF_IFD_GPS;
1807             break;
1808         }
1809         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: {
1810             ifd = EXIF_IFD_INTEROPERABILITY;
1811             break;
1812         }
1813         default: {
1814             break;
1815         }
1816     }
1817     return ifd;
1818 }
1819 
GetNextIfdFromLinkList(const ExifIfd & ifd)1820 ExifIfd ByteOrderedBuffer::GetNextIfdFromLinkList(const ExifIfd &ifd)
1821 {
1822     ExifIfd nextIfd = EXIF_IFD_COUNT;
1823     /**
1824      * In jpeg file, the next IFD of IFD_0 in IFD link list is IFD_1,
1825      * other IFD is pointed by tag.
1826      */
1827     if (ifd == EXIF_IFD_0) {
1828         nextIfd = EXIF_IFD_1;
1829     }
1830     return nextIfd;
1831 }
1832 
ReadInt32()1833 int32_t ByteOrderedBuffer::ReadInt32()
1834 {
1835     // Move current position to begin of next segment
1836     curPosition_ += CONSTANT_4;
1837     if (curPosition_ > bufferLength_) {
1838         IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1839         return -1;
1840     }
1841 
1842     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1843         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]) << MOVE_OFFSET_24) |
1844                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_16) |
1845                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1846                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1847     } else {
1848         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_24) |
1849                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_16) |
1850                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_8) |
1851                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]));
1852     }
1853 }
1854 
ReadUnsignedInt32()1855 uint32_t ByteOrderedBuffer::ReadUnsignedInt32()
1856 {
1857     return (static_cast<uint32_t>(ReadInt32()) & 0xffffffff);
1858 }
1859 
ReadShort()1860 int16_t ByteOrderedBuffer::ReadShort()
1861 {
1862     // Move current position to begin of next segment
1863     curPosition_ += CONSTANT_2;
1864     if (curPosition_ > bufferLength_) {
1865         IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1866         return -1;
1867     }
1868 
1869     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1870         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1871                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1872     } else {
1873         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_8) |
1874                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]));
1875     }
1876 }
1877 
ReadUnsignedShort()1878 uint16_t ByteOrderedBuffer::ReadUnsignedShort()
1879 {
1880     return (static_cast<uint32_t>(ReadShort()) & 0xffff);
1881 }
1882 
Peek()1883 uint32_t ByteOrderedBuffer::Peek()
1884 {
1885     return curPosition_;
1886 }
1887 
CheckExifEntryValid(const ExifIfd & ifd,const ExifTag & tag)1888 bool EXIFInfo::CheckExifEntryValid(const ExifIfd &ifd, const ExifTag &tag)
1889 {
1890     bool ret = false;
1891     switch (ifd) {
1892         case EXIF_IFD_0: {
1893             if (tag == EXIF_TAG_ORIENTATION ||
1894                 tag == EXIF_TAG_BITS_PER_SAMPLE ||
1895                 tag == EXIF_TAG_IMAGE_LENGTH ||
1896                 tag == EXIF_TAG_IMAGE_WIDTH) {
1897                 ret = true;
1898             }
1899             break;
1900         }
1901         case EXIF_IFD_EXIF: {
1902             if (tag == EXIF_TAG_DATE_TIME_ORIGINAL ||
1903                 tag == EXIF_TAG_EXPOSURE_TIME ||
1904                 tag == EXIF_TAG_FNUMBER ||
1905                 tag == EXIF_TAG_ISO_SPEED_RATINGS ||
1906                 tag == EXIF_TAG_SCENE_TYPE ||
1907                 tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1908                 ret = true;
1909             }
1910             break;
1911         }
1912         case EXIF_IFD_GPS: {
1913             if (tag == EXIF_TAG_GPS_LATITUDE ||
1914                 tag == EXIF_TAG_GPS_LONGITUDE ||
1915                 tag == EXIF_TAG_GPS_LATITUDE_REF ||
1916                 tag == EXIF_TAG_GPS_LONGITUDE_REF) {
1917                 ret = true;
1918             }
1919             break;
1920         }
1921         default:
1922             break;
1923     }
1924 
1925     if (!ret) {
1926         ret = CheckExifEntryValidEx(ifd, tag);
1927     }
1928 
1929     return ret;
1930 }
1931 
CheckExifEntryValidEx(const ExifIfd & ifd,const ExifTag & tag)1932 bool EXIFInfo::CheckExifEntryValidEx(const ExifIfd &ifd, const ExifTag &tag)
1933 {
1934     static std::vector<ExifTag> ifd0TagVec{EXIF_TAG_DATE_TIME, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1935         EXIF_TAG_MODEL};
1936     static std::vector<ExifTag> ifdExifTagVec{TAG_SENSITIVITY_TYPE, TAG_STANDARD_OUTPUT_SENSITIVITY,
1937         TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_METERING_MODE,
1938         EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_FLASH, EXIF_TAG_FOCAL_LENGTH, EXIF_TAG_USER_COMMENT, EXIF_TAG_PIXEL_X_DIMENSION,
1939         EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM};
1940     bool ret = false;
1941     switch (ifd) {
1942         case EXIF_IFD_0: {
1943             return std::find(ifd0TagVec.begin(), ifd0TagVec.end(), tag) != ifd0TagVec.end();
1944         }
1945         case EXIF_IFD_EXIF: {
1946             return std::find(ifdExifTagVec.begin(), ifdExifTagVec.end(), tag) != ifdExifTagVec.end();
1947         }
1948         case EXIF_IFD_GPS: {
1949             return tag == EXIF_TAG_GPS_TIME_STAMP || tag == EXIF_TAG_GPS_DATE_STAMP;
1950         }
1951         default:
1952             break;
1953     }
1954 
1955     return ret;
1956 }
1957 
NumSplit(std::string & src,std::vector<std::string> & out)1958 static void NumSplit(std::string &src, std::vector<std::string> &out)
1959 {
1960     bool cond = src.size() == 0;
1961     CHECK_ERROR_RETURN(cond);
1962     std::vector<std::string> res;
1963     size_t last = 0;
1964     for (size_t i = 0; i < src.size(); i++) {
1965         if (!std::isdigit(src[i])) {
1966             size_t splitSize = i - last;
1967             if (splitSize != 0) {
1968                 res.push_back(src.substr(last, splitSize));
1969             }
1970             last = i + SIZE_1;
1971         }
1972     }
1973     if (last <= (src.size() - SIZE_1)) {
1974         res.push_back(src.substr(last));
1975     }
1976     for (size_t i = 0; i < res.size() && i < out.size(); i++) {
1977         out[i] = res[i];
1978     }
1979 }
1980 
JoinStr(std::vector<std::string> & in,const std::string & delim)1981 static std::string JoinStr(std::vector<std::string> &in, const std::string &delim)
1982 {
1983     std::string res = "";
1984     for (size_t i = 0; i < (in.size() - SIZE_1); i++) {
1985         res.append(in[i]).append(delim);
1986     }
1987     res.append(in.back());
1988     return res;
1989 }
1990 
FormatTimeStamp(std::string & src,std::string & value)1991 static void FormatTimeStamp(std::string &src, std::string &value)
1992 {
1993     std::string date = src;
1994     std::string time = "";
1995     std::string::size_type position = src.find(" ");
1996     if (position != src.npos) {
1997         // Date and time
1998         date = src.substr(0, position);
1999         time = src.substr(position);
2000     }
2001     std::vector<std::string> dateVector = {"1970", "01", "01"};
2002     std::vector<std::string> timeVector = {"00", "00", "00"};
2003     NumSplit(date, dateVector);
2004     NumSplit(time, timeVector);
2005     value = JoinStr(dateVector, "-") + " " + JoinStr(timeVector, ":");
2006 }
2007 
SpecialExifData(EXIFInfo * info,const std::string & name,std::string & value)2008 static uint32_t SpecialExifData(EXIFInfo* info, const std::string &name, std::string &value)
2009 {
2010     if (IsSameTextStr(DATE_TIME_ORIGINAL_MEDIA, name)) {
2011         std::string orgValue;
2012         auto res = info->GetExifData(DATE_TIME_ORIGINAL, orgValue);
2013         if (res == Media::SUCCESS) {
2014             FormatTimeStamp(orgValue, value);
2015         }
2016         return res;
2017     } else if (IsSameTextStr(TAG_ORIENTATION_INT, name)) {
2018         std::string orgValue;
2019         auto res = info->GetExifData(TAG_ORIENTATION_STRING, orgValue);
2020         if (res != Media::SUCCESS) {
2021             return res;
2022         }
2023         bool cond = ORIENTATION_INT_MAP.count(orgValue) == 0;
2024         CHECK_DEBUG_RETURN_RET_LOG(cond, Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT,
2025                                    "SpecialExifData %{public}s not found %{public}s.",
2026                                    name.c_str(), orgValue.c_str());
2027         value = std::to_string(ORIENTATION_INT_MAP.at(orgValue));
2028         return res;
2029     }
2030     return Media::ERR_MEDIA_STATUS_ABNORMAL;
2031 }
2032 
GetExifTagByName(const std::string & name,ExifTag & tag)2033 static bool GetExifTagByName(const std::string &name, ExifTag &tag)
2034 {
2035     auto find_item = std::find_if(TAG_MAP.begin(), TAG_MAP.end(),
2036         [name](const std::map<ExifTag, std::string>::value_type item) {
2037         return IsSameTextStr(item.second, name);
2038     });
2039     auto find_maker_item = std::find_if(TAG_MAKER_NOTE_MAP.begin(), TAG_MAKER_NOTE_MAP.end(),
2040         [name](const std::map<ExifTag, std::string>::value_type item) {
2041         return IsSameTextStr(item.second, name);
2042     });
2043     if (find_item == TAG_MAP.end() && find_maker_item == TAG_MAKER_NOTE_MAP.end()) {
2044         return false;
2045     }
2046     tag = find_item->first;
2047     return true;
2048 }
2049 
GetExifData(const std::string name,std::string & value)2050 uint32_t EXIFInfo::GetExifData(const std::string name, std::string &value)
2051 {
2052     auto res = SpecialExifData(this, name, value);
2053     if (res == Media::SUCCESS || res != Media::ERR_MEDIA_STATUS_ABNORMAL) {
2054         IMAGE_LOGD("GetExifData %{public}s special result with %{public}d.", name.c_str(), res);
2055         return res;
2056     }
2057     ExifTag tag;
2058     if (!GetExifTagByName(name, tag)) {
2059         IMAGE_LOGD("GetExifData %{public}s not in the TAGs map.", name.c_str());
2060         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2061     }
2062     DumpTagsMap(exifTags_);
2063     bool cond = !exifTags_.Find(tag, value);
2064     CHECK_DEBUG_RETURN_RET_LOG(cond, Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT,
2065                                "GetExifData has no tag %{public}s[%{public}d], tags Size: %{public}zu.",
2066                                name.c_str(), tag, static_cast<size_t>(exifTags_.Size()));
2067     if (IsSameTextStr(value, DEFAULT_EXIF_VALUE)) {
2068         IMAGE_LOGD("GetExifData %{public}s[%{public}d] value is DEFAULT_EXIF_VALUE.",
2069             name.c_str(), tag);
2070         return Media::ERR_MEDIA_VALUE_INVALID;
2071     }
2072     return Media::SUCCESS;
2073 }
2074 
ModifyExifData(const std::string name,const std::string & value,const std::string & path)2075 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const std::string &path)
2076 {
2077     ExifTag tag;
2078     if (!GetExifTagByName(name, tag)) {
2079         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2080         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2081     }
2082     return ModifyExifData(tag, value, path);
2083 }
2084 
ModifyExifData(const std::string name,const std::string & value,const int fd)2085 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const int fd)
2086 {
2087     ExifTag tag;
2088     if (!GetExifTagByName(name, tag)) {
2089         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2090         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2091     }
2092     return ModifyExifData(tag, value, fd);
2093 }
2094 
ModifyExifData(const std::string name,const std::string & value,unsigned char * data,uint32_t size)2095 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, unsigned char *data, uint32_t size)
2096 {
2097     ExifTag tag;
2098     if (!GetExifTagByName(name, tag)) {
2099         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2100         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2101     }
2102     return ModifyExifData(tag, value, data, size);
2103 }
2104 } // namespace ImagePlugin
2105 } // namespace OHOS
2106