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