1 /*
2 ** SPDX-License-Identifier: BSD-3-Clause
3 ** Copyright Contributors to the OpenEXR Project.
4 */
5 
6 #include "openexr_decode.h"
7 
8 #include "internal_coding.h"
9 #include "internal_decompress.h"
10 #include "internal_structs.h"
11 #include "internal_xdr.h"
12 
13 #include <stdio.h>
14 #include <string.h>
15 
16 /**************************************/
17 
18 static exr_result_t
update_pack_unpack_ptrs(exr_decode_pipeline_t * decode)19 update_pack_unpack_ptrs (exr_decode_pipeline_t* decode)
20 {
21     exr_result_t  rv;
22     exr_storage_t stortype = ((exr_storage_t) decode->chunk.type);
23 
24     if (stortype == EXR_STORAGE_DEEP_SCANLINE ||
25         stortype == EXR_STORAGE_DEEP_TILED)
26     {
27         size_t sampsize =
28             (((size_t) decode->chunk.width) * ((size_t) decode->chunk.height));
29 
30         if ((decode->decode_flags & EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL))
31             sampsize += 1;
32         sampsize *= sizeof (int32_t);
33 
34         if (decode->chunk.sample_count_table_size == sampsize)
35         {
36             internal_decode_free_buffer (
37                 decode,
38                 EXR_TRANSCODE_BUFFER_SAMPLES,
39                 (void**) &(decode->sample_count_table),
40                 &(decode->sample_count_alloc_size));
41 
42             decode->sample_count_table = decode->packed_sample_count_table;
43             rv                         = EXR_ERR_SUCCESS;
44         }
45         else
46         {
47             rv = internal_decode_alloc_buffer (
48                 decode,
49                 EXR_TRANSCODE_BUFFER_SAMPLES,
50                 (void**) &(decode->sample_count_table),
51                 &(decode->sample_count_alloc_size),
52                 sampsize);
53         }
54 
55         if (rv != EXR_ERR_SUCCESS ||
56             (decode->decode_flags & EXR_DECODE_SAMPLE_DATA_ONLY) != 0)
57             return rv;
58     }
59 
60     if (decode->chunk.packed_size == decode->chunk.unpacked_size)
61     {
62         internal_decode_free_buffer (
63             decode,
64             EXR_TRANSCODE_BUFFER_UNPACKED,
65             &(decode->unpacked_buffer),
66             &(decode->unpacked_alloc_size));
67 
68         decode->unpacked_buffer = decode->packed_buffer;
69         rv                      = EXR_ERR_SUCCESS;
70     }
71     else
72     {
73         rv = internal_decode_alloc_buffer (
74             decode,
75             EXR_TRANSCODE_BUFFER_UNPACKED,
76             &(decode->unpacked_buffer),
77             &(decode->unpacked_alloc_size),
78             decode->chunk.unpacked_size);
79     }
80 
81     return rv;
82 }
83 
84 static exr_result_t
read_uncompressed_direct(exr_decode_pipeline_t * decode)85 read_uncompressed_direct (exr_decode_pipeline_t* decode)
86 {
87     exr_result_t rv;
88     int          height, start_y;
89     uint64_t     dataoffset, toread;
90     uint8_t*     cdata;
91     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (
92         decode->context, decode->part_index);
93 
94     dataoffset = decode->chunk.data_offset;
95 
96     height  = decode->chunk.height;
97     start_y = decode->chunk.start_y;
98     for (int y = 0; y < height; ++y)
99     {
100         for (int c = 0; c < decode->channel_count; ++c)
101         {
102             exr_coding_channel_info_t* decc = (decode->channels + c);
103 
104             cdata = decc->decode_to_ptr;
105             toread =
106                 (uint64_t) decc->width * (uint64_t) decc->bytes_per_element;
107 
108             if (decc->height == 0) continue;
109 
110             if (decc->y_samples > 1)
111             {
112                 if (((start_y + y) % decc->y_samples) != 0) continue;
113                 cdata +=
114                     ((uint64_t) (y / decc->y_samples) *
115                      (uint64_t) decc->user_line_stride);
116             }
117             else
118             {
119                 cdata += (uint64_t) y * (uint64_t) decc->user_line_stride;
120             }
121 
122             /* actual read into the output pointer */
123             rv = pctxt->do_read (
124                 pctxt, cdata, toread, &dataoffset, NULL, EXR_MUST_READ_ALL);
125             if (rv != EXR_ERR_SUCCESS) return rv;
126 
127             // need to swab them to native
128             if (decc->bytes_per_element == 2)
129                 priv_to_native16 (cdata, decc->width);
130             else
131                 priv_to_native32 (cdata, decc->width);
132         }
133     }
134 
135     return EXR_ERR_SUCCESS;
136 }
137 
138 static exr_result_t
default_read_chunk(exr_decode_pipeline_t * decode)139 default_read_chunk (exr_decode_pipeline_t* decode)
140 {
141     exr_result_t rv;
142     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (
143         decode->context, decode->part_index);
144 
145     if (decode->unpacked_buffer == decode->packed_buffer &&
146         decode->unpacked_alloc_size == 0)
147         decode->unpacked_buffer = NULL;
148 
149     if (part->storage_mode == EXR_STORAGE_DEEP_SCANLINE ||
150         part->storage_mode == EXR_STORAGE_DEEP_TILED)
151     {
152         rv = internal_decode_alloc_buffer (
153             decode,
154             EXR_TRANSCODE_BUFFER_PACKED_SAMPLES,
155             &(decode->packed_sample_count_table),
156             &(decode->packed_sample_count_alloc_size),
157             decode->chunk.sample_count_table_size);
158         if (rv != EXR_ERR_SUCCESS) return rv;
159 
160         if ((decode->decode_flags & EXR_DECODE_SAMPLE_DATA_ONLY))
161         {
162             rv = exr_read_deep_chunk (
163                 decode->context,
164                 decode->part_index,
165                 &(decode->chunk),
166                 NULL,
167                 decode->packed_sample_count_table);
168         }
169         else
170         {
171             rv = internal_decode_alloc_buffer (
172                 decode,
173                 EXR_TRANSCODE_BUFFER_PACKED,
174                 &(decode->packed_buffer),
175                 &(decode->packed_alloc_size),
176                 decode->chunk.packed_size);
177             if (rv != EXR_ERR_SUCCESS) return rv;
178 
179             rv = exr_read_deep_chunk (
180                 decode->context,
181                 decode->part_index,
182                 &(decode->chunk),
183                 decode->packed_buffer,
184                 decode->packed_sample_count_table);
185         }
186     }
187     else
188     {
189         rv = internal_decode_alloc_buffer (
190             decode,
191             EXR_TRANSCODE_BUFFER_PACKED,
192             &(decode->packed_buffer),
193             &(decode->packed_alloc_size),
194             decode->chunk.packed_size);
195         if (rv != EXR_ERR_SUCCESS) return rv;
196         rv = exr_read_chunk (
197             decode->context,
198             decode->part_index,
199             &(decode->chunk),
200             decode->packed_buffer);
201     }
202 
203     return rv;
204 }
205 
206 static exr_result_t
decompress_data(const struct _internal_exr_context * pctxt,const exr_compression_t ctype,exr_decode_pipeline_t * decode,void * packbufptr,size_t packsz,void * unpackbufptr,size_t unpacksz)207 decompress_data (
208     const struct _internal_exr_context* pctxt,
209     const exr_compression_t             ctype,
210     exr_decode_pipeline_t*              decode,
211     void*                               packbufptr,
212     size_t                              packsz,
213     void*                               unpackbufptr,
214     size_t                              unpacksz)
215 {
216     exr_result_t rv;
217 
218     if (packsz == 0) return EXR_ERR_SUCCESS;
219 
220     if (packsz == unpacksz && ctype != EXR_COMPRESSION_B44 &&
221         ctype != EXR_COMPRESSION_B44A)
222     {
223         if (unpackbufptr != packbufptr)
224             memcpy (unpackbufptr, packbufptr, unpacksz);
225         return EXR_ERR_SUCCESS;
226     }
227 
228     switch (ctype)
229     {
230         case EXR_COMPRESSION_NONE:
231             return pctxt->report_error (
232                 pctxt,
233                 EXR_ERR_INVALID_ARGUMENT,
234                 "no compresssion set but still trying to decompress");
235 
236         case EXR_COMPRESSION_RLE:
237             rv = internal_exr_undo_rle (
238                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
239             break;
240         case EXR_COMPRESSION_ZIP:
241         case EXR_COMPRESSION_ZIPS:
242             rv = internal_exr_undo_zip (
243                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
244             break;
245         case EXR_COMPRESSION_PIZ:
246             rv = internal_exr_undo_piz (
247                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
248             break;
249         case EXR_COMPRESSION_PXR24:
250             rv = internal_exr_undo_pxr24 (
251                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
252             break;
253         case EXR_COMPRESSION_B44:
254             rv = internal_exr_undo_b44 (
255                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
256             break;
257         case EXR_COMPRESSION_B44A:
258             rv = internal_exr_undo_b44a (
259                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
260             break;
261         case EXR_COMPRESSION_DWAA:
262             rv = internal_exr_undo_dwaa (
263                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
264             break;
265         case EXR_COMPRESSION_DWAB:
266             rv = internal_exr_undo_dwab (
267                 decode, packbufptr, packsz, unpackbufptr, unpacksz);
268             break;
269         case EXR_COMPRESSION_LAST_TYPE:
270         default:
271             return pctxt->print_error (
272                 pctxt,
273                 EXR_ERR_INVALID_ARGUMENT,
274                 "Compression technique 0x%02X invalid",
275                 ctype);
276     }
277 
278     return rv;
279 }
280 
281 static exr_result_t
default_decompress_chunk(exr_decode_pipeline_t * decode)282 default_decompress_chunk (exr_decode_pipeline_t* decode)
283 {
284     exr_result_t rv = EXR_ERR_SUCCESS;
285     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (
286         decode->context, decode->part_index);
287 
288     if (part->storage_mode == EXR_STORAGE_DEEP_SCANLINE ||
289         part->storage_mode == EXR_STORAGE_DEEP_TILED)
290     {
291         uint64_t sampsize =
292             (((uint64_t) decode->chunk.width) * ((uint64_t) decode->chunk.height));
293         sampsize *= sizeof (int32_t);
294 
295         rv = decompress_data (
296             pctxt,
297             part->comp_type,
298             decode,
299             decode->packed_sample_count_table,
300             decode->chunk.sample_count_table_size,
301             decode->sample_count_table,
302             sampsize);
303 
304         if (rv != EXR_ERR_SUCCESS)
305         {
306             return pctxt->print_error (
307                 pctxt,
308                 rv,
309                 "Unable to decompress sample table %" PRIu64 " -> %" PRIu64,
310                 decode->chunk.sample_count_table_size,
311                 (uint64_t)sampsize);
312         }
313         if ((decode->decode_flags & EXR_DECODE_SAMPLE_DATA_ONLY)) return rv;
314     }
315 
316     if (rv == EXR_ERR_SUCCESS)
317         rv = decompress_data (
318             pctxt,
319             part->comp_type,
320             decode,
321             decode->packed_buffer,
322             decode->chunk.packed_size,
323             decode->unpacked_buffer,
324             decode->chunk.unpacked_size);
325 
326     if (rv != EXR_ERR_SUCCESS)
327     {
328         return pctxt->print_error (
329             pctxt,
330             rv,
331             "Unable to decompress image data %" PRIu64 " -> %" PRIu64,
332             decode->chunk.packed_size,
333             decode->chunk.unpacked_size);
334     }
335     return rv;
336 }
337 
338 static exr_result_t
unpack_sample_table(const struct _internal_exr_context * pctxt,exr_decode_pipeline_t * decode)339 unpack_sample_table (
340     const struct _internal_exr_context* pctxt, exr_decode_pipeline_t* decode)
341 {
342     exr_result_t rv           = EXR_ERR_SUCCESS;
343     int32_t      w            = decode->chunk.width;
344     int32_t      h            = decode->chunk.height;
345     int32_t      totsamp      = 0;
346     int32_t*     samptable    = decode->sample_count_table;
347     size_t       combSampSize = 0;
348 
349     for (int c = 0; c < decode->channel_count; ++c)
350         combSampSize += ((size_t) decode->channels[c].bytes_per_element);
351 
352     if ((decode->decode_flags & EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL))
353     {
354         for (int32_t y = 0; y < h; ++y)
355         {
356             int32_t prevsamp = 0;
357             for (int32_t x = 0; x < w; ++x)
358             {
359                 int32_t nsamps =
360                     (int32_t) one_to_native32 ((uint32_t) samptable[y * w + x]);
361                 if (nsamps < 0) return EXR_ERR_INVALID_SAMPLE_DATA;
362                 samptable[y * w + x] = nsamps - prevsamp;
363                 prevsamp             = nsamps;
364             }
365             totsamp += prevsamp;
366         }
367         samptable[w * h] = totsamp;
368     }
369     else
370     {
371         for (int32_t y = 0; y < h; ++y)
372         {
373             int32_t prevsamp = 0;
374             for (int32_t x = 0; x < w; ++x)
375             {
376                 int32_t nsamps =
377                     (int32_t) one_to_native32 ((uint32_t) samptable[y * w + x]);
378                 if (nsamps < 0) return EXR_ERR_INVALID_SAMPLE_DATA;
379                 samptable[y * w + x] = nsamps;
380                 prevsamp             = nsamps;
381             }
382             totsamp += prevsamp;
383         }
384     }
385 
386     if (totsamp < 0 ||
387         (((uint64_t) totsamp) * combSampSize) > decode->chunk.unpacked_size)
388     {
389         rv = pctxt->report_error (
390             pctxt, EXR_ERR_INVALID_SAMPLE_DATA, "Corrupt sample count table");
391     }
392     return rv;
393 }
394 
395 /**************************************/
396 
397 exr_result_t
exr_decoding_initialize(exr_const_context_t ctxt,int part_index,const exr_chunk_info_t * cinfo,exr_decode_pipeline_t * decode)398 exr_decoding_initialize (
399     exr_const_context_t     ctxt,
400     int                     part_index,
401     const exr_chunk_info_t* cinfo,
402     exr_decode_pipeline_t*  decode)
403 {
404     exr_result_t          rv;
405     exr_decode_pipeline_t nil = { 0 };
406 
407     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index);
408     if (!cinfo || !decode)
409         return pctxt->standard_error (pctxt, EXR_ERR_INVALID_ARGUMENT);
410 
411     *decode = nil;
412 
413     rv = internal_coding_fill_channel_info (
414         &(decode->channels),
415         &(decode->channel_count),
416         decode->_quick_chan_store,
417         cinfo,
418         pctxt,
419         part);
420 
421     if (rv == EXR_ERR_SUCCESS)
422     {
423         decode->part_index = part_index;
424         decode->context    = ctxt;
425         decode->chunk      = *cinfo;
426     }
427     return rv;
428 }
429 
430 exr_result_t
exr_decoding_choose_default_routines(exr_const_context_t ctxt,int part_index,exr_decode_pipeline_t * decode)431 exr_decoding_choose_default_routines (
432     exr_const_context_t ctxt, int part_index, exr_decode_pipeline_t* decode)
433 {
434     int32_t isdeep = 0, chanstofill = 0, chanstounpack = 0, sametype = -2,
435             sameouttype = -2, samebpc = 0, sameoutbpc = 0, hassampling = 0,
436             hastypechange = 0, simpinterleave = 0, simpinterleaverev = 0,
437             simplineoff = 0, sameoutinc = 0;
438     uint8_t* interleaveptr = NULL;
439     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index);
440     if (!decode) return pctxt->standard_error (pctxt, EXR_ERR_INVALID_ARGUMENT);
441 
442     if (decode->context != ctxt || decode->part_index != part_index)
443         return pctxt->print_error (
444             pctxt,
445             EXR_ERR_INVALID_ARGUMENT,
446             "Cross-wired request for default routines from different context / part");
447 
448     isdeep = (part->storage_mode == EXR_STORAGE_DEEP_SCANLINE ||
449               part->storage_mode == EXR_STORAGE_DEEP_TILED)
450                  ? 1
451                  : 0;
452 
453     for (int c = 0; c < decode->channel_count; ++c)
454     {
455         exr_coding_channel_info_t* decc = (decode->channels + c);
456 
457         if (decc->height == 0 || !decc->decode_to_ptr) continue;
458 
459         /*
460          * if a user specifies a bad pixel stride / line stride
461          * we can't know this realistically, and they may want to
462          * use 0 to cause things to collapse for testing purposes
463          * so only test the values we know we use for decisions
464          */
465         if (decc->user_bytes_per_element != 2 &&
466             decc->user_bytes_per_element != 4)
467             return pctxt->print_error (
468                 pctxt,
469                 EXR_ERR_INVALID_ARGUMENT,
470                 "Invalid / unsupported output bytes per element (%d) for channel %c (%s)",
471                 (int) decc->user_bytes_per_element,
472                 c,
473                 decc->channel_name);
474 
475         if (decc->user_data_type != (uint16_t) (EXR_PIXEL_HALF) &&
476             decc->user_data_type != (uint16_t) (EXR_PIXEL_FLOAT) &&
477             decc->user_data_type != (uint16_t) (EXR_PIXEL_UINT))
478             return pctxt->print_error (
479                 pctxt,
480                 EXR_ERR_INVALID_ARGUMENT,
481                 "Invalid / unsupported output data type (%d) for channel %c (%s)",
482                 (int) decc->user_data_type,
483                 c,
484                 decc->channel_name);
485 
486         if (sametype == -2)
487             sametype = (int32_t) decc->data_type;
488         else if (sametype != (int32_t) decc->data_type)
489             sametype = -1;
490 
491         if (sameouttype == -2)
492             sameouttype = (int32_t) decc->user_data_type;
493         else if (sameouttype != (int32_t) decc->user_data_type)
494             sameouttype = -1;
495 
496         if (samebpc == 0)
497             samebpc = decc->bytes_per_element;
498         else if (samebpc != decc->bytes_per_element)
499             samebpc = -1;
500 
501         if (sameoutbpc == 0)
502             sameoutbpc = decc->user_bytes_per_element;
503         else if (sameoutbpc != decc->user_bytes_per_element)
504             sameoutbpc = -1;
505 
506         if (decc->x_samples != 1 || decc->y_samples != 1) hassampling = 1;
507 
508         ++chanstofill;
509         if (decc->user_pixel_stride != decc->bytes_per_element) ++chanstounpack;
510         if (decc->user_data_type != decc->data_type) ++hastypechange;
511 
512         if (simplineoff == 0)
513             simplineoff = decc->user_line_stride;
514         else if (simplineoff != decc->user_line_stride)
515             simplineoff = -1;
516 
517         if (simpinterleave == 0)
518         {
519             interleaveptr     = decc->decode_to_ptr;
520             simpinterleave    = decc->user_pixel_stride;
521             simpinterleaverev = decc->user_pixel_stride;
522         }
523         else
524         {
525             if (simpinterleave > 0 &&
526                 decc->decode_to_ptr !=
527                     (interleaveptr + c * decc->user_bytes_per_element))
528             {
529                 simpinterleave = -1;
530             }
531             if (simpinterleaverev > 0 &&
532                 decc->decode_to_ptr !=
533                     (interleaveptr - c * decc->user_bytes_per_element))
534             {
535                 simpinterleaverev = -1;
536             }
537             if (simpinterleave < 0 && simpinterleaverev < 0)
538                 interleaveptr = NULL;
539         }
540 
541         if (sameoutinc == 0)
542             sameoutinc = decc->user_pixel_stride;
543         else if (sameoutinc != decc->user_pixel_stride)
544             sameoutinc = -1;
545     }
546 
547     if (simpinterleave != sameoutbpc * decode->channel_count)
548         simpinterleave = -1;
549     if (simpinterleaverev != sameoutbpc * decode->channel_count)
550         simpinterleaverev = -1;
551 
552     /* special case, uncompressed and reading planar data straight in
553      * to all the channels */
554     if (!isdeep && part->comp_type == EXR_COMPRESSION_NONE &&
555         chanstounpack == 0 && hastypechange == 0 && chanstofill > 0 &&
556         chanstofill == decode->channel_count)
557     {
558         decode->read_fn               = &read_uncompressed_direct;
559         decode->decompress_fn         = NULL;
560         decode->unpack_and_convert_fn = NULL;
561         return EXR_ERR_SUCCESS;
562     }
563     decode->read_fn = &default_read_chunk;
564     if (part->comp_type != EXR_COMPRESSION_NONE)
565         decode->decompress_fn = &default_decompress_chunk;
566 
567     decode->unpack_and_convert_fn = internal_exr_match_decode (
568         decode,
569         isdeep,
570         chanstofill,
571         chanstounpack,
572         sametype,
573         sameouttype,
574         samebpc,
575         sameoutbpc,
576         hassampling,
577         hastypechange,
578         sameoutinc,
579         simpinterleave,
580         simpinterleaverev,
581         simplineoff);
582 
583     if (!decode->unpack_and_convert_fn)
584         return pctxt->report_error (
585             pctxt,
586             EXR_ERR_ARGUMENT_OUT_OF_RANGE,
587             "Unable to choose valid unpack routine");
588 
589     return EXR_ERR_SUCCESS;
590 }
591 
592 /**************************************/
593 
594 exr_result_t
exr_decoding_update(exr_const_context_t ctxt,int part_index,const exr_chunk_info_t * cinfo,exr_decode_pipeline_t * decode)595 exr_decoding_update (
596     exr_const_context_t     ctxt,
597     int                     part_index,
598     const exr_chunk_info_t* cinfo,
599     exr_decode_pipeline_t*  decode)
600 {
601     exr_result_t rv;
602     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index);
603     if (!cinfo || !decode)
604         return pctxt->standard_error (pctxt, EXR_ERR_INVALID_ARGUMENT);
605 
606     if (decode->context != ctxt || decode->part_index != part_index)
607         return pctxt->report_error (
608             pctxt,
609             EXR_ERR_INVALID_ARGUMENT,
610             "Invalid request for decoding update from different context / part");
611 
612     rv = internal_coding_update_channel_info (
613         decode->channels, decode->channel_count, cinfo, pctxt, part);
614     decode->chunk = *cinfo;
615 
616     return rv;
617 }
618 
619 /**************************************/
620 
621 exr_result_t
exr_decoding_run(exr_const_context_t ctxt,int part_index,exr_decode_pipeline_t * decode)622 exr_decoding_run (
623     exr_const_context_t ctxt, int part_index, exr_decode_pipeline_t* decode)
624 {
625     exr_result_t rv;
626     EXR_PROMOTE_READ_CONST_CONTEXT_AND_PART_OR_ERROR (ctxt, part_index);
627 
628     if (!decode) return pctxt->standard_error (pctxt, EXR_ERR_INVALID_ARGUMENT);
629     if (decode->context != ctxt || decode->part_index != part_index)
630         return pctxt->report_error (
631             pctxt,
632             EXR_ERR_INVALID_ARGUMENT,
633             "Invalid request for decoding update from different context / part");
634 
635     if (!decode->read_fn)
636         return pctxt->report_error (
637             pctxt,
638             EXR_ERR_INVALID_ARGUMENT,
639             "Decode pipeline has no read_fn declared");
640     rv = decode->read_fn (decode);
641     if (rv != EXR_ERR_SUCCESS)
642         return pctxt->report_error (
643             pctxt,
644             rv,
645             "Unable to read pixel data block from context");
646 
647     if (rv == EXR_ERR_SUCCESS) rv = update_pack_unpack_ptrs (decode);
648     if (rv != EXR_ERR_SUCCESS)
649         return pctxt->report_error (
650             pctxt,
651             rv,
652             "Decode pipeline unable to update pack / unpack pointers");
653 
654     if (rv == EXR_ERR_SUCCESS && decode->decompress_fn)
655         rv = decode->decompress_fn (decode);
656     if (rv != EXR_ERR_SUCCESS)
657         return pctxt->report_error (
658             pctxt, rv, "Decode pipeline unable to decompress data");
659 
660     if (rv == EXR_ERR_SUCCESS &&
661         (part->storage_mode == EXR_STORAGE_DEEP_SCANLINE ||
662          part->storage_mode == EXR_STORAGE_DEEP_TILED))
663     {
664         rv = unpack_sample_table (pctxt, decode);
665 
666         if ((decode->decode_flags & EXR_DECODE_SAMPLE_DATA_ONLY)) return rv;
667     }
668 
669     if (rv != EXR_ERR_SUCCESS)
670         return pctxt->report_error (
671             pctxt, rv, "Decode pipeline unable to unpack deep sample table");
672 
673     if (rv == EXR_ERR_SUCCESS && decode->realloc_nonimage_data_fn)
674         rv = decode->realloc_nonimage_data_fn (decode);
675     if (rv != EXR_ERR_SUCCESS)
676         return pctxt->report_error (
677             pctxt,
678             rv,
679             "Decode pipeline unable to realloc deep sample table info");
680 
681     if (rv == EXR_ERR_SUCCESS && decode->unpack_and_convert_fn)
682         rv = decode->unpack_and_convert_fn (decode);
683     if (rv != EXR_ERR_SUCCESS)
684         return pctxt->report_error (
685             pctxt, rv, "Decode pipeline unable to unpack and convert data");
686 
687     return rv;
688 }
689 
690 /**************************************/
691 
692 exr_result_t
exr_decoding_destroy(exr_const_context_t ctxt,exr_decode_pipeline_t * decode)693 exr_decoding_destroy (exr_const_context_t ctxt, exr_decode_pipeline_t* decode)
694 {
695     INTERN_EXR_PROMOTE_CONST_CONTEXT_OR_ERROR (ctxt);
696     if (decode)
697     {
698         exr_decode_pipeline_t nil = { 0 };
699         if (decode->channels != decode->_quick_chan_store)
700             pctxt->free_fn (decode->channels);
701 
702         if (decode->unpacked_buffer == decode->packed_buffer &&
703             decode->unpacked_alloc_size == 0)
704             decode->unpacked_buffer = NULL;
705 
706         internal_decode_free_buffer (
707             decode,
708             EXR_TRANSCODE_BUFFER_PACKED,
709             &(decode->packed_buffer),
710             &(decode->packed_alloc_size));
711         internal_decode_free_buffer (
712             decode,
713             EXR_TRANSCODE_BUFFER_UNPACKED,
714             &(decode->unpacked_buffer),
715             &(decode->unpacked_alloc_size));
716         internal_decode_free_buffer (
717             decode,
718             EXR_TRANSCODE_BUFFER_SCRATCH1,
719             &(decode->scratch_buffer_1),
720             &(decode->scratch_alloc_size_1));
721         internal_decode_free_buffer (
722             decode,
723             EXR_TRANSCODE_BUFFER_SCRATCH2,
724             &(decode->scratch_buffer_2),
725             &(decode->scratch_alloc_size_2));
726         internal_decode_free_buffer (
727             decode,
728             EXR_TRANSCODE_BUFFER_PACKED_SAMPLES,
729             &(decode->packed_sample_count_table),
730             &(decode->packed_sample_count_alloc_size));
731         internal_decode_free_buffer (
732             decode,
733             EXR_TRANSCODE_BUFFER_SAMPLES,
734             (void**) &(decode->sample_count_table),
735             &(decode->sample_count_alloc_size));
736         *decode = nil;
737     }
738     return EXR_ERR_SUCCESS;
739 }
740