/src/gdal/frmts/gtiff/libgeotiff/geo_get.c
Line | Count | Source (jump to first uncovered line) |
1 | | /********************************************************************** |
2 | | * |
3 | | * geo_get.c -- Public routines for GEOTIFF GeoKey access. |
4 | | * |
5 | | * Written By: Niles D. Ritter. |
6 | | * |
7 | | * copyright (c) 1995 Niles D. Ritter |
8 | | * |
9 | | * Permission granted to use this software, so long as this copyright |
10 | | * notice accompanies any products derived therefrom. |
11 | | * |
12 | | **********************************************************************/ |
13 | | |
14 | | #include <stddef.h> |
15 | | |
16 | | #include "geotiff.h" /* public interface */ |
17 | | #include "geo_tiffp.h" /* external TIFF interface */ |
18 | | #include "geo_keyp.h" /* private interface */ |
19 | | |
20 | | /* return the Header info of this geotiff file */ |
21 | | |
22 | | void GTIFDirectoryInfo(GTIF *gtif, int version[3], int *keycount) |
23 | 159k | { |
24 | 159k | if (version) |
25 | 159k | { |
26 | 159k | version[0] = gtif->gt_version; |
27 | 159k | version[1] = gtif->gt_rev_major; |
28 | 159k | version[2] = gtif->gt_rev_minor; |
29 | 159k | } |
30 | 159k | if (keycount) *keycount = gtif->gt_num_keys; |
31 | 159k | } |
32 | | |
33 | | |
34 | | int GTIFKeyInfo(GTIF *gtif, geokey_t key, int *size, tagtype_t* type) |
35 | 1.42M | { |
36 | 1.42M | int nIndex = gtif->gt_keyindex[ key ]; |
37 | | |
38 | 1.42M | if (!nIndex) return 0; |
39 | | |
40 | 324k | GeoKey *keyptr = gtif->gt_keys + nIndex; |
41 | 324k | if (size) *size = (int) keyptr->gk_size; |
42 | 324k | if (type) *type = keyptr->gk_type; |
43 | | |
44 | 324k | return (int)keyptr->gk_count; |
45 | 1.42M | } |
46 | | |
47 | | /** |
48 | | |
49 | | This function reads the value of a single GeoKey from a GeoTIFF file. |
50 | | |
51 | | @param gtif The geotiff information handle from GTIFNew(). |
52 | | |
53 | | @param thekey The geokey_t name (such as ProjectedCSTypeGeoKey). |
54 | | This must come from the list of legal geokey_t values |
55 | | (an enumeration) listed below. |
56 | | |
57 | | @param val The <b>val</b> argument is a pointer to the |
58 | | variable into which the value should be read. The type of the variable |
59 | | varies depending on the geokey_t given. While there is no ready mapping |
60 | | of geokey_t values onto types, in general code values are of type <i>short</i>, |
61 | | citations are strings, and everything else is of type <i>double</i>. Note |
62 | | that pointer's to <i>int</i> should never be passed to GTIFKeyGet() for |
63 | | integer values as they will be shorts, and the int's may not be properly |
64 | | initialized (and will be grossly wrong on MSB systems). |
65 | | |
66 | | @param nIndex Indicates how far into the list of values |
67 | | for this geokey to offset. Should normally be zero. |
68 | | |
69 | | @param count Indicates how many values |
70 | | to read. At this time all keys except for strings have only one value, |
71 | | so <b>nIndex</b> should be zero, and <b>count</b> should be one. |
72 | | |
73 | | @return The GTIFKeyGet() function returns the number of values read. Normally |
74 | | this would be one if successful or zero if the key doesn't exist for this |
75 | | file. |
76 | | |
77 | | From geokeys.inc we see the following geokey_t values are possible:<p> |
78 | | |
79 | | <pre> |
80 | | -- 6.2.1 GeoTIFF Configuration Keys -- |
81 | | |
82 | | ValuePair( GTModelTypeGeoKey, 1024) -- Section 6.3.1.1 Codes -- |
83 | | ValuePair( GTRasterTypeGeoKey, 1025) -- Section 6.3.1.2 Codes -- |
84 | | ValuePair( GTCitationGeoKey, 1026) -- documentation -- |
85 | | |
86 | | -- 6.2.2 Geographic CS Parameter Keys -- |
87 | | |
88 | | ValuePair( GeographicTypeGeoKey, 2048) -- Section 6.3.2.1 Codes -- |
89 | | ValuePair( GeogCitationGeoKey, 2049) -- documentation -- |
90 | | ValuePair( GeogGeodeticDatumGeoKey, 2050) -- Section 6.3.2.2 Codes -- |
91 | | ValuePair( GeogPrimeMeridianGeoKey, 2051) -- Section 6.3.2.4 codes -- |
92 | | ValuePair( GeogLinearUnitsGeoKey, 2052) -- Section 6.3.1.3 Codes -- |
93 | | ValuePair( GeogLinearUnitSizeGeoKey, 2053) -- meters -- |
94 | | ValuePair( GeogAngularUnitsGeoKey, 2054) -- Section 6.3.1.4 Codes -- |
95 | | ValuePair( GeogAngularUnitSizeGeoKey, 2055) -- radians -- |
96 | | ValuePair( GeogEllipsoidGeoKey, 2056) -- Section 6.3.2.3 Codes -- |
97 | | ValuePair( GeogSemiMajorAxisGeoKey, 2057) -- GeogLinearUnits -- |
98 | | ValuePair( GeogSemiMinorAxisGeoKey, 2058) -- GeogLinearUnits -- |
99 | | ValuePair( GeogInvFlatteningGeoKey, 2059) -- ratio -- |
100 | | ValuePair( GeogAzimuthUnitsGeoKey, 2060) -- Section 6.3.1.4 Codes -- |
101 | | ValuePair( GeogPrimeMeridianLongGeoKey, 2061) -- GeoAngularUnit -- |
102 | | |
103 | | -- 6.2.3 Projected CS Parameter Keys -- |
104 | | -- Several keys have been renamed,-- |
105 | | -- and the deprecated names aliased for backward compatibility -- |
106 | | |
107 | | ValuePair( ProjectedCSTypeGeoKey, 3072) -- Section 6.3.3.1 codes -- |
108 | | ValuePair( PCSCitationGeoKey, 3073) -- documentation -- |
109 | | ValuePair( ProjectionGeoKey, 3074) -- Section 6.3.3.2 codes -- |
110 | | ValuePair( ProjCoordTransGeoKey, 3075) -- Section 6.3.3.3 codes -- |
111 | | ValuePair( ProjLinearUnitsGeoKey, 3076) -- Section 6.3.1.3 codes -- |
112 | | ValuePair( ProjLinearUnitSizeGeoKey, 3077) -- meters -- |
113 | | ValuePair( ProjStdParallel1GeoKey, 3078) -- GeogAngularUnit -- |
114 | | ValuePair( ProjStdParallelGeoKey,ProjStdParallel1GeoKey) -- ** alias ** -- |
115 | | ValuePair( ProjStdParallel2GeoKey, 3079) -- GeogAngularUnit -- |
116 | | ValuePair( ProjNatOriginLongGeoKey, 3080) -- GeogAngularUnit -- |
117 | | ValuePair( ProjOriginLongGeoKey,ProjNatOriginLongGeoKey) -- ** alias ** -- |
118 | | ValuePair( ProjNatOriginLatGeoKey, 3081) -- GeogAngularUnit -- |
119 | | ValuePair( ProjOriginLatGeoKey,ProjNatOriginLatGeoKey) -- ** alias ** -- |
120 | | ValuePair( ProjFalseEastingGeoKey, 3082) -- ProjLinearUnits -- |
121 | | ValuePair( ProjFalseNorthingGeoKey, 3083) -- ProjLinearUnits -- |
122 | | ValuePair( ProjFalseOriginLongGeoKey, 3084) -- GeogAngularUnit -- |
123 | | ValuePair( ProjFalseOriginLatGeoKey, 3085) -- GeogAngularUnit -- |
124 | | ValuePair( ProjFalseOriginEastingGeoKey, 3086) -- ProjLinearUnits -- |
125 | | ValuePair( ProjFalseOriginNorthingGeoKey, 3087) -- ProjLinearUnits -- |
126 | | ValuePair( ProjCenterLongGeoKey, 3088) -- GeogAngularUnit -- |
127 | | ValuePair( ProjCenterLatGeoKey, 3089) -- GeogAngularUnit -- |
128 | | ValuePair( ProjCenterEastingGeoKey, 3090) -- ProjLinearUnits -- |
129 | | ValuePair( ProjCenterNorthingGeoKey, 3091) -- ProjLinearUnits -- |
130 | | ValuePair( ProjScaleAtNatOriginGeoKey, 3092) -- ratio -- |
131 | | ValuePair( ProjScaleAtOriginGeoKey,ProjScaleAtNatOriginGeoKey) -- ** alias ** -- |
132 | | ValuePair( ProjScaleAtCenterGeoKey, 3093) -- ratio -- |
133 | | ValuePair( ProjAzimuthAngleGeoKey, 3094) -- GeogAzimuthUnit -- |
134 | | ValuePair( ProjStraightVertPoleLongGeoKey, 3095) -- GeogAngularUnit -- |
135 | | |
136 | | 6.2.4 Vertical CS Keys |
137 | | |
138 | | ValuePair( VerticalCSTypeGeoKey, 4096) -- Section 6.3.4.1 codes -- |
139 | | ValuePair( VerticalCitationGeoKey, 4097) -- documentation -- |
140 | | ValuePair( VerticalDatumGeoKey, 4098) -- Section 6.3.4.2 codes -- |
141 | | ValuePair( VerticalUnitsGeoKey, 4099) -- Section 6.3.1 (.x) codes -- |
142 | | |
143 | | See https://github.com/opengeospatial/geotiff/pull/99 |
144 | | ValuePair( CoordinateEpochGeoKey, 5120) -- GeoKey of type double |
145 | | </pre> |
146 | | */ |
147 | | |
148 | | int GTIFKeyGet(GTIF *gtif, geokey_t thekey, void *val, int nIndex, int count) |
149 | 309k | { |
150 | 309k | const int kindex = gtif->gt_keyindex[ thekey ]; |
151 | | |
152 | 309k | if (!kindex) return 0; |
153 | | |
154 | 309k | GeoKey *key = gtif->gt_keys+kindex; |
155 | 309k | if (!count) count = (int) (key->gk_count - nIndex); |
156 | 309k | if (count <=0) return 0; |
157 | 309k | if (count > key->gk_count) count = (int) key->gk_count; |
158 | 309k | const gsize_t size = key->gk_size; |
159 | 309k | const tagtype_t type = key->gk_type; |
160 | | |
161 | 309k | char *data; |
162 | 309k | if (count==1 && type==TYPE_SHORT) data = (char *)&key->gk_data; |
163 | 90.1k | else data = key->gk_data; |
164 | | |
165 | 309k | _GTIFmemcpy( val, data + nIndex*size, count*size ); |
166 | | |
167 | 309k | if (type==TYPE_ASCII) |
168 | 63.4k | ((char *)val)[count-1] = '\0'; /* replace last char with NULL */ |
169 | | |
170 | 309k | return count; |
171 | 309k | } |
172 | | |
173 | | /************************************************************************/ |
174 | | /* GTIFKeyGetInternal() */ |
175 | | /************************************************************************/ |
176 | | |
177 | | static int GTIFKeyGetInternal( GTIF *psGTIF, geokey_t key, |
178 | | void* pData, |
179 | | int nIndex, |
180 | | int nCount, |
181 | | tagtype_t expected_tagtype ) |
182 | 1.42M | { |
183 | 1.42M | tagtype_t tagtype; |
184 | 1.42M | if( !GTIFKeyInfo(psGTIF, key, NULL, &tagtype) ) |
185 | 1.09M | return 0; |
186 | 324k | if( tagtype != expected_tagtype ) |
187 | 14.8k | { |
188 | 14.8k | if( psGTIF->gt_error_callback ) |
189 | 14.8k | { |
190 | 14.8k | psGTIF->gt_error_callback( |
191 | 14.8k | psGTIF, |
192 | 14.8k | LIBGEOTIFF_WARNING, |
193 | 14.8k | "Expected key %s to be of type %s. Got %s", |
194 | 14.8k | GTIFKeyName(key), GTIFTypeName(expected_tagtype), |
195 | 14.8k | GTIFTypeName(tagtype)); |
196 | 14.8k | } |
197 | 14.8k | return 0; |
198 | 14.8k | } |
199 | 309k | return GTIFKeyGet( psGTIF, key, pData, nIndex, nCount ); |
200 | 324k | } |
201 | | |
202 | | /************************************************************************/ |
203 | | /* GTIFKeyGetASCII() */ |
204 | | /************************************************************************/ |
205 | | |
206 | | /** |
207 | | * This function reads the value of a single GeoKey of type ASCII from a GeoTIFF file. |
208 | | * |
209 | | * Same as GTIFGetKey() except that it adds checking that the key read is of the |
210 | | * expected type. |
211 | | */ |
212 | | int GTIFKeyGetASCII( GTIF *gtif, geokey_t key, char* szStr, int szStrMaxLen ) |
213 | 132k | { |
214 | 132k | return GTIFKeyGetInternal( gtif, key, szStr, 0, szStrMaxLen, TYPE_ASCII ); |
215 | 132k | } |
216 | | |
217 | | /************************************************************************/ |
218 | | /* GTIFKeyGetSHORT() */ |
219 | | /************************************************************************/ |
220 | | |
221 | | /** |
222 | | * This function reads the value of a single GeoKey of type SHORT from a GeoTIFF file. |
223 | | * |
224 | | * Same as GTIFGetKey() except that it adds checking that the key read is of the |
225 | | * expected type. |
226 | | */ |
227 | | int GTIFKeyGetSHORT( GTIF *gtif, geokey_t key, unsigned short* pnVal, int nIndex, |
228 | | int nCount ) |
229 | 933k | { |
230 | 933k | return GTIFKeyGetInternal(gtif, key, pnVal, nIndex, nCount, TYPE_SHORT); |
231 | 933k | } |
232 | | |
233 | | /************************************************************************/ |
234 | | /* GDALGTIFKeyGetDOUBLE() */ |
235 | | /************************************************************************/ |
236 | | |
237 | | /** |
238 | | * This function reads the value of a single GeoKey of type DOUBLE from a GeoTIFF file. |
239 | | * |
240 | | * Same as GTIFGetKey() except that it adds checking that the key read is of the |
241 | | * expected type. |
242 | | */ |
243 | | int GTIFKeyGetDOUBLE( GTIF *gtif, geokey_t key, double* pdfVal, int nIndex, |
244 | | int nCount ) |
245 | 354k | { |
246 | 354k | return GTIFKeyGetInternal(gtif, key, pdfVal, nIndex, nCount, TYPE_DOUBLE); |
247 | 354k | } |