]>
Commit | Line | Data |
---|---|---|
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 | * $Log: tiffset.c,v $ | |
32 | * Revision 1.11 2005/09/13 14:13:42 dron | |
33 | * Avoid warnings. | |
34 | * | |
35 | * Revision 1.10 2005/02/24 14:47:11 fwarmerdam | |
36 | * Updated header. | |
37 | * | |
38 | */ | |
39 | ||
40 | ||
41 | #include <stdio.h> | |
42 | #include <string.h> | |
43 | #include <stdlib.h> | |
44 | ||
45 | #include "tiffio.h" | |
46 | ||
47 | static char* usageMsg[] = { | |
48 | "usage: tiffset [options] filename", | |
49 | "where options are:", | |
50 | " -s <tagname> [count] <value>... set the tag value", | |
51 | " -sf <tagname> <filename> read the tag value from file (for ASCII tags only)", | |
52 | NULL | |
53 | }; | |
54 | ||
55 | static void | |
56 | usage(void) | |
57 | { | |
58 | int i; | |
59 | for (i = 0; usageMsg[i]; i++) | |
60 | fprintf(stderr, "%s\n", usageMsg[i]); | |
61 | exit(-1); | |
62 | } | |
63 | ||
64 | static const TIFFFieldInfo * | |
65 | GetField(TIFF *tiff, const char *tagname) | |
66 | { | |
67 | const TIFFFieldInfo *fip; | |
68 | ||
69 | if( atoi(tagname) > 0 ) | |
70 | fip = TIFFFieldWithTag(tiff, (ttag_t)atoi(tagname)); | |
71 | else | |
72 | fip = TIFFFieldWithName(tiff, tagname); | |
73 | ||
74 | if (!fip) { | |
75 | fprintf( stderr, "Field name %s not recognised.\n", tagname ); | |
76 | return (TIFFFieldInfo *)NULL; | |
77 | } | |
78 | ||
79 | return fip; | |
80 | } | |
81 | ||
82 | int | |
83 | main(int argc, char* argv[]) | |
84 | { | |
85 | TIFF *tiff; | |
86 | int arg_index; | |
87 | ||
88 | if (argc < 2) | |
89 | usage(); | |
90 | ||
91 | tiff = TIFFOpen(argv[argc-1], "r+"); | |
92 | if (tiff == NULL) | |
93 | return 2; | |
94 | ||
95 | for( arg_index = 1; arg_index < argc-1; arg_index++ ) { | |
96 | if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) { | |
97 | const TIFFFieldInfo *fip; | |
98 | const char *tagname; | |
99 | ||
100 | arg_index++; | |
101 | tagname = argv[arg_index]; | |
102 | fip = GetField(tiff, tagname); | |
103 | ||
104 | if (!fip) | |
105 | return 3; | |
106 | ||
107 | arg_index++; | |
108 | if (fip->field_type == TIFF_ASCII) { | |
109 | if (TIFFSetField(tiff, fip->field_tag, argv[arg_index]) != 1) | |
110 | fprintf( stderr, "Failed to set %s=%s\n", | |
111 | fip->field_name, argv[arg_index] ); | |
112 | } else if (fip->field_writecount > 0) { | |
113 | int ret = 1; | |
114 | short wc; | |
115 | ||
116 | if (fip->field_writecount == TIFF_VARIABLE) | |
117 | wc = atoi(argv[arg_index++]); | |
118 | else | |
119 | wc = fip->field_writecount; | |
120 | ||
121 | if (argc - arg_index < wc) { | |
122 | fprintf( stderr, | |
123 | "Number of tag values is not enough. " | |
124 | "Expected %d values for %s tag, got %d\n", | |
125 | wc, fip->field_name, argc - arg_index); | |
126 | return 4; | |
127 | } | |
128 | ||
129 | if (wc > 1) { | |
130 | int i, size; | |
131 | void *array; | |
132 | ||
133 | switch (fip->field_type) { | |
134 | /* | |
135 | * XXX: We can't use TIFFDataWidth() | |
136 | * to determine the space needed to store | |
137 | * the value. For TIFF_RATIONAL values | |
138 | * TIFFDataWidth() returns 8, but we use 4-byte | |
139 | * float to represent rationals. | |
140 | */ | |
141 | case TIFF_BYTE: | |
142 | case TIFF_ASCII: | |
143 | case TIFF_SBYTE: | |
144 | case TIFF_UNDEFINED: | |
145 | default: | |
146 | size = 1; | |
147 | break; | |
148 | ||
149 | case TIFF_SHORT: | |
150 | case TIFF_SSHORT: | |
151 | size = 2; | |
152 | break; | |
153 | ||
154 | case TIFF_LONG: | |
155 | case TIFF_SLONG: | |
156 | case TIFF_FLOAT: | |
157 | case TIFF_IFD: | |
158 | case TIFF_RATIONAL: | |
159 | case TIFF_SRATIONAL: | |
160 | size = 4; | |
161 | break; | |
162 | ||
163 | case TIFF_DOUBLE: | |
164 | size = 8; | |
165 | break; | |
166 | } | |
167 | ||
168 | array = _TIFFmalloc(wc * size); | |
169 | if (!array) { | |
170 | fprintf(stderr, "No space for %s tag\n", | |
171 | tagname); | |
172 | return 4; | |
173 | } | |
174 | ||
175 | switch (fip->field_type) { | |
176 | case TIFF_BYTE: | |
177 | for (i = 0; i < wc; i++) | |
178 | ((uint8 *)array)[i] = atoi(argv[arg_index+i]); | |
179 | break; | |
180 | case TIFF_SHORT: | |
181 | for (i = 0; i < wc; i++) | |
182 | ((uint16 *)array)[i] = atoi(argv[arg_index+i]); | |
183 | break; | |
184 | case TIFF_SBYTE: | |
185 | for (i = 0; i < wc; i++) | |
186 | ((int8 *)array)[i] = atoi(argv[arg_index+i]); | |
187 | break; | |
188 | case TIFF_SSHORT: | |
189 | for (i = 0; i < wc; i++) | |
190 | ((int16 *)array)[i] = atoi(argv[arg_index+i]); | |
191 | break; | |
192 | case TIFF_LONG: | |
193 | for (i = 0; i < wc; i++) | |
194 | ((uint32 *)array)[i] = atol(argv[arg_index+i]); | |
195 | break; | |
196 | case TIFF_SLONG: | |
197 | case TIFF_IFD: | |
198 | for (i = 0; i < wc; i++) | |
199 | ((uint32 *)array)[i] = atol(argv[arg_index+i]); | |
200 | break; | |
201 | case TIFF_DOUBLE: | |
202 | for (i = 0; i < wc; i++) | |
203 | ((double *)array)[i] = atof(argv[arg_index+i]); | |
204 | break; | |
205 | case TIFF_RATIONAL: | |
206 | case TIFF_SRATIONAL: | |
207 | case TIFF_FLOAT: | |
208 | for (i = 0; i < wc; i++) | |
209 | ((float *)array)[i] = (float)atof(argv[arg_index+i]); | |
210 | break; | |
211 | default: | |
212 | break; | |
213 | } | |
214 | ||
215 | if (fip->field_passcount) { | |
216 | ret = TIFFSetField(tiff, fip->field_tag, | |
217 | wc, array); | |
218 | } else { | |
219 | ret = TIFFSetField(tiff, fip->field_tag, | |
220 | array); | |
221 | } | |
222 | ||
223 | _TIFFfree(array); | |
224 | } else { | |
225 | switch (fip->field_type) { | |
226 | case TIFF_BYTE: | |
227 | case TIFF_SHORT: | |
228 | case TIFF_SBYTE: | |
229 | case TIFF_SSHORT: | |
230 | ret = TIFFSetField(tiff, fip->field_tag, | |
231 | atoi(argv[arg_index++])); | |
232 | break; | |
233 | case TIFF_LONG: | |
234 | case TIFF_SLONG: | |
235 | case TIFF_IFD: | |
236 | ret = TIFFSetField(tiff, fip->field_tag, | |
237 | atol(argv[arg_index++])); | |
238 | break; | |
239 | case TIFF_DOUBLE: | |
240 | ret = TIFFSetField(tiff, fip->field_tag, | |
241 | atof(argv[arg_index++])); | |
242 | break; | |
243 | case TIFF_RATIONAL: | |
244 | case TIFF_SRATIONAL: | |
245 | case TIFF_FLOAT: | |
246 | ret = TIFFSetField(tiff, fip->field_tag, | |
247 | (float)atof(argv[arg_index++])); | |
248 | break; | |
249 | default: | |
250 | break; | |
251 | } | |
252 | } | |
253 | ||
254 | if (ret != 1) | |
255 | fprintf(stderr, "Failed to set %s\n", fip->field_name); | |
256 | arg_index += wc; | |
257 | } | |
258 | } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) { | |
259 | FILE *fp; | |
260 | const TIFFFieldInfo *fip; | |
261 | char *text; | |
262 | int len; | |
263 | ||
264 | arg_index++; | |
265 | fip = GetField(tiff, argv[arg_index]); | |
266 | ||
267 | if (!fip) | |
268 | return 3; | |
269 | ||
270 | if (fip->field_type != TIFF_ASCII) { | |
271 | fprintf( stderr, | |
272 | "Only ASCII tags can be set from file. " | |
273 | "%s is not ASCII tag.\n", fip->field_name ); | |
274 | return 5; | |
275 | } | |
276 | ||
277 | arg_index++; | |
278 | fp = fopen( argv[arg_index], "rt" ); | |
279 | if(fp == NULL) { | |
280 | perror( argv[arg_index] ); | |
281 | continue; | |
282 | } | |
283 | ||
284 | text = (char *) malloc(1000000); | |
285 | len = fread( text, 1, 999999, fp ); | |
286 | text[len] = '\0'; | |
287 | ||
288 | fclose( fp ); | |
289 | ||
290 | if(TIFFSetField( tiff, fip->field_tag, text ) != 1) { | |
291 | fprintf(stderr, "Failed to set %s from file %s\n", | |
292 | fip->field_name, argv[arg_index]); | |
293 | } | |
294 | ||
295 | _TIFFfree( text ); | |
296 | arg_index++; | |
297 | } else { | |
298 | fprintf(stderr, "Unrecognised option: %s\n", | |
299 | argv[arg_index]); | |
300 | usage(); | |
301 | } | |
302 | } | |
303 | ||
304 | TIFFRewriteDirectory(tiff); | |
305 | TIFFClose(tiff); | |
306 | return 0; | |
307 | } | |
308 | ||
309 | /* vim: set ts=8 sts=8 sw=8 noet: */ |