Avoid issue AOMediaCodec/libavif#2886
avifRGBImagePremultiplyAlpha() and avifRGBImageUnpremultiplyAlpha()
assume four-channel pixel buffers, so they would overrun the two-channel
pixel buffer in an avifRGBImage of the AVIF_RGB_FORMAT_GRAYA or
AVIF_RGB_FORMAT_AGRAY format. Return AVIF_RESULT_NOT_IMPLEMENTED before
this bug is fixed.
The bug was reported by Harrison Green.
Avoids https://github.com/AOMediaCodec/libavif/issues/2886.
diff --git a/src/alpha.c b/src/alpha.c
index f73400a..ec4976f 100644
--- a/src/alpha.c
+++ b/src/alpha.c
@@ -165,6 +165,10 @@
return libyuvResult;
}
+ if (rgb->format == AVIF_RGB_FORMAT_GRAYA || rgb->format == AVIF_RGB_FORMAT_AGRAY) {
+ return AVIF_RESULT_NOT_IMPLEMENTED;
+ }
+
assert(rgb->depth >= 8 && rgb->depth <= 16);
uint32_t max = (1 << rgb->depth) - 1;
@@ -280,6 +284,10 @@
return libyuvResult;
}
+ if (rgb->format == AVIF_RGB_FORMAT_GRAYA || rgb->format == AVIF_RGB_FORMAT_AGRAY) {
+ return AVIF_RESULT_NOT_IMPLEMENTED;
+ }
+
assert(rgb->depth >= 8 && rgb->depth <= 16);
uint32_t max = (1 << rgb->depth) - 1;
diff --git a/tests/gtest/avifalphapremtest.cc b/tests/gtest/avifalphapremtest.cc
index 5c8bf8e..a1dc2fd 100644
--- a/tests/gtest/avifalphapremtest.cc
+++ b/tests/gtest/avifalphapremtest.cc
@@ -1,6 +1,8 @@
// Copyright 2022 Google LLC
// SPDX-License-Identifier: BSD-2-Clause
+#include <string.h>
+
#include "avif/avif.h"
#include "aviftest_helpers.h"
#include "gtest/gtest.h"
@@ -61,6 +63,22 @@
}
}
+TEST(AlphaMultiplyTest, GrayAImagePremultiplyAlpha) {
+ avifRGBImage rgb;
+ memset(&rgb, 0, sizeof(rgb));
+ rgb.width = 6;
+ rgb.height = 1;
+ rgb.depth = 10;
+ rgb.format = AVIF_RGB_FORMAT_GRAYA; // 2 channels with alpha
+ ASSERT_EQ(avifRGBImageAllocatePixels(&rgb), AVIF_RESULT_OK);
+ memset(rgb.pixels, 1, (size_t)rgb.rowBytes * rgb.height);
+ // avifRGBImagePremultiplyAlpha assumes 4 channels and would overrun the
+ // 2-channel buffer. Until this bug (issue #2886) is fixed, it should return
+ // AVIF_RESULT_NOT_IMPLEMENTED.
+ EXPECT_EQ(avifRGBImagePremultiplyAlpha(&rgb), AVIF_RESULT_NOT_IMPLEMENTED);
+ avifRGBImageFreePixels(&rgb);
+}
+
//------------------------------------------------------------------------------
} // namespace