mm2 / Little-CMS

A free, open source, CMM engine. It provides fast transforms between ICC profiles.
https://www.littlecms.com
MIT License
571 stars 176 forks source link

TIFFTAG_TRANSFERFUNCTION values to cmsBuildTabulatedToneCurve16() #459

Closed mbechard closed 1 month ago

mbechard commented 2 months ago

The TIFF formats says TIFFTAG_TRANSFERFUNCTION is an array of 1<< bitsPerSample entries. So 65535 for 16-bits. However cmsBuildTabulatedToneCurve16() is limited to 65530 entries. Is this limitation necessarily? Can it be expanded so a transfer function from a 16-bit TIFF file can be consumed directly?

mm2 commented 2 months ago

Not same thing. The transfer function in TIFF format is a table for every possible value off the channel. In LittleCMS this is a vector of control nodes to do linear interpolation. One node for value is a big waste, but may have sense on 8 bits because ICC profiles works at 16 bits of precision, so you are using 256 nodes for a domain of 0..65535. In 16 bits, one node per value makes no sense at all.

Also, In 8 bits you have 256x3 = 768 bytes. Fine. But in 16 bits you have 64K32 which is about 400K. A lot of space for a transfer function. This is the reason nobody uses that over 8 bits, f you want colorimetry it is better to just embed the ICC profile.

mbechard commented 1 month ago

Yes, agreed that it was a weird way for the TIFF standard to describe the transfer for 16-bit. I'm just trying to be robust in my support for TIFF reading, so while I'll output ICC, I'd like to be able to ingest the TRANSFER for 16-bit files, if that happens to be the only data that's contained in the file. A 4k 16-bit .tiff file is 65MB, so 400K isn't terrible overhead though.

Since we're only off by 5 entries though, is there no way this can be expanded?

mm2 commented 1 month ago

400K is a huge pain for the CMM, indeed. Anyway, if you want to handle the rare case of a TIFF using that, you could just discard 5 entries on any location of the table (but the endpoints). That would make an error of 5/65536 which is 0.0076% Not sure if this is going to work, lcms uses those entries as interpolation nodes, not just 1:1 translation. Anyway, remember to never create such TIFFs!

mbechard commented 1 month ago

Ok, thanks for the input. Appreciate your time!