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 }
427 
DumpTagsMap(SafeMap<ExifTag,std::string> & tags)428 static void inline DumpTagsMap(SafeMap<ExifTag, std::string> &tags)
429 {
430     auto callbackIt = [](const ExifTag &key, std::string &value) {
431         if (TAG_MAP.count(key) == 0) {
432             IMAGE_LOGD("DumpTagsMap %{public}d.", key);
433             return;
434         }
435         std::string name = TAG_MAP.at(key);
436         IMAGE_LOGD("DumpTagsMap %{public}s(%{public}d).", name.c_str(), key);
437     };
438     tags.Iterate(callbackIt);
439 }
440 
ParseExifData(const unsigned char * buf,unsigned len)441 int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len)
442 {
443     IMAGE_LOGD("ParseExifData ENTER");
444     if (exifData_ != nullptr) {
445         exif_data_unref(exifData_);
446         exifData_ = nullptr;
447     }
448     exifData_ = exif_data_new();
449     if (!exifData_) {
450         return PARSE_EXIF_DATA_ERROR;
451     }
452     exif_data_unset_option(exifData_, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
453     exif_data_load_data (exifData_, buf, len);
454     exif_data_foreach_content(exifData_,
455         [](ExifContent *ec, void *userData) {
456             ExifIfd ifd = exif_content_get_ifd(ec);
457             (static_cast<EXIFInfo*>(userData))->imageFileDirectory_ = ifd;
458             if (ifd == EXIF_IFD_COUNT) {
459                 IMAGE_LOGD("GetIfd ERROR");
460                 return;
461             }
462             exif_content_foreach_entry(ec,
463                 [](ExifEntry *ee, void* userData) {
464                     if (ee == nullptr) {
465                         return;
466                     }
467                     char tagValueChar[1024];
468                     exif_entry_get_value(ee, tagValueChar, sizeof(tagValueChar));
469                     std::string tagValueStr(&tagValueChar[0], &tagValueChar[strlen(tagValueChar)]);
470                     if ((static_cast<EXIFInfo*>(userData))->CheckExifEntryValid(exif_entry_get_ifd(ee), ee->tag)) {
471                         (static_cast<EXIFInfo*>(userData))->SetExifTagValues(ee->tag, tagValueStr);
472                     }
473                 }, userData);
474         }, this);
475 
476     if (imageFileDirectory_ == EXIF_IFD_COUNT) {
477         return PARSE_EXIF_IFD_ERROR;
478     }
479     ExifMakerNote exifMakerNote;
480     if (exifMakerNote.Parser(exifData_, buf, len) == Media::SUCCESS) {
481         SetExifTagValues(static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_CAPTURE_MODE),
482             exifMakerNote.hwCaptureMode);
483         SetExifTagValues(static_cast<ExifTag>(ExifMakerNote::HW_MNOTE_TAG_PHYSICAL_APERTURE),
484             exifMakerNote.hwPhysicalAperture);
485     }
486     makerInfoTagValueMap = exifMakerNote.makerTagValueMap;
487     isExifDataParsed_ = true;
488     DumpTagsMap(exifTags_);
489     return PARSE_EXIF_SUCCESS;
490 }
491 
ParseExifData(const std::string & data)492 int EXIFInfo::ParseExifData(const std::string &data)
493 {
494     return ParseExifData((const unsigned char *)data.data(), data.length());
495 }
496 
IsExifDataParsed()497 bool EXIFInfo::IsExifDataParsed()
498 {
499     return isExifDataParsed_;
500 }
501 
SetExifTagValues(const ExifTag & tag,const std::string & value)502 void EXIFInfo::SetExifTagValues(const ExifTag &tag, const std::string &value)
503 {
504     exifTags_.EnsureInsert(tag, value);
505     if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
506         bitsPerSample_ = value;
507     } else if (tag == EXIF_TAG_ORIENTATION) {
508         orientation_ = value;
509     } else if (tag == EXIF_TAG_IMAGE_LENGTH) {
510         imageLength_ = value;
511     } else if (tag == EXIF_TAG_IMAGE_WIDTH) {
512         imageWidth_ = value;
513     } else if (tag == EXIF_TAG_GPS_LATITUDE) {
514         gpsLatitude_ = value;
515     } else if (tag == EXIF_TAG_GPS_LONGITUDE) {
516         gpsLongitude_ = value;
517     } else if (tag == EXIF_TAG_GPS_LATITUDE_REF) {
518         gpsLatitudeRef_ = value;
519     } else if (tag == EXIF_TAG_GPS_LONGITUDE_REF) {
520         gpsLongitudeRef_ = value;
521     } else if (tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
522         dateTimeOriginal_ = value;
523     } else if (tag == EXIF_TAG_EXPOSURE_TIME) {
524         exposureTime_ = value;
525     } else if (tag == EXIF_TAG_FNUMBER) {
526         fNumber_ = value;
527     } else if (tag == EXIF_TAG_ISO_SPEED_RATINGS) {
528         isoSpeedRatings_ = value;
529     } else if (tag == EXIF_TAG_SCENE_TYPE) {
530         sceneType_ = value;
531     } else if (tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
532         compressedBitsPerPixel_ = value;
533     } else {
534         SetExifTagValuesEx(tag, value);
535     }
536 }
537 
SetExifTagValuesEx(const ExifTag & tag,const std::string & value)538 void EXIFInfo::SetExifTagValuesEx(const ExifTag &tag, const std::string &value)
539 {
540     if (tag == EXIF_TAG_DATE_TIME) {
541         dateTime_ = value;
542     } else if (tag == EXIF_TAG_GPS_TIME_STAMP) {
543         gpsTimeStamp_ = value;
544     } else if (tag == EXIF_TAG_GPS_DATE_STAMP) {
545         gpsDateStamp_ = value;
546     } else if (tag == EXIF_TAG_IMAGE_DESCRIPTION) {
547         imageDescription_ = value;
548     } else if (tag == EXIF_TAG_MAKE) {
549         make_ = value;
550     } else if (tag == EXIF_TAG_MODEL) {
551         model_ = value;
552     } else if (tag == EXIF_TAG_JPEG_PROC) {
553         photoMode_ = value;
554     } else if (tag == TAG_SENSITIVITY_TYPE) {
555         sensitivityType_ = value;
556     } else if (tag == TAG_STANDARD_OUTPUT_SENSITIVITY) {
557         standardOutputSensitivity_ = value;
558     } else if (tag == TAG_RECOMMENDED_EXPOSURE_INDEX) {
559         recommendedExposureIndex_ = value;
560     } else if (tag == EXIF_TAG_APERTURE_VALUE) {
561         apertureValue_ = value;
562     } else if (tag == EXIF_TAG_EXPOSURE_BIAS_VALUE) {
563         exposureBiasValue_ = value;
564     } else if (tag == EXIF_TAG_METERING_MODE) {
565         meteringMode_ = value;
566     } else if (tag == EXIF_TAG_LIGHT_SOURCE) {
567         lightSource_ = value;
568     } else if (tag == EXIF_TAG_FLASH) {
569         flash_ = value;
570     } else if (tag == EXIF_TAG_FOCAL_LENGTH) {
571         focalLength_ = value;
572     } else if (tag == EXIF_TAG_USER_COMMENT) {
573         userComment_ = value;
574     } else if (tag == EXIF_TAG_PIXEL_X_DIMENSION) {
575         pixelXDimension_ = value;
576     } else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION) {
577         pixelYDimension_ = value;
578     } else if (tag == EXIF_TAG_WHITE_BALANCE) {
579         whiteBalance_ = value;
580     } else if (tag == EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM) {
581         focalLengthIn35mmFilm_ = value;
582     } else {
583         IMAGE_LOGD("No match tag name!");
584     }
585 }
586 
GetFileInfoByPath(const std::string & path,FILE ** file,unsigned long & fileLength,unsigned char ** fileBuf)587 uint32_t EXIFInfo::GetFileInfoByPath(const std::string &path, FILE **file, unsigned long &fileLength,
588     unsigned char **fileBuf)
589 {
590     *file = fopen(path.c_str(), "rb");
591     if (*file == nullptr) {
592         IMAGE_LOGD("Error creating file %{public}s", path.c_str());
593         return Media::ERR_MEDIA_IO_ABNORMAL;
594     }
595 
596     // read jpeg file to buff
597     fileLength = GetFileSize(*file);
598     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
599         IMAGE_LOGD("Get file size failed.");
600         (void)fclose(*file);
601         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
602     }
603 
604     *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
605     if (*fileBuf == nullptr) {
606         IMAGE_LOGD("Allocate buf for %{public}s failed.", path.c_str());
607         (void)fclose(*file);
608         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
609     }
610 
611     if (fread(*fileBuf, fileLength, 1, *file) != 1) {
612         IMAGE_LOGD("Read %{public}s failed.", path.c_str());
613         ReleaseSource(fileBuf, file);
614         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
615     }
616 
617     if (!((*fileBuf)[0] == 0xFF && (*fileBuf)[1] == 0xD8)) {
618         IMAGE_LOGD("%{public}s is not jpeg file.", path.c_str());
619         ReleaseSource(fileBuf, file);
620         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
621     }
622     return Media::SUCCESS;
623 }
624 
ModifyExifData(const ExifTag & tag,const std::string & value,const std::string & path)625 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path)
626 {
627     FILE *file = nullptr;
628     unsigned long fileLength;
629     unsigned char *fileBuf = nullptr;
630     uint32_t res = GetFileInfoByPath(path, &file, fileLength, &fileBuf);
631     if (res != Media::SUCCESS) {
632         return res;
633     }
634 
635     ExifData *ptrExifData = nullptr;
636     bool isNewExifData = false;
637     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
638         ReleaseSource(&fileBuf, &file);
639         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
640     }
641     (void)fclose(file);
642     file = nullptr;
643 
644     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
645     if (!isNewExifData && orginExifDataLength == 0) {
646         IMAGE_LOGD("There is no orginExifDataLength node in %{public}s.", path.c_str());
647         exif_data_unref(ptrExifData);
648         free(fileBuf);
649         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
650     }
651 
652     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
653     FILE *newFile = fopen(path.c_str(), "wb+");
654     if (newFile == nullptr) {
655         IMAGE_LOGD("Error create new file %{public}s", path.c_str());
656         ReleaseSource(&fileBuf, &newFile);
657         return Media::ERR_MEDIA_IO_ABNORMAL;
658     }
659     ExifEntry *entry = nullptr;
660     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
661         ReleaseSource(&fileBuf, &newFile);
662         exif_data_unref(ptrExifData);
663         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
664     }
665     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, newFile)) {
666         ReleaseSource(&fileBuf, &newFile);
667         exif_data_unref(ptrExifData);
668         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
669     }
670     ReleaseSource(&fileBuf, &newFile);
671     exif_data_unref(ptrExifData);
672     return Media::SUCCESS;
673 }
674 
GetFileInfoByFd(int localFd,FILE ** file,unsigned long & fileLength,unsigned char ** fileBuf)675 uint32_t EXIFInfo::GetFileInfoByFd(int localFd, FILE **file, unsigned long &fileLength, unsigned char **fileBuf)
676 {
677     *file = fdopen(localFd, "wb+");
678     if (*file == nullptr) {
679         IMAGE_LOGD("Error creating file %{public}d", localFd);
680         return Media::ERR_MEDIA_IO_ABNORMAL;
681     }
682 
683     // read jpeg file to buff
684     fileLength = GetFileSize(*file);
685     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
686         IMAGE_LOGD("Get file size failed.");
687         (void)fclose(*file);
688         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
689     }
690 
691     *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
692     if (*fileBuf == nullptr) {
693         IMAGE_LOGD("Allocate buf for %{public}d failed.", localFd);
694         (void)fclose(*file);
695         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
696     }
697 
698     // Set current position to begin of file.
699     (void)fseek(*file, 0L, 0);
700     if (fread(*fileBuf, fileLength, 1, *file) != 1) {
701         IMAGE_LOGD("Read %{public}d failed.", localFd);
702         ReleaseSource(fileBuf, file);
703         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
704     }
705 
706     if (!((*fileBuf)[0] == 0xFF && (*fileBuf)[1] == 0xD8)) {
707         IMAGE_LOGD("%{public}d is not jpeg file.", localFd);
708         ReleaseSource(fileBuf, file);
709         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
710     }
711     return Media::SUCCESS;
712 }
713 
ModifyExifData(const ExifTag & tag,const std::string & value,const int fd)714 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const int fd)
715 {
716     const int localFd = dup(fd);
717     FILE *file = nullptr;
718     unsigned long fileLength;
719     unsigned char *fileBuf = nullptr;
720     uint32_t res = GetFileInfoByFd(localFd, &file, fileLength, &fileBuf);
721     if (res != Media::SUCCESS) {
722         return res;
723     }
724 
725     ExifData *ptrExifData = nullptr;
726     bool isNewExifData = false;
727     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
728         ReleaseSource(&fileBuf, &file);
729         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
730     }
731 
732     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
733     if (!isNewExifData && orginExifDataLength == 0) {
734         IMAGE_LOGD("There is no orginExifDataLength node in %{public}d.", localFd);
735         free(fileBuf);
736         exif_data_unref(ptrExifData);
737         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
738     }
739 
740     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
741     // Set current position to begin of new file.
742     (void)fseek(file, 0L, 0);
743     ExifEntry *entry = nullptr;
744     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
745         ReleaseSource(&fileBuf, &file);
746         exif_data_unref(ptrExifData);
747         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
748     }
749 
750     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, file)) {
751         ReleaseSource(&fileBuf, &file);
752         exif_data_unref(ptrExifData);
753         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
754     }
755     ReleaseSource(&fileBuf, &file);
756     exif_data_unref(ptrExifData);
757     return Media::SUCCESS;
758 }
759 
ReleaseExifDataBuffer(unsigned char * exifDataBuf)760 void ReleaseExifDataBuffer(unsigned char* exifDataBuf)
761 {
762     if (exifDataBuf != nullptr) {
763         free(exifDataBuf);
764         exifDataBuf = nullptr;
765     }
766 }
767 
CheckInputDataValid(unsigned char * data,uint32_t size)768 uint32_t EXIFInfo::CheckInputDataValid(unsigned char *data, uint32_t size)
769 {
770     if (data == nullptr) {
771         IMAGE_LOGD("buffer is nullptr.");
772         return Media::ERR_IMAGE_SOURCE_DATA;
773     }
774 
775     if (size == 0) {
776         IMAGE_LOGD("buffer size is 0.");
777         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
778     }
779 
780     if (!(data[0] == 0xFF && data[1] == 0xD8)) {
781         IMAGE_LOGD("This is not jpeg file.");
782         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
783     }
784     return Media::SUCCESS;
785 }
786 
ModifyExifData(const ExifTag & tag,const std::string & value,unsigned char * data,uint32_t size)787 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value,
788     unsigned char *data, uint32_t size)
789 {
790     uint32_t checkInputRes = CheckInputDataValid(data, size);
791     if (checkInputRes != Media::SUCCESS) {
792         return checkInputRes;
793     }
794 
795     ExifData *ptrExifData = nullptr;
796     bool isNewExifData = false;
797     if (!CreateExifData(data, size, &ptrExifData, isNewExifData)) {
798         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
799     }
800 
801     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, data);
802     if (!isNewExifData && orginExifDataLength == 0) {
803         IMAGE_LOGD("There is no orginExifDataLength node in buffer.");
804         exif_data_unref(ptrExifData);
805         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
806     }
807 
808     ExifByteOrder order = GetExifByteOrder(isNewExifData, data);
809     ExifEntry *entry = nullptr;
810     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
811         exif_data_unref(ptrExifData);
812         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
813     }
814 
815     unsigned char* exifDataBuf = nullptr;
816     unsigned int exifDataBufLength = 0;
817     exif_data_save_data(ptrExifData, &exifDataBuf, &exifDataBufLength);
818     if (exifDataBuf == nullptr) {
819         IMAGE_LOGD("Get Exif Data Buf failed!");
820         exif_data_unref(ptrExifData);
821         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
822     }
823 
824     if (size == 0 || size > MAX_FILE_SIZE) {
825         IMAGE_LOGD("Buffer size is out of range.");
826         exif_data_unref(ptrExifData);
827         ReleaseExifDataBuffer(exifDataBuf);
828         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
829     }
830     unsigned char *tempBuf = static_cast<unsigned char *>(malloc(size));
831     if (tempBuf == nullptr) {
832         IMAGE_LOGD("Allocate temp buffer ailed.");
833         exif_data_unref(ptrExifData);
834         ReleaseExifDataBuffer(exifDataBuf);
835         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
836     }
837 
838     // Write EXIF header to buffer
839     uint32_t index = 0;
840     if (sizeof(EXIF_HEADER) >= size) {
841         IMAGE_LOGD("There is not enough space for EXIF header!");
842         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
843         return Media::ERR_MEDIA_OUT_OF_RANGE;
844     }
845 
846     for (size_t i = 0; i < sizeof(EXIF_HEADER); i++) {
847         tempBuf[index++] = EXIF_HEADER[i];
848     }
849 
850     // Write EXIF block length in big-endian order
851     unsigned char highBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8);
852     if (index >= size) {
853         IMAGE_LOGD("There is not enough space for writing EXIF block length!");
854         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
855         return Media::ERR_MEDIA_OUT_OF_RANGE;
856     }
857     tempBuf[index++] = highBit;
858 
859     unsigned char lowBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) & 0xff);
860     if (index >= size) {
861         IMAGE_LOGD("There is not enough space for writing EXIF block length!");
862         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
863         return Media::ERR_MEDIA_OUT_OF_RANGE;
864     }
865     tempBuf[index++] = lowBit;
866 
867     // Write EXIF data block
868     if ((index +  exifDataBufLength) >= size) {
869         IMAGE_LOGD("There is not enough space for writing EXIF data block!");
870         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
871         return Media::ERR_MEDIA_OUT_OF_RANGE;
872     }
873     for (unsigned int i = 0; i < exifDataBufLength; i++) {
874         tempBuf[index++] = exifDataBuf[i];
875     }
876 
877     // Write JPEG image data, skipping the non-EXIF header
878     if ((index + size - orginExifDataLength - sizeof(EXIF_HEADER) - MOVE_OFFSET_8) > size) {
879         IMAGE_LOGD("There is not enough space for writing JPEG image data!");
880         ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
881         return Media::ERR_MEDIA_OUT_OF_RANGE;
882     }
883 
884     for (unsigned int i = 0; i < (size - orginExifDataLength - sizeof(EXIF_HEADER)); i++) {
885         tempBuf[index++] = data[orginExifDataLength + sizeof(EXIF_HEADER) + i];
886     }
887 
888     for (unsigned int i = 0; i < size; i++) {
889         data[i] = tempBuf[i];
890     }
891 
892     ParseExifData(data, static_cast<unsigned int>(index));
893     ReleaseExifData(tempBuf, ptrExifData, exifDataBuf);
894     return Media::SUCCESS;
895 }
896 
ReleaseExifData(unsigned char * tempBuf,ExifData * ptrExifData,unsigned char * exifDataBuf)897 void EXIFInfo::ReleaseExifData(unsigned char *tempBuf, ExifData *ptrExifData, unsigned char* exifDataBuf)
898 {
899     if (tempBuf != nullptr) {
900         free(tempBuf);
901         tempBuf = nullptr;
902     }
903     exif_data_unref(ptrExifData);
904     ReleaseExifDataBuffer(exifDataBuf);
905 }
906 
InitExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag)907 ExifEntry* EXIFInfo::InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag)
908 {
909     ExifEntry *entry;
910     if (ifd < EXIF_IFD_0 || ifd > EXIF_IFD_COUNT) {
911         return nullptr;
912     }
913     /* Return an existing tag if one exists */
914     if (!(entry = exif_content_get_entry(exif->ifd[ifd], tag))) {
915         /* Allocate a new entry */
916         entry = exif_entry_new();
917         if (entry == nullptr) {
918             IMAGE_LOGD("Create new entry failed!");
919             return nullptr;
920         }
921         entry->tag = tag; // tag must be set before calling exif_content_add_entry
922         /* Attach the ExifEntry to an IFD */
923         exif_content_add_entry (exif->ifd[ifd], entry);
924 
925         /* Allocate memory for the entry and fill with default data */
926         exif_entry_initialize (entry, tag);
927 
928         /* Ownership of the ExifEntry has now been passed to the IFD.
929          * One must be very careful in accessing a structure after
930          * unref'ing it; in this case, we know "entry" won't be freed
931          * because the reference count was bumped when it was added to
932          * the IFD.
933          */
934         exif_entry_unref(entry);
935     }
936     return entry;
937 }
EXIFInfoBufferCheck(ExifEntry * exifEntry,size_t len)938 static void EXIFInfoBufferCheck(ExifEntry *exifEntry, size_t len)
939 {
940     if (exifEntry == nullptr || (exifEntry->size >= len)) {
941         return;
942     }
943     /* Create a memory allocator to manage this ExifEntry */
944     ExifMem *exifMem = exif_mem_new_default();
945     if (exifMem == nullptr) {
946         IMAGE_LOGD("Create mem failed!");
947         return;
948     }
949     auto buf = exif_mem_realloc(exifMem, exifEntry->data, len);
950     if (buf != nullptr) {
951         exifEntry->data = static_cast<unsigned char*>(buf);
952         exifEntry->size = len;
953     }
954     exif_mem_unref(exifMem);
955 }
956 
CreateExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag,size_t len,ExifFormat format)957 ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag,
958     size_t len, ExifFormat format)
959 {
960     void *buf;
961     ExifEntry *exifEntry;
962 
963     if ((exifEntry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
964         EXIFInfoBufferCheck(exifEntry, len);
965         return exifEntry;
966     }
967 
968     /* Create a memory allocator to manage this ExifEntry */
969     ExifMem *exifMem = exif_mem_new_default();
970     if (exifMem == nullptr) {
971         IMAGE_LOGD("Create mem failed!");
972         return nullptr;
973     }
974 
975     /* Create a new ExifEntry using our allocator */
976     exifEntry = exif_entry_new_mem (exifMem);
977     if (exifEntry == nullptr) {
978         IMAGE_LOGD("Create entry by mem failed!");
979         return nullptr;
980     }
981 
982     /* Allocate memory to use for holding the tag data */
983     buf = exif_mem_alloc(exifMem, len);
984     if (buf == nullptr) {
985         IMAGE_LOGD("Allocate memory failed!");
986         return nullptr;
987     }
988 
989     /* Fill in the entry */
990     exifEntry->data = static_cast<unsigned char*>(buf);
991     exifEntry->size = len;
992     exifEntry->tag = tag;
993     exifEntry->components = len;
994     exifEntry->format = format;
995 
996     /* Attach the ExifEntry to an IFD */
997     exif_content_add_entry (exif->ifd[ifd], exifEntry);
998 
999     /* The ExifMem and ExifEntry are now owned elsewhere */
1000     exif_mem_unref(exifMem);
1001     exif_entry_unref(exifEntry);
1002 
1003     return exifEntry;
1004 }
1005 
GetExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag,size_t len)1006 ExifEntry* EXIFInfo::GetExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len)
1007 {
1008     ExifEntry *exifEntry;
1009     if ((exifEntry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
1010         EXIFInfoBufferCheck(exifEntry, len);
1011         return exifEntry;
1012     }
1013     return nullptr;
1014 }
1015 
GetFileSize(FILE * fp)1016 unsigned long EXIFInfo::GetFileSize(FILE *fp)
1017 {
1018     long int position;
1019     long size;
1020 
1021     /* Save the current position. */
1022     position = ftell(fp);
1023 
1024     /* Jump to the end of the file. */
1025     (void)fseek(fp, 0L, SEEK_END);
1026 
1027     /* Get the end position. */
1028     size = ftell(fp);
1029 
1030     /* Jump back to the original position. */
1031     (void)fseek(fp, position, SEEK_SET);
1032 
1033     return static_cast<unsigned long>(size);
1034 }
1035 
CreateExifData(unsigned char * buf,unsigned long length,ExifData ** ptrData,bool & isNewExifData)1036 bool EXIFInfo::CreateExifData(unsigned char *buf, unsigned long length, ExifData **ptrData, bool &isNewExifData)
1037 {
1038     if (buf == nullptr) {
1039         IMAGE_LOGD("Create exif data but buf is null");
1040         return false;
1041     }
1042     if ((buf[BUFFER_POSITION_6] == 'E' && buf[BUFFER_POSITION_7] == 'x' &&
1043         buf[BUFFER_POSITION_8] == 'i' && buf[BUFFER_POSITION_9] == 'f')) {
1044         *ptrData = exif_data_new_from_data(buf, static_cast<unsigned int>(length));
1045         if (!(*ptrData)) {
1046             IMAGE_LOGD("Create exif data from file failed.");
1047             return false;
1048         }
1049         isNewExifData = false;
1050         IMAGE_LOGD("Create exif data from buffer.");
1051     } else {
1052         *ptrData = exif_data_new();
1053         if (!(*ptrData)) {
1054             IMAGE_LOGD("Create exif data failed.");
1055             return false;
1056         }
1057         /* Set the image options */
1058         exif_data_set_option(*ptrData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
1059         exif_data_set_data_type(*ptrData, EXIF_DATA_TYPE_COMPRESSED);
1060         exif_data_set_byte_order(*ptrData, EXIF_BYTE_ORDER_INTEL);
1061 
1062         /* Create the mandatory EXIF fields with default data */
1063         exif_data_fix(*ptrData);
1064         isNewExifData = true;
1065         IMAGE_LOGD("Create new exif data.");
1066     }
1067     return true;
1068 }
1069 
GetOrginExifDataLength(const bool & isNewExifData,unsigned char * buf)1070 unsigned int EXIFInfo::GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf)
1071 {
1072     unsigned int orginExifDataLength = 0;
1073     if (!isNewExifData) {
1074         orginExifDataLength = static_cast<unsigned int>(buf[BUFFER_POSITION_5]) |
1075             static_cast<unsigned int>(buf[BUFFER_POSITION_4] << MOVE_OFFSET_8);
1076     }
1077     return orginExifDataLength;
1078 }
1079 
GetExifByteOrder(const bool & isNewExifData,unsigned char * buf)1080 ExifByteOrder EXIFInfo::GetExifByteOrder(const bool &isNewExifData, unsigned char *buf)
1081 {
1082     if (isNewExifData) {
1083         return EXIF_BYTE_ORDER_INTEL;
1084     } else {
1085         if (buf[BUFFER_POSITION_12] == 'M' && buf[BUFFER_POSITION_13] == 'M') {
1086             return EXIF_BYTE_ORDER_MOTOROLA;
1087         } else {
1088             return EXIF_BYTE_ORDER_INTEL;
1089         }
1090     }
1091 }
1092 
GCD(int a,int b)1093 static int GCD(int a, int b)
1094 {
1095     if (b == 0) {
1096         return a;
1097     }
1098     return GCD(b, a % b);
1099 }
1100 
GetFractionFromStr(const std::string & decimal,ExifRational & result)1101 static bool GetFractionFromStr(const std::string &decimal, ExifRational &result)
1102 {
1103     int intPart = stoi(decimal.substr(0, decimal.find(".")));
1104     double decPart = stod(decimal.substr(decimal.find(".")));
1105 
1106     int numerator = decPart * pow(10, decimal.length() - decimal.find(".") - 1);
1107     int denominator = pow(10, decimal.length() - decimal.find(".") - 1);
1108 
1109     int gcdVal = GCD(numerator, denominator);
1110     if (gcdVal == 0) {
1111         IMAGE_LOGD("gcdVal is zero");
1112         return false;
1113     }
1114     numerator /= gcdVal;
1115     denominator /= gcdVal;
1116 
1117     numerator += intPart * denominator;
1118 
1119     result.numerator = static_cast<ExifLong>(numerator);
1120     result.denominator = static_cast<ExifLong>(denominator);
1121     return true;
1122 }
1123 
ExifIntValueByFormat(unsigned char * b,ExifByteOrder order,ExifFormat format,long value)1124 static void ExifIntValueByFormat(unsigned char *b, ExifByteOrder order, ExifFormat format, long value)
1125 {
1126     switch (format) {
1127         case EXIF_FORMAT_SHORT:
1128             exif_set_short(b, order, (ExifShort)value);
1129             break;
1130         case EXIF_FORMAT_SSHORT:
1131             exif_set_sshort(b, order, (ExifSShort)value);
1132             break;
1133         case EXIF_FORMAT_LONG:
1134             exif_set_long(b, order, (ExifLong)value);
1135             break;
1136         case EXIF_FORMAT_SLONG:
1137             exif_set_slong(b, order, (ExifSLong)value);
1138             break;
1139         case EXIF_FORMAT_BYTE:
1140         case EXIF_FORMAT_SRATIONAL:
1141         case EXIF_FORMAT_UNDEFINED:
1142         case EXIF_FORMAT_ASCII:
1143         case EXIF_FORMAT_RATIONAL:
1144         default:
1145             IMAGE_LOGD("ExifIntValueByFormat unsupported format %{public}d.", format);
1146             break;
1147     }
1148 }
1149 
ConvertStringToDouble(const std::string & str,double & number)1150 static bool ConvertStringToDouble(const std::string &str, double &number)
1151 {
1152     char* end = nullptr;
1153     number = std::strtod(str.c_str(), &end);
1154     return end != str.c_str() && *end == '\0' && number != HUGE_VAL;
1155 }
1156 
IsValidGpsData(const std::vector<std::string> & dataVec,const ExifTag & tag)1157 static bool IsValidGpsData(const std::vector<std::string> &dataVec, const ExifTag &tag)
1158 {
1159     if (dataVec.size() != SIZE_3 || (tag != EXIF_TAG_GPS_LATITUDE && tag != EXIF_TAG_GPS_LONGITUDE)) {
1160         IMAGE_LOGD("Gps dms data size is invalid.");
1161         return false;
1162     }
1163     double degree = 0.0;
1164     double minute = 0.0;
1165     double second = 0.0;
1166     if (!ConvertStringToDouble(dataVec[CONSTANT_0], degree) ||
1167         !ConvertStringToDouble(dataVec[CONSTANT_1], minute) ||
1168         !ConvertStringToDouble(dataVec[CONSTANT_2], second)) {
1169         IMAGE_LOGE("Convert gps data to double type failed.");
1170         return false;
1171     }
1172     constexpr uint32_t timePeriod = 60;
1173     double latOrLong = degree + minute / timePeriod + second / (timePeriod * timePeriod);
1174     if ((tag == EXIF_TAG_GPS_LATITUDE && (latOrLong > GPS_MAX_LATITUDE || latOrLong < GPS_MIN_LATITUDE)) ||
1175         (tag == EXIF_TAG_GPS_LONGITUDE && (latOrLong > GPS_MAX_LONGITUDE || latOrLong < GPS_MIN_LONGITUDE))) {
1176         IMAGE_LOGD("Gps latitude or longitude is out of range.");
1177         return false;
1178     }
1179     return true;
1180 }
1181 
ConvertGpsDataToRationals(const std::vector<std::string> & dataVec,std::vector<ExifRational> & exifRationals)1182 static bool ConvertGpsDataToRationals(const std::vector<std::string> &dataVec,
1183     std::vector<ExifRational> &exifRationals)
1184 {
1185     if (!(dataVec.size() == SIZE_3 && exifRationals.size() == SIZE_3)) {
1186         IMAGE_LOGD("Data size is invalid.");
1187         return false;
1188     }
1189 
1190     int32_t degree = static_cast<int32_t>(atoi(dataVec[CONSTANT_0].c_str()));
1191     int32_t minute = static_cast<int32_t>(atoi(dataVec[CONSTANT_1].c_str()));
1192     double secondDouble = 0.0;
1193     ConvertStringToDouble(dataVec[CONSTANT_2], secondDouble);
1194     int32_t second = static_cast<int32_t>(secondDouble * GPS_DIGIT_NUMBER);
1195 
1196     exifRationals[CONSTANT_0].numerator = static_cast<ExifLong>(degree);
1197     exifRationals[CONSTANT_0].denominator = static_cast<ExifLong>(1);
1198     exifRationals[CONSTANT_1].numerator = static_cast<ExifLong>(minute);
1199     exifRationals[CONSTANT_1].denominator = static_cast<ExifLong>(1);
1200     exifRationals[CONSTANT_2].numerator = static_cast<ExifLong>(second);
1201     exifRationals[CONSTANT_2].denominator = static_cast<ExifLong>(GPS_DIGIT_NUMBER);
1202     return true;
1203 }
1204 
SetGpsRationals(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<ExifRational> & exifRationals)1205 bool EXIFInfo::SetGpsRationals(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order,
1206     const ExifTag &tag, const std::vector<ExifRational> &exifRationals)
1207 {
1208     if (exifRationals.size() != SIZE_3) {
1209         IMAGE_LOGD("ExifRationals size is invalid.");
1210         return false;
1211     }
1212     *ptrEntry = GetExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24);
1213     if ((*ptrEntry) == nullptr) {
1214         IMAGE_LOGD("Get exif entry failed.");
1215         return false;
1216     }
1217     exif_set_rational((*ptrEntry)->data, order, exifRationals[CONSTANT_0]);
1218     exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_8, order, exifRationals[CONSTANT_1]);
1219     exif_set_rational((*ptrEntry)->data + MOVE_OFFSET_16, order, exifRationals[CONSTANT_2]);
1220     return true;
1221 }
1222 
SetGpsDegreeRational(ExifData * data,ExifEntry ** ptrEntry,ExifByteOrder order,const ExifTag & tag,const std::vector<std::string> & dataVec)1223 bool EXIFInfo::SetGpsDegreeRational(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order, const ExifTag &tag,
1224     const std::vector<std::string> &dataVec)
1225 {
1226     if (dataVec.size() != SIZE_2) {
1227         IMAGE_LOGD("Gps degree data size is invalid.");
1228         return false;
1229     }
1230     ExifRational exifRational;
1231     exifRational.numerator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_0].c_str()));
1232     exifRational.denominator = static_cast<ExifLong>(atoi(dataVec[CONSTANT_1].c_str()));
1233     *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_8, EXIF_FORMAT_RATIONAL);
1234     if ((*ptrEntry) == nullptr) {
1235         IMAGE_LOGD("Get exif entry failed.");
1236         return false;
1237     }
1238     exif_set_rational((*ptrEntry)->data, order, exifRational);
1239     return true;
1240 }
1241 
CreateExifEntryOfBitsPerSample(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1242 bool EXIFInfo::CreateExifEntryOfBitsPerSample(const ExifTag &tag, ExifData *data, const std::string &value,
1243     ExifByteOrder order, ExifEntry **ptrEntry)
1244 {
1245     *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_BITS_PER_SAMPLE);
1246     if ((*ptrEntry) == nullptr) {
1247         IMAGE_LOGD("Get exif entry failed.");
1248         return false;
1249     }
1250     std::vector<std::string> bitsVec;
1251     SplitStr(value, ",", bitsVec);
1252     if (bitsVec.size() > CONSTANT_4) {
1253         IMAGE_LOGD("BITS_PER_SAMPLE Invalid value %{public}s", value.c_str());
1254         return false;
1255     }
1256     if (bitsVec.size() != 0) {
1257         for (size_t i = 0; i < bitsVec.size(); i++) {
1258             exif_set_short((*ptrEntry)->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str()));
1259         }
1260     }
1261     return true;
1262 }
1263 
GetExifIfdByExifTag(const ExifTag & tag)1264 ExifIfd EXIFInfo::GetExifIfdByExifTag(const ExifTag &tag)
1265 {
1266     static std::vector exifIfd0Vec{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1267         EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME};
1268     static std::vector exifIfdExifVec{EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH,
1269         EXIF_TAG_ISO_SPEED_RATINGS, EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE,
1270         EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX,
1271         EXIF_TAG_SENSITIVITY_TYPE, EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT,
1272         EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1273         EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1274     static std::vector exifIfdGpsVec{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF,
1275         EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE};
1276     if (std::find(exifIfd0Vec.begin(), exifIfd0Vec.end(), tag) != exifIfd0Vec.end()) {
1277         return EXIF_IFD_0;
1278     } else if (std::find(exifIfdExifVec.begin(), exifIfdExifVec.end(), tag) != exifIfdExifVec.end()) {
1279         return EXIF_IFD_EXIF;
1280     } else if (std::find(exifIfdGpsVec.begin(), exifIfdGpsVec.end(), tag) != exifIfdGpsVec.end()) {
1281         return EXIF_IFD_GPS;
1282     }
1283     return EXIF_IFD_COUNT;
1284 }
1285 
GetExifFormatByExifTag(const ExifTag & tag)1286 ExifFormat EXIFInfo::GetExifFormatByExifTag(const ExifTag &tag)
1287 {
1288     static std::vector exifFormatAscii{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1289         EXIF_TAG_MODEL, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF,
1290         EXIF_TAG_GPS_LONGITUDE_REF};
1291     static std::vector exifFormatRational{EXIF_TAG_GPS_LATITUDE, EXIF_TAG_GPS_LONGITUDE, EXIF_TAG_APERTURE_VALUE};
1292     static std::vector exifFormatSRational{EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME, EXIF_TAG_FNUMBER,
1293         EXIF_TAG_FOCAL_LENGTH};
1294     if (std::find(exifFormatAscii.begin(), exifFormatAscii.end(), tag) != exifFormatAscii.end()) {
1295         return EXIF_FORMAT_ASCII;
1296     } else if (std::find(exifFormatRational.begin(), exifFormatRational.end(), tag) != exifFormatRational.end()) {
1297         return EXIF_FORMAT_RATIONAL;
1298     } else if (std::find(exifFormatSRational.begin(), exifFormatSRational.end(), tag) != exifFormatSRational.end()) {
1299         return EXIF_FORMAT_SRATIONAL;
1300     } else if (tag == EXIF_TAG_SCENE_TYPE || tag == EXIF_TAG_USER_COMMENT) {
1301         return EXIF_FORMAT_UNDEFINED;
1302     } else if (tag == EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY) {
1303         return EXIF_FORMAT_LONG;
1304     }
1305     return EXIF_FORMAT_UNDEFINED;
1306 }
1307 
GetExifNameByExifTag(const ExifTag & tag)1308 std::string EXIFInfo::GetExifNameByExifTag(const ExifTag &tag)
1309 {
1310     for (uint32_t i = 0; i < sizeof(EXIF_TAG_TABLE) / sizeof(EXIF_TAG_TABLE[0]); i++) {
1311         if (EXIF_TAG_TABLE[i].tag != tag) {
1312             return EXIF_TAG_TABLE[i].name;
1313         }
1314     }
1315     return "";
1316 }
CreateExifEntryOfRationalExif(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry,const std::string & separator,size_t sepSize)1317 bool EXIFInfo::CreateExifEntryOfRationalExif(const ExifTag &tag, ExifData *data, const std::string &value,
1318     ExifByteOrder order, ExifEntry **ptrEntry, const std::string& separator, size_t sepSize)
1319 {
1320     std::vector<std::string> longVec;
1321     SplitStr(value, separator, longVec);
1322     if (longVec.size() != sepSize) {
1323         IMAGE_LOGD("%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(), value.c_str());
1324         return false;
1325     }
1326     ExifRational longRational;
1327     longRational.numerator = static_cast<ExifLong>(atoi(longVec[0].c_str()));
1328     longRational.denominator = static_cast<ExifLong>(atoi(longVec[1].c_str()));
1329     *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, sizeof(longRational), GetExifFormatByExifTag(tag));
1330     if ((*ptrEntry) == nullptr) {
1331         IMAGE_LOGD("Get %{public}s exif entry failed.", GetExifNameByExifTag(tag).c_str());
1332         return false;
1333     }
1334     exif_set_rational((*ptrEntry)->data, order, longRational);
1335     return true;
1336 }
1337 
CreateExifEntryOfGpsTimeStamp(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1338 bool EXIFInfo::CreateExifEntryOfGpsTimeStamp(const ExifTag &tag, ExifData *data, const std::string &value,
1339     ExifByteOrder order, ExifEntry **ptrEntry)
1340 {
1341     std::vector<std::string> longVec;
1342     SplitStr(value, ":", longVec);
1343     if (longVec.size() != CONSTANT_3) {
1344         IMAGE_LOGD("GPS time stamp Invalid value %{public}s", value.c_str());
1345         return false;
1346     }
1347     *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, tag, MOVE_OFFSET_24, EXIF_FORMAT_SRATIONAL);
1348     if ((*ptrEntry) == nullptr) {
1349         IMAGE_LOGD("Get GPS time stamp exif entry failed.");
1350         return false;
1351     }
1352     exif_set_long((*ptrEntry)->data, order, static_cast<ExifSLong>(atoi(longVec[CONSTANT_0].c_str())));
1353     exif_set_long((*ptrEntry)->data + MOVE_OFFSET_8, order,
1354                   static_cast<ExifSLong>(atoi(longVec[CONSTANT_1].c_str())));
1355     exif_set_long((*ptrEntry)->data + MOVE_OFFSET_16, order,
1356                   static_cast<ExifSLong>(atoi(longVec[CONSTANT_2].c_str())));
1357     return true;
1358 }
1359 
CreateExifEntryOfCompressedBitsPerPixel(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1360 bool EXIFInfo::CreateExifEntryOfCompressedBitsPerPixel(const ExifTag &tag, ExifData *data, const std::string &value,
1361     ExifByteOrder order, ExifEntry **ptrEntry)
1362 {
1363     *ptrEntry = InitExifTag(data, EXIF_IFD_EXIF, tag);
1364     if ((*ptrEntry) == nullptr) {
1365         IMAGE_LOGD("Get exif entry failed.");
1366         return false;
1367     }
1368     ExifRational rat;
1369     if (!GetFractionFromStr(value, rat)) {
1370         IMAGE_LOGD("Get fraction from value failed.");
1371         return false;
1372     }
1373     exif_set_rational((*ptrEntry)->data, order, rat);
1374     return true;
1375 }
1376 
CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1377 bool EXIFInfo::CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag &tag, ExifData *data, const std::string &value,
1378     ExifByteOrder order, ExifEntry **ptrEntry)
1379 {
1380     std::vector<std::string> longVec;
1381     SplitStr(value, ",", longVec);
1382     if (longVec.size() == CONSTANT_2) {
1383         return SetGpsDegreeRational(data, ptrEntry, order, tag, longVec);
1384     }
1385     if (longVec.size() != CONSTANT_3 || !IsValidGpsData(longVec, tag)) {
1386         IMAGE_LOGD("%{public}s Invalid value %{public}s", GetExifNameByExifTag(tag).c_str(),
1387             value.c_str());
1388         return false;
1389     }
1390     std::vector<ExifRational> longRational(GPS_DMS_COUNT);
1391     return ConvertGpsDataToRationals(longVec, longRational) &&
1392         SetGpsRationals(data, ptrEntry, order, tag, longRational);
1393 }
1394 
CreateExifEntry(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)1395 bool EXIFInfo::CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
1396     ExifByteOrder order, ExifEntry **ptrEntry)
1397 {
1398     static std::vector vector1{EXIF_TAG_ORIENTATION, EXIF_TAG_IMAGE_LENGTH, EXIF_TAG_IMAGE_WIDTH,
1399         EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, EXIF_TAG_FLASH, EXIF_TAG_ISO_SPEED_RATINGS,
1400         EXIF_TAG_ISO_SPEED, EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_METERING_MODE, EXIF_TAG_PIXEL_X_DIMENSION,
1401         EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_SENSITIVITY_TYPE};
1402     static std::vector vector2{EXIF_TAG_GPS_DATE_STAMP, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE, EXIF_TAG_MODEL,
1403         EXIF_TAG_SCENE_TYPE, EXIF_TAG_STANDARD_OUTPUT_SENSITIVITY, EXIF_TAG_USER_COMMENT, EXIF_TAG_DATE_TIME_ORIGINAL,
1404         EXIF_TAG_DATE_TIME, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TAG_GPS_LONGITUDE_REF};
1405     static std::vector vector3{EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_EXPOSURE_TIME,
1406         EXIF_TAG_FNUMBER, EXIF_TAG_FOCAL_LENGTH};
1407     if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
1408         return CreateExifEntryOfBitsPerSample(tag, data, value, order, ptrEntry);
1409     } else if (std::find(vector1.begin(), vector1.end(), tag) != vector1.end()) {
1410         *ptrEntry = InitExifTag(data, GetExifIfdByExifTag(tag), tag);
1411         if ((*ptrEntry) == nullptr) {
1412             IMAGE_LOGD("Get %{public}s exif entry failed.", GetExifNameByExifTag(tag).c_str());
1413             return false;
1414         }
1415         ExifIntValueByFormat((*ptrEntry)->data, order, (*ptrEntry)->format, atoi(value.c_str()));
1416         return true;
1417     } else if (std::find(vector2.begin(), vector2.end(), tag) != vector2.end()) {
1418         *ptrEntry = CreateExifTag(data, GetExifIfdByExifTag(tag), tag, value.length(), GetExifFormatByExifTag(tag));
1419         if ((*ptrEntry) == nullptr || (*ptrEntry)->size < value.length()) {
1420             IMAGE_LOGD("Get %{public}s exif entry failed.", GetExifNameByExifTag(tag).c_str());
1421             return false;
1422         }
1423         if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
1424             IMAGE_LOGD("%{public}s memcpy error", GetExifNameByExifTag(tag).c_str());
1425         }
1426         return true;
1427     } else if (tag == EXIF_TAG_GPS_LATITUDE || tag == EXIF_TAG_GPS_LONGITUDE) {
1428         return CreateExifEntryOfGpsLatitudeOrLongitude(tag, data, value, order, ptrEntry);
1429     } else if (std::find(vector3.begin(), vector3.end(), tag) != vector3.end()) {
1430         return CreateExifEntryOfRationalExif(tag, data, value, order, ptrEntry, "/", static_cast<size_t>(CONSTANT_2));
1431     } else if (tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1432         return CreateExifEntryOfCompressedBitsPerPixel(tag, data, value, order, ptrEntry);
1433     } else if (tag == EXIF_TAG_GPS_TIME_STAMP) {
1434         return CreateExifEntryOfGpsTimeStamp(tag, data, value, order, ptrEntry);
1435     }
1436     return true;
1437 }
1438 
WriteExifDataToFile(ExifData * data,unsigned int orginExifDataLength,unsigned long fileLength,unsigned char * buf,FILE * fp)1439 bool EXIFInfo::WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
1440     unsigned char *buf, FILE *fp)
1441 {
1442     unsigned char* exifDataBuf = nullptr;
1443     unsigned int exifDataBufLength = 0;
1444     exif_data_save_data(data, &exifDataBuf, &exifDataBufLength);
1445     if (exifDataBuf == nullptr) {
1446         IMAGE_LOGD("Get Exif Data Buf failed!");
1447         return false;
1448     }
1449 
1450     // Write EXIF header
1451     if (fwrite(EXIF_HEADER, sizeof(EXIF_HEADER), 1, fp) != 1) {
1452         IMAGE_LOGD("Error writing EXIF header to file!");
1453         ReleaseExifDataBuffer(exifDataBuf);
1454         return false;
1455     }
1456 
1457     // Write EXIF block length in big-endian order
1458     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, fp) < 0) {
1459         IMAGE_LOGD("Error writing EXIF block length to file!");
1460         ReleaseExifDataBuffer(exifDataBuf);
1461         return false;
1462     }
1463 
1464     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, fp) < 0) {
1465         IMAGE_LOGD("Error writing EXIF block length to file!");
1466         ReleaseExifDataBuffer(exifDataBuf);
1467         return false;
1468     }
1469 
1470     // Write EXIF data block
1471     if (fwrite(exifDataBuf, exifDataBufLength, 1, fp) != 1) {
1472         IMAGE_LOGD("Error writing EXIF data block to file!");
1473         ReleaseExifDataBuffer(exifDataBuf);
1474         return false;
1475     }
1476     // Write JPEG image data, skipping the non-EXIF header
1477     unsigned int dataOffset = orginExifDataLength + sizeof(EXIF_HEADER);
1478     if (fwrite(buf + dataOffset, fileLength - dataOffset, 1, fp) != 1) {
1479         IMAGE_LOGD("Error writing JPEG image data to file!");
1480         ReleaseExifDataBuffer(exifDataBuf);
1481         return false;
1482     }
1483 
1484     UpdateCacheExifData(fp);
1485     ReleaseExifDataBuffer(exifDataBuf);
1486     return true;
1487 }
1488 
ReleaseSource(unsigned char ** ptrBuf,FILE ** ptrFile)1489 void EXIFInfo::ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile)
1490 {
1491     if (ptrBuf != nullptr && *ptrBuf != nullptr) {
1492         free(*ptrBuf);
1493         *ptrBuf = nullptr;
1494         ptrBuf = nullptr;
1495     }
1496 
1497     if (ptrFile != nullptr && *ptrFile != nullptr) {
1498         fclose(*ptrFile);
1499         *ptrFile = nullptr;
1500         ptrFile = nullptr;
1501     }
1502 }
1503 
UpdateCacheExifData(FILE * fp)1504 void EXIFInfo::UpdateCacheExifData(FILE *fp)
1505 {
1506     unsigned long fileLength = GetFileSize(fp);
1507     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
1508         IMAGE_LOGD("Get file size failed.");
1509         return;
1510     }
1511 
1512     unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
1513     if (fileBuf == nullptr) {
1514         IMAGE_LOGD("Allocate buf failed.");
1515         return;
1516     }
1517 
1518     // Set current position to begin of file.
1519     (void)fseek(fp, 0L, 0);
1520     if (fread(fileBuf, fileLength, 1, fp) != 1) {
1521         IMAGE_LOGD("Read new file failed.");
1522         free(fileBuf);
1523         fileBuf = nullptr;
1524         return;
1525     }
1526 
1527     ParseExifData(fileBuf, static_cast<unsigned int>(fileLength));
1528     free(fileBuf);
1529     fileBuf = nullptr;
1530 }
1531 
GetFilterArea(const uint8_t * buf,const uint32_t & bufSize,const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1532 uint32_t EXIFInfo::GetFilterArea(const uint8_t *buf,
1533                                  const uint32_t &bufSize,
1534                                  const int &privacyType,
1535                                  std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1536 {
1537     std::unique_ptr<ByteOrderedBuffer> byteOrderedBuffer = std::make_unique<ByteOrderedBuffer>(buf, bufSize);
1538     byteOrderedBuffer->GenerateDEArray();
1539     if (byteOrderedBuffer->directoryEntryArray_.size() == 0) {
1540         IMAGE_LOGD("Read Exif info range failed.");
1541         return ERROR_PARSE_EXIF_FAILED;
1542     }
1543 
1544     GetAreaFromExifEntries(privacyType, byteOrderedBuffer->directoryEntryArray_, ranges);
1545     if (ranges.size() == 0) {
1546         IMAGE_LOGD("There is no exif info need filtered in this image.");
1547         return ERROR_NO_EXIF_TAGS;
1548     }
1549 
1550     return Media::SUCCESS;
1551 }
1552 
GetAreaFromExifEntries(const int & privacyType,const std::vector<DirectoryEntry> & entryArray,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1553 void EXIFInfo::GetAreaFromExifEntries(const int &privacyType,
1554                                       const std::vector<DirectoryEntry> &entryArray,
1555                                       std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1556 {
1557     if (privacyType == PERMISSION_GPS_TYPE) {
1558         for (size_t i = 0; i < entryArray.size(); i++) {
1559             if (entryArray[i].ifd == EXIF_IFD_GPS) {
1560                 std::pair<uint32_t, uint32_t> range =
1561                     std::make_pair(entryArray[i].valueOffset, entryArray[i].valueLength);
1562                 ranges.push_back(range);
1563             }
1564         }
1565     }
1566 }
1567 
ByteOrderedBuffer(const uint8_t * fileBuf,uint32_t bufferLength)1568 ByteOrderedBuffer::ByteOrderedBuffer(const uint8_t *fileBuf, uint32_t bufferLength)
1569     : buf_(fileBuf), bufferLength_(bufferLength)
1570 {
1571     if (bufferLength >= BUFFER_POSITION_12 && bufferLength >= BUFFER_POSITION_13) {
1572         if (fileBuf[BUFFER_POSITION_12] == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') {
1573             byteOrder_ = EXIF_BYTE_ORDER_MOTOROLA;
1574         } else {
1575             byteOrder_ = EXIF_BYTE_ORDER_INTEL;
1576         }
1577     }
1578 }
1579 
~ByteOrderedBuffer()1580 ByteOrderedBuffer::~ByteOrderedBuffer() {}
1581 
GenerateDEArray()1582 void ByteOrderedBuffer::GenerateDEArray()
1583 {
1584     // Move current position to begin of IFD0 offset segment
1585     curPosition_ = TIFF_OFFSET_FROM_FILE_BEGIN + CONSTANT_4;
1586     int32_t ifd0Offset = ReadInt32();
1587     if (ifd0Offset < 0) {
1588         IMAGE_LOGD("Get IFD0 offset failed!");
1589         return;
1590     }
1591     // Transform tiff offset to position of file
1592     ifd0Offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(ifd0Offset));
1593     // Move current position to begin of IFD0 segment
1594     curPosition_ = static_cast<uint32_t>(ifd0Offset);
1595 
1596     if (curPosition_ + CONSTANT_2 > bufferLength_) {
1597         IMAGE_LOGD("There is no data from the offset: %{public}d.", curPosition_);
1598         return;
1599     }
1600     GetDataRangeFromIFD(EXIF_IFD_0);
1601 }
1602 
GetDataRangeFromIFD(const ExifIfd & ifd)1603 void ByteOrderedBuffer::GetDataRangeFromIFD(const ExifIfd &ifd)
1604 {
1605     handledIfdOffsets_.push_back(curPosition_);
1606     int16_t entryCount = ReadShort();
1607     if (static_cast<uint32_t>(curPosition_ + BYTE_COUNTS_12 * entryCount) > bufferLength_ || entryCount <= 0) {
1608         IMAGE_LOGD(" The size of entries is either too big or negative.");
1609         return;
1610     }
1611     GetDataRangeFromDE(ifd, entryCount);
1612 
1613     if (Peek() + CONSTANT_4 <= bufferLength_) {
1614         int32_t nextIfdOffset = ReadInt32();
1615         if (nextIfdOffset == 0) {
1616             IMAGE_LOGD("Stop reading file since this IFD is finished");
1617             return;
1618         }
1619         // Transform tiff offset to position of file
1620         if (nextIfdOffset != -1) {
1621             nextIfdOffset = static_cast<int32_t>(TransformTiffOffsetToFilePos(nextIfdOffset));
1622         }
1623         // Check if the next IFD offset
1624         // 1. Exists within the boundaries of the buffer
1625         // 2. Does not point to a previously read IFD.
1626         if (nextIfdOffset > 0L && static_cast<uint32_t>(nextIfdOffset) < bufferLength_) {
1627             if (!IsIFDhandled(nextIfdOffset)) {
1628                 curPosition_ = static_cast<uint32_t>(nextIfdOffset);
1629                 ExifIfd nextIfd = GetNextIfdFromLinkList(ifd);
1630                 GetDataRangeFromIFD(nextIfd);
1631             } else {
1632                 IMAGE_LOGD("Stop reading buffer since re-reading an IFD at %{public}d.", nextIfdOffset);
1633             }
1634         } else {
1635             IMAGE_LOGD("Stop reading file since a wrong offset at %{public}d.", nextIfdOffset);
1636         }
1637     }
1638 }
1639 
GetDataRangeFromDE(const ExifIfd & ifd,const int16_t & count)1640 void ByteOrderedBuffer::GetDataRangeFromDE(const ExifIfd &ifd, const int16_t &count)
1641 {
1642     for (int16_t i = 0; i < count; i++) {
1643         uint16_t tagNumber = ReadUnsignedShort();
1644         uint16_t dataFormat = ReadUnsignedShort();
1645         int32_t numberOfComponents = ReadInt32();
1646         uint32_t nextEntryOffset = Peek() + CONSTANT_4;
1647 
1648         uint32_t byteCount = 0;
1649         bool valid = SetDEDataByteCount(tagNumber, dataFormat, numberOfComponents, byteCount);
1650         if (!valid) {
1651             curPosition_ = static_cast<uint32_t>(nextEntryOffset);
1652             continue;
1653         }
1654 
1655         // Read a value from data field or seek to the value offset which is stored in data
1656         // field if the size of the entry value is bigger than 4.
1657         // If the size of the entry value is less than 4, value is stored in value offset area.
1658         if (byteCount > CONSTANT_4) {
1659             int32_t offset = ReadInt32();
1660             // Transform tiff offset to position of file
1661             if (offset != -1) {
1662                 offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(offset));
1663             }
1664             if ((static_cast<uint32_t>(offset) + byteCount) <= bufferLength_) {
1665                 curPosition_ = static_cast<uint32_t>(offset);
1666             } else {
1667                 // Skip if invalid data offset.
1668                 IMAGE_LOGI("Skip the tag entry since data offset is invalid: %{public}d.", offset);
1669                 curPosition_ = nextEntryOffset;
1670                 continue;
1671             }
1672         }
1673 
1674         // Recursively parse IFD when a IFD pointer tag appears
1675         if (IsIFDPointerTag(tagNumber)) {
1676             ExifIfd ifdOfIFDPointerTag = GetIFDOfIFDPointerTag(tagNumber);
1677             ParseIFDPointerTag(ifdOfIFDPointerTag, dataFormat);
1678             curPosition_ = nextEntryOffset;
1679             continue;
1680         }
1681 
1682         uint32_t bytesOffset = Peek();
1683         uint32_t bytesLength = byteCount;
1684         DirectoryEntry directoryEntry = {static_cast<ExifTag>(tagNumber), static_cast<ExifFormat>(dataFormat),
1685                                          numberOfComponents, bytesOffset, bytesLength, ifd};
1686         directoryEntryArray_.push_back(directoryEntry);
1687 
1688         // Seek to next tag offset
1689         if (Peek() != nextEntryOffset) {
1690             curPosition_ = nextEntryOffset;
1691         }
1692     }
1693 }
1694 
TransformTiffOffsetToFilePos(const uint32_t & offset)1695 uint32_t ByteOrderedBuffer::TransformTiffOffsetToFilePos(const uint32_t &offset)
1696 {
1697     return offset + TIFF_OFFSET_FROM_FILE_BEGIN;
1698 }
1699 
SetDEDataByteCount(const uint16_t & tagNumber,const uint16_t & dataFormat,const int32_t & numberOfComponents,uint32_t & count)1700 bool ByteOrderedBuffer::SetDEDataByteCount(const uint16_t &tagNumber,
1701                                            const uint16_t &dataFormat,
1702                                            const int32_t &numberOfComponents,
1703                                            uint32_t &count)
1704 {
1705     if (IsValidTagNumber(tagNumber)) {
1706         IMAGE_LOGD("Skip the tag entry since tag number is not defined: %{public}d.", tagNumber);
1707     } else if (dataFormat <= 0 || exif_format_get_size(static_cast<ExifFormat>(dataFormat)) == 0) {
1708         IMAGE_LOGD("Skip the tag entry since data format is invalid: %{public}d.", dataFormat);
1709     } else {
1710         count = static_cast<uint32_t>(numberOfComponents) *
1711                 static_cast<uint32_t>(exif_format_get_size(static_cast<ExifFormat>(dataFormat)));
1712         if (count < 0) {
1713             IMAGE_LOGD("Skip the tag entry since the number of components is invalid: %{public}d.",
1714                 numberOfComponents);
1715         } else {
1716             return true;
1717         }
1718     }
1719     return false;
1720 }
1721 
ParseIFDPointerTag(const ExifIfd & ifd,const uint16_t & dataFormat)1722 void ByteOrderedBuffer::ParseIFDPointerTag(const ExifIfd &ifd, const uint16_t &dataFormat)
1723 {
1724     uint32_t offset = 0U;
1725     // Get offset from data field
1726     switch (static_cast<ExifFormat>(dataFormat)) {
1727         case EXIF_FORMAT_SHORT: {
1728             offset = static_cast<uint32_t>(ReadUnsignedShort());
1729             break;
1730         }
1731         case EXIF_FORMAT_SSHORT: {
1732             offset = ReadShort();
1733             break;
1734         }
1735         case EXIF_FORMAT_LONG: {
1736             offset = ReadUnsignedInt32();
1737             break;
1738         }
1739         case EXIF_FORMAT_SLONG: {
1740             offset = static_cast<uint32_t>(ReadInt32());
1741             break;
1742         }
1743         default: {
1744             // Nothing to do
1745             break;
1746         }
1747     }
1748     // Transform tiff offset to position of file
1749     offset = TransformTiffOffsetToFilePos(offset);
1750     // Check if the next IFD offset
1751     // 1. Exists within the boundaries of the buffer
1752     // 2. Does not point to a previously read IFD.
1753     if (offset > 0L && offset < bufferLength_) {
1754         if (!IsIFDhandled(offset)) {
1755             curPosition_ = offset;
1756             GetDataRangeFromIFD(ifd);
1757         } else {
1758             IMAGE_LOGD("Skip jump into the IFD since it has already been read at %{public}d.", offset);
1759         }
1760     } else {
1761         IMAGE_LOGD("Skip jump into the IFD since its offset is invalid: %{public}d.", offset);
1762     }
1763 }
1764 
IsValidTagNumber(const uint16_t & tagNumber)1765 bool ByteOrderedBuffer::IsValidTagNumber(const uint16_t &tagNumber)
1766 {
1767     for (uint32_t i = 0; (IsSameTextStr(EXIF_TAG_TABLE[i].name, "")); i++) {
1768         if (EXIF_TAG_TABLE[i].number == tagNumber) {
1769             return true;
1770         }
1771     }
1772     return false;
1773 }
1774 
IsIFDhandled(const uint32_t & position)1775 bool ByteOrderedBuffer::IsIFDhandled(const uint32_t &position)
1776 {
1777     if (handledIfdOffsets_.size() == 0) {
1778         IMAGE_LOGD("There is no handled IFD!");
1779         return false;
1780     }
1781 
1782     for (size_t i = 0; i < handledIfdOffsets_.size(); i++) {
1783         if (handledIfdOffsets_[i] == position) {
1784             return true;
1785         }
1786     }
1787     return false;
1788 }
1789 
IsIFDPointerTag(const uint16_t & tagNumber)1790 bool ByteOrderedBuffer::IsIFDPointerTag(const uint16_t &tagNumber)
1791 {
1792     bool ret = false;
1793     switch (static_cast<ExifTag>(tagNumber)) {
1794         case EXIF_TAG_SUB_IFDS:
1795         case EXIF_TAG_EXIF_IFD_POINTER:
1796         case EXIF_TAG_GPS_INFO_IFD_POINTER:
1797         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
1798             ret = true;
1799             break;
1800         default:
1801             break;
1802     }
1803     return ret;
1804 }
1805 
GetIFDOfIFDPointerTag(const uint16_t & tagNumber)1806 ExifIfd ByteOrderedBuffer::GetIFDOfIFDPointerTag(const uint16_t &tagNumber)
1807 {
1808     ExifIfd ifd = EXIF_IFD_COUNT;
1809     switch (static_cast<ExifTag>(tagNumber)) {
1810         case EXIF_TAG_EXIF_IFD_POINTER: {
1811             ifd = EXIF_IFD_EXIF;
1812             break;
1813         }
1814         case EXIF_TAG_GPS_INFO_IFD_POINTER: {
1815             ifd = EXIF_IFD_GPS;
1816             break;
1817         }
1818         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: {
1819             ifd = EXIF_IFD_INTEROPERABILITY;
1820             break;
1821         }
1822         default: {
1823             break;
1824         }
1825     }
1826     return ifd;
1827 }
1828 
GetNextIfdFromLinkList(const ExifIfd & ifd)1829 ExifIfd ByteOrderedBuffer::GetNextIfdFromLinkList(const ExifIfd &ifd)
1830 {
1831     ExifIfd nextIfd = EXIF_IFD_COUNT;
1832     /**
1833      * In jpeg file, the next IFD of IFD_0 in IFD link list is IFD_1,
1834      * other IFD is pointed by tag.
1835      */
1836     if (ifd == EXIF_IFD_0) {
1837         nextIfd = EXIF_IFD_1;
1838     }
1839     return nextIfd;
1840 }
1841 
ReadInt32()1842 int32_t ByteOrderedBuffer::ReadInt32()
1843 {
1844     // Move current position to begin of next segment
1845     curPosition_ += CONSTANT_4;
1846     if (curPosition_ > bufferLength_) {
1847         IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1848         return -1;
1849     }
1850 
1851     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1852         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]) << MOVE_OFFSET_24) |
1853                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_16) |
1854                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1855                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1856     } else {
1857         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_24) |
1858                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_16) |
1859                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_8) |
1860                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]));
1861     }
1862 }
1863 
ReadUnsignedInt32()1864 uint32_t ByteOrderedBuffer::ReadUnsignedInt32()
1865 {
1866     return (static_cast<uint32_t>(ReadInt32()) & 0xffffffff);
1867 }
1868 
ReadShort()1869 int16_t ByteOrderedBuffer::ReadShort()
1870 {
1871     // Move current position to begin of next segment
1872     curPosition_ += CONSTANT_2;
1873     if (curPosition_ > bufferLength_) {
1874         IMAGE_LOGD("Current Position %{public}u out of range.", curPosition_);
1875         return -1;
1876     }
1877 
1878     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1879         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1880                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1881     } else {
1882         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_8) |
1883                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]));
1884     }
1885 }
1886 
ReadUnsignedShort()1887 uint16_t ByteOrderedBuffer::ReadUnsignedShort()
1888 {
1889     return (static_cast<uint32_t>(ReadShort()) & 0xffff);
1890 }
1891 
Peek()1892 uint32_t ByteOrderedBuffer::Peek()
1893 {
1894     return curPosition_;
1895 }
1896 
CheckExifEntryValid(const ExifIfd & ifd,const ExifTag & tag)1897 bool EXIFInfo::CheckExifEntryValid(const ExifIfd &ifd, const ExifTag &tag)
1898 {
1899     bool ret = false;
1900     switch (ifd) {
1901         case EXIF_IFD_0: {
1902             if (tag == EXIF_TAG_ORIENTATION ||
1903                 tag == EXIF_TAG_BITS_PER_SAMPLE ||
1904                 tag == EXIF_TAG_IMAGE_LENGTH ||
1905                 tag == EXIF_TAG_IMAGE_WIDTH) {
1906                 ret = true;
1907             }
1908             break;
1909         }
1910         case EXIF_IFD_EXIF: {
1911             if (tag == EXIF_TAG_DATE_TIME_ORIGINAL ||
1912                 tag == EXIF_TAG_EXPOSURE_TIME ||
1913                 tag == EXIF_TAG_FNUMBER ||
1914                 tag == EXIF_TAG_ISO_SPEED_RATINGS ||
1915                 tag == EXIF_TAG_SCENE_TYPE ||
1916                 tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1917                 ret = true;
1918             }
1919             break;
1920         }
1921         case EXIF_IFD_GPS: {
1922             if (tag == EXIF_TAG_GPS_LATITUDE ||
1923                 tag == EXIF_TAG_GPS_LONGITUDE ||
1924                 tag == EXIF_TAG_GPS_LATITUDE_REF ||
1925                 tag == EXIF_TAG_GPS_LONGITUDE_REF) {
1926                 ret = true;
1927             }
1928             break;
1929         }
1930         default:
1931             break;
1932     }
1933 
1934     if (!ret) {
1935         ret = CheckExifEntryValidEx(ifd, tag);
1936     }
1937 
1938     return ret;
1939 }
1940 
CheckExifEntryValidEx(const ExifIfd & ifd,const ExifTag & tag)1941 bool EXIFInfo::CheckExifEntryValidEx(const ExifIfd &ifd, const ExifTag &tag)
1942 {
1943     static std::vector<ExifTag> ifd0TagVec{EXIF_TAG_DATE_TIME, EXIF_TAG_IMAGE_DESCRIPTION, EXIF_TAG_MAKE,
1944         EXIF_TAG_MODEL};
1945     static std::vector<ExifTag> ifdExifTagVec{TAG_SENSITIVITY_TYPE, TAG_STANDARD_OUTPUT_SENSITIVITY,
1946         TAG_RECOMMENDED_EXPOSURE_INDEX, EXIF_TAG_APERTURE_VALUE, EXIF_TAG_EXPOSURE_BIAS_VALUE, EXIF_TAG_METERING_MODE,
1947         EXIF_TAG_LIGHT_SOURCE, EXIF_TAG_FLASH, EXIF_TAG_FOCAL_LENGTH, EXIF_TAG_USER_COMMENT, EXIF_TAG_PIXEL_X_DIMENSION,
1948         EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TAG_WHITE_BALANCE, EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM};
1949     bool ret = false;
1950     switch (ifd) {
1951         case EXIF_IFD_0: {
1952             return std::find(ifd0TagVec.begin(), ifd0TagVec.end(), tag) != ifd0TagVec.end();
1953         }
1954         case EXIF_IFD_EXIF: {
1955             return std::find(ifdExifTagVec.begin(), ifdExifTagVec.end(), tag) != ifdExifTagVec.end();
1956         }
1957         case EXIF_IFD_GPS: {
1958             return tag == EXIF_TAG_GPS_TIME_STAMP || tag == EXIF_TAG_GPS_DATE_STAMP;
1959         }
1960         default:
1961             break;
1962     }
1963 
1964     return ret;
1965 }
1966 
NumSplit(std::string & src,std::vector<std::string> & out)1967 static void NumSplit(std::string &src, std::vector<std::string> &out)
1968 {
1969     if (src.size() == 0) {
1970         return;
1971     }
1972     std::vector<std::string> res;
1973     size_t last = 0;
1974     for (size_t i = 0; i < src.size(); i++) {
1975         if (!std::isdigit(src[i])) {
1976             size_t splitSize = i - last;
1977             if (splitSize != 0) {
1978                 res.push_back(src.substr(last, splitSize));
1979             }
1980             last = i + SIZE_1;
1981         }
1982     }
1983     if (last <= (src.size() - SIZE_1)) {
1984         res.push_back(src.substr(last));
1985     }
1986     for (size_t i = 0; i < res.size() && i < out.size(); i++) {
1987         out[i] = res[i];
1988     }
1989 }
1990 
JoinStr(std::vector<std::string> & in,const std::string & delim)1991 static std::string JoinStr(std::vector<std::string> &in, const std::string &delim)
1992 {
1993     std::string res = "";
1994     for (size_t i = 0; i < (in.size() - SIZE_1); i++) {
1995         res.append(in[i]).append(delim);
1996     }
1997     res.append(in.back());
1998     return res;
1999 }
2000 
FormatTimeStamp(std::string & src,std::string & value)2001 static void FormatTimeStamp(std::string &src, std::string &value)
2002 {
2003     std::string date = src;
2004     std::string time = "";
2005     std::string::size_type position = src.find(" ");
2006     if (position != src.npos) {
2007         // Date and time
2008         date = src.substr(0, position);
2009         time = src.substr(position);
2010     }
2011     std::vector<std::string> dateVector = {"1970", "01", "01"};
2012     std::vector<std::string> timeVector = {"00", "00", "00"};
2013     NumSplit(date, dateVector);
2014     NumSplit(time, timeVector);
2015     value = JoinStr(dateVector, "-") + " " + JoinStr(timeVector, ":");
2016 }
2017 
SpecialExifData(EXIFInfo * info,const std::string & name,std::string & value)2018 static uint32_t SpecialExifData(EXIFInfo* info, const std::string &name, std::string &value)
2019 {
2020     if (IsSameTextStr(DATE_TIME_ORIGINAL_MEDIA, name)) {
2021         std::string orgValue;
2022         auto res = info->GetExifData(DATE_TIME_ORIGINAL, orgValue);
2023         if (res == Media::SUCCESS) {
2024             FormatTimeStamp(orgValue, value);
2025         }
2026         return res;
2027     } else if (IsSameTextStr(TAG_ORIENTATION_INT, name)) {
2028         std::string orgValue;
2029         auto res = info->GetExifData(TAG_ORIENTATION_STRING, orgValue);
2030         if (res != Media::SUCCESS) {
2031             return res;
2032         }
2033         if (ORIENTATION_INT_MAP.count(orgValue) == 0) {
2034             IMAGE_LOGD("SpecialExifData %{public}s not found %{public}s.",
2035                 name.c_str(), orgValue.c_str());
2036             return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2037         }
2038         value = std::to_string(ORIENTATION_INT_MAP.at(orgValue));
2039         return res;
2040     }
2041     return Media::ERR_MEDIA_STATUS_ABNORMAL;
2042 }
2043 
GetExifTagByName(const std::string & name,ExifTag & tag)2044 static bool GetExifTagByName(const std::string &name, ExifTag &tag)
2045 {
2046     auto find_item = std::find_if(TAG_MAP.begin(), TAG_MAP.end(),
2047         [name](const std::map<ExifTag, std::string>::value_type item) {
2048         return IsSameTextStr(item.second, name);
2049     });
2050     auto find_maker_item = std::find_if(TAG_MAKER_NOTE_MAP.begin(), TAG_MAKER_NOTE_MAP.end(),
2051         [name](const std::map<ExifTag, std::string>::value_type item) {
2052         return IsSameTextStr(item.second, name);
2053     });
2054     if (find_item == TAG_MAP.end() && find_maker_item == TAG_MAKER_NOTE_MAP.end()) {
2055         return false;
2056     }
2057     tag = find_item->first;
2058     return true;
2059 }
2060 
GetExifData(const std::string name,std::string & value)2061 uint32_t EXIFInfo::GetExifData(const std::string name, std::string &value)
2062 {
2063     auto res = SpecialExifData(this, name, value);
2064     if (res == Media::SUCCESS || res != Media::ERR_MEDIA_STATUS_ABNORMAL) {
2065         IMAGE_LOGD("GetExifData %{public}s special result with %{public}d.", name.c_str(), res);
2066         return res;
2067     }
2068     ExifTag tag;
2069     if (!GetExifTagByName(name, tag)) {
2070         IMAGE_LOGD("GetExifData %{public}s not in the TAGs map.", name.c_str());
2071         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2072     }
2073     DumpTagsMap(exifTags_);
2074     if (!exifTags_.Find(tag, value)) {
2075         IMAGE_LOGD("GetExifData has no tag %{public}s[%{public}d], tags Size: %{public}zu.",
2076             name.c_str(), tag, static_cast<size_t>(exifTags_.Size()));
2077         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2078     }
2079     if (IsSameTextStr(value, DEFAULT_EXIF_VALUE)) {
2080         IMAGE_LOGD("GetExifData %{public}s[%{public}d] value is DEFAULT_EXIF_VALUE.",
2081             name.c_str(), tag);
2082         return Media::ERR_MEDIA_VALUE_INVALID;
2083     }
2084     return Media::SUCCESS;
2085 }
2086 
ModifyExifData(const std::string name,const std::string & value,const std::string & path)2087 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const std::string &path)
2088 {
2089     ExifTag tag;
2090     if (!GetExifTagByName(name, tag)) {
2091         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2092         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2093     }
2094     return ModifyExifData(tag, value, path);
2095 }
2096 
ModifyExifData(const std::string name,const std::string & value,const int fd)2097 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, const int fd)
2098 {
2099     ExifTag tag;
2100     if (!GetExifTagByName(name, tag)) {
2101         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2102         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2103     }
2104     return ModifyExifData(tag, value, fd);
2105 }
2106 
ModifyExifData(const std::string name,const std::string & value,unsigned char * data,uint32_t size)2107 uint32_t EXIFInfo::ModifyExifData(const std::string name, const std::string &value, unsigned char *data, uint32_t size)
2108 {
2109     ExifTag tag;
2110     if (!GetExifTagByName(name, tag)) {
2111         IMAGE_LOGD("ModifyExifData %{public}s not in the TAGs map.", name.c_str());
2112         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
2113     }
2114     return ModifyExifData(tag, value, data, size);
2115 }
2116 } // namespace ImagePlugin
2117 } // namespace OHOS
2118