]> git.tdb.fi Git - ttf2png.git/commitdiff
Refactor image initialization
authorMikko Rasa <tdb@tdb.fi>
Sat, 5 May 2018 12:47:17 +0000 (15:47 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 5 May 2018 12:47:17 +0000 (15:47 +0300)
ttf2png.c

index 6543a8d8a009b2de12f898c6effcb964707012b1..93576c1eb4daec90ec7db69f8ad3efac83060302 100644 (file)
--- a/ttf2png.c
+++ b/ttf2png.c
@@ -77,7 +77,7 @@ void convert_size(char, unsigned *, unsigned *);
 void sort_and_compact_ranges(Range *, unsigned *);
 int range_cmp(const void *, const void *);
 unsigned round_to_pot(unsigned);
-void *alloc_image_data(size_t, size_t);
+int init_image(Image *, size_t, size_t);
 int init_font(Font *, FT_Face, const Range *, unsigned, bool, unsigned, unsigned);
 int init_glyphs(Font *, FT_Face, const Range *, bool, unsigned, unsigned);
 int copy_bitmap(const FT_Bitmap *, Image *);
@@ -487,28 +487,32 @@ unsigned round_to_pot(unsigned n)
        return n+1;
 }
 
-void *alloc_image_data(size_t a, size_t b)
+int init_image(Image *image, size_t w, size_t h)
 {
-       void *ptr;
+       size_t s;
 
-       /* Carry out the multiplication manually so we can check for overflow. */
-       while(b>1)
+       image->w = w;
+       image->h = h;
+       image->data = NULL;
+
+       if(!image->w || !image->h)
+               return 0;
+
+       s = w*h;
+       if(s/h!=w)
        {
-               size_t c = a;
-               a *= 2;
-               if(b&1)
-                       a += c;
-               if(a<c)
-               {
-                       fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(c/1024*b));
-                       return NULL;
-               }
-               b /= 2;
+               fprintf(stderr, "Cannot allocate memory for a %dx%d image\n", image->w, image->h);
+               return -1;
+       }
+
+       image->data = malloc(s);
+       if(!image->data)
+       {
+               fprintf(stderr, "Cannot allocate memory for a %dx%d image\n", image->w, image->h);
+               return -1;
        }
-       ptr = malloc(a);
-       if(!ptr)
-               fprintf(stderr, "Cannot allocate %lu kbytes of memory for image\n", (unsigned long)(a/1024*b));
-       return ptr;
+
+       return 0;
 }
 
 int init_font(Font *font, FT_Face face, const Range *ranges, unsigned n_ranges, bool autohinter, unsigned distfield, unsigned border)
@@ -655,20 +659,10 @@ int copy_bitmap(const FT_Bitmap *bmp, Image *image)
        unsigned char *src;
        unsigned char *dst;
 
-       image->w = bmp->width;
-       image->h = bmp->rows;
+       if(init_image(image, bmp->width, bmp->rows))
+               return -1;
        if(!image->w || !image->h)
-       {
-               image->data = NULL;
                return 0;
-       }
-
-       image->data = (unsigned char *)malloc(image->w*image->h);
-       if(!image->data)
-       {
-               fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", image->w*image->h);
-               return -1;
-       }
 
        if(bmp->pitch<0)
                src = bmp->buffer+(bmp->rows-1)*-bmp->pitch;
@@ -746,27 +740,14 @@ int create_distance_field(const FT_Bitmap *bmp, Image *image, unsigned scale, un
        unsigned x, y;
        Image base_image;
 
-       if(!bmp->width || !bmp->rows)
-       {
-               image->w = 0;
-               image->h = 0;
-               image->data = NULL;
+       if(init_image(image, (bmp->width+scale-1)/scale+2*margin, (bmp->rows+scale-1)/scale+2*margin))
+               return -1;
+       if(!image->w || !image->h)
                return 0;
-       }
 
        if(copy_bitmap(bmp, &base_image))
                return -1;
 
-       image->w = (base_image.w-1)/scale+2*margin+1;
-       image->h = (base_image.h-1)/scale+2*margin+1;
-       image->data = (unsigned char *)malloc(image->w*image->h);
-       if(!image->data)
-       {
-               fprintf(stderr, "Cannot allocate %d bytes of memory for glyph\n", image->w*image->h);
-               free(base_image.data);
-               return -1;
-       }
-
        for(y=0; y<image->h; ++y) for(x=0; x<image->w; ++x)
        {
                int bx = (x-margin)*scale+scale/2;
@@ -788,7 +769,7 @@ int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool s
 {
        unsigned i;
        int top = 0, bot = 0;
-       unsigned first, last;
+       unsigned first, n_cells;
        unsigned maxw = 0, maxh = 0;
 
        /* Find extremes of the glyph images. */
@@ -844,18 +825,15 @@ int render_grid(Font *font, unsigned cellw, unsigned cellh, unsigned cpl, bool s
        }
 
        first = font->glyphs[0].code;
-       if(!seq)
-               first -= first%cpl;
-       last = font->glyphs[font->n_glyphs-1].code;
-
-       font->image.w = cpl*cellw;
        if(seq)
-               font->image.h = (font->n_glyphs+cpl-1)/cpl*cellh;
+               n_cells = font->n_glyphs;
        else
-               font->image.h = (last-first+cpl)/cpl*cellh;
+       {
+               first -= first%cpl;
+               n_cells = font->glyphs[font->n_glyphs-1].code+1-first;
+       }
 
-       font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h);
-       if(!font->image.data)
+       if(init_image(&font->image, cpl*cellw, (n_cells+cpl-1)/cpl*cellh))
                return -1;
        memset(font->image.data, 0, font->image.w*font->image.h);
 
@@ -931,8 +909,7 @@ int render_packed(Font *font, unsigned margin, unsigned padding)
        glyphs.  Since glyphs are rectangular and the image is filled starting from
        the top, it's enough to track the number of used pixels at the top of each
        column. */
-       font->image.data = (unsigned char *)alloc_image_data(font->image.w, font->image.h);
-       if(!font->image.data)
+       if(init_image(&font->image, font->image.w, font->image.h))
                return -1;
        memset(font->image.data, 0, font->image.w*font->image.h);
        used_pixels = (unsigned *)malloc(font->image.w*sizeof(unsigned));