...instead of doing this manually.
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)
void ass_synth_done(ASS_SynthPriv *priv)
{
- free(priv->tmp);
+ ass_aligned_free(priv->tmp);
free(priv->g0);
free(priv->g);
free(priv->gt2);
{
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;
void ass_free_bitmap(Bitmap *bm)
{
if (bm)
- free(bm->buffer_ptr);
+ ass_aligned_free(bm->buffer);
free(bm);
}
typedef struct ass_synth_priv {
int tmp_w, tmp_h;
- unsigned *tmp;
+ void *tmp;
int g_r;
int g_w;
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,
FreeList *item = render_priv->free_head;
while(item) {
FreeList *oi = item;
- free(item->object);
+ ass_aligned_free(item->object);
item = item->next;
free(oi);
}
}
// 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);
}
// 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,
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,
// 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;
#include "config.h"
+#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stdint.h>
#include <inttypes.h>
#include <strings.h>
#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;
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);
/* 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;