ImfIDManifest.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. // Copyright (c) Contributors to the OpenEXR Project.
  3. #ifndef INCLUDED_IMF_ID_MANIFEST_H
  4. #define INCLUDED_IMF_ID_MANIFEST_H
  5. //-----------------------------------------------------------------------------
  6. //
  7. // class IDManifest, to store a table mapping ID numbers to text
  8. //
  9. //-----------------------------------------------------------------------------
  10. #include "ImfForward.h"
  11. #include <cstdint>
  12. #include <map>
  13. #include <vector>
  14. #include <set>
  15. #include <string>
  16. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
  17. class IMF_EXPORT_TYPE IDManifest
  18. {
  19. public:
  20. // indication of how long a mapping between an ID number and the text holds for
  21. enum IMF_EXPORT_ENUM IdLifetime
  22. {
  23. LIFETIME_FRAME, // The mapping may change every frame:
  24. LIFETIME_SHOT, // The mapping is consistent for every frame of a shot
  25. LIFETIME_STABLE // The mapping is consistent for all time.
  26. };
  27. //
  28. // hashing scheme is stored as a string rather than an enum, to allow
  29. // proprietary schemes to be encoded with less danger of collision
  30. // proprietary schemes should be encoded in a reverse-URL syntax
  31. //
  32. IMF_EXPORT
  33. static const std::string UNKNOWN; // = "unknown" : default value for encoding scheme and hash scheme - should be changed
  34. IMF_EXPORT
  35. static const std::string NOTHASHED; // = "none" : no relationship between text and ID
  36. IMF_EXPORT
  37. static const std::string CUSTOMHASH; // = "custom" : text is hashed using defined scheme
  38. IMF_EXPORT
  39. static const std::string MURMURHASH3_32; // = "MurmurHash3_32" : MurmurHash3 32 bit is used
  40. IMF_EXPORT
  41. static const std::string MURMURHASH3_64; // = "MurmurHash3_64" : bottom 8 bytes of MurmarHash3_128 (64 bit architecture version) is used
  42. IMF_EXPORT
  43. static const std::string ID_SCHEME; // ="id" : 32 bit ID stored directly in a UINT channel
  44. IMF_EXPORT
  45. static const std::string ID2_SCHEME; // ="id2" : 64 bit ID stored in two channels, specified by the ChannelGroup
  46. IMF_EXPORT
  47. IDManifest();
  48. friend class CompressedIDManifest;
  49. //
  50. // decompress a compressed IDManifest into IDManifest for reading
  51. //
  52. IMF_EXPORT
  53. IDManifest(const CompressedIDManifest&);
  54. //
  55. // construct manifest from serialized representation stored at 'data'
  56. //
  57. IMF_EXPORT
  58. IDManifest(const char* data, const char* end);
  59. private :
  60. // internal helper function called by constructors
  61. IMF_HIDDEN void init(const char* data,const char* end);
  62. public :
  63. //
  64. // Description of the information represented by a single group of channels
  65. //
  66. class IMF_EXPORT_TYPE ChannelGroupManifest
  67. {
  68. private:
  69. std::set<std::string> _channels; // group of channels this manifest represents
  70. std::vector<std::string> _components; // ordered list of components represented by this channel group
  71. IdLifetime _lifeTime;
  72. std::string _hashScheme; //one of above strings or custom value e.g "nz.co.wetafx.cleverhash2"
  73. std::string _encodingScheme; //string identifying scheme to encode ID numbers within the image
  74. typedef std::map<uint64_t, std::vector<std::string> > IDTable;
  75. IDTable _table;
  76. // used for << operator to work: tracks the last item inserted into the Manifest
  77. IDTable::iterator _insertionIterator;
  78. bool _insertingEntry; // true if << has been called but not enough strings yet set
  79. public:
  80. IMF_EXPORT
  81. ChannelGroupManifest();
  82. IMF_EXPORT
  83. const std::set<std::string>& getChannels() const;
  84. IMF_EXPORT
  85. std::set<std::string>& getChannels();
  86. IMF_EXPORT
  87. void setChannels(const std::set<std::string>& channels);
  88. IMF_EXPORT
  89. void setChannel(const std::string& channel);
  90. // get list of components for this channel group
  91. IMF_EXPORT
  92. const std::vector<std::string>& getComponents() const;
  93. // set components: throws an exception if there are already entries in the table
  94. // and the component length changes
  95. IMF_EXPORT
  96. void setComponents(const std::vector<std::string>& components);
  97. // set name of single component: throws an exception if there are already entries in the table
  98. // unless there was previously one component
  99. IMF_EXPORT
  100. void setComponent(const std::string& component);
  101. IdLifetime getLifetime() const { return _lifeTime;}
  102. void setLifetime(const IdLifetime& lifeTime) { _lifeTime = lifeTime;}
  103. const std::string& getHashScheme() const { return _hashScheme;}
  104. void setHashScheme(const std::string& hashScheme) { _hashScheme = hashScheme;}
  105. const std::string& getEncodingScheme() const { return _encodingScheme;}
  106. void setEncodingScheme(const std::string& encodingScheme) { _encodingScheme = encodingScheme;}
  107. class Iterator; // iterator which allows modification of the text
  108. class ConstIterator; // iterator which does not allow modification
  109. IMF_EXPORT
  110. Iterator begin();
  111. IMF_EXPORT
  112. ConstIterator begin() const;
  113. IMF_EXPORT
  114. Iterator end();
  115. IMF_EXPORT
  116. ConstIterator end() const;
  117. // return number of entries in manifest - could be 0
  118. IMF_EXPORT
  119. size_t size() const ;
  120. // insert a new entry - text must contain same number of items as getComponents
  121. IMF_EXPORT
  122. Iterator insert(uint64_t idValue, const std::vector<std::string>& text);
  123. // insert a new entry - getComponents must be a single entry
  124. IMF_EXPORT
  125. Iterator insert(uint64_t idValue, const std::string& text);
  126. // compute hash of given entry, insert into manifest, and return
  127. // the computed hash. Exception will be thrown if hash scheme isn't recognised
  128. IMF_EXPORT
  129. uint64_t insert(const std::vector<std::string>& text);
  130. IMF_EXPORT
  131. uint64_t insert(const std::string& text);
  132. IMF_EXPORT
  133. Iterator find(uint64_t idValue);
  134. IMF_EXPORT
  135. ConstIterator find(uint64_t idValue) const;
  136. IMF_EXPORT
  137. void erase(uint64_t idValue);
  138. // return reference to idName for given idValue. Adds the mapping to the vector if it doesn't exist
  139. IMF_EXPORT
  140. std::vector<std::string>& operator[](uint64_t idValue);
  141. // add a new entry to the manifest as an insertion operator: <<
  142. // the component strings must also be inserted using <<
  143. // throws an exception if the previous insert operation didn't insert the correct number of string components
  144. IMF_EXPORT
  145. ChannelGroupManifest& operator<<(uint64_t idValue);
  146. // insert a string as the next component of a previously inserted attribute
  147. IMF_EXPORT
  148. ChannelGroupManifest& operator<<(const std::string& text);
  149. IMF_EXPORT
  150. bool operator==(const ChannelGroupManifest& other) const;
  151. bool operator!=(const ChannelGroupManifest& other) const { return !(*this==other);}
  152. friend class IDManifest;
  153. };
  154. private:
  155. std::vector<ChannelGroupManifest> _manifest;
  156. public:
  157. // add a new channel group definition to the table, presumably populated with mappings
  158. // 'table' will be copied to the internal manifest; to further modify use the return value
  159. IMF_EXPORT
  160. ChannelGroupManifest& add(const ChannelGroupManifest& table);
  161. //insert an empty table definition for the given channel / group of channels
  162. IMF_EXPORT
  163. ChannelGroupManifest& add(const std::set<std::string>& group);
  164. IMF_EXPORT
  165. ChannelGroupManifest& add(const std::string& channel);
  166. // return number of items in manifest
  167. IMF_EXPORT
  168. size_t size() const;
  169. // find the first manifest ChannelGroupManifest that defines the given channel
  170. // if channel not find, returns a value equal to size()
  171. IMF_EXPORT
  172. size_t find(const std::string& channel) const;
  173. IMF_EXPORT
  174. const ChannelGroupManifest& operator[](size_t index) const;
  175. IMF_EXPORT
  176. ChannelGroupManifest& operator[](size_t index);
  177. //
  178. // serialize manifest into data array. Array will be resized to the required size
  179. //
  180. IMF_EXPORT
  181. void serialize(std::vector<char>& data) const;
  182. IMF_EXPORT
  183. bool operator==(const IDManifest& other) const;
  184. IMF_EXPORT
  185. bool operator!=(const IDManifest& other) const;
  186. //
  187. // add entries from 'other' into this manifest if possible
  188. // * all ChannelGroupsManifests for different ChannelGroups
  189. // will be appended.
  190. // * Where 'other' contains a manifest for the same
  191. // ChannelGroup:
  192. // * If _components differs, the entire ChannelGroupManifest is skipped
  193. // * Otherwise, entries not present in 'this' will be inserted
  194. // * _hashScheme, _lifeTime and _encodingScheme will be unchanged
  195. //
  196. // returns 'false' if the same ChannelGroupManifest appears in both 'other' and 'this',
  197. // but with different _components, _hashScheme, _lifeTime or _encodingScheme
  198. // or if any idValue maps to different strings in 'other' and 'this'
  199. //
  200. IMF_EXPORT
  201. bool merge(const IDManifest& other);
  202. //
  203. // static has generation functions
  204. //
  205. IMF_EXPORT
  206. static unsigned int MurmurHash32(const std::string& idString);
  207. IMF_EXPORT
  208. static unsigned int MurmurHash32(const std::vector<std::string>& idString);
  209. IMF_EXPORT
  210. static uint64_t MurmurHash64(const std::string& idString);
  211. IMF_EXPORT
  212. static uint64_t MurmurHash64(const std::vector<std::string>& idString);
  213. };
  214. //
  215. // zlip compressed version of IDManifest - the IDManifestAttribute encodes this format
  216. // This should be transparent to the user, since there is implicit casting between the two types
  217. //
  218. class CompressedIDManifest
  219. {
  220. public:
  221. IMF_EXPORT
  222. CompressedIDManifest();
  223. IMF_EXPORT
  224. CompressedIDManifest(const CompressedIDManifest& other);
  225. IMF_EXPORT
  226. CompressedIDManifest& operator=(const CompressedIDManifest& other);
  227. //
  228. // construct a compressed version of the given manifest - to decompress it cast to an IDManifest
  229. //
  230. IMF_EXPORT
  231. CompressedIDManifest(const IDManifest& manifest);
  232. IMF_EXPORT
  233. ~CompressedIDManifest();
  234. int _compressedDataSize;
  235. size_t _uncompressedDataSize;
  236. unsigned char* _data;
  237. };
  238. //
  239. // Read/Write Iterator object to access individual entries within a manifest
  240. //
  241. class IDManifest::ChannelGroupManifest::Iterator
  242. {
  243. public:
  244. IMF_EXPORT
  245. Iterator ();
  246. IMF_EXPORT
  247. explicit Iterator (const IDManifest::ChannelGroupManifest::IDTable::iterator &i);
  248. friend class IDManifest::ChannelGroupManifest::ConstIterator;
  249. IMF_EXPORT
  250. Iterator & operator ++ ();
  251. IMF_EXPORT
  252. uint64_t id() const;
  253. IMF_EXPORT
  254. std::vector<std::string>& text();
  255. private:
  256. std::map< uint64_t , std::vector<std::string> >::iterator _i;
  257. };
  258. //
  259. // Read-only Iterator object to access individual entries within a manifest
  260. //
  261. class IDManifest::ChannelGroupManifest::ConstIterator
  262. {
  263. public:
  264. IMF_EXPORT
  265. ConstIterator ();
  266. // explicit cast from internal map operator (for internal use only)
  267. IMF_EXPORT
  268. explicit ConstIterator (const IDManifest::ChannelGroupManifest::IDTable::const_iterator &i);
  269. // cast from non-const to const iterator
  270. IMF_EXPORT
  271. ConstIterator (const IDManifest::ChannelGroupManifest::Iterator &other);
  272. IMF_EXPORT
  273. ConstIterator & operator ++ ();
  274. IMF_EXPORT
  275. uint64_t id() const;
  276. IMF_EXPORT
  277. const std::vector<std::string>& text() const;
  278. private:
  279. std::map< uint64_t , std::vector<std::string> >::const_iterator _i;
  280. friend bool operator == (const ConstIterator &, const ConstIterator &);
  281. friend bool operator != (const ConstIterator &, const ConstIterator &);
  282. };
  283. //
  284. // ChannelGroupManifest::Iterator implementation: all inline
  285. //
  286. inline IDManifest::ChannelGroupManifest::Iterator::Iterator() {}
  287. inline IDManifest::ChannelGroupManifest::Iterator::Iterator(const IDManifest::ChannelGroupManifest::IDTable::iterator &i) :_i(i) {}
  288. inline uint64_t
  289. IDManifest::ChannelGroupManifest::Iterator::id() const { return _i->first;}
  290. inline std::vector<std::string>&
  291. IDManifest::ChannelGroupManifest::Iterator::text() { return _i->second;}
  292. inline IDManifest::ChannelGroupManifest::Iterator&
  293. IDManifest::ChannelGroupManifest::Iterator::operator++()
  294. {
  295. ++_i;
  296. return *this;
  297. }
  298. //
  299. // ChannelGroupManifest::ConstIterator implementation: all inline
  300. //
  301. inline IDManifest::ChannelGroupManifest::ConstIterator::ConstIterator() {}
  302. inline IDManifest::ChannelGroupManifest::ConstIterator::ConstIterator(const IDManifest::ChannelGroupManifest::Iterator &other) : _i(other._i) {}
  303. inline IDManifest::ChannelGroupManifest::ConstIterator::ConstIterator(const IDManifest::ChannelGroupManifest::IDTable::const_iterator &i) :_i(i) {}
  304. inline uint64_t
  305. IDManifest::ChannelGroupManifest::ConstIterator::id() const { return _i->first;}
  306. inline const std::vector<std::string>&
  307. IDManifest::ChannelGroupManifest::ConstIterator::text() const { return _i->second;}
  308. inline IDManifest::ChannelGroupManifest::ConstIterator &
  309. IDManifest::ChannelGroupManifest::ConstIterator::operator++()
  310. {
  311. ++_i;
  312. return *this;
  313. }
  314. inline bool
  315. operator==(const IDManifest::ChannelGroupManifest::ConstIterator& a, const IDManifest::ChannelGroupManifest::ConstIterator& b)
  316. {
  317. return a._i ==b._i;
  318. }
  319. inline bool
  320. operator!=(const IDManifest::ChannelGroupManifest::ConstIterator& a, const IDManifest::ChannelGroupManifest::ConstIterator& b)
  321. {
  322. return a._i !=b._i;
  323. }
  324. OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
  325. #endif