Blame tools/tiffset.c

Packit 7838c8
/******************************************************************************
Packit 7838c8
 * $Id: tiffset.c,v 1.19 2017-10-01 17:38:12 erouault Exp $
Packit 7838c8
 *
Packit 7838c8
 * Project:  libtiff tools
Packit 7838c8
 * Purpose:  Mainline for setting metadata in existing TIFF files.
Packit 7838c8
 * Author:   Frank Warmerdam, warmerdam@pobox.com
Packit 7838c8
 *
Packit 7838c8
 ******************************************************************************
Packit 7838c8
 * Copyright (c) 2000, Frank Warmerdam
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 7838c8
 * its documentation for any purpose is hereby granted without fee, provided
Packit 7838c8
 * that (i) the above copyright notices and this permission notice appear in
Packit 7838c8
 * all copies of the software and related documentation, and (ii) the names of
Packit 7838c8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 7838c8
 * publicity relating to the software without the specific, prior written
Packit 7838c8
 * permission of Sam Leffler and Silicon Graphics.
Packit 7838c8
 * 
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 7838c8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 7838c8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 7838c8
 * 
Packit 7838c8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 7838c8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 7838c8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 7838c8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 7838c8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 7838c8
 * OF THIS SOFTWARE.
Packit 7838c8
 ******************************************************************************
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
Packit 7838c8
#include <stdio.h>
Packit 7838c8
#include <string.h>
Packit 7838c8
#include <stdlib.h>
Packit 7838c8
Packit 7838c8
#include "tiffio.h"
Packit 7838c8
Packit 7838c8
static char* usageMsg[] = {
Packit 7838c8
"usage: tiffset [options] filename",
Packit 7838c8
"where options are:",
Packit 7838c8
" -s <tagname> [count] <value>...   set the tag value",
Packit 7838c8
" -u <tagname> to unset the tag",
Packit 7838c8
" -d <dirno> set the directory",
Packit 7838c8
" -sd <diroff> set the subdirectory",
Packit 7838c8
" -sf <tagname> <filename>  read the tag value from file (for ASCII tags only)",
Packit 7838c8
NULL
Packit 7838c8
};
Packit 7838c8
Packit 7838c8
static void
Packit 7838c8
usage(void)
Packit 7838c8
{
Packit 7838c8
	int i;
Packit 7838c8
	for (i = 0; usageMsg[i]; i++)
Packit 7838c8
		fprintf(stderr, "%s\n", usageMsg[i]);
Packit 7838c8
	exit(-1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
static const TIFFField *
Packit 7838c8
GetField(TIFF *tiff, const char *tagname)
Packit 7838c8
{
Packit 7838c8
    const TIFFField *fip;
Packit 7838c8
Packit 7838c8
    if( atoi(tagname) > 0 )
Packit 7838c8
        fip = TIFFFieldWithTag(tiff, (ttag_t)atoi(tagname));
Packit 7838c8
    else
Packit 7838c8
        fip = TIFFFieldWithName(tiff, tagname);
Packit 7838c8
Packit 7838c8
    if (!fip) {
Packit 7838c8
        fprintf( stderr, "Field name \"%s\" is not recognised.\n", tagname );
Packit 7838c8
        return (TIFFField *)NULL;
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    return fip;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
main(int argc, char* argv[])
Packit 7838c8
{
Packit 7838c8
    TIFF *tiff;
Packit 7838c8
    int  arg_index;
Packit 7838c8
Packit 7838c8
    if (argc < 2)
Packit 7838c8
        usage();
Packit 7838c8
Packit 7838c8
    tiff = TIFFOpen(argv[argc-1], "r+");
Packit 7838c8
    if (tiff == NULL)
Packit 7838c8
        return 2;
Packit 7838c8
Packit 7838c8
    for( arg_index = 1; arg_index < argc-1; arg_index++ ) {
Packit 7838c8
	if (strcmp(argv[arg_index],"-d") == 0 && arg_index < argc-2) {
Packit 7838c8
	    arg_index++;
Packit 7838c8
	    if( TIFFSetDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
Packit 7838c8
            {
Packit 7838c8
               fprintf( stderr, "Failed to set directory=%s\n", argv[arg_index] );
Packit 7838c8
               return 6;
Packit 7838c8
            }
Packit 7838c8
	    arg_index++;
Packit 7838c8
	}
Packit 7838c8
	if (strcmp(argv[arg_index],"-sd") == 0 && arg_index < argc-2) {
Packit 7838c8
	    arg_index++;
Packit 7838c8
	    if( TIFFSetSubDirectory(tiff, atoi(argv[arg_index]) ) != 1 )
Packit 7838c8
            {
Packit 7838c8
               fprintf( stderr, "Failed to set sub directory=%s\n", argv[arg_index] );
Packit 7838c8
               return 7;
Packit 7838c8
            }
Packit 7838c8
	    arg_index++;
Packit 7838c8
	}
Packit 7838c8
    /* Add unset option to tiffset -- Zach Baker (niquil@niquil.net) 11/14/2012 */ 
