strukturag / libheif

libheif is an HEIF and AVIF file format decoder and encoder.
Other
1.74k stars 301 forks source link

Fuji X-T5 HEIF Files - Slow export to PNG #862

Closed etrigan63 closed 1 year ago

etrigan63 commented 1 year ago

I am working with an HEIF based workflow using files captured by my Fuji X-T5. The images open fine in darktable and digikam 8 but exporting to a compressed PNG file is very slow, The Fuji X0T5 produces 40Mpx images normally and it takes over 30 seconds to save the image as a PNG. My machine is no slouch (Ryzen 5950 (16c-32t) + 64GB RAM + Radeon 6750XT) and storage is very fast. darktable exports the file and the dialog box goes away after a few seconds, file keeps growing for up to 30s. Exporting to JPG only takes a second to two. IMG-20230508-0056.hif.zip I have attached a sample HEIF image for you to test with.

silverbacknet commented 1 year ago

Why post here if the heif loads fine and the problem is the way darktable exports it to PNG? But regardless, you're going to be horribly hamstrung by the fact that libpng is single-threaded and unoptimized, plus barely gains you anything on real camera images; consider another lossless format that can actually use multithreading, like jpegxl.

There are other much faster png libraries they could switch to, like mtpng, but they're not a drop-in replacement.

etrigan63 commented 1 year ago

Why post here if the heif loads fine and the problem is the way darktable exports it to PNG? But regardless, you're going to be horribly hamstrung by the fact that libpng is single-threaded and unoptimized, plus barely gains you anything on real camera images; consider another lossless format that can actually use multithreading, like jpegxl.

There are other much faster png libraries they could switch to, like mtpng, but they're not a drop-in replacement.

Because I have exported from RAW to PNG and not encountered this delay. Why would the PNG library be fast with RAW and slow with HEIF? Ergo, the issue must be with libheif. I am also not familiar with the "behind the scenes" operation of these applications. I am a user, not a developer and such knowledge is not common in the user space.

bradh commented 1 year ago

Why post here if the heif loads fine and the problem is the way darktable exports it to PNG? But regardless, you're going to be horribly hamstrung by the fact that libpng is single-threaded and unoptimized, plus barely gains you anything on real camera images; consider another lossless format that can actually use multithreading, like jpegxl. There are other much faster png libraries they could switch to, like mtpng, but they're not a drop-in replacement.

Because I have exported from RAW to PNG and not encountered this delay. Why would the PNG library be fast with RAW and slow with HEIF? Ergo, the issue must be with libheif. I am also not familiar with the "behind the scenes" operation of these applications. I am a user, not a developer and such knowledge is not common in the user space.

Didn't you say export to JPG is fast? So why assume it is the input reader?

I did check the input file, and it is definitely slower converting to PNG than JPEG or Y4M (perhaps an order of magnitude slower).

So what you really have is a mismatch between the input you are providing and the output you are asking for. It needs a lot of conversion work, and that takes time.

I don't think the real issue is in libheif though (since converting to JPEG is fast, right), and if darktable is slower than you'd like, perhaps that is the place to file the bug.

farindk commented 1 year ago

The slow part is libpng or, to be more specific, zlib. One can control the compression speed of zlib with png_set_compression_level(). I have added an option to heif-convert to set this parameter (--png-compression-level). With this, I can get everything from 7 seconds (fastest setting) to 4 minutes (slowest settings). The default was around 40 seconds. It is clear that the PNG file size grows when you set it to faster values.

@etrigan63 When you report this to darktable, you can propose that they add a similar option to set png_set_compression_level(). Maybe there already is. I haven't checked.

bradh commented 1 year ago

Does that change also address #704?

farindk commented 1 year ago

@bradh Right. Both can be closed.

kmilos commented 1 year ago

Incidentally, don't know if libpng can take advantage of libdeflate instead, it is several times faster than zlib: https://aras-p.info/blog/2021/08/09/EXR-libdeflate-is-great/

And yes, darktable already lets you change the zlib compression level parameter for PNGs (the default is 5).

@etrigan63 Have you tried exporting to lossless TIFF w/ predictor from darktable instead? You'll get very similar compression ratio to PNG, but should be faster as it uses libdeflate.

farindk commented 1 year ago

libpng cannot use libdeflate because the API is different. Unfortunately, it's not a simple drop-in replacement like libjpeg/libjpeg-turbo: https://github.com/glennrp/libpng/issues/205

Another option of optimization would be to parallelize it like pigz does: https://zlib.net/pigz/ But that has to be done within libpng.

kmilos commented 1 year ago

Well, at least it's on the radar. Thanks.

etrigan63 commented 1 year ago

@etrigan63 Have you tried exporting to lossless TIFF w/ predictor from darktable instead? You'll get very similar compression ratio to PNG, but should be faster as it uses libdeflate.

Yes, the TIFF export is very quick and I will use that for the time being. I will experiment with the compression levels there as well.