Allow import/export of images in AV1 Image File Format (AVIF)

In the future we hope to see heif and avif support.” (quote from https://docs.krita.org/en/reference_manual/hdr_display.html)

HEIF-HEIC support is available in krita already, but AVIF support is missing. I suggest to add AVIF support too.

I was able to open AVIF pictures with custom build of krita. It was necessary to modify 3 files in plugins/impex/qimageio/

krita_qimageio.desktop
add image/avif; to MimeType= list

krita_qimageio_export.json
add ,image/avif to X-KDE-Export list and
add ,avif to X-KDE-Extensions list.

krita_qimageio_import.json
add ,image/avif to X-KDE-Import list and
add ,avif to X-KDE-Extensions list.

I have a Qt Image Plugin with AVIF support installed. I published sources and step-by-step installation manual here:
http://188.121.162.14/avif/kde.html

If you don’t want to open/save AVIF pictures via external Qt plug-in and you prefer to include AVIF encoding/decoding code to krita directly, please let me know. Majority of the plug-in code can be reused.

2 Likes

Do you want to propose this as a patch? I was going to integrate it into my aur builds of Krita just to try out and was wondering your plans on it. It wouldn’t be merged until the upstream avif plugin is merged into Qt proper but having a merge open on invent with patches available would be nice for packagers in the meantime.

I think fixed internal list of supported image formats it not a perfect solution.
I think it would be better to use
QImageReader::supportedImageFormats()
and dynamically detect what image formats are available.
It would automatically add support for other image formats too.

That is how pretty much all other KDE software does it, is there an open issue or merge request in place to fix it?

I am not aware of open issues or merge requests.
There are multiple ways how to support AVIF in krita.

  1. My Qt plug-in
  2. Add code using libavif directly
  3. require new libheif v1.7.0 - added support for AVIF too,
    and update files under plugins/impex/heif

I would like to hear opinion of krita developers what they think is the best.

We would prefer to go via libheif, as that gives us more control over what Krita can export and we’re sure we can build it cross-platform. The main reason it hasn’t been done is basically that we haven’t had the time, being instead focused on the resource rewrite, bug-fixing, and some small done-in-a-week-or-two features.

Patches are indeed welcome, please come to #krita on freenode if you have technical questions, we’re happy to answer them.

Seems libavif is still in a “work in progress” state, but not sure what exactly that means.
The AVIF support in libheif is also just a few days old…so don’t consider this my ultimate opinion on this.

In any case, the qimagio plugins only support few generic options, that’s not too great for exporting artwork. Peeking at the avif plugin code, it seems to switch from 4:2:2 chroma subsampling to 4:4:4 at some odd quality level, it would be nice if those things can be set separately, like you can with the JPEG exporter.

So extending the HEIF exporter with the new libheif seems like the most logical option to me too.

To be honest, I wasn’t aware that HEVC/HEIC already supported 4:4:4 chroma sampling (and that the krita exporter uses that), after the disappointment of WebP I gave up on these hyped JPEG replacements based on video codecs for high quality results.

libavif “work in progress” means that the development is very active. There was a breaking change between 0.5.x and 0.6.x, there will be another breaking change between 0.7.x and future 0.8.x probably.
You can open image sequences/animations via libavif, you can’t save them yet. What is implemented, works perfectly. Google is using libavif in development Chrome.
Qt plug-ins in general are limited by existing Qt interface. You can set quality (typically 0-100 range). For highest quality I set YUV444 pixel format, for high I set YUV422, for medium and low quality YUV420 to achieve high compression. The plug-in reads the 10bit and 12bit AVIF images too. Output is 8bit per channel for compatibility reasons with some apps now. I am going to provide output without 8bit downgrade in the near future.
I understand that opening AVIF via existing libheif code is easy. It seems the AVIF support will be limited to 8bit as libheif release info indicate: Support for reading and writing AVIF (8 bit) images through libaom has been added. Future libheif releases will probably add 10/12 bit support too.
libavif and new libheif have one thing in common. Both of them use libaom to encode/decode AV1 data stream (libavif can optionally use other AV1 decoders/encoders instead).
libaom is a common dependency. libavif recommends to use libaom 2.0.0, because it is much faster than old 1.0.0 from 2018. v2.0.0 fixed bug with 10/12bit encoding at fastest real-time speed settings. Unfortunately lot of distros are slow to upgrade, they keep the old libaom 1.0.0 only.

To change the impex/heif plugin to allow AVIF is not complicated.
However when I started to use libheif and compared the behavior with libavif I encountered some important (from my point of view) issues. I reported them to libheif project and some of them are resolved already.
Prior working on the patch I would suggest to wait till all of them are resolved.

@wolthera
Perhaps you know, the Qt AVIF plug-in was added to kimageformats
Using it via plugins/impex/qimageio is trivial.

Meanwhile the libheif got improved too, lot of issues were resolved and there are new releases.

Please let me know if you still wish to use the AVIF format via plugins/impex/heif ?

If the plugins/impex/heif is the only way to add AVIF in krita, I would update the heif plugin. In this case I just need to require newer libheif.
Right now you require old find_package(HEIF "1.3.0"), recent version is 1.10.

There is a branch implementing AVIF support with upgraded libheif, but it’s currently stuck on an unresolved upstream issue:

I didn’t know about the branch.

It is matter of fact, that it is necessary to use few function from C API to obtain the ICC or NCLX color profile.

First, obtain heif_image_handle* ImageHandle::get_raw_image_handle()

then you can call heif_image_handle_get_color_profile_type
and in case of ICC heif_image_handle_get_raw_color_profile_size heif_image_handle_get_raw_color_profile

and in case of NCLX heif_image_handle_get_nclx_color_profile

Some example code how to get LCMS profile from the NCLX is https://gitlab.gnome.org/GNOME/gimp/-/blob/master/plug-ins/common/file-heif.c#L639 Note: PQ and HLG curves are not yet implemented there.

Yes, I saw the implementation in GIMP, what is tricky however is that our color profiles are kind of unique in that they’re a thing we load that isn’t a resource, so they need to be created in a certain place. I need to talk to halla and dmitry before I dare to do anything there as I’d be worried about memory-leaks and other unexpected loading issues… But we’re first going to need to finish the Resource Rewrite.

Hello,
I saw that Krita_Nightly_Windows_Dependency_Build builds libheif without AVIF support. Is the current state planned/expected and the AVIF will be enabled later?

08:25:31  CMake Warning at ext_heif/CMakeLists.txt:120 (message):
08:25:31    Meson Build system was not found, see https://mesonbuild.com
08:25:31  
08:25:31  
08:25:31  CMake Warning at ext_heif/CMakeLists.txt:123 (message):
08:25:31    Ninja Build system was not found, see https://ninja-build.org/
08:25:31  
08:25:31  
08:25:31  CMake Warning at ext_heif/CMakeLists.txt:126 (message):
08:25:31    Rust compiler was not found, see https://www.rust-lang.org/
08:25:31  
08:25:31  
08:25:31  CMake Warning at ext_heif/CMakeLists.txt:128 (message):
08:25:31    Disabling AVIF support.


09:57:34  -- Could NOT find DAV1D (missing: DAV1D_INCLUDE_DIR DAV1D_LIBRARIES) 
09:57:34  HEIF decoder, libde265: found
09:57:34  HEIF encoder, x265: found
09:57:34  AVIF encoder, aom: not found
09:57:34  AVIF decoder, aom: not found
09:57:34  AVIF encoder, rav1e: not found
09:57:34  AVIF decoder, dav1d: not found

Afaik, the main issue is that we’re having issues with the version string of cargo. We’re also working on a MSVC build, which also requires some specifics. We’ll need to sort these out first, I think.

There’s no active objections against building libheif for windows, except that libaom requires perl afaik, so hence us trying to get rav1e to work.