Coverage Report

Created: 2025-06-13 06:18

/src/gdal/frmts/gtiff/libgeotiff/geo_names.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * geo_names.c
3
 *
4
 *  This encapsulates all of the value-naming mechanism of
5
 *  libgeotiff.
6
 *
7
 *  Written By: Niles Ritter
8
 *
9
 *  copyright (c) 1995   Niles D. Ritter
10
 *
11
 *  Permission granted to use this software, so long as this copyright
12
 *  notice accompanies any products derived therefrom.
13
 *
14
 */
15
16
#include "geotiffio.h"
17
#include "geonames.h"
18
#include "geo_tiffp.h" /* for tag names */
19
#include "geo_keyp.h"
20
21
#include "proj.h"
22
23
static const KeyInfo _formatInfo[] =  {
24
   {TYPE_BYTE,    "Byte"},
25
   {TYPE_SHORT,   "Short"},
26
   {TYPE_LONG,    "Long"},
27
   {TYPE_RATIONAL,"Rational"},
28
   {TYPE_ASCII,   "Ascii"},
29
   {TYPE_FLOAT,   "Float"},
30
   {TYPE_DOUBLE,  "Double"},
31
   {TYPE_SBYTE,   "SignedByte"},
32
   {TYPE_SSHORT,  "SignedShort"},
33
   {TYPE_SLONG,  "SignedLong"},
34
   {TYPE_UNKNOWN, "Unknown"},
35
    END_LIST
36
};
37
38
static const KeyInfo _tagInfo[] =  {
39
    {GTIFF_PIXELSCALE,  "ModelPixelScaleTag"},
40
    {GTIFF_TRANSMATRIX, "ModelTransformationTag"},
41
    {GTIFF_TIEPOINTS,   "ModelTiepointTag"},
42
     /* This alias maps the Intergraph symbol to the current tag */
43
    {GTIFF_TRANSMATRIX, "IntergraphMatrixTag"},
44
    END_LIST
45
};
46
47
static const char *FindName(const KeyInfo *info,int key)
48
0
{
49
0
   while (info->ki_key>=0 && info->ki_key != key) info++;
50
51
0
   if (info->ki_key<0)
52
0
   {
53
0
     static char errmsg[80];
54
0
     sprintf(errmsg,"Unknown-%d", key );
55
0
     return errmsg;
56
0
   }
57
0
   return info->ki_name;
58
0
}
59
60
char *GTIFKeyName(geokey_t key)
61
0
{
62
0
   return (char*) FindName( &_keyInfo[0],key);
63
0
}
64
65
const char* GTIFKeyNameEx(GTIF* gtif, geokey_t key)
66
0
{
67
0
    const KeyInfo *info;
68
0
    if( gtif->gt_version == GEOTIFF_SPEC_1_0_VERSION &&
69
0
        gtif->gt_rev_major == GEOTIFF_SPEC_1_0_KEY_REVISION &&
70
0
        gtif->gt_rev_minor == GEOTIFF_SPEC_1_0_MINOR_REVISION )
71
0
    {
72
0
        info = &_keyInfo[0];
73
0
    }
74
0
    else
75
0
    {
76
0
        info = &_keyInfoV11[0];
77
0
    }
78
0
    while (info->ki_key>=0 && info->ki_key != (int)key) info++;
79
0
    if (info->ki_key<0)
80
0
    {
81
0
        sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", key );
82
0
        return gtif->szTmpBufferForGTIFValueNameEx;
83
0
    }
84
0
    return info->ki_name;
85
0
}
86
87
char *GTIFTypeName(tagtype_t type)
88
0
{
89
0
   return (char*) FindName( &_formatInfo[0],type);
90
0
}
91
92
char *GTIFTagName(int tag)
93
0
{
94
0
   return (char*) FindName( &_tagInfo[0],tag);
95
0
}
96
97
static const KeyInfo* FindTable(geokey_t key)
98
0
{
99
0
   const KeyInfo *info;
100
101
0
   switch (key)
102
0
   {
103
  /* All codes using linear/angular/whatever units */
104
0
  case GeogLinearUnitsGeoKey:
105
0
  case ProjLinearUnitsGeoKey:
106
0
  case GeogAngularUnitsGeoKey:
107
0
  case GeogAzimuthUnitsGeoKey:
108
0
  case VerticalUnitsGeoKey:
109
0
                          info=_geounitsValue; break;
110
111
    /* put other key-dependent lists here */
112
0
  case GTModelTypeGeoKey:       info=_modeltypeValue; break;
113
0
  case GTRasterTypeGeoKey:      info=_rastertypeValue; break;
114
0
  case GeographicTypeGeoKey:    info=_geographicValue; break;
115
0
  case GeogGeodeticDatumGeoKey: info=_geodeticdatumValue; break;
116
0
  case GeogEllipsoidGeoKey:     info=_ellipsoidValue; break;
117
0
  case GeogPrimeMeridianGeoKey: info=_primemeridianValue; break;
118
0
  case ProjectedCSTypeGeoKey:   info=_pcstypeValue; break;
119
0
  case ProjectionGeoKey:        info=_projectionValue; break;
120
0
  case ProjCoordTransGeoKey:    info=_coordtransValue; break;
121
0
  case VerticalCSTypeGeoKey:    info=_vertcstypeValue; break;
122
0
  case VerticalDatumGeoKey:     info=_vdatumValue; break;
123
124
  /* And if all else fails... */
125
0
    default:                      info = _csdefaultValue;break;
126
0
   }
127
128
0
   return info;
129
0
}
130
131
char *GTIFValueName(geokey_t key, int value)
132
0
{
133
134
0
   return (char*) FindName(FindTable(key), value);
135
0
}
136
137
static void GetNameFromDatabase(GTIF* gtif,
138
                                const char* pszCode,
139
                                PJ_CATEGORY category,
140
                                char* pszOut,
141
                                size_t nOutSize)
