photopea / UTIF.js

Fast and advanced TIFF decoder
MIT License
424 stars 87 forks source link

16-bit TIFF treated as 8-bit? #110

Closed lutifyme closed 1 year ago

lutifyme commented 1 year ago

Hi,

Is it possible that Photopea and utif.js treat 16-bit tiff files as if they were 8-bit discarding data in process?

Here's a sample file I'm testing in Photopea: https://www.dropbox.com/s/lylyfw6qxg8tmuv/rwg-tif_1.176.5.tif?dl=0

It's a file exported from RED .r3d raw file in REDWideGamutRGB color space with Log3G10 gamma using Davinci Resolve.

When I add contrast to it and saturation to "normalize" the image I end up with something like this: https://www.dropbox.com/s/1xxk8124htclxl6/Screen%20Shot%202022-10-13%20at%2010.26.32.png?dl=0

Notice the banding in the sky.

When I do the same, in Davinci resolve on the same tiff file, The sky appears correctly without banding. See example: https://www.dropbox.com/s/ia3oa3wwhw5zldy/Screen%20Shot%202022-10-13%20at%2010.28.06.png?dl=0

To make it clear, I'm not monitoring in Davinci in 10 bit but rather 8-bit to better simulate browser environment. It's not a monitoring issue.

After making this test I wanted to make sure it's not a browser vs. desktop issue, so I used a minimal app built on top of three.js which uses utif.js for its 'tiff loader'. I loaded that tiff file as texture and performed a similar edit on it. Contrast and saturation. Result is similar to Photopea with banding in the sky.

However, when I export that very same tiff file as EXR from Davinci and use the exr file in that minimal three.js app and load a texture using the EXR loader from three, and perform the same edit, I get a clean result. So the issue is not due to browser's limitations, but rather probably in the way utif.js treats the tiff file.

Reading through utif.js readme I see this: TIFF files may have various number of channels and various color depth. The interpretation of data depends on many tags (see the TIFF 6 specification). The following function converts any TIFF image into a 8-bit RGBA image. Did I read this wrong or does utif.js always convert the tiff file into 8bit?

You wouldn't notice this usually on a "normal" file but since this file has RWG color space which is HUGE and log3g10 gamma, 8-bit file just can't withstand the manipulation without "breaking".

Thanks!

Goran

photopea commented 1 year ago

Hi Goran,

Photopea can represent only 8-bit images at the moment. If you load a 16-bit image, a 10-bit image, or a 1-bit image, it is always converted into RGB, 8 bits per channel sample. So half of information is thrown away in your case.

UTIF.js can decode the original data of a TIFF file (e.g. 2-bit RGB image - 6 bits per pixel, a 16-bit Gray+Alpha image - 32 bits per pixel, etc.). However, if you use UTIF.toRGBA8(), it converts the current image into a 8-bit RGBA image (32 bits per pixel).

You need to process your original 16-bit data before displaying it on a monitor (i.e. converting to 8-bit RGB). Photopea can not do it at the moment.

photopea commented 1 year ago

Does your TIFF contain an ICC color profile? I can not see any. Maybe I could make Photopea convert the color data into sRGB, so that you can see the correct colors.

lutifyme commented 1 year ago

Thanks!

lutifyme commented 1 year ago

The file doesn't contain ICC profile. Davinci exports images as untagged RGB. I think the right thing to do would be to allow for decoding of the original data and have a choice to use that or the result of UTIF.toRGBA8(). That way one could handle conversion into 8-bit RGB independently of utif.js and use utif.js as "pure" tiff decoder.