Allocates the dstImage. Also verifies some spec compliance rules for grids, if relevant.
| 1731 | |
| 1732 | // Allocates the dstImage. Also verifies some spec compliance rules for grids, if relevant. |
| 1733 | static avifResult avifDecoderDataAllocateImagePlanes(const avifDecoderData * data, const avifTileInfo * info, avifImage * dstImage, avifBool * cicpSet) |
| 1734 | { |
| 1735 | const avifTile * tile = &data->tiles.tile[info->firstTileIndex]; |
| 1736 | uint32_t dstWidth; |
| 1737 | uint32_t dstHeight; |
| 1738 | |
| 1739 | if (info->grid.rows > 0 && info->grid.columns > 0) { |
| 1740 | const avifImageGrid * grid = &info->grid; |
| 1741 | // Validate grid image size and tile size. |
| 1742 | // |
| 1743 | // HEIF (ISO/IEC 23008-12:2017), Section 6.6.2.3.1: |
| 1744 | // The tiled input images shall completely "cover" the reconstructed image grid canvas, ... |
| 1745 | if ((((uint64_t)tile->image->width * grid->columns) < grid->outputWidth) || |
| 1746 | (((uint64_t)tile->image->height * grid->rows) < grid->outputHeight)) { |
| 1747 | avifDiagnosticsPrintf(data->diag, |
| 1748 | "Grid image tiles do not completely cover the image (HEIF (ISO/IEC 23008-12:2017), Section 6.6.2.3.1)"); |
| 1749 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
| 1750 | } |
| 1751 | // Tiles in the rightmost column and bottommost row must overlap the reconstructed image grid canvas. See MIAF (ISO/IEC 23000-22:2019), Section 7.3.11.4.2, Figure 2. |
| 1752 | if ((((uint64_t)tile->image->width * (grid->columns - 1)) >= grid->outputWidth) || |
| 1753 | (((uint64_t)tile->image->height * (grid->rows - 1)) >= grid->outputHeight)) { |
| 1754 | avifDiagnosticsPrintf(data->diag, |
| 1755 | "Grid image tiles in the rightmost column and bottommost row do not overlap the reconstructed image grid canvas. See MIAF (ISO/IEC 23000-22:2019), Section 7.3.11.4.2, Figure 2"); |
| 1756 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
| 1757 | } |
| 1758 | if (!avifAreGridDimensionsValid(tile->image->yuvFormat, |
| 1759 | grid->outputWidth, |
| 1760 | grid->outputHeight, |
| 1761 | tile->image->width, |
| 1762 | tile->image->height, |
| 1763 | data->diag)) { |
| 1764 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
| 1765 | } |
| 1766 | dstWidth = grid->outputWidth; |
| 1767 | dstHeight = grid->outputHeight; |
| 1768 | } else { |
| 1769 | // Only one tile. Width and height are inherited from the 'ispe' property of the corresponding avifDecoderItem. |
| 1770 | dstWidth = tile->width; |
| 1771 | dstHeight = tile->height; |
| 1772 | } |
| 1773 | |
| 1774 | const avifBool alpha = avifIsAlpha(tile->input->itemCategory); |
| 1775 | if (alpha) { |
| 1776 | // An alpha tile does not contain any YUV pixels. |
| 1777 | AVIF_ASSERT_OR_RETURN(tile->image->yuvFormat == AVIF_PIXEL_FORMAT_NONE); |
| 1778 | } |
| 1779 | |
| 1780 | const uint32_t dstDepth = tile->image->depth; |
| 1781 | |
| 1782 | // Lazily populate dstImage with the new frame's properties. |
| 1783 | const avifBool dimsOrDepthIsDifferent = (dstImage->width != dstWidth) || (dstImage->height != dstHeight) || |
| 1784 | (dstImage->depth != dstDepth); |
| 1785 | const avifBool yuvFormatIsDifferent = !alpha && (dstImage->yuvFormat != tile->image->yuvFormat); |
| 1786 | if (dimsOrDepthIsDifferent || yuvFormatIsDifferent) { |
| 1787 | if (alpha) { |
| 1788 | // Alpha doesn't match size, just bail out |
| 1789 | avifDiagnosticsPrintf(data->diag, "Alpha plane dimensions do not match color plane dimensions"); |
| 1790 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
no test coverage detected