Add the ignoreICC option to avifDecoder

This allows us to remove the ignoreColorProfile parameter from the
avifImageCreateView() function.

There is a change of behavior to avifdec:
The message "[--ignore-icc] Discarding ICC profile.\n" won't be printed
if the --ignore-icc or --icc option is specified and the image has an
ICC profile.

Bug: https://github.com/AOMediaCodec/libavif/issues/3277
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 510cc2d..f567966 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@
 
 ### Added since 1.4.2
 
+* Add the ignoreICC option to avifDecoder
 * avifenc: add --ignore-alpha flag to discard alpha channel on encode
 * avifgainmaputil: add --ignore-alpha flag to discard alpha channel
 
@@ -25,6 +26,9 @@
 * Fix printed gain map size in avifenc when converting a jpeg with a gain map
   and using --grid.
 * Allow setting avifDecoder::imageSizeLimit to any value.
+* avifdec: The message "[--ignore-icc] Discarding ICC profile.\n" won't be
+  printed if the --ignore-icc or --icc option is specified and the image has an
+  ICC profile.
 
 ## [1.4.2] - 2026-05-26
 
diff --git a/apps/avifdec.c b/apps/avifdec.c
index 25880ea..4176152 100644
--- a/apps/avifdec.c
+++ b/apps/avifdec.c
@@ -321,6 +321,7 @@
     } else if (enableSampleTransforms) {
         decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_SAMPLE_TRANSFORMS;
     }
+    decoder->ignoreICC = ignoreICC;
 
     avifResult result = avifDecoderSetIOFile(decoder, inputFilename);
     if (result != AVIF_RESULT_OK) {
@@ -405,30 +406,25 @@
             }
         }
 
