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