libjxl / libjxl

JPEG XL image format reference implementation
BSD 3-Clause "New" or "Revised" License
2.71k stars 260 forks source link

Gaborish filter regression #3458

Open yota-code opened 7 months ago

yota-code commented 7 months ago

Describe the bug

As noted by eddie.sato on this message https://discord.com/channels/794206087879852103/803645746661425173/1225342521014485103 The generation loss of the jxl exibit an issue which might be induced by a regression on the gaborish filter (encoding part, as stated by _wb_)

To Reproduce

Encode and decode the same image twice in a row

Expected behavior

The second encoding should insert a minimal distortion

Screenshots

genloss.webm

Environment

Additional context

cf. the dicussion following the post on discord:

_wb_ — Looks like jpegli zeroes AC quite quickly. And inv_gaborish(gaborish) should probably be made closer to the identity function. _wb_ — [...] the encoder side gaborish has been changed since then, I suspect causing a regression in terms of generation loss.

niutech commented 7 months ago

Realistically, who is going to save the same image in the same format 10+ times? If you are a photo retoucher, you use an intermediate format, such as PSD, PSB, KRA, XCF, TIFF.

yota-code commented 7 months ago

Indeed, the use case is useless but:

if the origin of the issue is a regression, everybody could benefit from correcting it

jonsneyers commented 7 months ago

Repeated recompression does occur in practice. Memes typically get shared in lossy formats, and can get recompressed dozens of times because:

When I look at some of the memes I encounter in the wild, they do exhibit the kind of artifacts corresponding to dozens or even hundreds of generations.

Also if we want to use very high quality lossy as a plausible alternative to lossless in capturing/authoring workflows (e.g. using lossy JXL payloads in DNG), I would argue that avoiding generation loss is one of the key requirements.

So I think this issue should be investigated and I think we should re-tune the encoder-side Gaborish to optimize not the first generation but the Nth one.