title: Adding custom tags to a TIFF file
body: <p>I’m quite new to libtiff, but I’ve managed to get tiff files
  saving and opening without much trouble.</p>
  
  <p>Now, I’m being ambitious and trying to add custom tags into my files. I’ve
  read the documentation (<a href="http://www.remotesensing.org/libtiff/addingtags.html" rel="nofollow">see here</a>) and written some test code which compiles without
  errors, but fails at runtime with an access violation at the first call to
  TIFFSetField that features a custom field (calls to TIFFSetField with
  standard fields are fine).</p>
  
  <p>My test code follows: just under 100 lines, with the only external
  dependency (besides libtiff) being my code to open a test image from a
  .pgm file.  Can anyone point out what I’m doing wrong? By the way, I'm using libtiff 4.0.3.</p>
  
  <pre><code>#include "stdafx.h"
  #include "PGM.h"      // Just for reading in the test image
  #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          65005
  
  static const TIFFFieldInfo xtiffFieldInfo[] = {
      { TIFFTAG_INCIDENTPOWER,  -1, -1, TIFF_LONG,  FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("LaserIncidentPower") },
      { TIFFTAG_REFLECTEDPOWER, -1, -1, TIFF_LONG,  FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("LaserReflectedPower") },
      { TIFFTAG_T1,             -1, -1, TIFF_FLOAT, FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("Temperature_1") },
      { TIFFTAG_T2,             -1, -1, TIFF_FLOAT, FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("Temperature_2") },
      { TIFFTAG_HUMIDITY,       -1, -1, TIFF_FLOAT, FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("Humidity") },
      { TIFFTAG_EXPOSURE,       -1, -1, TIFF_FLOAT, FIELD_CUSTOM, 0, 1, const_cast&lt;char*&gt;("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 void registerCustomTIFFTags(TIFF *tif)
  {
      /* Install the extended Tag field info */
      TIFFMergeFieldInfo(tif, xtiffFieldInfo, N(xtiffFieldInfo));
  }
  
  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:
      TIFF* tif = TIFFOpen(filename, "w");
  
      // Set the tags: first the standard ones...
      TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx);
      TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny);
      TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
      TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
      TIFFSetField(tif, TIFFTAG_ZIPQUALITY, 6); // Takes maximum advantage of Intel ZLIB enhancements
      TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
      TIFFSetField(tif, TIFFTAG_ORIENTATION, static_cast&lt;int&gt;(ORIENTATION_TOPLEFT));
      TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
      TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, ny);
      // Saving the whole image in a single block makes heavy
      // demands on memory but should enable optimum compression
      TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  
      // ... and now our own custom ones; if we comment out this next block then everything
      // works as it should and we successfully save the image:
      registerCustomTIFFTags(tif);
      TIFFSetField(tif, TIFFTAG_INCIDENTPOWER, Power1);   // Access violation here
      TIFFSetField(tif, TIFFTAG_REFLECTEDPOWER, Power2);
      TIFFSetField(tif, TIFFTAG_T1, T1);
      TIFFSetField(tif, TIFFTAG_T2, T2);
      TIFFSetField(tif, TIFFTAG_HUMIDITY, Humidity);
      TIFFSetField(tif, TIFFTAG_EXPOSURE, Exposure);
  
      TIFFWriteEncodedStrip(tif, 0, static_cast&lt;void *&gt;(image), nx * ny * 2); 
                                                                // The '* 2' is present because each pixel
                                                                // has 16 bits, hence two bytes
      // Write the directory to a file, and close it:
      TIFFWriteDirectory(tif);
      TIFFClose(tif);
  }
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      // Variables to hold the image
      int nx, ny;
      unsigned short *image = nullptr;
  
      // Information we'd like to put into our custom tags:
      int Power1 = 1000000;
      int Power2 = 8;
      float T1 = 23.5f;
      float T2 = -18.7f;
      float Humidity = 0.98f;
      float Exposure = 0.001f;
  
      // Read the test image in from a PGM file:
      readFromPGM(&amp;nx, &amp;ny, &amp;image, "TestImage.pgm");
  
      // Save the image as a TIF file:
      saveAsTiff(nx, ny, image, "TestImage.tif", Power1, Power2, T1, T2, Humidity, Exposure);
      return 0;
  }
  </code></pre>