| 16 | }; |
| 17 | |
| 18 | avifResult EncodeDecodeGrid(const std::vector<std::vector<Cell>>& cell_rows, |
| 19 | avifPixelFormat yuv_format) { |
| 20 | // Construct a grid. |
| 21 | std::vector<ImagePtr> cell_images; |
| 22 | cell_images.reserve(cell_rows.size() * cell_rows.front().size()); |
| 23 | for (const std::vector<Cell>& cell_row : cell_rows) { |
| 24 | assert(cell_row.size() == cell_rows.front().size()); |
| 25 | for (const Cell& cell : cell_row) { |
| 26 | cell_images.emplace_back(testutil::CreateImage( |
| 27 | cell.width, cell.height, /*depth=*/8, yuv_format, AVIF_PLANES_ALL)); |
| 28 | if (!cell_images.back()) { |
| 29 | return AVIF_RESULT_INVALID_ARGUMENT; |
| 30 | } |
| 31 | testutil::FillImageGradient(cell_images.back().get()); |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | // Encode the grid image (losslessly for easy pixel-by-pixel comparison). |
| 36 | EncoderPtr encoder(avifEncoderCreate()); |
| 37 | if (!encoder) { |
| 38 | return AVIF_RESULT_OUT_OF_MEMORY; |
| 39 | } |
| 40 | encoder->speed = AVIF_SPEED_FASTEST; |
| 41 | encoder->quality = AVIF_QUALITY_LOSSLESS; |
| 42 | encoder->qualityAlpha = AVIF_QUALITY_LOSSLESS; |
| 43 | // cell_image_ptrs exists only to match the libavif API. |
| 44 | std::vector<avifImage*> cell_image_ptrs(cell_images.size()); |
| 45 | for (size_t i = 0; i < cell_images.size(); ++i) { |
| 46 | cell_image_ptrs[i] = cell_images[i].get(); |
| 47 | } |
| 48 | avifResult result = avifEncoderAddImageGrid( |
| 49 | encoder.get(), static_cast<uint32_t>(cell_rows.front().size()), |
| 50 | static_cast<uint32_t>(cell_rows.size()), cell_image_ptrs.data(), |
| 51 | AVIF_ADD_IMAGE_FLAG_SINGLE); |
| 52 | if (result != AVIF_RESULT_OK) { |
| 53 | return result; |
| 54 | } |
| 55 | |
| 56 | testutil::AvifRwData encoded_avif; |
| 57 | result = avifEncoderFinish(encoder.get(), &encoded_avif); |
| 58 | if (result != AVIF_RESULT_OK) { |
| 59 | return result; |
| 60 | } |
| 61 | |
| 62 | // Decode the grid image. |
| 63 | ImagePtr image(avifImageCreateEmpty()); |
| 64 | DecoderPtr decoder(avifDecoderCreate()); |
| 65 | if (!image || !decoder) { |
| 66 | return AVIF_RESULT_OUT_OF_MEMORY; |
| 67 | } |
| 68 | result = avifDecoderReadMemory(decoder.get(), image.get(), encoded_avif.data, |
| 69 | encoded_avif.size); |
| 70 | if (result != AVIF_RESULT_OK) { |
| 71 | return result; |
| 72 | } |
| 73 | |
| 74 | // Reconstruct the input image by merging all cells into a single avifImage. |
| 75 | ImagePtr grid = testutil::CreateImage( |
no test coverage detected