-
Notifications
You must be signed in to change notification settings - Fork 65
Decode HEIC with correct color space #731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Decode HEIC with correct color space #731
Conversation
Possibly closes: woelper#710 Instead of always decoding as RGBA, I manually convert the image from its real color space to RGBA. I'm not sure if this fixes the issue, but it seems like a good thing to do anyway.
3e3ef80 to
1cafbd3
Compare
|
Do you have samples of the broken images so I can test locally? This patch was a bit hard to figure out, so I'll have to fiddle with the code more till it works. 😅 I tested it with a few HEIC images but not a large range of them because I couldn't find too many samples. |
|
These photos are a friends and I discovered this issue while they were viewing them on my laptop. As they are not mine, I'll ask for permission to send some of the originals for this PR. Do you have a preferred method I would be able to send a few of these privately to you? |
|
To clarify, some HEIC images worked but those specific images failed? If we can figure out the format, I can probably fix it without needing the images. If not, you could probably just email them (I think my email is in the commit). For reference, I tested with these: https://heic.digital/samples/ |
|
I've emailed you some sample images, please feel free to let me know if you need more! I can also send you the raws if needed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is missing many cases that were previously handled internally by libheif.
It’s necessary to account for the following:
- 8/10 bit depth ( 12 bit depth HEIC's is possible but rare, AFAIK no opensource tools can encode 12 bit, so it's probably not required for HEIC's)
- YUV range changes
- YUV matrix changes
- GBR (identity matrix), which is technically YUV but slightly different and not especially rare.
- Monochrome is YUV 4:0:0 that should be handled appropriately
There are also YCgCo images sometimes but as far as I know they are not handled out of the box in libheif so it should not be broken.
This won't help with HDR curves because they are different thing.
| let buf = image::ImageBuffer::from_vec(width as u32, height as u32, res) | ||
| .context("Can't create HEIC/HEIF ImageBuffer with given res")?; | ||
| let i = DynamicImage::ImageRgba8(buf); | ||
| Some(ColorSpace::YCbCr(chroma)) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this branch is correct one.
It's missing:
- Checking the image bit depth, and handling or rejecting unsupported depths. Typically, libheif supports 8-bit and 10-bit for HEIC.
- Accounting that YUV range is subject to change.
- Accounting for the YUV matrix, which may vary. For HEIC, it is usually BT.709 rather than BT.601. But it's needed to be queried from libheif.
| let img = lib_heif.decode(&handle, ColorSpace::Undefined, None)?; | ||
|
|
||
| let i = match img.color_space() { | ||
| Some(ColorSpace::Rgb(chroma @ (RgbChroma::Rgb | RgbChroma::Rgba))) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libheif can use 10 and 12 bits as well, not only 8 bit images.
| let width = img.width(); | ||
| let height = img.height(); | ||
|
|
||
| let i = DynamicImage::ImageLuma8( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Monochrome used in HEIC is YUV image with only Y plane, so it's required to handle YUV range and YUV matrix as well and image also could be 10 bit.
|
@awxkee I recently realized that I didn't have to do any of this. @Stoppedpuma Yes, I got them and thank you! I have a slightly busy week, but I'll get back to work on this soon as I can. |
No worries, take your time! |
|
Typical flow to handle HDR image without gainmaps:
This is not actually as complicated as it may seems, but it does require some attention to details. |
|
Hmm, if this is dependent on the renderer then it may be best to wait until Oculante moves off Notan. |
I agree, there's a lot of things that we have to change with our move away from Notan (and even for updating Notan before we move away from it). |
Possibly closes: #710
Instead of always decoding as RGBA, I manually convert the image from its real color space to RGBA. I'm not sure if this fixes the issue, but it seems like a good thing to do anyway.
I still have to test this so it's a draft for now.