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 #ifndef PLUGINS_COMMON_LIBS_IMAGE_LIBEXTPLUGIN_INCLUDE_HEIF_PARSER_HEIF_PARSER_H
17 #define PLUGINS_COMMON_LIBS_IMAGE_LIBEXTPLUGIN_INCLUDE_HEIF_PARSER_HEIF_PARSER_H
18 
19 #include "box/heif_box.h"
20 #include "box/basic_box.h"
21 #include "box/item_data_box.h"
22 #include "box/item_info_box.h"
23 #include "box/item_property_box.h"
24 #include "box/item_property_color_box.h"
25 #include "box/item_property_hvcc_box.h"
26 #include "box/item_ref_box.h"
27 #include "heif_image.h"
28 
29 #include <map>
30 
31 namespace OHOS {
32 namespace ImagePlugin {
33 enum heif_header_option {
34     heif_header_data,
35     heif_no_header,
36     heif_only_header
37 };
38 
39 class HeifParser {
40 public:
41     HeifParser();
42 
HeifParser(const std::shared_ptr<HeifInputStream> & inputStream)43     explicit HeifParser(const std::shared_ptr<HeifInputStream> &inputStream) : inputStream_(inputStream) {};
44 
45     ~HeifParser();
46 
47     static heif_error MakeFromStream(const std::shared_ptr<HeifInputStream> &stream, std::shared_ptr<HeifParser> *out);
48 
49     static heif_error MakeFromMemory(const void *data, size_t size, bool isNeedCopy, std::shared_ptr<HeifParser> *out);
50 
51     void Write(HeifStreamWriter &writer);
52 
53     std::shared_ptr<HeifImage> GetImage(heif_item_id itemId);
54 
55     std::shared_ptr<HeifImage> GetPrimaryImage();
56 
57     std::shared_ptr<HeifImage> GetGainmapImage();
58 
59     std::shared_ptr<HeifImage> GetAuxiliaryMapImage(const std::string type);
60 
61     std::shared_ptr<HeifImage> GetTmapImage();
62 
63     std::string GetItemType(heif_item_id itemId) const;
64 
65     heif_error GetGridLength(heif_item_id itemId, size_t &length);
66 
67     heif_error GetItemData(heif_item_id itemId, std::vector<uint8_t> *out,
68                            heif_header_option option = heif_no_header) const;
69 
70     void GetTileImages(heif_item_id gridItemId, std::vector<std::shared_ptr<HeifImage>> &out);
71 
72     void GetIdenImage(heif_item_id itemId, std::shared_ptr<HeifImage> &out);
73 
74     void GetAllItemId(std::vector<heif_item_id> &itemIdList) const;
75 
76     heif_error SetExifMetadata(const std::shared_ptr<HeifImage> &master_image, const uint8_t *data, uint32_t size);
77 
78     heif_error UpdateExifMetadata(const std::shared_ptr<HeifImage> &master_image, const uint8_t *data,
79                                   uint32_t size, heif_item_id itemId);
80 
GetTiffOffset()81     long GetTiffOffset()
82     {
83         SetTiffOffset();
84         return tiffOffset_;
85     }
86 
87 private:
88     // stream
89     std::shared_ptr<HeifInputStream> inputStream_;
90 
91     long tiffOffset_ = 0;
92 
93     // boxes
94     std::shared_ptr<HeifFtypBox> ftypBox_;
95     std::shared_ptr<HeifMetaBox> metaBox_;
96     std::shared_ptr<HeifHdlrBox> hdlrBox_;
97     std::shared_ptr<HeifPtimBox> pitmBox_;
98     std::shared_ptr<HeifIinfBox> iinfBox_;
99     std::map<heif_item_id, std::shared_ptr<HeifInfeBox> > infeBoxes_;
100     std::shared_ptr<HeifIrefBox> irefBox_;
101     std::shared_ptr<HeifIprpBox> iprpBox_;
102     std::shared_ptr<HeifIpcoBox> ipcoBox_;
103     std::shared_ptr<HeifIpmaBox> ipmaBox_;
104     std::shared_ptr<HeifIdatBox> idatBox_;
105     std::shared_ptr<HeifIlocBox> ilocBox_;
106     std::vector<std::shared_ptr<HeifBox> > topBoxes_;
107 
108     // images
109     std::map<heif_item_id, std::shared_ptr<HeifImage>> images_;
110     std::shared_ptr<HeifImage> primaryImage_; // shortcut to primary image
111     std::shared_ptr<HeifImage> tmapImage_;
112 
113     // reading functions for boxes
114     heif_error AssembleBoxes(HeifStreamReader &reader);
115 
116     heif_item_id GetPrimaryItemId() const;
117 
118     bool HasItemId(heif_item_id itemId) const;
119 
120     std::string GetItemContentType(heif_item_id itemId) const;
121 
122     std::string GetItemUriType(heif_item_id itemId) const;
123 
124     std::shared_ptr<HeifInfeBox> GetInfeBox(heif_item_id itemId) const;
125 
126     heif_error GetAllProperties(heif_item_id itemId, std::vector<std::shared_ptr<HeifBox>> &properties) const;
127 
128     template<class BoxType>
GetProperty(heif_item_id itemId)129     std::shared_ptr<BoxType> GetProperty(heif_item_id itemId) const
130     {
131         std::vector<std::shared_ptr<HeifBox>> properties;
132         heif_error err = GetAllProperties(itemId, properties);
133         if (err) {
134             return nullptr;
135         }
136 
137         for (auto &property: properties) {
138             if (auto box = std::dynamic_pointer_cast<BoxType>(property)) {
139                 return box;
140             }
141         }
142         return nullptr;
143     }
144 
145     // reading functions for images
146     heif_error AssembleImages();
147 
148     void ExtractImageProperties(std::shared_ptr<HeifImage> &image);
149 
150     void ExtractDerivedImageProperties();
151 
152     void ExtractThumbnailImage(std::shared_ptr<HeifImage> &thumbnailImage, const HeifIrefBox::Reference &ref);
153 
154     void ExtractAuxImage(std::shared_ptr<HeifImage> &auxImage, const HeifIrefBox::Reference &ref);
155 
156     void ExtractNonMasterImages();
157 
158     void ExtractMetadata(const std::vector<heif_item_id> &allItemIds);
159 
160     // writing fuctions for boxes
161     heif_item_id GetNextItemId() const;
162 
163     std::shared_ptr<HeifInfeBox> AddItem(const char *itemType, bool hidden = false);
164 
165     void AddHvccProperty(heif_item_id itemId);
166 
167     heif_error AppendHvccNalData(heif_item_id itemId, const std::vector<uint8_t> &data);
168 
169     heif_error SetHvccConfig(heif_item_id itemId, const HvccConfig &config);
170 
171     void AddIspeProperty(heif_item_id itemId, uint32_t width, uint32_t height);
172 
173     void AddPixiProperty(heif_item_id itemId, uint8_t c1, uint8_t c2 = 0, uint8_t c3 = 0);
174 
175     heif_property_id AddProperty(heif_item_id itemId, const std::shared_ptr<HeifBox>& property, bool essential);
176 
177     void AppendIlocData(heif_item_id itemId, const std::vector<uint8_t> &data, uint8_t constructionMethod = 0);
178 
179     void SetPrimaryItemId(heif_item_id itemId);
180 
181     void AddReference(heif_item_id fromItemId, uint32_t type, const std::vector<heif_item_id> &toItemIds);
182 
183     void SetAuxcProperty(heif_item_id itemId, const std::string &type);
184 
185     void SetColorProfile(heif_item_id itemId, const std::shared_ptr<const HeifColorProfile> &profile);
186 
187     void CheckExtentData();
188 
189     // writing functions for images
190     void SetPrimaryImage(const std::shared_ptr<HeifImage> &image);
191 
192     uint32_t GetExifHeaderOffset(const uint8_t *data, uint32_t size);
193 
194     heif_error SetMetadata(const std::shared_ptr<HeifImage> &image, const std::vector<uint8_t> &data,
195                       const char *item_type, const char *content_type);
196 
197     uint8_t GetConstructMethod(const heif_item_id& id);
198 
199     void ExtractGainmap(const std::vector<heif_item_id>& allItemIds);
200 
201     void ExtractDisplayData(std::shared_ptr<HeifImage>& image, heif_item_id& itemId);
202 
203     void ExtractIT35Metadata(const heif_item_id& metadataItemId);
204 
205     void ExtractISOMetadata(const heif_item_id& itemId);
206 
207     void ExtractGainmapImage(const heif_item_id& tmapId);
208 
209     void ExtractFragmentMetadata(const heif_item_id& itemId);
210 
211     void SetTiffOffset();
212 };
213 } // namespace ImagePlugin
214 } // namespace OHOS
215 
216 #endif // PLUGINS_COMMON_LIBS_IMAGE_LIBEXTPLUGIN_INCLUDE_HEIF_PARSER_HEIF_PARSER_H
217