AWARE [SYSTEMS] Imaging expertise for the Delphi developer
TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems

1999.06.20 21:19 "Re: Controlling Rational Values", by Niles Ritter

```Tom writes,

> Does anyone know of a way to explicitly set which numerator and denominator
> get used when setting rational TIFF Tags?
>
> For example, I'm setting the YRESOLUTION tag to 200 which I pass to
> TIFFSetField as a float.  Libtiff stores the value 419430400 as the
> numerator and 2097152 as the denominator in the YRESOLUTION tag.  This, of
> course, is correct; however, I was hoping I could store 200 as the numerator
> and 1 as the denominator.
>

Explicitly setting the denominator to some value sounds like a bad idea; what you
really want is the "best" representation, which for anything sufficiently close to
an integer gives (x,1).

The libtiff code for generating RATIONAL values from float is correct but not optimal
mathematically. I had to improve on it a while back but don't have the code in-hand
at the current moment, but can describe it to help you get there.

libtiff code only gives you an integer pair (p,q) such that p/q approximates the rational tag
value x to order O(q).  Approximation theory says you can always find a (p,q) that does the
job to order O(q ^ 2); such an algorithm for integers x should just return (x,1).

To do this you create what's called a continued-fraction expansion of x, which is to
say a sequence of integers n1, n2, n3, ... such that  nk are positive for k>1 and

x  = n1 + 1  /  (n2 + 1 / (n3 + 1 / (n4 ....... ))))).

You can create the sequence as far you as you like by starting with x, then successively
taking the greatest integer part less than or equal to x then inverting the remainder.
Obviously, if the remainder hits zero (as any rational number would), stop.

For example, if you were given PI = 3.14159265... and you go for four iterations

3                            =  3 + 0.1415926...   -->  n1 = 3
1/(0.1415926..)  =  7 + 0.0625159...   -->  n2 = 7
1/(0.0625159..)  =  15  + 0.9959104...   --> n3 = 15
1/ (0.9959104..) =  1 + 0.004                  --> n4 = 1

This gives PI = 3 + 1/(7 + 1/(15 + 1/1) )  = 3 + 1/(113/16)  = 355/113

Which is the famous chinese value for PI, accurate to over six decimal places.

This algorithm is about as fast as the libtiff algorithm, and quickly converges
on a very close approximation for most numbers. The worst case situation is
when x = golden ratio  = ( 1 + squareroot(5)) / 2,

in which case  n1 = n2 = .. = 1; but even that case is

You now know more about approximation theory than you ever
wanted to know...

> I found a reader which incorrectly assumes the denominator is 1 and I would
> like to make compatible TIFF images if it's easy enough to control.
>

What reader program would that be?  That is such hideous bug that the company
needs immediate naming & public rebuke, especially if they actually charge money
for such rubbish. There is a reason the tag was called rational, after all...

--Niles.
```