2010.12.24 16:28 "[Tiff] TIFFTAG_SMINSAMPLEVALUE and TIFFTAG_SMAXSAMPLEVALUE", by Olivier Paquet
Hi,
I brought up the issue back in September that these two tags could not be read/written with different per sample values by libtiff because the interface expects only a single value. I suggest you go read the discussion in the archive but the short of it is that a new interface would be needed if this is to be supported.
I've since had to come up with something for my own use which I'd like to submit for some review and comments. I'm attaching two patches. The first is against the 3.9 branch and is a fairly small change to allow libtiff to read files with different values for each sample. Internally, libtiff still stores only one value which is the min/max of what was read. There are no user visible changes and this only lets libtiff read files that it couldn't before. There is no access to the per sample values.
The second patch is against 4.0 and adds read/write support for multiple values. The internal representation has been changed to multiple values. Again, the API is maintained for the TIFFGetField by returning the min/max of all sample values. Access to the per sample values is possible through a pseudo tag which changes the behavior of TIFFSetField/TIFFGetField to handle the smin/smax tag as arrays. For example, with 3 floating point samples, one used to have:
float min_value = 0;
TIFFSetField( m_TIFF, TIFFTAG_SMINSAMPLEVALUE, min_value );
But it is now also possible to do:
float min_values[3] = { 0f, 0.2f, 0.3f };
TIFFSetField( m_TIFF, TIFFTAG_PERSAMPLE, PERSAMPLE_MULTI );
TIFFSetField( m_TIFF, TIFFTAG_SMINSAMPLEVALUE, &min_values[0] );
/* Reset to default behavior, if needed. */
TIFFSetField( m_TIFF, TIFFTAG_PERSAMPLE, PERSAMPLE_MERGED );
I decided against adding TIFFSetFieldSample/etc functions as in the
original discussion for a few reasons:
- It required rather invasive changes in the libtiff API (there are a few versions of each function, function pointers to be added, etc) for such a simple feature.
- It made setting the tag strange as there is the possibility that it will not be set for all channels.
- It required more complex client side code (loops everywhere, need to allocate storage to get the field).
- Finally, TIFFPrintDirectory (and so tiffinfo) now prints the multiple values instead of one in libtiff4. This is pretty much the only user visible change in default behavior.
- I'd like to at least commit the libtiff 3.9 patch in the coming weeks so it will eventually migrate to distributions and people will stop bugging me about tiffinfo failing on our tiff files :-) I'd also like to avoid maintaining the 4.0 patch out of tree forever so if anyone has a major objection to it, please suggest a reasonable alternative. If anyone asks, I can supply a sample TIFF with different values for the smin/smax tag.
Olivier