Blame tools/tiffset.c

Packit 994f1a
/******************************************************************************
Packit 994f1a
 * $Id: tiffset.c,v 1.12.2.1 2010-06-08 18:50:44 bfriesen Exp $
Packit 994f1a
 *
Packit 994f1a
 * Project:  libtiff tools
Packit 994f1a
 * Purpose:  Mainline for setting metadata in existing TIFF files.
Packit 994f1a
 * Author:   Frank Warmerdam, warmerdam@pobox.com
Packit 994f1a
 *
Packit 994f1a
 ******************************************************************************
Packit 994f1a
 * Copyright (c) 2000, Frank Warmerdam
Packit 994f1a
 *
Packit 994f1a
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 994f1a
 * its documentation for any purpose is hereby granted without fee, provided
Packit 994f1a
 * that (i) the above copyright notices and this permission notice appear in
Packit 994f1a
 * all copies of the software and related documentation, and (ii) the names of
Packit 994f1a
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 994f1a
 * publicity relating to the software without the specific, prior written
Packit 994f1a
 * permission of Sam Leffler and Silicon Graphics.
Packit 994f1a
 * 
Packit 994f1a
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 994f1a
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 994f1a
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 994f1a
 * 
Packit 994f1a
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 994f1a
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 994f1a
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 994f1a
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 994f1a
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 994f1a
 * OF THIS SOFTWARE.
Packit 994f1a
 ******************************************************************************
Packit 994f1a
 *
Packit 994f1a
 * $Log: tiffset.c,v $
Packit 994f1a
 * Revision 1.12.2.1  2010-06-08 18:50:44  bfriesen
Packit 994f1a
 * * Add an emacs formatting mode footer to all source files so that
Packit 994f1a
 * emacs can be effectively used.
Packit 994f1a
 *
Packit 994f1a
 * Revision 1.12  2007/02/24 17:14:14  dron
Packit 994f1a
 * Properly handle tags with TIFF_VARIABLE writecount. As per bug
Packit 994f1a
 * http://bugzilla.remotesensing.org/show_bug.cgi?id=1350
Packit 994f1a
 *
Packit 994f1a
 * Revision 1.11  2005/09/13 14:13:42  dron
Packit 994f1a
 * Avoid warnings.
Packit 994f1a
 *
Packit 994f1a
 * Revision 1.10  2005/02/24 14:47:11  fwarmerdam
Packit 994f1a
 * Updated header.
Packit 994f1a
 *
Packit 994f1a
 */
