New CMake options: AVIF_CODEC_AOM_DECODE, AVIF_CODEC_AOM_ENCODE
These allow for someone to only use/link against libaom for its encode or decode capabilities,
instead of being forced to link against both.
Also, I removed the Open codec implementations for SVT and rav1e and documented in the internal
header that Open is just for the decode path. (That function could probably use a rename.)
avifCodecVersions() now also hints at what each compiled-in codec is actually offering (enc and/or dec).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b8cd9f..bc4ff46 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,10 @@
option(AVIF_LOCAL_RAV1E "Build the rav1e codec by providing your own copy of the repo in ext/rav1e (see Local Builds in README)" OFF)
option(AVIF_LOCAL_SVT "Build the SVT-AV1 codec by providing your own copy of the repo in ext/SVT-AV1 (see Local Builds in README)" OFF)
+# These options allow libavif to only link against / use libaom's encoder or decoder, instead of being forced to use both
+option(AVIF_CODEC_AOM_DECODE "if AVIF_CODEC_AOM is on, use/offer libaom's decoder" ON)
+option(AVIF_CODEC_AOM_ENCODE "if AVIF_CODEC_AOM is on, use/offer libaom's encoder" ON)
+
if(AVIF_LOCAL_LIBGAV1)
enable_language(CXX)
endif()
@@ -338,7 +342,18 @@
endif()
if(AVIF_CODEC_AOM)
- message(STATUS "libavif: Codec enabled: aom (encode/decode)")
+ if(AVIF_CODEC_AOM_ENCODE AND AVIF_CODEC_AOM_DECODE)
+ message(STATUS "libavif: Codec enabled: aom (encode/decode)")
+ set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_ENCODE=1 -DAVIF_CODEC_AOM_DECODE=1)
+ elseif(AVIF_CODEC_AOM_ENCODE)
+ message(STATUS "libavif: Codec enabled: aom (encode only)")
+ set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_ENCODE=1)
+ elseif(AVIF_CODEC_AOM_DECODE)
+ message(STATUS "libavif: Codec enabled: aom (decode only)")
+ set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM_DECODE=1)
+ else()
+ message(FATAL_ERROR "libavif: AVIF_CODEC_AOM is on, but both AVIF_CODEC_AOM_ENCODE and AVIF_CODEC_AOM_DECODE are off. Disable AVIF_CODEC_AOM to disable both parts of the codec.")
+ endif()
set(AVIF_CODEC_DEFINITIONS ${AVIF_CODEC_DEFINITIONS} -DAVIF_CODEC_AOM=1)
set(AVIF_SRCS ${AVIF_SRCS}
src/codec_aom.c
diff --git a/include/avif/internal.h b/include/avif/internal.h
index 5e8ada7..605c92a 100644
--- a/include/avif/internal.h
+++ b/include/avif/internal.h
@@ -160,7 +160,7 @@
struct avifCodec;
struct avifCodecInternal;
-typedef avifBool (*avifCodecOpenFunc)(struct avifCodec * codec);
+typedef avifBool (*avifCodecOpenFunc)(struct avifCodec * codec); // decode only
typedef avifBool (*avifCodecGetNextImageFunc)(struct avifCodec * codec, const avifDecodeSample * sample, avifBool alpha, avifImage * image);
// EncodeImage and EncodeFinish are not required to always emit a sample, but when all images are
// encoded and EncodeFinish is called, the number of samples emitted must match the number of submitted frames.
diff --git a/src/avif.c b/src/avif.c
index 95b4bdb..08ae313 100644
--- a/src/avif.c
+++ b/src/avif.c
@@ -470,7 +470,18 @@
{ AVIF_CODEC_CHOICE_LIBGAV1, "libgav1", avifCodecVersionGav1, avifCodecCreateGav1, AVIF_CODEC_FLAG_CAN_DECODE },
#endif
#if defined(AVIF_CODEC_AOM)
- { AVIF_CODEC_CHOICE_AOM, "aom", avifCodecVersionAOM, avifCodecCreateAOM, AVIF_CODEC_FLAG_CAN_DECODE | AVIF_CODEC_FLAG_CAN_ENCODE },
+ { AVIF_CODEC_CHOICE_AOM,
+ "aom",
+ avifCodecVersionAOM,
+ avifCodecCreateAOM,
+#if defined(AVIF_CODEC_AOM_DECODE) && defined(AVIF_CODEC_AOM_ENCODE)
+ AVIF_CODEC_FLAG_CAN_DECODE | AVIF_CODEC_FLAG_CAN_ENCODE
+#elif defined(AVIF_CODEC_AOM_DECODE)
+ AVIF_CODEC_FLAG_CAN_DECODE
+#elif defined(AVIF_CODEC_AOM_ENCODE)
+ AVIF_CODEC_FLAG_CAN_ENCODE
+#endif
+ },
#endif
#if defined(AVIF_CODEC_RAV1E)
{ AVIF_CODEC_CHOICE_RAV1E, "rav1e", avifCodecVersionRav1e, avifCodecCreateRav1e, AVIF_CODEC_FLAG_CAN_ENCODE },
@@ -549,6 +560,14 @@
append(&writePos, &remainingLen, ", ");
}
append(&writePos, &remainingLen, availableCodecs[i].name);
+ if ((availableCodecs[i].flags & (AVIF_CODEC_FLAG_CAN_ENCODE | AVIF_CODEC_FLAG_CAN_DECODE)) ==
+ (AVIF_CODEC_FLAG_CAN_ENCODE | AVIF_CODEC_FLAG_CAN_DECODE)) {
+ append(&writePos, &remainingLen, " [enc/dec]");
+ } else if (availableCodecs[i].flags & AVIF_CODEC_FLAG_CAN_ENCODE) {
+ append(&writePos, &remainingLen, " [enc]");
+ } else if (availableCodecs[i].flags & AVIF_CODEC_FLAG_CAN_DECODE) {
+ append(&writePos, &remainingLen, " [dec]");
+ }
append(&writePos, &remainingLen, ":");
append(&writePos, &remainingLen, availableCodecs[i].version());
}
diff --git a/src/codec_aom.c b/src/codec_aom.c
index fcdeab6..f5a0591 100644
--- a/src/codec_aom.c
+++ b/src/codec_aom.c
@@ -11,10 +11,15 @@
#pragma clang diagnostic ignored "-Wused-but-marked-unused"
#endif
-#include "aom/aom_decoder.h"
+#if defined(AVIF_CODEC_AOM_ENCODE)
#include "aom/aom_encoder.h"
#include "aom/aomcx.h"
+#endif
+
+#if defined(AVIF_CODEC_AOM_DECODE)
+#include "aom/aom_decoder.h"
#include "aom/aomdx.h"
+#endif
#ifdef __clang__
#pragma clang diagnostic pop
@@ -31,29 +36,39 @@
struct avifCodecInternal
{
+#if defined(AVIF_CODEC_AOM_DECODE)
avifBool decoderInitialized;
aom_codec_ctx_t decoder;
aom_codec_iter_t iter;
aom_image_t * image;
+#endif
+#if defined(AVIF_CODEC_AOM_ENCODE)
avifBool encoderInitialized;
aom_codec_ctx_t encoder;
avifPixelFormatInfo formatInfo;
aom_img_fmt_t aomFormat;
avifBool monochromeEnabled;
+#endif
};
static void aomCodecDestroyInternal(avifCodec * codec)
{
+#if defined(AVIF_CODEC_AOM_DECODE)
if (codec->internal->decoderInitialized) {
aom_codec_destroy(&codec->internal->decoder);
}
+#endif
+
+#if defined(AVIF_CODEC_AOM_ENCODE)
if (codec->internal->encoderInitialized) {
aom_codec_destroy(&codec->internal->encoder);
}
avifFree(codec->internal);
+#endif
}
+#if defined(AVIF_CODEC_AOM_DECODE)
static avifBool aomCodecOpen(struct avifCodec * codec)
{
aom_codec_iface_t * decoder_interface = aom_codec_av1_dx();
@@ -184,6 +199,9 @@
return AVIF_TRUE;
}
+#endif // defined(AVIF_CODEC_AOM_DECODE)
+
+#if defined(AVIF_CODEC_AOM_ENCODE)
static aom_img_fmt_t avifImageCalcAOMFmt(const avifImage * image, avifBool alpha)
{
@@ -605,6 +623,8 @@
return AVIF_TRUE;
}
+#endif // defined(AVIF_CODEC_AOM_ENCODE)
+
const char * avifCodecVersionAOM(void)
{
return aom_codec_version_str();
@@ -614,12 +634,18 @@
{
avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec));
memset(codec, 0, sizeof(struct avifCodec));
+
+#if defined(AVIF_CODEC_AOM_DECODE)
codec->open = aomCodecOpen;
codec->getNextImage = aomCodecGetNextImage;
+#endif
+
+#if defined(AVIF_CODEC_AOM_ENCODE)
codec->encodeImage = aomCodecEncodeImage;
codec->encodeFinish = aomCodecEncodeFinish;
- codec->destroyInternal = aomCodecDestroyInternal;
+#endif
+ codec->destroyInternal = aomCodecDestroyInternal;
codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal));
memset(codec->internal, 0, sizeof(struct avifCodecInternal));
return codec;
diff --git a/src/codec_rav1e.c b/src/codec_rav1e.c
index c0d18c6..c672b8f 100644
--- a/src/codec_rav1e.c
+++ b/src/codec_rav1e.c
@@ -23,12 +23,6 @@
avifFree(codec->internal);
}
-static avifBool rav1eCodecOpen(struct avifCodec * codec)
-{
- codec->internal->rav1eContext = NULL;
- return AVIF_TRUE;
-}
-
// Official support wasn't added until v0.4.0
static avifBool rav1eSupports400(void)
{
@@ -271,7 +265,6 @@
{
avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec));
memset(codec, 0, sizeof(struct avifCodec));
- codec->open = rav1eCodecOpen;
codec->encodeImage = rav1eCodecEncodeImage;
codec->encodeFinish = rav1eCodecEncodeFinish;
codec->destroyInternal = rav1eCodecDestroyInternal;
diff --git a/src/codec_svt.c b/src/codec_svt.c
index d86866a..434dae1 100644
--- a/src/codec_svt.c
+++ b/src/codec_svt.c
@@ -24,13 +24,6 @@
static avifBool allocate_svt_buffers(EbBufferHeaderType ** input_buf);
static avifResult dequeue_frame(avifCodec * codec, avifCodecEncodeOutput * output, avifBool done_sending_pics);
-static avifBool svtCodecOpen(struct avifCodec * codec)
-{
- (void)(codec);
-
- return AVIF_TRUE;
-}
-
static avifResult svtCodecEncodeImage(avifCodec * codec,
avifEncoder * encoder,
const avifImage * image,
@@ -216,7 +209,6 @@
{
avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec));
memset(codec, 0, sizeof(struct avifCodec));
- codec->open = svtCodecOpen;
codec->encodeImage = svtCodecEncodeImage;
codec->encodeFinish = svtCodecEncodeFinish;
codec->destroyInternal = svtCodecDestroyInternal;