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

Lossless avif worse than a bmp in a zip file #2434

Open
uriesk opened this issue Sep 19, 2024 · 7 comments
Open

Lossless avif worse than a bmp in a zip file #2434

uriesk opened this issue Sep 19, 2024 · 7 comments

Comments

@uriesk
Copy link

uriesk commented Sep 19, 2024

I noticed that lossless libavif gets beaten by PNGs and regularly even by BMPs inside a zip file.

Like here is a screenshot of this repository, once as BMP in a ZIP file, and once as AVIF.
Everything with default settings, only the lossless switch on avifenc.
The zipped BMP has 406 kB, the AVIF has 412 kB.
libavif.bmp.zip
libavif.avif.zip

(Note that the only reason why i zipped the AVIF as well, is because github doesn't allow AVIF upload. You have to extract it.)

Meanwhile both WEBP and JXL get the file down to below 250 kB in lossless mode. So i don't think that this is intentional.

@vrabaud
Copy link
Collaborator

vrabaud commented Sep 19, 2024

Hi, thx for the report. AVIF lossless is lossy with not quantization which makes it work great for photos but not for artificial content, where other algorithms perform better. Still, using the default arguments with libaom as an encoder, I get:

avifenc -q 100 /tmp/test.png /tmp/tmp
Successfully loaded: /tmp/test.png
Quality set to 100, assuming --lossless to enable warnings on potential lossless issues.
WARNING: [--lossless] Input data was RGB and matrixCoefficients isn't set to identity (--cicp x/x/0); Output might not be lossless.
AVIF to be written: (Lossy)
 * Resolution     : 1363x1512
 * Bit Depth      : 8
 * Format         : YUV444
 * Alpha          : Not premultiplied
 * Range          : Full
 * Color Primaries: 1
 * Transfer Char. : 2
 * Matrix Coeffs. : 6
 * ICC Profile    : Absent
 * XMP Metadata   : Absent
 * Exif Metadata  : Absent
 * Transformations: None
 * Progressive    : Unavailable
Encoding with codec 'aom' speed [6], color quality [100 (Lossless)], alpha quality [100 (Lossless)], tileRowsLog2 [0], tileColsLog2 [0], 72 worker thread(s), please wait...

Encoded successfully.
 * Color total size: 335309 bytes
 * Alpha total size: 0 bytes
Wrote AVIF: /tmp/tmp

335kB is not the 412kB you mention. Which command line did you use? You can also change the speed: ./avifenc -q 100 -s 0 /tmp/test.png /tmp/tmp does give 250kB like the other codecs.
I did not use -l, which is invalid. Even -s 0 only gives 308 kB

You can also push WebP to get an even lower size:

cwebp -lossless -m 6 -q 100 /tmp/test.png
File:      /tmp/test.png
Dimension: 1363 x 1512
Output:    204782 bytes (0.79 bpp)
Lossless-ARGB compressed size: 204782 bytes
  * Header size: 1996 bytes, image data size: 202760
  * Lossless features used: SUBTRACT-GREEN
  * Precision Bits: histogram=5 cache=10

@uriesk
Copy link
Author

uriesk commented Sep 19, 2024

Hello, i used
avifenc --lossless input.png output.avif
and avifenc --version gives me

Version: 1.0.4 (dav1d [dec]:1.4.3, aom [enc/dec]:v3.9.0, rav1e [enc]:0.7.1 (UNKNOWN), svt [enc]:v2.1.0)
libyuv : unavailable

What i noticed is that the larger the image is, the more likely lossless avif is to beat zipped bmp files. This one has 1363x1512, which is on the larger end already. I made a screenshot of your reply and tested it with that.

time { magick post.png post.bmp; zip post.bmp.zip post.bmp; }
takes 0.141s and produces a post.bmp.zip with 235 kB

time avifenc --lossless post.png post.avif
takes 8.527s and produces a post.avif with 291 kB

time avifenc -q 100 -s 0 post.png post.avif
takes 1m18.503s and produces a post.avif with 202 kB

While it is nice that the -s 0 produces a smaller output than a bitmap in a zip file, over 1 min of encoding is quite a lot. In comparison:

time cjxl -q 100 post.png post.jxl
takes 0m4,305s and produces a post.jxl with 177 kB, so it's even beating the -s 0 avif by over 14% while encoding 16 times faster.

I attached all the files here:
aviftest.zip

@uriesk
Copy link
Author

uriesk commented Sep 19, 2024

which makes it work great for photos but not for artificial content

To test this one, i downloaded the current bing.com wallpaper and converted it to png, which outputed a 3.8 MB PNG file.
I converted it to a zipped bmp file and it has 4.8 MB.
I converted it to a lossless AVIF and it has 4.4 MB.

While lossless avif is 10% more effective than zipping a bmp file in this case, it is also 16% larger than the PNG file.
There seems to be something wrong with lossless avif. If that is by design, then this is a bit sad, since webp has a great lossless mode.

Here the files of this test:
aviftest2.zip

@vrabaud
Copy link
Collaborator

vrabaud commented Sep 19, 2024

You are right, in a way, it is by design because there is no specific path for lossless. E.g., WebP lossless is totally different from lossy.

At least, the last photo you sent can be compressed to 2.9 M using -s 0, which is closer to the 2.6M from WebP.

@y-guyon
Copy link
Collaborator

y-guyon commented Sep 20, 2024

@uriesk May I know why -q 100 is necessary? Could -q 90 or another high quality value be enough visually for your use case?

@uriesk
Copy link
Author

uriesk commented Sep 20, 2024

@y-guyon
Generational loss. Most images on the web are PNGs. If we would want them to be lossy, we wouldn't use PNG.
https://w3techs.com/technologies/overview/image_format

@y-guyon
Copy link
Collaborator

y-guyon commented Sep 23, 2024

Generational loss.

Did you encounter issues due to repeated -q 90 AVIF encodes of the same asset?
In my experience the file size savings of lossy even at very high quality far outweigh the risk of seeing any degradation due to generational loss, because either:

  • You are recompressing the asset yourself, then you likely have access to the original asset;
  • Someone else is recompressing the asset. You have no control on how they do it and it often ends with medium quality JPEG, which degrades the image way more than tens of high-quality encodes.

Could you share the details of your use case?

Most images on the web are PNGs. https://w3techs.com/technologies/overview/image_format

The graph you linked says "PNG is used by 80.6% of all the websites", not "80.6% of images are PNGs".

JPEG's market share is around 10% higher than PNG:
https://almanac.httparchive.org/en/2022/media#format-adoption
I expect the gap to be even greater if the market share was weighted by pixel count, meaning PNGs are likely tiny images or contain content that compresses better with PNG than with JPEG.

If we would want them to be lossy, we wouldn't use PNG.

In some cases PNG is used for its translucency support, not for its lossless compression capabilities.
If it was only about lossless compression and file size, we would see a lot more of WebP or SVG files.
In my experience, WebP always leads to smaller sizes than PNG for the same losslessly compressed content.

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

No branches or pull requests

4 participants
@vrabaud @uriesk @y-guyon and others