diff options
Diffstat (limited to 'ffmpeg/libavutil/mem.c')
| -rw-r--r-- | ffmpeg/libavutil/mem.c | 142 |
1 files changed, 135 insertions, 7 deletions
diff --git a/ffmpeg/libavutil/mem.c b/ffmpeg/libavutil/mem.c index 860c011..10b0137 100644 --- a/ffmpeg/libavutil/mem.c +++ b/ffmpeg/libavutil/mem.c @@ -38,6 +38,7 @@ #include "avassert.h" #include "avutil.h" +#include "common.h" #include "intreadwrite.h" #include "mem.h" @@ -77,7 +78,7 @@ void *av_malloc(size_t size) long diff; #endif - /* let's disallow possible ambiguous cases */ + /* let's disallow possibly ambiguous cases */ if (size > (max_alloc_size - 32)) return NULL; @@ -133,7 +134,7 @@ void *av_malloc(size_t size) } #if CONFIG_MEMORY_POISONING if (ptr) - memset(ptr, 0x2a, size); + memset(ptr, FF_MEMORY_POISON, size); #endif return ptr; } @@ -144,7 +145,7 @@ void *av_realloc(void *ptr, size_t size) int diff; #endif - /* let's disallow possible ambiguous cases */ + /* let's disallow possibly ambiguous cases */ if (size > (max_alloc_size - 32)) return NULL; @@ -180,6 +181,42 @@ void *av_realloc_f(void *ptr, size_t nelem, size_t elsize) return r; } +int av_reallocp(void *ptr, size_t size) +{ + void **ptrptr = ptr; + void *ret; + + if (!size) { + av_freep(ptr); + return 0; + } + ret = av_realloc(*ptrptr, size); + + if (!ret) { + av_freep(ptr); + return AVERROR(ENOMEM); + } + + *ptrptr = ret; + return 0; +} + +void *av_realloc_array(void *ptr, size_t nmemb, size_t size) +{ + if (!size || nmemb >= INT_MAX / size) + return NULL; + return av_realloc(ptr, nmemb * size); +} + +int av_reallocp_array(void *ptr, size_t nmemb, size_t size) +{ + void **ptrptr = ptr; + *ptrptr = av_realloc_f(*ptrptr, nmemb, size); + if (!*ptrptr && nmemb && size) + return AVERROR(ENOMEM); + return 0; +} + void av_free(void *ptr) { #if CONFIG_MEMALIGN_HACK @@ -222,14 +259,24 @@ char *av_strdup(const char *s) char *ptr = NULL; if (s) { int len = strlen(s) + 1; - ptr = av_malloc(len); + ptr = av_realloc(NULL, len); if (ptr) memcpy(ptr, s, len); } return ptr; } -/* add one element to a dynamic array */ +void *av_memdup(const void *p, size_t size) +{ + void *ptr = NULL; + if (p) { + ptr = av_malloc(size); + if (ptr) + memcpy(ptr, p, size); + } + return ptr; +} + void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) { /* see similar ffmpeg.c:grow_array() */ @@ -239,15 +286,58 @@ void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem) nb = *nb_ptr; tab = *(intptr_t**)tab_ptr; if ((nb & (nb - 1)) == 0) { - if (nb == 0) + if (nb == 0) { nb_alloc = 1; - else + } else { + if (nb > INT_MAX / (2 * sizeof(intptr_t))) + goto fail; nb_alloc = nb * 2; + } tab = av_realloc(tab, nb_alloc * sizeof(intptr_t)); + if (!tab) + goto fail; *(intptr_t**)tab_ptr = tab; } tab[nb++] = (intptr_t)elem; *nb_ptr = nb; + return; + +fail: + av_freep(tab_ptr); + *nb_ptr = 0; +} + +void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size, + const uint8_t *elem_data) +{ + int nb = *nb_ptr, nb_alloc; + uint8_t *tab = *tab_ptr, *tab_elem_data; + + if ((nb & (nb - 1)) == 0) { + if (nb == 0) { + nb_alloc = 1; + } else { + if (nb > INT_MAX / (2 * elem_size)) + goto fail; + nb_alloc = nb * 2; + } + tab = av_realloc(tab, nb_alloc * elem_size); + if (!tab) + goto fail; + *tab_ptr = tab; + } + *nb_ptr = nb + 1; + tab_elem_data = tab + nb*elem_size; + if (elem_data) + memcpy(tab_elem_data, elem_data, elem_size); + else if (CONFIG_MEMORY_POISONING) + memset(tab_elem_data, FF_MEMORY_POISON, elem_size); + return tab_elem_data; + +fail: + av_freep(tab_ptr); + *nb_ptr = 0; + return NULL; } static void fill16(uint8_t *dst, int len) @@ -374,3 +464,41 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) } } +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +{ + if (min_size < *size) + return ptr; + + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + + ptr = av_realloc(ptr, min_size); + /* we could set this to the unmodified min_size but this is safer + * if the user lost the ptr and uses NULL now + */ + if (!ptr) + min_size = 0; + + *size = min_size; + + return ptr; +} + +static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) +{ + void **p = ptr; + if (min_size < *size) + return 0; + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + av_free(*p); + *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size); + if (!*p) + min_size = 0; + *size = min_size; + return 1; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + ff_fast_malloc(ptr, size, min_size, 0); +} + |