142
0
{
143
0
    PJ* obj = proj_create_from_database(
144
0
        gtif->pj_context, "EPSG", pszCode, category,
145
0
        FALSE, NULL);
146
0
    if( obj )
147
0
    {
148
0
        const char* pszName = proj_get_name(obj);
149
0
        if( pszName )
150
0
        {
151
0
            size_t nToCopy = MIN(strlen(pszName), nOutSize - 1);
152
0
            memcpy(pszOut, pszName, nToCopy);
153
0
            pszOut[nToCopy] = 0;
154
0
        }
155
0
        proj_destroy(obj);
156
0
    }
157
0
    else
158
0
    {
159
0
        pszOut[0] = 0;
160
0
    }
161
0
}
162
163
const char *GTIFValueNameEx(GTIF* gtif, geokey_t key, int value)
164
0
{
165
0
    int useHardcodedTables = 0;
166
167
0
    if( value == KvUndefined || value == KvUserDefined )
168
0
    {
169
0
        useHardcodedTables = 1;
170
0
    }
171
0
    else if( gtif->gt_version == GEOTIFF_SPEC_1_0_VERSION &&
172
0
             gtif->gt_rev_major == GEOTIFF_SPEC_1_0_KEY_REVISION &&
173
0
             gtif->gt_rev_minor == GEOTIFF_SPEC_1_0_MINOR_REVISION )
174
0
    {
175
0
        useHardcodedTables = 1;
176
0
    }
177
0
    else if( key == GTModelTypeGeoKey ||
178
0
             key == GTRasterTypeGeoKey ||
179
0
             key == ProjCoordTransGeoKey )
180
0
    {
181
0
        useHardcodedTables = 1;
182
0
    }
183
0
    else if( key == VerticalCSTypeGeoKey &&
184
0
             value >= 5001 && value <= 5033 )
185
0
    {
186
0
        useHardcodedTables = 1;
187
0
    }
188
189
0
    const KeyInfo *info = FindTable(key);
190
0
    if( useHardcodedTables )
191
0
    {
192
0
        while (info->ki_key>=0 && info->ki_key != value) info++;
193
0
    }
194
195
0
    if ( !useHardcodedTables || info->ki_key<0 )
196
0
    {
197
0
        sprintf(gtif->szTmpBufferForGTIFValueNameEx,"Unknown-%d", value );
198
199
0
        if( gtif->pj_context == NULL )
200
0
        {
201
0
            gtif->pj_context = proj_context_create();
202
0
            if( gtif->pj_context )
203
0
            {
204
0
                gtif->own_pj_context = TRUE;
205
0
            }
206
0
        }
207
0
        if( gtif->pj_context )
208
0
        {
209
0
            char szCode[12];
210
0
            char szName[120];
211
212
0
            szName[0] = 0;
213
0
            sprintf(szCode, "%d", value);
214
215
0
            switch (key)
216
0
            {
217
                /* All codes using linear/angular/whatever units */
218
0
                case GeogLinearUnitsGeoKey:
219
0
                case ProjLinearUnitsGeoKey:
220
0
                case GeogAngularUnitsGeoKey:
221
0
                case GeogAzimuthUnitsGeoKey:
222
0
                case VerticalUnitsGeoKey:
223
0
                {
224
0
                    const char* pszName = NULL;
225
0
                    if( proj_uom_get_info_from_database(gtif->pj_context,
226
0
                         "EPSG", szCode, &pszName, NULL, NULL) && pszName )
227
0
                    {
228
0
                        strncpy(szName, pszName, sizeof(szName));
229
0
                        szName[sizeof(szName)-1] = 0;
230
0
                    }
231
0
                    break;
232
0
                }
233
234
0
                case GeogGeodeticDatumGeoKey:
235
0
                case VerticalDatumGeoKey:
236
0
                    GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_DATUM,
237
0
                                        szName, sizeof(szName));
238
0
                    break;
239
240
0
                case GeogEllipsoidGeoKey:
241
0
                    GetNameFromDatabase(gtif, szCode, PJ_CATEGORY_ELLIPSOID,
242
0
                                        szName, sizeof(szName));
243
0
                    break;
244
245
0
                case GeogPrimeMeridianGeoKey:
246
0
                    GetNameFromDatabase(gtif, szCode,
247
0
                                        PJ_CATEGORY_PRIME_MERIDIAN,
248
0
                                        szName, sizeof(szName));
249
0
                    break;
250
251
0
                case GeographicTypeGeoKey:
252
0
                case ProjectedCSTypeGeoKey:
253
0
                case VerticalCSTypeGeoKey:
254
0
                    GetNameFromDatabase(gtif, szCode,
255
0
                                        PJ_CATEGORY_CRS,
256
0
                                        szName, sizeof(szName));
257
0
                    break;
258
259
0
                case ProjectionGeoKey:
260
0
                    GetNameFromDatabase(gtif, szCode,
261
0
                                        PJ_CATEGORY_COORDINATE_OPERATION,
262
0
                                        szName, sizeof(szName));
263
0
                    break;
264
265
0
                default:
266
0
                    break;
267
0
            }
268
269
0
            if( szName[0] != 0 )
270
0
            {
271
0
                sprintf(gtif->szTmpBufferForGTIFValueNameEx,
272
0
                        "Code-%d (%s)", value, szName );
273
0
            }
274
275
0
        }
276
277
0
        return gtif->szTmpBufferForGTIFValueNameEx;
278
0
    }
