Created new cmake option AVIF_CODEC_AOM, reorganized struct avifCodec to prepare for other codec impls
diff --git a/src/avif.c b/src/avif.c index 99a9f5b..ffe5e0c 100644 --- a/src/avif.c +++ b/src/avif.c
@@ -1,7 +1,7 @@ // Copyright 2019 Joe Drago. All rights reserved. // SPDX-License-Identifier: BSD-2-Clause -#include "avif/avif.h" +#include "avif/internal.h" #include <string.h> @@ -80,7 +80,7 @@ case AVIF_RESULT_DECODE_ALPHA_FAILED: return "Decoding of alpha plane failed"; case AVIF_RESULT_COLOR_ALPHA_SIZE_MISMATCH: return "Color and alpha planes size mismatch"; case AVIF_RESULT_ISPE_SIZE_MISMATCH: return "Plane sizes don't match ispe values"; - case AVIF_UNSUPPORTED_PIXEL_FORMAT: return "Unsupported pixel format"; + case AVIF_RESULT_NO_CODEC_AVAILABLE: return "No codec available"; case AVIF_RESULT_UNKNOWN_ERROR: default: break; @@ -238,3 +238,13 @@ { return (image->depth > 8) ? AVIF_TRUE : AVIF_FALSE; } + +// avifCodecCreate*() functions are in their respective codec_*.c files + +void avifCodecDestroy(avifCodec * codec) +{ + if (codec && codec->destroyInternal) { + codec->destroyInternal(codec); + } + avifFree(codec); +}
diff --git a/src/codec_aom.c b/src/codec_aom.c index 97783bd..e715b9c 100644 --- a/src/codec_aom.c +++ b/src/codec_aom.c
@@ -20,15 +20,7 @@ avifCodecConfigurationBox configs[AVIF_CODEC_PLANES_COUNT]; }; -avifCodec * avifCodecCreate() -{ - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); - return codec; -} - -void avifCodecDestroy(avifCodec * codec) +static void aomCodecDestroyInternal(avifCodec * codec) { for (int plane = 0; plane < AVIF_CODEC_PLANES_COUNT; ++plane) { if (codec->internal->decoderInitialized[plane]) { @@ -37,10 +29,9 @@ avifRawDataFree(&codec->internal->encodedOBUs[plane]); } avifFree(codec->internal); - avifFree(codec); } -avifBool avifCodecDecode(avifCodec * codec, avifCodecPlanes planes, avifRawData * obu) +static avifBool aomCodecDecode(avifCodec * codec, avifCodecPlanes planes, avifRawData * obu) { aom_codec_stream_info_t si; aom_codec_iface_t * decoder_interface = aom_codec_av1_dx(); @@ -67,7 +58,7 @@ return (codec->internal->images[planes]) ? AVIF_TRUE : AVIF_FALSE; } -avifCodecImageSize avifCodecGetImageSize(avifCodec * codec, avifCodecPlanes planes) +static avifCodecImageSize aomCodecGetImageSize(avifCodec * codec, avifCodecPlanes planes) { avifCodecImageSize size; if (codec->internal->images[planes]) { @@ -80,7 +71,7 @@ return size; } -avifBool avifCodecAlphaLimitedRange(avifCodec * codec) +static avifBool aomCodecAlphaLimitedRange(avifCodec * codec) { aom_image_t * aomAlphaImage = codec->internal->images[AVIF_CODEC_PLANES_ALPHA]; if (aomAlphaImage && (aomAlphaImage->range == AOM_CR_STUDIO_RANGE)) { @@ -89,7 +80,7 @@ return AVIF_FALSE; } -avifResult avifCodecGetDecodedImage(avifCodec * codec, avifImage * image) +static avifResult aomCodecGetDecodedImage(avifCodec * codec, avifImage * image) { aom_image_t * aomColorImage = codec->internal->images[AVIF_CODEC_PLANES_COLOR]; aom_image_t * aomAlphaImage = codec->internal->images[AVIF_CODEC_PLANES_ALPHA]; @@ -360,7 +351,7 @@ return success; } -avifResult avifCodecEncodeImage(avifCodec * codec, avifImage * image, avifEncoder * encoder, avifRawData * colorOBU, avifRawData * alphaOBU) +static avifResult aomCodecEncodeImage(avifCodec * codec, avifImage * image, avifEncoder * encoder, avifRawData * colorOBU, avifRawData * alphaOBU) { if (colorOBU) { if (!encodeOBU(image, AVIF_FALSE, encoder, colorOBU, &codec->internal->configs[AVIF_CODEC_PLANES_COLOR])) { @@ -375,7 +366,24 @@ return AVIF_RESULT_OK; } -void avifCodecGetConfigurationBox(avifCodec * codec, avifCodecPlanes planes, avifCodecConfigurationBox * outConfig) +static void aomCodecGetConfigurationBox(avifCodec * codec, avifCodecPlanes planes, avifCodecConfigurationBox * outConfig) { memcpy(outConfig, &codec->internal->configs[planes], sizeof(avifCodecConfigurationBox)); } + +avifCodec * avifCodecCreateAOM() +{ + avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + memset(codec, 0, sizeof(struct avifCodec)); + codec->decode = aomCodecDecode; + codec->getImageSize = aomCodecGetImageSize; + codec->alphaLimitedRange = aomCodecAlphaLimitedRange; + codec->getDecodedImage = aomCodecGetDecodedImage; + codec->encodeImage = aomCodecEncodeImage; + codec->getConfigurationBox = aomCodecGetConfigurationBox; + codec->destroyInternal = aomCodecDestroyInternal; + + codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + memset(codec->internal, 0, sizeof(struct avifCodecInternal)); + return codec; +}
diff --git a/src/read.c b/src/read.c index a40bc6c..73b97a5 100644 --- a/src/read.c +++ b/src/read.c
@@ -554,6 +554,11 @@ { avifCodec * codec = NULL; +#ifndef AVIF_CODEC_AOM + // Just bail out early, we're not surviving this function without a decoder compiled in + return AVIF_RESULT_NO_CODEC_AVAILABLE; +#endif + // ----------------------------------------------------------------------- // Parse BMFF boxes @@ -647,21 +652,26 @@ } avifBool hasAlpha = (alphaOBU.size > 0) ? AVIF_TRUE : AVIF_FALSE; - codec = avifCodecCreate(); - if (!avifCodecDecode(codec, AVIF_CODEC_PLANES_COLOR, &colorOBU)) { +#ifdef AVIF_CODEC_AOM + codec = avifCodecCreateAOM(); +#else +// #error No decoder available! + return AVIF_RESULT_NO_CODEC_AVAILABLE; +#endif + if (!codec->decode(codec, AVIF_CODEC_PLANES_COLOR, &colorOBU)) { avifCodecDestroy(codec); return AVIF_RESULT_DECODE_COLOR_FAILED; } - avifCodecImageSize colorPlanesSize = avifCodecGetImageSize(codec, AVIF_CODEC_PLANES_COLOR); + avifCodecImageSize colorPlanesSize = codec->getImageSize(codec, AVIF_CODEC_PLANES_COLOR); avifCodecImageSize alphaPlanesSize; memset(&alphaPlanesSize, 0, sizeof(alphaPlanesSize)); if (hasAlpha) { - if (!avifCodecDecode(codec, AVIF_CODEC_PLANES_ALPHA, &alphaOBU)) { + if (!codec->decode(codec, AVIF_CODEC_PLANES_ALPHA, &alphaOBU)) { avifCodecDestroy(codec); return AVIF_RESULT_DECODE_ALPHA_FAILED; } - alphaPlanesSize = avifCodecGetImageSize(codec, AVIF_CODEC_PLANES_ALPHA); + alphaPlanesSize = codec->getImageSize(codec, AVIF_CODEC_PLANES_ALPHA); if ((colorPlanesSize.width != alphaPlanesSize.width) || (colorPlanesSize.height != alphaPlanesSize.height)) { avifCodecDestroy(codec); @@ -686,14 +696,14 @@ avifImageFreePlanes(image, AVIF_PLANES_ALL); - avifResult imageResult = avifCodecGetDecodedImage(codec, image); + avifResult imageResult = codec->getDecodedImage(codec, image); if (imageResult != AVIF_RESULT_OK) { avifCodecDestroy(codec); return imageResult; } #if defined(AVIF_FIX_STUDIO_ALPHA) - if (hasAlpha && avifCodecAlphaLimitedRange(codec)) { + if (hasAlpha && codec->alphaLimitedRange(codec)) { // Naughty! Alpha planes are supposed to be full range. Correct that here. if (avifImageUsesU16(image)) { for (int j = 0; j < image->height; ++j) {
diff --git a/src/write.c b/src/write.c index 354ef1a..bb3a2d0 100644 --- a/src/write.c +++ b/src/write.c
@@ -46,7 +46,14 @@ avifResult result = AVIF_RESULT_UNKNOWN_ERROR; avifRawData colorOBU = AVIF_RAW_DATA_EMPTY; avifRawData alphaOBU = AVIF_RAW_DATA_EMPTY; - avifCodec * codec = avifCodecCreate(); + avifCodec * codec = NULL; + +#ifdef AVIF_CODEC_AOM + codec = avifCodecCreateAOM(); +#else + // Just bail out early, we're not surviving this function without an encoder compiled in + return AVIF_RESULT_NO_CODEC_AVAILABLE; +#endif avifStream s; avifStreamStart(&s, output); @@ -81,7 +88,7 @@ alphaOBUPtr = NULL; } - avifResult encodeResult = avifCodecEncodeImage(codec, image, encoder, &colorOBU, alphaOBUPtr); + avifResult encodeResult = codec->encodeImage(codec, image, encoder, &colorOBU, alphaOBUPtr); if (encodeResult != AVIF_RESULT_OK) { result = encodeResult; goto writeCleanup; @@ -246,7 +253,7 @@ ipmaPush(&ipmaColor, ipcoIndex); avifCodecConfigurationBox colorConfig; - avifCodecGetConfigurationBox(codec, AVIF_CODEC_PLANES_COLOR, &colorConfig); + codec->getConfigurationBox(codec, AVIF_CODEC_PLANES_COLOR, &colorConfig); writeConfigBox(&s, &colorConfig); ++ipcoIndex; ipmaPush(&ipmaColor, ipcoIndex); @@ -260,7 +267,7 @@ ipmaPush(&ipmaAlpha, ipcoIndex); avifCodecConfigurationBox alphaConfig; - avifCodecGetConfigurationBox(codec, AVIF_CODEC_PLANES_ALPHA, &alphaConfig); + codec->getConfigurationBox(codec, AVIF_CODEC_PLANES_ALPHA, &alphaConfig); writeConfigBox(&s, &alphaConfig); ++ipcoIndex; ipmaPush(&ipmaAlpha, ipcoIndex);