-        if (ignoreICC) {
+        assert(!ignoreICC || decoder->image->icc.size == 0);
+        if (iccOverrideFilename) {
             imageView = avifImageCreateEmpty();
             if (!imageView) {
                 fprintf(stderr, "ERROR: Out of memory\n");
                 goto cleanup;
             }
-            if (decoder->image->icc.size > 0) {
-                printf("[--ignore-icc] Discarding ICC profile.\n");
-            }
             result = avifImageCreateView(imageView,
                                          decoder->image,
-                                         /*ignoreColorProfile=*/AVIF_TRUE,
                                          /*ignoreAlpha=*/AVIF_FALSE);
             if (result != AVIF_RESULT_OK) {
                 fprintf(stderr, "ERROR: Failed to create image view\n");
                 goto cleanup;
             }
-            if (iccOverrideFilename) {
-                printf("[--icc] Setting ICC profile: %s\n", iccOverrideFilename);
-                result = avifImageSetProfileICC(imageView, iccOverride.data, iccOverride.size);
-                if (result != AVIF_RESULT_OK) {
-                    fprintf(stderr, "ERROR: Failed to set ICC: %s\n", avifResultToString(result));
-                    goto cleanup;
-                }
+            printf("[--icc] Setting ICC profile: %s\n", iccOverrideFilename);
+            result = avifImageSetProfileICC(imageView, iccOverride.data, iccOverride.size);
+            if (result != AVIF_RESULT_OK) {
+                fprintf(stderr, "ERROR: Failed to set ICC: %s\n", avifResultToString(result));
+                goto cleanup;
             }
         } else {
             imageView = decoder->image;
diff --git a/apps/avifgainmaputil/extractgainmap_command.cc b/apps/avifgainmaputil/extractgainmap_command.cc
index ccb0da7..31b766d 100644
--- a/apps/avifgainmaputil/extractgainmap_command.cc
+++ b/apps/avifgainmaputil/extractgainmap_command.cc
@@ -25,6 +25,7 @@
   }
   decoder->maxThreads = arg_jobs_.jobs.value();
   decoder->imageContentToDecode = AVIF_IMAGE_CONTENT_GAIN_MAP;
+  decoder->ignoreICC = true;
 
   avifResult result = ReadAvif(decoder.get(), arg_input_filename_);
   if (result != AVIF_RESULT_OK) {
@@ -36,7 +37,6 @@
     return AVIF_RESULT_OUT_OF_MEMORY;
   }
   result = avifImageCreateView(image.get(), decoder->image,
-                               /*ignoreColorProfile=*/true,
                                /*ignoreAlpha=*/false);
   if (result != AVIF_RESULT_OK) {
     return result;
diff --git a/apps/avifgainmaputil/imageio.cc b/apps/avifgainmaputil/imageio.cc
index 329831e..5e2fc53 100644
--- a/apps/avifgainmaputil/imageio.cc
+++ b/apps/avifgainmaputil/imageio.cc
@@ -3,6 +3,7 @@
 
 #include "imageio.h"
 
+#include <cassert>
 #include <cstring>
 #include <fstream>
 #include <iostream>
@@ -201,10 +202,11 @@
     if (decoder == nullptr) {
       return AVIF_RESULT_OUT_OF_MEMORY;
     }
+    decoder->maxThreads = jobs;
     if (!ignore_gain_map) {
       decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
     }
-    decoder->maxThreads = jobs;
+    decoder->ignoreICC = ignore_profile;
     avifResult result = ReadAvif(decoder.get(), input_filename);
     if (result != AVIF_RESULT_OK) {
       return result;
@@ -214,8 +216,7 @@
     if (!view) {
       return AVIF_RESULT_OUT_OF_MEMORY;
     }
-    result = avifImageCreateView(view.get(), decoder->image, ignore_profile,
-                                 ignore_alpha);
+    result = avifImageCreateView(view.get(), decoder->image, ignore_alpha);
     if (result != AVIF_RESULT_OK) {
       return result;
     }
@@ -284,6 +285,12 @@
               << " (" << decoder->diag.error << ")\n";
     return result;
   }
+  if (decoder->ignoreICC) {
+    assert(decoder->image->icc.size == 0);
+    if (decoder->image->gainMap) {
+      assert(decoder->image->gainMap->altICC.size == 0);
+    }
+  }
 
   return AVIF_RESULT_OK;
 }
diff --git a/apps/avifgainmaputil/swapbase_command.cc b/apps/avifgainmaputil/swapbase_command.cc
index 3dd6c43..14432a9 100644
--- a/apps/avifgainmaputil/swapbase_command.cc
+++ b/apps/avifgainmaputil/swapbase_command.cc
@@ -165,6 +165,7 @@
   }
   decoder->maxThreads = arg_jobs_.jobs.value();
   decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
+  decoder->ignoreICC = arg_image_read_.ignore_profile;
   avifResult result = ReadAvif(decoder.get(), arg_input_filename_);
   if (result != AVIF_RESULT_OK) {
     return result;
@@ -175,7 +176,6 @@
     return AVIF_RESULT_OUT_OF_MEMORY;
   }
   result = avifImageCreateView(image.get(), decoder->image,
-                               arg_image_read_.ignore_profile,
                                arg_image_read_.ignore_alpha);
   if (result != AVIF_RESULT_OK) {
     return result;
diff --git a/apps/avifgainmaputil/tonemap_command.cc b/apps/avifgainmaputil/tonemap_command.cc
index 8b36c58..fa40592 100644
--- a/apps/avifgainmaputil/tonemap_command.cc
+++ b/apps/avifgainmaputil/tonemap_command.cc
@@ -67,6 +67,7 @@
   }
   decoder->maxThreads = arg_jobs_.jobs.value();
   decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
+  decoder->ignoreICC = arg_image_read_.ignore_profile;
   avifResult result = ReadAvif(decoder.get(), arg_input_filename_);
   if (result != AVIF_RESULT_OK) {
     return result;
@@ -77,7 +78,6 @@
     return AVIF_RESULT_OUT_OF_MEMORY;
   }
   result = avifImageCreateView(image.get(), decoder->image,
-                               arg_image_read_.ignore_profile,
                                arg_image_read_.ignore_alpha);
   if (result != AVIF_RESULT_OK) {
     return result;
diff --git a/apps/shared/avifutil.c b/apps/shared/avifutil.c
index 61a6f12..20e47b7 100644
--- a/apps/shared/avifutil.c
+++ b/apps/shared/avifutil.c
@@ -824,7 +824,7 @@
     return AVIF_RESULT_OK;
 }
 
-avifResult avifImageCreateView(avifImage * dstImage, const avifImage * srcImage, avifBool ignoreColorProfile, avifBool ignoreAlpha)
+avifResult avifImageCreateView(avifImage * dstImage, const avifImage * srcImage, avifBool ignoreAlpha)
 {
     avifResult res = AVIF_RESULT_OK;
     if (!dstImage || !srcImage) {
@@ -841,7 +841,7 @@
         avifImageFreePlanes(dstImage, AVIF_PLANES_A);
     }
 
-    if (!ignoreColorProfile) {
+    if (srcImage->icc.size > 0) {
         res = avifImageSetProfileICC(dstImage, srcImage->icc.data, srcImage->icc.size);
         if (res != AVIF_RESULT_OK) {
             return res;
@@ -889,7 +889,7 @@
         dstImage->gainMap->altICC.data = NULL;
         dstImage->gainMap->altICC.size = 0;
 
-        if (!ignoreColorProfile && srcImage->gainMap->altICC.size > 0) {
+        if (srcImage->gainMap->altICC.size > 0) {
             res = avifRWDataSet(&dstImage->gainMap->altICC, srcImage->gainMap->altICC.data, srcImage->gainMap->altICC.size);
             if (res != AVIF_RESULT_OK) {
                 return res;
@@ -903,7 +903,6 @@
             }
             res = avifImageCreateView(dstImage->gainMap->image,
                                       srcImage->gainMap->image,
-                                      ignoreColorProfile,
                                       /*ignoreAlpha=*/AVIF_TRUE);
             if (res != AVIF_RESULT_OK) {
                 return res;
diff --git a/apps/shared/avifutil.h b/apps/shared/avifutil.h
index e99f9d5..cfa1da5 100644
--- a/apps/shared/avifutil.h
+++ b/apps/shared/avifutil.h
@@ -132,7 +132,7 @@
 // If a gain map is present in 'srcImage', the gain map of 'dstImage' is also set to
 // a view of the original gain map.
 // 'dstImage' should be an empty image. It will not own the pixel data.
-avifResult avifImageCreateView(avifImage * dstImage, const avifImage * srcImage, avifBool ignoreColorProfile, avifBool ignoreAlpha);
+avifResult avifImageCreateView(avifImage * dstImage, const avifImage * srcImage, avifBool ignoreAlpha);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/include/avif/avif.h b/include/avif/avif.h
index 27baf2f..faab302 100644
--- a/include/avif/avif.h
+++ b/include/avif/avif.h
@@ -1384,6 +1384,10 @@
 
     // Version 1.2.0 ends here. Add any new members after this line.
     // --------------------------------------------------------------------------------------------
+
+    // Enable this to avoid reading and surfacing ICC profile to the decoded avifImage and gain map
+    // metadata.
+    avifBool ignoreICC;
 } avifDecoder;
 
 // Creates a decoder initialized with default settings values.
diff --git a/src/read.c b/src/read.c
index 0d823e2..fb8226f 100644
--- a/src/read.c
+++ b/src/read.c
@@ -5648,7 +5648,7 @@
 
 // On success, this function returns AVIF_RESULT_OK and does the following:
 // * If a colr property was found in |properties|:
-//   - Read the icc data into |icc| from |io|.
+//   - If |icc| is not null, reads the icc data into |icc| from |io|.
 //   - Sets the CICP values as documented in avifReadColorNclxProperty().
 // This function fails if more than one icc or nclx property is found in
 // |properties|. The output parameters may be populated even in case of failure
@@ -5671,10 +5671,12 @@
             if (colrICCSeen) {
                 return AVIF_RESULT_BMFF_PARSE_FAILED;
             }
-            avifROData iccRead;
-            AVIF_CHECKRES(io->read(io, 0, prop->u.colr.iccOffset, prop->u.colr.iccSize, &iccRead));
+            if (icc) {
+                avifROData iccRead;
+                AVIF_CHECKRES(io->read(io, 0, prop->u.colr.iccOffset, prop->u.colr.iccSize, &iccRead));
+                AVIF_CHECKRES(avifRWDataSet(icc, iccRead.data, iccRead.size));
+            }
             colrICCSeen = AVIF_TRUE;
-            AVIF_CHECKRES(avifRWDataSet(icc, iccRead.data, iccRead.size));
         }
     }
     return avifReadColorNclxProperty(properties, colorPrimaries, transferCharacteristics, matrixCoefficients, yuvRange, cicpSet);
@@ -5818,7 +5820,7 @@
     // This may allocate gainMapTmp.altICC which must be freed in case of error.
     result = avifReadColorProperties(decoder->io,
                                      &toneMappedImageItemTmp->properties,
-                                     &gainMapTmp.altICC,
+                                     decoder->ignoreICC ? NULL : &gainMapTmp.altICC,
                                      &gainMapTmp.altColorPrimaries,
                                      &gainMapTmp.altTransferCharacteristics,
                                      &gainMapTmp.altMatrixCoefficients,
@@ -6548,7 +6550,7 @@
 
     AVIF_CHECKRES(avifReadColorProperties(decoder->io,
                                           colorProperties,
-                                          &decoder->image->icc,
+                                          decoder->ignoreICC ? NULL : &decoder->image->icc,
                                           &decoder->image->colorPrimaries,
                                           &decoder->image->transferCharacteristics,
                                           &decoder->image->matrixCoefficients,
diff --git a/tests/gtest/avifmetadatatest.cc b/tests/gtest/avifmetadatatest.cc
index e54ed7a..28dfb26 100644
--- a/tests/gtest/avifmetadatatest.cc
+++ b/tests/gtest/avifmetadatatest.cc
@@ -215,6 +215,14 @@
   EXPECT_EQ(decoder->image->icc.data[2], 2);
   EXPECT_EQ(decoder->image->icc.data[3], 84);
   avifDecoderDestroy(decoder);
+
+  decoder = avifDecoderCreate();
+  ASSERT_NE(decoder, nullptr);
+  decoder->ignoreICC = true;
+  EXPECT_EQ(avifDecoderSetIOFile(decoder, file_path.c_str()), AVIF_RESULT_OK);
+  EXPECT_EQ(avifDecoderParse(decoder), AVIF_RESULT_OK);
+  ASSERT_EQ(decoder->image->icc.size, 0u);
+  avifDecoderDestroy(decoder);
 }
 
 //------------------------------------------------------------------------------