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