Line data Source code
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 data_type;
60 : void *internal_value;
61 0 : if( !ST_GetKey( (ST_TIFF*) tif, (int) tag, count, &data_type,
62 : &internal_value ) )
63 0 : return 0;
64 :
65 0 : if( data_type != ST_TagType( tag ) )
66 0 : return 0;
67 :
68 0 : const int item_size = ST_TypeSize( data_type );
69 :
70 0 : void *ret_value = (char *)_GTIFcalloc( (size_t)(*count) * item_size );
71 0 : if (!ret_value) return 0;
72 :
73 0 : _TIFFmemcpy( ret_value, internal_value, (size_t)(item_size) * *count );
74 :
75 0 : *(void **)val = ret_value;
76 0 : return 1;
77 : }
78 :
79 : /*
80 : * Set a GeoTIFF TIFF field.
81 : */
82 0 : static int _GTIFSetField (tiff_t *tif, pinfo_t tag, int count, void *value )
83 : {
84 0 : const int st_type = ST_TagType( tag );
85 :
86 0 : return ST_SetKey( (ST_TIFF *) tif, (int) tag, count, st_type, value );
87 : }
88 :
89 : /*
90 : * This routine is supposed to return the TagType of the <tag>
91 : * TIFF tag. Unfortunately, "libtiff" does not provide this
92 : * service by default, so we just have to "know" what type of tags
93 : * we've got, and how many. We only define the ones Geotiff
94 : * uses here, and others return UNKNOWN. The "tif" parameter
95 : * is provided for those TIFF implementations that provide
96 : * for tag-type queries.
97 : */
98 0 : static tagtype_t _GTIFTagType (tiff_t *tif, pinfo_t tag)
99 : {
100 : (void) tif; /* dummy reference */
101 :
102 : tagtype_t ttype;
103 0 : switch (tag)
104 : {
105 0 : case GTIFF_ASCIIPARAMS: ttype=TYPE_ASCII; break;
106 0 : case GTIFF_PIXELSCALE:
107 : case GTIFF_TRANSMATRIX:
108 : case GTIFF_TIEPOINTS:
109 0 : case GTIFF_DOUBLEPARAMS: ttype=TYPE_DOUBLE; break;
110 0 : case GTIFF_GEOKEYDIRECTORY: ttype=TYPE_SHORT; break;
111 0 : default: ttype = TYPE_UNKNOWN;
112 : }
113 :
114 0 : return ttype;
115 : }
116 :
117 : /************************************************************************/
118 : /* ST_TagType() */
119 : /************************************************************************/
120 :
121 0 : int ST_TagType( int tag )
122 : {
123 0 : switch (tag)
124 : {
125 0 : case GTIFF_ASCIIPARAMS:
126 0 : return STT_ASCII;
127 :
128 0 : case GTIFF_PIXELSCALE:
129 : case GTIFF_TRANSMATRIX:
130 : case GTIFF_TIEPOINTS:
131 : case GTIFF_DOUBLEPARAMS:
132 0 : return STT_DOUBLE;
133 :
134 0 : case GTIFF_GEOKEYDIRECTORY:
135 0 : return STT_SHORT;
136 : }
137 :
138 0 : return -1;
139 : }
140 :
141 :
142 : /************************************************************************/
143 : /* ST_TypeSize() */
144 : /************************************************************************/
145 :
146 0 : static int ST_TypeSize( int st_type )
147 :
148 : {
149 0 : if( st_type == STT_ASCII )
150 0 : return 1;
151 0 : else if( st_type == STT_SHORT )
152 0 : return 2;
153 : else /* if( st_type == STT_DOUBLE ) */
154 0 : return 8;
155 : }
156 :
157 : /************************************************************************/
158 : /* ST_Create() */
159 : /************************************************************************/
160 :
161 0 : ST_TIFF *ST_Create()
162 :
163 : {
164 0 : return (ST_TIFF *) calloc(1,sizeof(ST_TIFF));
165 : }
166 :
167 : /************************************************************************/
168 : /* ST_Destroy() */
169 : /************************************************************************/
170 :
171 0 : void ST_Destroy( ST_TIFF *st )
172 :
173 : {
174 0 : for( int i = 0; i < st->key_count; i++ )
175 0 : free( st->key_list[i].data );
176 :
177 0 : if( st->key_list )
178 0 : free( st->key_list );
179 0 : free( st );
180 0 : }
181 :
182 : /************************************************************************/
183 : /* ST_SetKey() */
184 : /************************************************************************/
185 :
186 0 : int ST_SetKey( ST_TIFF *st, int tag, int count, int st_type, void *data )
187 :
188 : {
189 : /* -------------------------------------------------------------------- */
190 : /* We should compute the length if we were not given a count */
191 : /* -------------------------------------------------------------------- */
192 0 : if (count == 0 && st_type == STT_ASCII )
193 : {
194 0 : count = (int)strlen((char*)data)+1;
195 : }
196 :
197 : /* -------------------------------------------------------------------- */
198 : /* If we already have a value for this tag, replace it. */
199 : /* -------------------------------------------------------------------- */
200 0 : const int item_size = ST_TypeSize( st_type );
201 0 : for( int i = 0; i < st->key_count; i++ )
202 : {
203 0 : if( st->key_list[i].tag == tag )
204 : {
205 0 : free( st->key_list[i].data );
206 0 : st->key_list[i].count = count;
207 0 : st->key_list[i].type = st_type;
208 : /* +1 to make clang static analyzer not warn about potential malloc(0) */
209 0 : st->key_list[i].data = malloc(item_size*count+1);
210 0 : memcpy( st->key_list[i].data, data, (size_t)count * item_size );
211 0 : return 1;
212 : }
213 : }
214 :
215 : /* -------------------------------------------------------------------- */
216 : /* Otherwise, add a new entry. */
217 : /* -------------------------------------------------------------------- */
218 0 : st->key_count++;
219 0 : st->key_list = (ST_KEY *) realloc(st->key_list,
220 0 : sizeof(ST_KEY) * st->key_count);
221 0 : st->key_list[st->key_count-1].tag = tag;
222 0 : st->key_list[st->key_count-1].count = count;
223 0 : st->key_list[st->key_count-1].type = st_type;
224 : /* +1 to make clang static analyzer not warn about potential malloc(0) */
225 0 : st->key_list[st->key_count-1].data = malloc((size_t)(item_size) * count+1);
226 0 : memcpy( st->key_list[st->key_count-1].data, data, (size_t)(item_size) * count );
227 :
228 0 : return 1;
229 : }
230 :
231 : /************************************************************************/
232 : /* ST_GetKey() */
233 : /************************************************************************/
234 :
235 0 : int ST_GetKey( ST_TIFF *st, int tag, int *count,
236 : int *st_type, void **data_ptr )
237 :
238 : {
239 0 : for( int i = 0; i < st->key_count; i++ )
240 : {
241 0 : if( st->key_list[i].tag == tag )
242 : {
243 0 : if( count )
244 0 : *count = st->key_list[i].count;
245 0 : if( st_type )
246 0 : *st_type = st->key_list[i].type;
247 0 : if( data_ptr )
248 0 : *data_ptr = st->key_list[i].data;
249 0 : return 1;
250 : }
251 : }
252 :
253 0 : return 0;
254 : }
|