Packit 994f1a
Packit 994f1a
Packit 994f1a
#include <stdio.h>
Packit 994f1a
#include <string.h>
Packit 994f1a
#include <stdlib.h>
Packit 994f1a
Packit 994f1a
#include "tiffio.h"
Packit 994f1a
Packit 994f1a
static char* usageMsg[] = {
Packit 994f1a
"usage: tiffset [options] filename",
Packit 994f1a
"where options are:",
Packit 994f1a
" -s <tagname> [count] <value>...   set the tag value",
Packit 994f1a
" -sf <tagname> <filename>  read the tag value from file (for ASCII tags only)",
Packit 994f1a
NULL
Packit 994f1a
};
Packit 994f1a
Packit 994f1a
static void
Packit 994f1a
usage(void)
Packit 994f1a
{
Packit 994f1a
	int i;
Packit 994f1a
	for (i = 0; usageMsg[i]; i++)
Packit 994f1a
		fprintf(stderr, "%s\n", usageMsg[i]);
Packit 994f1a
	exit(-1);
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
static const TIFFFieldInfo *
Packit 994f1a
GetField(TIFF *tiff, const char *tagname)
Packit 994f1a
{
Packit 994f1a
    const TIFFFieldInfo *fip;
Packit 994f1a
Packit 994f1a
    if( atoi(tagname) > 0 )
Packit 994f1a
        fip = TIFFFieldWithTag(tiff, (ttag_t)atoi(tagname));
Packit 994f1a
    else
Packit 994f1a
        fip = TIFFFieldWithName(tiff, tagname);
Packit 994f1a
Packit 994f1a
    if (!fip) {
Packit 994f1a
        fprintf( stderr, "Field name %s not recognised.\n", tagname );
Packit 994f1a
        return (TIFFFieldInfo *)NULL;
Packit 994f1a
    }
Packit 994f1a
Packit 994f1a
    return fip;
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
int
Packit 994f1a
main(int argc, char* argv[])
Packit 994f1a
{
Packit 994f1a
    TIFF *tiff;
Packit 994f1a
    int  arg_index;
Packit 994f1a
Packit 994f1a
    if (argc < 2)
Packit 994f1a
        usage();
Packit 994f1a
Packit 994f1a
    tiff = TIFFOpen(argv[argc-1], "r+");
Packit 994f1a
    if (tiff == NULL)
Packit 994f1a
        return 2;
Packit 994f1a
Packit 994f1a
    for( arg_index = 1; arg_index < argc-1; arg_index++ ) {
Packit 994f1a
        if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) {
Packit 994f1a
            const TIFFFieldInfo *fip;
Packit 994f1a
            const char *tagname;
Packit 994f1a
Packit 994f1a
            arg_index++;
Packit 994f1a
            tagname = argv[arg_index];
Packit 994f1a
            fip = GetField(tiff, tagname);
Packit 994f1a
Packit 994f1a
            if (!fip)
Packit 994f1a
                return 3;
Packit 994f1a
Packit 994f1a
            arg_index++;
Packit 994f1a
            if (fip->field_type == TIFF_ASCII) {
Packit 994f1a
                if (TIFFSetField(tiff, fip->field_tag, argv[arg_index]) != 1)
Packit 994f1a
                    fprintf( stderr, "Failed to set %s=%s\n",
Packit 994f1a
                             fip->field_name, argv[arg_index] );
Packit 994f1a
            } else if (fip->field_writecount > 0
Packit 994f1a
		       || fip->field_writecount == TIFF_VARIABLE) {
Packit 994f1a
                int     ret = 1;
Packit 994f1a
                short   wc;
Packit 994f1a
Packit 994f1a
                if (fip->field_writecount == TIFF_VARIABLE)
Packit 994f1a
                        wc = atoi(argv[arg_index++]);
Packit 994f1a
                else
Packit 994f1a
                        wc = fip->field_writecount;
Packit 994f1a
Packit 994f1a
                if (argc - arg_index < wc) {
Packit 994f1a
                    fprintf( stderr,
Packit 994f1a
                             "Number of tag values is not enough. "
Packit 994f1a
                             "Expected %d values for %s tag, got %d\n",
Packit 994f1a
                             wc, fip->field_name, argc - arg_index);
Packit 994f1a
                    return 4;
Packit 994f1a
                }
Packit 994f1a
                    
Packit 994f1a
                if (wc > 1) {
Packit 994f1a
                        int     i, size;
Packit 994f1a
                        void    *array;
Packit 994f1a
Packit 994f1a
                        switch (fip->field_type) {
Packit 994f1a
                                /*
Packit 994f1a
                                 * XXX: We can't use TIFFDataWidth()
Packit 994f1a
                                 * to determine the space needed to store
Packit 994f1a
                                 * the value. For TIFF_RATIONAL values
Packit 994f1a
                                 * TIFFDataWidth() returns 8, but we use 4-byte
Packit 994f1a
                                 * float to represent rationals.
Packit 994f1a
                                 */
Packit 994f1a
                                case TIFF_BYTE:
Packit 994f1a
                                case TIFF_ASCII:
Packit 994f1a
                                case TIFF_SBYTE:
Packit 994f1a
                                case TIFF_UNDEFINED:
Packit 994f1a
				default:
Packit 994f1a
                                    size = 1;
Packit 994f1a
                                    break;
Packit 994f1a
Packit 994f1a
                                case TIFF_SHORT:
Packit 994f1a
                                case TIFF_SSHORT:
Packit 994f1a
                                    size = 2;
Packit 994f1a
                                    break;
Packit 994f1a
Packit 994f1a
                                case TIFF_LONG:
Packit 994f1a
                                case TIFF_SLONG:
Packit 994f1a
                                case TIFF_FLOAT:
Packit 994f1a
                                case TIFF_IFD:
Packit 994f1a
                                case TIFF_RATIONAL:
Packit 994f1a
                                case TIFF_SRATIONAL:
Packit 994f1a
                                    size = 4;
Packit 994f1a
                                    break;
Packit 994f1a
Packit 994f1a
                                case TIFF_DOUBLE:
Packit 994f1a
                                    size = 8;
Packit 994f1a
                                    break;
Packit 994f1a
                        }
Packit 994f1a
Packit 994f1a
                        array = _TIFFmalloc(wc * size);
Packit 994f1a
                        if (!array) {
Packit 994f1a
                                fprintf(stderr, "No space for %s tag\n",
Packit 994f1a
                                        tagname);
Packit 994f1a
                                return 4;
Packit 994f1a
                        }
Packit 994f1a
Packit 994f1a
                        switch (fip->field_type) {
Packit 994f1a
                            case TIFF_BYTE:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((uint8 *)array)[i] = atoi(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_SHORT:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((uint16 *)array)[i] = atoi(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_SBYTE:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((int8 *)array)[i] = atoi(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_SSHORT:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((int16 *)array)[i] = atoi(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_LONG:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_SLONG:
Packit 994f1a
                            case TIFF_IFD:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_DOUBLE:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((double *)array)[i] = atof(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_RATIONAL:
Packit 994f1a
                            case TIFF_SRATIONAL:
Packit 994f1a
                            case TIFF_FLOAT:
Packit 994f1a
                                for (i = 0; i < wc; i++)
Packit 994f1a
                                    ((float *)array)[i] = (float)atof(argv[arg_index+i]);
Packit 994f1a
                                break;
Packit 994f1a
                            default:
Packit 994f1a
                                break;
Packit 994f1a
                        }
Packit 994f1a
                
Packit 994f1a
                        if (fip->field_passcount) {
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   wc, array);
Packit 994f1a
                        } else {
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   array);
Packit 994f1a
                        }
Packit 994f1a
Packit 994f1a
                        _TIFFfree(array);
Packit 994f1a
                } else {
Packit 994f1a
                        switch (fip->field_type) {
Packit 994f1a
                            case TIFF_BYTE:
Packit 994f1a
                            case TIFF_SHORT:
Packit 994f1a
                            case TIFF_SBYTE:
Packit 994f1a
                            case TIFF_SSHORT:
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   atoi(argv[arg_index++]));
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_LONG:
Packit 994f1a
                            case TIFF_SLONG:
Packit 994f1a
                            case TIFF_IFD:
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   atol(argv[arg_index++]));
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_DOUBLE:
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   atof(argv[arg_index++]));
Packit 994f1a
                                break;
Packit 994f1a
                            case TIFF_RATIONAL:
Packit 994f1a
                            case TIFF_SRATIONAL:
Packit 994f1a
                            case TIFF_FLOAT:
Packit 994f1a
                                ret = TIFFSetField(tiff, fip->field_tag,
Packit 994f1a
                                                   (float)atof(argv[arg_index++]));
Packit 994f1a
                                break;
Packit 994f1a
                            default:
Packit 994f1a
                                break;
Packit 994f1a
                        }
Packit 994f1a
                }
Packit 994f1a
Packit 994f1a
                if (ret != 1)
Packit 994f1a
                    fprintf(stderr, "Failed to set %s\n", fip->field_name);
Packit 994f1a
                arg_index += wc;
Packit 994f1a
            }
Packit 994f1a
        } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) {
Packit 994f1a
            FILE    *fp;
Packit 994f1a
            const TIFFFieldInfo *fip;
Packit 994f1a
            char    *text;
Packit 994f1a
            int     len;
Packit 994f1a
Packit 994f1a
            arg_index++;
Packit 994f1a
            fip = GetField(tiff, argv[arg_index]);
Packit 994f1a
Packit 994f1a
            if (!fip)
Packit 994f1a
                return 3;
Packit 994f1a
Packit 994f1a
            if (fip->field_type != TIFF_ASCII) {
Packit 994f1a
                fprintf( stderr,
Packit 994f1a
                         "Only ASCII tags can be set from file. "
Packit 994f1a
                         "%s is not ASCII tag.\n", fip->field_name );
Packit 994f1a
                return 5;
Packit 994f1a
            }
Packit 994f1a
Packit 994f1a
            arg_index++;
Packit 994f1a
            fp = fopen( argv[arg_index], "rt" );
Packit 994f1a
            if(fp == NULL) {
Packit 994f1a
                perror( argv[arg_index] );
Packit 994f1a
                continue;
Packit 994f1a
            }
Packit 994f1a
Packit 994f1a
            text = (char *) malloc(1000000);
Packit 994f1a
            len = fread( text, 1, 999999, fp );
Packit 994f1a
            text[len] = '\0';
Packit 994f1a
Packit 994f1a
            fclose( fp );
Packit 994f1a
Packit 994f1a
            if(TIFFSetField( tiff, fip->field_tag, text ) != 1) {
Packit 994f1a
                fprintf(stderr, "Failed to set %s from file %s\n", 
Packit 994f1a
                        fip->field_name, argv[arg_index]);
Packit 994f1a
            }
Packit 994f1a
Packit 994f1a
            _TIFFfree( text );
Packit 994f1a
            arg_index++;
Packit 994f1a
        } else {
Packit 994f1a
            fprintf(stderr, "Unrecognised option: %s\n",
Packit 994f1a
                    argv[arg_index]);
Packit 994f1a
            usage();
Packit 994f1a
        }
Packit 994f1a
    }
Packit 994f1a
Packit 994f1a
    TIFFRewriteDirectory(tiff);
Packit 994f1a
    TIFFClose(tiff);
Packit 994f1a
    return 0;
Packit 994f1a
}
Packit 994f1a
Packit 994f1a
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 994f1a
/*
Packit 994f1a
 * Local Variables:
Packit 994f1a
 * mode: c
Packit 994f1a
 * c-basic-offset: 8
Packit 994f1a
 * fill-column: 78
Packit 994f1a
 * End:
Packit 994f1a
 */