diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-06-13 23:27:11 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-06-13 23:27:11 -0400 |
commit | ce05759b5e485dee64489a5940c61ab40ffa16de (patch) | |
tree | a2b40754de0e3ae5cfc091367cd5f8d8c0bc8a65 | |
parent | 5bbefcb3209ad43564e8b49a52acf211434e3c94 (diff) |
Some tweaks to reallocation
-rw-r--r-- | region-iter.c | 51 |
1 files changed, 27 insertions, 24 deletions
diff --git a/region-iter.c b/region-iter.c index 9acbe97..96cd675 100644 --- a/region-iter.c +++ b/region-iter.c @@ -77,32 +77,37 @@ next_power (size_t n) return r; } +static void * +realloc_ab_plus_c (void *m, unsigned int a, unsigned int b, unsigned int c) +{ + if (b && a >= INT32_MAX / b) + return NULL; + + if (c >= INT32_MAX - a * b) + return NULL; + + return realloc (m, a * b + c); +} + static pixman_region32_data_t * region_data_append (pixman_region32_data_t *data, int n) { - size_t new_size = next_power ((data? data->numRects : 0) + n); - - new_size = - sizeof (pixman_region32_data_t) + sizeof (pixman_box32_t) * new_size; + size_t new_size, n_rects; - if (!data) - { - data = malloc (new_size); + n_rects = data? data->numRects : 0; + new_size = next_power (n_rects + n); - if (!data) - return NULL; + if (data && data->size == new_size) + return data; - data->numRects = 0; - } - else + if ((data = realloc_ab_plus_c ( + data, new_size, sizeof (pixman_box32_t), + sizeof (pixman_region32_data_t)))) { - data = realloc (data, new_size); - - if (!data) - return NULL; + data->numRects = n_rects; + data->size = new_size; } - data->size = new_size; return data; } @@ -173,14 +178,14 @@ region_builder_add_box (region_builder_t *builder, if (builder->data == BROKEN_DATA) return FALSE; - if (!(builder->data = region_data_append (builder->data, 1))) + if (!(data = region_data_append (builder->data, 1))) { free (builder->data); builder->data = BROKEN_DATA; return FALSE; } - data = builder->data; + builder->data = data; if (data->numRects == 0) last_box = NULL; @@ -194,7 +199,6 @@ region_builder_add_box (region_builder_t *builder, else if (x1 == last_box->x2) { last_box->x2 = x2; - printf ("coal\n"); return; } } @@ -204,8 +208,6 @@ region_builder_add_box (region_builder_t *builder, last_box->y1 = y1; last_box->x2 = x2; last_box->y2 = y2; - - printf ("added box now %d\n", data->numRects); } static pixman_bool_t @@ -352,7 +354,8 @@ region_iter_get_row (region_iter_t *iter, row_t *row) return TRUE; } -/* Overlapped iter */ +/* Overlapped iter + */ typedef struct overlapped_iter_t overlapped_iter_t; struct overlapped_iter_t { @@ -577,7 +580,7 @@ segment_iter_get_segment (segment_iter_t *iter, segment_t *segment) typedef enum { INTERSECT = (1 << BOTH), - SUBTRACT = (1 << ROW1) + SUBTRACT = (1 << ROW1), XOR = (1 << ROW1) | (1 << ROW2), UNION = (1 << BOTH) | (1 << ROW1) | (1 << ROW2), } ops_t; |