Skip to content

Commit 2aa52b8

Browse files
authored
Merge pull request #39 from rouault/add_GTIFKeyGetASCII
API: add GTIFKeyGetASCII(), GTIFKeyGetSHORT() and GTIFKeyGetDOUBLE() as safer variants of GTIFKeyGet() with type checking
2 parents 9f4fbb1 + 09c71d6 commit 2aa52b8

File tree

4 files changed

+113
-67
lines changed

4 files changed

+113
-67
lines changed

libgeotiff/bin/listgeo.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ static void GTIFPrintCorners( GTIF *gtif, GTIFDefn *defn, FILE * fp_out,
228228
printf( "\nCorner Coordinates:\n" );
229229

230230
unsigned short raster_type = RasterPixelIsArea;
231-
GTIFKeyGet(gtif, GTRasterTypeGeoKey, &raster_type, 0, 1);
231+
GTIFKeyGetSHORT(gtif, GTRasterTypeGeoKey, &raster_type, 0, 1);
232232

233233
double xmin = (raster_type == RasterPixelIsArea) ? 0.0 : -0.5;
234234
double ymin = xmin;

libgeotiff/geo_get.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,79 @@ int GTIFKeyGet(GTIF *gtif, geokey_t thekey, void *val, int nIndex, int count)
174174

175175
return count;
176176
}
177+
178+
/************************************************************************/
179+
/* GTIFKeyGetInternal() */
180+
/************************************************************************/
181+
182+
static int GTIFKeyGetInternal( GTIF *psGTIF, geokey_t key,
183+
void* pData,
184+
int nIndex,
185+
int nCount,
186+
tagtype_t expected_tagtype )
187+
{
188+
tagtype_t tagtype;
189+
if( !GTIFKeyInfo(psGTIF, key, NULL, &tagtype) )
190+
return 0;
191+
if( tagtype != expected_tagtype )
192+
{
193+
if( psGTIF->gt_error_callback )
194+
{
195+
psGTIF->gt_error_callback(
196+
psGTIF,
197+
LIBGEOTIFF_WARNING,
198+
"Expected key %s to be of type %s. Got %s",
199+
GTIFKeyName(key), GTIFTypeName(expected_tagtype),
200+
GTIFTypeName(tagtype));
201+
}
202+
return 0;
203+
}
204+
return GTIFKeyGet( psGTIF, key, pData, nIndex, nCount );
205+
}
206+
207+
/************************************************************************/
208+
/* GTIFKeyGetASCII() */
209+
/************************************************************************/
210+
211+
/**
212+
* This function reads the value of a single GeoKey of type ASCII from a GeoTIFF file.
213+
*
214+
* Same as GTIFGetKey() except that it adds checking that the key read is of the
215+
* expected type.
216+
*/
217+
int GTIFKeyGetASCII( GTIF *gtif, geokey_t key, char* szStr, int szStrMaxLen )
218+
{
219+
return GTIFKeyGetInternal( gtif, key, szStr, 0, szStrMaxLen, TYPE_ASCII );
220+
}
221+
222+
/************************************************************************/
223+
/* GTIFKeyGetSHORT() */
224+
/************************************************************************/
225+
226+
/**
227+
* This function reads the value of a single GeoKey of type SHORT from a GeoTIFF file.
228+
*
229+
* Same as GTIFGetKey() except that it adds checking that the key read is of the
230+
* expected type.
231+
*/
232+
int GTIFKeyGetSHORT( GTIF *gtif, geokey_t key, unsigned short* pnVal, int nIndex,
233+
int nCount )
234+
{
235+
return GTIFKeyGetInternal(gtif, key, pnVal, nIndex, nCount, TYPE_SHORT);
236+
}
237+
238+
/************************************************************************/
239+
/* GDALGTIFKeyGetDOUBLE() */
240+
/************************************************************************/
241+
242+
/**
243+
* This function reads the value of a single GeoKey of type DOUBLE from a GeoTIFF file.
244+
*
245+
* Same as GTIFGetKey() except that it adds checking that the key read is of the
246+
* expected type.
247+
*/
248+
int GTIFKeyGetDOUBLE( GTIF *gtif, geokey_t key, double* pdfVal, int nIndex,
249+
int nCount )
250+
{
251+
return GTIFKeyGetInternal(gtif, key, pdfVal, nIndex, nCount, TYPE_DOUBLE);
252+
}

libgeotiff/geo_normalize.c

Lines changed: 29 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,23 @@
104104

105105
CPL_INLINE static void CPL_IGNORE_RET_VAL_INT(CPL_UNUSED int unused) {}
106106

107+
/************************************************************************/
108+
/* GTIFKeyGetSSHORT() */
109+
/************************************************************************/
110+
111+
// Geotiff SHORT keys are supposed to be unsigned, but geo_normalize interface
112+
// uses signed short...
113+
static int GTIFKeyGetSSHORT( GTIF *gtif, geokey_t key, short* pnVal )
114+
{
115+
unsigned short sVal;
116+
if( GTIFKeyGetSHORT(gtif, key, &sVal, 0, 1) == 1 )
117+
{
118+
memcpy(pnVal, &sVal, 2);
119+
return 1;
120+
}
121+
return 0;
122+
}
123+
107124
/************************************************************************/
108125
/* GTIFGetPCSInfo() */
109126
/************************************************************************/
@@ -1641,59 +1658,6 @@ int GTIFGetProjTRFInfo( /* Conversion code */
16411658
return ret;
16421659
}
16431660

