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