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