2007.07.02 18:33 "[Tiff] Tag Extensions Refuse to Work", by Kevin Myers

Hi folks,

I've been trying for about 24 hours straight to get the dynamic tiff tag extension mechanism to work properly, and it is driving me nuts. I hope that maybe some of you who are more proficient C programmers than myself can take a quick look at my code and jump straight to the solution. Here is the basic situation:

I'm working with tiffset.c from the tools directory in libtiff as a starting point.

I am attempting to extend tiffset so that it can store new tags specified by the user on the command line.

To accomplish this, I studied Defining Application Tags in addingtags.html, and followed that documentation very closely. I added the extended tag initialization and callback methods to tiffset, and after a little bit of experimentation that part mostly seems to work ok, I added some printf statements to the code so that I could see when these methods were being called, and they seem to be called at appropriate times and with appropriate values for both calling and return parameters. The required additions and modifications to tiffset.c for this purpose really weren't very extensive.

But what is now happening is this: If I try to set the value of built-in tags, everything works as expected. But if I try to set the value of an extended tag, the TiffSetField method appears to execute ok. But when you look at the resulting file, the new tag has been added to the file, but the data contained within the tag is garbage. It looks like a pointer somewhere is getting screwed up, but I am not a very experienced C programmer, and I have limited tools at my disposal. It is taking me forever to track down this problem.

I have attached my modified tiffset.c source code, along with the console output from some tests that I ran. If somebody can help me figure out what is going wrong, I would sure appreciate it. BTW, I am working with libtiff v3.8.2 under Windows XP, in case it matters.

One last thing: For my purposes, it is not acceptable to add new built-in tags. I really need to get the dynamic tag support working.

Thanks,

Kevin M.

Microsoft (R) Program Maintenance Utility Version 8.00.50727.762

Copyright (C) Microsoft Corporation. All rights reserved.

        cl /nologo /Ox /MD /EHsc /W3 -I..\libtiff -DAVOID_WIN32_FILEIO -DCHECK_JPEG_YCBCR_SUBSAMPLING -DDEFAULT_EXTRASAMPLE_AS_ALPHA -DSTRIPCHOP_DEFAULT=TIFF_STRIPCHOP -DSTRIP_SIZE_DEFAULT=8192 -DPIXARLOG_SUPPORT -DZIP_SUPPORT -DJPEG_SUPPORT -DLOGLUV_SUPPORT -DNEXT_SUPPORT -DTHUNDER_SUPPORT -DLZW_SUPPORT -DPACKBITS_SUPPORT -DCCITT_SUPPORT -DTIF_PLATFORM_CONSOLE -DFILLODER_LSB2MSB  tiffset.c   C:\GnuWin32\lib/jpeg.lib C:\GnuWin32\lib/zlib.lib ..\port\libport.lib ..\libtiff\libtiff.lib

tiffset.c

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>del out.txt

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools\out.txt

The process cannot access the file because it is being used by another process.

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>C:

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>cd \GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>rem c:\autoexec.bat

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>rem nmake /f Makefile.vc tiffset.exe

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>rem Should produce "one" in tag 305, and does - BACKWARDS (is this normal?)

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>copy test0.tif test.tif

        1 file(s) copied.

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>tiffdump test.tif

test.tif:
Magic: 0x4d4d <big-endian> Version: 0x2a
Directory 0: offset 8 (0x8) next 0 (0)
ImageWidth (256) LONG (4) 1<1888>
ImageLength (257) LONG (4) 1<73125>
BitsPerSample (258) SHORT (3) 1<1>
Compression (259) SHORT (3) 1<4>
Photometric (262) SHORT (3) 1<0>
FillOrder (266) SHORT (3) 1<1>
Make (271) ASCII (2) 9<XEROX \0>
Model (272) ASCII (2) 17<7356 \0>
StripOffsets (273) LONG (4) 1<316>
SamplesPerPixel (277) SHORT (3) 1<1>
RowsPerStrip (278) LONG (4) 1<73125>
StripByteCounts (279) LONG (4) 1<1819148>
XResolution (282) RATIONAL (5) 1<200>
YResolution (283) RATIONAL (5) 1<200>
ResolutionUnit (296) SHORT (3) 1<2>

