| 1700 | } |
| 1701 | |
| 1702 | static avifResult avifEncoderAddImageInternal(avifEncoder * encoder, |
| 1703 | uint32_t gridCols, |
| 1704 | uint32_t gridRows, |
| 1705 | const avifImage * const * cellImages, |
| 1706 | uint64_t durationInTimescales, |
| 1707 | avifAddImageFlags addImageFlags) |
| 1708 | { |
| 1709 | // ----------------------------------------------------------------------- |
| 1710 | // Verify encoding is possible |
| 1711 | |
| 1712 | if (!avifCodecName(encoder->codecChoice, AVIF_CODEC_FLAG_CAN_ENCODE)) { |
| 1713 | return AVIF_RESULT_NO_CODEC_AVAILABLE; |
| 1714 | } |
| 1715 | |
| 1716 | if (encoder->extraLayerCount >= AVIF_MAX_AV1_LAYER_COUNT) { |
| 1717 | avifDiagnosticsPrintf(&encoder->diag, "extraLayerCount [%u] must be less than %d", encoder->extraLayerCount, AVIF_MAX_AV1_LAYER_COUNT); |
| 1718 | return AVIF_RESULT_INVALID_ARGUMENT; |
| 1719 | } |
| 1720 | |
| 1721 | // ----------------------------------------------------------------------- |
| 1722 | // Validate images |
| 1723 | |
| 1724 | const uint32_t cellCount = gridCols * gridRows; |
| 1725 | if (cellCount == 0) { |
| 1726 | return AVIF_RESULT_INVALID_ARGUMENT; |
| 1727 | } |
| 1728 | |
| 1729 | const avifImage * firstCell = cellImages[0]; |
| 1730 | const avifImage * bottomRightCell = cellImages[cellCount - 1]; |
| 1731 | AVIF_CHECKERR(firstCell->depth == 8 || firstCell->depth == 10 || firstCell->depth == 12 || |
| 1732 | (firstCell->depth == 16 && encoder->sampleTransformRecipe != AVIF_SAMPLE_TRANSFORM_NONE), |
| 1733 | AVIF_RESULT_UNSUPPORTED_DEPTH); |
| 1734 | AVIF_CHECKERR(firstCell->yuvFormat != AVIF_PIXEL_FORMAT_NONE, AVIF_RESULT_NO_YUV_FORMAT_SELECTED); |
| 1735 | if (!firstCell->width || !firstCell->height || !bottomRightCell->width || !bottomRightCell->height) { |
| 1736 | return AVIF_RESULT_NO_CONTENT; |
| 1737 | } |
| 1738 | |
| 1739 | AVIF_CHECKRES(avifValidateGrid(gridCols, gridRows, cellImages, /*validateGainMap=*/AVIF_FALSE, &encoder->diag)); |
| 1740 | |
| 1741 | const avifBool hasGainMap = (firstCell->gainMap && firstCell->gainMap->image != NULL); |
| 1742 | |
| 1743 | // Check that either all cells have a gain map, or none of them do. |
| 1744 | // If a gain map is present, check that they all have the same gain map metadata. |
| 1745 | for (uint32_t cellIndex = 0; cellIndex < cellCount; ++cellIndex) { |
| 1746 | const avifImage * cellImage = cellImages[cellIndex]; |
| 1747 | const avifBool cellHasGainMap = (cellImage->gainMap && cellImage->gainMap->image); |
| 1748 | if (cellHasGainMap != hasGainMap) { |
| 1749 | avifDiagnosticsPrintf(&encoder->diag, "cells should either all have a gain map image, or none of them should, found a mix"); |
| 1750 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
| 1751 | } |
| 1752 | if (hasGainMap) { |
| 1753 | if (!avifSameGainMapAltMetadata(firstCell->gainMap, cellImage->gainMap)) { |
| 1754 | avifDiagnosticsPrintf(&encoder->diag, "all cells should have the same alternate image metadata in the gain map"); |
| 1755 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
| 1756 | } |
| 1757 | if (!avifSameGainMapMetadata(firstCell->gainMap, cellImage->gainMap)) { |
| 1758 | avifDiagnosticsPrintf(&encoder->diag, "all cells should have the same gain map metadata"); |
| 1759 | return AVIF_RESULT_INVALID_IMAGE_GRID; |
no test coverage detected