diff --git a/tests/gtest/avifincrtest.cc b/tests/gtest/avifincrtest.cc index ed88a422f8..18d6a887c2 100644 --- a/tests/gtest/avifincrtest.cc +++ b/tests/gtest/avifincrtest.cc @@ -55,10 +55,11 @@ TEST(IncrementalTest, Decode) { // Cell height is hardcoded because there is no API to extract it from an // encoded payload. - testutil::DecodeIncrementally( - encoded_avif, /*is_persistent=*/true, /*give_size_hint=*/true, - /*use_nth_image_api=*/false, *reference, /*cell_height=*/154, - /*enable_fine_incremental_check=*/true); + testutil::DecodeIncrementally(encoded_avif, decoder.get(), + /*is_persistent=*/true, /*give_size_hint=*/true, + /*use_nth_image_api=*/false, *reference, + /*cell_height=*/154, + /*enable_fine_incremental_check=*/true); } //------------------------------------------------------------------------------ @@ -98,8 +99,9 @@ TEST_P(IncrementalTest, EncodeDecode) { testutil::EncodeRectAsIncremental(*image, width, height, create_alpha, flat_cells, &encoded_avif, &cell_width, &cell_height); + testutil::DecodeNonIncrementallyAndIncrementally( - encoded_avif, encoded_avif_is_persistent, give_size_hint, + encoded_avif, decoder.get(), encoded_avif_is_persistent, give_size_hint, use_nth_image_api, cell_height, /*enable_fine_incremental_check=*/true); } diff --git a/tests/gtest/avifincrtest_helpers.cc b/tests/gtest/avifincrtest_helpers.cc index 2aeb2fa059..76361fb3d1 100644 --- a/tests/gtest/avifincrtest_helpers.cc +++ b/tests/gtest/avifincrtest_helpers.cc @@ -4,7 +4,9 @@ #include "avifincrtest_helpers.h" #include +#include #include +#include #include #include "avif/avif.h" @@ -275,9 +277,10 @@ void EncodeRectAsIncremental(const avifImage& image, uint32_t width, //------------------------------------------------------------------------------ -void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent, - bool give_size_hint, bool use_nth_image_api, - const avifImage& reference, uint32_t cell_height, +void DecodeIncrementally(const avifRWData& encoded_avif, avifDecoder* decoder, + bool is_persistent, bool give_size_hint, + bool use_nth_image_api, const avifImage& reference, + uint32_t cell_height, bool enable_fine_incremental_check) { // AVIF cells are at least 64 pixels tall. if (cell_height != reference.height) { @@ -292,35 +295,39 @@ void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent, /*destroy=*/nullptr, PartialRead, /*write=*/nullptr, give_size_hint ? encoded_avif.size : 0, is_persistent, &data}; + avifDecoderSetIO(decoder, &io); + // Reset the decoder's IO to nullptr before 'io' goes out of scope and becomes + // invalid. + auto cleanup_io_fn = [](avifDecoder* decoder) { + avifDecoderSetIO(decoder, nullptr); + }; + std::unique_ptr cleanup_io( + decoder, cleanup_io_fn); // Call automatically at end of scope. - testutil::AvifDecoderPtr decoder(avifDecoderCreate(), avifDecoderDestroy); - ASSERT_NE(decoder, nullptr); - avifDecoderSetIO(decoder.get(), &io); decoder->allowIncremental = AVIF_TRUE; const size_t step = std::max(1, data.full_size / 10000); // Parsing is not incremental. - avifResult parse_result = avifDecoderParse(decoder.get()); + avifResult parse_result = avifDecoderParse(decoder); while (parse_result == AVIF_RESULT_WAITING_ON_IO) { ASSERT_LT(data.available.size, data.full_size) << "avifDecoderParse() returned WAITING_ON_IO instead of OK"; data.available.size = std::min(data.available.size + step, data.full_size); - parse_result = avifDecoderParse(decoder.get()); + parse_result = avifDecoderParse(decoder); } ASSERT_EQ(parse_result, AVIF_RESULT_OK); // Decoding is incremental. uint32_t previously_decoded_row_count = 0; avifResult next_image_result = use_nth_image_api - ? avifDecoderNthImage(decoder.get(), 0) - : avifDecoderNextImage(decoder.get()); + ? avifDecoderNthImage(decoder, 0) + : avifDecoderNextImage(decoder); while (next_image_result == AVIF_RESULT_WAITING_ON_IO) { ASSERT_LT(data.available.size, data.full_size) << (use_nth_image_api ? "avifDecoderNthImage(0)" : "avifDecoderNextImage()") << " returned WAITING_ON_IO instead of OK"; - const uint32_t decoded_row_count = - avifDecoderDecodedRowCount(decoder.get()); + const uint32_t decoded_row_count = avifDecoderDecodedRowCount(decoder); ASSERT_GE(decoded_row_count, previously_decoded_row_count); const uint32_t min_decoded_row_count = GetMinDecodedRowCount( reference.height, cell_height, reference.alphaPlane != nullptr, @@ -330,30 +337,28 @@ void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent, previously_decoded_row_count = decoded_row_count; data.available.size = std::min(data.available.size + step, data.full_size); - next_image_result = use_nth_image_api - ? avifDecoderNthImage(decoder.get(), 0) - : avifDecoderNextImage(decoder.get()); + next_image_result = use_nth_image_api ? avifDecoderNthImage(decoder, 0) + : avifDecoderNextImage(decoder); } ASSERT_EQ(next_image_result, AVIF_RESULT_OK); ASSERT_EQ(data.available.size, data.full_size); - ASSERT_EQ(avifDecoderDecodedRowCount(decoder.get()), decoder->image->height); + ASSERT_EQ(avifDecoderDecodedRowCount(decoder), decoder->image->height); ComparePartialYuva(reference, *decoder->image, reference.height); } void DecodeNonIncrementallyAndIncrementally( - const avifRWData& encoded_avif, bool is_persistent, bool give_size_hint, - bool use_nth_image_api, uint32_t cell_height, + const avifRWData& encoded_avif, avifDecoder* decoder, bool is_persistent, + bool give_size_hint, bool use_nth_image_api, uint32_t cell_height, bool enable_fine_incremental_check) { AvifImagePtr reference(avifImageCreateEmpty(), avifImageDestroy); ASSERT_NE(reference, nullptr); - testutil::AvifDecoderPtr decoder(avifDecoderCreate(), avifDecoderDestroy); - ASSERT_NE(decoder, nullptr); - ASSERT_EQ(avifDecoderReadMemory(decoder.get(), reference.get(), - encoded_avif.data, encoded_avif.size), + decoder->allowIncremental = AVIF_FALSE; + ASSERT_EQ(avifDecoderReadMemory(decoder, reference.get(), encoded_avif.data, + encoded_avif.size), AVIF_RESULT_OK); - DecodeIncrementally(encoded_avif, is_persistent, give_size_hint, + DecodeIncrementally(encoded_avif, decoder, is_persistent, give_size_hint, use_nth_image_api, *reference, cell_height, enable_fine_incremental_check); } diff --git a/tests/gtest/avifincrtest_helpers.h b/tests/gtest/avifincrtest_helpers.h index 4706902985..1541d8deb3 100644 --- a/tests/gtest/avifincrtest_helpers.h +++ b/tests/gtest/avifincrtest_helpers.h @@ -4,6 +4,8 @@ #ifndef LIBAVIF_TESTS_AVIFINCRTEST_HELPERS_H_ #define LIBAVIF_TESTS_AVIFINCRTEST_HELPERS_H_ +#include + #include "avif/avif.h" namespace libavif { @@ -24,16 +26,17 @@ void EncodeRectAsIncremental(const avifImage& image, uint32_t width, // incremental granularity. enable_fine_incremental_check checks that sample // rows are gradually output when feeding more and more input bytes to the // decoder. -void DecodeIncrementally(const avifRWData& encoded_avif, bool is_persistent, - bool give_size_hint, bool use_nth_image_api, - const avifImage& reference, uint32_t cell_height, +void DecodeIncrementally(const avifRWData& encoded_avif, avifDecoder* decoder, + bool is_persistent, bool give_size_hint, + bool use_nth_image_api, const avifImage& reference, + uint32_t cell_height, bool enable_fine_incremental_check = false); // Calls DecodeIncrementally() with the reference being a regular decoding of // encoded_avif. void DecodeNonIncrementallyAndIncrementally( - const avifRWData& encoded_avif, bool is_persistent, bool give_size_hint, - bool use_nth_image_api, uint32_t cell_height, + const avifRWData& encoded_avif, avifDecoder* decoder, bool is_persistent, + bool give_size_hint, bool use_nth_image_api, uint32_t cell_height, bool enable_fine_incremental_check = false); } // namespace testutil