Don't allow chroma sample position to change

The color config (colour primaries, transfer characteristics, matrix
coefficients, color range, and chroma sample position) is part of the
AV1 sequence header OBU, so changes to the color config are not allowed.
Check changes to chroma sample position between two
aomCodecEncodeImage() calls.

Add a test with changes to chroma sample position and color range.
diff --git a/src/write.c b/src/write.c
index 649183e..7de26e4 100644
--- a/src/write.c
+++ b/src/write.c
@@ -1140,7 +1140,9 @@
         // If the first image in the sequence had an alpha plane (even if fully opaque), all
         // subsequent images must have alpha as well.
         if ((imageMetadata->depth != firstCell->depth) || (imageMetadata->yuvFormat != firstCell->yuvFormat) ||
-            (imageMetadata->yuvRange != firstCell->yuvRange) || (imageMetadata->colorPrimaries != firstCell->colorPrimaries) ||
+            (imageMetadata->yuvRange != firstCell->yuvRange) ||
+            (imageMetadata->yuvChromaSamplePosition != firstCell->yuvChromaSamplePosition) ||
+            (imageMetadata->colorPrimaries != firstCell->colorPrimaries) ||
             (imageMetadata->transferCharacteristics != firstCell->transferCharacteristics) ||
             (imageMetadata->matrixCoefficients != firstCell->matrixCoefficients) ||
             (imageMetadata->alphaPremultiplied != firstCell->alphaPremultiplied) ||
diff --git a/tests/gtest/avifchangesettingtest.cc b/tests/gtest/avifchangesettingtest.cc
index e37e346..cf60537 100644
--- a/tests/gtest/avifchangesettingtest.cc
+++ b/tests/gtest/avifchangesettingtest.cc
@@ -154,5 +154,50 @@
             AVIF_RESULT_CANNOT_CHANGE_SETTING);
 }
 
+TEST(ChangeSettingTest, UnchangeableImageMetadata) {
+  const uint32_t image_size = 512;
+  // The first image is full range.
+  testutil::AvifImagePtr image1 =
+      testutil::CreateImage(image_size, image_size, 8, AVIF_PIXEL_FORMAT_YUV420,
+                            AVIF_PLANES_YUV, AVIF_RANGE_FULL);
+  ASSERT_NE(image1, nullptr);
+  testutil::FillImageGradient(image1.get());
+  // The second image is limited range.
+  testutil::AvifImagePtr image2 =
+      testutil::CreateImage(image_size, image_size, 8, AVIF_PIXEL_FORMAT_YUV420,
+                            AVIF_PLANES_YUV, AVIF_RANGE_LIMITED);
+  ASSERT_NE(image2, nullptr);
+  testutil::FillImageGradient(image2.get());
+
+  // Encode
+  testutil::AvifEncoderPtr encoder(avifEncoderCreate(), avifEncoderDestroy);
+  ASSERT_NE(encoder, nullptr);
+  encoder->codecChoice = AVIF_CODEC_CHOICE_AOM;
+  encoder->speed = AVIF_SPEED_FASTEST;
+  encoder->timescale = 1;
+  ASSERT_EQ(encoder->repetitionCount, AVIF_REPETITION_COUNT_INFINITE);
+  encoder->minQuantizer = 63;
+  encoder->maxQuantizer = 63;
+
+  ASSERT_EQ(avifEncoderAddImage(encoder.get(), image1.get(), 1,
+                                AVIF_ADD_IMAGE_FLAG_NONE),
+            AVIF_RESULT_OK);
+
+  ASSERT_EQ(avifEncoderAddImage(encoder.get(), image1.get(), 1,
+                                AVIF_ADD_IMAGE_FLAG_NONE),
+            AVIF_RESULT_OK);
+
+  ASSERT_EQ(image1->yuvChromaSamplePosition,
+            AVIF_CHROMA_SAMPLE_POSITION_UNKNOWN);
+  image1->yuvChromaSamplePosition = AVIF_CHROMA_SAMPLE_POSITION_VERTICAL;
+  ASSERT_EQ(avifEncoderAddImage(encoder.get(), image1.get(), 1,
+                                AVIF_ADD_IMAGE_FLAG_NONE),
+            AVIF_RESULT_INCOMPATIBLE_IMAGE);
+
+  ASSERT_EQ(avifEncoderAddImage(encoder.get(), image2.get(), 1,
+                                AVIF_ADD_IMAGE_FLAG_NONE),
+            AVIF_RESULT_INCOMPATIBLE_IMAGE);
+}
+
 }  // namespace
 }  // namespace libavif