Return-Path: <tiff-bounces@lists.maptools.org>
Received: from inas037.isp.belgacom.be (localhost [127.0.0.1])
        by inav010.isp.belgacom.be (8.12.11.20060308/8.12.11/Skynet-IN-AV-3.00) with ESMTP id k9BAZ9Q1007396
        for <joris.at.lebbeke@skynet.be>; Wed, 11 Oct 2006 12:35:09 +0200
        (envelope-from <tiff-bounces@lists.maptools.org>)
Received: from inmx003.isp.belgacom.be (inmx003.isp.belgacom.be [195.238.5.11])
	by inas037.isp.belgacom.be (Postfix) with ESMTP id 4737213A03
	for <joris.at.lebbeke@skynet.be>; Wed, 11 Oct 2006 12:35:09 +0200 (CEST)
Received: from duke.maptools.org (r153.dmsolutions.ca [209.217.116.153] (may be forged))
        by inmx003.isp.belgacom.be (8.12.11.20060308/8.12.11/Skynet-IN-2.32) with ESMTP id k9BAYwC5002671
        for <joris.at.lebbeke@skynet.be>; Wed, 11 Oct 2006 12:34:59 +0200
        (envelope-from <tiff-bounces@lists.maptools.org>)
Received: from duke.maptools.org (duke.maptools.org [127.0.0.1])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id k9BALFxZ002656;
	Wed, 11 Oct 2006 06:21:37 -0400
Received: from fmmailgate03.web.de (fmmailgate03.web.de [217.72.192.234])
	by duke.maptools.org (8.12.11/8.12.10) with ESMTP id k9BALCDe002651
	for <tiff@lists.maptools.org>; Wed, 11 Oct 2006 06:21:13 -0400
Received: from smtp08.web.de (fmsmtp08.dlan.cinetic.de [172.20.5.216])
	by fmmailgate03.web.de (Postfix) with ESMTP id 834582840F8B
	for <tiff@lists.maptools.org>; Wed, 11 Oct 2006 12:21:11 +0200 (CEST)
