]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/mem.c
Handle input or output len of 0 properly in lzo decoder.
[ffmpeg] / libavutil / mem.c
index a91ac4a07b81a365f941abab660fd9e8f7035954..18fe28b7cea215b5665648ec2274937f32f7b021 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * default memory allocator for libavutil
 /*
  * default memory allocator for libavutil
- * Copyright (c) 2002 Fabrice Bellard.
+ * Copyright (c) 2002 Fabrice Bellard
  *
  * This file is part of FFmpeg.
  *
  *
  * This file is part of FFmpeg.
  *
  */
 
 /**
  */
 
 /**
- * @file mem.c
- * default memory allocator for libavutil.
+ * @file
+ * default memory allocator for libavutil
  */
 
  */
 
-#include "common.h"
+#include "config.h"
 
 
-/* here we can use OS dependent allocation functions */
-#undef malloc
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include "avutil.h"
+#include "mem.h"
+
+/* here we can use OS-dependent allocation functions */
 #undef free
 #undef free
+#undef malloc
 #undef realloc
 
 #undef realloc
 
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
+#ifdef MALLOC_PREFIX
+
+#define malloc         AV_JOIN(MALLOC_PREFIX, malloc)
+#define memalign       AV_JOIN(MALLOC_PREFIX, memalign)
+#define posix_memalign AV_JOIN(MALLOC_PREFIX, posix_memalign)
+#define realloc        AV_JOIN(MALLOC_PREFIX, realloc)
+#define free           AV_JOIN(MALLOC_PREFIX, free)
+
+void *malloc(size_t size);
+void *memalign(size_t align, size_t size);
+int   posix_memalign(void **ptr, size_t align, size_t size);
+void *realloc(void *ptr, size_t size);
+void  free(void *ptr);
 
 
-/* you can redefine av_malloc and av_free in your project to use your
+#endif /* MALLOC_PREFIX */
+
+/* You can redefine av_malloc and av_free in your project to use your
    memory allocator. You do not need to suppress this file because the
    memory allocator. You do not need to suppress this file because the
-   linker will do it automatically */
+   linker will do it automatically. */
 
 
-void *av_malloc(unsigned int size)
+void *av_malloc(FF_INTERNAL_MEM_TYPE size)
 {
 {
-    void *ptr;
-#ifdef CONFIG_MEMALIGN_HACK
+    void *ptr = NULL;
+#if CONFIG_MEMALIGN_HACK
     long diff;
 #endif
 
     long diff;
 #endif
 
@@ -50,31 +72,34 @@ void *av_malloc(unsigned int size)
     if(size > (INT_MAX-16) )
         return NULL;
 
     if(size > (INT_MAX-16) )
         return NULL;
 
-#ifdef CONFIG_MEMALIGN_HACK
+#if CONFIG_MEMALIGN_HACK
     ptr = malloc(size+16);
     if(!ptr)
         return ptr;
     diff= ((-(long)ptr - 1)&15) + 1;
     ptr = malloc(size+16);
     if(!ptr)
         return ptr;
     diff= ((-(long)ptr - 1)&15) + 1;
-    ptr += diff;
+    ptr = (char*)ptr + diff;
     ((char*)ptr)[-1]= diff;
     ((char*)ptr)[-1]= diff;
-#elif defined (HAVE_MEMALIGN)
+#elif HAVE_POSIX_MEMALIGN
+    if (posix_memalign(&ptr,16,size))
+        ptr = NULL;
+#elif HAVE_MEMALIGN
     ptr = memalign(16,size);
     /* Why 64?
        Indeed, we should align it:
          on 4 for 386
          on 16 for 486
     ptr = memalign(16,size);
     /* Why 64?
        Indeed, we should align it:
          on 4 for 386
          on 16 for 486
-         on 32 for 586, PPro - k6-III
+         on 32 for 586, PPro - K6-III
          on 64 for K7 (maybe for P3 too).
        Because L1 and L2 caches are aligned on those values.
        But I don't want to code such logic here!
      */
      /* Why 16?
          on 64 for K7 (maybe for P3 too).
        Because L1 and L2 caches are aligned on those values.
        But I don't want to code such logic here!
      */
      /* Why 16?
-        because some cpus need alignment, for example SSE2 on P4, & most RISC cpus
+        Because some CPUs need alignment, for example SSE2 on P4, & most RISC CPUs
         it will just trigger an exception and the unaligned load will be done in the
         it will just trigger an exception and the unaligned load will be done in the
-        exception handler or it will just segfault (SSE2 on P4)
-        Why not larger? because i didnt see a difference in benchmarks ...
+        exception handler or it will just segfault (SSE2 on P4).
+        Why not larger? Because I did not see a difference in benchmarks ...
      */
      */
-     /* benchmarks with p3
+     /* benchmarks with P3
         memalign(64)+1          3071,3051,3032
         memalign(64)+2          3051,3032,3041
         memalign(64)+4          2911,2896,2915
         memalign(64)+1          3071,3051,3032
         memalign(64)+2          3051,3032,3041
         memalign(64)+4          2911,2896,2915
@@ -83,7 +108,7 @@ void *av_malloc(unsigned int size)
         memalign(64)+32         2546,2545,2571
         memalign(64)+64         2570,2533,2558
 
         memalign(64)+32         2546,2545,2571
         memalign(64)+64         2570,2533,2558
 
-        btw, malloc seems to do 8 byte alignment by default here
+        BTW, malloc seems to do 8-byte alignment by default here.
      */
 #else
     ptr = malloc(size);
      */
 #else
     ptr = malloc(size);
@@ -91,9 +116,9 @@ void *av_malloc(unsigned int size)
     return ptr;
 }
 
     return ptr;
 }
 
