Skip to content

Commit 56e3e6f

Browse files
committed
Implement a cache for exif tag name lookups
1 parent e5324a2 commit 56e3e6f

File tree

1 file changed

+54
-13
lines changed

1 file changed

+54
-13
lines changed

ext/exif/exif.c

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ ZEND_BEGIN_MODULE_GLOBALS(exif)
132132
char * encode_jis;
133133
char * decode_jis_be;
134134
char * decode_jis_le;
135+
HashTable *tag_table_cache;
135136
ZEND_END_MODULE_GLOBALS(exif)
136137

137138
ZEND_DECLARE_MODULE_GLOBALS(exif)
@@ -197,6 +198,7 @@ static PHP_GINIT_FUNCTION(exif)
197198
exif_globals->encode_jis = NULL;
198199
exif_globals->decode_jis_be = NULL;
199200
exif_globals->decode_jis_le = NULL;
201+
exif_globals->tag_table_cache = NULL;
200202
}
201203
/* }}} */
202204

@@ -219,6 +221,10 @@ PHP_MINIT_FUNCTION(exif)
219221
PHP_MSHUTDOWN_FUNCTION(exif)
220222
{
221223
UNREGISTER_INI_ENTRIES();
224+
if (EXIF_G(tag_table_cache)) {
225+
zend_hash_destroy(EXIF_G(tag_table_cache));
226+
free(EXIF_G(tag_table_cache));
227+
}
222228
return SUCCESS;
223229
}
224230
/* }}} */
@@ -721,7 +727,6 @@ static tag_info_array tag_table_IFD = {
721727
{ 0x8773, "ICC_Profile"},
722728
{ 0x8822, "ExposureProgram"},
723729
{ 0x8824, "SpectralSensity"},
724-
{ 0x8828, "OECF"},
725730
{ 0x8825, "GPS_IFD_Pointer"},
726731
{ 0x8827, "ISOSpeedRatings"},
727732
{ 0x8828, "OECF"},
@@ -1350,25 +1355,61 @@ static const maker_note_type maker_note_array[] = {
13501355
};
13511356
/* }}} */
13521357

1358+
static HashTable *exif_make_tag_ht(tag_info_type *tag_table)
1359+
{
1360+
HashTable *ht = malloc(sizeof(HashTable));
1361+
zend_hash_init(ht, 0, NULL, NULL, 1);
1362+
while (tag_table->Tag != TAG_END_OF_LIST) {
1363+
if (!zend_hash_index_add_ptr(ht, tag_table->Tag, tag_table->Desc)) {
1364+
zend_error(E_CORE_ERROR, "Duplicate tag %x", tag_table->Tag);
1365+
}
1366+
tag_table++;
1367+
}
1368+
return ht;
1369+
}
1370+
1371+
static void exif_tag_ht_dtor(zval *zv)
1372+
{
1373+
HashTable *ht = Z_PTR_P(zv);
1374+
zend_hash_destroy(ht);
1375+
free(ht);
1376+
}
1377+
1378+
static HashTable *exif_get_tag_ht(tag_info_type *tag_table)
1379+
{
1380+
HashTable *ht;
1381+
1382+
if (!EXIF_G(tag_table_cache)) {
1383+
EXIF_G(tag_table_cache) = malloc(sizeof(HashTable));
1384+
zend_hash_init(EXIF_G(tag_table_cache), 0, NULL, exif_tag_ht_dtor, 1);
1385+
}
1386+
1387+
ht = zend_hash_index_find_ptr(EXIF_G(tag_table_cache), (uintptr_t) tag_table);
1388+
if (ht) {
1389+
return ht;
1390+
}
1391+
1392+
ht = exif_make_tag_ht(tag_table);
1393+
zend_hash_index_add_new_ptr(EXIF_G(tag_table_cache), (uintptr_t) tag_table, ht);
1394+
return ht;
1395+
}
1396+
13531397
/* {{{ exif_get_tagname
13541398
Get headername for tag_num or NULL if not defined */
13551399
static char * exif_get_tagname(int tag_num, char *ret, int len, tag_table_type tag_table)
13561400
{
1357-
int i, t;
13581401
char tmp[32];
1359-
1360-
for (i = 0; (t = tag_table[i].Tag) != TAG_END_OF_LIST; i++) {
1361-
if (t == tag_num) {
1362-
if (ret && len) {
1363-
strlcpy(ret, tag_table[i].Desc, abs(len));
1364-
if (len < 0) {
1365-
memset(ret + strlen(ret), ' ', -len - strlen(ret) - 1);
1366-
ret[-len - 1] = '\0';
1367-
}
1368-
return ret;
1402+
char *desc = zend_hash_index_find_ptr(exif_get_tag_ht(tag_table), tag_num);
1403+
if (desc) {
1404+
if (ret && len) {
1405+
strlcpy(ret, desc, abs(len));
1406+
if (len < 0) {
1407+
memset(ret + strlen(ret), ' ', -len - strlen(ret) - 1);
1408+
ret[-len - 1] = '\0';
13691409
}
1370-
return tag_table[i].Desc;
1410+
return ret;
13711411
}
1412+
return desc;
13721413
}
13731414

13741415
if (ret && len) {

0 commit comments

Comments
 (0)