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