• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "exif_info.h"
17 #include <algorithm>
18 #include <cstdio>
19 #include <memory>
20 #include <unistd.h>
21 #include "media_errors.h"
22 #include "string_ex.h"
23 #include "securec.h"
24 
25 namespace OHOS {
26 namespace ImagePlugin {
27 namespace {
28     using namespace OHOS::HiviewDFX;
29     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "Exif" };
30     static constexpr int PARSE_EXIF_SUCCESS = 0;
31     static constexpr int PARSE_EXIF_DATA_ERROR = 10001;
32     static constexpr int PARSE_EXIF_IFD_ERROR = 10002;
33     static constexpr int BUFFER_POSITION_4 = 4;
34     static constexpr int BUFFER_POSITION_5 = 5;
35     static constexpr int BUFFER_POSITION_6 = 6;
36     static constexpr int BUFFER_POSITION_7 = 7;
37     static constexpr int BUFFER_POSITION_8 = 8;
38     static constexpr int BUFFER_POSITION_9 = 9;
39     static constexpr int BUFFER_POSITION_12 = 12;
40     static constexpr int BUFFER_POSITION_13 = 13;
41     static constexpr int LENGTH_OFFSET_2 = 2;
42     static constexpr int BYTE_COUNTS_12 = 12;
43     static constexpr int MOVE_OFFSET_8 = 8;
44     static constexpr int MOVE_OFFSET_16 = 16;
45     static constexpr int MOVE_OFFSET_24 = 24;
46     static constexpr int CONSTANT_2 = 2;
47     static constexpr int CONSTANT_3 = 3;
48     static constexpr int CONSTANT_4 = 4;
49     static constexpr unsigned long MAX_FILE_SIZE = 1000 * 1000 * 1000;
50     static constexpr uint32_t ERROR_PARSE_EXIF_FAILED = 1;
51     static constexpr uint32_t ERROR_NO_EXIF_TAGS = 2;
52 
53     /* raw EXIF header data */
54     static const unsigned char exifHeader[] = {
55         0xff, 0xd8, 0xff, 0xe1
56     };
57     /* Offset of tiff begin from jpeg file begin */
58     static constexpr uint32_t TIFF_OFFSET_FROM_FILE_BEGIN = 12;
59     static constexpr int PERMISSION_GPS_TYPE = 1;
60 
61     static const struct TagEntry {
62         /*! Tag ID. There may be duplicate tags when the same number is used for
63          * different meanings in different IFDs. */
64         ExifTag tag;
65         const std::string name;
66         const uint16_t number;
67     } ExifTagTable[] = {
68         {EXIF_TAG_GPS_VERSION_ID, "GPSVersionID", 0x0000},
69         {EXIF_TAG_INTEROPERABILITY_INDEX, "InteroperabilityIndex", 0x0001},
70         {EXIF_TAG_GPS_LATITUDE_REF, "GPSLatitudeRef", 0x0001},
71         {EXIF_TAG_INTEROPERABILITY_VERSION, "InteroperabilityVersion", 0x0002},
72         {EXIF_TAG_GPS_LATITUDE, "GPSLatitude", 0x0002},
73         {EXIF_TAG_GPS_LONGITUDE_REF, "GPSLongitudeRef", 0x0003},
74         {EXIF_TAG_GPS_LONGITUDE, "GPSLongitude", 0x0004},
75         {EXIF_TAG_GPS_ALTITUDE_REF, "GPSAltitudeRef", 0x0005},
76         {EXIF_TAG_GPS_ALTITUDE, "GPSAltitude", 0x0006},
77         {EXIF_TAG_GPS_TIME_STAMP, "GPSTimeStamp", 0x0007},
78         {EXIF_TAG_GPS_SATELLITES, "GPSSatellites", 0x0008},
79         {EXIF_TAG_GPS_STATUS, "GPSStatus", 0x0009},
80         {EXIF_TAG_GPS_MEASURE_MODE, "GPSMeasureMode", 0x000a},
81         {EXIF_TAG_GPS_DOP, "GPSDOP", 0x000b},
82         {EXIF_TAG_GPS_SPEED_REF, "GPSSpeedRef", 0x000c},
83         {EXIF_TAG_GPS_SPEED, "GPSSpeed", 0x000d},
84         {EXIF_TAG_GPS_TRACK_REF, "GPSTrackRef", 0x000e},
85         {EXIF_TAG_GPS_TRACK, "GPSTrack", 0x000f},
86         {EXIF_TAG_GPS_IMG_DIRECTION_REF, "GPSImgDirectionRef", 0x0010},
87         {EXIF_TAG_GPS_IMG_DIRECTION, "GPSImgDirection", 0x0011},
88         {EXIF_TAG_GPS_MAP_DATUM, "GPSMapDatum", 0x0012},
89         {EXIF_TAG_GPS_DEST_LATITUDE_REF, "GPSDestLatitudeRef", 0x0013},
90         {EXIF_TAG_GPS_DEST_LATITUDE, "GPSDestLatitude", 0x0014},
91         {EXIF_TAG_GPS_DEST_LONGITUDE_REF, "GPSDestLongitudeRef", 0x0015},
92         {EXIF_TAG_GPS_DEST_LONGITUDE, "GPSDestLongitude", 0x0016},
93         {EXIF_TAG_GPS_DEST_BEARING_REF, "GPSDestBearingRef", 0x0017},
94         {EXIF_TAG_GPS_DEST_BEARING, "GPSDestBearing", 0x0018},
95         {EXIF_TAG_GPS_DEST_DISTANCE_REF, "GPSDestDistanceRef", 0x0019},
96         {EXIF_TAG_GPS_DEST_DISTANCE, "GPSDestDistance", 0x001a},
97         {EXIF_TAG_GPS_PROCESSING_METHOD, "GPSProcessingMethod", 0x001b},
98         {EXIF_TAG_GPS_AREA_INFORMATION, "GPSAreaInformation", 0x001c},
99         {EXIF_TAG_GPS_DATE_STAMP, "GPSDateStamp", 0x001d},
100         {EXIF_TAG_GPS_DIFFERENTIAL, "GPSDifferential", 0x001e},
101         {EXIF_TAG_GPS_H_POSITIONING_ERROR, "GPSHPositioningError", 0x001f},
102         /* Not in EXIF 2.2 */
103         {EXIF_TAG_NEW_SUBFILE_TYPE, "NewSubfileType", 0x00fe},
104         {EXIF_TAG_IMAGE_WIDTH, "ImageWidth", 0x0100},
105         {EXIF_TAG_IMAGE_LENGTH, "ImageLength", 0x0101},
106         {EXIF_TAG_BITS_PER_SAMPLE, "BitsPerSample", 0x0102},
107         {EXIF_TAG_COMPRESSION, "Compression", 0x0103},
108         {EXIF_TAG_PHOTOMETRIC_INTERPRETATION, "PhotometricInterpretation", 0x0106},
109         /* Not in EXIF 2.2 */
110         {EXIF_TAG_FILL_ORDER, "FillOrder", 0x010a},
111         /* Not in EXIF 2.2 */
112         {EXIF_TAG_DOCUMENT_NAME, "DocumentName", 0x010d},
113         {EXIF_TAG_IMAGE_DESCRIPTION, "ImageDescription", 0x010e},
114         {EXIF_TAG_MAKE, "Make", 0x010f},
115         {EXIF_TAG_MODEL, "Model", 0x0110},
116         {EXIF_TAG_STRIP_OFFSETS, "StripOffsets", 0x0111},
117         {EXIF_TAG_ORIENTATION, "Orientation", 0x0112},
118         {EXIF_TAG_SAMPLES_PER_PIXEL, "SamplesPerPixel", 0x0115},
119         {EXIF_TAG_ROWS_PER_STRIP, "RowsPerStrip", 0x0116},
120         {EXIF_TAG_STRIP_BYTE_COUNTS, "StripByteCounts", 0x0117},
121         {EXIF_TAG_X_RESOLUTION, "XResolution", 0x011a},
122         {EXIF_TAG_Y_RESOLUTION, "YResolution", 0x011b},
123         {EXIF_TAG_PLANAR_CONFIGURATION, "PlanarConfiguration", 0x011c},
124         {EXIF_TAG_RESOLUTION_UNIT, "ResolutionUnit", 0x0128},
125         {EXIF_TAG_TRANSFER_FUNCTION, "TransferFunction", 0x012d},
126         {EXIF_TAG_SOFTWARE, "Software", 0x0131},
127         {EXIF_TAG_DATE_TIME, "DateTime", 0x0132},
128         {EXIF_TAG_ARTIST, "Artist", 0x013b},
129         {EXIF_TAG_WHITE_POINT, "WhitePoint", 0x013e},
130         {EXIF_TAG_PRIMARY_CHROMATICITIES, "PrimaryChromaticities", 0x013f},
131         /* Not in EXIF 2.2 */
132         {EXIF_TAG_SUB_IFDS, "SubIFDs", 0x014a},
133         /* Not in EXIF 2.2 */
134         {EXIF_TAG_TRANSFER_RANGE, "TransferRange", 0x0156},
135         /* Not in EXIF 2.2 */
136         {EXIF_TAG_JPEG_PROC, "JPEGProc", 0x0200},
137         {EXIF_TAG_JPEG_INTERCHANGE_FORMAT, "JPEGInterchangeFormat", 0x0201},
138         {EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, "JPEGInterchangeFormatLength", 0x0202},
139         {EXIF_TAG_YCBCR_COEFFICIENTS, "YCbCrCoefficients", 0x0211},
140         {EXIF_TAG_YCBCR_SUB_SAMPLING, "YCbCrSubSampling", 0x0212},
141         {EXIF_TAG_YCBCR_POSITIONING, "YCbCrPositioning", 0x0213},
142         {EXIF_TAG_REFERENCE_BLACK_WHITE, "ReferenceBlackWhite", 0x0214},
143         /* Not in EXIF 2.2 */
144         {EXIF_TAG_XML_PACKET, "XMLPacket", 0x02bc},
145         /* Not in EXIF 2.2 */
146         {EXIF_TAG_RELATED_IMAGE_FILE_FORMAT, "RelatedImageFileFormat", 0x1000},
147         /* Not in EXIF 2.2 */
148         {EXIF_TAG_RELATED_IMAGE_WIDTH, "RelatedImageWidth", 0x1001},
149         /* Not in EXIF 2.2 */
150         {EXIF_TAG_RELATED_IMAGE_LENGTH, "RelatedImageLength", 0x1002},
151         /* Not in EXIF 2.2 */
152         {EXIF_TAG_CFA_REPEAT_PATTERN_DIM, "CFARepeatPatternDim", 0x828d},
153         /* Not in EXIF 2.2 */
154         {EXIF_TAG_CFA_PATTERN, "CFAPattern", 0x828e},
155         /* Not in EXIF 2.2 */
156         {EXIF_TAG_BATTERY_LEVEL, "BatteryLevel", 0x828f},
157         {EXIF_TAG_COPYRIGHT, "Copyright", 0x8298},
158         {EXIF_TAG_EXPOSURE_TIME, "ExposureTime", 0x829a},
159         {EXIF_TAG_FNUMBER, "FNumber", 0x829d},
160         /* Not in EXIF 2.2 */
161         {EXIF_TAG_IPTC_NAA, "IPTC/NAA", 0x83bb},
162         /* Not in EXIF 2.2 */
163         {EXIF_TAG_IMAGE_RESOURCES, "ImageResources", 0x8649},
164         {EXIF_TAG_EXIF_IFD_POINTER, "ExifIfdPointer", 0x8769},
165         /* Not in EXIF 2.2 */
166         {EXIF_TAG_INTER_COLOR_PROFILE, "InterColorProfile", 0x8773},
167         {EXIF_TAG_EXPOSURE_PROGRAM, "ExposureProgram", 0x8822},
168         {EXIF_TAG_SPECTRAL_SENSITIVITY, "SpectralSensitivity", 0x8824},
169         {EXIF_TAG_GPS_INFO_IFD_POINTER, "GPSInfoIFDPointer", 0x8825},
170         {EXIF_TAG_ISO_SPEED_RATINGS, "ISOSpeedRatings", 0x8827},
171         {EXIF_TAG_OECF, "OECF", 0x8828},
172         /* Not in EXIF 2.2 */
173         {EXIF_TAG_TIME_ZONE_OFFSET, "TimeZoneOffset", 0x882a},
174         {EXIF_TAG_EXIF_VERSION, "ExifVersion", 0x9000},
175         {EXIF_TAG_DATE_TIME_ORIGINAL, "DateTimeOriginal", 0x9003},
176         {EXIF_TAG_DATE_TIME_DIGITIZED, "DateTimeDigitized", 0x9004},
177         {EXIF_TAG_COMPONENTS_CONFIGURATION, "ComponentsConfiguration", 0x9101},
178         {EXIF_TAG_COMPRESSED_BITS_PER_PIXEL, "CompressedBitsPerPixel", 0x9102},
179         {EXIF_TAG_SHUTTER_SPEED_VALUE, "ShutterSpeedValue", 0x9201},
180         {EXIF_TAG_APERTURE_VALUE, "ApertureValue", 0x9202},
181         {EXIF_TAG_BRIGHTNESS_VALUE, "BrightnessValue", 0x9203},
182         {EXIF_TAG_EXPOSURE_BIAS_VALUE, "ExposureBiasValue", 0x9204},
183         {EXIF_TAG_MAX_APERTURE_VALUE, "MaxApertureValue", 0x9205},
184         {EXIF_TAG_SUBJECT_DISTANCE, "SubjectDistance", 0x9206},
185         {EXIF_TAG_METERING_MODE, "MeteringMode", 0x9207},
186         {EXIF_TAG_LIGHT_SOURCE, "LightSource", 0x9208},
187         {EXIF_TAG_FLASH, "Flash", 0x9209},
188         {EXIF_TAG_FOCAL_LENGTH, "FocalLength", 0x920a},
189         {EXIF_TAG_SUBJECT_AREA, "SubjectArea", 0x9214},
190         /* Not in EXIF 2.2 */
191         {EXIF_TAG_TIFF_EP_STANDARD_ID, "TIFF/EPStandardID", 0x9216},
192         {EXIF_TAG_MAKER_NOTE, "MakerNote", 0x927c},
193         {EXIF_TAG_USER_COMMENT, "UserComment", 0x9286},
194         {EXIF_TAG_SUB_SEC_TIME, "SubsecTime", 0x9290},
195         {EXIF_TAG_SUB_SEC_TIME_ORIGINAL, "SubSecTimeOriginal", 0x9291},
196         {EXIF_TAG_SUB_SEC_TIME_DIGITIZED, "SubSecTimeDigitized", 0x9292},
197         /* Not in EXIF 2.2 (Microsoft extension) */
198         {EXIF_TAG_XP_TITLE, "XPTitle", 0x9c9b},
199         /* Not in EXIF 2.2 (Microsoft extension) */
200         {EXIF_TAG_XP_COMMENT, "XPComment", 0x9c9c},
201         /* Not in EXIF 2.2 (Microsoft extension) */
202         {EXIF_TAG_XP_AUTHOR, "XPAuthor", 0x9c9d},
203         /* Not in EXIF 2.2 (Microsoft extension) */
204         {EXIF_TAG_XP_KEYWORDS, "XPKeywords", 0x9c9e},
205         /* Not in EXIF 2.2 (Microsoft extension) */
206         {EXIF_TAG_XP_SUBJECT, "XPSubject", 0x9c9f},
207         {EXIF_TAG_FLASH_PIX_VERSION, "FlashpixVersion", 0xa000},
208         {EXIF_TAG_COLOR_SPACE, "ColorSpace", 0xa001},
209         {EXIF_TAG_PIXEL_X_DIMENSION, "PixelXDimension", 0xa002},
210         {EXIF_TAG_PIXEL_Y_DIMENSION, "PixelYDimension", 0xa003},
211         {EXIF_TAG_RELATED_SOUND_FILE, "RelatedSoundFile", 0xa004},
212         {EXIF_TAG_INTEROPERABILITY_IFD_POINTER, "InteroperabilityIFDPointer", 0xa005},
213         {EXIF_TAG_FLASH_ENERGY, "FlashEnergy", 0xa20b},
214         {EXIF_TAG_SPATIAL_FREQUENCY_RESPONSE, "SpatialFrequencyResponse", 0xa20c},
215         {EXIF_TAG_FOCAL_PLANE_X_RESOLUTION, "FocalPlaneXResolution", 0xa20e},
216         {EXIF_TAG_FOCAL_PLANE_Y_RESOLUTION, "FocalPlaneYResolution", 0xa20f},
217         {EXIF_TAG_FOCAL_PLANE_RESOLUTION_UNIT, "FocalPlaneResolutionUnit", 0xa210},
218         {EXIF_TAG_SUBJECT_LOCATION, "SubjectLocation", 0xa214},
219         {EXIF_TAG_EXPOSURE_INDEX, "ExposureIndex", 0xa215},
220         {EXIF_TAG_SENSING_METHOD, "SensingMethod", 0xa217},
221         {EXIF_TAG_FILE_SOURCE, "FileSource", 0xa300},
222         {EXIF_TAG_SCENE_TYPE, "SceneType", 0xa301},
223         {EXIF_TAG_NEW_CFA_PATTERN, "CFAPattern", 0xa302},
224         {EXIF_TAG_CUSTOM_RENDERED, "CustomRendered", 0xa401},
225         {EXIF_TAG_EXPOSURE_MODE, "ExposureMode", 0xa402},
226         {EXIF_TAG_WHITE_BALANCE, "WhiteBalance", 0xa403},
227         {EXIF_TAG_DIGITAL_ZOOM_RATIO, "DigitalZoomRatio", 0xa404},
228         {EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM, "FocalLengthIn35mmFilm", 0xa405},
229         {EXIF_TAG_SCENE_CAPTURE_TYPE, "SceneCaptureType", 0xa406},
230         {EXIF_TAG_GAIN_CONTROL, "GainControl", 0xa407},
231         {EXIF_TAG_CONTRAST, "Contrast", 0xa408},
232         {EXIF_TAG_SATURATION, "Saturation", 0xa409},
233         {EXIF_TAG_SHARPNESS, "Sharpness", 0xa40a},
234         {EXIF_TAG_DEVICE_SETTING_DESCRIPTION, "DeviceSettingDescription", 0xa40b},
235         {EXIF_TAG_SUBJECT_DISTANCE_RANGE, "SubjectDistanceRange", 0xa40c},
236         {EXIF_TAG_IMAGE_UNIQUE_ID, "ImageUniqueID", 0xa420},
237         /* EXIF 2.3 */
238         {EXIF_TAG_CAMERA_OWNER_NAME, "CameraOwnerName", 0xa430},
239         /* EXIF 2.3 */
240         {EXIF_TAG_BODY_SERIAL_NUMBER, "BodySerialNumber", 0xa431},
241         /* EXIF 2.3 */
242         {EXIF_TAG_LENS_SPECIFICATION, "LensSpecification", 0xa432},
243         /* EXIF 2.3 */
244         {EXIF_TAG_LENS_MAKE, "LensMake", 0xa433},
245         /* EXIF 2.3 */
246         {EXIF_TAG_LENS_MODEL, "LensModel", 0xa434},
247         /* EXIF 2.3 */
248         {EXIF_TAG_LENS_SERIAL_NUMBER, "LensSerialNumber", 0xa435},
249         /* EXIF 2.32 */
250         {EXIF_TAG_COMPOSITE_IMAGE, "CompositeImage", 0xa460},
251         /* EXIF 2.32 */
252         {EXIF_TAG_SOURCE_IMAGE_NUMBER_OF_COMPOSITE_IMAGE, "SourceImageNumberOfCompositeImage", 0xa461},
253         /* EXIF 2.32 */
254         {EXIF_TAG_SOURCE_EXPOSURE_TIMES_OF_COMPOSITE_IMAGE, "SourceExposureTimesOfCompositeImage", 0xa462},
255         /* EXIF 2.3 */
256         {EXIF_TAG_GAMMA, "Gamma", 0xa500},
257         /* Not in EXIF 2.2 */
258         {EXIF_TAG_PRINT_IMAGE_MATCHING, "PrintImageMatching", 0xc4a5},
259         /* Not in EXIF 2.2 (from the Microsoft HD Photo specification) */
260         {EXIF_TAG_PADDING, "Padding", 0xea1c},
261         {static_cast<ExifTag>(0xffff), "", 0xffff}};
262 }
263 
264 const std::string EXIFInfo::DEFAULT_EXIF_VALUE = "default_exif_value";
265 
EXIFInfo()266 EXIFInfo::EXIFInfo()
267     : bitsPerSample_(DEFAULT_EXIF_VALUE),
268       orientation_(DEFAULT_EXIF_VALUE),
269       imageLength_(DEFAULT_EXIF_VALUE),
270       imageWidth_(DEFAULT_EXIF_VALUE),
271       gpsLatitude_(DEFAULT_EXIF_VALUE),
272       gpsLongitude_(DEFAULT_EXIF_VALUE),
273       gpsLatitudeRef_(DEFAULT_EXIF_VALUE),
274       gpsLongitudeRef_(DEFAULT_EXIF_VALUE),
275       dateTimeOriginal_(DEFAULT_EXIF_VALUE),
276       exposureTime_(DEFAULT_EXIF_VALUE),
277       fNumber_(DEFAULT_EXIF_VALUE),
278       isoSpeedRatings_(DEFAULT_EXIF_VALUE),
279       sceneType_(DEFAULT_EXIF_VALUE),
280       compressedBitsPerPixel_(DEFAULT_EXIF_VALUE),
281       imageFileDirectory_(EXIF_IFD_COUNT),
282       exifData_(nullptr),
283       isExifDataParsed_(false)
284 {
285 }
286 
~EXIFInfo()287 EXIFInfo::~EXIFInfo()
288 {
289     if (exifData_ != nullptr) {
290         exif_data_unref(exifData_);
291         exifData_ = nullptr;
292     }
293 }
294 
ParseExifData(const unsigned char * buf,unsigned len)295 int EXIFInfo::ParseExifData(const unsigned char *buf, unsigned len)
296 {
297     HiLog::Debug(LABEL, "ParseExifData ENTER");
298     exifData_ = exif_data_new_from_data(buf, len);
299     if (!exifData_) {
300         return PARSE_EXIF_DATA_ERROR;
301     }
302     exif_data_foreach_content(exifData_,
303         [](ExifContent *ec, void *userData) {
304             ExifIfd ifd = exif_content_get_ifd(ec);
305             (static_cast<EXIFInfo*>(userData))->imageFileDirectory_ = ifd;
306             if (ifd == EXIF_IFD_COUNT) {
307                 HiLog::Debug(LABEL, "GetIfd ERROR");
308                 return;
309             }
310             exif_content_foreach_entry(ec,
311                 [](ExifEntry *ee, void* userData) {
312                     if (ee == nullptr || userData == nullptr) {
313                         return;
314                     }
315                     char tagValueChar[1024];
316                     exif_entry_get_value(ee, tagValueChar, sizeof(tagValueChar));
317                     std::string tagValueStr(&tagValueChar[0], &tagValueChar[strlen(tagValueChar)]);
318                     if ((static_cast<EXIFInfo*>(userData))->CheckExifEntryValid(exif_entry_get_ifd(ee), ee->tag)) {
319                         (static_cast<EXIFInfo*>(userData))->SetExifTagValues(ee->tag, tagValueStr);
320                     }
321                 }, userData);
322         }, this);
323 
324     if (imageFileDirectory_ == EXIF_IFD_COUNT) {
325         return PARSE_EXIF_IFD_ERROR;
326     }
327     isExifDataParsed_ = true;
328     return PARSE_EXIF_SUCCESS;
329 }
330 
ParseExifData(const std::string & data)331 int EXIFInfo::ParseExifData(const std::string &data)
332 {
333     return ParseExifData((const unsigned char *)data.data(), data.length());
334 }
335 
IsExifDataParsed()336 bool EXIFInfo::IsExifDataParsed()
337 {
338     return isExifDataParsed_;
339 }
340 
SetExifTagValues(const ExifTag & tag,const std::string & value)341 void EXIFInfo::SetExifTagValues(const ExifTag &tag, const std::string &value)
342 {
343     if (tag == EXIF_TAG_BITS_PER_SAMPLE) {
344         bitsPerSample_ = value;
345     } else if (tag == EXIF_TAG_ORIENTATION) {
346         orientation_ = value;
347     } else if (tag == EXIF_TAG_IMAGE_LENGTH) {
348         imageLength_ = value;
349     } else if (tag == EXIF_TAG_IMAGE_WIDTH) {
350         imageWidth_ = value;
351     } else if (tag == EXIF_TAG_GPS_LATITUDE) {
352         gpsLatitude_ = value;
353     } else if (tag == EXIF_TAG_GPS_LONGITUDE) {
354         gpsLongitude_ = value;
355     } else if (tag == EXIF_TAG_GPS_LATITUDE_REF) {
356         gpsLatitudeRef_ = value;
357     } else if (tag == EXIF_TAG_GPS_LONGITUDE_REF) {
358         gpsLongitudeRef_ = value;
359     } else if (tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
360         dateTimeOriginal_ = value;
361     } else if (tag == EXIF_TAG_EXPOSURE_TIME) {
362         exposureTime_ = value;
363     } else if (tag == EXIF_TAG_FNUMBER) {
364         fNumber_ = value;
365     } else if (tag == EXIF_TAG_ISO_SPEED_RATINGS) {
366         isoSpeedRatings_ = value;
367     } else if (tag == EXIF_TAG_SCENE_TYPE) {
368         sceneType_ = value;
369     } else if (tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
370         compressedBitsPerPixel_ = value;
371     } else {
372         HiLog::Error(LABEL, "No match tag name!");
373     }
374 }
375 
ModifyExifData(const ExifTag & tag,const std::string & value,const std::string & path)376 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path)
377 {
378     FILE *file = fopen(path.c_str(), "rb");
379     if (file == nullptr) {
380         HiLog::Error(LABEL, "Error creating file %{public}s", path.c_str());
381         return Media::ERR_MEDIA_IO_ABNORMAL;
382     }
383 
384     // read jpeg file to buff
385     unsigned long fileLength = GetFileSize(file);
386     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
387         HiLog::Error(LABEL, "Get file size failed.");
388         (void)fclose(file);
389         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
390     }
391 
392     unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
393     if (fileBuf == nullptr) {
394         HiLog::Error(LABEL, "Allocate buf for %{public}s failed.", path.c_str());
395         (void)fclose(file);
396         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
397     }
398 
399     if (fread(fileBuf, fileLength, 1, file) != 1) {
400         HiLog::Error(LABEL, "Read %{public}s failed.", path.c_str());
401         ReleaseSource(&fileBuf, &file);
402         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
403     }
404 
405     if (!(fileBuf[0] == 0xFF && fileBuf[1] == 0xD8)) {
406         HiLog::Error(LABEL, "%{public}s is not jpeg file.", path.c_str());
407         ReleaseSource(&fileBuf, &file);
408         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
409     }
410 
411     ExifData *ptrExifData = nullptr;
412     bool isNewExifData = false;
413     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
414         ReleaseSource(&fileBuf, &file);
415         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
416     }
417     (void)fclose(file);
418     file = nullptr;
419 
420     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
421     if (!isNewExifData && orginExifDataLength == 0) {
422         HiLog::Error(LABEL, "There is no orginExifDataLength node in %{public}s.", path.c_str());
423         exif_data_unref(ptrExifData);
424         free(fileBuf);
425         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
426     }
427 
428     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
429     FILE *newFile = fopen(path.c_str(), "wb+");
430     if (newFile == nullptr) {
431         HiLog::Error(LABEL, "Error create new file %{public}s", path.c_str());
432         ReleaseSource(&fileBuf, &newFile);
433         return Media::ERR_MEDIA_IO_ABNORMAL;
434     }
435     ExifEntry *entry = nullptr;
436     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
437         ReleaseSource(&fileBuf, &newFile);
438         exif_data_unref(ptrExifData);
439         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
440     }
441     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, newFile)) {
442         ReleaseSource(&fileBuf, &newFile);
443         exif_data_unref(ptrExifData);
444         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
445     }
446     ReleaseSource(&fileBuf, &newFile);
447     exif_data_unref(ptrExifData);
448     return Media::SUCCESS;
449 }
450 
ModifyExifData(const ExifTag & tag,const std::string & value,const int fd)451 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value, const int fd)
452 {
453     const int localFd = dup(fd);
454     FILE *file = fdopen(localFd, "wb+");
455     if (file == nullptr) {
456         HiLog::Error(LABEL, "Error creating file %{public}d", localFd);
457         return Media::ERR_MEDIA_IO_ABNORMAL;
458     }
459 
460     // read jpeg file to buff
461     unsigned long fileLength = GetFileSize(file);
462     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
463         HiLog::Error(LABEL, "Get file size failed.");
464         (void)fclose(file);
465         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
466     }
467 
468     unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
469     if (fileBuf == nullptr) {
470         HiLog::Error(LABEL, "Allocate buf for %{public}d failed.", localFd);
471         (void)fclose(file);
472         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
473     }
474 
475     // Set current position to begin of file.
476     (void)fseek(file, 0L, 0);
477     if (fread(fileBuf, fileLength, 1, file) != 1) {
478         HiLog::Error(LABEL, "Read %{public}d failed.", localFd);
479         ReleaseSource(&fileBuf, &file);
480         return Media::ERR_MEDIA_READ_PARCEL_FAIL;
481     }
482 
483     if (!(fileBuf[0] == 0xFF && fileBuf[1] == 0xD8)) {
484         HiLog::Error(LABEL, "%{public}d is not jpeg file.", localFd);
485         ReleaseSource(&fileBuf, &file);
486         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
487     }
488 
489     ExifData *ptrExifData = nullptr;
490     bool isNewExifData = false;
491     if (!CreateExifData(fileBuf, fileLength, &ptrExifData, isNewExifData)) {
492         ReleaseSource(&fileBuf, &file);
493         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
494     }
495 
496     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, fileBuf);
497     if (!isNewExifData && orginExifDataLength == 0) {
498         HiLog::Error(LABEL, "There is no orginExifDataLength node in %{public}d.", localFd);
499         free(fileBuf);
500         exif_data_unref(ptrExifData);
501         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
502     }
503 
504     ExifByteOrder order = GetExifByteOrder(isNewExifData, fileBuf);
505     // Set current position to begin of new file.
506     (void)fseek(file, 0L, 0);
507     ExifEntry *entry = nullptr;
508     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
509         ReleaseSource(&fileBuf, &file);
510         exif_data_unref(ptrExifData);
511         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
512     }
513 
514     if (!WriteExifDataToFile(ptrExifData, orginExifDataLength, fileLength, fileBuf, file)) {
515         ReleaseSource(&fileBuf, &file);
516         exif_data_unref(ptrExifData);
517         return Media::ERR_MEDIA_WRITE_PARCEL_FAIL;
518     }
519     ReleaseSource(&fileBuf, &file);
520     exif_data_unref(ptrExifData);
521     return Media::SUCCESS;
522 }
523 
ModifyExifData(const ExifTag & tag,const std::string & value,unsigned char * data,uint32_t size)524 uint32_t EXIFInfo::ModifyExifData(const ExifTag &tag, const std::string &value,
525     unsigned char *data, uint32_t size)
526 {
527     if (data == nullptr) {
528         HiLog::Error(LABEL, "buffer is nullptr.");
529         return Media::ERR_IMAGE_SOURCE_DATA;
530     }
531 
532     if (size == 0) {
533         HiLog::Error(LABEL, "buffer size is 0.");
534         return Media::ERR_MEDIA_BUFFER_TOO_SMALL;
535     }
536 
537     if (!(data[0] == 0xFF && data[1] == 0xD8)) {
538         HiLog::Error(LABEL, "This is not jpeg file.");
539         return Media::ERR_IMAGE_MISMATCHED_FORMAT;
540     }
541 
542     ExifData *ptrExifData = nullptr;
543     bool isNewExifData = false;
544     if (!CreateExifData(data, size, &ptrExifData, isNewExifData)) {
545         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
546     }
547 
548     unsigned int orginExifDataLength = GetOrginExifDataLength(isNewExifData, data);
549     if (!isNewExifData && orginExifDataLength == 0) {
550         HiLog::Error(LABEL, "There is no orginExifDataLength node in buffer.");
551         exif_data_unref(ptrExifData);
552         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
553     }
554 
555     ExifByteOrder order = GetExifByteOrder(isNewExifData, data);
556     ExifEntry *entry = nullptr;
557     if (!CreateExifEntry(tag, ptrExifData, value, order, &entry)) {
558         exif_data_unref(ptrExifData);
559         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
560     }
561 
562     unsigned char* exifDataBuf = nullptr;
563     unsigned int exifDataBufLength = 0;
564     exif_data_save_data(ptrExifData, &exifDataBuf, &exifDataBufLength);
565     if (exifDataBuf == nullptr) {
566         HiLog::Error(LABEL, "Get Exif Data Buf failed!");
567         exif_data_unref(ptrExifData);
568         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
569     }
570 
571     if (size == 0 || size > MAX_FILE_SIZE) {
572         HiLog::Error(LABEL, "Buffer size is out of range.");
573         exif_data_unref(ptrExifData);
574         return Media::ERR_IMAGE_DECODE_EXIF_UNSUPPORT;
575     }
576     unsigned char *tempBuf = static_cast<unsigned char *>(malloc(size));
577     if (tempBuf == nullptr) {
578         HiLog::Error(LABEL, "Allocate temp buffer ailed.");
579         exif_data_unref(ptrExifData);
580         return Media::ERR_IMAGE_MALLOC_ABNORMAL;
581     }
582 
583     // Write EXIF header to buffer
584     uint32_t index = 0;
585     if (sizeof(exifHeader) >= size) {
586         HiLog::Error(LABEL, "There is not enough space for EXIF header!");
587         free(tempBuf);
588         tempBuf = nullptr;
589         exif_data_unref(ptrExifData);
590         return Media::ERR_MEDIA_OUT_OF_RANGE;
591     }
592 
593     for (size_t i = 0; i < sizeof(exifHeader); i++) {
594         tempBuf[index] = exifHeader[i];
595         index += 1;
596     }
597 
598     // Write EXIF block length in big-endian order
599     unsigned char highBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8);
600     if (index >= size) {
601         HiLog::Error(LABEL, "There is not enough space for writing EXIF block length!");
602         free(tempBuf);
603         tempBuf = nullptr;
604         exif_data_unref(ptrExifData);
605         return Media::ERR_MEDIA_OUT_OF_RANGE;
606     }
607     tempBuf[index] = highBit;
608     index += 1;
609 
610     unsigned char lowBit = static_cast<unsigned char>((exifDataBufLength + LENGTH_OFFSET_2) & 0xff);
611     if (index >= size) {
612         HiLog::Error(LABEL, "There is not enough space for writing EXIF block length!");
613         free(tempBuf);
614         tempBuf = nullptr;
615         exif_data_unref(ptrExifData);
616         return Media::ERR_MEDIA_OUT_OF_RANGE;
617     }
618     tempBuf[index] = lowBit;
619     index += 1;
620 
621     // Write EXIF data block
622     if ((index +  exifDataBufLength) >= size) {
623         HiLog::Error(LABEL, "There is not enough space for writing EXIF data block!");
624         free(tempBuf);
625         tempBuf = nullptr;
626         exif_data_unref(ptrExifData);
627         return Media::ERR_MEDIA_OUT_OF_RANGE;
628     }
629     for (unsigned int i = 0; i < exifDataBufLength; i++) {
630         tempBuf[index] = exifDataBuf[i];
631         index += 1;
632     }
633 
634     // Write JPEG image data, skipping the non-EXIF header
635     if ((index + size - orginExifDataLength - sizeof(exifHeader)) > size) {
636         HiLog::Error(LABEL, "There is not enough space for writing JPEG image data!");
637         free(tempBuf);
638         tempBuf = nullptr;
639         exif_data_unref(ptrExifData);
640         return Media::ERR_MEDIA_OUT_OF_RANGE;
641     }
642     for (unsigned int i = 0; i < (size - orginExifDataLength - sizeof(exifHeader)); i++) {
643         tempBuf[index] = data[orginExifDataLength + sizeof(exifHeader) + i];
644         index += 1;
645     }
646 
647     for (unsigned int i = 0; i < size; i++) {
648         data[i] = tempBuf[i];
649     }
650 
651     ParseExifData(data, static_cast<unsigned int>(index));
652     free(tempBuf);
653     tempBuf = nullptr;
654     exif_data_unref(ptrExifData);
655     return Media::SUCCESS;
656 }
657 
InitExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag)658 ExifEntry* EXIFInfo::InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag)
659 {
660     ExifEntry *entry;
661     /* Return an existing tag if one exists */
662     if (!(entry = exif_content_get_entry(exif->ifd[ifd], tag))) {
663         /* Allocate a new entry */
664         entry = exif_entry_new();
665         if (entry == nullptr) {
666             HiLog::Error(LABEL, "Create new entry failed!");
667             return nullptr;
668         }
669         entry->tag = tag; // tag must be set before calling exif_content_add_entry
670         /* Attach the ExifEntry to an IFD */
671         exif_content_add_entry (exif->ifd[ifd], entry);
672 
673         /* Allocate memory for the entry and fill with default data */
674         exif_entry_initialize (entry, tag);
675 
676         /* Ownership of the ExifEntry has now been passed to the IFD.
677          * One must be very careful in accessing a structure after
678          * unref'ing it; in this case, we know "entry" won't be freed
679          * because the reference count was bumped when it was added to
680          * the IFD.
681          */
682         exif_entry_unref(entry);
683     }
684     return entry;
685 }
686 
CreateExifTag(ExifData * exif,ExifIfd ifd,ExifTag tag,size_t len,ExifFormat format)687 ExifEntry* EXIFInfo::CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag,
688     size_t len, ExifFormat format)
689 {
690     void *buf;
691     ExifEntry *exifEntry;
692 
693     if ((exifEntry = exif_content_get_entry(exif->ifd[ifd], tag)) != nullptr) {
694         return exifEntry;
695     }
696 
697     /* Create a memory allocator to manage this ExifEntry */
698     ExifMem *exifMem = exif_mem_new_default();
699     if (exifMem == nullptr) {
700         HiLog::Error(LABEL, "Create mem failed!");
701         return nullptr;
702     }
703 
704     /* Create a new ExifEntry using our allocator */
705     exifEntry = exif_entry_new_mem (exifMem);
706     if (exifEntry == nullptr) {
707         HiLog::Error(LABEL, "Create entry by mem failed!");
708         return nullptr;
709     }
710 
711     /* Allocate memory to use for holding the tag data */
712     buf = exif_mem_alloc(exifMem, len);
713     if (buf == nullptr) {
714         HiLog::Error(LABEL, "Allocate memory failed!");
715         return nullptr;
716     }
717 
718     /* Fill in the entry */
719     exifEntry->data = static_cast<unsigned char*>(buf);
720     exifEntry->size = len;
721     exifEntry->tag = tag;
722     exifEntry->components = len;
723     exifEntry->format = format;
724 
725     /* Attach the ExifEntry to an IFD */
726     exif_content_add_entry (exif->ifd[ifd], exifEntry);
727 
728     /* The ExifMem and ExifEntry are now owned elsewhere */
729     exif_mem_unref(exifMem);
730     exif_entry_unref(exifEntry);
731 
732     return exifEntry;
733 }
734 
GetFileSize(FILE * fp)735 unsigned long EXIFInfo::GetFileSize(FILE *fp)
736 {
737     long int position;
738     long size;
739 
740     /* Save the current position. */
741     position = ftell(fp);
742 
743     /* Jump to the end of the file. */
744     (void)fseek(fp, 0L, SEEK_END);
745 
746     /* Get the end position. */
747     size = ftell(fp);
748 
749     /* Jump back to the original position. */
750     (void)fseek(fp, position, SEEK_SET);
751 
752     return static_cast<unsigned long>(size);
753 }
754 
CreateExifData(unsigned char * buf,unsigned long length,ExifData ** ptrData,bool & isNewExifData)755 bool EXIFInfo::CreateExifData(unsigned char *buf, unsigned long length, ExifData **ptrData, bool &isNewExifData)
756 {
757     if ((buf[BUFFER_POSITION_6] == 'E' && buf[BUFFER_POSITION_7] == 'x' &&
758         buf[BUFFER_POSITION_8] == 'i' && buf[BUFFER_POSITION_9] == 'f')) {
759         *ptrData = exif_data_new_from_data(buf, static_cast<unsigned int>(length));
760         if (!(*ptrData)) {
761             HiLog::Error(LABEL, "Create exif data from file failed.");
762             return false;
763         }
764         isNewExifData = false;
765         HiLog::Debug(LABEL, "Create exif data from buffer.");
766     } else {
767         *ptrData = exif_data_new();
768         if (!(*ptrData)) {
769             HiLog::Error(LABEL, "Create exif data failed.");
770             return false;
771         }
772         /* Set the image options */
773         exif_data_set_option(*ptrData, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);
774         exif_data_set_data_type(*ptrData, EXIF_DATA_TYPE_COMPRESSED);
775         exif_data_set_byte_order(*ptrData, EXIF_BYTE_ORDER_INTEL);
776 
777         /* Create the mandatory EXIF fields with default data */
778         exif_data_fix(*ptrData);
779         isNewExifData = true;
780         HiLog::Debug(LABEL, "Create new exif data.");
781     }
782     return true;
783 }
784 
GetOrginExifDataLength(const bool & isNewExifData,unsigned char * buf)785 unsigned int EXIFInfo::GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf)
786 {
787     unsigned int orginExifDataLength = 0;
788     if (!isNewExifData) {
789         orginExifDataLength = static_cast<unsigned int>(buf[BUFFER_POSITION_5]) |
790             static_cast<unsigned int>(buf[BUFFER_POSITION_4] << MOVE_OFFSET_8);
791     }
792     return orginExifDataLength;
793 }
794 
GetExifByteOrder(const bool & isNewExifData,unsigned char * buf)795 ExifByteOrder EXIFInfo::GetExifByteOrder(const bool &isNewExifData, unsigned char *buf)
796 {
797     if (isNewExifData) {
798         return EXIF_BYTE_ORDER_INTEL;
799     } else {
800         if (buf[BUFFER_POSITION_12] == 'M' && buf[BUFFER_POSITION_13] == 'M') {
801             return EXIF_BYTE_ORDER_MOTOROLA;
802         } else {
803             return EXIF_BYTE_ORDER_INTEL;
804         }
805     }
806 }
807 
CreateExifEntry(const ExifTag & tag,ExifData * data,const std::string & value,ExifByteOrder order,ExifEntry ** ptrEntry)808 bool EXIFInfo::CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
809     ExifByteOrder order, ExifEntry **ptrEntry)
810 {
811     switch (tag) {
812         case EXIF_TAG_BITS_PER_SAMPLE: {
813             *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_BITS_PER_SAMPLE);
814             if ((*ptrEntry) == nullptr) {
815                 HiLog::Error(LABEL, "Get exif entry failed.");
816                 return false;
817             }
818             std::vector<std::string> bitsVec;
819             SplitStr(value, ",", bitsVec);
820             if (bitsVec.size() > CONSTANT_2) {
821                 HiLog::Error(LABEL, "BITS_PER_SAMPLE Invalid value %{public}s", value.c_str());
822                 return false;
823             }
824             if (bitsVec.size() != 0) {
825                 for (size_t i = 0; i < bitsVec.size(); i++) {
826                     exif_set_short((*ptrEntry)->data + i * CONSTANT_2, order, (ExifShort)atoi(bitsVec[i].c_str()));
827                 }
828             }
829             break;
830         }
831         case EXIF_TAG_ORIENTATION: {
832             *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_ORIENTATION);
833             if ((*ptrEntry) == nullptr) {
834                 HiLog::Error(LABEL, "Get exif entry failed.");
835                 return false;
836             }
837             exif_set_short((*ptrEntry)->data, order, (ExifShort)atoi(value.c_str()));
838             break;
839         }
840         case EXIF_TAG_IMAGE_LENGTH: {
841             *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH);
842             if ((*ptrEntry) == nullptr) {
843                 HiLog::Error(LABEL, "Get exif entry failed.");
844                 return false;
845             }
846             exif_set_long((*ptrEntry)->data, order, (ExifLong)atoi(value.c_str()));
847             break;
848         }
849         case EXIF_TAG_IMAGE_WIDTH: {
850             *ptrEntry = InitExifTag(data, EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH);
851             if ((*ptrEntry) == nullptr) {
852                 HiLog::Error(LABEL, "Get exif entry failed.");
853                 return false;
854             }
855             exif_set_long((*ptrEntry)->data, order, (ExifLong)atoi(value.c_str()));
856             break;
857         }
858         case EXIF_TAG_GPS_LATITUDE: {
859             std::vector<std::string> latVec;
860             SplitStr(value, ",", latVec);
861             if (latVec.size() != CONSTANT_2) {
862                 HiLog::Error(LABEL, "GPS_LATITUDE Invalid value %{public}s", value.c_str());
863                 return false;
864             }
865 
866             ExifRational latRational;
867             latRational.numerator = static_cast<ExifSLong>(atoi(latVec[0].c_str()));
868             latRational.denominator = static_cast<ExifSLong>(atoi(latVec[1].c_str()));
869             *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE,
870                 sizeof(latRational), EXIF_FORMAT_RATIONAL);
871             if ((*ptrEntry) == nullptr) {
872                 HiLog::Error(LABEL, "Get exif entry failed.");
873                 return false;
874             }
875             exif_set_rational((*ptrEntry)->data, order, latRational);
876             break;
877         }
878         case EXIF_TAG_GPS_LONGITUDE: {
879             std::vector<std::string> longVec;
880             SplitStr(value, ",", longVec);
881             if (longVec.size() != CONSTANT_2) {
882                 HiLog::Error(LABEL, "GPS_LONGITUDE Invalid value %{public}s", value.c_str());
883                 return false;
884             }
885 
886             ExifRational longRational;
887             longRational.numerator = static_cast<ExifSLong>(atoi(longVec[0].c_str()));
888             longRational.denominator = static_cast<ExifSLong>(atoi(longVec[1].c_str()));
889             *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE,
890                 sizeof(longRational), EXIF_FORMAT_RATIONAL);
891             if ((*ptrEntry) == nullptr) {
892                 HiLog::Error(LABEL, "Get exif entry failed.");
893                 return false;
894             }
895             exif_set_rational((*ptrEntry)->data, order, longRational);
896             break;
897         }
898         case EXIF_TAG_GPS_LATITUDE_REF: {
899             *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LATITUDE_REF,
900                 value.length(), EXIF_FORMAT_ASCII);
901             if ((*ptrEntry) == nullptr) {
902                 HiLog::Error(LABEL, "Get exif entry failed.");
903                 return false;
904             }
905             if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
906                 HiLog::Error(LABEL, "LATITUDE ref memcpy error");
907             }
908             break;
909         }
910         case EXIF_TAG_GPS_LONGITUDE_REF: {
911             *ptrEntry = CreateExifTag(data, EXIF_IFD_GPS, EXIF_TAG_GPS_LONGITUDE_REF,
912                 value.length(), EXIF_FORMAT_ASCII);
913             if ((*ptrEntry) == nullptr) {
914                 HiLog::Error(LABEL, "Get exif entry failed.");
915                 return false;
916             }
917             if (memcpy_s((*ptrEntry)->data, value.length(), value.c_str(), value.length()) != 0) {
918                 HiLog::Error(LABEL, "LONGITUDE ref memcpy error");
919             }
920             break;
921         }
922         default:
923             break;
924     }
925     return true;
926 }
927 
WriteExifDataToFile(ExifData * data,unsigned int orginExifDataLength,unsigned long fileLength,unsigned char * buf,FILE * fp)928 bool EXIFInfo::WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
929     unsigned char *buf, FILE *fp)
930 {
931     unsigned char* exifDataBuf = nullptr;
932     unsigned int exifDataBufLength = 0;
933     exif_data_save_data(data, &exifDataBuf, &exifDataBufLength);
934     if (exifDataBuf == nullptr) {
935         HiLog::Error(LABEL, "Get Exif Data Buf failed!");
936         return false;
937     }
938 
939     // Write EXIF header
940     if (fwrite(exifHeader, sizeof(exifHeader), 1, fp) != 1) {
941         HiLog::Error(LABEL, "Error writing EXIF header to file!");
942         return false;
943     }
944 
945     // Write EXIF block length in big-endian order
946     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) >> MOVE_OFFSET_8, fp) < 0) {
947         HiLog::Error(LABEL, "Error writing EXIF block length to file!");
948         return false;
949     }
950 
951     if (fputc((exifDataBufLength + LENGTH_OFFSET_2) & 0xff, fp) < 0) {
952         HiLog::Error(LABEL, "Error writing EXIF block length to file!");
953         return false;
954     }
955 
956     // Write EXIF data block
957     if (fwrite(exifDataBuf, exifDataBufLength, 1, fp) != 1) {
958         HiLog::Error(LABEL, "Error writing EXIF data block to file!");
959         return false;
960     }
961     // Write JPEG image data, skipping the non-EXIF header
962     unsigned int dataOffset = orginExifDataLength + sizeof(exifHeader);
963     if (fwrite(buf + dataOffset, fileLength - dataOffset, 1, fp) != 1) {
964         HiLog::Error(LABEL, "Error writing JPEG image data to file!");
965         return false;
966     }
967 
968     UpdateCacheExifData(fp);
969     return true;
970 }
971 
ReleaseSource(unsigned char ** ptrBuf,FILE ** ptrFile)972 void EXIFInfo::ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile)
973 {
974     if (*ptrBuf) {
975         free(*ptrBuf);
976         *ptrBuf = nullptr;
977         ptrBuf = nullptr;
978     }
979 
980     if (*ptrFile != nullptr) {
981         fclose(*ptrFile);
982         *ptrFile = nullptr;
983         ptrFile = nullptr;
984     }
985 }
986 
UpdateCacheExifData(FILE * fp)987 void EXIFInfo::UpdateCacheExifData(FILE *fp)
988 {
989     unsigned long fileLength = GetFileSize(fp);
990     if (fileLength == 0 || fileLength > MAX_FILE_SIZE) {
991         HiLog::Error(LABEL, "Get file size failed.");
992         return;
993     }
994 
995     unsigned char *fileBuf = static_cast<unsigned char *>(malloc(fileLength));
996     if (fileBuf == nullptr) {
997         HiLog::Error(LABEL, "Allocate buf failed.");
998         return;
999     }
1000 
1001     // Set current position to begin of file.
1002     (void)fseek(fp, 0L, 0);
1003     if (fread(fileBuf, fileLength, 1, fp) != 1) {
1004         HiLog::Error(LABEL, "Read new file failed.");
1005         free(fileBuf);
1006         fileBuf = nullptr;
1007         return;
1008     }
1009 
1010     ParseExifData(fileBuf, static_cast<unsigned int>(fileLength));
1011     free(fileBuf);
1012     fileBuf = nullptr;
1013 }
1014 
GetFilterArea(const uint8_t * buf,const uint32_t & bufSize,const int & privacyType,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1015 uint32_t EXIFInfo::GetFilterArea(const uint8_t *buf,
1016                                  const uint32_t &bufSize,
1017                                  const int &privacyType,
1018                                  std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1019 {
1020     std::unique_ptr<ByteOrderedBuffer> byteOrderedBuffer = std::make_unique<ByteOrderedBuffer>(buf, bufSize);
1021     byteOrderedBuffer->GenerateDEArray();
1022     if (byteOrderedBuffer->directoryEntryArray_.size() == 0) {
1023         HiLog::Error(LABEL, "Read Exif info range failed.");
1024         return ERROR_PARSE_EXIF_FAILED;
1025     }
1026 
1027     GetAreaFromExifEntries(privacyType, byteOrderedBuffer->directoryEntryArray_, ranges);
1028     if (ranges.size() == 0) {
1029         HiLog::Error(LABEL, "There is no exif info need filtered in this image.");
1030         return ERROR_NO_EXIF_TAGS;
1031     }
1032 
1033     return Media::SUCCESS;
1034 }
1035 
GetAreaFromExifEntries(const int & privacyType,const std::vector<DirectoryEntry> & entryArray,std::vector<std::pair<uint32_t,uint32_t>> & ranges)1036 void EXIFInfo::GetAreaFromExifEntries(const int &privacyType,
1037                                       const std::vector<DirectoryEntry> &entryArray,
1038                                       std::vector<std::pair<uint32_t, uint32_t>> &ranges)
1039 {
1040     if (privacyType == PERMISSION_GPS_TYPE) {
1041         for (size_t i = 0; i < entryArray.size(); i++) {
1042             if (entryArray[i].ifd == EXIF_IFD_GPS) {
1043                 std::pair<uint32_t, uint32_t> range =
1044                     std::make_pair(entryArray[i].valueOffset, entryArray[i].valueLength);
1045                 ranges.push_back(range);
1046             }
1047         }
1048     }
1049 }
1050 
ByteOrderedBuffer(const uint8_t * fileBuf,uint32_t bufferLength)1051 ByteOrderedBuffer::ByteOrderedBuffer(const uint8_t *fileBuf, uint32_t bufferLength)
1052     : buf_(fileBuf), bufferLength_(bufferLength)
1053 {
1054     if (bufferLength >= BUFFER_POSITION_12 && bufferLength >= BUFFER_POSITION_13) {
1055         if (fileBuf[BUFFER_POSITION_12] == 'M' && fileBuf[BUFFER_POSITION_13] == 'M') {
1056             byteOrder_ = EXIF_BYTE_ORDER_MOTOROLA;
1057         } else {
1058             byteOrder_ = EXIF_BYTE_ORDER_INTEL;
1059         }
1060     }
1061 }
1062 
~ByteOrderedBuffer()1063 ByteOrderedBuffer::~ByteOrderedBuffer() {}
1064 
GenerateDEArray()1065 void ByteOrderedBuffer::GenerateDEArray()
1066 {
1067     // Move current position to begin of IFD0 offset segment
1068     curPosition_ = TIFF_OFFSET_FROM_FILE_BEGIN + CONSTANT_4;
1069     int32_t ifd0Offset = ReadInt32();
1070     if (ifd0Offset < 0) {
1071         HiLog::Error(LABEL, "Get IFD0 offset failed!");
1072         return;
1073     }
1074     // Transform tiff offset to position of file
1075     ifd0Offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(ifd0Offset));
1076     // Move current position to begin of IFD0 segment
1077     curPosition_ = static_cast<uint32_t>(ifd0Offset);
1078 
1079     if (curPosition_ + CONSTANT_2 > bufferLength_) {
1080         HiLog::Error(LABEL, "There is no data from the offset: %{public}d.", curPosition_);
1081         return;
1082     }
1083     GetDataRangeFromIFD(EXIF_IFD_0);
1084 }
1085 
GetDataRangeFromIFD(const ExifIfd & ifd)1086 void ByteOrderedBuffer::GetDataRangeFromIFD(const ExifIfd &ifd)
1087 {
1088     handledIfdOffsets_.push_back(curPosition_);
1089     int16_t entryCount = ReadShort();
1090     if (static_cast<uint32_t>(curPosition_ + BYTE_COUNTS_12 * entryCount) > bufferLength_ || entryCount <= 0) {
1091         HiLog::Error(LABEL, " The size of entries is either too big or negative.");
1092         return;
1093     }
1094     GetDataRangeFromDE(ifd, entryCount);
1095 
1096     if (Peek() + CONSTANT_4 <= bufferLength_) {
1097         int32_t nextIfdOffset = ReadInt32();
1098         if (nextIfdOffset == 0) {
1099             HiLog::Error(LABEL, "Stop reading file since this IFD is finished");
1100             return;
1101         }
1102         // Transform tiff offset to position of file
1103         if (nextIfdOffset != -1) {
1104             nextIfdOffset = static_cast<int32_t>(TransformTiffOffsetToFilePos(nextIfdOffset));
1105         }
1106         // Check if the next IFD offset
1107         // 1. Exists within the boundaries of the buffer
1108         // 2. Does not point to a previously read IFD.
1109         if (nextIfdOffset > 0L && static_cast<uint32_t>(nextIfdOffset) < bufferLength_) {
1110             if (!IsIFDhandled(nextIfdOffset)) {
1111                 curPosition_ = static_cast<uint32_t>(nextIfdOffset);
1112                 ExifIfd nextIfd = GetNextIfdFromLinkList(ifd);
1113                 GetDataRangeFromIFD(nextIfd);
1114             } else {
1115                 HiLog::Error(LABEL, "Stop reading buffer since re-reading an IFD at %{public}d.", nextIfdOffset);
1116             }
1117         } else {
1118             HiLog::Error(LABEL, "Stop reading file since a wrong offset at %{public}d.", nextIfdOffset);
1119         }
1120     }
1121 }
1122 
GetDataRangeFromDE(const ExifIfd & ifd,const int16_t & count)1123 void ByteOrderedBuffer::GetDataRangeFromDE(const ExifIfd &ifd, const int16_t &count)
1124 {
1125     for (int16_t i = 0; i < count; i++) {
1126         uint16_t tagNumber = ReadUnsignedShort();
1127         uint16_t dataFormat = ReadUnsignedShort();
1128         int32_t numberOfComponents = ReadInt32();
1129         uint32_t nextEntryOffset = Peek() + CONSTANT_4;
1130 
1131         uint32_t byteCount = 0;
1132         bool valid = SetDEDataByteCount(tagNumber, dataFormat, numberOfComponents, byteCount);
1133         if (!valid) {
1134             curPosition_ = static_cast<uint32_t>(nextEntryOffset);
1135             continue;
1136         }
1137 
1138         // Read a value from data field or seek to the value offset which is stored in data
1139         // field if the size of the entry value is bigger than 4.
1140         // If the size of the entry value is less than 4, value is stored in value offset area.
1141         if (byteCount > CONSTANT_4) {
1142             int32_t offset = ReadInt32();
1143             // Transform tiff offset to position of file
1144             if (offset != -1) {
1145                 offset = static_cast<int32_t>(TransformTiffOffsetToFilePos(offset));
1146             }
1147             if ((static_cast<uint32_t>(offset) + byteCount) <= bufferLength_) {
1148                 curPosition_ = static_cast<uint32_t>(offset);
1149             } else {
1150                 // Skip if invalid data offset.
1151                 HiLog::Error(LABEL, "Skip the tag entry since data offset is invalid: %{public}d.", offset);
1152                 curPosition_ = nextEntryOffset;
1153                 continue;
1154             }
1155         }
1156 
1157         // Recursively parse IFD when a IFD pointer tag appears
1158         if (IsIFDPointerTag(tagNumber)) {
1159             ExifIfd ifdOfIFDPointerTag = GetIFDOfIFDPointerTag(tagNumber);
1160             ParseIFDPointerTag(ifdOfIFDPointerTag, dataFormat);
1161             curPosition_ = nextEntryOffset;
1162             continue;
1163         }
1164 
1165         uint32_t bytesOffset = Peek();
1166         uint32_t bytesLength = byteCount;
1167         DirectoryEntry directoryEntry = {static_cast<ExifTag>(tagNumber), static_cast<ExifFormat>(dataFormat),
1168                                          numberOfComponents, bytesOffset, bytesLength, ifd};
1169         directoryEntryArray_.push_back(directoryEntry);
1170 
1171         // Seek to next tag offset
1172         if (Peek() != nextEntryOffset) {
1173             curPosition_ = nextEntryOffset;
1174         }
1175     }
1176 }
1177 
TransformTiffOffsetToFilePos(const uint32_t & offset)1178 uint32_t ByteOrderedBuffer::TransformTiffOffsetToFilePos(const uint32_t &offset)
1179 {
1180     return offset + TIFF_OFFSET_FROM_FILE_BEGIN;
1181 }
1182 
SetDEDataByteCount(const uint16_t & tagNumber,const uint16_t & dataFormat,const int32_t & numberOfComponents,uint32_t & count)1183 bool ByteOrderedBuffer::SetDEDataByteCount(const uint16_t &tagNumber,
1184                                            const uint16_t &dataFormat,
1185                                            const int32_t &numberOfComponents,
1186                                            uint32_t &count)
1187 {
1188     if (IsValidTagNumber(tagNumber)) {
1189         HiLog::Error(LABEL, "Skip the tag entry since tag number is not defined: %{public}d.", tagNumber);
1190     } else if (dataFormat <= 0 || exif_format_get_size(static_cast<ExifFormat>(dataFormat)) == 0) {
1191         HiLog::Error(LABEL, "Skip the tag entry since data format is invalid: %{public}d.", dataFormat);
1192     } else {
1193         count = static_cast<uint32_t>(numberOfComponents) *
1194                 static_cast<uint32_t>(exif_format_get_size(static_cast<ExifFormat>(dataFormat)));
1195         if (count < 0) {
1196             HiLog::Error(LABEL, "Skip the tag entry since the number of components is invalid: %{public}d.",
1197                          numberOfComponents);
1198         } else {
1199             return true;
1200         }
1201     }
1202     return false;
1203 }
1204 
ParseIFDPointerTag(const ExifIfd & ifd,const uint16_t & dataFormat)1205 void ByteOrderedBuffer::ParseIFDPointerTag(const ExifIfd &ifd, const uint16_t &dataFormat)
1206 {
1207     uint32_t offset = 0U;
1208     // Get offset from data field
1209     switch (static_cast<ExifFormat>(dataFormat)) {
1210         case EXIF_FORMAT_SHORT: {
1211             offset = static_cast<uint32_t>(ReadUnsignedShort());
1212             break;
1213         }
1214         case EXIF_FORMAT_SSHORT: {
1215             offset = ReadShort();
1216             break;
1217         }
1218         case EXIF_FORMAT_LONG: {
1219             offset = ReadUnsignedInt32();
1220             break;
1221         }
1222         case EXIF_FORMAT_SLONG: {
1223             offset = static_cast<uint32_t>(ReadInt32());
1224             break;
1225         }
1226         default: {
1227             // Nothing to do
1228             break;
1229         }
1230     }
1231     // Transform tiff offset to position of file
1232     offset = TransformTiffOffsetToFilePos(offset);
1233     // Check if the next IFD offset
1234     // 1. Exists within the boundaries of the buffer
1235     // 2. Does not point to a previously read IFD.
1236     if (offset > 0L && offset < bufferLength_) {
1237         if (!IsIFDhandled(offset)) {
1238             curPosition_ = offset;
1239             GetDataRangeFromIFD(ifd);
1240         } else {
1241             HiLog::Error(LABEL, "Skip jump into the IFD since it has already been read at %{public}d.", offset);
1242         }
1243     } else {
1244         HiLog::Error(LABEL, "Skip jump into the IFD since its offset is invalid: %{public}d.", offset);
1245     }
1246 }
1247 
IsValidTagNumber(const uint16_t & tagNumber)1248 bool ByteOrderedBuffer::IsValidTagNumber(const uint16_t &tagNumber)
1249 {
1250     for (uint32_t i = 0; (IsSameTextStr(ExifTagTable[i].name, "")); i++) {
1251         if (ExifTagTable[i].number == tagNumber) {
1252             return true;
1253         }
1254     }
1255     return false;
1256 }
1257 
IsIFDhandled(const uint32_t & position)1258 bool ByteOrderedBuffer::IsIFDhandled(const uint32_t &position)
1259 {
1260     if (handledIfdOffsets_.size() == 0) {
1261         HiLog::Error(LABEL, "There is no handled IFD!");
1262         return false;
1263     }
1264 
1265     for (size_t i = 0; i < handledIfdOffsets_.size(); i++) {
1266         if (handledIfdOffsets_[i] == position) {
1267             return true;
1268         }
1269     }
1270     return false;
1271 }
1272 
IsIFDPointerTag(const uint16_t & tagNumber)1273 bool ByteOrderedBuffer::IsIFDPointerTag(const uint16_t &tagNumber)
1274 {
1275     bool ret = false;
1276     switch (static_cast<ExifTag>(tagNumber)) {
1277         case EXIF_TAG_SUB_IFDS:
1278         case EXIF_TAG_EXIF_IFD_POINTER:
1279         case EXIF_TAG_GPS_INFO_IFD_POINTER:
1280         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER:
1281             ret = true;
1282             break;
1283         default:
1284             break;
1285     }
1286     return ret;
1287 }
1288 
GetIFDOfIFDPointerTag(const uint16_t & tagNumber)1289 ExifIfd ByteOrderedBuffer::GetIFDOfIFDPointerTag(const uint16_t &tagNumber)
1290 {
1291     ExifIfd ifd = EXIF_IFD_COUNT;
1292     switch (static_cast<ExifTag>(tagNumber)) {
1293         case EXIF_TAG_EXIF_IFD_POINTER: {
1294             ifd = EXIF_IFD_EXIF;
1295             break;
1296         }
1297         case EXIF_TAG_GPS_INFO_IFD_POINTER: {
1298             ifd = EXIF_IFD_GPS;
1299             break;
1300         }
1301         case EXIF_TAG_INTEROPERABILITY_IFD_POINTER: {
1302             ifd = EXIF_IFD_INTEROPERABILITY;
1303             break;
1304         }
1305         default: {
1306             break;
1307         }
1308     }
1309     return ifd;
1310 }
1311 
GetNextIfdFromLinkList(const ExifIfd & ifd)1312 ExifIfd ByteOrderedBuffer::GetNextIfdFromLinkList(const ExifIfd &ifd)
1313 {
1314     ExifIfd nextIfd = EXIF_IFD_COUNT;
1315     /**
1316      * In jpeg file, the next IFD of IFD_0 in IFD link list is IFD_1,
1317      * other IFD is pointed by tag.
1318      */
1319     if (ifd == EXIF_IFD_0) {
1320         nextIfd = EXIF_IFD_1;
1321     }
1322     return nextIfd;
1323 }
1324 
ReadInt32()1325 int32_t ByteOrderedBuffer::ReadInt32()
1326 {
1327     // Move current position to begin of next segment
1328     curPosition_ += CONSTANT_4;
1329     if (curPosition_ > bufferLength_) {
1330         HiLog::Error(LABEL, "Current Position %{public}u out of range.", curPosition_);
1331         return -1;
1332     }
1333 
1334     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1335         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]) << MOVE_OFFSET_24) |
1336                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_16) |
1337                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1338                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1339     } else {
1340         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_24) |
1341                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_16) |
1342                 (static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_3]) << MOVE_OFFSET_8) |
1343                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_4]));
1344     }
1345 }
1346 
ReadUnsignedInt32()1347 uint32_t ByteOrderedBuffer::ReadUnsignedInt32()
1348 {
1349     return (static_cast<uint32_t>(ReadInt32()) & 0xffffffff);
1350 }
1351 
ReadShort()1352 int16_t ByteOrderedBuffer::ReadShort()
1353 {
1354     // Move current position to begin of next segment
1355     curPosition_ += CONSTANT_2;
1356     if (curPosition_ > bufferLength_) {
1357         HiLog::Error(LABEL, "Current Position %{public}u out of range.", curPosition_);
1358         return -1;
1359     }
1360 
1361     if (byteOrder_ == EXIF_BYTE_ORDER_MOTOROLA) {
1362         return ((static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]) << MOVE_OFFSET_8) |
1363                 static_cast<unsigned int>(buf_[curPosition_ - 1]));
1364     } else {
1365         return ((static_cast<unsigned int>(buf_[curPosition_ - 1]) << MOVE_OFFSET_8) |
1366                 static_cast<unsigned int>(buf_[curPosition_ - CONSTANT_2]));
1367     }
1368 }
1369 
ReadUnsignedShort()1370 uint16_t ByteOrderedBuffer::ReadUnsignedShort()
1371 {
1372     return (static_cast<uint32_t>(ReadShort()) & 0xffff);
1373 }
1374 
Peek()1375 uint32_t ByteOrderedBuffer::Peek()
1376 {
1377     return curPosition_;
1378 }
1379 
CheckExifEntryValid(const ExifIfd & ifd,const ExifTag & tag)1380 bool EXIFInfo::CheckExifEntryValid(const ExifIfd &ifd, const ExifTag &tag)
1381 {
1382     bool ret = false;
1383     switch (ifd) {
1384         case EXIF_IFD_0: {
1385             if (tag == EXIF_TAG_ORIENTATION ||
1386                 tag == EXIF_TAG_BITS_PER_SAMPLE ||
1387                 tag == EXIF_TAG_IMAGE_LENGTH ||
1388                 tag == EXIF_TAG_IMAGE_WIDTH) {
1389                 ret = true;
1390             }
1391             break;
1392         }
1393         case EXIF_IFD_EXIF: {
1394             if (tag == EXIF_TAG_DATE_TIME_ORIGINAL ||
1395                 tag == EXIF_TAG_EXPOSURE_TIME ||
1396                 tag == EXIF_TAG_FNUMBER ||
1397                 tag == EXIF_TAG_ISO_SPEED_RATINGS ||
1398                 tag == EXIF_TAG_SCENE_TYPE ||
1399                 tag == EXIF_TAG_COMPRESSED_BITS_PER_PIXEL) {
1400                 ret = true;
1401             }
1402             break;
1403         }
1404         case EXIF_IFD_GPS: {
1405             if (tag == EXIF_TAG_GPS_LATITUDE ||
1406                 tag == EXIF_TAG_GPS_LONGITUDE ||
1407                 tag == EXIF_TAG_GPS_LATITUDE_REF ||
1408                 tag == EXIF_TAG_GPS_LONGITUDE_REF) {
1409                 ret = true;
1410             }
1411             break;
1412         }
1413         default:
1414             break;
1415     }
1416     return ret;
1417 }
1418 } // namespace ImagePlugin
1419 } // namespace OHOS
1420