00001 /********************************************************************** 00002 * 00003 * geo_print.c -- Key-dumping routines for GEOTIFF files. 00004 * 00005 * Written By: Niles D. Ritter. 00006 * 00007 * copyright (c) 1995 Niles D. Ritter 00008 * 00009 * Permission granted to use this software, so long as this copyright 00010 * notice accompanies any products derived therefrom. 00011 * 00012 * Revision History; 00013 * 00014 * 20 June, 1995 Niles D. Ritter New 00015 * 7 July, 1995 NDR Fix indexing 00016 * 27 July, 1995 NDR Added Import utils 00017 * 28 July, 1995 NDR Made parser more strict. 00018 * 29 Sep, 1995 NDR Fixed matrix printing. 00019 * 00020 * $Log$ 00020 * Revision 1.2 2001/03/05 04:58:33 warmerda 00020 * updated 00020 * 00021 * Revision 1.3 1999/05/04 03:14:35 warmerda 00022 * avoid warnings 00023 * 00024 * Revision 1.2 1999/05/03 17:50:31 warmerda 00025 * avoid warnings on IRIX 00026 * 00027 * 00028 **********************************************************************/ 00029 00030 #include "geotiff.h" /* public interface */ 00031 #include "geo_tiffp.h" /* external TIFF interface */ 00032 #include "geo_keyp.h" /* private interface */ 00033 #include "geokeys.h" 00034 00035 #include <stdio.h> /* for sprintf */ 00036 00037 #define FMT_GEOTIFF "Geotiff_Information:" 00038 #define FMT_VERSION "Version: %hd" 00039 #define FMT_REV "Key_Revision: %1hd.%hd" 00040 #define FMT_TAGS "Tagged_Information:" 00041 #define FMT_TAGEND "End_Of_Tags." 00042 #define FMT_KEYS "Keyed_Information:" 00043 #define FMT_KEYEND "End_Of_Keys." 00044 #define FMT_GEOEND "End_Of_Geotiff." 00045 #define FMT_DOUBLE "%-17.9g" 00046 #define FMT_SHORT "%-11hd" 00047 00048 static void DefaultPrint(char *string, void *aux); 00049 static void PrintKey(GeoKey *key, GTIFPrintMethod print,void *aux); 00050 static void PrintGeoTags(GTIF *gtif,GTIFReadMethod scan,void *aux); 00051 static void PrintTag(int tag, int nrows, double *data, int ncols, 00052 GTIFPrintMethod print,void *aux); 00053 static void DefaultRead(char *string, void *aux); 00054 static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux); 00055 static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux); 00056 static char message[1024]; 00057 00058 /* 00059 * Print off the directory info, using whatever method is specified 00060 * (defaults to fprintf if null). The "aux" parameter is provided for user 00061 * defined method for passing parameters or whatever. 00062 * 00063 * The output format is a "GeoTIFF meta-data" file, which may be 00064 * used to import information with the GTIFFImport() routine. 00065 */ 00066 00067 void GTIFPrint(GTIF *gtif, GTIFPrintMethod print,void *aux) 00068 { 00069 int i; 00070 int numkeys = gtif->gt_num_keys; 00071 GeoKey *key = gtif->gt_keys; 00072 00073 if (!print) print = (GTIFPrintMethod) &DefaultPrint; 00074 if (!aux) aux=stdout; 00075 00076 sprintf(message,FMT_GEOTIFF "\n"); 00077 print(message,aux); 00078 sprintf(message, "Version: %hd" ,gtif->gt_version); 00079 sprintf(message, FMT_VERSION,gtif->gt_version); 00080 print(" ",aux); print(message,aux); print("\n",aux); 00081 sprintf(message, FMT_REV,gtif->gt_rev_major, 00082 gtif->gt_rev_minor); 00083 print(" ",aux); print(message,aux); print("\n",aux); 00084 00085 sprintf(message," %s\n",FMT_TAGS); print(message,aux); 00086 PrintGeoTags(gtif,print,aux); 00087 sprintf(message," %s\n",FMT_TAGEND); print(message,aux); 00088 00089 sprintf(message," %s\n",FMT_KEYS); print(message,aux); 00090 for (i=0; i<numkeys; i++) 00091 PrintKey(++key,print,aux); 00092 sprintf(message," %s\n",FMT_KEYEND); print(message,aux); 00093 00094 sprintf(message," %s\n",FMT_GEOEND); print(message,aux); 00095 } 00096 00097 static void PrintGeoTags(GTIF *gt, GTIFPrintMethod print,void *aux) 00098 { 00099 double *data; 00100 int count; 00101 tiff_t *tif=gt->gt_tif; 00102 00103 if ((gt->gt_methods.get)(tif, GTIFF_TIEPOINTS, &count, &data )) 00104 PrintTag(GTIFF_TIEPOINTS,count/3, data, 3, print, aux); 00105 if ((gt->gt_methods.get)(tif, GTIFF_PIXELSCALE, &count, &data )) 00106 PrintTag(GTIFF_PIXELSCALE,count/3, data, 3, print, aux); 00107 if ((gt->gt_methods.get)(tif, GTIFF_TRANSMATRIX, &count, &data )) 00108 PrintTag(GTIFF_TRANSMATRIX,count/4, data, 4, print, aux); 00109 } 00110 00111 static void PrintTag(int tag, int nrows, double *dptr, int ncols, 00112 GTIFPrintMethod print,void *aux) 00113 { 00114 int i,j; 00115 double *data=dptr; 00116 00117 print(" ",aux); 00118 print(GTIFTagName(tag),aux); 00119 sprintf(message," (%d,%d):\n",nrows,ncols); 00120 print(message,aux); 00121 for (i=0;i<nrows;i++) 00122 { 00123 print(" ",aux); 00124 for (j=0;j<ncols;j++) 00125 { 00126 sprintf(message,FMT_DOUBLE,*data++); 00127 print(message,aux); 00128 } 00129 print("\n",aux); 00130 } 00131 _GTIFFree(dptr); /* free up the allocated memory */ 00132 } 00133 00134 00135 static void PrintKey(GeoKey *key, GTIFPrintMethod print, void *aux) 00136 { 00137 char *data; 00138 geokey_t keyid = (geokey_t) key->gk_key; 00139 int count = key->gk_count; 00140 int vals_now,i; 00141 pinfo_t *sptr; 00142 double *dptr; 00143 00144 00145 print(" ",aux); 00146 print(GTIFKeyName(keyid),aux); 00147 00148 sprintf(message," (%s,%d): ",GTIFTypeName(key->gk_type),count); 00149 print(message,aux); 00150 00151 if (key->gk_type==TYPE_SHORT && count==1) 00152 data = (char *)&key->gk_data; 00153 else 00154 data = key->gk_data; 00155 00156 switch (key->gk_type) 00157 { 00158 case TYPE_ASCII: 00159 print("\"",aux); 00160 _GTIFmemcpy(message,data,count); 00161 message[count-1]='\0'; 00162 print(message,aux); 00163 print("\"\n",aux); 00164 break; 00165 00166 case TYPE_DOUBLE: 00167 for (dptr = (double *)data; count > 0; count-= vals_now) 00168 { 00169 vals_now = count > 3? 3: count; 00170 for (i=0; i<vals_now; i++,dptr++) 00171 { 00172 sprintf(message,FMT_DOUBLE ,*dptr); 00173 print(message,aux); 00174 } 00175 print("\n",aux); 00176 } 00177 break; 00178 00179 case TYPE_SHORT: 00180 sptr = (pinfo_t *)data; 00181 if (count==1) 00182 { 00183 sprintf(message,"%s\n",GTIFValueName(keyid,*sptr)); 00184 print(message,aux); 00185 } 00186 else 00187 for (; count > 0; count-= vals_now) 00188 { 00189 vals_now = count > 3? 3: count; 00190 for (i=0; i<vals_now; i++,sptr++) 00191 { 00192 sprintf(message,FMT_SHORT,*sptr); 00193 print(message,aux); 00194 } 00195 print("\n",aux); 00196 } 00197 break; 00198 00199 default: 00200 sprintf(message, "Unknown Type (%d)\n",key->gk_type); 00201 print(message,aux); 00202 break; 00203 } 00204 } 00205 00206 static void DefaultPrint(char *string, void *aux) 00207 { 00208 /* Pretty boring */ 00209 fprintf((FILE *)aux,string); 00210 } 00211 00212 00213 /* 00214 * Importing metadata file 00215 */ 00216 00217 /* 00218 * Import the directory info, using whatever method is specified 00219 * (defaults to fscanf if null). The "aux" parameter is provided for user 00220 * defined method for passing file or whatever. 00221 * 00222 * The input format is a "GeoTIFF meta-data" file, which may be 00223 * generated by the GTIFFPrint() routine. 00224 */ 00225 00226 int GTIFImport(GTIF *gtif, GTIFReadMethod scan,void *aux) 00227 { 00228 int status; 00229 00230 if (!scan) scan = (GTIFReadMethod) &DefaultRead; 00231 if (!aux) aux=stdin; 00232 00233 scan(message,aux); 00234 if (strncmp(message,FMT_GEOTIFF,8)) return 0; 00235 scan(message,aux); 00236 if (!sscanf(message,FMT_VERSION,>if->gt_version)) return 0; 00237 scan(message,aux); 00238 if (sscanf(message,FMT_REV,>if->gt_rev_major, 00239 >if->gt_rev_minor) !=2) return 0; 00240 00241 scan(message,aux); 00242 if (strncmp(message,FMT_TAGS,8)) return 0; 00243 while ((status=ReadTag(gtif,scan,aux))>0); 00244 if (status < 0) return 0; 00245 00246 scan(message,aux); 00247 if (strncmp(message,FMT_KEYS,8)) return 0; 00248 while ((status=ReadKey(gtif,scan,aux))>0); 00249 00250 return (status==0); /* success */ 00251 } 00252 00253 static int StringError(char *string) 00254 { 00255 fprintf(stderr,"Parsing Error at \'%s\'\n",string); 00256 return -1; 00257 } 00258 00259 #define SKIPWHITE(vptr) \ 00260 while (*vptr && (*vptr==' '||*vptr=='\t')) vptr++ 00261 #define FINDCHAR(vptr,c) \ 00262 while (*vptr && *vptr!=(c)) vptr++ 00263 00264 static int ReadTag(GTIF *gt,GTIFReadMethod scan,void *aux) 00265 { 00266 int i,j,tag; 00267 char *vptr; 00268 char tagname[100]; 00269 double data[100],*dptr=data; 00270 int count,nrows,ncols,num; 00271 00272 scan(message,aux); 00273 if (!strncmp(message,FMT_TAGEND,8)) return 0; 00274 00275 num=sscanf(message,"%[^( ] (%d,%d):\n",tagname,&nrows,&ncols); 00276 if (num!=3) return StringError(message); 00277 00278 tag = GTIFTagCode(tagname); 00279 if (tag < 0) return StringError(tagname); 00280 00281 count = nrows*ncols; 00282 for (i=0;i<nrows;i++) 00283 { 00284 scan(message,aux); 00285 vptr = message; 00286 for (j=0;j<ncols;j++) 00287 { 00288 if (!sscanf(vptr,"%lg",dptr++)) 00289 return StringError(vptr); 00290 FINDCHAR(vptr,' '); 00291 SKIPWHITE(vptr); 00292 } 00293 } 00294 (gt->gt_methods.set)(gt->gt_tif, tag, count, data ); 00295 00296 return 1; 00297 } 00298 00299 00300 static int ReadKey(GTIF *gt, GTIFReadMethod scan, void *aux) 00301 { 00302 tagtype_t ktype; 00303 int count,outcount; 00304 int vals_now,i; 00305 geokey_t key; 00306 int icode; 00307 pinfo_t code; 00308 short *sptr; 00309 char name[1000]; 00310 char type[20]; 00311 double data[100]; 00312 double *dptr; 00313 char *cdata = (char *)data; 00314 char *vptr; 00315 int num; 00316 00317 scan(message,aux); 00318 if (!strncmp(message,FMT_KEYEND,8)) return 0; 00319 00320 num=sscanf(message,"%[^( ] (%[^,],%d):\n",name,type,&count); 00321 if (num!=3) return StringError(message); 00322 00323 vptr = message; 00324 FINDCHAR(vptr,':'); 00325 if (!*vptr) return StringError(message); 00326 vptr+=2; 00327 00328 if( GTIFKeyCode(name) < 0 ) 00329 return StringError(name); 00330 else 00331 key = (geokey_t) GTIFKeyCode(name); 00332 00333 if( GTIFTypeCode(type) < 0 ) 00334 return StringError(type); 00335 else 00336 ktype = (tagtype_t) GTIFTypeCode(type); 00337 00338 /* skip white space */ 00339 SKIPWHITE(vptr); 00340 if (!*vptr) return StringError(message); 00341 00342 switch (ktype) 00343 { 00344 case TYPE_ASCII: 00345 FINDCHAR(vptr,'"'); 00346 if (!*vptr) return StringError(message); 00347 _GTIFmemcpy(cdata,vptr+1,count); 00348 cdata[count-1]='\0'; 00349 GTIFKeySet(gt,key,ktype,count,cdata); 00350 break; 00351 00352 case TYPE_DOUBLE: 00353 outcount = count; 00354 for (dptr = data; count > 0; count-= vals_now) 00355 { 00356 vals_now = count > 3? 3: count; 00357 for (i=0; i<vals_now; i++,dptr++) 00358 { 00359 if (!sscanf(vptr,"%lg" ,dptr)) 00360 StringError(vptr); 00361 FINDCHAR(vptr,' '); 00362 SKIPWHITE(vptr); 00363 } 00364 if (vals_now<count) 00365 { 00366 scan(message,aux); 00367 vptr = message; 00368 } 00369 } 00370 if (outcount==1) 00371 GTIFKeySet(gt,key,ktype,outcount,data[0]); 00372 else 00373 GTIFKeySet(gt,key,ktype,outcount,data); 00374 break; 00375 00376 case TYPE_SHORT: 00377 if (count==1) 00378 { 00379 icode = GTIFValueCode(key,vptr); 00380 if (icode < 0) return StringError(vptr); 00381 code = icode; 00382 GTIFKeySet(gt,key,ktype,count,code); 00383 } 00384 else /* multi-valued short - no such thing yet */ 00385 { 00386 sptr = (short *)data; 00387 outcount = count; 00388 for (; count > 0; count-= vals_now) 00389 { 00390 vals_now = count > 3? 3: count; 00391 for (i=0; i<vals_now; i++,sptr++) 00392 { 00393 int work_int; 00394 00395 /* note: FMT_SHORT (%11hd) not supported on IRIX */ 00396 sscanf(message,"%11d",&work_int); 00397 *sptr = work_int; 00398 scan(message,aux); 00399 } 00400 if (vals_now<count) 00401 { 00402 scan(message,aux); 00403 vptr = message; 00404 } 00405 } 00406 GTIFKeySet(gt,key,ktype,outcount,sptr); 00407 } 00408 break; 00409 00410 default: 00411 return -1; 00412 } 00413 return 1; 00414 } 00415 00416 00417 static void DefaultRead(char *string, void *aux) 00418 { 00419 /* Pretty boring */ 00420 fscanf((FILE *)aux,"%[^\n]\n",string); 00421 } 00422