Working With Private TIFF Tags

TIFF files can contain private tags. LEADTOOLS can allow you to create, set and read private tags in TIFF files for your application's own use. In order to do this, you must create a SubIFD (Image File Directory) and then create your own private tags inside that IFD.

The following code writes a SubIFD and then creates two private tags into the file you specify

C#
private const int MY_SUBIFDTAG = 0xFFFE; 
private const int PRIVATETAG_1 = 0x8001; // use private tags, because LEADTOOLS will reject attempts to write tags below 0x8000 
private const int PRIVATETAG_2 = 0x8002; // use private tags, because LEADTOOLS will reject attempts to write tags below 0x8000 
private const int TAG_COUNT = 2;         // since we will be writing two tags 
private const int TAG_SIZE = 12;         // the number of bytes in one tag 
             
private long GetSubIFDOffset(string fileName) 
{ 
   using (RasterCodecs codecs = new RasterCodecs()) 
   { 
      long[] offsets = null; 
      IList<RasterTagMetadata> tags = codecs.ReadTagsWithOffsets(fileName, 1, out offsets); 
      uint x = 0; 
      foreach (RasterTagMetadata tag in tags) 
      { 
         if (tag.Id == MY_SUBIFDTAG) 
            return offsets[x]; 
         x++; 
      } 
   } 
             
   return 0; 
} 
             
private void CreateSubIFD(string fileName) 
{ 
   using (RasterCodecs codecs = new RasterCodecs()) 
   { 
      // get the SubIFD offset, if it exists 
      RasterTagMetadata subIFD = null; 
      long subIFDOffset = GetSubIFDOffset(fileName); 
      if (subIFDOffset == 0) 
      { 
         // the SubIFD does not exist, write it 
         long ifdSize = 6 + TAG_COUNT * TAG_SIZE; 
         ushort[] ifd = new ushort[ifdSize]; 
         // build the IFD: set the number of tags in the IFD 
         ifd[0] = TAG_COUNT; 
         // and set dummy placeholders for each tag as follows: pIFD[1 + (TAG_SIZE / 2) * tag_index] = tag value 
         ifd[1 + (TAG_SIZE / 2) * 0] = PRIVATETAG_1; 
         ifd[1 + (TAG_SIZE / 2) * 1] = PRIVATETAG_2; 
             
         subIFD = new RasterTagMetadata(); 
         subIFD.Id = MY_SUBIFDTAG; 
         subIFD.DataType = RasterTagMetadataDataType.UInt16; 
         subIFD.FromUInt16(ifd); 
         // write the tag as UNDEFINED 
         subIFD.DataType = RasterTagMetadataDataType.Undefined; 
             
         // write the SubIFD in the file 
         codecs.WriteTag(fileName, 1, subIFD); 
             
         subIFD = null; 
             
         // get the SubIFD offset. It should be > 0 now 
         subIFDOffset = GetSubIFDOffset(fileName); 
         if (subIFDOffset == 0) 
            throw new Exception("failure"); 
      } 
             
      // write the private tags 
      // set private tags 1 and 2 
      RasterTagMetadata privateTag1 = new RasterTagMetadata(); 
      privateTag1.Id = PRIVATETAG_1; 
      privateTag1.DataType = RasterTagMetadataDataType.Int32; 
      privateTag1.FromInt32(new int[] { 5 }); 
             
      RasterTagMetadata privateTag2 = new RasterTagMetadata(); 
      privateTag2.Id = PRIVATETAG_2; 
      privateTag2.DataType = RasterTagMetadataDataType.Ascii; 
      privateTag2.FromAscii("My String"); 
             
      // write the private tags into the SubIFD 
      codecs.Options.Tiff.Save.UseImageFileDirectoryOffset = true; 
      codecs.Options.Tiff.Save.ImageFileDirectoryOffset = subIFDOffset; 
      codecs.WriteTag(fileName, 1, privateTag1); 
      codecs.WriteTag(fileName, 1, privateTag2); 
             
      privateTag1 = null; 
      privateTag2 = null; 
             
      codecs.Options.Tiff.Load.UseImageFileDirectoryOffset = true; 
      codecs.Options.Tiff.Load.ImageFileDirectoryOffset = subIFDOffset; 
             
      // read private tag 1 from SubIFD 
      privateTag1 = codecs.ReadTag(fileName, 1, PRIVATETAG_1); 
      if ((privateTag1.ToInt32())[0] != 5) 
         throw new Exception("Failure"); 
             
      // read private tag 2 from SubIFD 
      privateTag2 = codecs.ReadTag(fileName, 1, PRIVATETAG_2); 
      if (privateTag2.ToAscii() != "My String") 
         throw new Exception("Failure"); 
   } 
} 

You can create private tags in TIFF or EXIF JPEG files. This code will fail if you use it with regular JPEG files.

NOTE: Once you have created the SubIFD, you can add and read tags from it as many times as you need.

Help Version 22.0.2023.7.17
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Imaging, Medical, and Document

Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.