Encodes an animation and decodes it. For simplicity, there is only one source image, all frames are identical.
| 23 | // Encodes an animation and decodes it. |
| 24 | // For simplicity, there is only one source image, all frames are identical. |
| 25 | void EncodeDecodeAnimation(std::vector<ImagePtr> frames, |
| 26 | const std::vector<FrameOptions>& frame_options, |
| 27 | EncoderPtr encoder, DecoderPtr decoder) { |
| 28 | ASSERT_NE(encoder, nullptr); |
| 29 | ASSERT_NE(decoder, nullptr); |
| 30 | ImagePtr decoded_image(avifImageCreateEmpty()); |
| 31 | ASSERT_NE(decoded_image, nullptr); |
| 32 | |
| 33 | const size_t num_frames = frames.size(); |
| 34 | int total_duration = 0; |
| 35 | |
| 36 | // Encode. |
| 37 | for (size_t i = 0; i < num_frames; ++i) { |
| 38 | total_duration += frame_options[i].duration; |
| 39 | const avifResult result = |
| 40 | avifEncoderAddImage(encoder.get(), frames[i].get(), |
| 41 | frame_options[i].duration, frame_options[i].flags); |
| 42 | ASSERT_EQ(result, AVIF_RESULT_OK) |
| 43 | << avifResultToString(result) << ": " << encoder->diag.error; |
| 44 | } |
| 45 | AvifRwData encoded_data; |
| 46 | avifResult result = avifEncoderFinish(encoder.get(), &encoded_data); |
| 47 | ASSERT_EQ(result, AVIF_RESULT_OK) |
| 48 | << avifResultToString(result) << ": " << encoder->diag.error; |
| 49 | |
| 50 | // Decode. |
| 51 | result = avifDecoderSetIOMemory(decoder.get(), encoded_data.data, |
| 52 | encoded_data.size); |
| 53 | ASSERT_EQ(result, AVIF_RESULT_OK) |
| 54 | << avifResultToString(result) << ": " << decoder->diag.error; |
| 55 | |
| 56 | result = avifDecoderParse(decoder.get()); |
| 57 | ASSERT_EQ(result, AVIF_RESULT_OK) |
| 58 | << avifResultToString(result) << ": " << decoder->diag.error; |
| 59 | |
| 60 | if (decoder->requestedSource == AVIF_DECODER_SOURCE_PRIMARY_ITEM || |
| 61 | num_frames == 1) { |
| 62 | ASSERT_EQ(decoder->imageCount, 1); |
| 63 | } else { |
| 64 | ASSERT_EQ(decoder->imageCount, num_frames); |
| 65 | EXPECT_EQ(decoder->durationInTimescales, total_duration); |
| 66 | |
| 67 | for (size_t i = 0; i < num_frames; ++i) { |
| 68 | result = avifDecoderNextImage(decoder.get()); |
| 69 | ASSERT_EQ(result, AVIF_RESULT_OK) |
| 70 | << " frame " << i << ": " << avifResultToString(result) << " (" |
| 71 | << decoder->diag.error << ")"; |
| 72 | EXPECT_EQ(decoder->image->width, frames[i]->width); |
| 73 | EXPECT_EQ(decoder->image->height, frames[i]->height); |
| 74 | EXPECT_EQ(decoder->image->depth, frames[i]->depth); |
| 75 | EXPECT_EQ(decoder->image->yuvFormat, frames[i]->yuvFormat); |
| 76 | } |
| 77 | result = avifDecoderNextImage(decoder.get()); |
| 78 | ASSERT_EQ(result, AVIF_RESULT_NO_IMAGES_REMAINING) |
| 79 | << avifResultToString(result) << ": " << decoder->diag.error; |
| 80 | } |
| 81 | } |
| 82 |
nothing calls this directly
no test coverage detected