Main Page   Compound List   File List   Compound Members   File Members   Related Pages  

geo_new.c

00001 /**********************************************************************
00002  *
00003  *  geo_new.c  -- Public routines for GEOTIFF GeoKey access.
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  *    20 June, 1995      Niles D. Ritter         New
00013  *    7 July,  1995      Greg Martin             Fix index
00014  *
00015  **********************************************************************/
00016 
00017 #include "geotiffio.h"   /* public interface        */
00018 #include "geo_tiffp.h" /* external TIFF interface */
00019 #include "geo_keyp.h"  /* private interface       */
00020 
00021 /* private local routines */
00022 static int ReadKey(GTIF* gt, KeyEntry* entptr,GeoKey* keyptr);
00023 
00024 /**********************************************************************
00025  *
00026  *                        Public Routines
00027  *
00028  **********************************************************************/
00029 
00030 
00051 GTIF* GTIFNew(void *tif)
00052 {
00053         GTIF* gt=(GTIF*)0;
00054         int count,bufcount,index;
00055         GeoKey *keyptr;
00056         pinfo_t *data;
00057         KeyEntry *entptr;
00058         KeyHeader *header;
00059         
00060         gt = (GTIF*)_GTIFcalloc( sizeof(GTIF));
00061         if (!gt) goto failure;  
00062         
00063         /* install TIFF file and I/O methods */
00064         gt->gt_tif = (tiff_t *)tif;
00065         _GTIFSetDefaultTIFF(&gt->gt_methods);
00066         
00067         /* since this is an array, GTIF will allocate the memory */
00068         if (!(gt->gt_methods.get)(tif, GTIFF_GEOKEYDIRECTORY, &gt->gt_nshorts, &data ))
00069         {
00070                 /* No ProjectionInfo, create a blank one */
00071                 data=(pinfo_t*)_GTIFcalloc((4+MAX_VALUES)*sizeof(pinfo_t));
00072                 if (!data) goto failure;        
00073                 header = (KeyHeader *)data;
00074                 header->hdr_version = GvCurrentVersion;
00075                 header->hdr_rev_major = GvCurrentRevision;
00076                 header->hdr_rev_minor = GvCurrentMinorRev;
00077                 gt->gt_nshorts=sizeof(KeyHeader)/sizeof(pinfo_t);
00078         }
00079         gt->gt_short = data;
00080         header = (KeyHeader *)data;
00081         
00082         if (header->hdr_version > GvCurrentVersion) goto failure;
00083         if (header->hdr_rev_major > GvCurrentRevision)
00084         {
00085                 /* issue warning */
00086         }
00087         
00088         /* If we got here, then the geokey can be parsed */
00089         count = header->hdr_num_keys;
00090         gt->gt_num_keys = count;
00091         gt->gt_version  = header->hdr_version;
00092         gt->gt_rev_major  = header->hdr_rev_major;
00093         gt->gt_rev_minor  = header->hdr_rev_minor;
00094 
00095         bufcount = count+MAX_KEYS; /* allow for expansion */
00096 
00097         /* Get the PARAMS Tags, if any */
00098         if (!(gt->gt_methods.get)(tif, GTIFF_DOUBLEPARAMS, &gt->gt_ndoubles, &gt->gt_double ))
00099         {
00100                 gt->gt_double=(double*)_GTIFcalloc(MAX_VALUES*sizeof(double));
00101                 if (!gt->gt_double) goto failure;       
00102         }
00103         if (!(gt->gt_methods.get)(tif, GTIFF_ASCIIPARAMS, &gt->gt_nascii, &gt->gt_ascii ))
00104         {
00105                 gt->gt_ascii = (char*)_GTIFcalloc(MAX_VALUES*sizeof(char));
00106                 if (!gt->gt_ascii) goto failure;
00107         }
00108         else  gt->gt_nascii--; /* last NULL doesn't count; "|" used for delimiter */
00109 
00110         /* allocate space for GeoKey array and its index */
00111         gt->gt_keys = (GeoKey *)_GTIFcalloc( sizeof(GeoKey)*bufcount);
00112         if (!gt->gt_keys) goto failure;
00113         gt->gt_keyindex = (int *)_GTIFcalloc( sizeof(int)*(MAX_KEYINDEX+1));
00114         if (!gt->gt_keyindex) goto failure;
00115         
00116         /*  Loop to get all GeoKeys */
00117         entptr = ((KeyEntry *)data) + 1;
00118         keyptr = gt->gt_keys;
00119         gt->gt_keymin = MAX_KEYINDEX;
00120         gt->gt_keymax = 0;
00121         for (index=1; index<=count; index++,entptr++)
00122         {
00123                 if (!ReadKey(gt, entptr, ++keyptr))
00124                         goto failure;
00125                         
00126                 /* Set up the index (start at 1, since 0=unset) */
00127                 gt->gt_keyindex[entptr->ent_key] = index;               
00128         }
00129         
00130         return gt;
00131         
00132 failure:
00133         /* Notify of error */
00134         if (gt) free(gt);
00135         return (GTIF *)0;
00136 }
00137 
00138 /**********************************************************************
00139  *
00140  *                        Private Routines
00141  *
00142  **********************************************************************/
00143 
00144 /*
00145  * Given KeyEntry, read in the GeoKey value location and set up
00146  *  the Key structure, returning 0 if failure.
00147  */
00148 
00149 static int ReadKey(GTIF* gt, KeyEntry* entptr,GeoKey* keyptr)
00150 {
00151         int offset,count;
00152         
00153         keyptr->gk_key = entptr->ent_key;
00154         keyptr->gk_count = entptr->ent_count;
00155         count = entptr->ent_count;
00156         offset = entptr->ent_val_offset;
00157         if (gt->gt_keymin > keyptr->gk_key)  gt->gt_keymin=keyptr->gk_key;
00158         if (gt->gt_keymax < keyptr->gk_key)  gt->gt_keymax=keyptr->gk_key;
00159         
00160         if (entptr->ent_location)
00161           keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,entptr->ent_location);
00162         else
00163           keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,GTIFF_GEOKEYDIRECTORY);
00164           
00165         switch (entptr->ent_location)
00166         {
00167                 case GTIFF_LOCAL:
00168                         /* store value into data value */
00169                         *(pinfo_t *)(&keyptr->gk_data) = entptr->ent_val_offset;
00170                         break;
00171                 case GTIFF_GEOKEYDIRECTORY:
00172                         keyptr->gk_data = (char *)(gt->gt_short+offset);
00173                         if (gt->gt_nshorts < offset+count)
00174                                 gt->gt_nshorts = offset+count;
00175                         break;
00176                 case GTIFF_DOUBLEPARAMS:
00177                         keyptr->gk_data = (char *)(gt->gt_double+offset);
00178                         if (gt->gt_ndoubles < offset+count)
00179                                 gt->gt_ndoubles = offset+count;
00180                         break;
00181                 case GTIFF_ASCIIPARAMS:
00182                         keyptr->gk_data = (char *)(gt->gt_ascii+offset);
00183                         if (gt->gt_nascii < offset+count)
00184                                 gt->gt_nascii = offset+count;
00185                         break;
00186                 default:
00187                         return 0; /* failure */
00188         }
00189         keyptr->gk_size = _gtiff_size[keyptr->gk_type];
00190         
00191         return 1; /* success */
00192 }

Generated at Sun Mar 4 23:32:44 2001 for libgeotiff by doxygen1.2.3-20001105 written by Dimitri van Heesch, © 1997-2000