1 /*
2  * Copyright (C) 2024 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 <array>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <string>
20 #include <sys/mman.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include "image_log.h"
24 #include "tiff_parser.h"
25 
26 #undef LOG_DOMAIN
27 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
28 
29 #undef LOG_TAG
30 #define LOG_TAG "TiffParser"
31 
32 namespace OHOS {
33 namespace Media {
34 namespace {
35     constexpr auto TIFF_BYTEORDER_SIZE = 4;
36     static const std::array<byte, TIFF_BYTEORDER_SIZE> tiffByteOrderII { 0x49, 0x49, 0x2a, 0x00 };
37     static const std::array<byte, TIFF_BYTEORDER_SIZE> tiffByteOrderMM { 0x4d, 0x4d, 0x00, 0x2a };
38 }
39 
Decode(const unsigned char * dataPtr,const uint32_t & size,ExifData ** exifData)40 void TiffParser::Decode(const unsigned char *dataPtr, const uint32_t &size, ExifData **exifData)
41 {
42     if (dataPtr == nullptr) {
43         return;
44     }
45     *exifData = exif_data_new();
46     exif_data_unset_option(*exifData, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
47     exif_data_load_data_general(*exifData, dataPtr, size);
48 }
49 
Encode(unsigned char ** dataPtr,uint32_t & size,ExifData * exifData)50 void TiffParser::Encode(unsigned char **dataPtr, uint32_t &size, ExifData *exifData)
51 {
52     if (exifData == nullptr) {
53         return;
54     }
55     exif_data_save_data_general(exifData, dataPtr, &size);
56     IMAGE_LOGD("Encode dataPtr size is: %{public}u", size);
57 }
58 
DecodeJpegExif(const unsigned char * dataPtr,const uint32_t & size,ExifData ** exifData)59 void TiffParser::DecodeJpegExif(const unsigned char *dataPtr, const uint32_t &size, ExifData **exifData)
60 {
61     IMAGE_LOGD("Decoding Jpeg Exif data.");
62     if (dataPtr == nullptr) {
63         return;
64     }
65     *exifData = exif_data_new();
66     exif_data_unset_option(*exifData, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
67     exif_data_load_data(*exifData, dataPtr, size);
68 }
69 
EncodeJpegExif(unsigned char ** dataPtr,uint32_t & size,ExifData * exifData)70 void TiffParser::EncodeJpegExif(unsigned char **dataPtr, uint32_t &size, ExifData *exifData)
71 {
72     IMAGE_LOGD("Encoding Jpeg Exif data.");
73     if (exifData == nullptr) {
74         return;
75     }
76     exif_data_save_data(exifData, dataPtr, &size);
77 }
78 
FindTiffPos(const DataBuf & dataBuf)79 size_t TiffParser::FindTiffPos(const DataBuf &dataBuf)
80 {
81     return FindTiffPos(dataBuf.CData(), dataBuf.Size());
82 }
83 
FindTiffPos(const byte * dataBuf,size_t bufLength)84 size_t TiffParser::FindTiffPos(const byte *dataBuf, size_t bufLength)
85 {
86     size_t tiffPos = std::numeric_limits<size_t>::max();
87     if (dataBuf == nullptr || bufLength < TIFF_BYTEORDER_SIZE) {
88         return tiffPos;
89     }
90 
91     for (size_t i = 0; i < bufLength - TIFF_BYTEORDER_SIZE; i++) {
92         if (memcmp(dataBuf + i, tiffByteOrderII.data(), tiffByteOrderII.size()) == 0) {
93             tiffPos = i;
94             break;
95         } else if (memcmp(dataBuf + i, tiffByteOrderMM.data(), tiffByteOrderMM.size()) == 0) {
96             tiffPos = i;
97             break;
98         }
99     }
100     return tiffPos;
101 }
102 } // namespace Media
103 } // namespace OHOS
104