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