Incompatibility with unsigned rationals

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Incompatibility with unsigned rationals

Alnahawi, Nouri
Dear Tiff Community,

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:

Starting at line 2110:

    else if (value<1.0)
    {
        m[0]=(uint32)(value*0xFFFFFFFF);
        m[1]=0xFFFFFFFF;
    }
    else
    {
        m[0]=0xFFFFFFFF;
        m[1]=(uint32)(0xFFFFFFFF/value);

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: http://www.asmail.be/msg0054967491.html
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.

Cheers!
Nouri

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Incompatibility with unsigned rationals

Phil Harvey-2
Isn't this a bug in IRfanView? (Interpreting 0xffffffff
in a TIFF_RATIONAL as a signed integer.)

        - Phil


_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Incompatibility with unsigned rationals

Phil Harvey-2
In reply to this post by Alnahawi, Nouri

> 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

        - Phil

_______________________________________________
Tiff mailing list: [hidden email]
http://lists.maptools.org/mailman/listinfo/tiff
http://www.remotesensing.org/libtiff/
Loading...