AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
October 2006

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2006.10.11 10:21 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Sebastian Boehmer
2006.10.12 13:01 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Anurag Singh
2006.10.12 13:41 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by <sebastian.boehmer@web.de>
2006.10.13 05:16 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Anurag Singh
2006.10.14 12:58 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Anurag Singh
2006.10.16 19:35 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Sebastian Boehmer

2006.10.11 10:21 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Sebastian Boehmer

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;
}