LCOV - code coverage report
Current view: directory - frmts/gtiff/libgeotiff - geo_set.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 80 60 75.0 %
Date: 2011-12-18 Functions: 1 1 100.0 %

       1                 : /**********************************************************************
       2                 :  *
       3                 :  *  geo_set.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 "geotiff.h"   /* public interface        */
      15                 : #include "geo_tiffp.h" /* external TIFF interface */
      16                 : #include "geo_keyp.h"  /* private interface       */
      17                 : 
      18                 : #include <assert.h>
      19                 : 
      20                 : /**
      21                 : This function writes a geokey_t value to a GeoTIFF file.
      22                 : 
      23                 : @param gtif The geotiff information handle from GTIFNew().
      24                 : 
      25                 : @param keyID The geokey_t name (such as ProjectedCSTypeGeoKey).
      26                 : This must come from the list of legal geokey_t values
      27                 : (an enumeration) listed below.
      28                 : 
      29                 : @param val The <b>val</b> argument is a pointer to the
      30                 : variable into which the value should be read.  The type of the variable
      31                 : varies depending on the geokey_t given.  While there is no ready mapping
      32                 : of geokey_t values onto types, in general code values are of type <i>short</i>,
      33                 : citations are strings, and everything else is of type <i>double</i>.  Note
      34                 : that pointer's to <i>int</i> should never be passed to GTIFKeyGet() for
      35                 : integer values as they will be shorts, and the int's may not be properly
      36                 : initialized (and will be grossly wrong on MSB systems).
      37                 : 
      38                 : @param index Indicates how far into the list of values
      39                 : for this geokey to offset. Should normally be zero.
      40                 : 
      41                 : @param count Indicates how many values
      42                 : to read.  At this time all keys except for strings have only one value,
      43                 : so <b>index</b> should be zero, and <b>count</b> should be one.<p>
      44                 : 
      45                 : The <b>key</b> indicates the key name to be written to the
      46                 : file and should from the geokey_t enumeration 
      47                 : (eg. <tt>ProjectedCSTypeGeoKey</tt>).  The full list of possible geokey_t
      48                 : values can be found in geokeys.inc, or in the online documentation for
      49                 : GTIFKeyGet().<p>
      50                 : 
      51                 : The <b>type</b> should be one of TYPE_SHORT, TYPE_ASCII, or TYPE_DOUBLE and
      52                 : will indicate the type of value being passed at the end of the argument
      53                 : list (the key value).  The <b>count</b> should be one except for strings
      54                 : when it should be the length of the string (or zero to for this to be
      55                 : computed internally).  As a special case a <b>count</b> of -1 can be
      56                 : used to request an existing key be deleted, in which no value is passed.<p>
      57                 : 
      58                 : The actual value is passed at the end of the argument list, and should be
      59                 : a short, a double, or a char * value.  Note that short and double values
      60                 : are passed by value rather than as pointers when count is 1, but as pointers
      61                 : if count is larger than 1.<p>
      62                 : 
      63                 : Note that key values aren't actually flushed to the file until
      64                 : GTIFWriteKeys() is called.  Till then 
      65                 : the new values are just kept with the GTIF structure.<p>
      66                 : 
      67                 : <b>Example:</b><p>
      68                 : 
      69                 : <pre>
      70                 :     GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, 
      71                 :                RasterPixelIsArea);
      72                 :     GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, 
      73                 :                "UTM 11 North / NAD27" );
      74                 : </pre>
      75                 : 
      76                 :  */
      77                 : 
      78            6755 : int GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type, int count,...)
      79                 : {
      80                 :     va_list ap;
      81            6755 :     int index = gtif->gt_keyindex[ keyID ];
      82            6755 :     int newvalues = 0;
      83                 :     GeoKey *key;
      84            6755 :     char *data = NULL;
      85            6755 :     char *val = NULL;
      86                 :     pinfo_t sval;
      87                 :     double dval;
      88                 : 
      89            6755 :     va_start(ap, count);
      90                 :     /* pass singleton keys by value */
      91            6780 :     if (count>1 && type!=TYPE_ASCII) 
      92                 :     {
      93              25 :         val = va_arg(ap, char*);
      94                 :     }
      95            6730 :     else if( count == -1 )
      96                 :     {
      97                 :         /* delete the indicated tag */
      98               0 :         va_end(ap);
      99                 : 
     100               0 :         if( index < 1 )
     101               0 :             return 0;
     102                 : 
     103               0 :         if (gtif->gt_keys[index].gk_type == TYPE_ASCII)
     104                 :         {
     105               0 :             _GTIFFree (gtif->gt_keys[index].gk_data);
     106                 :         }
     107                 : 
     108               0 :         while( index < gtif->gt_num_keys )
     109                 :         {
     110               0 :             _GTIFmemcpy( gtif->gt_keys + index, 
     111               0 :                          gtif->gt_keys + index + 1, 
     112                 :                          sizeof(GeoKey) );
     113               0 :             gtif->gt_keyindex[gtif->gt_keys[index].gk_key] = index;
     114               0 :             index++;
     115                 :         }
     116                 : 
     117               0 :         gtif->gt_num_keys--;
     118               0 :         gtif->gt_nshorts -= sizeof(KeyEntry)/sizeof(pinfo_t);
     119               0 :         gtif->gt_keyindex[keyID] = 0;
     120               0 :         gtif->gt_flags |= FLAG_FILE_MODIFIED;
     121                 : 
     122               0 :         return 1;
     123                 :     }
     124            6730 :     else switch (type)
     125                 :     {
     126            3972 :       case TYPE_SHORT:  sval=(pinfo_t) va_arg(ap, int); val=(char *)&sval;     break;
     127            1599 :       case TYPE_DOUBLE: dval=va_arg(ap, dblparam_t); val=(char *)&dval;  break;
     128                 :       case TYPE_ASCII: 
     129            1159 :         val=va_arg(ap, char*);
     130            1159 :         count = strlen(val) + 1; /* force = string length */
     131            1159 :         break;
     132                 :       default:
     133               0 :         assert( FALSE );
     134                 :         break;
     135                 :     }
     136            6755 :     va_end(ap);
     137                 :     
     138                 :     /* We assume here that there are no multi-valued SHORTS ! */
     139            6755 :     if (index)
     140                 :     {
     141                 :         /* Key already exists */
     142              80 :         key = gtif->gt_keys+index;
     143              80 :         if (type!=key->gk_type || count > key->gk_count)
     144                 :         {
     145                 :             /* need to reset data pointer */
     146              25 :             key->gk_type = type;
     147              25 :             key->gk_count = count;
     148              25 :             key->gk_size = _gtiff_size[ type ];
     149              25 :             newvalues = 1;
     150                 :         }
     151                 :     }
     152                 :     else
     153                 :     {
     154                 :         /* We need to create the key */
     155            6675 :         if (gtif->gt_num_keys == MAX_KEYS) return 0;
     156            6675 :         key = gtif->gt_keys + ++gtif->gt_num_keys;
     157            6675 :         index = gtif->gt_num_keys;
     158            6675 :         gtif->gt_keyindex[ keyID ] = index;
     159            6675 :         key->gk_key = keyID;
     160            6675 :         key->gk_type = type;
     161            6675 :         key->gk_count = count;
     162            6675 :         key->gk_size = _gtiff_size[ type ];
     163            6675 :         if (gtif->gt_keymin > keyID)  gtif->gt_keymin=keyID;
     164            6675 :         if (gtif->gt_keymax < keyID)  gtif->gt_keymax=keyID;
     165            6675 :         newvalues = 1;
     166                 :     }
     167                 : 
     168            6755 :     if (newvalues)
     169                 :     {
     170            6700 :         switch (type)
     171                 :         {
     172                 :           case TYPE_SHORT:  
     173            3962 :             if (count > 1) return 0;
     174            3962 :             data = (char *)&key->gk_data; /* store value *in* data */
     175            3962 :             break;
     176                 :           case TYPE_DOUBLE:
     177            1579 :             key->gk_data = (char *)(gtif->gt_double + gtif->gt_ndoubles);
     178            1579 :             data = key->gk_data;
     179            1579 :             gtif->gt_ndoubles += count;
     180            1579 :             break;
     181                 :           case TYPE_ASCII:
     182            1159 :             break;
     183                 :           default:
     184               0 :             va_end(ap);
     185               0 :             return 0;
     186                 :         }
     187            6700 :         gtif->gt_nshorts += sizeof(KeyEntry)/sizeof(pinfo_t);
     188                 :     }
     189                 : 
     190                 :     /* this fixes a bug where if a request is made to write a duplicate
     191                 :        key, we must initialize the data to a valid value.
     192                 :        Bryan Wells (bryan@athena.bangor.autometric.com) */
     193                 :         
     194                 :     else /* no new values, but still have something to write */
     195                 :     {
     196              55 :         switch (type)
     197                 :         {
     198                 :           case TYPE_SHORT:  
     199              10 :             if (count > 1) return 0;
     200              10 :             data = (char *)&key->gk_data; /* store value *in* data */
     201              10 :             break;
     202                 :           case TYPE_DOUBLE:
     203              45 :             data = key->gk_data;
     204              45 :             break;
     205                 :           case TYPE_ASCII:
     206               0 :             break;
     207                 :           default:
     208               0 :             return 0;
     209                 :         }
     210                 :     }
     211                 :         
     212            6755 :     switch (type)
     213                 :     {
     214                 :       case TYPE_ASCII:
     215                 :         /* throw away existing data and allocate room for new data */
     216            1159 :         if (key->gk_data != 0)
     217                 :         {
     218              25 :             _GTIFFree(key->gk_data);
     219                 :         }
     220            1159 :         key->gk_data = (char *)_GTIFcalloc(count);
     221            1159 :         key->gk_count = count;
     222            1159 :         data = key->gk_data;
     223                 :         break;
     224                 :       default:
     225                 :         break;
     226                 :     }
     227                 : 
     228            6755 :     _GTIFmemcpy(data, val, count*key->gk_size);
     229                 :     
     230            6755 :     gtif->gt_flags |= FLAG_FILE_MODIFIED;
     231            6755 :     return 1;
     232                 : }

Generated by: LCOV version 1.7