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