Skip to content

Instantly share code, notes, and snippets.

@ctrueden
Created March 20, 2015 16:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctrueden/6a91656fa9804d1a874a to your computer and use it in GitHub Desktop.
Save ctrueden/6a91656fa9804d1a874a to your computer and use it in GitHub Desktop.
How WiscScan injects OME-XML into an existing TIFF file
strLen = OMEXMLMetadataString.size();
// Can't just overwrite the TIFFTAG_IMAGEDESCRIPTION since TIFFOPEN will just rewrite the tiff
// Need to do it like the 4d case
CFile myFile;
if(!myFile.Open(newTemp, CFile::modeReadWrite) )
continue;
strOffset = myFile.GetLength();
/* read the head of the TIFF file to get the IFH (Image File Header);
* offset to byte 5 to get the 4 byte offset to the first Image File Directory (IFD) structure
* TIFF HEADER: first 8 bytes are 0x49492A00 then the 4 byte offset to the IFH
* 4949 = intel byte ordering; 2A = version; 00 unused???
*/
if (myFile.Seek( 0x4, CFile::begin ) != 4 || myFile.Read(&IFDOffset, 0x4) != 4) {
TRACE("updateOME4DTS can't read tiff header"); //um, panic? bad file
continue;
}
/* walk the (essentially linked list in the file) of IFD structures to find the IMAGEDESCRIPTION
*
* IFD consists of 2 byte directory entry count, then said entry count * 12 bytes of Directory
* Entry structure, then either 0x00000000 to indicate end or ptr to next IFD
*
* NB: this only walks 1 such IFD structure -- should be OK, IMAGEDESCRIPTION in first set of structs
*/
// Seek to the IFD
lActual = myFile.Seek(IFDOffset, CFile::begin);
// Read the number of IFD's? Still confused on this one
myFile.Read(&count, 4);
for(int k=0; k<count; k++){
// The offset to the first directory entry
LONG nextDirEntryOffset = LONG(IFDOffset) + 2 + 12*k;
lActual = myFile.Seek(nextDirEntryOffset, CFile::begin);
myFile.Read(&tag, 2);
if(tag == 0x010E /* dec 270, TIFFTAG_IMAGEDESCRIPTION */ ){
lActual = myFile.Seek(nextDirEntryOffset+4, CFile::begin);
myFile.Write(&strLen, 4);
lActual = myFile.Seek(nextDirEntryOffset+8, CFile::begin);
myFile.Write(&strOffset, 4);
lActual = myFile.Seek(strOffset, CFile::begin);
myFile.Write(OMEXMLMetadataString.c_str(), UINT(strLen));
lActual = myFile.Seek(nextDirEntryOffset+4, CFile::begin);
myFile.Read(&tmp1, 4);
lActual = myFile.Seek(nextDirEntryOffset+8, CFile::begin);
myFile.Read(&tmp2, 4);
break;
}
}
myFile.Close();
@ctrueden
Copy link
Author

This code is part of LOCI's WiscScan application; I cannot take credit for the actual implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment