photopea / UTIF.js

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

toRGBAx #88

Closed thany closed 4 years ago

thany commented 4 years ago

Can we please have a toRGBAx in addition to toRGBA8?

This would return pixel data using an arbitrary amount of bits per channel. We would have to pass how many bits per channel we need returned. The function could also have to return how many bits the pixels consist of, if number of bits is not passed. It's very common for RAW-ish images to have been saved with 12 or 14 or more bits per channel.

This would be helpful for images that are saved with more than 8 bits per channel, and even more helpful for HDR images where the pixels are saved with 16/32-bits floating point values.

Javascript (or indeed typescript) doesn't care how many bits a number uses. A number is a number. So the datatype returned by this function can be identical to toRGBA8, just with possibly different values.

photopea commented 4 years ago

If you need to work with RAW images, there is usually just one number per pixel (red, green or blue), but never all three (RGB).

You would have to do demosaicing. I think RAW processing should not be a part of UTIF.js, as it would make the library 4x larger.

You can implement toRGBAx() yourself, by reading the TIFF tags and the decompressed binary data in the "data" parameter.

thany commented 4 years ago

I didn't mean to use this feature for RAW processing. Just saying that DNG can contain more than 8bpc, whereever said DNG comes from. Be it a RAW from a camera/scanner, or someone converting a PNG48 to DNG, or someone just being clever with Photoshop.

photopea commented 4 years ago

You should access the "data" property in such cases. Also, often, it is not clear how to convert e.g. 14 bits to 16. Are we supposed to ad two zeros or two ones?

E.g. converting 4 bits to 8 is clear, as you multiply it by 17 and get integers between 0 and 255.

As I said, toRGBAx() makes no sense for DNG. DNG contains just one sample per pixel (e.g. red) and it is not clear what should be the other three numbers (for green, blue, alpha).

thany commented 4 years ago

Also, often, it is not clear how to convert e.g. 14 bits to 16. Are we supposed to ad two zeros or two ones?

You provide your own answer. This is always a beautiful thing to happen, don't you think? Here it is:

E.g. converting 4 bits to 8 is clear, as you multiply it by 17 and get integers between 0 and 255.

There's your answer.

There's no difference between upscaling 4 to 8 bits, and upscaling 14 to 16. The former can be done by >> 4, the latter by >> 2. There's really nothing much more than that.

As I said, toRGBAx() makes no sense for DNG. DNG contains just one sample per pixel (e.g. red) and it is not clear what should be the other three numbers (for green, blue, alpha).

What are you on about? It seems like you say DNG only contains red. I'm pretty sure DNG can contain colours, and indeed samples for other colour channels? 🤔

Apparently you have no problems including an arbitrary conversion to 8 bits, but to any other pixel format, that's a no go for you? I don't quite understand your thought process. But it's okay, I'll do it myself. That's probably less work than trying to convince you. No offense.

photopea commented 4 years ago

I believe you are confusing the bit shift to the left and right: >> and << .

If we convert 14 bits to 16 by adding two zeros, I think that is not what most of people expect, because the maximum - the value with sixteen ones (0xffff) would be unreachable. If we scale it proportionally and then rounded to integers, it would mean losing quality.

In raw photography, every pixel contain just one value. Half of pixels contain values for green, a quarter contain values for red, and another quarter contain values for blue . See the bayer filter: https://en.wikipedia.org/wiki/Bayer_filter

thany commented 4 years ago

You don't need rounding. If you shift by 2 bits (essentially multiplying by 4), you will never end up with non-integer values 😃

And yes, you're right, I meant the << shift-left.

If we convert 14 bits to 16 by adding two zeros, I think that is not what most of people expect

If you convert 4 to 8 bits, you are also "adding 4 zeros", so I don't see the difference.

the value with sixteen ones (0xffff) would be unreachable

Is that an issue then?

photopea commented 4 years ago

No, when converting 4 bits to 8 bits, I do not add four zeros. I multiply it by 17 (instead of 16) - as I said above. The number "1111" is converted to "11111111" (15 to 255). The minimum and maximum values for 4 bits are converted to minimum and maximum values for 8 bits.

I tihnk it is a problem, when a maximum value for 14 bits is not converted to a maximum value for 16 bits. If we added "11" instead of "00", there would be a problem with a value zero, which would not be a zero anymore.

wshart commented 3 years ago

@photopea Would it be more reasonable to make a version of the toRGBAx where x is 16 or 32?

I have to work with a lot of 16 and 32-bit microscopy TIFFs that really benefit from the extra precision.

I'd just hash it together myself, but it's a bit beyond me!

photopea commented 3 years ago

@wshart In that case, I think you should be able to read the "data" parameter directly, which will contain the data that you need.