~ubuntu-branches/ubuntu/hardy/libterralib/hardy

« back to all changes in this revision

Viewing changes to src/tiff/geo_set.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2005-11-25 22:32:59 UTC
  • Revision ID: james.westby@ubuntu.com-20051125223259-3zubal8ux4ki4fjg
Tags: upstream-3.0.3b2
ImportĀ upstreamĀ versionĀ 3.0.3b2

Show diffs side-by-side

added added

removed removed

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