279
0
    return info->ki_name;
280
0
}
281
282
/*
283
 * Inverse Utilities (name->code)
284
 */
285
286
287
static int FindCode(const KeyInfo *info,const char *key)
288
0
{
289
0
   while (info->ki_key>=0 && strcmp(info->ki_name,key) ) info++;
290
291
0
   if (info->ki_key<0)
292
0
   {
293
  /* not a registered key; might be generic code */
294
0
  if (!strncmp(key,"Unknown-",8))
295
0
  {
296
0
    int code=-1;
297
0
    sscanf(key,"Unknown-%d",&code);
298
0
    return code;
299
0
  } else if (!strncmp(key,"Code-",5))
300
0
  {
301
0
    int code=-1;
302
0
    sscanf(key,"Code-%d",&code);
303
0
    return code;
304
0
  }
305
0
  else return -1;
306
0
   }
307
0
   return info->ki_key;
308
0
}
309
310
int GTIFKeyCode(const char *key)
311
0
{
312
0
   int ret = FindCode( &_keyInfo[0],key);
313
0
   if( ret < 0 )
314
0
       ret = FindCode( &_keyInfoV11[0],key);
315
0
   return ret;
316
0
}
317
318
int GTIFTypeCode(const char *type)
319
0
{
320
0
   return FindCode( &_formatInfo[0],type);
321
0
}
322
323
int GTIFTagCode(const char *tag)
324
0
{
325
0
   return FindCode( &_tagInfo[0],tag);
326
0
}
327
328
329
/*
330
 *  The key must be determined with GTIFKeyCode() before
331
 *  the name can be encoded.
332
 */
333
int GTIFValueCode(geokey_t key, const char *name)
334
0
{
335
0
   return FindCode(FindTable(key),name);
336
0
}