Received: from [132.230.21.145] (helo=[132.230.21.145])
	by smtp08.web.de with asmtp (WEB.DE 4.107 #114) id 1GXbD5-00070w-00
	for tiff@lists.maptools.org; Wed, 11 Oct 2006 12:21:11 +0200
Message-ID: <452CC597.8010801@web.de>
Date: Wed, 11 Oct 2006 12:21:11 +0200
From: Sebastian Boehmer <sebastian.boehmer@web.de>
User-Agent: Thunderbird 1.5.0.7 (X11/20060911)
MIME-Version: 1.0
CC: Tiff <tiff@lists.maptools.org>
Subject: Re: [Tiff] Handling Of SubIFD in Libtiff Ver 3.8.3
References: <11848b2f0610110038y69352c69j6d521e7c8cf12f63@mail.gmail.com>
In-Reply-To: <11848b2f0610110038y69352c69j6d521e7c8cf12f63@mail.gmail.com>
Content-Type: multipart/mixed; boundary="------------060804030000010707000400"
X-Sender: sebastian.boehmer@web.de
X-BeenThere: tiff@lists.maptools.org
X-Mailman-Version: 2.1.4
Precedence: list
List-Id: TIFF and libtiff discussion <tiff.lists.maptools.org>
List-Unsubscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=unsubscribe>
List-Archive: <http://lists.maptools.org/mailman/private/tiff>
List-Post: <mailto:tiff@lists.maptools.org>
List-Help: <mailto:tiff-request@lists.maptools.org?subject=help>
List-Subscribe: <http://lists.maptools.org/mailman/listinfo/tiff>,
	<mailto:tiff-request@lists.maptools.org?subject=subscribe>
Sender: tiff-bounces@lists.maptools.org
Errors-To: tiff-bounces@lists.maptools.org
X-UIDL: 000000000023ceae.00001bb4
X-MSP-STORE: Wed, 11 Oct 2006 12:35:13 +0200
Status: RO

This is a multi-part message in MIME format.
--------------060804030000010707000400
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Hello folks,

This Problem could be solved with the patch in the bugzilla report 1320
http://bugzilla.remotesensing.org/show_bug.cgi?id=1320

It add the following interface for private sub IFD support:
extern	void TIFFMergePrivateFieldInfo(TIFF*, const TIFFFieldInfo[],unsigned int);
extern	const TIFFFieldInfo* TIFFFindPrivateFieldInfo(TIFF*, ttag_t, TIFFDataType);
extern	const TIFFFieldInfo* TIFFPrivateFieldWithTag(TIFF*, ttag_t);

extern  int TIFFSetPrivateField(TIFF*, ttag_t, ...);
extern	int TIFFVSetPrivateField(TIFF*, ttag_t, va_list);
extern	int TIFFGetPrivateField(TIFF*, ttag_t, ...);
extern	int TIFFVGetPrivateField(TIFF*, ttag_t, va_list);
extern  int TIFFWritePrivateDirectory(TIFF*, toff_t*);
extern  int TIFFReadPrivateDirectory(TIFF*, toff_t);
extern	int TIFFReadPrivateDirectoryWithFieldInfo(TIFF*, toff_t, const TIFFFieldInfo[], size_t);


In the attachment is an example Interface for the ATR private tags.
The code below comes from this files.
greets, Sebastian


Here is a draft of an example:

Use the code for custom tags from
http://www.remotesensing.org/libtiff/addingtags.html
The essenctial changes are marked with //!!!

 File: private_tags.h
---

#include <tiffio.h>
#include <tiff.h>

#define	   TIFFTAG_PRIVATE_OFFSET	0xB10A	// !!!


// !!!
static const TIFFFieldInfo tiffIFDOffset[] = {
	/* TIFF_IFD is actual not correct implemented in libtiff. */
	//{ TIFFTAG_PRIVATE_OFFSET, 1,1, TIFF_IFD,	FIELD_CUSTOM,
	//	TRUE, FALSE, "IMTEK ATR2 IFD" }
	/* BUG: libtiff 06-09-26: TIFF_IFD didn't work correct date:06-09-26 */
	{ TIFFTAG_PRIVATE_OFFSET, 1,1, TIFF_LONG,	FIELD_CUSTOM,
		TRUE, FALSE, "IMTEK ATR2 IFD" }
};

static const TIFFFieldInfo xtiffFieldInfo[] = {
  
  /* XXX Insert Your tags here */
    { TIFFTAG_GEOPIXELSCALE,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
      TRUE,	TRUE,	"GeoPixelScale" },
    { TIFFTAG_GEOTRANSMATRIX,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
      TRUE,	TRUE,	"GeoTransformationMatrix" },
    { TIFFTAG_GEOTIEPOINTS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
      TRUE,	TRUE,	"GeoTiePoints" },
    { TIFFTAG_GEOKEYDIRECTORY, -1,-1, TIFF_SHORT,	FIELD_CUSTOM,
      TRUE,	TRUE,	"GeoKeyDirectory" },
    { TIFFTAG_GEODOUBLEPARAMS,	-1,-1, TIFF_DOUBLE,	FIELD_CUSTOM,
      TRUE,	TRUE,	"GeoDoubleParams" },
    { TIFFTAG_GEOASCIIPARAMS,	-1,-1, TIFF_ASCII,	FIELD_CUSTOM,
      TRUE,	FALSE,	"GeoASCIIParams" }
};

#define	N(a)	(sizeof (a) / sizeof (a[0]))

static TIFFExtendProc _ParentExtender = NULL;

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 void
_XTIFFDefaultDirectory(TIFF *tif)
{
    /* Install the extended Tag field info */
    TIFFMergeFieldInfo(tif, tiffIFDOffset, N(tiffIFDOffset));			// !!!
    TIFFMergePrivateFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));		// !!!

    /* 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);
}

---


File: application.cc
---
#include <tiffio.h>			// the libtiff


int main() {
	char filename[] = "test.tiff";
	unsinged int length=100, width=100;
	uint16 bps=8, spp=1;
	unsigned char* imageBuffer = new unsigned char[2*length*width];

	_XTIFFInitialize();
	TIFF* image;
	if (( image = TIFFOpen(filename,"w")) == NULL) {
		printf("Could not open %s for \n",filename);
		return -1;
	}

	/*
	* Write the Image
	*/
	// Check that it is of a type that we support
	if(TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bps) == 0){
		printf("Couldn't write the bits per sample. It is not possible to write the image.");
		TIFFClose(image);
		return -1;
	}
	if(TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, spp) == 0){
		printf("Couldn't write number of samples per pixel (last time %i)",spp);
		TIFFClose(image);
		return -1;
	}
	if(TIFFSetField(image, TIFFTAG_IMAGEWIDTH, width) == 0){
		printf("Couldn't write the width (last time %i)",width);
		TIFFClose(image);
		return -1;
	}

