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 #ifndef EXIF_INFO_H
16 #define EXIF_INFO_H
17 
18 #include <safe_map.h>
19 #include <string>
20 #include <vector>
21 
22 #include <libexif/exif-data.h>
23 
24 #include "exif_maker_note.h"
25 
26 namespace OHOS {
27 namespace ImagePlugin {
28 struct DirectoryEntry {
29     ExifTag tag;
30     ExifFormat format;
31     int32_t dataCounts;   // Counts of this format data
32     uint32_t valueOffset; // Offset of Directory Entry data area from JPEG File
33     uint32_t valueLength; // Length of Directory Entry data area
34     ExifIfd ifd;          // IFD of this Entry is in
35 };
36 
37 /*
38  * Class responsible for storing and parsing EXIF information from a JPEG blob
39  */
40 class EXIFInfo {
41 public:
42     EXIFInfo();
43     ~EXIFInfo();
44     /*
45      * Parsing function for an entire JPEG image buffer.
46      * PARAM 'data': A pointer to a JPEG image.
47      * PARAM 'length': The length of the JPEG image.
48      * RETURN:  PARSE_EXIF_SUCCESS (0) on success with 'result' filled out
49      *          error code otherwise, as defined by the PARSE_EXIF_ERROR_* macros
50      */
51     int ParseExifData(const unsigned char *buf, unsigned len);
52     int ParseExifData(const std::string &data);
53     uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, const std::string &path);
54     uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, const int fd);
55     uint32_t ModifyExifData(const ExifTag &tag, const std::string &value, unsigned char *data, uint32_t size);
56     uint32_t GetFilterArea(const uint8_t *buf,
57                               const uint32_t &bufSize,
58                               const int &privacyType,
59                               std::vector<std::pair<uint32_t, uint32_t>> &ranges);
60     bool IsExifDataParsed();
61     uint32_t GetExifData(const std::string name, std::string &value);
62     uint32_t ModifyExifData(const std::string name, const std::string &value, const std::string &path);
63     uint32_t ModifyExifData(const std::string name, const std::string &value, const int fd);
64     uint32_t ModifyExifData(const std::string name, const std::string &value, unsigned char *data, uint32_t size);
65 
66 public:
67     static const std::string DEFAULT_EXIF_VALUE;
68     std::string bitsPerSample_; // Number of bits in each pixel of an image.
69     std::string orientation_;
70     std::string imageLength_;   // Image length.
71     std::string imageWidth_;    // mage width.
72     std::string gpsLatitude_;
73     std::string gpsLongitude_;
74     std::string gpsLatitudeRef_;
75     std::string gpsLongitudeRef_;
76     std::string dateTimeOriginal_;  // Original date and time.
77     std::string exposureTime_;
78     std::string fNumber_;
79     std::string isoSpeedRatings_;
80     std::string sceneType_;
81     std::string compressedBitsPerPixel_;
82     std::string dateTime_;
83     std::string gpsTimeStamp_;
84     std::string gpsDateStamp_;
85     std::string imageDescription_;
86     std::string make_;
87     std::string model_;
88     std::string photoMode_;
89     std::string sensitivityType_;
90     std::string standardOutputSensitivity_;
91     std::string recommendedExposureIndex_;
92     std::string apertureValue_;
93     std::string exposureBiasValue_;
94     std::string meteringMode_;
95     std::string lightSource_;
96     std::string flash_;
97     std::string focalLength_;
98     std::string userComment_;
99     std::string pixelXDimension_;
100     std::string pixelYDimension_;
101     std::string whiteBalance_;
102     std::string focalLengthIn35mmFilm_;
103     std::string hwMnoteCaptureMode_;
104     std::string hwMnotePhysicalAperture_;
105     std::string hwMnoteRollAngle_;
106     std::string hwMnotePitchAngle_;
107     std::string hwMnoteSceneFoodConf_;
108     std::string hwMnoteSceneStageConf_;
109     std::string hwMnoteSceneBlueSkyConf_;
110     std::string hwMnoteSceneGreenPlantConf_;
111     std::string hwMnoteSceneBeachConf_;
112     std::string hwMnoteSceneSnowConf_;
113     std::string hwMnoteSceneSunsetConf_;
114     std::string hwMnoteSceneFlowersConf_;
115     std::string hwMnoteSceneNightConf_;
116     std::string hwMnoteSceneTextConf_;
117     std::string hwMnoteFaceCount_;
118     std::string hwMnoteFocusMode_;
119     std::map<std::string, std::string> makerInfoTagValueMap;
120 
121 private:
122     void SetExifTagValues(const ExifTag &tag, const std::string &value);
123     void SetExifTagValuesEx(const ExifTag &tag, const std::string &value);
124     ExifEntry* InitExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag);
125     ExifEntry* CreateExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len, ExifFormat format);
126     ExifEntry* GetExifTag(ExifData *exif, ExifIfd ifd, ExifTag tag, size_t len);
127     unsigned long GetFileSize(FILE *fp);
128     void ReleaseSource(unsigned char **ptrBuf, FILE **ptrFile);
129     bool CreateExifData(unsigned char *buf, unsigned long length, ExifData **data, bool &isNewExifData);
130     unsigned int GetOrginExifDataLength(const bool &isNewExifData, unsigned char *buf);
131     ExifByteOrder GetExifByteOrder(const bool &isNewExifData, unsigned char *buf);
132     bool CreateExifEntry(const ExifTag &tag, ExifData *data, const std::string &value,
133         ExifByteOrder order, ExifEntry **ptrEntry);
134     bool CreateExifEntryOfBitsPerSample(const ExifTag &tag, ExifData *data, const std::string &value,
135         ExifByteOrder order, ExifEntry **ptrEntry);
136     bool CreateExifEntryOfRationalExif(const ExifTag &tag, ExifData *data, const std::string &value,
137         ExifByteOrder order, ExifEntry **ptrEntry, const std::string& separator, size_t sepSize);
138     bool CreateExifEntryOfGpsTimeStamp(const ExifTag &tag, ExifData *data, const std::string &value,
139         ExifByteOrder order, ExifEntry **ptrEntry);
140     bool CreateExifEntryOfCompressedBitsPerPixel(const ExifTag &tag, ExifData *data, const std::string &value,
141         ExifByteOrder order, ExifEntry **ptrEntry);
142     bool CreateExifEntryOfGpsLatitudeOrLongitude(const ExifTag &tag, ExifData *data, const std::string &value,
143         ExifByteOrder order, ExifEntry **ptrEntry);
144     ExifIfd GetExifIfdByExifTag(const ExifTag &tag);
145     ExifFormat GetExifFormatByExifTag(const ExifTag &tag);
146     std::string GetExifNameByExifTag(const ExifTag &tag);
147     bool WriteExifDataToFile(ExifData *data, unsigned int orginExifDataLength, unsigned long fileLength,
148         unsigned char *buf, FILE *fp);
149     void UpdateCacheExifData(FILE *fp);
150     bool CheckExifEntryValid(const ExifIfd &ifd, const ExifTag &tag);
151     bool CheckExifEntryValidEx(const ExifIfd &ifd, const ExifTag &tag);
152     void GetAreaFromExifEntries(const int &privacyType,
153         const std::vector<DirectoryEntry> &entryArray,
154         std::vector<std::pair<uint32_t, uint32_t>> &ranges);
155     bool SetGpsRationals(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order, const ExifTag &tag,
156         const std::vector<ExifRational> &exifRationals);
157     bool SetGpsDegreeRational(ExifData *data, ExifEntry **ptrEntry, ExifByteOrder order, const ExifTag &tag,
158         const std::vector<std::string> &dataVec);
159     uint32_t GetFileInfoByPath(const std::string &path, FILE **file, unsigned long &fileLength,
160         unsigned char **fileBuf);
161     uint32_t GetFileInfoByFd(int localFd, FILE **file, unsigned long &fileLength, unsigned char **fileBuf);
162     void ReleaseExifData(unsigned char *tempBuf, ExifData *ptrExifData, unsigned char* exifDataBuf);
163     uint32_t CheckInputDataValid(unsigned char *data, uint32_t size);
164 
165 private:
166     ExifIfd imageFileDirectory_;
167     ExifData* exifData_;
168     bool isExifDataParsed_;
169     SafeMap<ExifTag, std::string> exifTags_;
170 };
171 
172 class ByteOrderedBuffer {
173 public:
174     ByteOrderedBuffer(const uint8_t *fileBuf, uint32_t bufferLength);
175     ~ByteOrderedBuffer();
176     void GenerateDEArray();
177 
178 public:
179     ExifByteOrder byteOrder_ = EXIF_BYTE_ORDER_MOTOROLA;
180     const uint8_t *buf_;
181     uint32_t bufferLength_ = 0;
182     uint32_t curPosition_ = 0;
183     std::vector<DirectoryEntry> directoryEntryArray_;
184     std::vector<uint32_t> handledIfdOffsets_;
185 
186 private:
187     void GetDataRangeFromIFD(const ExifIfd &ifd);
188     void GetDataRangeFromDE(const ExifIfd &ifd, const int16_t &count);
189     int32_t ReadInt32();
190     uint32_t ReadUnsignedInt32();
191     int16_t ReadShort();
192     uint16_t ReadUnsignedShort();
193     uint32_t Peek();
194     bool SetDEDataByteCount(const uint16_t &tagNumber,
195                             const uint16_t &dataFormat,
196                             const int32_t &numberOfComponents,
197                             uint32_t &count);
198     bool IsValidTagNumber(const uint16_t &tagNumber);
199     bool IsIFDhandled(const uint32_t &position);
200     bool IsIFDPointerTag(const uint16_t &tagNumber);
201     ExifIfd GetIFDOfIFDPointerTag(const uint16_t &tagNumber);
202     ExifIfd GetNextIfdFromLinkList(const ExifIfd &ifd);
203     void ParseIFDPointerTag(const ExifIfd &ifd, const uint16_t &dataFormat);
204     uint32_t TransformTiffOffsetToFilePos(const uint32_t &offset);
205 };
206 } // namespace ImagePlugin
207 } // namespace OHOS
208 #endif // EXIF_INFO_H
209