AOMediaCodec / libavif

libavif - Library for encoding and decoding .avif files
Other
1.45k stars 190 forks source link

avifenc from 0.9.0 doesn't encode image correctly (at least MIME type isn't detected correctly) #569

Closed Thermi closed 3 years ago

Thermi commented 3 years ago

Hi,

avifenc from libavif version 0.9.0 doesn't encode a PNG picture into an AV1F picture correctly. At the very least, it prevents the MIME type from being correctly detected by file: av1f test picture from https://libre-software.net/avif-test/#avif_test

$ file 'AVIF Test picture (JPEG converted to AVIF with Convertio).avif' 
AVIF Test picture (JPEG converted to AVIF with Convertio).avif: ISO Media, HEIF Image

Converted picture using avifenc with default settings:

$ file test-picture.avif
test-picture.avif: ISO Media

The picture also can't be opened with ristretto from xfce4 (https://gitlab.xfce.org/apps/ristretto/-/issues/56#note_28997). ristretto uses gdk-pixbuf to load the picture. As mentioned before, the test picture fronm libre-software.net works fine, but a picture generated with avifenc does not.

joedrago commented 3 years ago

Is this new to 0.9.0, or is this the only avifenc you've tried? Can you supply the faulty output AVIF in this bug (or make one that you can share)? I won't pretend that libavif is perfect/bug-free, but seeing as gdk-pixbuf is just libavif underneath too, I'd be surprised if a newer output couldn't be read by an older reader.

In addition to the image you're having issues with, can you supply the following:

Thermi commented 3 years ago

I only tried avifenc from 0.9.0. Here's an AVIF that doesn't get opened correctly. Fry_Looking_Squint.avif.zip Here's the original jpeg: Fry_Looking_Squint.jpg

I found something out. ristretto uses the heif pixbufloader when opening the test image:

$ ps aux  | grep ristretto
thermi   1041900  0.0  0.1 441484 60700 ?        Sl   04:18   0:00 ristretto /home/thermi/Downloads/AVIF Test picture (JPEG converted to AVIF with Convertio).avif
$ cat /proc/1041900/maps | grep pix
7fb8143c8000-7fb8143c9000 r--p 00000000 fe:00 1613713280                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
7fb8143c9000-7fb8143ca000 r-xp 00001000 fe:00 1613713280                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
7fb8143ca000-7fb8143cb000 r--p 00002000 fe:00 1613713280                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
7fb8143cb000-7fb8143cc000 r--p 00002000 fe:00 1613713280                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
7fb8143cc000-7fb8143cd000 rw-p 00003000 fe:00 1613713280                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
7fb814e08000-7fb814e09000 r--p 00000000 fe:00 1613771669                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-heif.so
7fb814e09000-7fb814e0a000 r-xp 00001000 fe:00 1613771669                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-heif.so
7fb814e0a000-7fb814e0b000 r--p 00002000 fe:00 1613771669                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-heif.so
7fb814e0b000-7fb814e0c000 r--p 00002000 fe:00 1613771669                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-heif.so
7fb814e0c000-7fb814e0d000 rw-p 00003000 fe:00 1613771669                 /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-heif.so
7fb8156d5000-7fb8156db000 r--p 00000000 fe:00 1618848318                 /usr/share/locale/de/LC_MESSAGES/gdk-pixbuf.mo
7fb819424000-7fb81942f000 r--p 00000000 fe:00 540381124                  /usr/lib/libpixman-1.so.0.40.0
7fb81942f000-7fb8194b1000 r-xp 0000b000 fe:00 540381124                  /usr/lib/libpixman-1.so.0.40.0
7fb8194b1000-7fb8194c3000 r--p 0008d000 fe:00 540381124                  /usr/lib/libpixman-1.so.0.40.0
7fb8194c3000-7fb8194cb000 r--p 0009e000 fe:00 540381124                  /usr/lib/libpixman-1.so.0.40.0
7fb8194cb000-7fb8194cc000 rw-p 000a6000 fe:00 540381124                  /usr/lib/libpixman-1.so.0.40.0
7fb81a2ad000-7fb81a2b6000 r--p 00000000 fe:00 544745156                  /usr/lib/libgdk_pixbuf-2.0.so.0.4200.4
7fb81a2b6000-7fb81a2df000 r-xp 00009000 fe:00 544745156                  /usr/lib/libgdk_pixbuf-2.0.so.0.4200.4
7fb81a2df000-7fb81a2f0000 r--p 00032000 fe:00 544745156                  /usr/lib/libgdk_pixbuf-2.0.so.0.4200.4
7fb81a2f0000-7fb81a2f2000 r--p 00042000 fe:00 544745156                  /usr/lib/libgdk_pixbuf-2.0.so.0.4200.4
7fb81a2f2000-7fb81a2f3000 rw-p 00044000 fe:00 544745156                  /usr/lib/libgdk_pixbuf-2.0.so.0.4200.4

