Skip to content

Commit 80cfd99

Browse files
committed
Reduce reallocations in exif parsing
Instead of reallocating lists element by element, increase the allocated list size exponentially.
1 parent 11649a6 commit 80cfd99

File tree

1 file changed

+25
-32
lines changed

1 file changed

+25
-32
lines changed

ext/exif/exif.c

Lines changed: 25 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,6 +1760,7 @@ typedef struct {
17601760

17611761
typedef struct {
17621762
int count;
1763+
int alloc_count;
17631764
image_info_data *list;
17641765
} image_info_list;
17651766
/* }}} */
@@ -1880,6 +1881,7 @@ typedef struct {
18801881

18811882
typedef struct {
18821883
int count;
1884+
int alloc_count;
18831885
file_section *list;
18841886
} file_section_list;
18851887

@@ -2004,11 +2006,14 @@ typedef struct {
20042006
*/
20052007
static int exif_file_sections_add(image_info_type *ImageInfo, int type, size_t size, uchar *data)
20062008
{
2007-
file_section *tmp;
2008-
int count = ImageInfo->file.count;
2009+
int count = ImageInfo->file.count;
2010+
if (count == ImageInfo->file.alloc_count) {
2011+
int new_alloc_count = ImageInfo->file.alloc_count ? ImageInfo->file.alloc_count * 2 : 1;
2012+
ImageInfo->file.list = safe_erealloc(
2013+
ImageInfo->file.list, new_alloc_count, sizeof(file_section), 0);
2014+
ImageInfo->file.alloc_count = new_alloc_count;
2015+
}
20092016

2010-
tmp = safe_erealloc(ImageInfo->file.list, (count+1), sizeof(file_section), 0);
2011-
ImageInfo->file.list = tmp;
20122017
ImageInfo->file.list[count].type = 0xFFFF;
20132018
ImageInfo->file.list[count].data = NULL;
20142019
ImageInfo->file.list[count].size = 0;
@@ -2064,6 +2069,16 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
20642069
}
20652070
/* }}} */
20662071

2072+
static image_info_data *exif_alloc_image_info_data(image_info_list *info_list) {
2073+
if (info_list->count == info_list->alloc_count) {
2074+
int new_alloc_count = info_list->alloc_count ? info_list->alloc_count * 2 : 1;
2075+
info_list->list = safe_erealloc(
2076+
info_list->list, new_alloc_count, sizeof(image_info_data), 0);
2077+
info_list->alloc_count = new_alloc_count;
2078+
}
2079+
return &info_list->list[info_list->count++];
2080+
}
2081+
20672082
/* {{{ exif_iif_add_value
20682083
Add a value to image_info
20692084
*/
@@ -2073,16 +2088,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
20732088
void *vptr, *vptr_end;
20742089
image_info_value *info_value;
20752090
image_info_data *info_data;
2076-
image_info_data *list;
20772091

20782092
if (length < 0) {
20792093
return;
20802094
}
20812095

2082-
list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
2083-
image_info->info_list[section_index].list = list;
2084-
2085-
info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
2096+
info_data = exif_alloc_image_info_data(&image_info->info_list[section_index]);
20862097
memset(info_data, 0, sizeof(image_info_data));
20872098
info_data->tag = tag;
20882099
info_data->format = format;
@@ -2205,7 +2216,6 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
22052216
}
22062217
}
22072218
image_info->sections_found |= 1<<section_index;
2208-
image_info->info_list[section_index].count++;
22092219
}
22102220
/* }}} */
22112221

@@ -2223,20 +2233,13 @@ static void exif_iif_add_tag(image_info_type *image_info, int section_index, cha
22232233
*/
22242234
static void exif_iif_add_int(image_info_type *image_info, int section_index, char *name, int value)
22252235
{
2226-
image_info_data *info_data;
2227-
image_info_data *list;
2228-
2229-
list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
2230-
image_info->info_list[section_index].list = list;
2231-
2232-
info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
2236+
image_info_data *info_data = exif_alloc_image_info_data(&image_info->info_list[section_index]);
22332237
info_data->tag = TAG_NONE;
22342238
info_data->format = TAG_FMT_SLONG;
22352239
info_data->length = 1;
22362240
info_data->name = estrdup(name);
22372241
info_data->value.i = value;
22382242
image_info->sections_found |= 1<<section_index;
2239-
image_info->info_list[section_index].count++;
22402243
}
22412244
/* }}} */
22422245

@@ -2245,20 +2248,15 @@ static void exif_iif_add_int(image_info_type *image_info, int section_index, cha
22452248
*/
22462249
static void exif_iif_add_str(image_info_type *image_info, int section_index, char *name, char *value)
22472250
{
2248-
image_info_data *info_data;
2249-
image_info_data *list;
2250-
22512251
if (value) {
2252-
list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
2253-
image_info->info_list[section_index].list = list;
2254-
info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
2252+
image_info_data *info_data =
2253+
exif_alloc_image_info_data(&image_info->info_list[section_index]);
22552254
info_data->tag = TAG_NONE;
22562255
info_data->format = TAG_FMT_STRING;
22572256
info_data->length = 1;
22582257
info_data->name = estrdup(name);
22592258
info_data->value.s = estrdup(value);
22602259
image_info->sections_found |= 1<<section_index;
2261-
image_info->info_list[section_index].count++;
22622260
}
22632261
}
22642262
/* }}} */
@@ -2286,13 +2284,9 @@ static void exif_iif_add_fmt(image_info_type *image_info, int section_index, cha
22862284
*/
22872285
static void exif_iif_add_buffer(image_info_type *image_info, int section_index, char *name, int length, char *value)
22882286
{
2289-
image_info_data *info_data;
2290-
image_info_data *list;
2291-
22922287
if (value) {
2293-
list = safe_erealloc(image_info->info_list[section_index].list, (image_info->info_list[section_index].count+1), sizeof(image_info_data), 0);
2294-
image_info->info_list[section_index].list = list;
2295-
info_data = &image_info->info_list[section_index].list[image_info->info_list[section_index].count];
2288+
image_info_data *info_data =
2289+
exif_alloc_image_info_data(&image_info->info_list[section_index]);
22962290
info_data->tag = TAG_NONE;
22972291
info_data->format = TAG_FMT_UNDEFINED;
22982292
info_data->length = length;
@@ -2301,7 +2295,6 @@ static void exif_iif_add_buffer(image_info_type *image_info, int section_index,
23012295
memcpy(info_data->value.s, value, length);
23022296
info_data->value.s[length] = 0;
23032297
image_info->sections_found |= 1<<section_index;
2304-
image_info->info_list[section_index].count++;
23052298
}
23062299
}
23072300
/* }}} */

0 commit comments

Comments
 (0)