Add unit test for color grid/alpha no grid case
Add a unit test to make sure that decoding the test file from
issue #1203 results in a decoded file with alpha channel.
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index c98405b..02628d7 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -100,6 +100,11 @@
target_include_directories(avifcodectest PRIVATE ${GTEST_INCLUDE_DIRS})
add_test(NAME avifcodectest COMMAND avifcodectest)
+ add_executable(avifdecodetest gtest/avifdecodetest.cc)
+ target_link_libraries(avifdecodetest aviftest_helpers ${GTEST_LIBRARIES})
+ target_include_directories(avifdecodetest PRIVATE ${GTEST_INCLUDE_DIRS})
+ add_test(NAME avifdecodetest COMMAND avifdecodetest ${CMAKE_CURRENT_SOURCE_DIR}/data/)
+
add_executable(avifgridapitest gtest/avifgridapitest.cc)
target_link_libraries(avifgridapitest avif_internal aviftest_helpers ${GTEST_BOTH_LIBRARIES})
target_include_directories(avifgridapitest PRIVATE ${GTEST_INCLUDE_DIRS})
diff --git a/tests/data/README.md b/tests/data/README.md
index 933f2e3..8755fae 100644
--- a/tests/data/README.md
+++ b/tests/data/README.md
@@ -175,3 +175,29 @@
Source: Personal photo converted with `avifenc --grid 1x5 --yuv 420` at
commit [632d131](https://github.com/AOMediaCodec/libavif/commit/632d13188f9b7faa40f20d870e792174b8b5b8e6).
+
+### File [color_grid_alpha_nogrid.avif](color_grid_alpha_nogrid.avif)
+
+![](color_grid_alpha_nogrid.avif)
+
+License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE)
+
+Source: https://github.com/AOMediaCodec/libavif/issues/1203
+
+The color planes are arranged as a 1x2 grid item. The alpha plane items are
+tagged as `dimg` for each color plane item (without a `grid` item on its own).
+This is allowed per the specification. libavif should decode such files
+correctly (i.e.) it should report them as files with alpha channel.
+
+Box structure of the items in this file:
+```
+[primary item grid]
+ ^ ^
+ |dimg |dimg
+ | |
+[color] [color]
+ ^ ^
+ |auxl |auxl
+ | |
+[alpha] [alpha]
+```
diff --git a/tests/data/color_grid_alpha_nogrid.avif b/tests/data/color_grid_alpha_nogrid.avif
new file mode 100644
index 0000000..fa301f5
--- /dev/null
+++ b/tests/data/color_grid_alpha_nogrid.avif
Binary files differ
diff --git a/tests/gtest/avifavmtest.cc b/tests/gtest/avifavmtest.cc
index 9420e56..8366271 100644
--- a/tests/gtest/avifavmtest.cc
+++ b/tests/gtest/avifavmtest.cc
@@ -82,12 +82,7 @@
/*alpha=*/Values(true)));
TEST(AvmTest, Av1StillWorksWhenAvmIsEnabled) {
- const char* encoding_codec =
- avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_ENCODE);
- const char* decoding_codec =
- avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_DECODE);
- if (encoding_codec == nullptr || std::string(encoding_codec) == "avm" ||
- decoding_codec == nullptr || std::string(decoding_codec) == "avm") {
+ if (!testutil::Av1EncoderAvailable() || !testutil::Av1DecoderAvailable()) {
GTEST_SKIP() << "AV1 codec unavailable, skip test.";
}
// avm is the only AV2 codec, so the default codec will be an AV1 one.
diff --git a/tests/gtest/avifdecodetest.cc b/tests/gtest/avifdecodetest.cc
new file mode 100644
index 0000000..7342b3c
--- /dev/null
+++ b/tests/gtest/avifdecodetest.cc
@@ -0,0 +1,45 @@
+// Copyright 2023 Google LLC
+// SPDX-License-Identifier: BSD-2-Clause
+
+#include "avif/avif.h"
+#include "aviftest_helpers.h"
+#include "gtest/gtest.h"
+
+namespace libavif {
+namespace {
+
+// Used to pass the data folder path to the GoogleTest suites.
+const char* data_path = nullptr;
+
+TEST(AvifDecodeTest, ColorGridAlphaNoGrid) {
+ if (!testutil::Av1DecoderAvailable()) {
+ GTEST_SKIP() << "AV1 Codec unavailable, skip test.";
+ }
+ // Test case from https://github.com/AOMediaCodec/libavif/issues/1203.
+ const char* file_name = "color_grid_alpha_nogrid.avif";
+ testutil::AvifDecoderPtr decoder(avifDecoderCreate(), avifDecoderDestroy);
+ 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(avifDecoderNextImage(decoder.get()), AVIF_RESULT_OK);
+ EXPECT_NE(decoder->image->alphaPlane, nullptr);
+ EXPECT_GT(decoder->image->alphaRowBytes, 0u);
+}
+
+} // namespace
+} // namespace libavif
+
+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;
+ }
+ libavif::data_path = argv[1];
+ return RUN_ALL_TESTS();
+}
diff --git a/tests/gtest/aviftest_helpers.cc b/tests/gtest/aviftest_helpers.cc
index 32e7f1b..349a0f8 100644
--- a/tests/gtest/aviftest_helpers.cc
+++ b/tests/gtest/aviftest_helpers.cc
@@ -374,6 +374,18 @@
return decoded;
}
+bool Av1EncoderAvailable() {
+ const char* encoding_codec =
+ avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_ENCODE);
+ return encoding_codec != nullptr && std::string(encoding_codec) != "avm";
+}
+
+bool Av1DecoderAvailable() {
+ const char* decoding_codec =
+ avifCodecName(AVIF_CODEC_CHOICE_AUTO, AVIF_CODEC_FLAG_CAN_DECODE);
+ return decoding_codec != nullptr && std::string(decoding_codec) != "avm";
+}
+
//------------------------------------------------------------------------------
static avifResult avifIOLimitedReaderRead(avifIO* io, uint32_t readFlags,
diff --git a/tests/gtest/aviftest_helpers.h b/tests/gtest/aviftest_helpers.h
index ba99faf..10b6683 100644
--- a/tests/gtest/aviftest_helpers.h
+++ b/tests/gtest/aviftest_helpers.h
@@ -103,6 +103,12 @@
// Returns nullptr in case of error.
AvifImagePtr Decode(const uint8_t* bytes, size_t num_bytes);
+// Returns true if an AV1 encoder is available.
+bool Av1EncoderAvailable();
+
+// Returns true if an AV1 decoder is available.
+bool Av1DecoderAvailable();
+
//------------------------------------------------------------------------------
// avifIO overlay