2014.01.22 03:07 "[Tiff] TIFF_SETGET_C0_DOUBLE handling missing?", by Jürgen_Buchmüller

2014.01.23 19:45 "Re: [Tiff] TIFF_SETGET_C0_DOUBLE handling missing?", by Jürgen_Buchmüller

Am Mittwoch, den 22.01.2014, 09:11 -0600 schrieb Bob Friesenhahn:

Problems are not intentional. Contributions of well tested source patches are appreciated.

Well tested it isn't, because I have just one application using it. It is rather straightforward, though, which is why it will almost certainly be ok. See attached diff against 4.0.3.

What doesn't work is to declare a TIFFField with field_type == TIFF_RATIONAL and then use TIFF_GETSET_C0_DOUBLE, because there is an array conversion to rational just for float arrays, not for double arrays.

The combination TIFF_RATIONAL vs. DOUBLE just works for single values, since TIFFWriteDirectoryTagRational() expects a double value.

In other words: in tif_dirwrite.c there is no implementation of a TIFFWriteDirectoryTagCheckedRationalArrayDouble() function with "double* value" as its last parameter. It would have to be written and used for the case where the field_type is TIFF_RATIONAL and the passed in array type is TIFF_.._DOUBLE.

I tried to add this type of conversion to libtiff-4.0.3, but then stumbled across the fact that the TIFF_RATIONAL and TIFF_SRATIONAL types are implicitly converted to float arrays in tif_dirread.c and there is no (easy) way to make that conversion depend on the field declaration.

If there is interest, I could try to implement the TIFFFieldArray for the EXIF_TAG_GPS_... and also the TIFFReadGPSDirectory() and TIFFCreateGPSDirectory() functions, analogous to TIFFReadEXIFDirectory() and TIFFCreateEXIFDirectory().

I have it running with a private TIFFFieldArray which, to avoid inconsistent use of float and double, defines TIFF_SETGET_FLOAT and TIFF_GETSET_C0_FLOAT for all rationals in EXIF-GPS.

Jürgen

--- /home/urmeli/src/qt/iwlibs/tiff-4.0.3/libtiff/tif_dirread.c 2012-08-19 18:56:34.000000000 +0200
+++ tif_dirread.c       2014-01-22 13:48:51.776375988 +0100
@@ -4969,6 +4969,28 @@
                                }
                        }
                        break;
+               case TIFF_SETGET_C0_DOUBLE:
+                       {
+                               double* data;
+                               assert(fip->field_readcount>=1);
+                               assert(fip->field_passcount==0);
+                               if (dp->tdir_count!=(uint64)fip->field_readcount)
+                                    /* corrupt file */;
+                               else
+                               {
+                                       err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+                                       if (err==TIFFReadDirEntryErrOk)
+                                       {
+                                               int m;
+                                               m=TIFFSetField(tif,dp->tdir_tag,data);
+                                               if (data!=0)
+                                                       _TIFFfree(data);
+                                               if (!m)
+                                                       return(0);
+                                       }
+                               }
+                       }
+                       break;

                case TIFF_SETGET_C16_ASCII:
                        {
                                uint8* data;