1
0
Fork 0

avcodec/tiff_data: Avoid relocations for TiffGeoTagNameType

Instead store all the strings in one continugous string
(with internal \0) and use offsets to access the actual
substrings. This replaces the pointers to the strings
and therefore avoids relocations (and on x64, it actually
shrinks TiffGeoTagNameType by reusing padding to store
the offset field).

This saves 720B of .data.rel.ro and 1080B of .rela.dyn
(containing the relocation records) here while increasing
.rodata by 384B.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
Andreas Rheinhardt 2024-03-09 16:12:26 +01:00
parent ad6347fc37
commit 282812d6dc
3 changed files with 93 additions and 71 deletions

View File

@ -139,27 +139,31 @@ static void free_geotags(TiffContext *const s)
s->geotag_count = 0;
}
#define RET_GEOKEY(TYPE, array, element)\
if (key >= TIFF_##TYPE##_KEY_ID_OFFSET &&\
key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(tiff_##array##_name_type_map))\
return tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].element;
static const char *get_geokey_name(int key)
{
RET_GEOKEY(VERT, vert, name);
RET_GEOKEY(PROJ, proj, name);
RET_GEOKEY(GEOG, geog, name);
RET_GEOKEY(CONF, conf, name);
#define RET_GEOKEY_STR(TYPE, array)\
if (key >= TIFF_##TYPE##_KEY_ID_OFFSET &&\
key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(tiff_##array##_name_type_map))\
return tiff_##array##_name_type_string + tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].offset;
RET_GEOKEY_STR(VERT, vert);
RET_GEOKEY_STR(PROJ, proj);
RET_GEOKEY_STR(GEOG, geog);
RET_GEOKEY_STR(CONF, conf);
return NULL;
}
static int get_geokey_type(int key)
{
RET_GEOKEY(VERT, vert, type);
RET_GEOKEY(PROJ, proj, type);
RET_GEOKEY(GEOG, geog, type);
RET_GEOKEY(CONF, conf, type);
#define RET_GEOKEY_TYPE(TYPE, array)\
if (key >= TIFF_##TYPE##_KEY_ID_OFFSET &&\
key - TIFF_##TYPE##_KEY_ID_OFFSET < FF_ARRAY_ELEMS(tiff_##array##_name_type_map))\
return tiff_##array##_name_type_map[key - TIFF_##TYPE##_KEY_ID_OFFSET].type;
RET_GEOKEY_TYPE(VERT, vert);
RET_GEOKEY_TYPE(PROJ, proj);
RET_GEOKEY_TYPE(GEOG, geog);
RET_GEOKEY_TYPE(CONF, conf);
return AVERROR_INVALIDDATA;
}

View File

@ -222,9 +222,4 @@ typedef struct TiffGeoTagKeyName {
const char *const name;
} TiffGeoTagKeyName;
typedef struct TiffGeoTagNameType {
const char *const name;
const enum TiffGeoTagType type;
} TiffGeoTagNameType;
#endif /* AVCODEC_TIFF_H */

View File

@ -32,66 +32,89 @@
#include "tiff.h"
typedef struct TiffGeoTagNameType {
enum TiffGeoTagType type;
unsigned offset;
} TiffGeoTagNameType;
#define TIFF_CONF_KEY_ID_OFFSET 1024
static const TiffGeoTagNameType tiff_conf_name_type_map[] = {
{"GTModelTypeGeoKey", GEOTIFF_SHORT },
{"GTRasterTypeGeoKey", GEOTIFF_SHORT },
{"GTCitationGeoKey", GEOTIFF_STRING}
};
#define CONF_NAME_TYPE_MAP(KEY) \
KEY(GTModelTypeGeoKey, SHORT ) \
KEY(GTRasterTypeGeoKey, SHORT ) \
KEY(GTCitationGeoKey, STRING) \
#define TIFF_GEOG_KEY_ID_OFFSET 2048
static const TiffGeoTagNameType tiff_geog_name_type_map[] = {
{"GeographicTypeGeoKey", GEOTIFF_SHORT },
{"GeogCitationGeoKey", GEOTIFF_STRING},
{"GeogGeodeticDatumGeoKey", GEOTIFF_SHORT },
{"GeogPrimeMeridianGeoKey", GEOTIFF_SHORT },
{"GeogLinearUnitsGeoKey", GEOTIFF_SHORT },
{"GeogLinearUnitSizeGeoKey", GEOTIFF_DOUBLE},
{"GeogAngularUnitsGeoKey", GEOTIFF_SHORT },
{"GeogAngularUnitSizeGeoKey", GEOTIFF_DOUBLE},
{"GeogEllipsoidGeoKey", GEOTIFF_SHORT },
{"GeogSemiMajorAxisGeoKey", GEOTIFF_DOUBLE},
{"GeogSemiMinorAxisGeoKey", GEOTIFF_DOUBLE},
{"GeogInvFlatteningGeoKey", GEOTIFF_DOUBLE},
{"GeogAzimuthUnitsGeoKey", GEOTIFF_SHORT },
{"GeogPrimeMeridianLongGeoKey", GEOTIFF_DOUBLE}
};
#define GEOG_NAME_TYPE_MAP(KEY) \
KEY(GeographicTypeGeoKey, SHORT ) \
KEY(GeogCitationGeoKey, STRING) \
KEY(GeogGeodeticDatumGeoKey, SHORT ) \
KEY(GeogPrimeMeridianGeoKey, SHORT ) \
KEY(GeogLinearUnitsGeoKey, SHORT ) \
KEY(GeogLinearUnitSizeGeoKey, DOUBLE) \
KEY(GeogAngularUnitsGeoKey, SHORT ) \
KEY(GeogAngularUnitSizeGeoKey, DOUBLE) \
KEY(GeogEllipsoidGeoKey, SHORT ) \
KEY(GeogSemiMajorAxisGeoKey, DOUBLE) \
KEY(GeogSemiMinorAxisGeoKey, DOUBLE) \
KEY(GeogInvFlatteningGeoKey, DOUBLE) \
KEY(GeogAzimuthUnitsGeoKey, SHORT ) \
KEY(GeogPrimeMeridianLongGeoKey, DOUBLE) \
#define TIFF_PROJ_KEY_ID_OFFSET 3072
static const TiffGeoTagNameType tiff_proj_name_type_map[] = {
{"ProjectedCSTypeGeoKey", GEOTIFF_SHORT },
{"PCSCitationGeoKey", GEOTIFF_STRING},
{"ProjectionGeoKey", GEOTIFF_SHORT },
{"ProjCoordTransGeoKey", GEOTIFF_SHORT },
{"ProjLinearUnitsGeoKey", GEOTIFF_SHORT },
{"ProjLinearUnitSizeGeoKey", GEOTIFF_DOUBLE},
{"ProjStdParallel1GeoKey", GEOTIFF_DOUBLE},
{"ProjStdParallel2GeoKey", GEOTIFF_DOUBLE},
{"ProjNatOriginLongGeoKey", GEOTIFF_DOUBLE},
{"ProjNatOriginLatGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseEastingGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseNorthingGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseOriginLongGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseOriginLatGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseOriginEastingGeoKey", GEOTIFF_DOUBLE},
{"ProjFalseOriginNorthingGeoKey", GEOTIFF_DOUBLE},
{"ProjCenterLongGeoKey", GEOTIFF_DOUBLE},
{"ProjCenterLatGeoKey", GEOTIFF_DOUBLE},
{"ProjCenterEastingGeoKey", GEOTIFF_DOUBLE},
{"ProjCenterNorthingGeoKey", GEOTIFF_DOUBLE},
{"ProjScaleAtNatOriginGeoKey", GEOTIFF_DOUBLE},
{"ProjScaleAtCenterGeoKey", GEOTIFF_DOUBLE},
{"ProjAzimuthAngleGeoKey", GEOTIFF_DOUBLE},
{"ProjStraightVertPoleLongGeoKey", GEOTIFF_DOUBLE}
};
#define PROJ_NAME_TYPE_MAP(KEY) \
KEY(ProjectedCSTypeGeoKey, SHORT ) \
KEY(PCSCitationGeoKey, STRING) \
KEY(ProjectionGeoKey, SHORT ) \
KEY(ProjCoordTransGeoKey, SHORT ) \
KEY(ProjLinearUnitsGeoKey, SHORT ) \
KEY(ProjLinearUnitSizeGeoKey, DOUBLE) \
KEY(ProjStdParallel1GeoKey, DOUBLE) \
KEY(ProjStdParallel2GeoKey, DOUBLE) \
KEY(ProjNatOriginLongGeoKey, DOUBLE) \
KEY(ProjNatOriginLatGeoKey, DOUBLE) \
KEY(ProjFalseEastingGeoKey, DOUBLE) \
KEY(ProjFalseNorthingGeoKey, DOUBLE) \
KEY(ProjFalseOriginLongGeoKey, DOUBLE) \
KEY(ProjFalseOriginLatGeoKey, DOUBLE) \
KEY(ProjFalseOriginEastingGeoKey, DOUBLE) \
KEY(ProjFalseOriginNorthingGeoKey, DOUBLE) \
KEY(ProjCenterLongGeoKey, DOUBLE) \
KEY(ProjCenterLatGeoKey, DOUBLE) \
KEY(ProjCenterEastingGeoKey, DOUBLE) \
KEY(ProjCenterNorthingGeoKey, DOUBLE) \
KEY(ProjScaleAtNatOriginGeoKey, DOUBLE) \
KEY(ProjScaleAtCenterGeoKey, DOUBLE) \
KEY(ProjAzimuthAngleGeoKey, DOUBLE) \
KEY(ProjStraightVertPoleLongGeoKey, DOUBLE) \
#define TIFF_VERT_KEY_ID_OFFSET 4096
static const TiffGeoTagNameType tiff_vert_name_type_map[] = {
{"VerticalCSTypeGeoKey", GEOTIFF_SHORT },
{"VerticalCitationGeoKey", GEOTIFF_STRING},
{"VerticalDatumGeoKey", GEOTIFF_SHORT },
{"VerticalUnitsGeoKey", GEOTIFF_SHORT }
};
#define VERT_NAME_TYPE_MAP(KEY) \
KEY(VerticalCSTypeGeoKey, SHORT ) \
KEY(VerticalCitationGeoKey, STRING) \
KEY(VerticalDatumGeoKey, SHORT ) \
KEY(VerticalUnitsGeoKey, SHORT ) \
#define ADD_OFFSET(NAME, TYPE) \
NAME ## _OFFSET, \
NAME ## _END = NAME ## _OFFSET + sizeof(#NAME) - 1, \
#define STRING(NAME, TYPE) #NAME "\0"
#define ENTRY(NAME, TYPE) { .type = GEOTIFF_ ## TYPE, .offset = NAME ## _OFFSET },
#define NAME_TYPE_MAP(NAME, name) \
enum { \
NAME ## _NAME_TYPE_MAP(ADD_OFFSET) \
}; \
static const TiffGeoTagNameType tiff_ ## name ## _name_type_map[] = { \
NAME ## _NAME_TYPE_MAP(ENTRY) \
}; \
static const char *const tiff_ ## name ## _name_type_string = \
NAME ## _NAME_TYPE_MAP(STRING)
NAME_TYPE_MAP(CONF, conf);
NAME_TYPE_MAP(GEOG, geog);
NAME_TYPE_MAP(PROJ, proj);
NAME_TYPE_MAP(VERT, vert);
#define TIFF_GEO_KEY_UNDEFINED 0
#define TIFF_GEO_KEY_USER_DEFINED 32767