summaryrefslogtreecommitdiff
path: root/gst/dvbsubenc/libimagequant/mempool.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/dvbsubenc/libimagequant/mempool.c')
-rw-r--r--gst/dvbsubenc/libimagequant/mempool.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gst/dvbsubenc/libimagequant/mempool.c b/gst/dvbsubenc/libimagequant/mempool.c
new file mode 100644
index 000000000..c2777d831
--- /dev/null
+++ b/gst/dvbsubenc/libimagequant/mempool.c
@@ -0,0 +1,69 @@
+
+#include "libimagequant.h"
+#include "mempool.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <assert.h>
+
+#define ALIGN_MASK 15UL
+#define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
+
+struct mempool
+{
+ unsigned int used, size;
+ void *(*malloc) (size_t);
+ void (*free) (void *);
+ struct mempool *next;
+};
+LIQ_PRIVATE void *
+mempool_create (mempool * mptr, const unsigned int size, unsigned int max_size,
+ void *(*malloc) (size_t), void (*free) (void *))
+{
+ mempool old;
+ uintptr_t mptr_used_start;
+
+ if (*mptr && ((*mptr)->used + size) <= (*mptr)->size) {
+ unsigned int prevused = (*mptr)->used;
+ (*mptr)->used += (size + 15UL) & ~0xFUL;
+ return ((char *) (*mptr)) + prevused;
+ }
+
+ old = *mptr;
+ if (!max_size)
+ max_size = (1 << 17);
+ max_size = size + ALIGN_MASK > max_size ? size + ALIGN_MASK : max_size;
+
+ *mptr = malloc (MEMPOOL_RESERVED + max_size);
+ if (!*mptr)
+ return NULL;
+ **mptr = (struct mempool) {
+ .malloc = malloc,.free = free,.size = MEMPOOL_RESERVED + max_size,.used =
+ sizeof (struct mempool),.next = old,};
+ mptr_used_start = (uintptr_t) (*mptr) + (*mptr)->used;
+ (*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK; // reserve bytes required to make subsequent allocations aligned
+ assert (!(((uintptr_t) (*mptr) + (*mptr)->used) & ALIGN_MASK));
+
+ return mempool_alloc (mptr, size, size);
+}
+
+LIQ_PRIVATE void *
+mempool_alloc (mempool * mptr, unsigned int size, unsigned int max_size)
+{
+ if (((*mptr)->used + size) <= (*mptr)->size) {
+ unsigned int prevused = (*mptr)->used;
+ (*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
+ return ((char *) (*mptr)) + prevused;
+ }
+
+ return mempool_create (mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
+}
+
+LIQ_PRIVATE void
+mempool_destroy (mempool m)
+{
+ while (m) {
+ mempool next = m->next;
+ m->free (m);
+ m = next;
+ }
+}