- 2014.06.06 11:11 "Re: [Tiff] What's wrong with my code for adding custom tags to a file", by Stephen Morris
2014.06.09 11:32 "Re: [Tiff] What's wrong with my code for adding custom tags to a file", by Stephen Morris
Here as promised is my ultimately successful testing code.
It turned out that there were two keys to getting it to work:
- Defining the TIFFFieldInfo fields correctly as Paul Heckbert pointed out, which is different from the example given in the documentation.
- Using the ³extender² pattern for encapsulating the call to TIFFMergeFieldInfo, but doing this *before* opening the file. If I left the call until after opening the file, then when reading a file with custom tags the ³Warning, unknown field² messages would be issued immediately on opening the file.
Here is the code. As in my original posting, this is a complete listing apart from my separate ŒPGM¹ module which just reads in an image from a .pgm file. My test code then proceeds to re-save this file as a TIFF containing various custom tags; and then to clear the tag values and re-read the file, verifying that the tag values stored in the file can also be correctly read back from it:
‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹‹
#include "stdafx.h"
#include "PGM.h"
#include "tiffio.h"
// There are a number of TIFF-related definitions we need to make in order
to support the custom tags
// that we want to include in our files. The form of these definitions and
subroutines comes straight
// out of the libtiff documentation, and the values of the custom tags
themselves come from the
// range (65000-75535) defined in the TIFF specification as "reusable" and
suitable for private use
// within organisations. See
http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf
#define N(a) (sizeof(a) / sizeof (a[0]))
#define TIFFTAG_INCIDENTPOWER 65000
#define TIFFTAG_REFLECTEDPOWER 65001
#define TIFFTAG_T1 65002
#define TIFFTAG_T2 65003
#define TIFFTAG_HUMIDITY 65004
#define TIFFTAG_EXPOSURE 65005static const TIFFFieldInfo xtiffFieldInfo[] = {
{ TIFFTAG_INCIDENTPOWER, 1, 1, TIFF_LONG, FIELD_CUSTOM, 0, 0,
const_cast<char*>("LaserIncidentPower") },
{ TIFFTAG_REFLECTEDPOWER, 1, 1, TIFF_LONG, FIELD_CUSTOM, 0, 0,
const_cast<char*>("LaserReflectedPower") },
{ TIFFTAG_T1, 1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Temperature_1") },
{ TIFFTAG_T2, 1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Temperature_2") },
{ TIFFTAG_HUMIDITY, 1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("Humidity") },
{ TIFFTAG_EXPOSURE, 1, 1, TIFF_FLOAT, FIELD_CUSTOM, 0, 0,
const_cast<char*>("ExposureTime(ms)") }
}; //
The casts are necessary because the
//
string literals are inherently const,
//
but the definition of TIFFFieldInfo
//
requires a non-const string pointer.
//
The Intel and Microsoft compilers
//
tolerate this, but gcc doesn't.static TIFFExtendProc parent_extender = NULL; // In case we want a chain of extensions
static void registerCustomTIFFTags(TIFF *tif) {
/* Install the extended Tag field info */
int error = TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
if (parent_extender)
(*parent_extender)(tif);
}static void augment_libtiff_with_custom_tags() {
bool first_time = true; Static
if (!first_time) return;
first_time = false;
parent_extender = TIFFSetTagExtender(registerCustomTIFFTags);}
void saveAsTiff(int nx, int ny, unsigned short *image, const char* filename,
int Power1, int Power2, float T1, float T2, float
Humidity, float Exposure)
{
// Create the TIFF directory object:
augment_libtiff_with_custom_tags();
TIFF* tif = TI