| 611 | } |
| 612 | |
| 613 | static avifResult avifCodecDecodeInputFillFromDecoderItem(avifCodecDecodeInput * decodeInput, |
| 614 | avifDecoderItem * item, |
| 615 | avifBool allowProgressive, |
| 616 | const uint32_t imageCountLimit, |
| 617 | const uint64_t sizeHint, |
| 618 | avifDiagnostics * diag) |
| 619 | { |
| 620 | if (sizeHint && (item->size > sizeHint)) { |
| 621 | avifDiagnosticsPrintf(diag, "Exceeded avifIO's sizeHint, possibly truncated data"); |
| 622 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 623 | } |
| 624 | |
| 625 | uint8_t layerCount = 0; |
| 626 | size_t layerSizes[4] = { 0 }; |
| 627 | const avifProperty * a1lxProp = avifPropertyArrayFind(&item->properties, "a1lx"); |
| 628 | if (a1lxProp) { |
| 629 | // Calculate layer count and all layer sizes from the a1lx box, and then validate |
| 630 | |
| 631 | size_t remainingSize = item->size; |
| 632 | for (int i = 0; i < 3; ++i) { |
| 633 | ++layerCount; |
| 634 | |
| 635 | const size_t layerSize = (size_t)a1lxProp->u.a1lx.layerSize[i]; |
| 636 | if (layerSize) { |
| 637 | if (layerSize >= remainingSize) { // >= instead of > because there must be room for the last layer |
| 638 | avifDiagnosticsPrintf(diag, "a1lx layer index [%d] does not fit in item size", i); |
| 639 | return AVIF_RESULT_BMFF_PARSE_FAILED; |
| 640 | } |
| 641 | layerSizes[i] = layerSize; |
| 642 | remainingSize -= layerSize; |
| 643 | } else { |
| 644 | layerSizes[i] = remainingSize; |
| 645 | remainingSize = 0; |
| 646 | break; |
| 647 | } |
| 648 | } |
| 649 | if (remainingSize > 0) { |
| 650 | AVIF_ASSERT_OR_RETURN(layerCount == 3); |
| 651 | ++layerCount; |
| 652 | layerSizes[3] = remainingSize; |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | const avifProperty * lselProp = avifPropertyArrayFind(&item->properties, "lsel"); |
| 657 | // Progressive images offer layers via the a1lxProp, but don't specify a layer selection with lsel. |
| 658 | // |
| 659 | // For backward compatibility with earlier drafts of AVIF spec v1.1.0, treat an absent lsel as |
| 660 | // equivalent to layer_id == 0xFFFF during the transitional period. Remove !lselProp when the test |
| 661 | // images have been updated to the v1.1.0 spec. |
| 662 | item->progressive = (a1lxProp && (!lselProp || (lselProp->u.lsel.layerID == 0xFFFF))); |
| 663 | if (lselProp && (lselProp->u.lsel.layerID != 0xFFFF)) { |
| 664 | // Layer selection. This requires that the underlying AV1 codec decodes all layers, |
| 665 | // and then only returns the requested layer as a single frame. To the user of libavif, |
| 666 | // this appears to be a single frame. |
| 667 | |
| 668 | decodeInput->allLayers = AVIF_TRUE; |
| 669 | |
| 670 | size_t sampleSize = 0; |
no test coverage detected