LCOV - code coverage report
Current view: top level - frmts/gtiff/libgeotiff - geo_set.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 61 87 70.1 %
Date: 2024-05-04 12:52:34 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.14