-void *av_realloc(void *ptr, unsigned int size)
+void *av_realloc(void *ptr, FF_INTERNAL_MEM_TYPE size)
 {
 {
-#ifdef CONFIG_MEMALIGN_HACK
+#if CONFIG_MEMALIGN_HACK
     int diff;
 #endif
 
     int diff;
 #endif
 
@@ -101,11 +126,11 @@ void *av_realloc(void *ptr, unsigned int size)
     if(size > (INT_MAX-16) )
         return NULL;
 
     if(size > (INT_MAX-16) )
         return NULL;
 
-#ifdef CONFIG_MEMALIGN_HACK
+#if CONFIG_MEMALIGN_HACK
     //FIXME this isn't aligned correctly, though it probably isn't needed
     if(!ptr) return av_malloc(size);
     diff= ((char*)ptr)[-1];
     //FIXME this isn't aligned correctly, though it probably isn't needed
     if(!ptr) return av_malloc(size);
     diff= ((char*)ptr)[-1];
-    return realloc(ptr - diff, size + diff) + diff;
+    return (char*)realloc((char*)ptr - diff, size + diff) + diff;
 #else
     return realloc(ptr, size);
 #endif
 #else
     return realloc(ptr, size);
 #endif
@@ -115,8 +140,8 @@ void av_free(void *ptr)
 {
     /* XXX: this test should not be needed on most libcs */
     if (ptr)
 {
     /* XXX: this test should not be needed on most libcs */
     if (ptr)
-#ifdef CONFIG_MEMALIGN_HACK
-        free(ptr - ((char*)ptr)[-1]);
+#if CONFIG_MEMALIGN_HACK
+        free((char*)ptr - ((char*)ptr)[-1]);
 #else
         free(ptr);
 #endif
 #else
         free(ptr);
 #endif
@@ -129,11 +154,9 @@ void av_freep(void *arg)
     *ptr = NULL;
 }
 
     *ptr = NULL;
 }
 
-void *av_mallocz(unsigned int size)
+void *av_mallocz(FF_INTERNAL_MEM_TYPE size)
 {
 {
-    void *ptr;
-
-    ptr = av_malloc(size);
+    void *ptr = av_malloc(size);
     if (ptr)
         memset(ptr, 0, size);
     return ptr;
     if (ptr)
         memset(ptr, 0, size);
     return ptr;
@@ -141,12 +164,13 @@ void *av_mallocz(unsigned int size)
 
 char *av_strdup(const char *s)
 {
 
 char *av_strdup(const char *s)
 {
-    char *ptr;
-    int len;
-    len = strlen(s) + 1;
-    ptr = av_malloc(len);
-    if (ptr)
-        memcpy(ptr, s, len);
+    char *ptr= NULL;
+    if(s){
+        int len = strlen(s) + 1;
+        ptr = av_malloc(len);
+        if (ptr)
+            memcpy(ptr, s, len);
+    }
     return ptr;
 }
 
     return ptr;
 }