From: dron@ak4719.spb.edu (Andrey Kiselev)
Date: Mon, 15 Sep 2003 11:45:36 +0400
Subject: [Tiff] writing out custom tags
In-Reply-To: <782C91C1988A404980FDAEA2E0C65CC0038CA87D@comail.digitalglobe.com>
References: <782C91C1988A404980FDAEA2E0C65CC0038CA87D@comail.digitalglobe.com>
Message-ID: <20030915074536.GA17825@ak4719.spb.edu>
Content-Type: multipart/mixed;
     boundary="wRRV7LY7NUeQGEoC"

--wRRV7LY7NUeQGEoC
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Fri, Sep 12, 2003 at 10:04:29AM -0600, Chris Padwick wrote:
> I'm trying to copy a custom tag from an input file to an output file.
> I'm using version 3.6.0 of the tiff library, grabbed from cvs last
> night. First, tiffcp doesn't copy the tag I'm interested in.  The
> input file is tiled and has 5 directories and each directory has a
> private tag.  Here is a tiffdump of the first directory:
>  
> Tiffdump: Magic: 0x4d4d <big-endian> Version: 0x2a Directory 0: offset
> 881328152 (0x34880018) next 881437232 (0x3489aa30) ImageWidth (256)
> SHORT (3) 1<6290> ImageLength (257) SHORT (3) 1<6780> <snip> . . .
> 34595 (0x8723) LONG (4) 137<1769472 262144 65536 65537 262144 65536
> 6619141 589824 406664 222298118 65536 5256328 223870986 131072 341128
> 229113867 131072 341128 229507084 65536 7353480 229900301 65536
> 3683464 ... <snip>
>  
> The tag I'm interested in is 34595.  I can read this tag no problem,
> but when I go to write it out I get a segfault.  Here is the code I'm
> using:

Chris,

You have made a few mistakes in your code:
 1. You forgot to set image parameters for the output file
 2. You shouldn't explicitly call TagExtender() function, it will be
 used in the libtiff internals when needed.
 3. You should provide total tag count to the TIFFSetField() function:

 	TIFFSetField(outtif, TIFFTAG_PRIVATE, iCount, lng);

I have attached corrected code (with C++-zation removed). That code
works for me:

$ tiffinfo inputfile.tif 
TIFF Directory at offset 0x30008
  Subfile Type: (0 = 0x0)
  Image Width: 256 Image Length: 256
  Tile Width: 256 Tile Length: 256
  Resolution: 72, 72 pixels/inch
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: RGB color
  Document Name: "/home/dron/projects/tiff/bugs/test.tif"
  Image Description: "dron"
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 3
  Planar Configuration: single image plane

$ tiffinfo outfile.tif 
TIFFReadDirectory: Warning, outfile.tif: unknown field with tag 34595 (0x8723) encountered.
TIFF Directory at offset 0x30008
  Image Width: 256 Image Length: 256
  Tile Width: 256 Tile Length: 256
  Bits/Sample: 8
  Compression Scheme: None
  Orientation: row 0 top, col 0 lhs
  Samples/Pixel: 3
  Planar Configuration: single image plane
  Tag 34595: 10,20,30,40

Hope this helps.

					Andrey

-- 
Andrey V. Kiselev
Home phone:  +7 812 5274898  ICQ# 26871517

--wRRV7LY7NUeQGEoC
Content-Type: text/x-csrc; charset=us-ascii
Content-Disposition: attachment; filename="cust-tags.c"

//=========================================================================
// test_write_tags.cpp : a function to test the writing of custom tags to
// tiff images.
//
//=========================================================================
//Includes 
#include <stdio.h>
#include <stdlib.h>
#include <tiffio.h>
 
#define           TIFFTAG_PRIVATE         34595
 
static void TagExtender(TIFF *tiff)
{
    static const TIFFFieldInfo xtiffFieldInfo[] = {
        { TIFFTAG_PRIVATE, TIFF_VARIABLE, TIFF_VARIABLE, TIFF_LONG,
            FIELD_CUSTOM, 0, 1, "Private Tag" }
    };
 
    TIFFMergeFieldInfo( tiff, xtiffFieldInfo,
                    sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]) );
}
 
int main( int argc, char* argv[] )
{
      TIFF *intif=(TIFF*)0;
      TIFF *outtif=(TIFF*)0;
      int dir_count = 0;
      int dir_ndx;
      int result = 1;
      //unsigned long* lng;
      unsigned long lng[] = {10, 20, 30, 40};
      unsigned short iCount;

      intif=TIFFOpen("inputfile.tif","r");
      if (!intif)
      {
            fprintf( stderr, "Unable to open input file.  Quitting.\n" );
            return 1;
      }
 
      outtif = TIFFOpen("outfile.tif", "w");
      if( !outtif )
      {
            fprintf( stderr, "\n\nUnable to open output file.  Quitting\n"
);
            return( 1 );
      }
 
      do
      {
            dir_count++;
      } while( TIFFReadDirectory( intif ) );
 
      printf( "%d directories in input file\n", dir_count );
 
      TIFFSetTagExtender(TagExtender);
 
      for( dir_ndx = 0; dir_ndx < dir_count; dir_ndx++ )
      {
            tdata_t buf;
            uint32 tileWidth, tileLength, imageLength, imageWidth;
            uint32 x, y;
 
            TIFFSetDirectory( intif, dir_ndx );
            fprintf( stderr, "Processing directory %d ...\n", dir_ndx );
           
            TIFFGetField(intif, TIFFTAG_TILEWIDTH, &tileWidth);
            TIFFGetField(intif, TIFFTAG_TILELENGTH, &tileLength);
            TIFFGetField(intif, TIFFTAG_IMAGELENGTH, &imageLength);
            TIFFGetField(intif, TIFFTAG_IMAGEWIDTH, &imageWidth);
 
            TIFFCreateDirectory( outtif );
            TIFFSetDirectory( outtif, dir_ndx );
            TIFFSetField(outtif, TIFFTAG_IMAGEWIDTH, imageWidth);
            TIFFSetField(outtif, TIFFTAG_IMAGELENGTH, imageLength);
            TIFFSetField(outtif, TIFFTAG_BITSPERSAMPLE, 8);
            TIFFSetField(outtif, TIFFTAG_SAMPLESPERPIXEL, 3);
            TIFFSetField(outtif, TIFFTAG_TILEWIDTH, tileWidth);
            TIFFSetField(outtif, TIFFTAG_TILELENGTH, tileLength);
            TIFFSetField(outtif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
            TIFFSetField(outtif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
 
            //result = TIFFGetField(intif, TIFFTAG_PRIVATE, &iCount, &lng); 
            iCount = sizeof(lng)/sizeof(lng[0]);
            fprintf(stderr, "iCount=%d\n", iCount);
            if( result )
                result = TIFFSetField(outtif, TIFFTAG_PRIVATE, iCount, lng);
 
            
            buf = _TIFFmalloc(TIFFTileSize(intif));
            for (y = 0; y < imageLength; y += tileLength)
            {
                  for (x = 0; x < imageWidth; x += tileWidth)
                  {
                        TIFFReadTile(intif, buf, x, y, 0, 0);
                        TIFFWriteTile(outtif, buf, x, y, 0, 0);
                  }
            }
 
            TIFFWriteDirectory( outtif );
            _TIFFfree( buf );
      }
      
    TIFFClose(intif);
    TIFFClose(outtif);
      
      return( 0 );
}


--wRRV7LY7NUeQGEoC--

