summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-06-13 23:27:11 -0400
committerSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-06-13 23:27:11 -0400
commitce05759b5e485dee64489a5940c61ab40ffa16de (patch)
treea2b40754de0e3ae5cfc091367cd5f8d8c0bc8a65
parent5bbefcb3209ad43564e8b49a52acf211434e3c94 (diff)
Some tweaks to reallocation
-rw-r--r--region-iter.c51
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;