LCOV - code coverage report
Current view: directory - frmts/gtiff/libgeotiff - geo_new.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 108 96 88.9 %
Date: 2011-12-18 Functions: 4 3 75.0 %

       1                 : /**********************************************************************
       2                 :  *
       3                 :  *  geo_new.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                 :  *    20 June, 1995      Niles D. Ritter         New
      13                 :  *    7 July,  1995      Greg Martin             Fix index
      14                 :  *
      15                 :  **********************************************************************/
      16                 : 
      17                 : #include "geotiffio.h"   /* public interface        */
      18                 : #include "geo_tiffp.h" /* external TIFF interface */
      19                 : #include "geo_keyp.h"  /* private interface       */
      20                 : #include "geo_simpletags.h" 
      21                 : 
      22                 : /* private local routines */
      23                 : static int ReadKey(GTIF* gt, TempKeyData* tempData,
      24                 :                    KeyEntry* entptr, GeoKey* keyptr);
      25                 : 
      26                 : 
      27                 : /**********************************************************************
      28                 :  *
      29                 :  *                        Public Routines
      30                 :  *
      31                 :  **********************************************************************/
      32                 : 
      33                 : 
      34                 : /**
      35                 :  * Given an open TIFF file, look for GTIF keys and 
      36                 :  *  values and return GTIF structure.
      37                 : 
      38                 : This function creates a GeoTIFF information interpretation handle
      39                 : (GTIF *) based on a passed in TIFF handle originally from 
      40                 : XTIFFOpen().  Even though the argument 
      41                 : (<b>tif</b>) is shown as type <tt>void *</tt>, it is really normally
      42                 : of type <tt>TIFF *</tt>.<p>
      43                 : 
      44                 : The returned GTIF handle can be used to read or write GeoTIFF tags 
      45                 : using the various GTIF functions.  The handle should be destroyed using
      46                 : GTIFFree() before the file is closed with TIFFClose().<p>
      47                 : 
      48                 : If the file accessed has no GeoTIFF keys, an valid (but empty) GTIF is
      49                 : still returned.  GTIFNew() is used both for existing files being read, and
      50                 : for new TIFF files that will have GeoTIFF tags written to them.<p>
      51                 : 
      52                 :  */
      53                 : 
      54            5603 : GTIF* GTIFNew(void *tif)
      55                 : 
      56                 : {
      57                 :     TIFFMethod default_methods;
      58            5603 :     _GTIFSetDefaultTIFF( &default_methods );
      59                 : 
      60            5603 :     return GTIFNewWithMethods( tif, &default_methods );
      61                 : }
      62                 : 
      63               0 : GTIF *GTIFNewSimpleTags( void *tif )
      64                 : 
      65                 : {
      66                 :     TIFFMethod default_methods;
      67               0 :     GTIFSetSimpleTagsMethods( &default_methods );
      68                 : 
      69               0 :     return GTIFNewWithMethods( tif, &default_methods );
      70                 : }
      71                 : 
      72                 : /************************************************************************/
      73                 : /*                         GTIFNewWithMethods()                         */
      74                 : /*                                                                      */
      75                 : /*      Create a new geotiff, passing in the methods structure to       */
      76                 : /*      support not libtiff implementations without replacing the       */
      77                 : /*      default methods.                                                */
      78                 : /************************************************************************/
      79                 : 
      80            5603 : GTIF* GTIFNewWithMethods(void *tif, TIFFMethod* methods)
      81                 : {
      82            5603 :     GTIF* gt=(GTIF*)0;
      83                 :     int count,bufcount,index;
      84                 :     GeoKey *keyptr;
      85                 :     pinfo_t *data;
      86                 :     KeyEntry *entptr;
      87                 :     KeyHeader *header;
      88                 :     TempKeyData tempData;
      89                 : 
      90            5603 :     memset( &tempData, 0, sizeof(tempData) );
      91            5603 :     gt = (GTIF*)_GTIFcalloc( sizeof(GTIF));
      92            5603 :     if (!gt) goto failure;  
      93                 :   
      94                 :     /* install TIFF file and I/O methods */
      95            5603 :     gt->gt_tif = (tiff_t *)tif;
      96            5603 :     memcpy( &gt->gt_methods, methods, sizeof(TIFFMethod) );
      97                 : 
      98                 :     /* since this is an array, GTIF will allocate the memory */
      99           13093 :     if ( tif == NULL 
     100            5603 :          || !(gt->gt_methods.get)(tif, GTIFF_GEOKEYDIRECTORY, &gt->gt_nshorts, &data ))
     101                 :     {
     102                 :         /* No ProjectionInfo, create a blank one */
     103            1887 :         data=(pinfo_t*)_GTIFcalloc((4+MAX_VALUES)*sizeof(pinfo_t));
     104            1887 :         if (!data) goto failure;  
     105            1887 :         header = (KeyHeader *)data;
     106            1887 :         header->hdr_version = GvCurrentVersion;
     107            1887 :         header->hdr_rev_major = GvCurrentRevision;
     108            1887 :         header->hdr_rev_minor = GvCurrentMinorRev;
     109            1887 :         gt->gt_nshorts=sizeof(KeyHeader)/sizeof(pinfo_t);
     110                 :     }
     111                 :     else
     112                 :     {
     113                 :         /* resize data array so it can be extended if needed */
     114            3716 :         data = (pinfo_t*) _GTIFrealloc(data,(4+MAX_VALUES)*sizeof(pinfo_t));
     115                 :     }
     116            5603 :     gt->gt_short = data;
     117            5603 :     header = (KeyHeader *)data;
     118                 :   
     119            5603 :     if (header->hdr_version > GvCurrentVersion) goto failure;
     120            5603 :     if (header->hdr_rev_major > GvCurrentRevision)
     121                 :     {
     122                 :         /* issue warning */
     123                 :     }
     124                 :   
     125                 :     /* If we got here, then the geokey can be parsed */
     126            5603 :     count = header->hdr_num_keys;
     127                 : 
     128            5603 :     if (count * sizeof(KeyEntry) >= (4 + MAX_VALUES) * sizeof(pinfo_t)) 
     129               0 :         goto failure; 
     130                 : 
     131            5603 :     gt->gt_num_keys = count;
     132            5603 :     gt->gt_version  = header->hdr_version;
     133            5603 :     gt->gt_rev_major  = header->hdr_rev_major;
     134            5603 :     gt->gt_rev_minor  = header->hdr_rev_minor;
     135                 : 
     136            5603 :     bufcount = count+MAX_KEYS; /* allow for expansion */
     137                 : 
     138                 :     /* Get the PARAMS Tags, if any */
     139           14809 :     if (tif == NULL
     140           11206 :         || !(gt->gt_methods.get)(tif, GTIFF_DOUBLEPARAMS,
     141            5603 :                                  &gt->gt_ndoubles, &gt->gt_double ))
     142                 :     {
     143            3603 :         gt->gt_double=(double*)_GTIFcalloc(MAX_VALUES*sizeof(double));
     144            3603 :         if (!gt->gt_double) goto failure;  
     145                 :     }
     146                 :     else
     147                 :     {
     148                 :         /* resize data array so it can be extended if needed */
     149            2000 :         gt->gt_double = (double*) _GTIFrealloc(gt->gt_double,
     150                 :                                                (MAX_VALUES)*sizeof(double));
     151                 :     }
     152           13117 :     if ( tif == NULL
     153            5603 :          || !(gt->gt_methods.get)(tif, GTIFF_ASCIIPARAMS,
     154                 :                                   &tempData.tk_asciiParamsLength,
     155                 :                                   &tempData.tk_asciiParams ))
     156                 :     {
     157            1911 :         tempData.tk_asciiParams         = 0;
     158            1911 :         tempData.tk_asciiParamsLength   = 0;
     159                 :     }
     160                 :     else
     161                 :     {
     162                 :         /* last NULL doesn't count; "|" used for delimiter */
     163            7384 :         if( tempData.tk_asciiParamsLength > 0 
     164            7384 :             && tempData.tk_asciiParams[tempData.tk_asciiParamsLength-1] == '\0')
     165                 :         {
     166            3692 :             --tempData.tk_asciiParamsLength;
     167                 :         }
     168                 :     }
     169                 : 
     170                 :     /* allocate space for GeoKey array and its index */
     171            5603 :     gt->gt_keys = (GeoKey *)_GTIFcalloc( sizeof(GeoKey)*bufcount);
     172            5603 :     if (!gt->gt_keys) goto failure;
     173            5603 :     gt->gt_keyindex = (int *)_GTIFcalloc( sizeof(int)*(MAX_KEYINDEX+1));
     174            5603 :     if (!gt->gt_keyindex) goto failure;
     175                 :   
     176                 :     /*  Loop to get all GeoKeys */
     177            5603 :     entptr = ((KeyEntry *)data) + 1;
     178            5603 :     keyptr = gt->gt_keys;
     179            5603 :     gt->gt_keymin = MAX_KEYINDEX;
     180            5603 :     gt->gt_keymax = 0;
     181           30929 :     for (index=1; index<=count; index++,entptr++)
     182                 :     {
     183           25327 :         if (!ReadKey(gt, &tempData, entptr, ++keyptr))
     184               1 :             goto failure;
     185                 :       
     186                 :         /* Set up the index (start at 1, since 0=unset) */
     187           25326 :         gt->gt_keyindex[entptr->ent_key] = index;   
     188                 :     }
     189                 : 
     190            5602 :     if( tempData.tk_asciiParams != NULL )
     191            3692 :         _GTIFFree( tempData.tk_asciiParams );
     192                 :   
     193            5602 :     return gt;
     194                 :   
     195                 :   failure:
     196                 :     /* Notify of error */
     197               1 :     if( tempData.tk_asciiParams != NULL )
     198               0 :         _GTIFFree( tempData.tk_asciiParams );    
     199               1 :     GTIFFree (gt);
     200               1 :     return (GTIF *)0;
     201                 : }
     202                 : 
     203                 : /**********************************************************************
     204                 :  *
     205                 :  *                        Private Routines
     206                 :  *
     207                 :  **********************************************************************/
     208                 : 
     209                 : /*
     210                 :  * Given KeyEntry, read in the GeoKey value location and set up
     211                 :  *  the Key structure, returning 0 if failure.
     212                 :  */
     213                 : 
     214           25327 : static int ReadKey(GTIF* gt, TempKeyData* tempData,
     215                 :                    KeyEntry* entptr, GeoKey* keyptr)
     216                 : {
     217                 :     int offset,count;
     218                 :   
     219           25327 :     keyptr->gk_key = entptr->ent_key;
     220           25327 :     keyptr->gk_count = entptr->ent_count;
     221           25327 :     count = entptr->ent_count;
     222           25327 :     offset = entptr->ent_val_offset;
     223           25327 :     if (gt->gt_keymin > keyptr->gk_key)  gt->gt_keymin=keyptr->gk_key;
     224           25327 :     if (gt->gt_keymax < keyptr->gk_key)  gt->gt_keymax=keyptr->gk_key;
     225                 :   
     226           25327 :     if (entptr->ent_location)
     227            9085 :         keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,entptr->ent_location);
     228                 :     else
     229           16242 :         keyptr->gk_type = (gt->gt_methods.type)(gt->gt_tif,GTIFF_GEOKEYDIRECTORY);
     230                 :     
     231           25327 :     switch (entptr->ent_location)
     232                 :     {
     233                 :         case GTIFF_LOCAL:
     234                 :             /* store value into data value */
     235           16242 :             *(pinfo_t *)(&keyptr->gk_data) = entptr->ent_val_offset;
     236           16242 :             break;
     237                 :         case GTIFF_GEOKEYDIRECTORY:
     238               0 :             keyptr->gk_data = (char *)(gt->gt_short+offset);
     239               0 :             if (gt->gt_nshorts < offset+count)
     240               0 :                 gt->gt_nshorts = offset+count;
     241               0 :             break;
     242                 :         case GTIFF_DOUBLEPARAMS:
     243            4482 :             keyptr->gk_data = (char *)(gt->gt_double+offset);
     244            4482 :             if (gt->gt_ndoubles < offset+count)
     245               0 :                 gt->gt_ndoubles = offset+count;
     246            4482 :             break;
     247                 :         case GTIFF_ASCIIPARAMS:
     248            9210 :             if( offset + count == tempData->tk_asciiParamsLength + 1 
     249            4603 :                 && count > 0 )
     250                 :             {
     251                 :                 /* some vendors seem to feel they should not use the 
     252                 :                    terminating '|' char, but do include a terminating '\0'
     253                 :                    which we lose in the low level reading code.  
     254                 :                    If this is the case, drop the extra character */
     255               4 :                 count--;
     256                 :             }
     257            9197 :             else if (offset < tempData->tk_asciiParamsLength
     258            9197 :                      && offset + count > tempData->tk_asciiParamsLength )
     259                 :             {
     260               0 :                 count = tempData->tk_asciiParamsLength - offset;
     261                 :                 /* issue warning... if we could */
     262                 :             }
     263            4599 :             else if (offset + count > tempData->tk_asciiParamsLength)
     264               1 :                 return (0);
     265                 : 
     266            4602 :             keyptr->gk_count = MAX(1,count+1);
     267            4602 :             keyptr->gk_data = (char *) _GTIFcalloc (keyptr->gk_count);
     268                 : 
     269            9204 :             _GTIFmemcpy (keyptr->gk_data,
     270            4602 :                          tempData->tk_asciiParams + offset, count);
     271            4602 :             if( keyptr->gk_data[MAX(0,count-1)] == '|' )
     272                 :             {
     273            4598 :                 keyptr->gk_data[MAX(0,count-1)] = '\0';
     274            4598 :                 keyptr->gk_count = count;
     275                 :             }
     276                 :             else
     277               4 :                 keyptr->gk_data[MAX(0,count)] = '\0';
     278            4602 :             break;
     279                 :         default:
     280               0 :             return 0; /* failure */
     281                 :     }
     282           25326 :     keyptr->gk_size = _gtiff_size[keyptr->gk_type];
     283                 :   
     284           25326 :     return 1; /* success */
     285                 : }

Generated by: LCOV version 1.7