1 /* 2 ** SPDX-License-Identifier: BSD-3-Clause 3 ** Copyright Contributors to the OpenEXR Project. 4 */ 5 6 #ifndef OPENEXR_ATTR_H 7 #define OPENEXR_ATTR_H 8 9 #include "openexr_context.h" 10 11 #include <stddef.h> 12 #include <stdint.h> 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 /** @file */ 19 20 /** 21 * @defgroup AttributeTypes Attribute/metadata value types and struct declarations 22 * 23 * @brief These are a group of enum values defining valid values for 24 * some attributes and then associated structs for other types. 25 * 26 * Some of these types will be directly representable/storable in 27 * the file, some not. There is some overlap here with Imath, and they 28 * should be kept in the same order for compatibility. However do note 29 * that these are just the raw data, and no useful functions are 30 * declared at this layer, that is what Imath is for. 31 * 32 * @{ 33 */ 34 35 /** Enum declaring allowed values for \c uint8_t value stored in built-in compression type. */ 36 typedef enum 37 { 38 EXR_COMPRESSION_NONE = 0, 39 EXR_COMPRESSION_RLE = 1, 40 EXR_COMPRESSION_ZIPS = 2, 41 EXR_COMPRESSION_ZIP = 3, 42 EXR_COMPRESSION_PIZ = 4, 43 EXR_COMPRESSION_PXR24 = 5, 44 EXR_COMPRESSION_B44 = 6, 45 EXR_COMPRESSION_B44A = 7, 46 EXR_COMPRESSION_DWAA = 8, 47 EXR_COMPRESSION_DWAB = 9, 48 EXR_COMPRESSION_LAST_TYPE /**< Invalid value, provided for range checking. */ 49 } exr_compression_t; 50 51 /** Enum declaring allowed values for \c uint8_t value stored in built-in env map type. */ 52 typedef enum 53 { 54 EXR_ENVMAP_LATLONG = 0, 55 EXR_ENVMAP_CUBE = 1, 56 EXR_ENVMAP_LAST_TYPE /**< Invalid value, provided for range checking. */ 57 } exr_envmap_t; 58 59 /** Enum declaring allowed values for \c uint8_t value stored in \c lineOrder type. */ 60 typedef enum 61 { 62 EXR_LINEORDER_INCREASING_Y = 0, 63 EXR_LINEORDER_DECREASING_Y = 1, 64 EXR_LINEORDER_RANDOM_Y = 2, 65 EXR_LINEORDER_LAST_TYPE /**< Invalid value, provided for range checking. */ 66 } exr_lineorder_t; 67 68 /** Enum declaring allowed values for part type. */ 69 typedef enum 70 { 71 EXR_STORAGE_SCANLINE = 0, /**< Corresponds to type of \c scanlineimage. */ 72 EXR_STORAGE_TILED, /**< Corresponds to type of \c tiledimage. */ 73 EXR_STORAGE_DEEP_SCANLINE, /**< Corresponds to type of \c deepscanline. */ 74 EXR_STORAGE_DEEP_TILED, /**< Corresponds to type of \c deeptile. */ 75 EXR_STORAGE_LAST_TYPE /**< Invalid value, provided for range checking. */ 76 } exr_storage_t; 77 78 /** @brief Enum representing what type of tile information is contained. */ 79 typedef enum 80 { 81 EXR_TILE_ONE_LEVEL = 0, /**< Single level of image data. */ 82 EXR_TILE_MIPMAP_LEVELS = 1, /**< Mipmapped image data. */ 83 EXR_TILE_RIPMAP_LEVELS = 2, /**< Ripmapped image data. */ 84 EXR_TILE_LAST_TYPE /**< Invalid value, provided for range checking. */ 85 } exr_tile_level_mode_t; 86 87 /** @brief Enum representing how to scale positions between levels. */ 88 typedef enum 89 { 90 EXR_TILE_ROUND_DOWN = 0, 91 EXR_TILE_ROUND_UP = 1, 92 EXR_TILE_ROUND_LAST_TYPE 93 } exr_tile_round_mode_t; 94 95 /** @brief Enum capturing the underlying data type on a channel. */ 96 typedef enum 97 { 98 EXR_PIXEL_UINT = 0, 99 EXR_PIXEL_HALF = 1, 100 EXR_PIXEL_FLOAT = 2, 101 EXR_PIXEL_LAST_TYPE 102 } exr_pixel_type_t; 103 104 /* /////////////////////////////////////// */ 105 /* First set of structs are data where we can read directly with no allocation needed... */ 106 107 /* Most are naturally aligned, but force some of these 108 * structs to be tightly packed 109 */ 110 #pragma pack(push, 1) 111 112 /** @brief Struct to hold color chromaticities to interpret the tristimulus color values in the image data. */ 113 typedef struct 114 { 115 float red_x; 116 float red_y; 117 float green_x; 118 float green_y; 119 float blue_x; 120 float blue_y; 121 float white_x; 122 float white_y; 123 } exr_attr_chromaticities_t; 124 125 /** @brief Struct to hold keycode information. */ 126 typedef struct 127 { 128 int32_t film_mfc_code; 129 int32_t film_type; 130 int32_t prefix; 131 int32_t count; 132 int32_t perf_offset; 133 int32_t perfs_per_frame; 134 int32_t perfs_per_count; 135 } exr_attr_keycode_t; 136 137 /** @brief struct to hold a 32-bit floating-point 3x3 matrix. */ 138 typedef struct 139 { 140 float m[9]; 141 } exr_attr_m33f_t; 142 143 /** @brief struct to hold a 64-bit floating-point 3x3 matrix. */ 144 typedef struct 145 { 146 double m[9]; 147 } exr_attr_m33d_t; 148 149 /** @brief Struct to hold a 32-bit floating-point 4x4 matrix. */ 150 typedef struct 151 { 152 float m[16]; 153 } exr_attr_m44f_t; 154 155 /** @brief Struct to hold a 64-bit floating-point 4x4 matrix. */ 156 typedef struct 157 { 158 double m[16]; 159 } exr_attr_m44d_t; 160 161 /** @brief Struct to hold an integer ratio value. */ 162 typedef struct 163 { 164 int32_t num; 165 uint32_t denom; 166 } exr_attr_rational_t; 167 168 /** @brief Struct to hold timecode information. */ 169 typedef struct 170 { 171 uint32_t time_and_flags; 172 uint32_t user_data; 173 } exr_attr_timecode_t; 174 175 /** @brief Struct to hold a 2-element integer vector. */ 176 typedef struct 177 { 178 union 179 { 180 struct 181 { 182 int32_t x, y; 183 }; 184 int32_t arr[2]; 185 }; 186 } exr_attr_v2i_t; 187 188 /** @brief Struct to hold a 2-element 32-bit float vector. */ 189 typedef struct 190 { 191 union 192 { 193 struct 194 { 195 float x, y; 196 }; 197 float arr[2]; 198 }; 199 } exr_attr_v2f_t; 200 201 /** @brief Struct to hold a 2-element 64-bit float vector. */ 202 typedef struct 203 { 204 union 205 { 206 struct 207 { 208 double x, y; 209 }; 210 double arr[2]; 211 }; 212 } exr_attr_v2d_t; 213 214 /** @brief Struct to hold a 3-element integer vector. */ 215 typedef struct 216 { 217 union 218 { 219 struct 220 { 221 int32_t x, y, z; 222 }; 223 int32_t arr[3]; 224 }; 225 } exr_attr_v3i_t; 226 227 /** @brief Struct to hold a 3-element 32-bit float vector. */ 228 typedef struct 229 { 230 union 231 { 232 struct 233 { 234 float x, y, z; 235 }; 236 float arr[3]; 237 }; 238 } exr_attr_v3f_t; 239 240 /** @brief Struct to hold a 3-element 64-bit float vector. */ 241 typedef struct 242 { 243 union 244 { 245 struct 246 { 247 double x, y, z; 248 }; 249 double arr[3]; 250 }; 251 } exr_attr_v3d_t; 252 253 /** @brief Struct to hold an integer box/region definition. */ 254 typedef struct 255 { 256 exr_attr_v2i_t min; 257 exr_attr_v2i_t max; 258 } exr_attr_box2i_t; 259 260 /** @brief Struct to hold a floating-point box/region definition. */ 261 typedef struct 262 { 263 exr_attr_v2f_t min; 264 exr_attr_v2f_t max; 265 } exr_attr_box2f_t; 266 267 /** @brief Struct holding base tiledesc attribute type defined in spec 268 * 269 * NB: This is in a tightly packed area so it can be read directly, be 270 * careful it doesn't become padded to the next \c uint32_t boundary. 271 */ 272 typedef struct 273 { 274 uint32_t x_size; 275 uint32_t y_size; 276 uint8_t level_and_round; 277 } exr_attr_tiledesc_t; 278 279 /** @brief Macro to access type of tiling from packed structure. */ 280 #define EXR_GET_TILE_LEVEL_MODE(tiledesc) \ 281 ((exr_tile_level_mode_t) (((tiledesc).level_and_round) & 0xF)) 282 /** @brief Macro to access the rounding mode of tiling from packed structure. */ 283 #define EXR_GET_TILE_ROUND_MODE(tiledesc) \ 284 ((exr_tile_round_mode_t) ((((tiledesc).level_and_round) >> 4) & 0xF)) 285 /** @brief Macro to pack the tiling type and rounding mode into packed structure. */ 286 #define EXR_PACK_TILE_LEVEL_ROUND(lvl, mode) \ 287 ((uint8_t) ((((uint8_t) ((mode) &0xF) << 4)) | ((uint8_t) ((lvl) &0xF)))) 288 289 #pragma pack(pop) 290 291 /* /////////////////////////////////////// */ 292 /* Now structs that involve heap allocation to store data. */ 293 294 /** Storage for a string. */ 295 typedef struct 296 { 297 int32_t length; 298 /** If this is non-zero, the string owns the data, if 0, is a const ref to a static string. */ 299 int32_t alloc_size; 300 301 const char* str; 302 } exr_attr_string_t; 303 304 /** Storage for a string vector. */ 305 typedef struct 306 { 307 int32_t n_strings; 308 /** If this is non-zero, the string vector owns the data, if 0, is a const ref. */ 309 int32_t alloc_size; 310 311 const exr_attr_string_t* strings; 312 } exr_attr_string_vector_t; 313 314 /** Float vector storage struct. */ 315 typedef struct 316 { 317 int32_t length; 318 /** If this is non-zero, the float vector owns the data, if 0, is a const ref. */ 319 int32_t alloc_size; 320 321 const float* arr; 322 } exr_attr_float_vector_t; 323 324 /** Hint for lossy compression methods about how to treat values 325 * (logarithmic or linear), meaning a human sees values like R, G, B, 326 * luminance difference between 0.1 and 0.2 as about the same as 1.0 327 * to 2.0 (logarithmic), where chroma coordinates are closer to linear 328 * (0.1 and 0.2 is about the same difference as 1.0 and 1.1). 329 */ 330 typedef enum 331 { 332 EXR_PERCEPTUALLY_LOGARITHMIC = 0, 333 EXR_PERCEPTUALLY_LINEAR = 1 334 } exr_perceptual_treatment_t; 335 336 /** Individual channel information. */ 337 typedef struct 338 { 339 exr_attr_string_t name; 340 /** Data representation for these pixels: uint, half, float. */ 341 exr_pixel_type_t pixel_type; 342 /** Possible values are 0 and 1 per docs exr_perceptual_treatment_t. */ 343 uint8_t p_linear; 344 uint8_t reserved[3]; 345 int32_t x_sampling; 346 int32_t y_sampling; 347 } exr_attr_chlist_entry_t; 348 349 /** List of channel information (sorted alphabetically). */ 350 typedef struct 351 { 352 int num_channels; 353 int num_alloced; 354 355 const exr_attr_chlist_entry_t* entries; 356 } exr_attr_chlist_t; 357 358 /** @brief Struct to define attributes of an embedded preview image. */ 359 typedef struct 360 { 361 uint32_t width; 362 uint32_t height; 363 /** If this is non-zero, the preview owns the data, if 0, is a const ref. */ 364 size_t alloc_size; 365 366 const uint8_t* rgba; 367 } exr_attr_preview_t; 368 369 /** Custom storage structure for opaque data. 370 * 371 * Handlers for opaque types can be registered, then when a 372 * non-builtin type is encountered with a registered handler, the 373 * function pointers to unpack/pack it will be set up. 374 * 375 * @sa exr_register_attr_type_handler 376 */ 377 typedef struct 378 { 379 int32_t size; 380 int32_t unpacked_size; 381 /** If this is non-zero, the struct owns the data, if 0, is a const ref. */ 382 int32_t packed_alloc_size; 383 uint8_t pad[4]; 384 385 void* packed_data; 386 387 /** When an application wants to have custom data, they can store 388 * an unpacked form here which will be requested to be destroyed 389 * upon destruction of the attribute. 390 */ 391 void* unpacked_data; 392 393 /** An application can register an attribute handler which then 394 * fills in these function pointers. This allows a user to delay 395 * the expansion of the custom type until access is desired, and 396 * similarly, to delay the packing of the data until write time. 397 */ 398 exr_result_t (*unpack_func_ptr) ( 399 exr_context_t ctxt, 400 const void* data, 401 int32_t attrsize, 402 int32_t* outsize, 403 void** outbuffer); 404 exr_result_t (*pack_func_ptr) ( 405 exr_context_t ctxt, 406 const void* data, 407 int32_t datasize, 408 int32_t* outsize, 409 void* outbuffer); 410 void (*destroy_unpacked_func_ptr) ( 411 exr_context_t ctxt, void* data, int32_t attrsize); 412 } exr_attr_opaquedata_t; 413 414 /* /////////////////////////////////////// */ 415 416 /** @brief Built-in/native attribute type enum. 417 * 418 * This will enable us to do a tagged type struct to generically store 419 * attributes. 420 */ 421 typedef enum 422 { 423 EXR_ATTR_UNKNOWN = 424 0, /**< Type indicating an error or uninitialized attribute. */ 425 EXR_ATTR_BOX2I, /**< Integer region definition. @see exr_attr_box2i_t. */ 426 EXR_ATTR_BOX2F, /**< Float region definition. @see exr_attr_box2f_t. */ 427 EXR_ATTR_CHLIST, /**< Definition of channels in file @see exr_chlist_entry. */ 428 EXR_ATTR_CHROMATICITIES, /**< Values to specify color space of colors in file @see exr_attr_chromaticities_t. */ 429 EXR_ATTR_COMPRESSION, /**< ``uint8_t`` declaring compression present. */ 430 EXR_ATTR_DOUBLE, /**< Double precision floating point number. */ 431 EXR_ATTR_ENVMAP, /**< ``uint8_t`` declaring environment map type. */ 432 EXR_ATTR_FLOAT, /**< Normal (4 byte) precision floating point number. */ 433 EXR_ATTR_FLOAT_VECTOR, /**< List of normal (4 byte) precision floating point numbers. */ 434 EXR_ATTR_INT, /**< 32-bit signed integer value. */ 435 EXR_ATTR_KEYCODE, /**< Struct recording keycode @see exr_attr_keycode_t. */ 436 EXR_ATTR_LINEORDER, /**< ``uint8_t`` declaring scanline ordering. */ 437 EXR_ATTR_M33F, /**< 9 32-bit floats representing a 3x3 matrix. */ 438 EXR_ATTR_M33D, /**< 9 64-bit floats representing a 3x3 matrix. */ 439 EXR_ATTR_M44F, /**< 16 32-bit floats representing a 4x4 matrix. */ 440 EXR_ATTR_M44D, /**< 16 64-bit floats representing a 4x4 matrix. */ 441 EXR_ATTR_PREVIEW, /**< 2 ``unsigned ints`` followed by 4 x w x h ``uint8_t`` image. */ 442 EXR_ATTR_RATIONAL, /**< \c int followed by ``unsigned int`` */ 443 EXR_ATTR_STRING, /**< ``int`` (length) followed by char string data. */ 444 EXR_ATTR_STRING_VECTOR, /**< 0 or more text strings (int + string). number is based on attribute size. */ 445 EXR_ATTR_TILEDESC, /**< 2 ``unsigned ints`` ``xSize``, ``ySize`` followed by mode. */ 446 EXR_ATTR_TIMECODE, /**< 2 ``unsigned ints`` time and flags, user data. */ 447 EXR_ATTR_V2I, /**< Pair of 32-bit integers. */ 448 EXR_ATTR_V2F, /**< Pair of 32-bit floats. */ 449 EXR_ATTR_V2D, /**< Pair of 64-bit floats. */ 450 EXR_ATTR_V3I, /**< Set of 3 32-bit integers. */ 451 EXR_ATTR_V3F, /**< Set of 3 32-bit floats. */ 452 EXR_ATTR_V3D, /**< Set of 3 64-bit floats. */ 453 EXR_ATTR_OPAQUE, /**< User/unknown provided type. */ 454 EXR_ATTR_LAST_KNOWN_TYPE 455 } exr_attribute_type_t; 456 457 /** @brief Storage, name and type information for an attribute. 458 * 459 * Attributes (metadata) for the file cause a surprising amount of 460 * overhead. It is not uncommon for a production-grade EXR to have 461 * many attributes. As such, the attribute struct is designed in a 462 * slightly more complicated manner. It is optimized to have the 463 * storage for that attribute: the struct itself, the name, the type, 464 * and the data all allocated as one block. Further, the type and 465 * standard names may use a static string to avoid allocating space 466 * for those as necessary with the pointers pointing to static strings 467 * (not to be freed). Finally, small values are optimized for. 468 */ 469 typedef struct 470 { 471 /** Name of the attribute. */ 472 const char* name; 473 /** String type name of the attribute. */ 474 const char* type_name; 475 /** Length of name string (short flag is 31 max, long allows 255). */ 476 uint8_t name_length; 477 /** Length of type string (short flag is 31 max, long allows 255). */ 478 uint8_t type_name_length; 479 480 uint8_t pad[2]; 481 482 /** Enum of the attribute type. */ 483 exr_attribute_type_t type; 484 485 /** Union of pointers of different types that can be used to type 486 * pun to an appropriate type for builtins. Do note that while 487 * this looks like a big thing, it is only the size of a single 488 * pointer. These are all pointers into some other data block 489 * storing the value you want, with the exception of the pod types 490 * which are just put in place (i.e. small value optimization). 491 * 492 * The attribute type \c type should directly correlate to one 493 * of these entries. 494 */ 495 union 496 { 497 // NB: not pointers for POD types 498 uint8_t uc; 499 double d; 500 float f; 501 int32_t i; 502 503 exr_attr_box2i_t* box2i; 504 exr_attr_box2f_t* box2f; 505 exr_attr_chlist_t* chlist; 506 exr_attr_chromaticities_t* chromaticities; 507 exr_attr_keycode_t* keycode; 508 exr_attr_float_vector_t* floatvector; 509 exr_attr_m33f_t* m33f; 510 exr_attr_m33d_t* m33d; 511 exr_attr_m44f_t* m44f; 512 exr_attr_m44d_t* m44d; 513 exr_attr_preview_t* preview; 514 exr_attr_rational_t* rational; 515 exr_attr_string_t* string; 516 exr_attr_string_vector_t* stringvector; 517 exr_attr_tiledesc_t* tiledesc; 518 exr_attr_timecode_t* timecode; 519 exr_attr_v2i_t* v2i; 520 exr_attr_v2f_t* v2f; 521 exr_attr_v2d_t* v2d; 522 exr_attr_v3i_t* v3i; 523 exr_attr_v3f_t* v3f; 524 exr_attr_v3d_t* v3d; 525 exr_attr_opaquedata_t* opaque; 526 uint8_t* rawptr; 527 }; 528 } exr_attribute_t; 529 530 /** @} */ 531 532 #ifdef __cplusplus 533 } /* extern "C" */ 534 #endif 535 536 #endif /* OPENEXR_ATTR_H */ 537