Add avifalphapremtest

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 765880a..11d1173 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -75,6 +75,11 @@
     target_include_directories(avifallocationtest PRIVATE ${GTEST_INCLUDE_DIRS})
     add_test(NAME avifallocationtest COMMAND avifallocationtest)
 
+    add_executable(avifalphapremtest gtest/avifalphapremtest.cc)
+    target_link_libraries(avifalphapremtest aviftest_helpers ${GTEST_BOTH_LIBRARIES})
+    target_include_directories(avifalphapremtest PRIVATE ${GTEST_INCLUDE_DIRS})
+    add_test(NAME avifalphapremtest COMMAND avifalphapremtest)
+
     add_executable(avifchangesettingtest gtest/avifchangesettingtest.cc)
     target_link_libraries(avifchangesettingtest aviftest_helpers ${GTEST_BOTH_LIBRARIES})
     target_include_directories(avifchangesettingtest PRIVATE ${GTEST_INCLUDE_DIRS})
diff --git a/tests/gtest/avifalphapremtest.cc b/tests/gtest/avifalphapremtest.cc
new file mode 100644
index 0000000..b8c97a3
--- /dev/null
+++ b/tests/gtest/avifalphapremtest.cc
@@ -0,0 +1,66 @@
+// Copyright 2022 Google LLC
+// SPDX-License-Identifier: BSD-2-Clause
+
+#include "avif/avif.h"
+#include "aviftest_helpers.h"
+#include "gtest/gtest.h"
+
+namespace libavif {
+namespace {
+
+//------------------------------------------------------------------------------
+
+TEST(AlphaMultiplyTest, OpaqueIsNoOp) {
+  for (bool premultiplied_input : {false, true}) {
+    if (!premultiplied_input) {
+      // TODO(yguyon): Fix the issue and remove this condition.
+      //               The issue is that avifPrepareReformatState() will result
+      //               in different YUV(A)-to-RGB conversion algorithm choices
+      //               (built-in or libyuv) depending on the presence of an
+      //               alpha channel, no matter if it is opaque or not, because
+      //               it considers that unpremultiplied YUVA samples should be
+      //               premultiplied before discarding alpha and converting to
+      //               RGB.
+      continue;
+    }
+
+    // YUVA.
+    testutil::AvifImagePtr opaque_alpha = testutil::CreateImage(
+        1024, 1024, /*depth=*/8, AVIF_PIXEL_FORMAT_YUV444, AVIF_PLANES_ALL);
+    const uint32_t yuva[] = {255, 255, 255, 255};
+    testutil::FillImagePlain(opaque_alpha.get(), yuva);
+    opaque_alpha->alphaPremultiplied = premultiplied_input;
+
+    // View on YUV (no alpha), to make sure the color values are identical.
+    testutil::AvifImagePtr no_alpha(avifImageCreateEmpty(), avifImageDestroy);
+    const avifCropRect rect = {0, 0, opaque_alpha->width, opaque_alpha->height};
+    ASSERT_EQ(avifImageSetViewRect(no_alpha.get(), opaque_alpha.get(), &rect),
+              AVIF_RESULT_OK);
+    avifImageFreePlanes(no_alpha.get(), AVIF_PLANES_A);
+
+    // Decorrelate YUV and Alpha.
+    testutil::FillImageGradient(no_alpha.get());
+
+    // Convert to RGB and discard any Alpha.
+    testutil::AvifRgbImage opaque_rgb(opaque_alpha.get(), opaque_alpha->depth,
+                                      AVIF_RGB_FORMAT_RGB);
+    ASSERT_EQ(avifImageYUVToRGB(opaque_alpha.get(), &opaque_rgb),
+              AVIF_RESULT_OK);
+    testutil::AvifRgbImage no_alpha_rgb(no_alpha.get(), no_alpha->depth,
+                                        AVIF_RGB_FORMAT_RGB);
+    ASSERT_EQ(avifImageYUVToRGB(no_alpha.get(), &no_alpha_rgb), AVIF_RESULT_OK);
+
+    // YUV samples with opaque alpha and with missing alpha should be converted
+    // to the same RGB values.
+    EXPECT_TRUE(testutil::AreByteSequencesEqual(
+        opaque_rgb.pixels, opaque_rgb.height * opaque_rgb.rowBytes,
+        no_alpha_rgb.pixels, no_alpha_rgb.height * no_alpha_rgb.rowBytes));
+
+    // TODO(yguyon): Also compare avifImageYUVToRGB() with ignoreAlpha.
+  }
+}
+
+//------------------------------------------------------------------------------
+
+}  // namespace
+}  // namespace libavif