Do not allow keeping the ICC when converting from RGB to gray (#2669)

diff --git a/apps/shared/avifjpeg.c b/apps/shared/avifjpeg.c
index 1b974dc..09bfb64 100644
--- a/apps/shared/avifjpeg.c
+++ b/apps/shared/avifjpeg.c
@@ -909,6 +909,12 @@
         unsigned int iccDataLen;
         if (read_icc_profile(&cinfo, &iccDataTmp, &iccDataLen)) {
             iccData = iccDataTmp;
+            if (requestedFormat == AVIF_PIXEL_FORMAT_YUV400) {
+                fprintf(stderr,
+                        "The image contains an RGB ICC profile which is incompatible with the requested output "
+                        "format YUV400 (grayscale). Pass --ignore-icc to discard the ICC profile.\n");
+                goto cleanup;
+            }
             if (avifImageSetProfileICC(avif, iccDataTmp, (size_t)iccDataLen) != AVIF_RESULT_OK) {
                 fprintf(stderr, "Setting ICC profile failed: %s (out of memory)\n", inputFilename);
                 goto cleanup;
diff --git a/apps/shared/avifpng.c b/apps/shared/avifpng.c
index b1685c8..9727ea9 100644
--- a/apps/shared/avifpng.c
+++ b/apps/shared/avifpng.c
@@ -365,6 +365,13 @@
         // When the sRGB / iCCP chunk is present, applications that recognize it and are capable of color management
         // must ignore the gAMA and cHRM chunks and use the sRGB / iCCP chunk instead.
         if (png_get_iCCP(png, info, &iccpProfileName, &iccpCompression, &iccpData, &iccpDataLen) == PNG_INFO_iCCP) {
+            if (rawColorType != PNG_COLOR_TYPE_GRAY && rawColorType != PNG_COLOR_TYPE_GRAY_ALPHA &&
+                avif->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {
+                fprintf(stderr,
+                        "The image contains an RGB ICC profile which is incompatible with the requested output "
+                        "format YUV400 (grayscale). Pass --ignore-icc to discard the ICC profile.\n");
+                goto cleanup;
+            }
             if (avifImageSetProfileICC(avif, iccpData, iccpDataLen) != AVIF_RESULT_OK) {
                 fprintf(stderr, "Setting ICC profile failed: out of memory.\n");
                 goto cleanup;
diff --git a/tests/gtest/avifreadimagetest.cc b/tests/gtest/avifreadimagetest.cc
index 1126128..68e1285 100644
--- a/tests/gtest/avifreadimagetest.cc
+++ b/tests/gtest/avifreadimagetest.cc
@@ -289,6 +289,34 @@
             0);
 }
 
+// Verify the invalidity of keeping the ICC profile for a gray image read from
+// an RGB image.
+TEST(ICCTest, RGB2Gray) {
+  for (const auto& file_name :
+       {"paris_icc_exif_xmp.png", "paris_exif_xmp_icc.jpg"}) {
+    const std::string file_path = std::string(data_path) + file_name;
+    for (bool ignore_icc : {false, true}) {
+      ImagePtr image(avifImageCreateEmpty());
+      // Read the image.
+      const avifAppFileFormat file_format = avifReadImage(
+          file_path.c_str(),
+          /*requestedFormat=*/AVIF_PIXEL_FORMAT_YUV400,
+          /*requestedDepth=*/0,
+          /*chromaDownsampling=*/AVIF_CHROMA_DOWNSAMPLING_AUTOMATIC,
+          /*ignoreColorProfile=*/ignore_icc, /*ignoreExif=*/false,
+          /*ignoreXMP=*/false, /*allowChangingCicp=*/true,
+          /*ignoreGainMap=*/true, AVIF_DEFAULT_IMAGE_SIZE_LIMIT, image.get(),
+          /*outDepth=*/nullptr, /*sourceTiming=*/nullptr,
+          /*frameIter=*/nullptr);
+      if (ignore_icc) {
+        ASSERT_NE(file_format, AVIF_APP_FILE_FORMAT_UNKNOWN);
+      } else {
+        ASSERT_EQ(file_format, AVIF_APP_FILE_FORMAT_UNKNOWN);
+      }
+    }
+  }
+}
+
 //------------------------------------------------------------------------------
 // Memory management tests
 
diff --git a/tests/test_cmd_grid.sh b/tests/test_cmd_grid.sh
index 4418a09..f5e3f6e 100755
--- a/tests/test_cmd_grid.sh
+++ b/tests/test_cmd_grid.sh
@@ -44,7 +44,7 @@
   "${AVIFDEC}" "${ENCODED_FILE_2x2}" "${DECODED_FILE_2x2}"
 
   echo "Testing monochrome grid with odd width (403 px)"
-  "${AVIFENC}" -s 8 "${INPUT_PNG}" --grid 2x2 --yuv 400 -o "${ENCODED_FILE_2x2}"
+  "${AVIFENC}" -s 8 "${INPUT_PNG}" --grid 2x2 --yuv 400 --ignore-icc -o "${ENCODED_FILE_2x2}"
   "${AVIFDEC}" "${ENCODED_FILE_2x2}" "${DECODED_FILE_2x2}"
 
   echo "Testing max grid"
diff --git a/tests/test_cmd_icc_profile.sh b/tests/test_cmd_icc_profile.sh
index 7e06acb..bb161ad 100755
--- a/tests/test_cmd_icc_profile.sh
+++ b/tests/test_cmd_icc_profile.sh
@@ -24,6 +24,8 @@
 INPUT_GRAY_PNG="${TESTDATA_DIR}/kodim03_grayscale_gamma1.6.png"
 REFERENCE_GRAY_PNG="${TESTDATA_DIR}/kodim03_grayscale_gamma1.6-reference.png"
 SRGB_ICC="${TESTDATA_DIR}/sRGB2014.icc"
+INPUT_ICC_PNG="${TESTDATA_DIR}/paris_icc_exif_xmp.png"
+INPUT_ICC_JPG="${TESTDATA_DIR}/paris_exif_xmp_icc.jpg"
 # Output file names.
 ENCODED_FILE="avif_test_cmd_icc_profile_encoded.avif"
 DECODED_FILE="avif_test_cmd_icc_profile_decoded.png"
@@ -44,6 +46,12 @@
   "${AVIFDEC}" "${ENCODED_FILE}" "${DECODED_FILE}" | grep "Transfer Char.* 12$"
   "${AVIFDEC}" "${ENCODED_FILE}" "${DECODED_FILE}" | grep "Matrix Coeffs.* 8$"
 
+  # RGB ICC cannot be kept when asking for gray.
+  "${AVIFENC}" -s 10 "${INPUT_ICC_JPG}" --yuv 400 -o "${ENCODED_FILE}" && exit 1
+  "${AVIFENC}" -s 10 "${INPUT_ICC_PNG}" --yuv 400 -o "${ENCODED_FILE}" && exit 1
+  "${AVIFENC}" -s 10 "${INPUT_ICC_JPG}" --yuv 400 --ignore-icc -o "${ENCODED_FILE}"
+  "${AVIFENC}" -s 10 "${INPUT_ICC_PNG}" --yuv 400 --ignore-icc -o "${ENCODED_FILE}"
+
   # We use third-party tool (ImageMagick) to independently check
   # our generated ICC profile is valid and correct.
   if command -v magick &> /dev/null