HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
IMG_Metadata.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: IMG_Metadata.h (IMG Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __IMG_Metadata__
12 #define __IMG_Metadata__
13 
14 #include "IMG_API.h"
15 #include <UT/UT_JSONValue.h>
16 #include <initializer_list>
17 
18 class UT_Options;
19 class UT_OptionEntry;
20 
22 {
23  enum class Scope
24  {
25  MD_Read = 0x01,
26  MD_Write = 0x02,
27  MD_RGBA = 0x04, // Only RGBA images (no AOVs)
28 
29  MD_ReadWrite = MD_Read|MD_Write,
30  MD_ReadRGBA = MD_Read|MD_RGBA,
31 
32  MD_Default = MD_Write
33  };
34  /// @{
35  /// Map enum to text string
36  static const char *scope(Scope s);
37  static Scope scope(const char *s);
38  static bool isWriteOnly(Scope s)
39  {
40  return (uint(s) & uint(Scope::MD_Read)) == 0;
41  }
42  static bool isReadOnly(Scope s)
43  {
44  return s == Scope::MD_Read || s == Scope::MD_ReadRGBA;
45  }
46  /// @}
47  enum class Storage
48  {
49  MD_Unknown = -1,
50  MD_Bool,
51  MD_Int8,
52  MD_Int16,
53  MD_Int32,
54  MD_Int64,
55  MD_UInt8,
56  MD_UInt16,
57  MD_UInt32,
58  MD_UInt64,
59  MD_Real16,
60  MD_Real32,
61  MD_Real64,
62  MD_String,
63  };
64  constexpr static bool isInteger(Storage s)
65  {
66  return s == Storage::MD_Bool
67  || s == Storage::MD_Int8
68  || s == Storage::MD_Int16
69  || s == Storage::MD_Int32
70  || s == Storage::MD_Int64
71  || s == Storage::MD_UInt8
72  || s == Storage::MD_UInt16
73  || s == Storage::MD_UInt32
74  || s == Storage::MD_UInt64;
75  }
76  constexpr static bool isFloat(Storage s)
77  {
78  return s == Storage::MD_Real16
79  || s == Storage::MD_Real32
80  || s == Storage::MD_Real64;
81  }
82  constexpr static bool isString(Storage s)
83  {
84  return s == Storage::MD_String;
85  }
86  /// @{
87  /// Map enum to text string
88  static const char *storage(Storage s);
89  static Storage storage(const char *s);
90  /// @}
91 
92  enum class TypeInfo
93  {
94  MD_None,
95  MD_Color,
96  MD_Point,
97  MD_Vector,
98  MD_Normal,
99  MD_Quaternion,
100  MD_Matrix,
101  MD_Box,
102 
103  // Some weird ones
104  MD_Memory, // int representing memory
105  MD_Time, // float representing time (in seconds)
106  MD_Timecode, // two int32 for 4-byte encoding of SMPTE time code
107  MD_Rational, // two int32 for numerator/denominator
108  MD_Keycode, // int[7] for the 28 byte encoding of SMPTE keycode
109  };
110  /// @{
111  /// Map enum to text string
112  static const char *typeInfo(TypeInfo t);
113  static TypeInfo typeInfo(const char *t);
114  /// @}
115 
116  IMG_MetadataItem() = default;
118  Storage store = Storage::MD_Unknown,
119  TypeInfo type = TypeInfo::MD_None)
120  {
121  myValue = value;
122  myStorage = store;
123  myTypeInfo = type;
124  }
126  Storage store = Storage::MD_Unknown,
127  TypeInfo type = TypeInfo::MD_None);
128 
129  /// Encode into a UT_JSONValue as a dict
130  UT_JSONValue encode() const;
131  /// Decode from a UT_JSONValue dictionary
132  bool decode(const UT_JSONValue &dict);
133 
134  /// Set value from an encoded "typed" string (see IMG_Metadata for more info)
135  /// The @c new_key will be the key name stripped of the type information
136  void setFromTypedString(const UT_StringHolder &typed_key,
137  const char *value,
138  UT_StringHolder &new_key);
139 
140  /// Check to see whether a string is a "typed" string.
141  static bool isTypedString(const UT_StringRef &old_key);
142 
143  /// @{
144  /// Set UI elements
145  void setLabel(const UT_StringHolder &label);
146  void setMenu(const UT_StringArray &tokens,
147  const UT_StringArray &labels,
148  bool strict);
149  void setRange(fpreal64 min, bool strict_min,
150  fpreal64 max, bool strict_max);
151  void setScope(Scope scope);
152  /// @}
153 
154  /// @{
155  /// Query UI elements - returns true of the UI element is defined
156  bool getLabel(UT_StringHolder &label) const;
157  bool hasMenu() const;
158  bool getMenu(UT_StringArray &tokens,
159  UT_StringArray &labels,
160  bool &strict) const;
161  bool hasRange() const;
162  bool getRange(fpreal64 &min, bool &strict_min,
163  fpreal64 &max, bool &strict_max) const;
164  Scope getScope() const;
165 
166  int menuSize() const;
167  int menuIndex(const UT_StringRef &token) const;
168  UT_StringHolder menuToken(int index) const;
169  UT_StringHolder menuLabel(int index) const;
170  UT_StringHolder menuLabel(const UT_StringRef &token) const;
171  /// @}
172 
173  /// Convert metadata to a string value. When @c pretty_print is @c true:
174  /// - If there's a menu, the corresponding label will be returned
175  /// - If there's type information, it will be used (i.e. printing a time or
176  /// memory)
177  UT_StringHolder toString(bool pretty_print) const;
178 
179  void clear()
180  {
181  myValue.setNull();
182  myUI.setNull();
183  myStorage = Storage::MD_Unknown;
184  myTypeInfo = TypeInfo::MD_None;
185  }
186 
187  /// Get the JSON value type. This uses the storage type first, but then
188  /// will fall back to the type of myValue.
189  UT_JSONValue::Type jsonType() const;
190 
191  bool intStorage() const { return isInteger(myStorage); }
192  bool floatStorage() const { return isFloat(myStorage); }
193  bool stringStorage() const { return isString(myStorage); }
194 
195  /// Save the value to a JSON writer
196  bool save(UT_JSONWriter &os) const;
197 
198  /// Debug print
199  void dump() const;
200 
201  UT_JSONValue myValue; // Value of the data
202  UT_JSONValue myUI; // Dictionary of UI hints
205 private:
206  void setUI(const UT_StringHolder &key, const UT_JSONValue &value);
207  const UT_JSONValue *getUI(const UT_StringRef &key) const;
208 };
209 
210 static bool
212 {
213  return int(a) & int(b);
214 }
215 
216 /// Map of metadata items
218 {
219 public:
222 
223  /// Clear the table
224  void clear() { myTable.clear(); }
225 
226  /// Merge from other metadata. If @c overwrite is enabled, any data in the
227  /// source will overwrite existing keys.
228  void merge(const IMG_Metadata &src, bool overwrite = true);
229 
230  /// Add named metadata.
231  /// @note this will overwrite existing keys
232  bool add(const UT_StringHolder &key, const IMG_MetadataItem &item);
233 
234  /// Set value from old-style metadata. This mimics the interface before
235  /// H20 (see @c IMG_File::setOption). Normally when calling @c
236  /// IMG_File::setOption, the value would be passed directly as a string.
237  /// For example: @code
238  /// fp->setOption("artist", "Van Gough");
239  /// fp->setOption("compression", "75");
240  /// fp->setOption("worldToCamera", "[1,0,0,0,0,1,0,0,...]");
241  /// @endcode
242  /// But, alternatively, the string could be encoded with type information.
243  /// For example: @code
244  /// fp->setOption("string artist", "Van Gough");
245  /// fp->setOption("int32 compression", "75");
246  /// fp->setOption("matrix4d worldToCamera", "[1,0,0...");
247  /// @endcode
248  /// The possible encoding type information was:
249  /// - bool Bool
250  /// - int8 Int8
251  /// - int16 Int16
252  /// - int32 Int32
253  /// - int64 Int64
254  /// - vec2i Int32[2] (no type info)
255  /// - vec3i Int32[3] (no type info)
256  /// - vec4i Int32[4] (no type info)
257  /// - uint8 UInt8
258  /// - uint16 UInt16
259  /// - uint32 UInt32
260  /// - uint64 UInt64
261  /// - vec2i UInt32[2] (no type info)
262  /// - vec3i UInt32[3] (no type info)
263  /// - vec4i UInt32[4] (no type info)
264  /// - half Real16
265  /// - vec2h Real16[2] (no type info)
266  /// - vec3h Real16[3] (no type info)
267  /// - vec4h Real16[4] (no type info)
268  /// - float Real32
269  /// - vec2f Real32[2] (no type info)
270  /// - vec3f Real32[3] (no type info)
271  /// - vec4f Real32[4] (no type info)
272  /// - mat3f <MATRIX> Real32[9]
273  /// - mat4f <MATRIX> Real32[16]
274  /// - matrix3f <MATRIX> Real32[9]
275  /// - matrix4f <MATRIX> Real32[16]
276  /// - double Real64
277  /// - vec2d Real64[2]
278  /// - vec3d Real64[3]
279  /// - vec4d Real64[4]
280  /// - mat3d <MATRIX> Real64[9]
281  /// - mat4d <MATRIX> Real64[16]
282  /// - matrix3d <MATRIX> Real64[9]
283  /// - matrix4d <MATRIX> Real64[16]
284  /// - string String
285  /// - clr3u8 <Color> UInt8[3]
286  /// - clr4u8 <Color> UInt8[4]
287  /// - clr3f <Color> Real32[3]
288  /// - clr4f <Color> Real32[4]
289  /// - clr3d <Color> Real64[3]
290  /// - clr4d <Color> Real64[4]
291  /// - point3f <Point> Real32[3]
292  /// - point3d <Point> Real64[3]
293  /// - normal3f <Normal> Real32[3]
294  /// - normal3d <Normal> Real64[3]
295  /// - vector3f <Vector> Real32[3]
296  /// - vector3d <Vector> Real64[3]
297  /// - timecode <Timecode> Int32[2]
298  /// - keycode <Keycode> Int32[7]
299  /// - rational <Rational> Int32[2]
300  /// - box2i <Box> Int32[4]
301  /// - box2f <Box> Real32[4]
302  /// - box3i <Box> Int32[6]
303  /// - box3f <Box> Real32[6]
304  /// - memory <Memory> Int64
305  /// - time <Time> Real64
306  /// - seconds <Time> Real64
307  ///
308  /// If there is no type information encoded in the string, the string will
309  /// be added verbatim.
310  bool addTypedString(const UT_StringHolder &name, const char *val);
311 
312  /// Find an item in the map and return it's representation
313  bool find(const UT_StringRef &name,
315  const char *format_prefix = nullptr) const;
316 
317  /// Test if a key exists in the metadata
318  bool contains(const UT_StringRef &key) const
319  { return myTable.contains(key); }
320 
321  /// Old style getOption() call that gets the value as a string
322  bool getOption(const UT_StringRef &name,
324  const char *prefix = nullptr) const;
325 
326  /// Remove metadata
327  void erase(const UT_StringRef &name) { myTable.erase(name); }
328 
329  /// Number of items
330  exint size() const { return myTable.size(); }
331 
332  /// @{
333  /// Iteration interface
335  const_iterator begin() const { return myTable.begin(); }
336  const_iterator end() const { return myTable.end(); }
337  /// @}
338 
339  /// @{
340  /// Import items
341  bool import(const UT_StringRef &name, bool &value,
342  const char *format = nullptr) const;
343  bool import(const UT_StringRef &n, UT_StringHolder &v,
344  const char *format = nullptr) const;
345  bool import(const UT_StringRef &name, int32 &val,
346  const char *format = nullptr) const;
347  bool import(const UT_StringRef &name, int64 &val,
348  const char *format = nullptr) const;
349  bool import(const UT_StringRef &name, fpreal32 &val,
350  const char *format = nullptr) const;
351  bool import(const UT_StringRef &name, fpreal64 &val,
352  const char *format = nullptr) const;
353  bool import(const UT_StringRef &name, UT_Matrix4F &m,
354  const char *format = nullptr) const;
355  bool import(const UT_StringRef &name, UT_Matrix4D &m,
356  const char *format = nullptr) const;
357  /// @}
358 
359  /// Convert metadata to a string value. When @c pretty_print is @c true:
360  /// - If there's a menu, the corresponding label will be returned
361  /// - If there's type information, it will be used (i.e. printing a time or
362  /// memory)
363  bool toString(const UT_StringRef &name,
365  const char *format = nullptr,
366  bool pretty_print = true) const;
367 
368  /// Save the value to a JSON writer
369  bool save(UT_JSONWriter &os) const;
370 
371  /// @{
372  /// Save encoded data to a JSON writer
373  UT_StringHolder saveEncoded() const;
374  bool saveEncoded(UT_JSONWriter &os) const;
375  /// @}
376  /// Load from an encoded JSON object
377  bool loadEncoded(const UT_JSONValue &jvalue);
378 
379  /// Debug print
380  void dump() const;
381 
382  /// Fill a UT_Options the best we can. IMG_Metadata is much more
383  /// expressive and flexible than a UT_Options, but this method does the
384  /// best. The method exists for older interfaces which expect a
385  /// UT_Options.
386  ///
387  /// If a piece of metadata isn't representable in a UT_Options, the string
388  /// representation of the value will be saved.
389  void fill(UT_Options &opts) const;
390 
391 private:
393 };
394 
395 /// A list of well-known metdata that a format understands. The list is ordered.
397 {
398 public:
402 
404  struct IMG_API Item
405  {
406  Item() = default;
408  const IMG_MetadataItem &item)
409  : myName(name)
410  , myItem(item)
411  {
412  }
413  /// Construct with storage/type info, but no UI
414  Item(const UT_StringHolder &name,
415  const UT_StringHolder &label,
416  const UT_JSONValue &value,
418  TypeInfo typeInfo);
419  /// Full constructor with UI elements and type information
420  Item(const UT_StringHolder &name,
421  const UT_StringHolder &label,
422  const UT_JSONValue &value,
423  const MenuCreator &menu = MenuCreator(),
424  fpreal64 range_min = 1,
425  fpreal64 range_max = -1,
426  Scope scope = Scope::MD_Default,
427  Storage storage = Storage::MD_Unknown,
428  TypeInfo typeInfo = TypeInfo::MD_None);
429 
432  };
433  explicit IMG_MetadataOptions() = default;
434  explicit IMG_MetadataOptions(std::initializer_list<Item> init)
435  : myList(init)
436  {
437  }
438 
439  void append(const Item &item) { myList.append(item); }
441  const IMG_MetadataItem &item)
442  {
443  myList.append(Item(name, item));
444  }
445 
446  /// @{
447  /// Lookup item
448  exint size() const { return myList.size(); }
449  int index(const UT_StringRef &name) const;
450  Item &get(int idx) { return myList[idx]; }
451  const Item &get(int idx) const { return myList[idx]; }
452  Item &operator[](int idx) { return myList[idx]; }
453  const Item &operator[](int idx) const { return myList[idx]; }
454  Item &get(const UT_StringRef &name) { return myList[index(name)]; }
455  const Item &get(const UT_StringRef &name) const { return myList[index(name)]; }
456  Item &operator[](const UT_StringRef &name) { return myList[index(name)]; }
457  const Item &operator[](const UT_StringRef &name) const { return myList[index(name)]; }
458  /// @}
459 
460  /// @{
461  /// Find the corresponding menu index for the value of a given parameter
462  int menuIndex(int parm_index,
463  const UT_StringRef &menu_token) const;
464  int menuIndex(const UT_StringRef &parm_name,
465  const UT_StringRef &menu_token) const
466  { return menuIndex(index(parm_name), menu_token); }
467  /// @}
468  /// @{
469  /// Get the token/label from the menu of a given parameter
470  UT_StringHolder menuToken(int parm_index, int menu_index) const;
472  { return menuToken(index(name), idx); }
473  UT_StringHolder menuLabel(int parm_index, int menu_index) const;
475  { return menuLabel(index(name), idx); }
476  /// @}
477 
478  /// @{
479  /// Iteration interface
481  const_iterator begin() const { return myList.begin(); }
482  const_iterator end() const { return myList.end(); }
483  /// @}
484 
485  /// Debug printing
486  void dump() const;
487  bool save(UT_JSONWriter &w) const;
488 
489 private:
490  UT_Array<Item> myList;
491 };
492 
493 #endif
bool isString(const AttributeArray &array)
type
Definition: core.h:556
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
void append(const UT_StringHolder &name, const IMG_MetadataItem &item)
Definition: IMG_Metadata.h:440
int int32
Definition: SYS_Types.h:39
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:2545
static bool isWriteOnly(Scope s)
Definition: IMG_Metadata.h:38
Storage
Definition: oidn.hpp:136
getFileOption("OpenEXR:storage") storage
Definition: HDK_Image.dox:276
const GLdouble * v
Definition: glcorearb.h:837
Item & operator[](int idx)
Definition: IMG_Metadata.h:452
GLsizei const GLfloat * value
Definition: glcorearb.h:824
UT_JSONValue myUI
Definition: IMG_Metadata.h:202
static constexpr bool isString(Storage s)
Definition: IMG_Metadata.h:82
int64 exint
Definition: SYS_Types.h:125
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Class which writes ASCII or binary JSON streams.
Definition: UT_JSONWriter.h:37
void clear()
Clear the table.
Definition: IMG_Metadata.h:224
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
Definition: core.h:2138
TypeInfo myTypeInfo
Definition: IMG_Metadata.h:204
const_iterator begin() const
Definition: IMG_Metadata.h:481
float fpreal32
Definition: SYS_Types.h:200
const_iterator end() const
Definition: IMG_Metadata.h:336
int menuIndex(const UT_StringRef &parm_name, const UT_StringRef &menu_token) const
Definition: IMG_Metadata.h:464
FMT_NOINLINE FMT_CONSTEXPR auto fill(OutputIt it, size_t n, const fill_t< Char > &fill) -> OutputIt
Definition: format.h:1860
static constexpr bool isFloat(Storage s)
Definition: IMG_Metadata.h:76
bool stringStorage() const
Definition: IMG_Metadata.h:193
double fpreal64
Definition: SYS_Types.h:201
#define IMG_API
Definition: IMG_API.h:10
UT_StringMap< IMG_MetadataItem >::const_iterator const_iterator
Definition: IMG_Metadata.h:334
GLdouble n
Definition: glcorearb.h:2008
const_iterator end() const
Definition: IMG_Metadata.h:482
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
const_iterator begin() const
Definition: IMG_Metadata.h:335
void erase(const UT_StringRef &name)
Remove metadata.
Definition: IMG_Metadata.h:327
exint size() const
Number of items.
Definition: IMG_Metadata.h:330
static constexpr bool isInteger(Storage s)
Definition: IMG_Metadata.h:64
bool floatStorage() const
Definition: IMG_Metadata.h:192
bool intStorage() const
Definition: IMG_Metadata.h:191
GLint GLint GLsizei GLint GLenum format
Definition: glcorearb.h:108
long long int64
Definition: SYS_Types.h:116
static bool isReadOnly(Scope s)
Definition: IMG_Metadata.h:42
UT_JSONValue myValue
Definition: IMG_Metadata.h:201
GLuint const GLchar * name
Definition: glcorearb.h:786
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
UT_StringHolder myName
Definition: IMG_Metadata.h:430
Item & operator[](const UT_StringRef &name)
Definition: IMG_Metadata.h:456
GLdouble t
Definition: glad.h:2397
const Item & operator[](int idx) const
Definition: IMG_Metadata.h:453
A list of well-known metdata that a format understands. The list is ordered.
Definition: IMG_Metadata.h:396
bool contains(const UT_StringRef &key) const
Test if a key exists in the metadata.
Definition: IMG_Metadata.h:318
IMG_MetadataItem myItem
Definition: IMG_Metadata.h:431
A map of string to various well defined value types.
Definition: UT_Options.h:84
__hostdev__ bool isInteger(GridType gridType)
Return true if the GridType maps to a POD integer type.
Definition: NanoVDB.h:820
Item(const UT_StringHolder &name, const IMG_MetadataItem &item)
Definition: IMG_Metadata.h:407
exint size() const
Definition: IMG_Metadata.h:448
IMG_MetadataItem(const UT_JSONValue &value, Storage store=Storage::MD_Unknown, TypeInfo type=TypeInfo::MD_None)
Definition: IMG_Metadata.h:117
GLuint index
Definition: glcorearb.h:786
UT_StringHolder menuLabel(const UT_StringRef &name, int idx) const
Definition: IMG_Metadata.h:474
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
Class to store JSON objects as C++ objects.
Definition: UT_JSONValue.h:99
Map of metadata items.
Definition: IMG_Metadata.h:217
void append(const Item &item)
Definition: IMG_Metadata.h:439
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
OutGridT XformOp bool bool MergePolicy merge
ImageBuf OIIO_API add(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
unsigned int uint
Definition: SYS_Types.h:45
const Item & operator[](const UT_StringRef &name) const
Definition: IMG_Metadata.h:457
IMG_MetadataOptions(std::initializer_list< Item > init)
Definition: IMG_Metadata.h:434
GLenum src
Definition: glcorearb.h:1793
UT_StringHolder menuToken(const UT_StringRef &name, int idx) const
Definition: IMG_Metadata.h:471