1 /* 2 ** SPDX-License-Identifier: BSD-3-Clause 3 ** Copyright Contributors to the OpenEXR Project. 4 */ 5 6 #ifndef OPENEXR_CORE_DECODE_H 7 #define OPENEXR_CORE_DECODE_H 8 9 #include "openexr_chunkio.h" 10 #include "openexr_coding.h" 11 12 #ifdef __cplusplus 13 extern "C" { 14 #endif 15 16 /** @file */ 17 18 /** Can be bit-wise or'ed into the decode_flags in the decode pipeline. 19 * 20 * Indicates that the sample count table should be decoded to a an 21 * individual sample count list (n, m, o, ...), with an extra int at 22 * the end containing the total samples. 23 * 24 * Without this (i.e. a value of 0 in that bit), indicates the sample 25 * count table should be decoded to a cumulative list (n, n+m, n+m+o, 26 * ...), which is the on-disk representation. 27 */ 28 #define EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL ((uint16_t) (1 << 0)) 29 30 /** Can be bit-wise or'ed into the decode_flags in the decode pipeline. 31 * 32 * Indicates that the data in the channel pointers to decode to is not 33 * a direct pointer, but instead is a pointer-to-pointers. In this 34 * mode, the user_pixel_stride and user_line_stride are used to 35 * advance the pointer offsets for each pixel in the output, but the 36 * user_bytes_per_element and user_data_type are used to put 37 * (successive) entries into each destination pointer (if not `NULL`). 38 * 39 * So each channel pointer must then point to an array of 40 * chunk.width * chunk.height pointers. 41 * 42 * With this, you can only extract desired pixels (although all the 43 * pixels must be initially decompressed) to handle such operations 44 * like proxying where you might want to read every other pixel. 45 * 46 * If this is NOT set (0), the default unpacking routine assumes the 47 * data will be planar and contiguous (each channel is a separate 48 * memory block), ignoring user_line_stride and user_pixel_stride. 49 */ 50 #define EXR_DECODE_NON_IMAGE_DATA_AS_POINTERS ((uint16_t) (1 << 1)) 51 52 /** 53 * When reading non-image data (i.e. deep), only read the sample table. 54 */ 55 #define EXR_DECODE_SAMPLE_DATA_ONLY ((uint16_t) (1 << 2)) 56 57 /** 58 * Struct meant to be used on a per-thread basis for reading exr data 59 * 60 * As should be obvious, this structure is NOT thread safe, but rather 61 * meant to be used by separate threads, which can all be accessing 62 * the same context concurrently. 63 */ 64 typedef struct _exr_decode_pipeline 65 { 66 /** The output channel information for this chunk. 67 * 68 * User is expected to fill the channel pointers for the desired 69 * output channels (any that are `NULL` will be skipped) if you are 70 * going to use exr_decoding_choose_default_routines(). If all that is 71 * desired is to read and decompress the data, this can be left 72 * uninitialized. 73 * 74 * Describes the channel information. This information is 75 * allocated dynamically during exr_decoding_initialize(). 76 */ 77 exr_coding_channel_info_t* channels; 78 int16_t channel_count; 79 80 /** Decode flags to control the behavior. */ 81 uint16_t decode_flags; 82 83 /** Copy of the parameters given to the initialize/update for 84 * convenience. 85 */ 86 int part_index; 87 exr_const_context_t context; 88 exr_chunk_info_t chunk; 89 90 /** Can be used by the user to pass custom context data through 91 * the decode pipeline. 92 */ 93 void* decoding_user_data; 94 95 /** The (compressed) buffer. 96 * 97 * If `NULL`, will be allocated during the run of the pipeline. 98 * 99 * If the caller wishes to take control of the buffer, simple 100 * adopt the pointer and set it to `NULL` here. Be cognizant of any 101 * custom allocators. 102 */ 103 void* packed_buffer; 104 105 /** Used when re-using the same decode pipeline struct to know if 106 * chunk is changed size whether current buffer is large enough. 107 */ 108 size_t packed_alloc_size; 109 110 /** The decompressed buffer (unpacked_size from the chunk block 111 * info), but still packed into storage order, only needed for 112 * compressed files. 113 * 114 * If `NULL`, will be allocated during the run of the pipeline when 115 * needed. 116 * 117 * If the caller wishes to take control of the buffer, simple 118 * adopt the pointer and set it to `NULL` here. Be cognizant of any 119 * custom allocators. 120 */ 121 void* unpacked_buffer; 122 123 /** Used when re-using the same decode pipeline struct to know if 124 * chunk is changed size whether current buffer is large enough. 125 */ 126 size_t unpacked_alloc_size; 127 128 /** For deep or other non-image data: packed sample table 129 * (compressed, raw on disk representation). 130 */ 131 void* packed_sample_count_table; 132 size_t packed_sample_count_alloc_size; 133 134 /** Usable, native sample count table. Depending on the flag set 135 * above, will be decoded to either a cumulative list (n, n+m, 136 * n+m+o, ...), or an individual table (n, m, o, ...). As an 137 * optimization, if the latter individual count table is chosen, 138 * an extra int32_t will be allocated at the end of the table to 139 * contain the total count of samples, so the table will be n+1 140 * samples in size. 141 */ 142 int32_t* sample_count_table; 143 size_t sample_count_alloc_size; 144 145 /** A scratch buffer of unpacked_size for intermediate results. 146 * 147 * If `NULL`, will be allocated during the run of the pipeline when 148 * needed. 149 * 150 * If the caller wishes to take control of the buffer, simple 151 * adopt the pointer and set it to `NULL` here. Be cognizant of any 152 * custom allocators. 153 */ 154 void* scratch_buffer_1; 155 156 /** Used when re-using the same decode pipeline struct to know if 157 * chunk is changed size whether current buffer is large enough. 158 */ 159 size_t scratch_alloc_size_1; 160 161 /** Some decompression routines may need a second scratch buffer (zlib). 162 * 163 * If `NULL`, will be allocated during the run of the pipeline when 164 * needed. 165 * 166 * If the caller wishes to take control of the buffer, simple 167 * adopt the pointer and set it to `NULL` here. Be cognizant of any 168 * custom allocators. 169 */ 170 void* scratch_buffer_2; 171 172 /** Used when re-using the same decode pipeline struct to know if 173 * chunk is changed size whether current buffer is large enough. 174 */ 175 size_t scratch_alloc_size_2; 176 177 /** Enable a custom allocator for the different buffers (if 178 * decoding on a GPU). If `NULL`, will use the allocator from the 179 * context. 180 */ 181 void* (*alloc_fn) (exr_transcoding_pipeline_buffer_id_t, size_t); 182 183 /** Enable a custom allocator for the different buffers (if 184 * decoding on a GPU). If `NULL`, will use the allocator from the 185 * context. 186 */ 187 void (*free_fn) (exr_transcoding_pipeline_buffer_id_t, void*); 188 189 /** Function chosen to read chunk data from the context. 190 * 191 * Initialized to a default generic read routine, may be updated 192 * based on channel information when 193 * exr_decoding_choose_default_routines() is called. This is done such that 194 * if the file is uncompressed and the output channel data is 195 * planar and the same type, the read function can read straight 196 * into the output channels, getting closer to a zero-copy 197 * operation. Otherwise a more traditional read, decompress, then 198 * unpack pipeline will be used with a default reader. 199 * 200 * This is allowed to be overridden, but probably is not necessary 201 * in most scenarios. 202 */ 203 exr_result_t (*read_fn) (struct _exr_decode_pipeline* pipeline); 204 205 /** Function chosen based on the compression type of the part to 206 * decompress data. 207 * 208 * If the user has a custom decompression method for the 209 * compression on this part, this can be changed after 210 * initialization. 211 * 212 * If only compressed data is desired, then assign this to `NULL` 213 * after initialization. 214 */ 215 exr_result_t (*decompress_fn) (struct _exr_decode_pipeline* pipeline); 216 217 /** Function which can be provided if you have bespoke handling for 218 * non-image data and need to re-allocate the data to handle the 219 * about-to-be unpacked data. 220 * 221 * If left `NULL`, will assume the memory pointed to by the channel 222 * pointers is sufficient. 223 */ 224 exr_result_t (*realloc_nonimage_data_fn) ( 225 struct _exr_decode_pipeline* pipeline); 226 227 /** Function chosen based on the output layout of the channels of the part to 228 * decompress data. 229 * 230 * This will be `NULL` after initialization, until the user 231 * specifies a custom routine, or initializes the channel data and 232 * calls exr_decoding_choose_default_routines(). 233 * 234 * If only compressed data is desired, then leave or assign this 235 * to `NULL` after initialization. 236 */ 237 exr_result_t (*unpack_and_convert_fn) ( 238 struct _exr_decode_pipeline* pipeline); 239 240 /** Small stash of channel info values. This is faster than calling 241 * malloc when the channel count in the part is small (RGBAZ), 242 * which is super common, however if there are a large number of 243 * channels, it will allocate space for that, so do not rely on 244 * this being used. 245 */ 246 exr_coding_channel_info_t _quick_chan_store[5]; 247 } exr_decode_pipeline_t; 248 249 /** @brief Simple macro to initialize an empty decode pipeline. */ 250 #define EXR_DECODE_PIPELINE_INITIALIZER \ 251 { \ 252 0 \ 253 } 254 255 /** Initialize the decoding pipeline structure with the channel info 256 * for the specified part, and the first block to be read. 257 * 258 * NB: The decode->unpack_and_convert_fn field will be `NULL` after this. If that 259 * stage is desired, initialize the channel output information and 260 * call exr_decoding_choose_default_routines(). 261 */ 262 EXR_EXPORT 263 exr_result_t exr_decoding_initialize ( 264 exr_const_context_t ctxt, 265 int part_index, 266 const exr_chunk_info_t* cinfo, 267 exr_decode_pipeline_t* decode); 268 269 /** Given an initialized decode pipeline, find appropriate functions 270 * to read and shuffle/convert data into the defined channel outputs. 271 * 272 * Calling this is not required if custom routines will be used, or if 273 * just the raw compressed data is desired. Although in that scenario, 274 * it is probably easier to just read the chunk directly using 275 * exr_read_chunk(). 276 */ 277 EXR_EXPORT 278 exr_result_t exr_decoding_choose_default_routines ( 279 exr_const_context_t ctxt, int part_index, exr_decode_pipeline_t* decode); 280 281 /** Given a decode pipeline previously initialized, update it for the 282 * new chunk to be read. 283 * 284 * In this manner, memory buffers can be re-used to avoid continual 285 * malloc/free calls. Further, it allows the previous choices for 286 * the various functions to be quickly re-used. 287 */ 288 EXR_EXPORT 289 exr_result_t exr_decoding_update ( 290 exr_const_context_t ctxt, 291 int part_index, 292 const exr_chunk_info_t* cinfo, 293 exr_decode_pipeline_t* decode); 294 295 /** Execute the decoding pipeline. */ 296 EXR_EXPORT 297 exr_result_t exr_decoding_run ( 298 exr_const_context_t ctxt, int part_index, exr_decode_pipeline_t* decode); 299 300 /** Free any intermediate memory in the decoding pipeline. 301 * 302 * This does *not* free any pointers referred to in the channel info 303 * areas, but rather only the intermediate buffers and memory needed 304 * for the structure itself. 305 */ 306 EXR_EXPORT 307 exr_result_t 308 exr_decoding_destroy (exr_const_context_t ctxt, exr_decode_pipeline_t* decode); 309 310 #ifdef __cplusplus 311 } /* extern "C" */ 312 #endif 313 314 #endif /* OPENEXR_CORE_DECODE_H */ 315