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