| AWARE [SYSTEMS] | Imaging expertise for the Delphi developer | |||||||
![]() |
TIFF and LibTiff Mailing List Archive | |||||||
LibTiff Mailing List
TIFF and LibTiff Mailing List Archive Contact
The TIFF Mailing List Homepage |
Thread2006.10.11 10:21 "Re: Handling Of SubIFD in Libtiff Ver 3.8.3", by Sebastian BoehmerHello 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; } |
|||||||