1 : /******************************************************************************
2 : * Copyright (c) 2008, Frank Warmerdam
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the "Software"),
6 : * to deal in the Software without restriction, including without limitation
7 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 : * and/or sell copies of the Software, and to permit persons to whom the
9 : * Software is furnished to do so, subject to the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included
12 : * in all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 : * DEALINGS IN THE SOFTWARE.
21 : ******************************************************************************
22 : *
23 : * geo_simpletags.c TIFF Interface module that just keeps track of the
24 : * tags in memory, without depending on libtiff.
25 : *
26 : *****************************************************************************/
27 :
28 : #include "geotiff.h" /* public GTIFF interface */
29 : #include "geo_simpletags.h"
30 :
31 : #include "geo_tiffp.h" /* Private TIFF interface */
32 : #include "geo_keyp.h" /* Private GTIFF interface */
33 :
34 : static int ST_TypeSize( int st_type );
35 :
36 : static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *value );
37 : static int _GTIFSetField (tiff_t *tif, pinfo_t tag, int count, void *value );
38 : static tagtype_t _GTIFTagType (tiff_t *tif, pinfo_t tag);
39 :
40 : /*
41 : * Set up default TIFF handlers.
42 : */
43 0 : void GTIFSetSimpleTagsMethods(TIFFMethod *method)
44 : {
45 0 : if (!method) return;
46 :
47 0 : method->get = _GTIFGetField;
48 0 : method->set = _GTIFSetField;
49 0 : method->type = _GTIFTagType;
50 : }
51 :
52 : /* returns the value of TIFF tag <tag>, or if
53 : * the value is an array, returns an allocated buffer
54 : * containing the values. Allocate a copy of the actual
55 : * buffer, sized up for updating.
56 : */
57 0 : static int _GTIFGetField (tiff_t *tif, pinfo_t tag, int *count, void *val )
58 : {
59 : int item_size, data_type;
60 : void *internal_value, *ret_value;
61 :
62 0 : if( !ST_GetKey( (ST_TIFF*) tif, (int) tag, count, &data_type,
63 : &internal_value ) )
64 0 : return 0;
65 :
66 0 : if( data_type != ST_TagType( tag ) )
67 0 : return 0;
68 :
69 0 : item_size = ST_TypeSize( data_type );
70 :
71 0 : ret_value = (char *)_GTIFcalloc( *count * item_size );
72 0 : if (!ret_value) return 0;
73 :
74 0 : _TIFFmemcpy( ret_value, internal_value, item_size * *count );
75 :
76 0 : *(void **)val = ret_value;
77 0 : return 1;
78 : }
79 :
80 : /*
81 : * Set a GeoTIFF TIFF field.
82 : */
83 0 : static int _GTIFSetField (tiff_t *tif, pinfo_t tag, int count, void *value )
84 : {
85 0 : int st_type = ST_TagType( tag );
86 :
87 0 : return ST_SetKey( (ST_TIFF *) tif, (int) tag, count, st_type, value );
88 : }
89 :
90 : /*
91 : * This routine is supposed to return the TagType of the <tag>
92 : * TIFF tag. Unfortunately, "libtiff" does not provide this
93 : * service by default, so we just have to "know" what type of tags
94 : * we've got, and how many. We only define the ones Geotiff
95 : * uses here, and others return UNKNOWN. The "tif" parameter
96 : * is provided for those TIFF implementations that provide
97 : * for tag-type queries.
98 : */
99 0 : static tagtype_t _GTIFTagType (tiff_t *tif, pinfo_t tag)
100 : {
101 : tagtype_t ttype;
102 :
103 : (void) tif; /* dummy reference */
104 :
105 0 : switch (tag)
106 : {
107 0 : case GTIFF_ASCIIPARAMS: ttype=TYPE_ASCII; break;
108 : case GTIFF_PIXELSCALE:
109 : case GTIFF_TRANSMATRIX:
110 : case GTIFF_TIEPOINTS:
111 0 : case GTIFF_DOUBLEPARAMS: ttype=TYPE_DOUBLE; break;
112 0 : case GTIFF_GEOKEYDIRECTORY: ttype=TYPE_SHORT; break;
113 0 : default: ttype = TYPE_UNKNOWN;
114 : }
115 :
116 0 : return ttype;
117 : }
118 :
119 : /************************************************************************/
120 : /* ST_TagType() */
121 : /************************************************************************/
122 :
123 0 : int ST_TagType( int tag )
124 : {
125 0 : switch (tag)
126 : {
127 : case GTIFF_ASCIIPARAMS:
128 0 : return STT_ASCII;
129 :
130 : case GTIFF_PIXELSCALE:
131 : case GTIFF_TRANSMATRIX:
132 : case GTIFF_TIEPOINTS:
133 : case GTIFF_DOUBLEPARAMS:
134 0 : return STT_DOUBLE;
135 :
136 : case GTIFF_GEOKEYDIRECTORY:
137 0 : return STT_SHORT;
138 : }
139 :
140 0 : return -1;
141 : }
142 :
143 :
144 : /************************************************************************/
145 : /* ST_TypeSize() */
146 : /************************************************************************/
147 :
148 0 : static int ST_TypeSize( int st_type )
149 :
150 : {
151 0 : if( st_type == STT_ASCII )
152 0 : return 1;
153 0 : else if( st_type == STT_SHORT )
154 0 : return 2;
155 0 : else if( st_type == STT_DOUBLE )
156 0 : return 8;
157 : else
158 0 : return 8;
159 : }
160 :
161 : /************************************************************************/
162 : /* ST_Create() */
163 : /************************************************************************/
164 :
165 0 : ST_TIFF *ST_Create()
166 :
167 : {
168 0 : return (ST_TIFF *) calloc(1,sizeof(ST_TIFF));
169 : }
170 :
171 : /************************************************************************/
172 : /* ST_Destroy() */
173 : /************************************************************************/
174 :
175 0 : void ST_Destroy( ST_TIFF *st )
176 :
177 : {
178 : int i;
179 :
180 0 : for( i = 0; i < st->key_count; i++ )
181 0 : free( st->key_list[i].data );
182 :
183 0 : if( st->key_list )
184 0 : free( st->key_list );
185 0 : free( st );
186 0 : }
187 :
188 : /************************************************************************/
189 : /* ST_SetKey() */
190 : /************************************************************************/
191 :
192 0 : int ST_SetKey( ST_TIFF *st, int tag, int count, int st_type, void *data )
193 :
194 : {
195 0 : int i, item_size = ST_TypeSize( st_type );
196 :
197 : /* -------------------------------------------------------------------- */
198 : /* We should compute the length if we were not given a count */
199 : /* -------------------------------------------------------------------- */
200 0 : if (count == 0 && st_type == STT_ASCII )
201 : {
202 0 : count = strlen((char*)data);
203 : }
204 :
205 : /* -------------------------------------------------------------------- */
206 : /* If we already have a value for this tag, replace it. */
207 : /* -------------------------------------------------------------------- */
208 0 : for( i = 0; i < st->key_count; i++ )
209 : {
210 0 : if( st->key_list[i].tag == tag )
211 : {
212 0 : free( st->key_list[i].data );
213 0 : st->key_list[i].count = count;
214 0 : st->key_list[i].type = st_type;
215 0 : st->key_list[i].data = malloc(item_size*count);
216 0 : memcpy( st->key_list[i].data, data, count * item_size );
217 0 : return 1;
218 : }
219 : }
220 :
221 : /* -------------------------------------------------------------------- */
222 : /* Otherwise, add a new entry. */
223 : /* -------------------------------------------------------------------- */
224 0 : st->key_count++;
225 0 : st->key_list = (ST_KEY *) realloc(st->key_list,
226 : sizeof(ST_KEY) * st->key_count);
227 0 : st->key_list[st->key_count-1].tag = tag;
228 0 : st->key_list[st->key_count-1].count = count;
229 0 : st->key_list[st->key_count-1].type = st_type;
230 0 : st->key_list[st->key_count-1].data = malloc(item_size * count);
231 0 : memcpy( st->key_list[st->key_count-1].data, data, item_size * count );
232 :
233 0 : return 1;
234 : }
235 :
236 : /************************************************************************/
237 : /* ST_GetKey() */
238 : /************************************************************************/
239 :
240 0 : int ST_GetKey( ST_TIFF *st, int tag, int *count,
241 : int *st_type, void **data_ptr )
242 :
243 : {
244 : int i;
245 :
246 0 : for( i = 0; i < st->key_count; i++ )
247 : {
248 0 : if( st->key_list[i].tag == tag )
249 : {
250 0 : if( count )
251 0 : *count = st->key_list[i].count;
252 0 : if( st_type )
253 0 : *st_type = st->key_list[i].type;
254 0 : if( data_ptr )
255 0 : *data_ptr = st->key_list[i].data;
256 0 : return 1;
257 : }
258 : }
259 :
260 0 : return 0;
261 : }
262 :
|