Allow providing a custom decoder to testutil::DecodeIncrementally. (#1592) This allows testing decoders with different settings.
diff --git a/tests/gtest/avifincrtest.cc b/tests/gtest/avifincrtest.cc index ed88a42..18d6a88 100644 --- a/tests/gtest/avifincrtest.cc +++ b/tests/gtest/avifincrtest.cc
@@ -55,10 +55,11 @@ // 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 @@ 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 2aeb2fa..76361fb 100644 --- a/tests/gtest/avifincrtest_helpers.cc +++ b/tests/gtest/avifincrtest_helpers.cc
@@ -4,7 +4,9 @@ #include "avifincrtest_helpers.h" #include <algorithm> +#include <cstdint> #include <cstring> +#include <memory> #include <vector> #include "avif/avif.h" @@ -275,9 +277,10 @@ //------------------------------------------------------------------------------ -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 @@ /*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<avifDecoder, decltype(cleanup_io_fn)> 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<size_t>(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 @@ 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 4706902..1541d8d 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 <cstdint> + #include "avif/avif.h" namespace libavif { @@ -24,16 +26,17 @@ // 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