2010.03.22 01:34 "[Tiff] Problems with Modified tiffset", by Kevin Myers

2010.03.22 02:56 "Re: [Tiff] Problems with Modified tiffset", by Kevin Myers

Oops, never mind, finally found the problem myself. Had inappropriate value for field_passcount member of TIFFFieldInfo structure to use with ASCII tag content. After changing value for field_passcount from TRUE to FALSE, all works as it should. Sorry for the false alarm. Hope nobody out there wasted any time trying to track this down...

My corrected code is attached, in case anyone is interested.

s/KAM

----- Original Message -----
From: Kevin Myers
To: tiff@lists.maptools.org
Sent: Sunday, March 21, 2010 20:34
Subject: Problems with Modified tiffset

I've already sent this to a couple of my acquaintances on this list, but thought I might as well run it past everyone in case someone else can spot the problem right away...

I have attempted to modify the tiffset program to allow it to set the value of user defined (custom) tags. I could have sworn that I had this working some time ago, but now it definitely isn't working, and I'm not sure if it is due to a bug in libtiff, or (more likely) some kind of problem in my own code. The modifications that I made are relatively simple, and make use of the so-called "tag extender" feature of libtiff, which is documented under the "Defining Application Tags" section on this web page:

http://www.remotesensing.org/libtiff/addingtags.html

I have attached my modified version of tiffset.c for tiff 3.9.2. Since I'm sure that many of you are much stronger C programmers than I am, I doubt that you will have any problems compiling this. My own approach was to temporarily replace the standard version of tiffset.c in the tools directory, delete or rename any previously generated tiffset.exe in the tools output folder if you have one, and go from there. From the tools folder, I simply used nmake /f makefile.vc under Windows XP using VC from Visual Studio 2008 Express.

After successfully compiling the program, here is what happens:

If I use my modified tiffset to set the value of a standard tiff tag, say ImageDescription (tag number 270, ASCII text), everything works fine. Here is how I would do that (assume test.tif is an existing tiff file):

tiffset -s 270 MyValue test.tif
or
tiffset -s ImageDescription NewValue test.tif

You can use tiffinfo to verify that the ImageDescription tag value is set correctly.

On the other hand, when I use the following command:

tiffset -s 65000 MyValue test.tif

Everything *appears* to proceed normally. But when I run tiffinfo, I find that tag 65000 did get set to *something*, but not what it was supposed to be. It seems to be getting set to some bytes from elsewhere in memory. Looks like some kind of pointer related problem...

Internally, tiffset is using the TIFFSetField function from libtiff to set the tag value. My modified tiffset currently includes a printf statement to print the values of the arguments to TIFFSetField immediately prior to the call, and everything *seems* to be ok at that point. The correct, anticipated values are printed at this point for both standard and user-defined tag cases. But somewhere within the execution of TIFFSetField, things are getting screwed up for the user-defined tag case, and I can't figure out why/where. The code used in TIFFSetField is somewhat beyond my level of C expertise, and it would take me forever to track down where the correct value is getting lost. Hopefully someone else out there may be able to track down this problem a lot more quickly. Any takers?

I'm trying to finish up a critical project with immediately pending deadlines. A small but critical portion of that project requires programmatically adding metadata to tiff images via custom tag values, and this problem currently has my progress ground to a complete standstill.

Thanks,
Kevin M.

/******************************************************************************
 * $Id: tiffset.c,v 1.13 2009/03/21 21:52:00 kam1 Exp $
 *
 * Project:  libtiff tools
 * Purpose:  Mainline for setting metadata in existing TIFF files.
 * Author:   Frank Warmerdam, warmerdam@pobox.com
 *
 ******************************************************************************
 * Copyright (c) 2000, Frank Warmerdam
 *
 * Permission to use, copy, modify, distribute, and sell this software and 
 * its documentation for any purpose is hereby granted without fee, provided
 * that (i) the above copyright notices and this permission notice appear in
 * all copies of the software and related documentation, and (ii) the names of
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 * publicity relating to the software without the specific, prior written
 * permission of Sam Leffler and Silicon Graphics.
 * 
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 * 
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 * OF THIS SOFTWARE.
 ******************************************************************************
 *
 * $Log: tiffset.c,v $
 * Revision 1.13  2009/03/21 21:52:00  kam1
 * Add support for setting undocumented ASCII tag values.
 *
 * Revision 1.12  2007/02/24 17:14:14  dron
 * Properly handle tags with TIFF_VARIABLE writecount. As per bug
 * http://bugzilla.remotesensing.org/show_bug.cgi?id=1350
 *
 * Revision 1.11  2005/09/13 14:13:42  dron
 * Avoid warnings.
 *
 * Revision 1.10  2005/02/24 14:47:11  fwarmerdam
 * Updated header.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "tiffio.h"

#define TRUE 1
#define FALSE 0

#define TIFFTAG_CUSTOM 65535

static char* usageMsg[] = {
"usage: tiffset [options] tiff-filename",
"where options are:",
" -s <tagname> [count] <value>... set the tag value",
" -sf <tagname> <tag data filename> set the tag value from file (ASCII tags only)",
NULL
};

static TIFFDataType     user_field_type = 0;            /* user specified TIFF tag data type */

static ttag_t           user_tag = 0;                   /* user specified TIFF tag Id */

static TIFFExtendProc   _ParentExtender = NULL;         /* parent tag extender proc */

static TIFFFieldInfo    xtiffFieldInfo[] = {

    { TIFFTAG_CUSTOM,   TIFF_VARIABLE,  TIFF_VARIABLE,  TIFF_ASCII,     FIELD_CUSTOM,   TRUE,   FALSE,  "Tag 65535" }

};

static void
usage(void)
{
        int i;
        for (i = 0; usageMsg[i]; i++)
                fprintf(stderr, "%s\n", usageMsg[i]);
        exit(-1);
}

/* KAM - tag type extender callback */
static void
_XTIFFDefaultDirectory(TIFF *tif)
{
        /* update our extended tag field info */
        xtiffFieldInfo[0].field_tag = user_tag;
// xtiffFieldInfo[0].field_type = user_field_type;
        sprintf(xtiffFieldInfo[0].field_name, "Tag %d", (int) user_tag);

/* Install the extended Tag field info */
TIFFMergeFieldInfo(tif, xtiffFieldInfo, 1);

        /* Since an XTIFF client module may have overridden
         * the default directory method, we call it now to
         * allow it to set up the rest of its own methods.
         */

    if (_ParentExtender) (*_ParentExtender)(tif);
}

/* KAM - initialize tag type extender */
static
void _XTIFFInitialize(void)
{
        static int first_time=1;

if (! first_time) return; /* Been there. Done that. */
first_time = 0;

        /* Grab the inherited method and install */
        _ParentExtender = TIFFSetTagExtender(_XTIFFDefaultDirectory);
}

static const TIFFFieldInfo *
GetField(TIFF *tiff, cons