00001 /********************************************************************** 00002 * 00003 * geo_set.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 * $Log$ 00012 * Revision 1.2 2001/03/05 04:58:33 warmerda 00012 * updated 00012 * 00013 * Revision 1.5 1999/05/04 03:09:33 warmerda 00014 * avoid warnings 00015 * 00016 * Revision 1.4 1999/05/03 17:50:31 warmerda 00017 * avoid warnings on IRIX 00018 * 00019 * Revision 1.3 1999/04/28 19:59:38 warmerda 00020 * added some doxygen style documentation 00021 * 00022 * Revision 1.2 1999/03/11 17:39:38 geotiff 00023 * Added fix for case where a key is being overwritten. 00024 * 00025 **********************************************************************/ 00026 00027 #include "geotiff.h" /* public interface */ 00028 #include "geo_tiffp.h" /* external TIFF interface */ 00029 #include "geo_keyp.h" /* private interface */ 00030 00031 #include <assert.h> 00032 00091 int GTIFKeySet(GTIF *gtif, geokey_t keyID, tagtype_t type, int count,...) 00092 { 00093 va_list ap; 00094 int index = gtif->gt_keyindex[ keyID ]; 00095 int newvalues = 0; 00096 GeoKey *key; 00097 char *data; 00098 char *val; 00099 pinfo_t sval; 00100 double dval; 00101 00102 va_start(ap, count); 00103 /* pass singleton keys by value */ 00104 if (count>1 && type!=TYPE_ASCII) val = va_arg(ap, char*); 00105 else switch (type) 00106 { 00107 case TYPE_SHORT: sval=va_arg(ap, int); val=(char *)&sval; break; 00108 case TYPE_DOUBLE: dval=va_arg(ap, dblparam_t); val=(char *)&dval; break; 00109 case TYPE_ASCII: 00110 val=va_arg(ap, char*); 00111 count = strlen(val) + 1; /* force = string length */ 00112 break; 00113 default: 00114 assert( FALSE ); 00115 break; 00116 } 00117 va_end(ap); 00118 00119 /* We assume here that there are no multi-valued SHORTS ! */ 00120 if (index) 00121 { 00122 /* Key already exists */ 00123 key = gtif->gt_keys+index; 00124 if (type!=key->gk_type || count > key->gk_count) 00125 { 00126 /* need to reset data pointer */ 00127 key->gk_type = type; 00128 key->gk_count = count; 00129 key->gk_size = _gtiff_size[ type ]; 00130 newvalues = 1; 00131 } 00132 } 00133 else 00134 { 00135 /* We need to create the key */ 00136 if (gtif->gt_num_keys == MAX_KEYS) return 0; 00137 key = gtif->gt_keys + ++gtif->gt_num_keys; 00138 index = gtif->gt_num_keys; 00139 gtif->gt_keyindex[ keyID ] = index; 00140 key->gk_key = keyID; 00141 key->gk_type = type; 00142 key->gk_count = count; 00143 key->gk_size = _gtiff_size[ type ]; 00144 if (gtif->gt_keymin > keyID) gtif->gt_keymin=keyID; 00145 if (gtif->gt_keymax < keyID) gtif->gt_keymax=keyID; 00146 newvalues = 1; 00147 } 00148 00149 if (newvalues) 00150 { 00151 switch (type) 00152 { 00153 case TYPE_SHORT: 00154 if (count > 1) return 0; 00155 data = (char *)&key->gk_data; /* store value *in* data */ 00156 break; 00157 case TYPE_DOUBLE: 00158 key->gk_data = (char *)(gtif->gt_double + gtif->gt_ndoubles); 00159 data = key->gk_data; 00160 gtif->gt_ndoubles += count; 00161 break; 00162 case TYPE_ASCII: 00163 key->gk_data = (char *)(gtif->gt_ascii + gtif->gt_nascii); 00164 data = key->gk_data; 00165 gtif->gt_nascii += count; 00166 data[--count] = '|'; /* replace NULL with '|' */ 00167 break; 00168 default: 00169 va_end(ap); 00170 return 0; 00171 } 00172 gtif->gt_nshorts += sizeof(KeyEntry)/sizeof(pinfo_t); 00173 } 00174 00175 /* this fixes a bug where if a request is made to write a duplicate 00176 key, we must initialize the data to a valid value. 00177 Bryan Wells (bryan@athena.bangor.autometric.com) */ 00178 00179 else /* no new values, but still have something to write */ 00180 { 00181 switch (type) 00182 { 00183 case TYPE_SHORT: 00184 if (count > 1) return 0; 00185 data = (char *)&key->gk_data; /* store value *in* data */ 00186 break; 00187 case TYPE_DOUBLE: 00188 data = key->gk_data; 00189 break; 00190 case TYPE_ASCII: 00191 data = key->gk_data; 00192 data[--count] = '|'; /* replace NULL with '|' */ 00193 break; 00194 default: 00195 return 0; 00196 } 00197 00198 } 00199 00200 _GTIFmemcpy(data, val, count*key->gk_size); 00201 00202 gtif->gt_flags |= FLAG_FILE_MODIFIED; 00203 return 1; 00204 }