diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index da1b0f96cb..0c67dbdaac 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -148,7 +148,7 @@ if(AVIF_ENABLE_GTEST) add_avif_gtest(avifopaquetest) add_avif_gtest_with_data(avifpng16bittest) - add_avif_gtest(avifprogressivetest) + add_avif_gtest_with_data(avifprogressivetest) add_avif_gtest(avifrangetest) add_avif_gtest_with_data(avifreadimagetest) add_avif_internal_gtest(avifrgbtest) diff --git a/tests/data/README.md b/tests/data/README.md index 73fa12ff75..d424f072a6 100644 --- a/tests/data/README.md +++ b/tests/data/README.md @@ -712,6 +712,48 @@ To export more images from sources/colors.psd: - For the wide color gamut version, choose Edit > Assign Profile... and set the color space to Rec.ITU-R BT.2020-1 +## Idat + +These files use the 'idat' box instead of the 'mdat' box to store data. + +### File [draw_points_idat.avif](draw_points_idat.avif) + +![](draw_points_idat.avif) + +License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE) + +Source: generated with a modified libavif at https://github.com/maryla-uc/libavif/tree/idat +by running `./avifenc -q 100 ../tests/data/draw_points.png ../tests/data/draw_points_idat.avif`  + +### File [draw_points_idat_metasize0.avif](draw_points_idat_metasize0.avif) + +![](draw_points_idat_metasize0.avif) + +License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE) + +Source: generated with a modified libavif at https://github.com/maryla-uc/libavif/tree/idat +after uncommenting the line under `// uncomment to make meta size zero` and running +`./avifenc -q 100 ../tests/data/draw_points.png ../tests/data/draw_points_idat_metasize0.avif`  + +### File [draw_points_idat_progressive.avif](draw_points_idat_progressive.avif) + +![](draw_points_idat_progressive.avif) + +License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE) + +Source: generated with a modified libavif at https://github.com/maryla-uc/libavif/tree/idat +by running `./avifenc -q 100 --progressive ../tests/data/draw_points.png ../tests/data/draw_points_idat_progressive.avif`  + +### File [draw_points_idat_progressive_metasize0.avif](draw_points_idat_progressive_metasize0.avif) + +![](draw_points_idat_progressive_metasize0.avif) + +License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE) + +Source: generated with a modified libavif at https://github.com/maryla-uc/libavif/tree/idat +after uncommenting the line under `// uncomment to make meta size zero` and running +`./avifenc -q 100 --progressive ../tests/data/draw_points.png ../tests/data/draw_points_idat_progressive_metasize0.avif`  + ## Animated Images ### File [colors-animated-8bpc.avif](colors-animated-8bpc.avif) diff --git a/tests/data/draw_points_idat.avif b/tests/data/draw_points_idat.avif new file mode 100644 index 0000000000..877e65413b Binary files /dev/null and b/tests/data/draw_points_idat.avif differ diff --git a/tests/data/draw_points_idat_metasize0.avif b/tests/data/draw_points_idat_metasize0.avif new file mode 100644 index 0000000000..bf78bfd91c Binary files /dev/null and b/tests/data/draw_points_idat_metasize0.avif differ diff --git a/tests/data/draw_points_idat_progressive.avif b/tests/data/draw_points_idat_progressive.avif new file mode 100644 index 0000000000..fe8b23db32 Binary files /dev/null and b/tests/data/draw_points_idat_progressive.avif differ diff --git a/tests/data/draw_points_idat_progressive_metasize0.avif b/tests/data/draw_points_idat_progressive_metasize0.avif new file mode 100644 index 0000000000..2eb8614ede Binary files /dev/null and b/tests/data/draw_points_idat_progressive_metasize0.avif differ diff --git a/tests/gtest/avifdecodetest.cc b/tests/gtest/avifdecodetest.cc index b16f0d9890..e4b5a96d83 100644 --- a/tests/gtest/avifdecodetest.cc +++ b/tests/gtest/avifdecodetest.cc @@ -41,6 +41,34 @@ TEST(AvifDecodeTest, ParseEmptyData) { ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_INVALID_FTYP); } +TEST(AvifDecodeTest, Idat) { + if (!testutil::Av1DecoderAvailable()) { + GTEST_SKIP() << "AV1 Codec unavailable, skip test."; + } + + const ImagePtr original = testutil::ReadImage(data_path, "draw_points.png"); + + for (const std::string file_name : + {"draw_points_idat.avif", "draw_points_idat_metasize0.avif", + "draw_points_idat_progressive.avif", + "draw_points_idat_progressive_metasize0.avif"}) { + SCOPED_TRACE(file_name); + DecoderPtr decoder(avifDecoderCreate()); + ASSERT_NE(decoder, nullptr); + ASSERT_EQ(avifDecoderSetIOFile( + decoder.get(), (std::string(data_path) + file_name).c_str()), + AVIF_RESULT_OK); + ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK); + EXPECT_EQ(decoder->alphaPresent, AVIF_TRUE); + EXPECT_EQ(decoder->imageSequenceTrackPresent, AVIF_FALSE); + ASSERT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK); + EXPECT_NE(decoder->image->alphaPlane, nullptr); + EXPECT_GT(decoder->image->alphaRowBytes, 0u); + + EXPECT_EQ(testutil::GetPsnr(*original, *decoder->image), 99.0); + } +} + // From https://crbug.com/334281983. TEST(AvifDecodeTest, PeekCompatibleFileTypeBad1) { constexpr uint8_t kData[] = {0x00, 0x00, 0x00, 0x1c, 0x66, diff --git a/tests/gtest/avifprogressivetest.cc b/tests/gtest/avifprogressivetest.cc index 4cb92daf62..ca251870ca 100644 --- a/tests/gtest/avifprogressivetest.cc +++ b/tests/gtest/avifprogressivetest.cc @@ -8,6 +8,9 @@ namespace avif { namespace { +// Used to pass the data folder path to the GoogleTest suites. +const char* data_path = nullptr; + class ProgressiveTest : public testing::Test { protected: static constexpr uint32_t kImageSize = 256; @@ -30,9 +33,9 @@ class ProgressiveTest : public testing::Test { testutil::FillImageGradient(image_.get()); } - void TestDecode(uint32_t expect_width, uint32_t expect_height) { - ASSERT_EQ(avifDecoderSetIOMemory(decoder_.get(), encoded_avif_.data, - encoded_avif_.size), + void TestDecode(uint8_t* data, size_t size, uint32_t expect_width, + uint32_t expect_height) { + ASSERT_EQ(avifDecoderSetIOMemory(decoder_.get(), data, size), AVIF_RESULT_OK); ASSERT_EQ(avifDecoderParse(decoder_.get()), AVIF_RESULT_OK); ASSERT_EQ(decoder_->progressiveState, AVIF_PROGRESSIVE_STATE_ACTIVE); @@ -46,6 +49,11 @@ class ProgressiveTest : public testing::Test { ASSERT_EQ(decoder_->image->height, expect_height); // TODO(wtc): Check avifDecoderNthImageMaxExtent(). } + } + + void TestDecode(uint32_t expect_width, uint32_t expect_height) { + TestDecode(encoded_avif_.data, encoded_avif_.size, expect_width, + expect_height); // TODO(wtc): Check decoder_->image and image_ are similar, and better // quality layer is more similar. @@ -169,5 +177,50 @@ TEST_F(ProgressiveTest, TooFewLayers) { AVIF_RESULT_INVALID_ARGUMENT); } +// Test progressive decoding with files that use 'idat' (inside the 'meta') box +// instead of 'mdat' to store the image data. Note that for now (as of v1.1.1) +// the decoder waits to have the full meta box available before parsing it, so +// incremental decoding is not really possible and progressive decoding makes +// little sense. But this checks that the files are still processed correctly. +TEST(DecodeProgressiveTest, DecodeIdat) { + const ImagePtr original = testutil::ReadImage(data_path, "draw_points.png"); + + for (const std::string file_name : + {"draw_points_idat_progressive.avif", + "draw_points_idat_progressive_metasize0.avif"}) { + SCOPED_TRACE(file_name); + const int expected_layer_count = 2; + + DecoderPtr decoder(avifDecoderCreate()); + decoder->allowProgressive = true; + ASSERT_EQ(avifDecoderSetIOFile( + decoder.get(), (std::string(data_path) + file_name).c_str()), + AVIF_RESULT_OK); + ASSERT_EQ(avifDecoderParse(decoder.get()), AVIF_RESULT_OK); + ASSERT_EQ(decoder->progressiveState, AVIF_PROGRESSIVE_STATE_ACTIVE); + ASSERT_EQ(static_cast(decoder->imageCount), expected_layer_count); + + for (uint32_t layer = 0; layer < expected_layer_count; ++layer) { + ASSERT_EQ(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK); + ASSERT_EQ(decoder->image->width, original->width); + ASSERT_EQ(decoder->image->height, original->height); + } + ASSERT_EQ(avifDecoderNextImage(decoder.get()), + AVIF_RESULT_NO_IMAGES_REMAINING); + } +} + } // namespace } // namespace avif + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if (argc != 2) { + std::cerr << "There must be exactly one argument containing the path to " + "the test data folder" + << std::endl; + return 1; + } + avif::data_path = argv[1]; + return RUN_ALL_TESTS(); +}