-
2006.09.26 14:22 "[Tiff] 2003.08.07 16:40 "Custom tags", by Andrey Kiselev", by Robert Scheck
- 2006.10.11 10:21 "Re: [Tiff] Handling Of SubIFD in Libtiff Ver 3.8.3", by Sebastian Boehmer
- 2006.09.27 12:43 "Re: [Tiff] help", by Joris Van Damme
- 2006.09.27 13:26 "Re: [Tiff] help", by Gerben Vos
2006.10.11 10:21 "Re: [Tiff] 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;
}