1644-
/************************************************************************/
1645-
/* GTIFKeyGetInternal() */
1646-
/************************************************************************/
1647-
1648-
static int GTIFKeyGetInternal( GTIF *psGTIF, geokey_t key,
1649-
void* pData,
1650-
int nIndex,
1651-
int nCount,
1652-
tagtype_t expected_tagtype )
1653-
{
1654-
tagtype_t tagtype;
1655-
if( !GTIFKeyInfo(psGTIF, key, NULL, &tagtype) )
1656-
return 0;
1657-
if( tagtype != expected_tagtype )
1658-
{
1659-
if( psGTIF->gt_error_callback )
1660-
{
1661-
psGTIF->gt_error_callback(
1662-
psGTIF,
1663-
LIBGEOTIFF_WARNING,
1664-
"Expected key %s to be of type %s. Got %s",
1665-
GTIFKeyName(key), GTIFTypeName(expected_tagtype),
1666-
GTIFTypeName(tagtype));
1667-
}
1668-
return 0;
1669-
}
1670-
return GTIFKeyGet( psGTIF, key, pData, nIndex, nCount );
1671-
}
1672-
1673-
/************************************************************************/
1674-
/* GTIFKeyGetSHORT() */
1675-
/************************************************************************/
1676-
1677-
static int GTIFKeyGetSHORT( GTIF *psGTIF, geokey_t key,
1678-
short* pnVal,
1679-
int nIndex,
1680-
int nCount )
1681-
{
1682-
return GTIFKeyGetInternal(psGTIF, key, pnVal, nIndex, nCount, TYPE_SHORT);
1683-
}
1684-
1685-
/************************************************************************/
1686-
/* GDALGTIFKeyGetDOUBLE() */
1687-
/************************************************************************/
1688-
1689-
static int GTIFKeyGetDOUBLE( GTIF *psGTIF, geokey_t key,
1690-
double* pdfVal,
1691-
int nIndex,
1692-
int nCount )
1693-
{
1694-
return GTIFKeyGetInternal(psGTIF, key, pdfVal, nIndex, nCount, TYPE_DOUBLE);
1695-
}
1696-
16971661
/************************************************************************/
16981662
/* GTIFFetchProjParms() */
16991663
/* */
@@ -2488,21 +2452,21 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
24882452
/* -------------------------------------------------------------------- */
24892453
/* Try to get the overall model type. */
24902454
/* -------------------------------------------------------------------- */
2491-
GTIFKeyGetSHORT(psGTIF,GTModelTypeGeoKey,&(psDefn->Model),0,1);
2455+
GTIFKeyGetSSHORT(psGTIF,GTModelTypeGeoKey,&(psDefn->Model));
24922456

24932457
/* -------------------------------------------------------------------- */
24942458
/* Extract the Geog units. */
24952459
/* -------------------------------------------------------------------- */
24962460
nGeogUOMLinear = 9001; /* Linear_Meter */
2497-
if( GTIFKeyGetSHORT(psGTIF, GeogLinearUnitsGeoKey, &nGeogUOMLinear, 0, 1 ) == 1 )
2461+
if( GTIFKeyGetSSHORT(psGTIF, GeogLinearUnitsGeoKey, &nGeogUOMLinear) == 1 )
24982462
{
24992463
psDefn->UOMLength = nGeogUOMLinear;
25002464
}
25012465