... see attachment

	/* write the image data */
	if ( bps == 8 ) {
		if ( TIFFWriteEncodedStrip(image, 0, imageBuffer, width * length) == 0 ) {
			printf("Write error: TIFF image writing. \nPerhaps not enought memory?");
			TIFFClose(image);
			return -2;
		}

	} else
		if ( TIFFWriteEncodedStrip(image, 0, imageBuffer, width * length * 2) == 0) {
			printf("Write error: TIFF image writing. \nPerhaps not enought memory?");
			TIFFClose(image);
			return -2;
		}


	/*
	* Write the Offset
	*/
	// with pseudo value for calculating offset
	if (!TIFFSetField(image, TIFFTAG_PRIVATE_OFFSET, 0 ))
		printf("Couldn't write the offset tag to 0");		
	if (!TIFFCheckpointDirectory(image))
		printf("Couldn't write the checkpoint");
	tiff_ifd_offset = TIFFCurrentDirOffset(image);
	if (!TIFFSetField(image, TIFFTAGSPEC_OFFSET_V1, tiff_ifd_offset)) {
		printf("Couldn't write the offset tag (offset=%d)",TIFFCurrentDirOffset(image));
	}
	if (!TIFFWriteDirectory(image)) {
		printf("Couldn't write the directory");
		TIFFClose(image);
		return -5;
	}


	/*
	* Write the private values
	*/
	if (! TIFFSetPrivateField(image, TIFFTAG_GEOPIXELSCALE, 0.3 ) {
		printf("Error at writing private field\n");
		return -2;
	}

...

	/*
	* Write the private Sub IFD
	*/
	toff_t tiff_ref_offset = 0;
	if (!TIFFWritePrivateCustomDirectory(image,&tiff_ref_offset)) {
		printf("Couldn't write the custom directory\n");
		TIFFClose(image);
		return -8;
	}

	TIFFClose(image);

/*
 * now we read the file
 */

	if ( (image = TIFFOpen(filename,"r")) == NULL ) {
		printf("Could not open %s for reading \n",filename);
		return -3;
	}

	/*
		* Get the Image
		*/
	// Check that it is of a type that we support
	if((TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bps) == 0) || !((bps == 8) || (bps == 16))){
		printf("Either undefined or unsupported number of bits per sample (should be 8 or 16)");
		TIFFClose(image);
		return -1;
	}

	if((TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp) == 0) || (spp != 1)){
		printf("Either undefined or unsupported number of samples per pixel (should be 1)");
		TIFFClose(image);
		return -1;
	}

...

	/* read the image */
	for (row = 0; row < length; row++)
		if ( TIFFReadScanline(image, &imageBuffer[row*scanLineSize], row, 0) == -1 ) {
			sprintf(error_str,"Read error on input \nscanLineSize=%i row=%i",scanLineSize,row);
			setError(error_str);
			closeFile(image);
			return -1;
		}

...
	/*
	 * Read the private subIFD
	 */

	toff_t tiff_ifd_offset;
	// get the offset to the directory
	if ( ! TIFFGetField(image, TIFFTAG_PRIVATE_OFFSET, &tiff_ifd_offset) ) {
		printf("Couldn't find the private IFD Offset to the ATR tags.");
		return -2;
	} 
	// read directory from offset
	if ( ! TIFFReadPrivateCustomDirectory(image, tiff_ifd_offset) ) {
		printf("Couldn't read the private ATR tags.");
		return -2;
	} 


	/*
	* Read the private values
	*/
	
	float f;
	if (TIFFGetPrivateField(image, TIFFTAG_GEOPIXELSCALE, &f) == 0) {
		printf("Couldn't read the private value geo pixel scale");
	}
...

	TIFFClose(image);

	return 0;
}





--------------060804030000010707000400
Content-Type: application/zip;
 name="ATRImageLib.zip"
Content-Transfer-Encoding: base64
Content-Disposition: inline;
 filename="ATRImageLib.zip"

UEsDBAoAAAAAAFNYSzUAAAAAAAAAAAAAAAAMABUAQVRSSW1hZ2VMaWIvVVQJAAMtsyxFcLYs
RVV4BAA5oekDUEsBAhcDCgAAAAAAU1hLNQAAAAAAAAAAAAAAAAwADQAAAAAAAAAQAO1BAAAA
AEFUUkltYWdlTGliL1VUBQADLbMsRVV4AABQSwUGAAAAAAEAAQBHAAAAPwAAAAAA
--------------060804030000010707000400
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Tiff mailing list: Tiff@lists.maptools.org
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
--------------060804030000010707000400--
