after a long struggle with trying to write EXIF fields into .tif files using libtiff v.4.0.7, I've discovered the following problem in the source file
tif_dirwrite.c - method TIFFWriteDirectoryTagCheckedRational:
libtiff defines RATIONAL as float for its IO, when used in other applications, and converts them when reading from files, and when writing into files, from / into suitable unsigned rationals (32 bit nom. and 32 bit denom.) . However, using the exiftool made
by Phil Harvey
http://www.sno.phy.queensu.ca/~phil/exiftool/ I found that the values are interpreted correctly. Using IfranView, it was not the case. A rational was interpreted as a signed rational, ignoring the decimal point numbers and making the value negative and
signed. This seemingly bug is a result of the 0xFFFFFFFF used for precision while converting the floats.
My workaround was to define my own field array, changing all TIFF_RATIONAL fields to TIFF_SRATIONAL, and it worked for IfranView and exiftool, since it forced using
TIFFWriteDirectoryTagCheckedSrationalArray, which converts using 0x7FFFFFFF because of the sign bit at the front, not maximizing precision as in 0xFFFFFFFF, which had lead to this incompatibility.
I didn't find a method such as TIFFWriteDirectoryTagCheckedSRational. Now I've spent almost 2 months trying to figure out how to write EXIF data to tif files, and I've found this method, by Paul Heckbert to be the best so far:
I just replaced TIFFCreateEXIFDirectory by TIFFCreateCustomDirectory, for which I had to define my own
TIFFField exifFields and TIFFFieldArray exifFieldArray from tif_dirinfo.c. I didn't change them there, I just copied them into my application and changed the tags I needed.
I hope this helps someone, and I hope someone would take care of these issues in a future update of the library.
> On Feb 17, 2017, at 4:26 AM, Alnahawi, Nouri <[hidden email]> wrote:
> An example: ExposureTime (defined as TIFF_RATIONAL) with value 1/640 = 0.0015625 is interpreted as -6710886 in IRfanView, whereas it should be 6710886,4294967295 = 1/640. FocalLength (also defined as TIFF_RATIONAL) with value 131.0 = 0,0076335877... is iterpreted correctly. So you can see what I mean :/
I wouldn't call it a bug in libTiff just because IRfanView can't read it, but the LibTiff rationalization algorithm is definitely flawed for other reasons:
1. Numbers which have exact rational representations may only be approximated (eg. 0.3 can be represented exactly as 3/10, but LibTiff writes 0x4cccccccc/0xffffffff which equals 2.999999999).
2. Rounding is done by truncation, so the nearest representation (for the given numerator or denominator of 0xffffffff) is only found half of the time.
3. In the Exif 2.31 specification there are 4 RATIONAL tags for which 0xffffffff in the numerator or denominator has a special meaning:
0x9206 SubjectDistance 0xffffffff in the numerator indicates infinity
0x9401 Humidity 0xffffffff in the denominator indicates unknown
0x9402 Pressure 0xffffffff in the denominator indicates unknown
0x9404 Acceleration 0xffffffff in the denominator indicates unknown