Packit 7838c8
    if (strcmp(argv[arg_index],"-u") == 0 && arg_index < argc-2) {
Packit 7838c8
            const TIFFField *fip;
Packit 7838c8
            const char *tagname;
Packit 7838c8
            arg_index++;
Packit 7838c8
            tagname = argv[arg_index];
Packit 7838c8
            fip = GetField(tiff, tagname);
Packit 7838c8
            if (!fip)
Packit 7838c8
                return 3;
Packit 7838c8
Packit 7838c8
            if (TIFFUnsetField(tiff, TIFFFieldTag(fip)) != 1)
Packit 7838c8
            {
Packit 7838c8
                    fprintf(stderr, "Failed to unset %s\n", TIFFFieldName(fip));
Packit 7838c8
            }
Packit 7838c8
            arg_index++;
Packit 7838c8
    } else if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) {
Packit 7838c8
            const TIFFField *fip;
Packit 7838c8
            const char *tagname;
Packit 7838c8
Packit 7838c8
            arg_index++;
Packit 7838c8
            tagname = argv[arg_index];
Packit 7838c8
            fip = GetField(tiff, tagname);
Packit 7838c8
Packit 7838c8
            if (!fip)
Packit 7838c8
                return 3;
Packit 7838c8
Packit 7838c8
            arg_index++;
Packit 7838c8
            if (TIFFFieldDataType(fip) == TIFF_ASCII) {
Packit 7838c8
                if (TIFFSetField(tiff, TIFFFieldTag(fip), argv[arg_index]) != 1)
Packit 7838c8
                    fprintf( stderr, "Failed to set %s=%s\n",
Packit 7838c8
                             TIFFFieldName(fip), argv[arg_index] );
Packit 7838c8
            } else if (TIFFFieldWriteCount(fip) > 0
Packit 7838c8
		       || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) {
Packit 7838c8
                int     ret = 1;
Packit 7838c8
                short   wc;
Packit 7838c8
Packit 7838c8
                if (TIFFFieldWriteCount(fip) == TIFF_VARIABLE)
Packit 7838c8
                        wc = atoi(argv[arg_index++]);
Packit 7838c8
                else
Packit 7838c8
                        wc = TIFFFieldWriteCount(fip);
Packit 7838c8
Packit 7838c8
                if (argc - arg_index < wc) {
Packit 7838c8
                    fprintf( stderr,
Packit 7838c8
                             "Number of tag values is not enough. "
Packit 7838c8
                             "Expected %d values for %s tag, got %d\n",
Packit 7838c8
                             wc, TIFFFieldName(fip), argc - arg_index);
Packit 7838c8
                    return 4;
Packit 7838c8
                }
Packit 7838c8
                    
Packit 7838c8
                if (wc > 1 || TIFFFieldWriteCount(fip) == TIFF_VARIABLE) {
Packit 7838c8
                        int     i, size;
Packit 7838c8
                        void    *array;
Packit 7838c8
Packit 7838c8
                        switch (TIFFFieldDataType(fip)) {
Packit 7838c8
                                /*
Packit 7838c8
                                 * XXX: We can't use TIFFDataWidth()
Packit 7838c8
                                 * to determine the space needed to store
Packit 7838c8
                                 * the value. For TIFF_RATIONAL values
Packit 7838c8
                                 * TIFFDataWidth() returns 8, but we use 4-byte
Packit 7838c8
                                 * float to represent rationals.
Packit 7838c8
                                 */
Packit 7838c8
                                case TIFF_BYTE:
Packit 7838c8
                                case TIFF_ASCII:
Packit 7838c8
                                case TIFF_SBYTE:
Packit 7838c8
                                case TIFF_UNDEFINED:
Packit 7838c8
				default:
Packit 7838c8
                                    size = 1;
Packit 7838c8
                                    break;
Packit 7838c8
Packit 7838c8
                                case TIFF_SHORT:
Packit 7838c8
                                case TIFF_SSHORT:
Packit 7838c8
                                    size = 2;
Packit 7838c8
                                    break;
Packit 7838c8
Packit 7838c8
                                case TIFF_LONG:
Packit 7838c8
                                case TIFF_SLONG:
Packit 7838c8
                                case TIFF_FLOAT:
Packit 7838c8
                                case TIFF_IFD:
Packit 7838c8
                                case TIFF_RATIONAL:
Packit 7838c8
                                case TIFF_SRATIONAL:
Packit 7838c8
                                    size = 4;
Packit 7838c8
                                    break;
Packit 7838c8
Packit 7838c8
                                case TIFF_DOUBLE:
Packit 7838c8
                                    size = 8;
Packit 7838c8
                                    break;
Packit 7838c8
                        }
Packit 7838c8
Packit 7838c8
                        array = _TIFFmalloc(wc * size);
Packit 7838c8
                        if (!array) {
Packit 7838c8
                                fprintf(stderr, "No space for %s tag\n",
Packit 7838c8
                                        tagname);
Packit 7838c8
                                return 4;
Packit 7838c8
                        }
Packit 7838c8
Packit 7838c8
                        switch (TIFFFieldDataType(fip)) {
Packit 7838c8
                            case TIFF_BYTE:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((uint8 *)array)[i] = atoi(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_SHORT:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((uint16 *)array)[i] = atoi(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_SBYTE:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((int8 *)array)[i] = atoi(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_SSHORT:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((int16 *)array)[i] = atoi(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_LONG:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_SLONG:
Packit 7838c8
                            case TIFF_IFD:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_DOUBLE:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((double *)array)[i] = atof(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_RATIONAL:
Packit 7838c8
                            case TIFF_SRATIONAL:
Packit 7838c8
                            case TIFF_FLOAT:
Packit 7838c8
                                for (i = 0; i < wc; i++)
Packit 7838c8
                                    ((float *)array)[i] = (float)atof(argv[arg_index+i]);
Packit 7838c8
                                break;
Packit 7838c8
                            default:
Packit 7838c8
                                break;
Packit 7838c8
                        }
Packit 7838c8
                
Packit 7838c8
                        if (TIFFFieldPassCount(fip)) {
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   wc, array);
Packit 7838c8
                        } else if (TIFFFieldTag(fip) == TIFFTAG_PAGENUMBER
Packit 7838c8
				   || TIFFFieldTag(fip) == TIFFTAG_HALFTONEHINTS
Packit 7838c8
				   || TIFFFieldTag(fip) == TIFFTAG_YCBCRSUBSAMPLING
Packit 7838c8
				   || TIFFFieldTag(fip) == TIFFTAG_DOTRANGE) {
Packit 7838c8
       				if (TIFFFieldDataType(fip) == TIFF_BYTE) {
Packit 7838c8
					ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
						((uint8 *)array)[0], ((uint8 *)array)[1]);
Packit 7838c8
				} else if (TIFFFieldDataType(fip) == TIFF_SHORT) {
Packit 7838c8
					ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
						((uint16 *)array)[0], ((uint16 *)array)[1]);
Packit 7838c8
				}
Packit 7838c8
			} else {
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   array);
Packit 7838c8
                        }
Packit 7838c8
Packit 7838c8
                        _TIFFfree(array);
Packit 7838c8
                } else {
Packit 7838c8
                        switch (TIFFFieldDataType(fip)) {
Packit 7838c8
                            case TIFF_BYTE:
Packit 7838c8
                            case TIFF_SHORT:
Packit 7838c8
                            case TIFF_SBYTE:
Packit 7838c8
                            case TIFF_SSHORT:
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   atoi(argv[arg_index++]));
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_LONG:
Packit 7838c8
                            case TIFF_SLONG:
Packit 7838c8
                            case TIFF_IFD:
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   atol(argv[arg_index++]));
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_DOUBLE:
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   atof(argv[arg_index++]));
Packit 7838c8
                                break;
Packit 7838c8
                            case TIFF_RATIONAL:
Packit 7838c8
                            case TIFF_SRATIONAL:
Packit 7838c8
                            case TIFF_FLOAT:
Packit 7838c8
                                ret = TIFFSetField(tiff, TIFFFieldTag(fip),
Packit 7838c8
                                                   (float)atof(argv[arg_index++]));
Packit 7838c8
                                break;
Packit 7838c8
                            default:
Packit 7838c8
                                break;
Packit 7838c8
                        }
Packit 7838c8
                }
Packit 7838c8
Packit 7838c8
                if (ret != 1)
Packit 7838c8
                    fprintf(stderr, "Failed to set %s\n", TIFFFieldName(fip));
Packit 7838c8
                arg_index += wc;
Packit 7838c8
            }
Packit 7838c8
        } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) {
Packit 7838c8
            FILE    *fp;
Packit 7838c8
            const TIFFField *fip;
Packit 7838c8
            char    *text;
Packit 7838c8
            size_t  len;
Packit 7838c8
Packit 7838c8
            arg_index++;
Packit 7838c8
            fip = GetField(tiff, argv[arg_index]);
Packit 7838c8
Packit 7838c8
            if (!fip)
Packit 7838c8
                return 3;
Packit 7838c8
Packit 7838c8
            if (TIFFFieldDataType(fip) != TIFF_ASCII) {
Packit 7838c8
                fprintf( stderr,
Packit 7838c8
                         "Only ASCII tags can be set from file. "
Packit 7838c8
                         "%s is not ASCII tag.\n", TIFFFieldName(fip) );
Packit 7838c8
                return 5;
Packit 7838c8
            }
Packit 7838c8
Packit 7838c8
            arg_index++;
Packit 7838c8
            fp = fopen( argv[arg_index], "rt" );
Packit 7838c8
            if(fp == NULL) {
Packit 7838c8
                perror( argv[arg_index] );
Packit 7838c8
                continue;
Packit 7838c8
            }
Packit 7838c8
Packit 7838c8
            text = (char *) malloc(1000000);
Packit 7838c8
            len = fread( text, 1, 999999, fp );
Packit 7838c8
            text[len] = '\0';
Packit 7838c8
Packit 7838c8
            fclose( fp );
Packit 7838c8
Packit 7838c8
            if(TIFFSetField( tiff, TIFFFieldTag(fip), text ) != 1) {
Packit 7838c8
                fprintf(stderr, "Failed to set %s from file %s\n", 
Packit 7838c8
                        TIFFFieldName(fip), argv[arg_index]);
Packit 7838c8
            }
Packit 7838c8
Packit 7838c8
            _TIFFfree( text );
Packit 7838c8
            arg_index++;
Packit 7838c8
        } else {
Packit 7838c8
            fprintf(stderr, "Unrecognised option: %s\n",
Packit 7838c8
                    argv[arg_index]);
Packit 7838c8
            usage();
Packit 7838c8
        }
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    TIFFRewriteDirectory(tiff);
Packit 7838c8
    TIFFClose(tiff);
Packit 7838c8
    return 0;
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/* vim: set ts=8 sts=8 sw=8 noet: */
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */