Add tests decoding files using 'idat' instead of 'mdat' (#2433)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index da1b0f9..0c67dbd 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -148,7 +148,7 @@
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 73fa12f..d424f07 100644
--- a/tests/data/README.md
+++ b/tests/data/README.md
@@ -712,6 +712,48 @@
- 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 0000000..877e654
--- /dev/null
+++ b/tests/data/draw_points_idat.avif
Binary files differ
diff --git a/tests/data/draw_points_idat_metasize0.avif b/tests/data/draw_points_idat_metasize0.avif
new file mode 100644
index 0000000..bf78bfd
--- /dev/null
+++ b/tests/data/draw_points_idat_metasize0.avif
Binary files differ
diff --git a/tests/data/draw_points_idat_progressive.avif b/tests/data/draw_points_idat_progressive.avif
new file mode 100644
index 0000000..fe8b23d
--- /dev/null
+++ b/tests/data/draw_points_idat_progressive.avif
Binary files 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 0000000..2eb8614
--- /dev/null
+++ b/tests/data/draw_points_idat_progressive_metasize0.avif
Binary files differ
diff --git a/tests/gtest/avifdecodetest.cc b/tests/gtest/avifdecodetest.cc
index b16f0d9..e4b5a96 100644
--- a/tests/gtest/avifdecodetest.cc
+++ b/tests/gtest/avifdecodetest.cc
@@ -41,6 +41,34 @@
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 4cb92da..ca25187 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 @@
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 @@
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 @@
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<uint32_t>(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();
+}