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