Reapply "Check that the gain map metadata is valid on decoding." (#2493)
This reverts commit aa9f74068981e6d4f00abc17cf721a5555f8303c.
diff --git a/src/read.c b/src/read.c
index 7808634..f85868c 100644
--- a/src/read.c
+++ b/src/read.c
@@ -2070,6 +2070,11 @@
if (writerVersion <= supportedMetadataVersion) {
AVIF_CHECKERR(avifROStreamRemainingBytes(&s) == 0, AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE);
}
+
+ if (avifGainMapValidateMetadata(gainMap, diag) != AVIF_RESULT_OK) {
+ return AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE;
+ }
+
return AVIF_RESULT_OK;
}
#endif // AVIF_ENABLE_EXPERIMENTAL_GAIN_MAP
diff --git a/tests/data/README.md b/tests/data/README.md
index 6d8a2fe..4ea64be 100644
--- a/tests/data/README.md
+++ b/tests/data/README.md
@@ -654,6 +654,18 @@
An image with a `tmap` item (i.e. a gain map) but no 'tmap' brand in the `ftyp` box.
The gain map should be ignored by the decoder since the `tmap` brand is missing.
+### File [seine_sdr_gainmap_gammazero.avif](seine_sdr_gainmap_gammazero.avif)
+
+
+
+License: [same as libavif](https://github.com/AOMediaCodec/libavif/blob/main/LICENSE)
+
+Source : same as seine_sdr_gainmap_srgb.avif generated with a modified avifenc that
+writes 0 instead of the gain map gamma numerator.
+
+An image with a gain map where the gain map gamma value is zero (invalid).
+
+
### File [seine_sdr_gainmap_big_srgb.avif](seine_sdr_gainmap_big_srgb.avif)

diff --git a/tests/data/seine_sdr_gainmap_gammazero.avif b/tests/data/seine_sdr_gainmap_gammazero.avif
new file mode 100644
index 0000000..eb34fdc
--- /dev/null
+++ b/tests/data/seine_sdr_gainmap_gammazero.avif
Binary files differ
diff --git a/tests/gtest/avifgainmaptest.cc b/tests/gtest/avifgainmaptest.cc
index 9f0f50c..14e6f5c 100644
--- a/tests/gtest/avifgainmaptest.cc
+++ b/tests/gtest/avifgainmaptest.cc
@@ -819,6 +819,19 @@
ASSERT_EQ(decoded->gainMap, nullptr);
}
+TEST(GainMapTest, DecodeInvalidGamma) {
+ const std::string path =
+ std::string(data_path) + "seine_sdr_gainmap_gammazero.avif";
+ ImagePtr decoded(avifImageCreateEmpty());
+ ASSERT_NE(decoded, nullptr);
+ DecoderPtr decoder(avifDecoderCreate());
+ ASSERT_NE(decoder, nullptr);
+ decoder->imageContentToDecode |= AVIF_IMAGE_CONTENT_GAIN_MAP;
+ // Fails to decode: invalid because the gain map gamma is zero.
+ ASSERT_EQ(avifDecoderReadFile(decoder.get(), decoded.get(), path.c_str()),
+ AVIF_RESULT_INVALID_TONE_MAPPED_IMAGE);
+}
+
#define EXPECT_FRACTION_NEAR(numerator, denominator, expected) \
EXPECT_NEAR(std::abs((double)numerator / denominator), expected, \
expected * 0.001);