Skip to content
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

HEIC: Unsupported feature: Unsupported color conversion #102

Open
cvdsoftware opened this issue Nov 17, 2022 · 3 comments
Open

HEIC: Unsupported feature: Unsupported color conversion #102

cvdsoftware opened this issue Nov 17, 2022 · 3 comments

Comments

@cvdsoftware
Copy link

I'm trying to process a heic file, but I got the following exception (using latest version):

System.InvalidOperationException
  HResult=0x80131509
  Message=Unsupported feature: Unsupported color conversion
  Source=PhotoSauce.NativeCodecs.Libheif
  StackTrace:
   at PhotoSauce.NativeCodecs.Libheif.HeifResult.Check(heif_error err)
   at PhotoSauce.NativeCodecs.Libheif.HeifContainer.HeifPixelSource.decodeImage()
   at PhotoSauce.NativeCodecs.Libheif.HeifContainer.HeifPixelSource.CopyPixelsInternal(PixelArea& prc, Int32 cbStride, Int32 cbBufferSize, Byte* pbBuffer)
   at PhotoSauce.MagicScaler.Transforms.ConversionTransform.copyPixelsDirect(PixelArea& prc, Int32 cbStride, Byte* pbBuffer)
   at PhotoSauce.MagicScaler.PixelSource.CopyPixels(PixelArea& prc, Int32 cbStride, Int32 cbBufferSize, Byte* pbBuffer)
   at PhotoSauce.Interop.Wic.IWICBitmapSourceImpl.copyPixels(IWICBitmapSource* pinst, WICRect* prc, UInt32 cbStride, UInt32 cbBufferSize, Byte* pbBuffer)
   at TerraFX.Interop.Windows.IWICBitmapFrameEncode.WriteSource(IWICBitmapSource* pIBitmapSource, WICRect* prc)
   at PhotoSauce.MagicScaler.WicImageEncoder.writeSource(IWICBitmapFrameEncode* frame, PixelSource src, PixelArea area)
   at PhotoSauce.MagicScaler.WicImageEncoder.WriteFrame(IPixelSource source, IMetadataSource meta, Rectangle area)
   at PhotoSauce.MagicScaler.MagicImageProcessor.WriteOutput(PipelineContext ctx, Stream ostm)
   at PhotoSauce.MagicScaler.MagicImageProcessor.ProcessImage(String imgPath, String outPath, ProcessImageSettings settings)
   at xxx

File properties:
image
image
image

Windows Photos can show the file.

Unfortunately I can't share the file, can I send it privately to you?

@saucecontrol
Copy link
Owner

saucecontrol commented Nov 17, 2022

Yep, you can email it to me directly.

I expect if the Windows decoder can handle it, libheif should be able to. There were changes to the way it does conversions in the last few versions, and I don't have a ton of test images.

@saucecontrol
Copy link
Owner

Received the sample image by email, thanks.

The error is coming back from libheif, although I don't see immediately why it's unable to do the conversion. Ultimately this issue comes down to a change that libheif made around v1.7.0 when they added support for AVIF. Rather than allowing you to retrieve the raw YCbCr planar data that comes from the underlying video decoder along with enough information to correctly convert it, they decided to do the conversion internally.

The result of that change was that if you ask for YCbCr from the decoder, it double converts YcbCr->RGB->YCbCr. That is, of course, much slower (strukturag/libheif#472) and, up until v1.12.0, resulted in incorrect colors due to a math error in the RGB->YCbCr side of the conversion (strukturag/libheif#313).

The Windows HEIF codec (msheif_store.dll) doesn't share the same behavior/bugs, but it's worth noting it doesn't decode the sample correctly either -- there's a bright green line at the top of the result, indicating some kind of issue with interpretation of the chroma data. It could be that the image itself is broken in some way, or it could be a separate bug in the WIC decoder.

To sum up, it's likely I could handle that image at least as well as Windows if I could get the YCbCr data out from libheif, but it's attempting to force a conversion to RGB that it can't do, so I'm stuck.

My longer term plan is replace libheif with my own container parser that invokes the video frame decoders (libde265 and dav1d) directly, but I'm putting priority on other areas for the time being. I'll mark this as an external issue for now.

@saucecontrol
Copy link
Owner

Just leaving a few notes here for myself after looking at this in more detail...

Looks like the issue here is actually that the image has multiple frames (YUV420 Main + Y RangeExtension). iOS interprets the second frame as an alpha mask and outputs an image with a transparent border, while the WIC decoder ignores the second frame entirely. libheif returns the "Unsupported color conversion" error whether the requested format is RGB or RGBA -- it's unclear whether there is some combination of parameters that will actually allow decode.

The apparent chroma artifacts at the image top would seem to be unrelated to the issue. They show up in both the WIC and iOS decoded frames, but the container and both frame bitstreams pass all validation tests I've run on them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants