Exiv2 / exiv2

Image metadata library and tools
http://www.exiv2.org/
Other
886 stars 280 forks source link

Add BigTiff Support #1556

Open clanmills opened 3 years ago

clanmills commented 3 years ago

BitTiff is 64 bit tiff. It is supported by tvisitor.cpp. Both the format and implementation is discussed in detail in my book: https://clanmills.com/exiv2/book/

The original request to support BigTiff came from Imperial College, London. They have 100 GByte images from a medical scanner which have multiple pages as the scanner "slices" through the body.

In many ways, it would be very desirable to add multi-page image support to Exiv2. I don't know if time will allow that. Multi-page support interacts with the Unified Metadata Container which is the Top feature I would like to see in Exiv2 v1.00. #1505.

Another matter that should be considered is to discontinue the use of Memory Mapped Files. The TiffVisitor code expects a tiff image to be in contiguous memory. This is achieved by memory mapping, or allocating memory equal to the image size and reading it into memory. This is totally unnecessary and very inefficient when dealing with large files.

It entirely like that time does not allow the project to fix multiple pages or remove the "contiguous memory block", so what can be done:

In the drawing below, you can see there are constants such as 12 (the width of the Tiff Record) and they are buried in the code. class TiffImage should have a member variable uint32t width which is set to 12 for Tiff images and 20 for BigTiff Images. There are values such as 2 and 4 in Tiff, which should be 4 or 8 in BitTiff.

550 rmills@rmillsmm-local:~/gnu/github/exiv2/0.27-maintenance $ grep 12 src/tiff*.cpp
src/tiffcomposite_int.cpp:        const uint32_t sizeDir = 2 + 12 * compCount + (hasNext_ ? 4 : 0);
src/tiffcomposite_int.cpp:        return 12;
src/tiffcomposite_int.cpp:        uint32_t len = 2 + 12 * compCount + (hasNext_ ? 4 : 0);
src/tiffvisitor_int.cpp:        return 12;
src/tiffvisitor_int.cpp:            if (p + 12 > pLast_) {
src/tiffvisitor_int.cpp:            p += 12;
src/tiffvisitor_int.cpp:        if (p + 12 > pLast_) {
551 rmills@rmillsmm-local:~/gnu/github/exiv2/0.27-maintenance $ 

Before you think "this is easy", think again. The file/data is frequently manipulated by using 2 byte functions such as getShort(), which may have to be getLong() in BitTiff, or getLongLong().

Is this difficult? No. It requires surgical precision and rigorous testing. There are Reference Tiff Files on the Internet and the URL is in my book. I have exchanged email with the author of BigTiff in Holland. He is friendly and helpful.

Having got the reference BigTiff files working, we should carefully study the puzzle discussed about about memory mapping. I hope that Milos will work on the Unified Metadata Container. When that is working, we should consider multi-page tiff support. It might even be quite easy!

tiff

cytrinox commented 1 month ago

Since PTGui (panorama stitching software) has published native Linux support, I've started shooting panoramas again, mostly as HDR - with final editing in darktable. These have usually ~400MP and possible output formats are TIF (32fp), OpenEXR and HDR-Radiance. While .EXR and .HDR don't have well defined metadata support afaik, TIFF fits best with excellent EXIF support. Unfortunately BigTIFF is not yet supported by exiv2, so I lost all metadata in this process. Just found this old issue, so here is a usecase for it :smile: