507 lines
16 KiB
C
507 lines
16 KiB
C
/*
|
|
** SPDX-License-Identifier: BSD-3-Clause
|
|
** Copyright Contributors to the OpenEXR Project.
|
|
*/
|
|
|
|
#ifndef OPENEXR_ATTR_H
|
|
#define OPENEXR_ATTR_H
|
|
|
|
#include "openexr_context.h"
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/** @file */
|
|
|
|
/**
|
|
* @defgroup AttributeTypes Attribute/metadata value types and struct declarations
|
|
*
|
|
* @brief These are a group of enum values defining valid values for
|
|
* some attributes and then associated structs for other types.
|
|
*
|
|
* Some of these types will be directly representable/storable in
|
|
* the file, some not. There is some overlap here with Imath, and they
|
|
* should be kept in the same order for compatibility. However do note
|
|
* that these are just the raw data, and no useful functions are
|
|
* declared at this layer, that is what Imath is for.
|
|
*
|
|
* @{
|
|
*/
|
|
|
|
/** Enum declaring allowed values for \c uint8_t value stored in built-in compression type. */
|
|
typedef enum
|
|
{
|
|
EXR_COMPRESSION_NONE = 0,
|
|
EXR_COMPRESSION_RLE = 1,
|
|
EXR_COMPRESSION_ZIPS = 2,
|
|
EXR_COMPRESSION_ZIP = 3,
|
|
EXR_COMPRESSION_PIZ = 4,
|
|
EXR_COMPRESSION_PXR24 = 5,
|
|
EXR_COMPRESSION_B44 = 6,
|
|
EXR_COMPRESSION_B44A = 7,
|
|
EXR_COMPRESSION_DWAA = 8,
|
|
EXR_COMPRESSION_DWAB = 9,
|
|
EXR_COMPRESSION_LAST_TYPE /**< Invalid value, provided for range checking. */
|
|
} exr_compression_t;
|
|
|
|
/** Enum declaring allowed values for \c uint8_t value stored in built-in env map type. */
|
|
typedef enum
|
|
{
|
|
EXR_ENVMAP_LATLONG = 0,
|
|
EXR_ENVMAP_CUBE = 1,
|
|
EXR_ENVMAP_LAST_TYPE /**< Invalid value, provided for range checking. */
|
|
} exr_envmap_t;
|
|
|
|
/** Enum declaring allowed values for \c uint8_t value stored in \c lineOrder type. */
|
|
typedef enum
|
|
{
|
|
EXR_LINEORDER_INCREASING_Y = 0,
|
|
EXR_LINEORDER_DECREASING_Y = 1,
|
|
EXR_LINEORDER_RANDOM_Y = 2,
|
|
EXR_LINEORDER_LAST_TYPE /**< Invalid value, provided for range checking. */
|
|
} exr_lineorder_t;
|
|
|
|
/** Enum declaring allowed values for part type. */
|
|
typedef enum
|
|
{
|
|
EXR_STORAGE_SCANLINE = 0, /**< Corresponds to type of \c scanlineimage. */
|
|
EXR_STORAGE_TILED, /**< Corresponds to type of \c tiledimage. */
|
|
EXR_STORAGE_DEEP_SCANLINE, /**< Corresponds to type of \c deepscanline. */
|
|
EXR_STORAGE_DEEP_TILED, /**< Corresponds to type of \c deeptile. */
|
|
EXR_STORAGE_LAST_TYPE, /**< Invalid value, provided for range checking. */
|
|
EXR_STORAGE_UNKNOWN /**< An unknown type, provided for future proofing. */
|
|
} exr_storage_t;
|
|
|
|
/** @brief Enum representing what type of tile information is contained. */
|
|
typedef enum
|
|
{
|
|
EXR_TILE_ONE_LEVEL = 0, /**< Single level of image data. */
|
|
EXR_TILE_MIPMAP_LEVELS = 1, /**< Mipmapped image data. */
|
|
EXR_TILE_RIPMAP_LEVELS = 2, /**< Ripmapped image data. */
|
|
EXR_TILE_LAST_TYPE /**< Invalid value, provided for range checking. */
|
|
} exr_tile_level_mode_t;
|
|
|
|
/** @brief Enum representing how to scale positions between levels. */
|
|
typedef enum
|
|
{
|
|
EXR_TILE_ROUND_DOWN = 0,
|
|
EXR_TILE_ROUND_UP = 1,
|
|
EXR_TILE_ROUND_LAST_TYPE
|
|
} exr_tile_round_mode_t;
|
|
|
|
/** @brief Enum capturing the underlying data type on a channel. */
|
|
typedef enum
|
|
{
|
|
EXR_PIXEL_UINT = 0,
|
|
EXR_PIXEL_HALF = 1,
|
|
EXR_PIXEL_FLOAT = 2,
|
|
EXR_PIXEL_LAST_TYPE
|
|
} exr_pixel_type_t;
|
|
|
|
/** Enum declaring allowed values for \c uint8_t value stored in \c deepImageState type. */
|
|
typedef enum
|
|
{
|
|
EXR_DIS_MESSY = 0,
|
|
EXR_DIS_SORTED = 1,
|
|
EXR_DIS_NON_OVERLAPPING = 2,
|
|
EXR_DIS_TIDY = 3,
|
|
EXR_DIS_LAST_TYPE /**< Invalid value, provided for range checking. */
|
|
} exr_deep_image_state_t;
|
|
|
|
/* /////////////////////////////////////// */
|
|
/* First set of structs are data where we can read directly with no allocation needed... */
|
|
|
|
/* Most are naturally aligned, but force some of these
|
|
* structs to be tightly packed
|
|
*/
|
|
#pragma pack(push, 1)
|
|
|
|
/** @brief Struct to hold color chromaticities to interpret the tristimulus color values in the image data. */
|
|
typedef struct
|
|
{
|
|
float red_x;
|
|
float red_y;
|
|
float green_x;
|
|
float green_y;
|
|
float blue_x;
|
|
float blue_y;
|
|
float white_x;
|
|
float white_y;
|
|
} exr_attr_chromaticities_t;
|
|
|
|
/** @brief Struct to hold keycode information. */
|
|
typedef struct
|
|
{
|
|
int32_t film_mfc_code;
|
|
int32_t film_type;
|
|
int32_t prefix;
|
|
int32_t count;
|
|
int32_t perf_offset;
|
|
int32_t perfs_per_frame;
|
|
int32_t perfs_per_count;
|
|
} exr_attr_keycode_t;
|
|
|
|
/** @brief struct to hold a 32-bit floating-point 3x3 matrix. */
|
|
typedef struct
|
|
{
|
|
float m[9];
|
|
} exr_attr_m33f_t;
|
|
|
|
/** @brief struct to hold a 64-bit floating-point 3x3 matrix. */
|
|
typedef struct
|
|
{
|
|
double m[9];
|
|
} exr_attr_m33d_t;
|
|
|
|
/** @brief Struct to hold a 32-bit floating-point 4x4 matrix. */
|
|
typedef struct
|
|
{
|
|
float m[16];
|
|
} exr_attr_m44f_t;
|
|
|
|
/** @brief Struct to hold a 64-bit floating-point 4x4 matrix. */
|
|
typedef struct
|
|
{
|
|
double m[16];
|
|
} exr_attr_m44d_t;
|
|
|
|
/** @brief Struct to hold an integer ratio value. */
|
|
typedef struct
|
|
{
|
|
int32_t num;
|
|
uint32_t denom;
|
|
} exr_attr_rational_t;
|
|
|
|
/** @brief Struct to hold timecode information. */
|
|
typedef struct
|
|
{
|
|
uint32_t time_and_flags;
|
|
uint32_t user_data;
|
|
} exr_attr_timecode_t;
|
|
|
|
/** @brief Struct to hold a 2-element integer vector. */
|
|
typedef struct
|
|
{
|
|
int32_t x, y;
|
|
} exr_attr_v2i_t;
|
|
|
|
/** @brief Struct to hold a 2-element 32-bit float vector. */
|
|
typedef struct
|
|
{
|
|
float x, y;
|
|
} exr_attr_v2f_t;
|
|
|
|
/** @brief Struct to hold a 2-element 64-bit float vector. */
|
|
typedef struct
|
|
{
|
|
double x, y;
|
|
} exr_attr_v2d_t;
|
|
|
|
/** @brief Struct to hold a 3-element integer vector. */
|
|
typedef struct
|
|
{
|
|
int32_t x, y, z;
|
|
} exr_attr_v3i_t;
|
|
|
|
/** @brief Struct to hold a 3-element 32-bit float vector. */
|
|
typedef struct
|
|
{
|
|
float x, y, z;
|
|
} exr_attr_v3f_t;
|
|
|
|
/** @brief Struct to hold a 3-element 64-bit float vector. */
|
|
typedef struct
|
|
{
|
|
double x, y, z;
|
|
} exr_attr_v3d_t;
|
|
|
|
/** @brief Struct to hold an integer box/region definition. */
|
|
typedef struct
|
|
{
|
|
exr_attr_v2i_t min;
|
|
exr_attr_v2i_t max;
|
|
} exr_attr_box2i_t;
|
|
|
|
/** @brief Struct to hold a floating-point box/region definition. */
|
|
typedef struct
|
|
{
|
|
exr_attr_v2f_t min;
|
|
exr_attr_v2f_t max;
|
|
} exr_attr_box2f_t;
|
|
|
|
/** @brief Struct holding base tiledesc attribute type defined in spec
|
|
*
|
|
* NB: This is in a tightly packed area so it can be read directly, be
|
|
* careful it doesn't become padded to the next \c uint32_t boundary.
|
|
*/
|
|
typedef struct
|
|
{
|
|
uint32_t x_size;
|
|
uint32_t y_size;
|
|
uint8_t level_and_round;
|
|
} exr_attr_tiledesc_t;
|
|
|
|
/** @brief Macro to access type of tiling from packed structure. */
|
|
#define EXR_GET_TILE_LEVEL_MODE(tiledesc) \
|
|
((exr_tile_level_mode_t) (((tiledesc).level_and_round) & 0xF))
|
|
/** @brief Macro to access the rounding mode of tiling from packed structure. */
|
|
#define EXR_GET_TILE_ROUND_MODE(tiledesc) \
|
|
((exr_tile_round_mode_t) ((((tiledesc).level_and_round) >> 4) & 0xF))
|
|
/** @brief Macro to pack the tiling type and rounding mode into packed structure. */
|
|
#define EXR_PACK_TILE_LEVEL_ROUND(lvl, mode) \
|
|
((uint8_t) ((((uint8_t) ((mode) & 0xF) << 4)) | ((uint8_t) ((lvl) & 0xF))))
|
|
|
|
#pragma pack(pop)
|
|
|
|
/* /////////////////////////////////////// */
|
|
/* Now structs that involve heap allocation to store data. */
|
|
|
|
/** Storage for a string. */
|
|
typedef struct
|
|
{
|
|
int32_t length;
|
|
/** If this is non-zero, the string owns the data, if 0, is a const ref to a static string. */
|
|
int32_t alloc_size;
|
|
|
|
const char* str;
|
|
} exr_attr_string_t;
|
|
|
|
/** Storage for a string vector. */
|
|
typedef struct
|
|
{
|
|
int32_t n_strings;
|
|
/** If this is non-zero, the string vector owns the data, if 0, is a const ref. */
|
|
int32_t alloc_size;
|
|
|
|
const exr_attr_string_t* strings;
|
|
} exr_attr_string_vector_t;
|
|
|
|
/** Float vector storage struct. */
|
|
typedef struct
|
|
{
|
|
int32_t length;
|
|
/** If this is non-zero, the float vector owns the data, if 0, is a const ref. */
|
|
int32_t alloc_size;
|
|
|
|
const float* arr;
|
|
} exr_attr_float_vector_t;
|
|
|
|
/** Hint for lossy compression methods about how to treat values
|
|
* (logarithmic or linear), meaning a human sees values like R, G, B,
|
|
* luminance difference between 0.1 and 0.2 as about the same as 1.0
|
|
* to 2.0 (logarithmic), where chroma coordinates are closer to linear
|
|
* (0.1 and 0.2 is about the same difference as 1.0 and 1.1).
|
|
*/
|
|
typedef enum
|
|
{
|
|
EXR_PERCEPTUALLY_LOGARITHMIC = 0,
|
|
EXR_PERCEPTUALLY_LINEAR = 1
|
|
} exr_perceptual_treatment_t;
|
|
|
|
/** Individual channel information. */
|
|
typedef struct
|
|
{
|
|
exr_attr_string_t name;
|
|
/** Data representation for these pixels: uint, half, float. */
|
|
exr_pixel_type_t pixel_type;
|
|
/** Possible values are 0 and 1 per docs exr_perceptual_treatment_t. */
|
|
uint8_t p_linear;
|
|
uint8_t reserved[3];
|
|
int32_t x_sampling;
|
|
int32_t y_sampling;
|
|
} exr_attr_chlist_entry_t;
|
|
|
|
/** List of channel information (sorted alphabetically). */
|
|
typedef struct
|
|
{
|
|
int num_channels;
|
|
int num_alloced;
|
|
|
|
const exr_attr_chlist_entry_t* entries;
|
|
} exr_attr_chlist_t;
|
|
|
|
/** @brief Struct to define attributes of an embedded preview image. */
|
|
typedef struct
|
|
{
|
|
uint32_t width;
|
|
uint32_t height;
|
|
/** If this is non-zero, the preview owns the data, if 0, is a const ref. */
|
|
size_t alloc_size;
|
|
|
|
const uint8_t* rgba;
|
|
} exr_attr_preview_t;
|
|
|
|
/** Custom storage structure for opaque data.
|
|
*
|
|
* Handlers for opaque types can be registered, then when a
|
|
* non-builtin type is encountered with a registered handler, the
|
|
* function pointers to unpack/pack it will be set up.
|
|
*
|
|
* @sa exr_register_attr_type_handler
|
|
*/
|
|
typedef struct
|
|
{
|
|
int32_t size;
|
|
int32_t unpacked_size;
|
|
/** If this is non-zero, the struct owns the data, if 0, is a const ref. */
|
|
int32_t packed_alloc_size;
|
|
uint8_t pad[4];
|
|
|
|
void* packed_data;
|
|
|
|
/** When an application wants to have custom data, they can store
|
|
* an unpacked form here which will be requested to be destroyed
|
|
* upon destruction of the attribute.
|
|
*/
|
|
void* unpacked_data;
|
|
|
|
/** An application can register an attribute handler which then
|
|
* fills in these function pointers. This allows a user to delay
|
|
* the expansion of the custom type until access is desired, and
|
|
* similarly, to delay the packing of the data until write time.
|
|
*/
|
|
exr_result_t (*unpack_func_ptr) (
|
|
exr_context_t ctxt,
|
|
const void* data,
|
|
int32_t attrsize,
|
|
int32_t* outsize,
|
|
void** outbuffer);
|
|
exr_result_t (*pack_func_ptr) (
|
|
exr_context_t ctxt,
|
|
const void* data,
|
|
int32_t datasize,
|
|
int32_t* outsize,
|
|
void* outbuffer);
|
|
void (*destroy_unpacked_func_ptr) (
|
|
exr_context_t ctxt, void* data, int32_t attrsize);
|
|
} exr_attr_opaquedata_t;
|
|
|
|
/* /////////////////////////////////////// */
|
|
|
|
/** @brief Built-in/native attribute type enum.
|
|
*
|
|
* This will enable us to do a tagged type struct to generically store
|
|
* attributes.
|
|
*/
|
|
typedef enum
|
|
{
|
|
EXR_ATTR_UNKNOWN =
|
|
0, /**< Type indicating an error or uninitialized attribute. */
|
|
EXR_ATTR_BOX2I, /**< Integer region definition. @see exr_attr_box2i_t. */
|
|
EXR_ATTR_BOX2F, /**< Float region definition. @see exr_attr_box2f_t. */
|
|
EXR_ATTR_CHLIST, /**< Definition of channels in file @see exr_chlist_entry. */
|
|
EXR_ATTR_CHROMATICITIES, /**< Values to specify color space of colors in file @see exr_attr_chromaticities_t. */
|
|
EXR_ATTR_COMPRESSION, /**< ``uint8_t`` declaring compression present. */
|
|
EXR_ATTR_DOUBLE, /**< Double precision floating point number. */
|
|
EXR_ATTR_ENVMAP, /**< ``uint8_t`` declaring environment map type. */
|
|
EXR_ATTR_FLOAT, /**< Normal (4 byte) precision floating point number. */
|
|
EXR_ATTR_FLOAT_VECTOR, /**< List of normal (4 byte) precision floating point numbers. */
|
|
EXR_ATTR_INT, /**< 32-bit signed integer value. */
|
|
EXR_ATTR_KEYCODE, /**< Struct recording keycode @see exr_attr_keycode_t. */
|
|
EXR_ATTR_LINEORDER, /**< ``uint8_t`` declaring scanline ordering. */
|
|
EXR_ATTR_M33F, /**< 9 32-bit floats representing a 3x3 matrix. */
|
|
EXR_ATTR_M33D, /**< 9 64-bit floats representing a 3x3 matrix. */
|
|
EXR_ATTR_M44F, /**< 16 32-bit floats representing a 4x4 matrix. */
|
|
EXR_ATTR_M44D, /**< 16 64-bit floats representing a 4x4 matrix. */
|
|
EXR_ATTR_PREVIEW, /**< 2 ``unsigned ints`` followed by 4 x w x h ``uint8_t`` image. */
|
|
EXR_ATTR_RATIONAL, /**< \c int followed by ``unsigned int`` */
|
|
EXR_ATTR_STRING, /**< ``int`` (length) followed by char string data. */
|
|
EXR_ATTR_STRING_VECTOR, /**< 0 or more text strings (int + string). number is based on attribute size. */
|
|
EXR_ATTR_TILEDESC, /**< 2 ``unsigned ints`` ``xSize``, ``ySize`` followed by mode. */
|
|
EXR_ATTR_TIMECODE, /**< 2 ``unsigned ints`` time and flags, user data. */
|
|
EXR_ATTR_V2I, /**< Pair of 32-bit integers. */
|
|
EXR_ATTR_V2F, /**< Pair of 32-bit floats. */
|
|
EXR_ATTR_V2D, /**< Pair of 64-bit floats. */
|
|
EXR_ATTR_V3I, /**< Set of 3 32-bit integers. */
|
|
EXR_ATTR_V3F, /**< Set of 3 32-bit floats. */
|
|
EXR_ATTR_V3D, /**< Set of 3 64-bit floats. */
|
|
EXR_ATTR_DEEP_IMAGE_STATE, /**< ``uint8_t`` declaring deep image state. */
|
|
EXR_ATTR_OPAQUE, /**< User/unknown provided type. */
|
|
EXR_ATTR_LAST_KNOWN_TYPE
|
|
} exr_attribute_type_t;
|
|
|
|
/** @brief Storage, name and type information for an attribute.
|
|
*
|
|
* Attributes (metadata) for the file cause a surprising amount of
|
|
* overhead. It is not uncommon for a production-grade EXR to have
|
|
* many attributes. As such, the attribute struct is designed in a
|
|
* slightly more complicated manner. It is optimized to have the
|
|
* storage for that attribute: the struct itself, the name, the type,
|
|
* and the data all allocated as one block. Further, the type and
|
|
* standard names may use a static string to avoid allocating space
|
|
* for those as necessary with the pointers pointing to static strings
|
|
* (not to be freed). Finally, small values are optimized for.
|
|
*/
|
|
typedef struct
|
|
{
|
|
/** Name of the attribute. */
|
|
const char* name;
|
|
/** String type name of the attribute. */
|
|
const char* type_name;
|
|
/** Length of name string (short flag is 31 max, long allows 255). */
|
|
uint8_t name_length;
|
|
/** Length of type string (short flag is 31 max, long allows 255). */
|
|
uint8_t type_name_length;
|
|
|
|
uint8_t pad[2];
|
|
|
|
/** Enum of the attribute type. */
|
|
exr_attribute_type_t type;
|
|
|
|
/** Union of pointers of different types that can be used to type
|
|
* pun to an appropriate type for builtins. Do note that while
|
|
* this looks like a big thing, it is only the size of a single
|
|
* pointer. These are all pointers into some other data block
|
|
* storing the value you want, with the exception of the pod types
|
|
* which are just put in place (i.e. small value optimization).
|
|
*
|
|
* The attribute type \c type should directly correlate to one
|
|
* of these entries.
|
|
*/
|
|
union
|
|
{
|
|
// NB: not pointers for POD types
|
|
uint8_t uc;
|
|
double d;
|
|
float f;
|
|
int32_t i;
|
|
|
|
exr_attr_box2i_t* box2i;
|
|
exr_attr_box2f_t* box2f;
|
|
exr_attr_chlist_t* chlist;
|
|
exr_attr_chromaticities_t* chromaticities;
|
|
exr_attr_keycode_t* keycode;
|
|
exr_attr_float_vector_t* floatvector;
|
|
exr_attr_m33f_t* m33f;
|
|
exr_attr_m33d_t* m33d;
|
|
exr_attr_m44f_t* m44f;
|
|
exr_attr_m44d_t* m44d;
|
|
exr_attr_preview_t* preview;
|
|
exr_attr_rational_t* rational;
|
|
exr_attr_string_t* string;
|
|
exr_attr_string_vector_t* stringvector;
|
|
exr_attr_tiledesc_t* tiledesc;
|
|
exr_attr_timecode_t* timecode;
|
|
exr_attr_v2i_t* v2i;
|
|
exr_attr_v2f_t* v2f;
|
|
exr_attr_v2d_t* v2d;
|
|
exr_attr_v3i_t* v3i;
|
|
exr_attr_v3f_t* v3f;
|
|
exr_attr_v3d_t* v3d;
|
|
exr_attr_opaquedata_t* opaque;
|
|
uint8_t* rawptr;
|
|
};
|
|
} exr_attribute_t;
|
|
|
|
/** @} */
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
#endif
|
|
|
|
#endif /* OPENEXR_ATTR_H */
|