From da4af2b6d86491536b0999f5b731c30b13ff0ac9 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 29 Jan 2014 18:11:13 +0100 Subject: Use a function for aligned memory allocations ...instead of doing this manually. --- libass/ass_bitmap.c | 17 ++++++++--------- libass/ass_bitmap.h | 3 +-- libass/ass_render.c | 23 +++++++++-------------- libass/ass_utils.c | 25 +++++++++++++++++++++++++ libass/ass_utils.h | 8 ++++++++ 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 #include #include +#include #include #include @@ -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; -- cgit v1.2.3