lavu/mem: add av_dynarray2_add()
authorStefano Sabatini <stefasab@gmail.com>
Sun, 14 Apr 2013 01:07:54 +0000 (03:07 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Mon, 13 May 2013 11:52:31 +0000 (13:52 +0200)
Based on a patch by Clément Bœsch.

See thread:
From: Clément Bœsch <ubitux@gmail.com>
Subject: [FFmpeg-devel] [PATCH 1/5] lavu: add av_dynarray_alloc_elem().
Date: Sun, 14 Apr 2013 03:07:54 +0200

doc/APIchanges
libavutil/mem.c
libavutil/mem.h
libavutil/version.h

index 1c5f6d1..4e5e5bd 100644 (file)
@@ -15,6 +15,9 @@ libavutil:     2012-10-22
 
 API changes, most recent first:
 
+2013-05-13 - xxxxxxx - lavu 52.31.100 - mem.h
+  Add av_dynarray2_add().
+
 2013-05-12 - xxxxxxx - lavfi 3.65.100
   Add AVFILTER_FLAG_SUPPORT_TIMELINE* filter flags.
 
index 9b22609..66502eb 100644 (file)
@@ -270,6 +270,39 @@ fail:
     *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)
 {
     uint32_t v = AV_RN16(dst - 2);
index 8433ada..a329469 100644 (file)
@@ -215,10 +215,35 @@ void av_freep(void *ptr);
  * @param tab_ptr pointer to the array to grow
  * @param nb_ptr  pointer to the number of elements in the array
  * @param elem    element to add
+ * @see av_dynarray2_add()
  */
 void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem);
 
 /**
+ * Add an element of size elem_size to a dynamic array.
+ *
+ * The array is reallocated when its number of elements reaches powers of 2.
+ * Therefore, the amortized cost of adding an element is constant.
+ *
+ * In case of success, the pointer to the array is updated in order to
+ * point to the new grown array, and the number pointed to by nb_ptr
+ * is incremented.
+ * In case of failure, the array is freed, *tab_ptr is set to NULL and
+ * *nb_ptr is set to 0.
+ *
+ * @param tab_ptr   pointer to the array to grow
+ * @param nb_ptr    pointer to the number of elements in the array
+ * @param elem_size size in bytes of the elements in the array
+ * @param elem_data pointer to the data of the element to add. If NULL, the space of
+ *                  the new added element is not filled.
+ * @return          pointer to the data of the element to copy in the new allocated space.
+ *                  If NULL, the new allocated space is left uninitialized."
+ * @see av_dynarray_add()
+ */
+void *av_dynarray2_add(void **tab_ptr, int *nb_ptr, size_t elem_size,
+                       const uint8_t *elem_data);
+
+/**
  * Multiply two size_t values checking for overflow.
  * @return  0 if success, AVERROR(EINVAL) if overflow.
  */
index 4d87631..f9a7040 100644 (file)
@@ -75,7 +75,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  52
-#define LIBAVUTIL_VERSION_MINOR  30
+#define LIBAVUTIL_VERSION_MINOR  31
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \