diff --git a/include/avif/internal.h b/include/avif/internal.h index 4982eac121..293c84ef10 100644 --- a/include/avif/internal.h +++ b/include/avif/internal.h @@ -14,6 +14,10 @@ extern "C" { #error "Your target is linking against avif and avif_internal: only one should be chosen" #endif +// Allocates count * size bytes and zero-initializes them. Returns NULL on memory +// allocation failure, including the case when count * size overflows size_t. +void * avifCalloc(size_t count, size_t size); + // Yes, clamp macros are nasty. Do not use them. #define AVIF_CLAMP(x, low, high) (((x) < (low)) ? (low) : (((high) < (x)) ? (high) : (x))) #define AVIF_MIN(a, b) (((a) < (b)) ? (a) : (b)) diff --git a/src/avif.c b/src/avif.c index f44dc49e93..e4bbfa187f 100644 --- a/src/avif.c +++ b/src/avif.c @@ -234,9 +234,8 @@ static avifResult avifImageCopyProperties(avifImage * dstImage, const avifImage dstImage->numProperties = 0; if (srcImage->numProperties != 0) { - dstImage->properties = (avifImageItemProperty *)avifAlloc(srcImage->numProperties * sizeof(srcImage->properties[0])); + dstImage->properties = (avifImageItemProperty *)avifCalloc(srcImage->numProperties, sizeof(srcImage->properties[0])); AVIF_CHECKERR(dstImage->properties != NULL, AVIF_RESULT_OUT_OF_MEMORY); - memset(dstImage->properties, 0, srcImage->numProperties * sizeof(srcImage->properties[0])); dstImage->numProperties = srcImage->numProperties; for (size_t i = 0; i < srcImage->numProperties; ++i) { memcpy(dstImage->properties[i].boxtype, srcImage->properties[i].boxtype, sizeof(srcImage->properties[i].boxtype)); diff --git a/src/codec_aom.c b/src/codec_aom.c index bc6bd55d4b..beba54e8e1 100644 --- a/src/codec_aom.c +++ b/src/codec_aom.c @@ -1395,11 +1395,10 @@ const char * avifCodecVersionAOM(void) avifCodec * avifCodecCreateAOM(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); #if defined(AVIF_CODEC_AOM_DECODE) codec->getNextImage = aomCodecGetNextImage; @@ -1411,12 +1410,11 @@ avifCodec * avifCodecCreateAOM(void) #endif codec->destroyInternal = aomCodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); return codec; } diff --git a/src/codec_avm.c b/src/codec_avm.c index 2328d6e457..6222f7fa6d 100644 --- a/src/codec_avm.c +++ b/src/codec_avm.c @@ -1043,11 +1043,10 @@ const char * avifCodecVersionAVM(void) avifCodec * avifCodecCreateAVM(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); codec->getNextImage = avmCodecGetNextImage; @@ -1055,11 +1054,10 @@ avifCodec * avifCodecCreateAVM(void) codec->encodeFinish = avmCodecEncodeFinish; codec->destroyInternal = avmCodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); return codec; } diff --git a/src/codec_dav1d.c b/src/codec_dav1d.c index 3f83c351e5..2f1210afbe 100644 --- a/src/codec_dav1d.c +++ b/src/codec_dav1d.c @@ -232,19 +232,17 @@ const char * avifCodecVersionDav1d(void) avifCodec * avifCodecCreateDav1d(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); codec->getNextImage = dav1dCodecGetNextImage; codec->destroyInternal = dav1dCodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); return codec; } diff --git a/src/codec_libgav1.c b/src/codec_libgav1.c index 7d07adf875..ec791ccac4 100644 --- a/src/codec_libgav1.c +++ b/src/codec_libgav1.c @@ -140,20 +140,18 @@ const char * avifCodecVersionGav1(void) avifCodec * avifCodecCreateGav1(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); codec->getNextImage = gav1CodecGetNextImage; codec->destroyInternal = gav1CodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); Libgav1DecoderSettingsInitDefault(&codec->internal->gav1Settings); return codec; } diff --git a/src/codec_rav1e.c b/src/codec_rav1e.c index dc220ed13c..97c92be3a7 100644 --- a/src/codec_rav1e.c +++ b/src/codec_rav1e.c @@ -333,20 +333,18 @@ const char * avifCodecVersionRav1e(void) avifCodec * avifCodecCreateRav1e(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); codec->encodeImage = rav1eCodecEncodeImage; codec->encodeFinish = rav1eCodecEncodeFinish; codec->destroyInternal = rav1eCodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(struct avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(struct avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); return codec; } diff --git a/src/codec_svt.c b/src/codec_svt.c index 2b887e85ef..a76fb5bd53 100644 --- a/src/codec_svt.c +++ b/src/codec_svt.c @@ -291,11 +291,10 @@ static avifResult svtCodecEncodeImage(avifCodec * codec, if (uvSize * 2 > UINT32_MAX - input_buffer->n_filled_len) { goto cleanup; } - uvPlanes = avifAlloc(uvSize); + uvPlanes = avifCalloc(uvSize, sizeof(uint8_t)); if (uvPlanes == NULL) { goto cleanup; } - memset(uvPlanes, 0, uvSize); input_picture_buffer->cb = uvPlanes; input_buffer->n_filled_len += (uint32_t)uvSize; input_picture_buffer->cr = uvPlanes; @@ -402,21 +401,19 @@ static void svtCodecDestroyInternal(avifCodec * codec) avifCodec * avifCodecCreateSvt(void) { - avifCodec * codec = (avifCodec *)avifAlloc(sizeof(avifCodec)); + avifCodec * codec = (avifCodec *)avifCalloc(1, sizeof(avifCodec)); if (codec == NULL) { return NULL; } - memset(codec, 0, sizeof(struct avifCodec)); codec->encodeImage = svtCodecEncodeImage; codec->encodeFinish = svtCodecEncodeFinish; codec->destroyInternal = svtCodecDestroyInternal; - codec->internal = (struct avifCodecInternal *)avifAlloc(sizeof(avifCodecInternal)); + codec->internal = (struct avifCodecInternal *)avifCalloc(1, sizeof(avifCodecInternal)); if (codec->internal == NULL) { avifFree(codec); return NULL; } - memset(codec->internal, 0, sizeof(struct avifCodecInternal)); return codec; } @@ -426,11 +423,10 @@ static avifBool allocate_svt_buffers(EbBufferHeaderType ** input_buf) if (!(*input_buf)) { return AVIF_FALSE; } - (*input_buf)->p_buffer = avifAlloc(sizeof(EbSvtIOFormat)); + (*input_buf)->p_buffer = avifCalloc(1, sizeof(EbSvtIOFormat)); if (!(*input_buf)->p_buffer) { return AVIF_FALSE; } - memset((*input_buf)->p_buffer, 0, sizeof(EbSvtIOFormat)); (*input_buf)->size = sizeof(EbBufferHeaderType); (*input_buf)->p_app_private = NULL; (*input_buf)->pic_type = EB_AV1_INVALID_PICTURE; diff --git a/src/gainmap.c b/src/gainmap.c index b35734f892..d87f96a8ba 100644 --- a/src/gainmap.c +++ b/src/gainmap.c @@ -393,11 +393,10 @@ avifResult avifFindMinMaxWithoutOutliers(const float * gainMapF, size_t numPixel const int maxNumBuckets = 10000; const int numBuckets = AVIF_MIN((int)ceilf((max - min) / bucketSize), maxNumBuckets); - int * histogram = avifAlloc(sizeof(int) * numBuckets); + int * histogram = avifCalloc(numBuckets, sizeof(int)); if (histogram == NULL) { return AVIF_RESULT_OUT_OF_MEMORY; } - memset(histogram, 0, sizeof(int) * numBuckets); for (size_t i = 0; i < numPixels; ++i) { ++(histogram[avifValueToBucketIdx(gainMapF[i], min, max, numBuckets)]); } diff --git a/src/io.c b/src/io.c index 08eb032a94..bd0ebda8b5 100644 --- a/src/io.c +++ b/src/io.c @@ -132,11 +132,10 @@ static void avifIOMemoryReaderDestroy(struct avifIO * io) avifIO * avifIOCreateMemoryReader(const uint8_t * data, size_t size) { - avifIOMemoryReader * reader = (avifIOMemoryReader *)avifAlloc(sizeof(avifIOMemoryReader)); + avifIOMemoryReader * reader = (avifIOMemoryReader *)avifCalloc(1, sizeof(avifIOMemoryReader)); if (reader == NULL) { return NULL; } - memset(reader, 0, sizeof(avifIOMemoryReader)); reader->io.destroy = avifIOMemoryReaderDestroy; reader->io.read = avifIOMemoryReaderRead; reader->io.sizeHint = size; @@ -230,12 +229,11 @@ avifIO * avifIOCreateFileReader(const char * filename) return NULL; } - avifIOFileReader * reader = (avifIOFileReader *)avifAlloc(sizeof(avifIOFileReader)); + avifIOFileReader * reader = (avifIOFileReader *)avifCalloc(1, sizeof(avifIOFileReader)); if (!reader) { fclose(f); return NULL; } - memset(reader, 0, sizeof(avifIOFileReader)); reader->f = f; reader->io.destroy = avifIOFileReaderDestroy; reader->io.read = avifIOFileReaderRead; diff --git a/src/mem.c b/src/mem.c index 5ccf5f3e0e..07ab027f62 100644 --- a/src/mem.c +++ b/src/mem.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 #include @@ -12,6 +12,11 @@ void * avifAlloc(size_t size) return malloc(size); } +void * avifCalloc(size_t count, size_t size) +{ + return calloc(count, size); +} + void avifFree(void * p) { free(p);