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 bool cond = errno == ERANGE && *endPtr != '\0';
1099 CHECK_ERROR_RETURN_RET(cond, false);
1100 return true;
1101 }
1102
GetFractionFromStr(const std::string & decimal,ExifRational & result)1103 static bool GetFractionFromStr(const std::string &decimal, ExifRational &result)
1104 {
1105 int intPart = 0;
1106 std::string intPartStr = decimal.substr(0, decimal.find("."));
1107 CHECK_ERROR_RETURN_RET_LOG(!ConvertToInt(intPartStr, intPart), false,
1108 "%{public}s failed, value out of range", __func__);
1109
1110 double decPart = 0.0;
1111 std::string decPartStr = decimal.substr(decimal.find("."));
1112 CHECK_ERROR_RETURN_RET_LOG(!ConvertToDouble(decPartStr, decPart), false,
1113 "%{public}s failed, value out of range", __func__);
1114
1115 int numerator = decPart * pow(10, decimal.length() - decimal.find(".") - 1);
1116 int denominator = pow(10, decimal.length() - decimal.find(".") - 1);
1117
1118 int gcdVal = GCD(numerator, denominator);
1119 bool cond = gcdVal == 0;
1120 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "gcdVal is zero");
1121 numerator /= gcdVal;
1122 denominator /= gcdVal;
1123
1124 numerator += intPart * denominator;
1125
1126 result.numerator = static_cast<ExifLong>(numerator);
1127 result.denominator = static_cast<ExifLong>(denominator);
1128 return true;
1129 }
1130
ExifIntValueByFormat(unsigned char * b,ExifByteOrder order,ExifFormat format,long value)1131 static void ExifIntValueByFormat(unsigned char *b, ExifByteOrder order, ExifFormat format, long value)
1132 {
1133 switch (format) {
1134 case EXIF_FORMAT_SHORT:
1135 exif_set_short(b, order, (ExifShort)value);
1136 break;
1137 case EXIF_FORMAT_SSHORT:
1138 exif_set_sshort(b, order, (ExifSShort)value);
1139 break;
1140 case EXIF_FORMAT_LONG:
1141 exif_set_long(b, order, (ExifLong)value);
1142 break;
1143 case EXIF_FORMAT_SLONG:
1144 exif_set_slong(b, order, (ExifSLong)value);
1145 break;
1146 case EXIF_FORMAT_BYTE:
1147 case EXIF_FORMAT_SRATIONAL:
1148 case EXIF_FORMAT_UNDEFINED:
1149 case EXIF_FORMAT_ASCII:
1150 case EXIF_FORMAT_RATIONAL:
1151 default:
1152 IMAGE_LOGD("ExifIntValueByFormat unsupported format %{public}d.", format);
1153 break;
1154 }
1155 }
1156
ConvertStringToDouble(const std::string & str,double & number)1157 static bool ConvertStringToDouble(const std::string &str, double &number)
1158 {
1159 char* end = nullptr;
1160 number = std::strtod(str.c_str(), &end);
1161 return end != str.c_str() && *end == '\0' && number != HUGE_VAL;
1162 }
1163
IsValidGpsData(const std::vector<std::string> & dataVec,const ExifTag & tag)1164 static bool IsValidGpsData(const std::vector<std::string> &dataVec, const ExifTag &tag)
1165 {
1166 bool cond = false;
1167 cond = dataVec.size() != SIZE_3 || (tag != EXIF_TAG_GPS_LATITUDE && tag != EXIF_TAG_GPS_LONGITUDE);
1168 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Gps dms data size is invalid.");
1169 double degree = 0.0;
1170 double minute = 0.0;
1171 double second = 0.0;
1172 if (!ConvertStringToDouble(dataVec[CONSTANT_0], degree) ||
1173 !ConvertStringToDouble(dataVec[CONSTANT_1], minute) ||
1174 !ConvertStringToDouble(dataVec[CONSTANT_2], second)) {
1175 IMAGE_LOGE("Convert gps data to double type failed.");
1176 return false;
1177 }
1178 constexpr uint32_t timePeriod = 60;
1179 double latOrLong = degree + minute / timePeriod + second / (timePeriod * timePeriod);
1180 cond = (tag == EXIF_TAG_GPS_LATITUDE && (latOrLong > GPS_MAX_LATITUDE || latOrLong < GPS_MIN_LATITUDE)) ||
1181 (tag == EXIF_TAG_GPS_LONGITUDE && (latOrLong > GPS_MAX_LONGITUDE || latOrLong < GPS_MIN_LONGITUDE));
1182 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Gps latitude or longitude is out of range.");
1183 return true;
1184 }
1185
ConvertGpsDataToRationals(const std::vector<std::string> & dataVec,std::vector<ExifRational> & exifRationals)1186 static bool ConvertGpsDataToRationals(const std::vector<std::string> &dataVec,
1187 std::vector<ExifRational> &exifRationals)
1188 {
1189 bool cond = !(dataVec.size() == SIZE_3 && exifRationals.size() == SIZE_3);
1190 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Data size is invalid.");
1191
1192 int32_t degree = static_cast<int32_t>(atoi(dataVec[CONSTANT_0].c_str()));
1193 int32_t minute = static_cast<int32_t>(atoi(dataVec[CONSTANT_1].c_str()));
1194 double secondDouble = 0.0;
1195 ConvertStringToDouble(dataVec[CONSTANT_2], secondDouble);
1196 int32_t second = static_cast<int32_t>(secondDouble * GPS_DIGIT_NUMBER);
1197
1198 exifRationals[CONSTANT_0].numerator = static_cast<ExifLong>(degree);
1199 exifRationals[CONSTANT_0].denominator = static_cast<ExifLong>(1);
1200 exifRationals[CONSTANT_1].numerator = static_cast<ExifLong>(minute);
1201 exifRationals[CONSTANT_1].denominator = static_cast<ExifLong>(1);
1202 exifRationals[CONSTANT_2].numerator = static_cast<ExifLong>(second);
1203 exifRationals[CONSTANT_2].denominator = static_cast<ExifLong>(GPS_DIGIT_NUMBER);
1204 return true;
1205 }
1206
SetGpsRationals(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<ExifRational> & exifRationals)1207 bool EXIFInfo::SetGpsRationals(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order,
1208 const ExifTag &tag, const std::vector<ExifRational> &exifRationals)
1209 {
1210 if (exifRationals.size() != SIZE_3) {
1211 IMAGE_LOGD("ExifRationals size is invalid.");
1212 return false;
1213 }
1214 *ptrEntry = GetExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24);
1215 if ((*ptrEntry) == nullptr) {
1216 IMAGE_LOGD("Get exif entry failed.");
1217 return false;
1218 }
1219 exif_set_rational((*ptrEntry)->data, order, exifRationals[CONSTANT_0]);
1220 exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_8, order, exifRationals[CONSTANT_1]);
1221 exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_16, order, exifRationals[CONSTANT_2]);
1222 return true;
1223 }
1224
SetGpsDegreeRational(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<std::string> & dataVec)1225 bool EXIFInfo::SetGpsDegreeRational(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order, const ExifTag &tag,
1226 const std::vector<std::string> &dataVec)
1227 {
1228 CHECK_DEBUG_RETURN_RET_LOG(dataVec.size() != SIZE_2, false, "Gps degree data size is invalid.");
1229 ExifRational exifRational;
1230 exifRational.numerator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_0].c_str()));
1231 exifRational.denominator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_1].c_str()));
1232 *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_8, EXIF_FORMAT_RATIONAL);
1233 bool cond = (*ptrEntry) == nullptr;
1234 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1235 exif_set_rational((*ptrEntry)->data, order, exifRational);
1236 return true;
1237 }
1238
CreateExifEntryOfBitsPerSample(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1239 bool EXIFInfo::CreateExifEntryOfBitsPerSample(const ExifTag &tag, ExifData *data, const std::string &value,
1240 ExifByteOrder order, ExifEntry **ptrEntry)
1241 {
1242 *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_BITS_PER_SAMPLE);
1243 bool cond = (*ptrEntry) == nullptr;
1244 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1245 std::vector<std::string> bitsVec;
1246 SplitStr(value, ",", bitsVec);
1247 CHECK_DEBUG_RETURN_RET_LOG(bitsVec.size() > CONSTANT_4, false,
1248 "BITS_PER_SAMPLE Invalid value %{public}s", value.c_str());
1249 if (bitsVec.size() != 0) {
1250 for (size_t i = 0; i < bitsVec.size(); i++) {
1251 exif_set_short((*ptrEntry)->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str()));
1252 }
1253 }
1254 return true;
1255 }
1256
GetExifIfdByExifTag(const ExifTag & tag)1257 ExifIfd EXIFInfo::GetExifIfdByExifTag(const ExifTag &tag)
1258 {
1259 static std::vector exifIfd0Vec{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1260 EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME};
1261 static std::vector exifIfdExifVec{EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH,
1262 EXIF_TAG_ISO_SPEED_RATINGS, EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE,
1263 EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX,
1264 EXIF_TAG_SENSITIVITY_TYPE, EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT,
1265 EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1266 EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1267 static std::vector exifIfdGpsVec{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF,
1268 EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE};
1269 if (std::find(exifIfd0Vec.begin(), exifIfd0Vec.end(), tag) != exifIfd0Vec.end()) {
1270 return EXIF_IFD_0;
1271 } else if (std::find(exifIfdExifVec.begin(), exifIfdExifVec.end(), tag) != exifIfdExifVec.end()) {
1272 return EXIF_IFD_EXIF;
1273 } else if (std::find(exifIfdGpsVec.begin(), exifIfdGpsVec.end(), tag) != exifIfdGpsVec.end()) {
1274 return EXIF_IFD_GPS;
1275 }
1276 return EXIF_IFD_COUNT;
1277 }
1278
GetExifFormatByExifTag(const ExifTag & tag)1279 ExifFormat EXIFInfo::GetExifFormatByExifTag(const ExifTag &tag)
1280 {
1281 static std::vector exifFormatAscii{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1282 EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF,
1283 EXIF_TAG_GPS_LONGITUDE_REF};
1284 static std::vector exifFormatRational{EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE, EXIF_TAG_APERTURE_VALUE};
1285 static std::vector exifFormatSRational{EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME, EXIF_TAG_FNUMBER,
1286 EXIF_TAG_FOCAL_LENGTH};
1287 if (std::find(exifFormatAscii.begin(), exifFormatAscii.end(), tag) != exifFormatAscii.end()) {
1288 return EXIF_FORMAT_ASCII;
1289 } else if (std::find(exifFormatRational.begin(), exifFormatRational.end(), tag) != exifFormatRational.end()) {
1290 return EXIF_FORMAT_RATIONAL;
1291 } else if (std::find(exifFormatSRational.begin(), exifFormatSRational.end(), tag) != exifFormatSRational.end()) {
1292 return EXIF_FORMAT_SRATIONAL;
1293 } else if (tag == EXIF_TAG_SCENE_TYPE || tag == EXIF_TAG_USER_COMMENT) {
1294 return EXIF_FORMAT_UNDEFINED;
1295 } else if (tag == EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY) {
1296 return EXIF_FORMAT_LONG;
1297 }
1298 return EXIF_FORMAT_UNDEFINED;
1299 }
1300
GetExifNameByExifTag(const ExifTag & tag)1301 std::string EXIFInfo::GetExifNameByExifTag(const ExifTag &tag)
1302 {
1303 for (uint32_t i = 0; i < sizeof(EXIF_TAG_TABLE) / sizeof(EXIF_TAG_TABLE[0]); i++) {
1304 CHECK_ERROR_RETURN_RET(EXIF_TAG_TABLE[i].tag != tag, EXIF_TAG_TABLE[i].name);
1305 }
1306 return "";
1307 }
CreateExifEntryOfRationalExif(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry,const std::string & separator,size_t sepSize)1308 bool EXIFInfo::CreateExifEntryOfRationalExif(const ExifTag &tag, ExifData *data, const std::string &value,
1309 ExifByteOrder order, ExifEntry **ptrEntry, const std::string& separator, size_t sepSize)
1310 {
1311 std::vector<std::string> longVec;
1312 SplitStr(value, separator, longVec);
1313 CHECK_DEBUG_RETURN_RET_LOG(longVec.size() != sepSize, false,
1314 "%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(), value.c_str());
1315 ExifRational longRational;
1316 longRational.numerator = static_cast<ExifLong>(atoi(longVec[0].c_str()));
1317 longRational.denominator = static_cast<ExifLong>(atoi(longVec[1].c_str()));
1318 *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, sizeof(longRational), GetExifFormatByExifTag(tag));
1319 bool cond = (*ptrEntry) == nullptr;
1320 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.", GetExifNameByExifTag(tag).c_str());
1321 exif_set_rational((*ptrEntry)->data, order, longRational);
1322 return true;
1323 }
1324
CreateExifEntryOfGpsTimeStamp(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1325 bool EXIFInfo::CreateExifEntryOfGpsTimeStamp(const ExifTag &tag, ExifData *data, const std::string &value,
1326 ExifByteOrder order, ExifEntry **ptrEntry)
1327 {
1328 std::vector<std::string> longVec;
1329 SplitStr(value, ":", longVec);
1330 CHECK_DEBUG_RETURN_RET_LOG(longVec.size() != CONSTANT_3, false,
1331 "GPS time stamp Invalid value %{public}s", value.c_str());
1332 *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24, EXIF_FORMAT_SRATIONAL);
1333 bool cond = (*ptrEntry) == nullptr;
1334 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get GPS time stamp exif entry failed.");
1335 exif_set_long((*ptrEntry)->data, order, static_cast<ExifSLong>(atoi(longVec[CONSTANT_0].c_str())));
1336 exif_set_long((*ptrEntry)->data + MOVE_OFFSET_8, order,
1337 static_cast<ExifSLong>(atoi(longVec[CONSTANT_1].c_str())));
1338 exif_set_long((*ptrEntry)->data + MOVE_OFFSET_16, order,
1339 static_cast<ExifSLong>(atoi(longVec[CONSTANT_2].c_str())));
1340 return true;
1341 }
1342
CreateExifEntryOfCompressedBitsPerPixel(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1343 bool EXIFInfo::CreateExifEntryOfCompressedBitsPerPixel(const ExifTag &tag, ExifData *data, const std::string &value,
1344 ExifByteOrder order, ExifEntry **ptrEntry)
1345 {
1346 *ptrEntry = InitExifTag(data, EXIF_IFD_EXIF, tag);
1347 bool cond = false;
1348 cond = (*ptrEntry) == nullptr;
1349 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get exif entry failed.");
1350 ExifRational rat;
1351 cond = !GetFractionFromStr(value, rat);
1352 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get fraction from value failed.");
1353 exif_set_rational((*ptrEntry)->data, order, rat);
1354 return true;
1355 }
1356
CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1357 bool EXIFInfo::CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag &tag, ExifData *data, const std::string &value,
1358 ExifByteOrder order, ExifEntry **ptrEntry)
1359 {
1360 std::vector<std::string> longVec;
1361 SplitStr(value, ",", longVec);
1362 if (longVec.size() == CONSTANT_2) {
1363 return SetGpsDegreeRational(data, ptrEntry, order, tag, longVec);
1364 }
1365 if (longVec.size() != CONSTANT_3 || !IsValidGpsData(longVec, tag)) {
1366 IMAGE_LOGD("%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(),
1367 value.c_str());
1368 return false;
1369 }
1370 std::vector<ExifRational> longRational(GPS_DMS_COUNT);
1371 return ConvertGpsDataToRationals(longVec, longRational) &&
1372 SetGpsRationals(data, ptrEntry, order, tag, longRational);
1373 }
1374
CreateExifEntry(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1375 bool EXIFInfo::CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
1376 ExifByteOrder order, ExifEntry **ptrEntry)
1377 {
1378 static std::vector vector1{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1379 EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH, EXIF_TAG_ISO_SPEED_RATINGS,
1380 EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE, EXIF_TAG_PIXEL_X_DIMENSION,
1381 EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_SENSITIVITY_TYPE};
1382 static std::vector vector2{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL,
1383 EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT, EXIF_TAG_DATE_TIME_ORIGINAL,
1384 EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF};
1385 static std::vector vector3{EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1386 EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1387 bool cond = false;
1388 if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
1389 return CreateExifEntryOfBitsPerSample(tag, data, value, order, ptrEntry);
1390 } else if (std::find(vector1.begin(), vector1.end(), tag) != vector1.end()) {
1391 *ptrEntry = InitExifTag(data, GetExifIfdByExifTag(tag), tag);
1392 cond = (*ptrEntry) == nullptr;
1393 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.",
1394 GetExifNameByExifTag(tag).c_str());
1395 ExifIntValueByFormat((*ptrEntry)->data, order, (*ptrEntry)->format, atoi(value.c_str()));
1396 return true;
1397 } else if (std::find(vector2.begin(), vector2.end(), tag) != vector2.end()) {
1398 *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, value.length(), GetExifFormatByExifTag(tag));
1399 cond = (*ptrEntry) == nullptr || (*ptrEntry)->size < value.length();
1400 CHECK_DEBUG_RETURN_RET_LOG(cond, false, "Get %{public}s exif entry failed.",
1401 GetExifNameByExifTag(tag).c_str());
1402 if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
1403 IMAGE_LOGD("%{public}s memcpy error", GetExifNameByExifTag(tag).c_str());
1404 }
1405 return true;
1406 }
1407 CHECK_ERROR_RETURN_RET(tag == EXIF_TAG_GPS_LATITUDE || tag == EXIF_TAG_GPS_LONGITUDE,
1408 CreateExifEntryOfGpsLatitudeOrLongitude(tag, data, value, order, ptrEntry));
1409 CHECK_ERROR_RETURN_RET(std::find(vector3.begin(), vector3.end(), tag) != vector3.end(),
1410 CreateExifEntryOfRationalExif(tag, data, value, order, ptrEntry, "/", static_cast<size_t>(CONSTANT_2)));
1411 CHECK_ERROR_RETURN_RET(tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL,
1412 CreateExifEntryOfCompressedBitsPerPixel(tag, data, value, order, ptrEntry));
1413 CHECK_ERROR_RETURN_RET(tag == EXIF_TAG_GPS_TIME_STAMP,
1414 CreateExifEntryOfGpsTimeStamp(tag, data, value, order, ptrEntry));
1415 return true;
1416 }
1417
WriteExifDataToFile(ExifData * data,unsigned int orginExifDataLength,unsigned long fileLength,unsigned char * buf,FILE * fp)1418 bool EXIFInfo::WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
1419 unsigned char *buf, FILE *fp)
1420 {
1421 unsigned char* exifDataBuf = nullptr;
1422 unsigned int exifDataBufLength = 0;
1423 exif_data_save_data(data, &exifDataBuf, &exifDataBufLength);
1424 if (exifDataBuf == nullptr) {
1425 IMAGE_LOGD("Get Exif Data Buf failed!");
1426 return false;
1427 }
1428
1429 // Write EXIF header
1430 if (fwrite(EXIF_HEADER, sizeof(EXIF_HEADER), 1, fp) != 1) {
1431 IMAGE_LOGD("Error writing EXIF header to file!");
1432 ReleaseExifDataBuffer(exifDataBuf);
1433 return false;
1434 }
1435
1436 // Write EXIF block length in big-endian order
1437 if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, fp) < 0) {
1438 IMAGE_LOGD("Error writing EXIF block length to file!");
1439 ReleaseExifDataBuffer(exifDataBuf);
1440 return false;
1441 }
1442
1443 if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, fp) < 0) {
1444 IMAGE_LOGD("Error writing EXIF block length to file!");
1445 ReleaseExifDataBuffer(exifDataBuf);
1446 return false;
1447 }
1448
1449 // Write EXIF data block
1450 if (fwrite(exifDataBuf, exifDataBufLength, 1, fp) != 1) {
1451 IMAGE_LOGD("Error writing EXIF data block to file!");
1452 ReleaseExifDataBuffer(exifDataBuf);
1453 return false;
1454 }
1455 // Write JPEG image data, skipping the non-EXIF header
1456 unsigned int dataOffset = orginExifDataLength + sizeof(EXIF_HEADER);
1457 if (fwrite(buf + dataOffset, fileLength - dataOffset, 1, fp) != 1) {
1458 IMAGE_LOGD("Error writing JPEG image data to file!");
1459 ReleaseExifDataBuffer(exifDataBuf);
1460 return false;
1461 }
1462
1463 UpdateCacheExifData(fp);
1464 ReleaseExifDataBuffer(exifDataBuf);
1465 return true;
1466 }
1467
ReleaseSource(unsigned char ** ptrBuf,FILE ** ptrFile)1468 void EXIFInfo::ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile)
1469 {
1470 if (ptrBuf != nullptr && *ptrBuf != nullptr) {
1471 free(*ptrBuf);
1472 *ptrBuf = nullptr;
1473 ptrBuf = nullptr;
1474 }
1475
1476 if (ptrFile != nullptr && *ptrFile != nullptr) {
1477 fclose(*ptrFile);
1478 *ptrFile = nullptr;
1479 ptrFile = nullptr;
1480 }
1481 }
1482
UpdateCacheExifData(FILE * fp)1483 void EXIFInfo::UpdateCacheExifData(FILE *fp)
1484 {
1485 unsigned long fileLength = GetFileSize(fp);
1486 if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
1487 IMAGE_LOGD("Get file size failed.");
1488 return;
1489 }
1490
1491 unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
1492 if (fileBuf == nullptr) {
1493 IMAGE_LOGD("Allocate buf failed.");
1494 return;
1495 }
1496
1497 // Set current position to begin of file.
1498 (void)fseek(fp, 0L, 0);
1499 if (fread(fileBuf, fileLength, 1, fp) != 1) {
1500 IMAGE_LOGD("Read new file failed.");
1501 free(fileBuf);
1502 fileBuf = nullptr;
1503 return;
1504 }
1505
1506 ParseExifData(fileBuf, static_cast<unsigned int>(fileLength));
1507 free(fileBuf);
1508 fileBuf = nullptr;
1509 }
1510
GetFilterArea(const uint8_t * buf,const uint32_t & bufSize,const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1511 uint32_t EXIFInfo::GetFilterArea(const uint8_t *buf,
1512 const uint32_t &bufSize,
1513 const int &privacyType,
1514 std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1515 {
1516 std::unique_ptr<ByteOrderedBuffer> byteOrderedBuffer = std::make_unique<ByteOrderedBuffer>(buf, bufSize);
1517 byteOrderedBuffer->GenerateDEArray();
1518 if (byteOrderedBuffer->directoryEntryArray_.size() == 0) {
1519 IMAGE_LOGD("Read Exif info range failed.");
1520 return ERROR_PARSE_EXIF_FAILED;
1521 }
1522
1523 GetAreaFromExifEntries(privacyType, byteOrderedBuffer->directoryEntryArray_, ranges);
1524 bool cond = ranges.size() == 0;
1525 CHECK_DEBUG_RETURN_RET_LOG(cond, ERROR_NO_EXIF_TAGS, "There is no exif info need filtered in this image.");
1526
1527 return Media::SUCCESS;
1528 }
1529
GetAreaFromExifEntries(const int & privacyType,const std::vector<DirectoryEntry> & entryArray,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1530 void EXIFInfo::GetAreaFromExifEntries(const int &privacyType,
1531 const std::vector<DirectoryEntry> &entryArray,
1532 std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1533 {
1534 if (privacyType == PERMISSION_GPS_TYPE) {
1535 for (size_t i = 0; i < entryArray.size(); i++) {
1536 if (entryArray[i].ifd == EXIF_IFD_GPS) {
1537 std::pair<uint32_t, uint32_t> range =
1538 std::make_pair(entryArray[i].valueOffset, entryArray[i].valueLength);
1539 ranges.push_back(range);
1540 }
1541 }
1542 }
1543 }
1544
ByteOrderedBuffer(const uint8_t * fileBuf,uint32_t bufferLength)1545 ByteOrderedBuffer::ByteOrderedBuffer(const uint8_t *fileBuf, uint32_t bufferLength)
1546 : buf_(fileBuf), bufferLength_(bufferLength)
1547 {
1548 if (bufferLength >= BUFFER_POSITION_12 && bufferLength >= BUFFER_POSITION_13) {
1549 if (fileBuf[BUFFER_POSITION_12] == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') {
1550 byteOrder_ = EXIF_BYTE_ORDER_MOTOROLA;
1551 } else {
1552 byteOrder_ = EXIF_BYTE_ORDER_INTEL;
1553 }
1554 }
1555 }
1556
~ByteOrderedBuffer()1557 ByteOrderedBuffer::~ByteOrderedBuffer() {}
1558
GenerateDEArray()1559 void ByteOrderedBuffer::GenerateDEArray()
1560 {
1561 // Move current position to begin of IFD0 offset segment
1562 curPosition_ = TIFF_OFFSET_FROM_FILE_BEGIN + CONSTANT_4;
1563 int32_t ifd0Offset = ReadInt32();
1564 if (ifd0Offset < 0) {
1565 IMAGE_LOGD("Get IFD0 offset failed!");
1566 return;
1567 }
1568 // Transform tiff offset to position of file
1569 ifd0Offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(ifd0Offset));
1570 // Move current position to begin of IFD0 segment
1571 curPosition_ = static_cast<uint32_t>(ifd0Offset);
1572
1573 bool cond = curPosition_ + CONSTANT_2 > bufferLength_;
1574 CHECK_DEBUG_RETURN_LOG(cond, "There is no data from the offset: %{public}d.", curPosition_);
1575 GetDataRangeFromIFD(EXIF_IFD_0);
1576 }
1577
GetDataRangeFromIFD(const ExifIfd & ifd)1578 void ByteOrderedBuffer::GetDataRangeFromIFD(const ExifIfd &ifd)
1579 {
1580 handledIfdOffsets_.push_back(curPosition_);
1581 int16_t entryCount = ReadShort();
1582 if (static_cast<uint32_t>(curPosition_ + BYTE_COUNTS_12 * entryCount) > bufferLength_ || entryCount <= 0) {
1583 IMAGE_LOGD(" The size of entries is either too big or negative.");
1584 return;
1585 }
1586 GetDataRangeFromDE(ifd, entryCount);
1587
1588 if (Peek() + CONSTANT_4 <= bufferLength_) {
1589 int32_t nextIfdOffset = ReadInt32();
1590 if (nextIfdOffset == 0) {
1591 IMAGE_LOGD("Stop reading file since this IFD is finished");
1592 return;
1593 }
1594 // Transform tiff offset to position of file
1595 if (nextIfdOffset != -1) {
1596 nextIfdOffset = static_cast<int32_t>(TransformTiffOffsetToFilePos(nextIfdOffset));
1597 }
1598 // Check if the next IFD offset
1599 // 1. Exists within the boundaries of the buffer
1600 // 2. Does not point to a previously read IFD.
1601 if (nextIfdOffset > 0L && static_cast<uint32_t>(nextIfdOffset) < bufferLength_) {
1602 if (!IsIFDhandled(nextIfdOffset)) {
1603 curPosition_ = static_cast<uint32_t>(nextIfdOffset);
1604 ExifIfd nextIfd = GetNextIfdFromLinkList(ifd);
1605 GetDataRangeFromIFD(nextIfd);
1606 } else {
1607 IMAGE_LOGD("Stop reading buffer since re-reading an IFD at %{public}d.", nextIfdOffset);
1608 }
1609 } else {
1610 IMAGE_LOGD("Stop reading file since a wrong offset at %{public}d.", nextIfdOffset);
1611 }
1612 }
1613 }
1614
GetDataRangeFromDE(const ExifIfd & ifd,const int16_t & count)1615 void ByteOrderedBuffer::GetDataRangeFromDE(const ExifIfd &ifd, const int16_t &count)
1616 {
1617 for (int16_t i = 0; i < count; i++) {
1618 uint16_t tagNumber = ReadUnsignedShort();
1619 uint16_t dataFormat = ReadUnsignedShort();
1620 int32_t numberOfComponents = ReadInt32();
1621 uint32_t nextEntryOffset = Peek() + CONSTANT_4;
1622
1623 uint32_t byteCount = 0;
1624 bool valid = SetDEDataByteCount(tagNumber, dataFormat, numberOfComponents, byteCount);
1625 if (!valid) {
1626 curPosition_ = static_cast<uint32_t>(nextEntryOffset);
1627 continue;
1628 }
1629
1630 // Read a value from data field or seek to the value offset which is stored in data
1631 // field if the size of the entry value is bigger than 4.
1632 // If the size of the entry value is less than 4, value is stored in value offset area.
1633 if (byteCount > CONSTANT_4) {
1634 int32_t offset = ReadInt32();
1635 // Transform tiff offset to position of file
1636 if (offset != -1) {
1637 offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(offset));
1638 }
1639 if ((static_cast<uint32_t>(offset) + byteCount) <= bufferLength_) {
1640 curPosition_ = static_cast<uint32_t>(offset);
1641 } else {
1642 // Skip if invalid data offset.
1643 IMAGE_LOGI("Skip the tag entry since data offset is invalid: %{public}d.", offset);
1644 curPosition_ = nextEntryOffset;
1645 continue;
1646 }
1647 }
1648
1649 // Recursively parse IFD when a IFD pointer tag appears
1650 if (IsIFDPointerTag(tagNumber)) {
1651 ExifIfd ifdOfIFDPointerTag = GetIFDOfIFDPointerTag(tagNumber);
1652 ParseIFDPointerTag(ifdOfIFDPointerTag, dataFormat);
1653 curPosition_ = nextEntryOffset;
1654 continue;
1655 }
1656
1657 uint32_t bytesOffset = Peek();
1658 uint32_t bytesLength = byteCount;
1659 DirectoryEntry directoryEntry = {static_cast<ExifTag>(tagNumber), static_cast<ExifFormat>(dataFormat),
1660 numberOfComponents, bytesOffset, bytesLength, ifd};
1661 directoryEntryArray_.push_back(directoryEntry);
1662
1663 // Seek to next tag offset
1664 if (Peek() != nextEntryOffset) {
1665 curPosition_ = nextEntryOffset;
1666 }
1667 }
1668 }
1669
TransformTiffOffsetToFilePos(const uint32_t & offset)1670 uint32_t ByteOrderedBuffer::TransformTiffOffsetToFilePos(const uint32_t &offset)
1671 {
1672 return offset + TIFF_OFFSET_FROM_FILE_BEGIN;
1673 }
1674
SetDEDataByteCount(const uint16_t & tagNumber,const uint16_t & dataFormat,const int32_t & numberOfComponents,uint32_t & count)1675 bool ByteOrderedBuffer::SetDEDataByteCount(const uint16_t &tagNumber,
1676 const uint16_t &dataFormat,
1677 const int32_t &numberOfComponents,
1678 uint32_t &count)
1679 {
1680 if (IsValidTagNumber(tagNumber)) {
1681 IMAGE_LOGD("Skip the tag entry since tag number is not defined: %{public}d.", tagNumber);
1682 } else if (dataFormat <= 0 || exif_format_get_size(static_cast<ExifFormat>(dataFormat)) == 0) {
1683 IMAGE_LOGD("Skip the tag entry since data format is invalid: %{public}d.", dataFormat);
1684 } else {
1685 count = static_cast<uint32_t>(numberOfComponents) *
1686 static_cast<uint32_t>(exif_format_get_size(static_cast<ExifFormat>(dataFormat)));
1687 if (count < 0) {
1688 IMAGE_LOGD("Skip the tag entry since the number of components is invalid: %{public}d.",
1689 numberOfComponents);
1690 } else {
1691 return true;
1692 }
1693 }
1694 return false;
1695 }
1696
ParseIFDPointerTag(const ExifIfd & ifd,const uint16_t & dataFormat)1697 void ByteOrderedBuffer::ParseIFDPointerTag(const ExifIfd &ifd, const uint16_t &dataFormat)
1698 {
1699 uint32_t offset = 0U;
1700 // Get offset from data field
1701 switch (static_cast<ExifFormat>(dataFormat)) {
1702 case EXIF_FORMAT_SHORT: {
1703 offset = static_cast<uint32_t>(ReadUnsignedShort());
1704 break;
1705 }
1706 case EXIF_FORMAT_SSHORT: {
1707 offset = ReadShort();
1708 break;
1709 }
1710 case EXIF_FORMAT_LONG: {
1711 offset = ReadUnsignedInt32();
1712 break;
1713 }
1714 case EXIF_FORMAT_SLONG: {
1715 offset = static_cast<uint32_t>(ReadInt32());
1716 break;
1717 }
1718 default: {
1719 // Nothing to do
1720 break;
1721 }
1722 }
1723 // Transform tiff offset to position of file
1724 offset = TransformTiffOffsetToFilePos(offset);
1725 // Check if the next IFD offset
1726 // 1. Exists within the boundaries of the buffer
1727 // 2. Does not point to a previously read IFD.
1728 if (offset > 0L && offset < bufferLength_) {
1729 if (!IsIFDhandled(offset)) {
1730 curPosition_ = offset;
1731 GetDataRangeFromIFD(ifd);
1732 } else {
1733 IMAGE_LOGD("Skip jump into the IFD since it has already been read at %{public}d.", offset);
1734 }
1735 } else {
1736 IMAGE_LOGD("Skip jump into the IFD since its offset is invalid: %{public}d.", offset);
1737 }
1738 }
1739
IsValidTagNumber(const uint16_t & tagNumber)1740 bool ByteOrderedBuffer::IsValidTagNumber(const uint16_t &tagNumber)
1741 {
1742 bool cond = false;
1743 for (uint32_t i = 0; (IsSameTextStr(EXIF_TAG_TABLE[i].name, "")); i++) {
1744 cond = EXIF_TAG_TABLE[i].number == tagNumber;
1745 CHECK_ERROR_RETURN_RET(cond, true);
1746 }
1747 return false;
1748 }
1749
IsIFDhandled(const uint32_t & position)1750 bool ByteOrderedBuffer::IsIFDhandled(const uint32_t &position)
1751 {
1752 if (handledIfdOffsets_.size() == 0) {
1753 IMAGE_LOGD("There is no handled IFD!");
1754 return false;
1755 }
1756
1757 for (size_t i = 0; i < handledIfdOffsets_.size(); i++) {
1758 if (handledIfdOffsets_[i] == position) {
1759 return true;
1760 }
1761 }
1762 return false;
1763 }
1764
IsIFDPointerTag(const uint16_t & tagNumber)1765 bool ByteOrderedBuffer::IsIFDPointerTag(const uint16_t &tagNumber)
1766 {
1767 bool ret = false;
1768 switch (static_cast<ExifTag>(tagNumber)) {
1769 case EXIF_TAG_SUB_IFDS:
1770 case EXIF_TAG_EXIF_IFD_POINTER:
1771 case EXIF_TAG_GPS_INFO_IFD_POINTER:
1772 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
1773 ret = true;
1774 break;
1775 default:
1776 break;
1777 }
1778 return ret;
1779 }
1780
GetIFDOfIFDPointerTag(const uint16_t & tagNumber)1781 ExifIfd ByteOrderedBuffer::GetIFDOfIFDPointerTag(const uint16_t &tagNumber)
1782 {
1783 ExifIfd ifd = EXIF_IFD_COUNT;
1784 switch (static_cast<ExifTag>(tagNumber)) {
1785 case EXIF_TAG_EXIF_IFD_POINTER: {
1786 ifd = EXIF_IFD_EXIF;
1787 break;
1788 }
1789 case EXIF_TAG_GPS_INFO_IFD_POINTER: {
1790 ifd = EXIF_IFD_GPS;
1791 break;
1792 }
1793 case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: {
1794 ifd = EXIF_IFD_INTEROPERABILITY;
1795 break;
1796 }
1797 default: {
1798 break;
1799 }
1800 }
1801 return ifd;
1802 }
1803
GetNextIfdFromLinkList(const ExifIfd & ifd)1804 ExifIfd ByteOrderedBuffer::GetNextIfdFromLinkList(const ExifIfd &ifd)
1805 {
1806 ExifIfd nextIfd = EXIF_IFD_COUNT;
1807 /**
1808 * In jpeg file, the next IFD of IFD_0 in IFD link list is IFD_1,
1809 * other IFD is pointed by tag.
1810 */
1811 if (ifd == EXIF_IFD_0) {
1812 nextIfd = EXIF_IFD_1;
1813 }
1814 return nextIfd;
1815 }
1816
ReadInt32()1817 int32_t ByteOrderedBuffer::ReadInt32()
1818 {
1819 // Move current position to begin of next segment
1820 curPosition_ += CONSTANT_4;
1821 if (curPosition_ > bufferLength_) {
1822 IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1823 return -1;
1824 }
1825
1826 if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1827 return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]) << MOVE_OFFSET_24) |
1828 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_16) |
1829 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1830 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1831 } else {
1832 return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_24) |
1833 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_16) |
1834 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_8) |
1835 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]));
1836 }
1837 }
1838
ReadUnsignedInt32()1839 uint32_t ByteOrderedBuffer::ReadUnsignedInt32()
1840 {
1841 return (static_cast<uint32_t>(ReadInt32()) & 0xffffffff);
1842 }
1843
ReadShort()1844 int16_t ByteOrderedBuffer::ReadShort()
1845 {
1846 // Move current position to begin of next segment
1847 curPosition_ += CONSTANT_2;
1848 if (curPosition_ > bufferLength_) {
1849 IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1850 return -1;
1851 }
1852
1853 if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1854 return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1855 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1856 } else {
1857 return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_8) |
1858 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]));
1859 }
1860 }
1861
ReadUnsignedShort()1862 uint16_t ByteOrderedBuffer::ReadUnsignedShort()
1863 {
1864 return (static_cast<uint32_t>(ReadShort()) & 0xffff);
1865 }
1866
Peek()1867 uint32_t ByteOrderedBuffer::Peek()
1868 {
1869 return curPosition_;
1870 }
1871
CheckExifEntryValid(const ExifIfd & ifd,const ExifTag & tag)1872 bool EXIFInfo::CheckExifEntryValid(const ExifIfd &ifd, const ExifTag &tag)
1873 {
1874 bool ret = false;
1875 switch (ifd) {
1876 case EXIF_IFD_0: {
1877 if (tag == EXIF_TAG_ORIENTATION ||
1878 tag == EXIF_TAG_BITS_PER_SAMPLE ||
1879 tag == EXIF_TAG_IMAGE_LENGTH ||
1880 tag == EXIF_TAG_IMAGE_WIDTH) {
1881 ret = true;
1882 }
1883 break;
1884 }
1885 case EXIF_IFD_EXIF: {
1886 if (tag == EXIF_TAG_DATE_TIME_ORIGINAL ||
1887 tag == EXIF_TAG_EXPOSURE_TIME ||
1888 tag == EXIF_TAG_FNUMBER ||
1889 tag == EXIF_TAG_ISO_SPEED_RATINGS ||
1890 tag == EXIF_TAG_SCENE_TYPE ||
1891 tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1892 ret = true;
1893 }
1894 break;
1895 }
1896 case EXIF_IFD_GPS: {
1897 if (tag == EXIF_TAG_GPS_LATITUDE ||
1898 tag == EXIF_TAG_GPS_LONGITUDE ||
1899 tag == EXIF_TAG_GPS_LATITUDE_REF ||
1900 tag == EXIF_TAG_GPS_LONGITUDE_REF) {
1901 ret = true;
1902 }
1903 break;
1904 }
1905 default:
1906 break;
1907 }
1908
1909 if (!ret) {
1910 ret = CheckExifEntryValidEx(ifd, tag);
1911 }
1912
1913 return ret;
1914 }
1915
CheckExifEntryValidEx(const ExifIfd & ifd,const ExifTag & tag)1916 bool EXIFInfo::CheckExifEntryValidEx(const ExifIfd &ifd, const ExifTag &tag)
1917 {
1918 static std::vector<ExifTag> ifd0TagVec{EXIF_TAG_DATE_TIME, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1919 EXIF_TAG_MODEL};
1920 static std::vector<ExifTag> ifdExifTagVec{TAG_SENSITIVITY_TYPE, TAG_STANDARD_OUTPUT_SENSITIVITY,
1921 TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_METERING_MODE,
1922 EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_FLASH, EXIF_TAG_FOCAL_LENGTH, EXIF_TAG_USER_COMMENT, EXIF_TAG_PIXEL_X_DIMENSION,
1923 EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM};
1924 bool ret = false;
1925 switch (ifd) {
1926 case EXIF_IFD_0: {
1927 return std::find(ifd0TagVec.begin(), ifd0TagVec.end(), tag) != ifd0TagVec.end();
1928 }
1929 case EXIF_IFD_EXIF: {
1930 return std::find(ifdExifTagVec.begin(), ifdExifTagVec.end(), tag) != ifdExifTagVec.end();
1931 }
1932 case EXIF_IFD_GPS: {
1933 return tag == EXIF_TAG_GPS_TIME_STAMP || tag == EXIF_TAG_GPS_DATE_STAMP;
1934 }
1935 default:
1936 break;
1937 }
1938
1939 return ret;
1940 }
1941
NumSplit(std::string & src,std::vector<std::string> & out)1942 static void NumSplit(std::string &src, std::vector<std::string> &out)
1943 {
1944 bool cond = src.size() == 0;
1945 CHECK_ERROR_RETURN(cond);
1946 std::vector<std::string> res;
1947 size_t last = 0;
1948 for (size_t i = 0; i < src.size(); i++) {
1949 if (!std::isdigit(src[i])) {
1950 size_t splitSize = i - last;
1951 if (splitSize != 0) {
1952 res.push_back(src.substr(last, splitSize));
1953 }
1954 last = i + SIZE_1;
1955 }
1956 }
1957 if (last <= (src.size() - SIZE_1)) {
1958 res.push_back(src.substr(last));
1959 }
1960 for (size_t i = 0; i < res.size() && i < out.size(); i++) {
1961 out[i] = res[i];
1962 }
1963 }
1964
JoinStr(std::vector<std::string> & in,const std::string & delim)1965 static std::string JoinStr(std::vector<std::string> &in, const std::string &delim)
1966 {
1967 std::string res = "";
1968 for (size_t i = 0; i < (in.size() - SIZE_1); i++) {
1969 res.append(in[i]).append(delim);
1970 }
1971 res.append(in.back());
1972 return res;
1973 }
1974
FormatTimeStamp(std::string & src,std::string & value)1975 static void FormatTimeStamp(std::string &src, std::string &value)
1976 {
1977 std::string date = src;
1978 std::string time = "";
1979 std::string::size_type position = src.find(" ");
1980 if (position != src.npos) {
1981 // Date and time
1982 date = src.substr(0, position);
1983 time = src.substr(position);
1984 }
1985 std::vector<std::string> dateVector = {"1970", "01", "01"};
1986 std::vector<std::string> timeVector = {"00", "00", "00"};
1987 NumSplit(date, dateVector);
1988 NumSplit(time, timeVector);
1989 value = JoinStr(dateVector, "-") + " " + JoinStr(timeVector, ":");
1990 }
1991
SpecialExifData(EXIFInfo * info,const std::string & name,std::string & value)1992 static uint32_t SpecialExifData(EXIFInfo* info, const std::string &name, std::string &value)
1993 {
1994 if (IsSameTextStr(DATE_TIME_ORIGINAL_MEDIA, name)) {
1995 std::string orgValue;
1996 auto res = info->GetExifData(DATE_TIME_ORIGINAL, orgValue);
1997 if (res == Media::SUCCESS) {
1998 FormatTimeStamp(orgValue, value);
1999 }
2000 return res;
2001 } else if (IsSameTextStr(TAG_ORIENTATION_INT, name)) {
2002 std::string orgValue;
2003 auto res = info->GetExifData(TAG_ORIENTATION_STRING, orgValue);
2004 if (res != Media::SUCCESS) {
2005 return res;
2006 }
2007 bool cond = ORIENTATION_INT_MAP.count(orgValue) == 0;
2008 CHECK_DEBUG_RETURN_RET_LOG(cond, Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT,
2009 "SpecialExifData %{public}s not found %{public}s.",
2010 name.c_str(), orgValue.c_str());
2011 value = std::to_string(ORIENTATION_INT_MAP.at(orgValue));
2012 return res;
2013 }
2014 return Media::ERR_MEDIA_STATUS_ABNORMAL;
2015 }
2016
GetExifTagByName(const std::string & name,ExifTag & tag)2017 static bool GetExifTagByName(const std::string &name, ExifTag &tag)
2018 {
2019 auto find_item = std::find_if(TAG_MAP.begin(), TAG_MAP.end(),
2020 [name](const std::map<ExifTag, std::string>::value_type item) {
2021 return IsSameTextStr(item.second, name);
2022 });
2023 auto find_maker_item = std::find_if(TAG_MAKER_NOTE_MAP.begin(), TAG_MAKER_NOTE_MAP.end(),
2024 [name](const std::map<ExifTag, std::string>::value_type item) {
2025 return IsSameTextStr(item.second, name);
2026 });
2027 if (find_item == TAG_MAP.end() && find_maker_item == TAG_MAKER_NOTE_MAP.end()) {
2028 return false;
2029 }
2030 tag = find_item->first;
2031 return true;
2032 }
2033
GetExifData(const std::string name,std::string & value)2034 uint32_t EXIFInfo::GetExifData(const std::string name, std::string &value)
2035 {
2036 auto res = SpecialExifData(this, name, value);
2037 if (res == Media::SUCCESS || res != Media::ERR_MEDIA_STATUS_ABNORMAL) {
2038 IMAGE_LOGD("GetExifData %{public}s special result with %{public}d.", name.c_str(), res);
2039 return res;
2040 }
2041 ExifTag tag;
2042 if (!GetExifTagByName(name, tag)) {
2043 IMAGE_LOGD("GetExifData %{public}s not in the TAGs map.", name.c_str());
2044 return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2045 }
2046 DumpTagsMap(exifTags_);
2047 bool cond = !exifTags_.Find(tag, value);
2048 CHECK_DEBUG_RETURN_RET_LOG(cond, Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT,
2049 "GetExifData has no tag %{public}s[%{public}d], tags Size: %{public}zu.",
2050 name.c_str(), tag, static_cast<size_t>(exifTags_.Size()));
2051 if (IsSameTextStr(value, DEFAULT_EXIF_VALUE)) {
2052 IMAGE_LOGD("GetExifData %{public}s[%{public}d] value is DEFAULT_EXIF_VALUE.",
2053 name.c_str(), tag);
2054 return Media::ERR_MEDIA_VALUE_INVALID;
2055 }
2056 return Media::SUCCESS;
2057 }
2058
ModifyExifData(const std::string name,const std::string & value,const std::string & path)2059 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const std::string &path)
2060 {
2061 ExifTag tag;
2062 if (!GetExifTagByName(name, tag)) {
2063 IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2064 return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2065 }
2066 return ModifyExifData(tag, value, path);
2067 }
2068
ModifyExifData(const std::string name,const std::string & value,const int fd)2069 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const int fd)
2070 {
2071 ExifTag tag;
2072 if (!GetExifTagByName(name, tag)) {
2073 IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2074 return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2075 }
2076 return ModifyExifData(tag, value, fd);
2077 }
2078
ModifyExifData(const std::string name,const std::string & value,unsigned char * data,uint32_t size)2079 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, unsigned char *data, uint32_t size)
2080 {
2081 ExifTag tag;
2082 if (!GetExifTagByName(name, tag)) {
2083 IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2084 return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2085 }
2086 return ModifyExifData(tag, value, data, size);
2087 }
2088 } // namespace ImagePlugin
2089 } // namespace OHOS
2090