A file encoded using heif-enc loads fine:

$ heif-enc Fry_Looking_Squint.jpg 
$ heif-info Fry_Looking_Squint.heic 
MIME type: image/heic
main brand: heic
compatible brands: mif1, heic

image: 240x240 (id=1), primary
  color profile: no
  alpha channel: no
  depth channel: no
$ ristretto Fry_Looking_Squint.heic 

That's what it says about a test image that doesn't load:

$ heif-info Fry_Looking_Squint.avif
MIME type: image/avif
main brand: avif
compatible brands: avif, mif1, miaf, MA1A

image: 240x240 (id=1), primary
  color profile: nclx
  alpha channel: no
  depth channel: no

The pixbufloader for av1f is installed though:

$ pacman -Ql libavif
[...]
libavif /usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-avif.so

This is now not necessarily an issue for libavif, but rather a disassembly of the whole problem that probably pertains the whole of Arch Linux, at the very least, because libheif is pulled in as dependency by gd and gimp:

$ LANG=C sudo pacman -R libheif
checking dependencies...
error: failed to prepare transaction (could not satisfy dependencies)
:: removing libheif breaks dependency 'libheif' required by gd
:: removing libheif breaks dependency 'libheif' required by gimp
joedrago commented 3 years ago

Hmm. I can verify that the file you supplied is a perfectly reasonable AVIF, and can be decoded both with older avifdec (v0.8.4) and with retail Chrome (which uses a very recent libavif SHA). Our interop with libheif is actually pretty good, honestly, so I'm surprised at this one. The libheif folks certainly know what they're doing.

Is it possible that the heif pixbuf module is getting a first shot at it and claiming it, only for it to not actually have AVIF support properly enabled at a lower level? I believe libheif has to opt into AVIF support, but I'm not sure.

I don't mean to send you on a wilder goose chase than you're already on, but if you're starting with a pretty reasonable/friendly AVIF and not actually invoking libavif to decode, I'm not sure how I can help. Perhaps ping the libheif folks?

If you want to play a bit more with some local files and see if we can guess what the issue is, perhaps see what limitations the heif pixbuf module demands on the AVIFs it reads. Possible offenders could be YUV subsampling and color range. For example:

avifenc --yuv 420 --range limited src.png out.avif

If that file can be read, try without the --yuv 420 part, and then try without the --range limited part. It is possible that the heif pixbuf module is an imcomplete implementation and will only tolerate a subset of legal AVIFs. Let me know!

Thermi commented 3 years ago

I progressed thus far that even building with libheif without pixbuf support, gdk-pixbuf2 does not continue trying the libavif pixbuf loader, so that doesn't work either for some reason.

The image converted with the subset isn't displayed, exactly like the one conveted with the full set.

joedrago commented 3 years ago

Perhaps @novomesk or @linkmauve have some ideas for helping debug gdk-pixbuf?

novomesk commented 3 years ago

New file package is needed, AVIF detection was added in December: https://github.com/file/file/commit/08007ef85fd239f4ffe355e683c890a63dbf56d6

The detection works afterwards:

file Fry_Looking_Squint.avif
Fry_Looking_Squint.avif: ISO Media, AVIF Image

AVIF Test picture (JPEG converted to AVIF with Convertio).avif has ftypmif1, that's why it was identified already as ISO Media, HEIF Image but AVIF created by libavif has ftypavif in the beginning.

After the upgrade, I am able to view the file with ristretto.

You can try other gdk-pixbuf based viewers, like gthumb or eog.

joedrago commented 3 years ago

Thanks for the info, @novomesk. I'm going to close this issue.

Thermi commented 3 years ago

Thank you, @novomesk. That did the trick!

Related to Arch, feature request is here: https://bugs.archlinux.org/task/70226