]> granicus.if.org Git - libass/commitdiff
Use a function for aligned memory allocations
authorwm4 <wm4@nowhere>
Wed, 29 Jan 2014 17:11:13 +0000 (18:11 +0100)
committerwm4 <wm4@nowhere>
Sun, 2 Feb 2014 19:02:40 +0000 (20:02 +0100)
...instead of doing this manually.

libass/ass_bitmap.c
libass/ass_bitmap.h
libass/ass_render.c
libass/ass_utils.c
libass/ass_utils.h

index 7689651089f84c43a3c28ce26222508ce53d6e97..9196faed9290e08e4ecde37c9f03c5c3b946715e 100644 (file)
@@ -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);
 }
 
index b51c1bfec967c7ea210811564218f6a3737d578e..b05e1120a734d93f749b5d5c52cb8d193d69a4e5 100644 (file)
@@ -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,
index e629fddd9fcc69c682f5dd2e2b53a8bfe37a4a0f..58d1a157110fe86666c7ed7423da4adaede75cb1 100644 (file)
@@ -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;
index 72993d76478241312403ebb0897be42609c32623..e119c02109e04cf4837a7b84e79d16ca6b8addf3 100644 (file)
 
 #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;
index 4e2ba6c3a58bb85693a5b6a0821adbfc55e0e581..7228b360a8fd2f4780fb93d422e48265768386b6 100644 (file)
@@ -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;