summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-01-29 18:11:13 +0100
committerwm4 <wm4@nowhere>2014-02-02 20:02:40 +0100
commitda4af2b6d86491536b0999f5b731c30b13ff0ac9 (patch)
tree9b941ab8dba74b2804993fe1bd7aa2fe9063926d
parent7514642f2575fd58c4f4809d74a0099f22d256f0 (diff)
downloadlibass-da4af2b6d86491536b0999f5b731c30b13ff0ac9.tar.bz2
libass-da4af2b6d86491536b0999f5b731c30b13ff0ac9.tar.xz
Use a function for aligned memory allocations
...instead of doing this manually.
-rw-r--r--libass/ass_bitmap.c17
-rw-r--r--libass/ass_bitmap.h3
-rw-r--r--libass/ass_render.c23
-rw-r--r--libass/ass_utils.c25
-rw-r--r--libass/ass_utils.h8
5 files changed, 51 insertions, 25 deletions
diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c
index 7689651..9196fae 100644
--- a/libass/ass_bitmap.c
+++ b/libass/ass_bitmap.c
@@ -103,8 +103,9 @@ void resize_tmp(ASS_SynthPriv *priv, int w, int h)
priv->tmp_w *= 2;
while (priv->tmp_h < h)
priv->tmp_h *= 2;
- free(priv->tmp);
- priv->tmp = malloc((priv->tmp_w + 1) * priv->tmp_h * sizeof(unsigned));
+ ass_aligned_free(priv->tmp);
+ priv->tmp =
+ ass_aligned_alloc(32, (priv->tmp_w + 1) * priv->tmp_h * sizeof(unsigned));
}
ASS_SynthPriv *ass_synth_init(double radius)
@@ -116,7 +117,7 @@ ASS_SynthPriv *ass_synth_init(double radius)
void ass_synth_done(ASS_SynthPriv *priv)
{
- free(priv->tmp);
+ ass_aligned_free(priv->tmp);
free(priv->g0);
free(priv->g);
free(priv->gt2);
@@ -127,12 +128,10 @@ Bitmap *alloc_bitmap(int w, int h)
{
Bitmap *bm;
- uintptr_t alignment_offset = (w > 31) ? 31 : ((w > 15) ? 15 : 0);
- unsigned s = (w + alignment_offset) & ~alignment_offset;
+ unsigned align = (w >= 32) ? 32 : ((w >= 16) ? 16 : 1);
+ unsigned s = ass_align(align, w);
bm = malloc(sizeof(Bitmap));
- bm->buffer_ptr = malloc(s * h + alignment_offset + 32);
- bm->buffer = (unsigned char*)
- (((uintptr_t)bm->buffer_ptr + alignment_offset) & ~alignment_offset);
+ bm->buffer = ass_aligned_alloc(align, s * h + 32);
memset(bm->buffer, 0, s * h + 32);
bm->w = w;
bm->h = h;
@@ -144,7 +143,7 @@ Bitmap *alloc_bitmap(int w, int h)
void ass_free_bitmap(Bitmap *bm)
{
if (bm)
- free(bm->buffer_ptr);
+ ass_aligned_free(bm->buffer);
free(bm);
}
diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h
index b51c1bf..b05e112 100644
--- a/libass/ass_bitmap.h
+++ b/libass/ass_bitmap.h
@@ -26,7 +26,7 @@
typedef struct ass_synth_priv {
int tmp_w, tmp_h;
- unsigned *tmp;
+ void *tmp;
int g_r;
int g_w;
@@ -46,7 +46,6 @@ typedef struct {
int w, h; // width, height
int stride;
unsigned char *buffer; // h * stride buffer
- unsigned char *buffer_ptr; // unaligned pointer (for free())
} Bitmap;
Bitmap *outline_to_bitmap(ASS_Library *library, FT_Library ftlib,
diff --git a/libass/ass_render.c b/libass/ass_render.c
index e629fdd..58d1a15 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -135,7 +135,7 @@ static void free_list_clear(ASS_Renderer *render_priv)
FreeList *item = render_priv->free_head;
while(item) {
FreeList *oi = item;
- free(item->object);
+ ass_aligned_free(item->object);
item = item->next;
free(oi);
}
@@ -570,10 +570,9 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
}
// Allocate new buffer and add to free list
- nbuffer = malloc(as * ah + 0x1F);
+ nbuffer = ass_aligned_alloc(32, as * ah);
if (!nbuffer) return;
free_list_add(render_priv, nbuffer);
- nbuffer = (unsigned char*)(((uintptr_t)nbuffer + 0x1F) & ~0x1F);
// Blend together
memcpy(nbuffer, abuffer, ((ah - 1) * as) + aw);
@@ -589,13 +588,11 @@ static void blend_vector_clip(ASS_Renderer *render_priv,
}
// Allocate new buffer and add to free list
- uintptr_t alignment_offset = (w > 15) ? 15 : ((w > 7) ? 7 : 0);
- unsigned ns = (w + alignment_offset) & ~alignment_offset;
- nbuffer = malloc(ns * h + alignment_offset);
+ unsigned align = (w >= 16) ? 16 : ((w >= 8) ? 8 : 1);
+ unsigned ns = ass_align(align, w);
+ nbuffer = ass_aligned_alloc(align, ns * h);
if (!nbuffer) return;
free_list_add(render_priv, nbuffer);
- nbuffer = (unsigned char*)
- (((uintptr_t)nbuffer + alignment_offset) & ~alignment_offset);
// Blend together
render_priv->mul_bitmaps_func(nbuffer, ns,
@@ -704,13 +701,11 @@ static ASS_Image *render_text(ASS_Renderer *render_priv, int dst_x, int dst_y)
s = cur->stride;
if(w + 31 < (unsigned)cur->stride){ // Larger value? Play with this.
// Allocate new buffer and add to free list
- uintptr_t alignment_offset = (w > 31) ? 31 : ((w > 15) ? 15 : 0);
- unsigned ns = (w + alignment_offset) & ~alignment_offset;
- uint8_t* nbuffer = malloc(ns * cur->h + alignment_offset);
+ unsigned align = (w >= 32) ? 32 : ((w >= 16) ? 16 : 1);
+ unsigned ns = ass_align(align, w);
+ uint8_t* nbuffer = ass_aligned_alloc(align, ns * cur->h);
if (!nbuffer) continue;
free_list_add(render_priv, nbuffer);
- nbuffer = (unsigned char*)
- (((uintptr_t)nbuffer + alignment_offset) & ~alignment_offset);
// Copy
render_priv->restride_bitmap_func(nbuffer, ns,
@@ -1711,7 +1706,7 @@ static void apply_blur(CombinedBitmapInfo *info, ASS_Renderer *render_priv)
// Apply box blur (multiple passes, if requested)
if (be) {
- uint16_t* tmp = (uint16_t*)(((uintptr_t)priv_blur->tmp + 0x0F) & ~0x0F);
+ uint16_t* tmp = priv_blur->tmp;
if (bm_o) {
unsigned passes = be;
unsigned w = bm_o->w;
diff --git a/libass/ass_utils.c b/libass/ass_utils.c
index 72993d7..e119c02 100644
--- a/libass/ass_utils.c
+++ b/libass/ass_utils.c
@@ -18,8 +18,10 @@
#include "config.h"
+#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
#include <inttypes.h>
#include <strings.h>
@@ -63,6 +65,29 @@ int has_avx2(void)
#endif // ASM
+void *ass_aligned_alloc(size_t alignment, size_t size)
+{
+ if (alignment & (alignment - 1))
+ abort(); // not a power of 2
+ if (size >= SIZE_MAX - alignment - sizeof(void *))
+ return NULL;
+ char *allocation = malloc(size + sizeof(void *) + alignment - 1);
+ if (!allocation)
+ return NULL;
+ char *ptr = allocation + sizeof(void *);
+ unsigned int misalign = (uintptr_t)ptr & (alignment - 1);
+ if (misalign)
+ ptr += alignment - misalign;
+ *((void **)ptr - 1) = allocation;
+ return ptr;
+}
+
+void ass_aligned_free(void *ptr)
+{
+ if (ptr)
+ free(*((void **)ptr - 1));
+}
+
int mystrtoi(char **p, int *res)
{
double temp_res;
diff --git a/libass/ass_utils.h b/libass/ass_utils.h
index 4e2ba6c..7228b36 100644
--- a/libass/ass_utils.h
+++ b/libass/ass_utils.h
@@ -49,6 +49,9 @@ int has_avx(void);
int has_avx2(void);
#endif
+void *ass_aligned_alloc(size_t alignment, size_t size);
+void ass_aligned_free(void *ptr);
+
int mystrtoi(char **p, int *res);
int mystrtoll(char **p, long long *res);
int mystrtou32(char **p, int base, uint32_t *res);
@@ -70,6 +73,11 @@ void *ass_guess_buffer_cp(ASS_Library *library, unsigned char *buffer,
/* defined in ass_strtod.c */
double ass_strtod(const char *string, char **endPtr);
+static inline size_t ass_align(size_t alignment, size_t s)
+{
+ return (s + (alignment - 1)) & ~(alignment - 1);
+}
+
static inline int d6_to_int(int x)
{
return (x + 32) >> 6;