Software (305) ASCII (2) 36<AccXES Version 6.1.00C ...>
DateTime (306) ASCII (2) 20<1999:12:07 19:32:49\0>

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>tiffset -s 305 one test.tif

_XTIFFInitialize
tifffile=test.tif
Before Text SetField
fip->field_tag:305
fip->field_readcount:-1
fip->field_writecount:-1
fip->field_type:2
fip->field_bit:65
fip->field_oktochange:1
fip->field_passcount:0
fip->field_name:Software
tag_value=one
After Text SetField
fip->field_tag:305
fip->field_readcount:-1
fip->field_writecount:-1
fip->field_type:2
fip->field_bit:65
fip->field_oktochange:1
fip->field_passcount:0
fip->field_name:Software
tag_value=one

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>tiffdump test.tif

test.tif:
Magic: 0x4d4d <big-endian> Version: 0x2a
Directory 0: offset 1819464 (0x1bc348) next 0 (0)
ImageWidth (256) SHORT (3) 1<1888>
ImageLength (257) LONG (4) 1<73125>
BitsPerSample (258) SHORT (3) 1<1>
Compression (259) SHORT (3) 1<4>
Photometric (262) SHORT (3) 1<0>
FillOrder (266) SHORT (3) 1<1>
Make (271) ASCII (2) 9<XEROX \0>
Model (272) ASCII (2) 17<7356 \0>
StripOffsets (273) LONG (4) 1<316>
SamplesPerPixel (277) SHORT (3) 1<1>
RowsPerStrip (278) LONG (4) 1<73125>
StripByteCounts (279) LONG (4) 1<1819148>
XResolution (282) RATIONAL (5) 1<200>
YResolution (283) RATIONAL (5) 1<200>
PlanarConfig (284) SHORT (3) 1<1>
ResolutionUnit (296) SHORT (3) 1<2>
Software (305) ASCII (2) 4<\0eno>
DateTime (306) ASCII (2) 20<1999:12:07 19:32:49\0>

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>rem Should produce "two" in tag 65000, and does NOT (tag created with garbage).

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>copy test0.tif test.tif

        1 file(s) copied.

C:\GnuWin32\src\tiff\3.8.2\tiff-3.8.2-src\tools>tiffdump test.tif

test.tif:
Magic: 0x4d4d <big-endian> Version: 0x2a
Directory 0: offset 8 (0x8) next 0 (0)
ImageWidth (256) LONG (4) 1<1888>
ImageLength (257) LONG (4) 1<73125>
BitsPerSample (258) SHORT (3) 1<1>
Compression (259) SHORT (3) 1<4>
Photometric (262) SHORT (3) 1<0>
FillOrder (266) SHORT (3) 1<1>
Make (271) ASCII (2) 9<XEROX \0>
Model (272) ASCII (2) 17<7356 \0>
StripOffsets (273) LONG (4) 1<316>
SamplesPerPixel (277) SHORT (3) 1<1>
RowsPerStrip (278) LONG (4) 1<73125>
StripByteCounts (279) LONG (4) 1<1819148>
XResolution (282) RATIONAL (5) 1<200>
YResolution (283) RATIONAL (5) 1<200>
ResolutionUnit (296) SHORT (3) 1<2>

Software (305) ASCII (2) 36<AccXES Version 6.1.00C   ...>
DateTime (306) ASCII (2) 20<1999:1G
/******************************************************************************
 * $Id: tiffset.c,v 1.11 2005/09/13 14:13:42 dron 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.11  2005/09/13 14:13:42  dron
 * Avoid warnings.
 *
 * Revision 1.10  2005/02/24 14:47:11  fwarmerdam
 * Updated header.
 *
 */

#include "tif_config.h"

#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> read the tag value from file (for ASCII tags only)",
NULL
};

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

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,   TRUE,   "Custom 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 */
        /* Normally xtiffFieldInfo is a list of TIFFFieldInfo structures */
        /* but since we only have one, the memory location is identical  */

    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 _X e