]> git.saurik.com Git - wxWidgets.git/blob - src/tiff/tools/tiffset.c
fix assertion failure when string transform is requested before entry is set
[wxWidgets.git] / src / tiff / tools / tiffset.c
1 /******************************************************************************
2 * $Id$
3 *
4 * Project: libtiff tools
5 * Purpose: Mainline for setting metadata in existing TIFF files.
6 * Author: Frank Warmerdam, warmerdam@pobox.com
7 *
8 ******************************************************************************
9 * Copyright (c) 2000, Frank Warmerdam
10 *
11 * Permission to use, copy, modify, distribute, and sell this software and
12 * its documentation for any purpose is hereby granted without fee, provided
13 * that (i) the above copyright notices and this permission notice appear in
14 * all copies of the software and related documentation, and (ii) the names of
15 * Sam Leffler and Silicon Graphics may not be used in any advertising or
16 * publicity relating to the software without the specific, prior written
17 * permission of Sam Leffler and Silicon Graphics.
18 *
19 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
21 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
22 *
23 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
24 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
25 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
26 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
27 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * OF THIS SOFTWARE.
29 ******************************************************************************
30 */
31
32
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36
37 #include "tiffio.h"
38
39 static char* usageMsg[] = {
40 "usage: tiffset [options] filename",
41 "where options are:",
42 " -s <tagname> [count] <value>... set the tag value",
43 " -d <dirno> set the directory",
44 " -sd <diroff> set the subdirectory",
45 " -sf <tagname> <filename> read the tag value from file (for ASCII tags only)",
46 NULL
47 };
48
49 static void
50 usage(void)
51 {
52 int i;
53 for (i = 0; usageMsg[i]; i++)
54 fprintf(stderr, "%s\n", usageMsg[i]);
55 exit(-1);
56 }
57
58 static const TIFFField *
59 GetField(TIFF *tiff, const char *tagname)
60 {
61 const TIFFField *fip;
62
63 if( atoi(tagname) > 0 )
64 fip = TIFFFieldWithTag(tiff, (ttag_t)atoi(tagname));
65 else
66 fip = TIFFFieldWithName(tiff, tagname);
67
68 if (!fip) {
69 fprintf( stderr, "Field name \"%s\" is not recognised.\n", tagname );
70 return (TIFFField *)NULL;
71 }
72
73 return fip;
74 }
75
76 int
77 main(int argc, char* argv[])
78 {
79 TIFF *tiff;
80 int arg_index;
81
82 if (argc < 2)
83 usage();
84
85 tiff = TIFFOpen(argv[argc-1], "r+");
86 if (tiff == NULL)
87 return 2;
88
89 for( arg_index = 1; arg_index < argc-1; arg_index++ ) {
90 if (strcmp(argv[arg_index],"-d") == 0 && arg_index < argc-2) {
91 arg_index++;
92 if( TIFFSetDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
93 {
94 fprintf( stderr, "Failed to set directory=%s\n", argv[arg_index] );
95 return 6;
96 }
97 arg_index++;
98 }
99 if (strcmp(argv[arg_index],"-sd") == 0 && arg_index < argc-2) {
100 arg_index++;
101 if( TIFFSetSubDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
102 {
103 fprintf( stderr, "Failed to set sub directory=%s\n", argv[arg_index] );
104 return 7;
105 }
106 arg_index++;
107 }
108 if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) {
109 const TIFFField *fip;
110 const char *tagname;
111
112 arg_index++;
113 tagname = argv[arg_index];
114 fip = GetField(tiff, tagname);
115
116 if (!fip)
117 return 3;
118
119 arg_index++;
120 if (TIFFFieldDataType(fip) == TIFF_ASCII) {
121 if (TIFFSetField(tiff, TIFFFieldTag(fip), argv[arg_index]) != 1)
122 fprintf( stderr, "Failed to set %s=%s\n",
123 TIFFFieldName(fip), argv[arg_index] );
124 } else if (TIFFFieldWriteCount(fip) > 0
125 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) {
126 int ret = 1;
127 short wc;
128
129 if (TIFFFieldWriteCount(fip) == TIFF_VARIABLE)
130 wc = atoi(argv[arg_index++]);
131 else
132 wc = TIFFFieldWriteCount(fip);
133
134 if (argc - arg_index < wc) {
135 fprintf( stderr,
136 "Number of tag values is not enough. "
137 "Expected %d values for %s tag, got %d\n",
138 wc, TIFFFieldName(fip), argc - arg_index);
139 return 4;
140 }
141
142 if (wc > 1) {
143 int i, size;
144 void *array;
145
146 switch (TIFFFieldDataType(fip)) {
147 /*
148 * XXX: We can't use TIFFDataWidth()
149 * to determine the space needed to store
150 * the value. For TIFF_RATIONAL values
151 * TIFFDataWidth() returns 8, but we use 4-byte
152 * float to represent rationals.
153 */
154 case TIFF_BYTE:
155 case TIFF_ASCII:
156 case TIFF_SBYTE:
157 case TIFF_UNDEFINED:
158 default:
159 size = 1;
160 break;
161
162 case TIFF_SHORT:
163 case TIFF_SSHORT:
164 size = 2;
165 break;
166
167 case TIFF_LONG:
168 case TIFF_SLONG:
169 case TIFF_FLOAT:
170 case TIFF_IFD:
171 case TIFF_RATIONAL:
172 case TIFF_SRATIONAL:
173 size = 4;
174 break;
175
176 case TIFF_DOUBLE:
177 size = 8;
178 break;
179 }
180
181 array = _TIFFmalloc(wc * size);
182 if (!array) {
183 fprintf(stderr, "No space for %s tag\n",
184 tagname);
185 return 4;
186 }
187
188 switch (TIFFFieldDataType(fip)) {
189 case TIFF_BYTE:
190 for (i = 0; i < wc; i++)
191 ((uint8 *)array)[i] = atoi(argv[arg_index+i]);
192 break;
193 case TIFF_SHORT:
194 for (i = 0; i < wc; i++)
195 ((uint16 *)array)[i] = atoi(argv[arg_index+i]);
196 break;
197 case TIFF_SBYTE:
198 for (i = 0; i < wc; i++)
199 ((int8 *)array)[i] = atoi(argv[arg_index+i]);
200 break;
201 case TIFF_SSHORT:
202 for (i = 0; i < wc; i++)
203 ((int16 *)array)[i] = atoi(argv[arg_index+i]);
204 break;
205 case TIFF_LONG:
206 for (i = 0; i < wc; i++)
207 ((uint32 *)array)[i] = atol(argv[arg_index+i]);
208 break;
209 case TIFF_SLONG:
210 case TIFF_IFD:
211 for (i = 0; i < wc; i++)
212 ((uint32 *)array)[i] = atol(argv[arg_index+i]);
213 break;
214 case TIFF_DOUBLE:
215 for (i = 0; i < wc; i++)
216 ((double *)array)[i] = atof(argv[arg_index+i]);
217 break;
218 case TIFF_RATIONAL:
219 case TIFF_SRATIONAL:
220 case TIFF_FLOAT:
221 for (i = 0; i < wc; i++)
222 ((float *)array)[i] = (float)atof(argv[arg_index+i]);
223 break;
224 default:
225 break;
226 }
227
228 if (TIFFFieldPassCount(fip)) {
229 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
230 wc, array);
231 } else if (TIFFFieldTag(fip) == TIFFTAG_PAGENUMBER
232 || TIFFFieldTag(fip) == TIFFTAG_HALFTONEHINTS
233 || TIFFFieldTag(fip) == TIFFTAG_YCBCRSUBSAMPLING
234 || TIFFFieldTag(fip) == TIFFTAG_DOTRANGE) {
235 if (TIFFFieldDataType(fip) == TIFF_BYTE) {
236 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
237 ((uint8 *)array)[0], ((uint8 *)array)[1]);
238 } else if (TIFFFieldDataType(fip) == TIFF_SHORT) {
239 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
240 ((uint16 *)array)[0], ((uint16 *)array)[1]);
241 }
242 } else {
243 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
244 array);
245 }
246
247 _TIFFfree(array);
248 } else {
249 switch (TIFFFieldDataType(fip)) {
250 case TIFF_BYTE:
251 case TIFF_SHORT:
252 case TIFF_SBYTE:
253 case TIFF_SSHORT:
254 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
255 atoi(argv[arg_index++]));
256 break;
257 case TIFF_LONG:
258 case TIFF_SLONG:
259 case TIFF_IFD:
260 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
261 atol(argv[arg_index++]));
262 break;
263 case TIFF_DOUBLE:
264 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
265 atof(argv[arg_index++]));
266 break;
267 case TIFF_RATIONAL:
268 case TIFF_SRATIONAL:
269 case TIFF_FLOAT:
270 ret = TIFFSetField(tiff, TIFFFieldTag(fip),
271 (float)atof(argv[arg_index++]));
272 break;
273 default:
274 break;
275 }
276 }
277
278 if (ret != 1)
279 fprintf(stderr, "Failed to set %s\n", TIFFFieldName(fip));
280 arg_index += wc;
281 }
282 } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) {
283 FILE *fp;
284 const TIFFField *fip;
285 char *text;
286 size_t len;
287
288 arg_index++;
289 fip = GetField(tiff, argv[arg_index]);
290
291 if (!fip)
292 return 3;
293
294 if (TIFFFieldDataType(fip) != TIFF_ASCII) {
295 fprintf( stderr,
296 "Only ASCII tags can be set from file. "
297 "%s is not ASCII tag.\n", TIFFFieldName(fip) );
298 return 5;
299 }
300
301 arg_index++;
302 fp = fopen( argv[arg_index], "rt" );
303 if(fp == NULL) {
304 perror( argv[arg_index] );
305 continue;
306 }
307
308 text = (char *) malloc(1000000);
309 len = fread( text, 1, 999999, fp );
310 text[len] = '\0';
311
312 fclose( fp );
313
314 if(TIFFSetField( tiff, TIFFFieldTag(fip), text ) != 1) {
315 fprintf(stderr, "Failed to set %s from file %s\n",
316 TIFFFieldName(fip), argv[arg_index]);
317 }
318
319 _TIFFfree( text );
320 arg_index++;
321 } else {
322 fprintf(stderr, "Unrecognised option: %s\n",
323 argv[arg_index]);
324 usage();
325 }
326 }
327
328 TIFFRewriteDirectory(tiff);
329 TIFFClose(tiff);
330 return 0;
331 }
332
333 /* vim: set ts=8 sts=8 sw=8 noet: */
334 /*
335 * Local Variables:
336 * mode: c
337 * c-basic-offset: 8
338 * fill-column: 78
339 * End:
340 */