25022466
/* -------------------------------------------------------------------- */
25032467
/* Try to get a PCS. */
25042468
/* -------------------------------------------------------------------- */
2505-
if( GTIFKeyGetSHORT(psGTIF,ProjectedCSTypeGeoKey, &(psDefn->PCS),0,1) == 1
2469+
if( GTIFKeyGetSSHORT(psGTIF,ProjectedCSTypeGeoKey, &(psDefn->PCS)) == 1
25062470
&& psDefn->PCS != KvUserDefined )
25072471
{
25082472
/*
@@ -2535,7 +2499,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
25352499
/* If the Proj_ code is specified directly, use that. */
25362500
/* -------------------------------------------------------------------- */
25372501
if( psDefn->ProjCode == KvUserDefined )
2538-
GTIFKeyGetSHORT(psGTIF, ProjectionGeoKey, &(psDefn->ProjCode), 0, 1 );
2502+
GTIFKeyGetSSHORT(psGTIF, ProjectionGeoKey, &(psDefn->ProjCode));
25392503

25402504
if( psDefn->ProjCode != KvUserDefined )
25412505
{
@@ -2566,7 +2530,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
25662530
/* Try to get a GCS. If found, it will override any implied by */
25672531
/* the PCS. */
25682532
/* -------------------------------------------------------------------- */
2569-
GTIFKeyGetSHORT(psGTIF, GeographicTypeGeoKey, &(psDefn->GCS), 0, 1 );
2533+
GTIFKeyGetSSHORT(psGTIF, GeographicTypeGeoKey, &(psDefn->GCS));
25702534
if( psDefn->GCS < 1 || psDefn->GCS >= KvUserDefined )
25712535
psDefn->GCS = KvUserDefined;
25722536

@@ -2584,7 +2548,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
25842548
/* Handle the GCS angular units. GeogAngularUnitsGeoKey */
25852549
/* overrides the GCS or PCS setting. */
25862550
/* -------------------------------------------------------------------- */
2587-
GTIFKeyGetSHORT(psGTIF, GeogAngularUnitsGeoKey, &(psDefn->UOMAngle), 0, 1 );
2551+
GTIFKeyGetSSHORT(psGTIF, GeogAngularUnitsGeoKey, &(psDefn->UOMAngle));
25882552
if( psDefn->UOMAngle != KvUserDefined )
25892553
{
25902554
GTIFGetUOMAngleInfoEx( psGTIF->pj_context,
@@ -2596,7 +2560,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
25962560
/* Check for a datum setting, and then use the datum to derive */
25972561
/* an ellipsoid. */
25982562
/* -------------------------------------------------------------------- */
2599-
GTIFKeyGetSHORT(psGTIF, GeogGeodeticDatumGeoKey, &(psDefn->Datum), 0, 1 );
2563+
GTIFKeyGetSSHORT(psGTIF, GeogGeodeticDatumGeoKey, &(psDefn->Datum));
26002564

26012565
if( psDefn->Datum != KvUserDefined )
26022566
{
@@ -2608,7 +2572,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
26082572
/* Check for an explicit ellipsoid. Use the ellipsoid to */
26092573
/* derive the ellipsoid characteristics, if possible. */
26102574
/* -------------------------------------------------------------------- */
2611-
GTIFKeyGetSHORT(psGTIF, GeogEllipsoidGeoKey, &(psDefn->Ellipsoid), 0, 1 );
2575+
GTIFKeyGetSSHORT(psGTIF, GeogEllipsoidGeoKey, &(psDefn->Ellipsoid));
26122576

26132577
if( psDefn->Ellipsoid != KvUserDefined )
26142578
{
@@ -2638,7 +2602,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
26382602
/* -------------------------------------------------------------------- */
26392603
/* Get the prime meridian info. */
26402604
/* -------------------------------------------------------------------- */
2641-
GTIFKeyGetSHORT(psGTIF, GeogPrimeMeridianGeoKey, &(psDefn->PM), 0, 1 );
2605+
GTIFKeyGetSSHORT(psGTIF, GeogPrimeMeridianGeoKey, &(psDefn->PM));
26422606

26432607
if( psDefn->PM != KvUserDefined )
26442608
{
@@ -2669,7 +2633,7 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
26692633
/* but these are very rarely not decimal degrees for actual */
26702634
/* file coordinates. */
26712635
/* -------------------------------------------------------------------- */
2672-
GTIFKeyGetSHORT(psGTIF,ProjLinearUnitsGeoKey,&(psDefn->UOMLength),0,1);
2636+
GTIFKeyGetSSHORT(psGTIF,ProjLinearUnitsGeoKey,&(psDefn->UOMLength));
26732637

26742638
if( psDefn->UOMLength != KvUserDefined )
26752639
{
@@ -2685,8 +2649,8 @@ int GTIFGetDefn( GTIF * psGTIF, GTIFDefn * psDefn )
26852649
/* -------------------------------------------------------------------- */
26862650
/* Handle a variety of user defined transform types. */
26872651
/* -------------------------------------------------------------------- */
2688-
if( GTIFKeyGetSHORT(psGTIF,ProjCoordTransGeoKey,
2689-
&(psDefn->CTProjection),0,1) == 1)
2652+
if( GTIFKeyGetSSHORT(psGTIF,ProjCoordTransGeoKey,
2653+
&(psDefn->CTProjection)) == 1)
26902654
{
26912655
GTIFFetchProjParms( psGTIF, psDefn );
26922656
}

libgeotiff/geotiff.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,14 @@ int GTIF_DLL GTIFSetVersionNumbers(GTIF* gtif,
142142
int GTIF_DLL GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type);
143143
int GTIF_DLL GTIFKeyGet(GTIF *gtif, geokey_t key, void *val, int index,
144144
int count);
145+
int GTIF_DLL GTIFKeyGetASCII(GTIF *gtif, geokey_t key, char* szStr,
146+
int szStrMaxLen);
147+
int GTIF_DLL GTIFKeyGetSHORT(GTIF *gtif, geokey_t key, unsigned short *val, int index,
148+
int count);
149+
int GTIF_DLL GTIFKeyGetDOUBLE(GTIF *gtif, geokey_t key, double *val, int index,
150+
int count);
145151
int GTIF_DLL GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type,
146-
int count,...);
152+
int count,...);
147153

148154
/* Metadata Import-Export utilities */
149155
void GTIF_DLL GTIFPrint(GTIF *gtif, GTIFPrintMethod print, void *aux);

0 commit comments

Comments
 (0)