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

Add JPEG XL support #3

Closed
eylenburg opened this issue Dec 7, 2023 · 86 comments · Fixed by FossifyOrg/Commons#56 or #253
Closed

Add JPEG XL support #3

eylenburg opened this issue Dec 7, 2023 · 86 comments · Fixed by FossifyOrg/Commons#56 or #253
Labels
feature request Issue is about a new feature in the app

Comments

@eylenburg
Copy link

eylenburg commented Dec 7, 2023

Checklist
[X] I made sure that there are no existing issues - open or closed - to which I could contribute my information.
[X] I have read the FAQ and my problem isn't listed.
[X] I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise.
[X] This issue contains only one feature request.
[X] I have read and understood the contribution guidelines.

Is your feature request related to a problem? Please describe.
It would be great to add JPEG XL support in the Gallery.

Describe the solution you'd like
Could maybe be based on this: https://github.com/oupson/jxlviewer

Describe alternatives you've considered
None

Additional context
JPEG XL is a new modern image format, supporting both lossless and lossy compression. It has about 17-27% better compression than JPEG (mozjpeg), 15-24% better compression than WebP and 5-10% better compression than AVIF (source: https://cloudinary.com/blog/jpeg-xl-how-it-started-how-its-going) It is supported by default by all Apple devices, Linux (KDE and GNOME), various browsers (Safari, GNOME Web, Firefox Nightly, Pale Moon, Waterfox, ...) and well-known industry brand names have publicly voiced support for JPEG XL as their preferred choice, including Facebook, Adobe, Intel, Krita etc.

@Aga-C
Copy link
Member

Aga-C commented Dec 7, 2023

Please adjust your feature request report to the issue template.

EDIT: Thanks!

@Aga-C Aga-C added the feature request Issue is about a new feature in the app label Dec 8, 2023
@T8RIN
Copy link

T8RIN commented Jan 2, 2024

You can use image toolbox for editing and previewing jxl 👀

@oupson
Copy link

oupson commented Jan 4, 2024

jxlviewer also provide a library so that other project can integrate jpeg-xl. However, it is not yet ready : it miss thumbnail loading and loading of image is not efficient enough for the moment.

If you want to try the gallery with jpeg-xl support I made a dirty fork here to experiment : https://github.com/oupson/Jxl-Gallery/

For a cleaner support, .jxl file extension should be added in photoExtensions in Commons.

If anyone want to try, there is another library supporting jpeg-xl : https://github.com/awxkee/jxl-coder.

@inson1
Copy link
Contributor

inson1 commented Jan 7, 2024

SimpleMobileTools/Simple-Gallery#2669 (17 likes)

@DocSniper
Copy link

DocSniper commented Jan 20, 2024

Samsung has also jumped on the JPEG XL bandwagon since the Galaxy S24:
https://r2.community.samsung.com/t5/CamCyclopedia/Introducing-the-Galaxy-S24-Camera-Gallery/ba-p/15350511

... Additionally, storage capacity has been reduced while maintaining image quality by providing JPEG XL format ...

@TPS
Copy link

TPS commented Jan 21, 2024

... Additionally, storage capacity has been reduced while maintaining image quality by providing JPEG XL format ...

I really hope this is a translation error on Samsung's part & they mean "optimized" or some such. 🤔

@inson1
Copy link
Contributor

inson1 commented Jan 22, 2024

Dont they just mean size of the image has been reduced while .... ?

@mgorny
Copy link

mgorny commented Jan 22, 2024

In my opinion, the most important feature of JPEG XL is bidirectional, lossless conversion between JPEG and JPEG XL. In other words, this feature would let me keep my whole media library on phone while reducing its size without actually having to sacrifice anything.

@jonnyawsom3
Copy link

Yeah, that's the main reason I'm hoping this goes through. My phone is 7 years old pushing 8, got about 50 GB of photos so that'd be 10+ GB of savings for free

@jonnyawsom3
Copy link

jonnyawsom3 commented Jan 28, 2024

Had an additional thought. Assuming most are transcoding their old gallery of jpegs, the share button could transcode back for compatibility with other apps. Assuming someone makes a PR with libjxl anyway.
Similar to Apple with HEIC, but lossless

@TPS
Copy link

TPS commented Jan 28, 2024

@jonnyawsom3 Not a bad idea, but make it configurable a few ways b/c:

  • Eventually, JxL will become widespread in its own right (e.g., it took PNG a good looong while)
  • Don't assume that every JxL is a reconstructible JPG:
    • The format has an extraordinary lossless mode far better than PNG's & usually better than WebP's
    • The native lossy mode is designed to be best-in-class
    • Even the lossless JPG transcoding doesn't have to keep that reconstruction data

Imho, should be chosen upon share button (before choosing receiving app):

  • IfF construction data detected, offer to transcode back to JPG
  • IfF regular lossless mode detected, offer lossless recode to WebP/PNG
  • Always offer sharing JxL directly

@jonnyawsom3
Copy link

@TPS Yeah, it would likely be enabled by default but an option you can disable. Then disabled by default when adoption is widespread

If reconstruction data is available, then share the transcoded jpeg. Otherwise fallback to the JXL file like a standard share

Considering this is a mobile app, and the compression JXL can manage, encoding to WebP or PNG could result in long wait times or files too large to reasonably share. The jpeg transcode is meant to be fast and efficient for exactly this use case.
Once again, this is a mobile gallery app, so camera photos are the most likely kind of JXL to see

We don't want to end up with a cluttered UI and far more work for what should hopefully be a temporary issue. Sorry for dragging this out

@OkyDooky
Copy link

OkyDooky commented Feb 3, 2024

so camera photos are the most likely kind of JXL to see

Lol. Not for me. I barely take (or receive) photos. I do, however, download tons of images from various sources. It would be nice to conveniently share them without having to worry about whether or not someone can view them. But, my main concern is being able to convert the downloaded images en masse and view them conveniently.

For example, I often casually download images from Pixiv, which allows artists to upload multiple images per post (sometimes above 100) and does not apply any aditional compression to them, which results in a very large download folder very quickly. Especially because the artists either can't into compressing efficiently or they're too concerned about marring their presented work. This results in tons of unnecessary PNGs and mysteriously bloated JPGs. And then I have to spend a ton of time after each spree sorting through and recompressing the images that are "too big," or I have to deal with not being able to update large apps, since my storage is only 32GB

So, I am very much in favor of not just adding viewing support but conversion support as well. @oupson 's fork works well, aside from performance issues (which may be due to how it is loading image previews, since it lags the moment I open a folder with JXL images in it and has the same lag when full-viewing them) and that it needs a non-JXL image file in order to display the folder. But, we'd need to decide which of libjxl's many settings to expose when converting images under the "resize" option. Do we just have the Distance/Quality slider? Or add a toggle for Lossless mode? How about the Effort setting? Expose it or just hardcode some defaults for lossless/lossy encoding to keep speeds good?

There's a JXL room on Matrix that bridges to the JXL Discord server where anyone here could ask the developers and contributors what they would recommend.

Re: cluttered UI
This may be worth it, if we consider that the format may be more quickly adopted (in full) than others. When it reaches that point, we can add clarifying info in the "What's New" pop-up dialogue upon updating that explains "the JXL format is now at a point where it can be safely shared without worrying if someone can or can't open it, so we have finally deprecated the JXL-exclusive sharing features offering conversion (however, they can still be enabled in the settings." I'm adding that last part because it may make sense to keep some compatibility capabilities, but just hide them away a bit.

@OkyDooky
Copy link

OkyDooky commented Feb 3, 2024

Also, I have one use case that I'm not sure the share function would take care of: uploading an image to a web site/service via the browser. I know that, even if it opens the system file manager, I can choose my file picker, but "sharing" usually just goes to an app and doesn't seem to follow the pipeline that file picking typically uses. 🤔
So, if I were posting to a social media site, like a Pleroma instance (it's like Mastodon and Misskey), and I preferred using the browser, then I may not be able to share the image. I'd have to convert it manually beforehand, since sharing to the browser (I don't think) shares it to the active tab or whatever web element activates the file picking thingy. Unless, of course, someone can figure out a way to have it convert in app (Gallery) and then offer that converted file to browser when picking an image. Or something like that.

@kremzli
Copy link

kremzli commented Feb 4, 2024

JXL is now supported by DNG 1.7 so pros probably will be using it, guessing from how much support JXL has gotten in every issue that got rejected ( web-platform-tests/interop#430 ). Samsung and Microsoft are also going to support it, so the only one not supporting it is Google. This gallery app recently added JXL support (only opening from file manager for now) IacobIonut01/Gallery#145 so maybe looking at it may be useful for implementing here

@OkyDooky
Copy link

OkyDooky commented Feb 4, 2024

so the only one not supporting it is Google

My hope is the external pressure will cause them to cave. That's why I think getting every FOSS project we can to support the format is ultimately a good thing.
The best thing would be for the internal team doing the stonewalling to have a free change of heart. But, realistically, I think they'll probably just be looking like this:
675fbf80eabf11721c93f345a156b40f
73c

@furdiburd
Copy link

furdiburd commented Feb 24, 2024

So jpeg xl support is still not planned for fossify? then i gonna spend some time and make a fix and a pull request for it...

@inson1
Copy link
Contributor

inson1 commented Feb 24, 2024

@furdiburd yes, please, PRs are welcome

@Prajitura
Copy link

Someone already implemented this in a fork of fossify gallery:
https://github.com/oupson/Jxl-Gallery/releases/tag/1.1.0
Please consider it

@furdiburd
Copy link

Someone already implemented this in a fork of fossify gallery: https://github.com/oupson/Jxl-Gallery/releases/tag/1.1.0 Please consider it

Oh okay. Then what about putting its changes into main? Would that make a big issue somewhere?

@Prajitura
Copy link

I don't know. I didn't make that fork and don't know programming, just wanted to view jxl files and found it

@OkyDooky
Copy link

That fork was already shared by Oupson in this issue a while back.
@furdiburd I would recommend pinging one of the main contributors of Fossify and Oupson to double-check any ideas or concerns.
I already mentioned there are some performance issues, but it seems the basic functionality merges fine.

@oupson
Copy link

oupson commented Feb 29, 2024

Someone already implemented this in a fork of fossify gallery: https://github.com/oupson/Jxl-Gallery/releases/tag/1.1.0 Please consider it

Oh okay. Then what about putting its changes into main? Would that make a big issue somewhere?

This was a very work-in-progress proof of concept, so I intentionally made it non-mergeable with upstream. I have implemented the missing features that would be useful with a jxl integration in the gallery.

I intended to publish the library in central portal, but due to lack of time and documentation it is not done yet.

@mexicancartel
Copy link

I already mentioned there are some performance issues, but it seems the basic functionality merges fine.

Btw same performance issues exist in rendering HEIC already. But not so bad after thumbnails are generated

@pmiossec
Copy link

pmiossec commented Mar 2, 2024

I already mentioned there are some performance issues, but it seems the basic functionality merges fine.

A very interesting post on the subject (and also a lot of interesting other information to take):
https://cloudinary.com/blog/jpeg-xl-and-the-pareto-front

@gianni-rosato
Copy link

Any updates on this? Can we get an official word from the development team? it seems a fork already exists

@naveensingh
Copy link
Member

Version 1.2.0 is now out with initial JXL support.

@PrivacyFriendlyMuffins
Copy link

PrivacyFriendlyMuffins commented Sep 21, 2024

I think I missed something... I thought we weren't going to add JXL support to Gallery? Mind you, I ain't complaining! I'm just...confuzzled. Could somebody explain what changed that I apparently didn't catch?

 


Edit: Meant to say weren't, not were. My mistake.

@furdiburd
Copy link

furdiburd commented Sep 21, 2024

I think I missed something... I thought we were going to add JXL support to Gallery? Mind you, I ain't complaining! I'm just...confuzzled. Could somebody explain what changed that I apparently didn't catch?

(I tested the new 1.2.0 version)
Fossify gallery now initaly supports jxl.
You can open pictures of that inside the app (like find the picture in file manager and select gallery as the app to open it)

edit: looks like the pictures extension (.jxl) got somehow removed when I moved those from my pc

@PrivacyFriendlyMuffins
Copy link

Ah. So it can display JXL images but only when invoked by another program. Is that right?

(Also, I misspoke. I meant to say "weren't", not "were" in my initial comment. Apologies.)

@naveensingh
Copy link
Member

Universal app size could lowered if we drop support for x86, x86_64 architectures.

@Prajitura
Copy link

I think I missed something... I thought we were going to add JXL support to Gallery? Mind you, I ain't complaining! I'm just...confuzzled. Could somebody explain what changed that I apparently didn't catch?

(I tested the new 1.2.0 version) Fossify gallery now initaly supports jxl. You can open pictures of that inside the app (like find the picture in file manager and select gallery as the app to open it) but it don't show .JXL pictures inside the app itself.

That's weird, I have a folder with both normal jpeg and jpeg xl, and I don't need any file manager to invoke the app, I just open the album and see both jpeg and jxl images there, all this without leaving the gallery app.
However it only works with jxl lossy, jxl lossless throws a "Failed to load media" error

@naveensingh
Copy link
Member

You can open pictures of that inside the app (like find the picture in file manager and select gallery as the app to open it) but it don't show .JXL pictures inside the app itself.

Maybe you added those files using some unconventional method like adb push? In any case, you can just go to Settings → Manage include folders => Add the folder(s) containing JXL.

@furdiburd
Copy link

You can open pictures of that inside the app (like find the picture in file manager and select gallery as the app to open it) but it don't show .JXL pictures inside the app itself.

Maybe you added those files using some unconventional method like adb push? In any case, you can just go to Settings → Manage include folders => Add the folder(s) containing JXL.

Just needed to manualy add the file extension to the pictures, those somehow got cut from the filename when I copied those from my PC to the phone

@mgorny
Copy link

mgorny commented Sep 22, 2024

For the record, I don't want to force extra work on anyone but if application size with JXL library is a concern, I think JXL could be moved to a separately installed plugin. I don't know how that's exactly done, I'm afraid, but I've seen some apps doing that.

@Quackdoc
Copy link
Contributor

Perhaps split apk building would be fine? I know gallery is used on x86 systems

@obscenelyvague
Copy link

FYI, for directories containing jxl files to show up or even to open jxl images via intent, from a file manager for example, the app needs to be given access to all files and not just media files. This is because Android still doesn't recognize jxl as an image format.

As it stands, support is still quite bare-bones. The plugin fails at decoding most practical resolutions. i.e. resolutions most smart phone cameras nowadays take photos at.

@Quackdoc
Copy link
Contributor

can you give an example image it fails on?

@obscenelyvague
Copy link

I created a small test image of SMPTE bars with the same dimensions and that didn't fail so I suppose it's not strictly a resolution issue.

Here's a standard 12MP photo taken using a smartphone: https://files.catbox.moe/vs1iho.jxl

Decoding fails like so:
D: skia: Failed to create image decoder with message 'unimplemented'
D: skia: Failed to create image decoder with message 'unimplemented'
W: Load failed for [/storage/emulated/0/Download/Jxl/IMG_20220713_190600.jxl] with dimensions [1080x2400]
W: class com.bumptech.glide.load.engine.GlideException: Failed to load resource
W: There were 17 root causes:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:   Cause (1 of 3): class com.bumptech.glide.load.engine.GlideException: Failed LoadPath{FileInputStream->Object->Drawable}, LOCAL
W: There were 14 root causes:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:     Cause (1 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->j->Drawable}
W:     Cause (2 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->Bitmap->BitmapDrawable}
W: There were 5 root causes:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (2 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (3 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (4 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (5 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:     Cause (3 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->Drawable->Drawable}
W: There were 5 root causes:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (2 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (3 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (4 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (5 of 5): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:     Cause (4 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->c->Drawable}
W: There was 1 root cause:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 1): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:     Cause (5 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->BitmapDrawable->Drawable}
W: There were 2 root causes:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 2): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:       Cause (2 of 2): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:     Cause (6 of 6): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{FileInputStream->s0->PictureDrawable}
W: There was 1 root cause:
W: R3.v(Mark has been invalidated, pos: 606844 markLimit: 5242880)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 1): class R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
W:   Cause (2 of 3): class com.bumptech.glide.load.engine.GlideException: Failed LoadPath{ParcelFileDescriptor->Object->Drawable}, LOCAL
W: There were 2 root causes:
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:     Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{ParcelFileDescriptor->Bitmap->BitmapDrawable}
W: There was 1 root cause:
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 1): class java.lang.RuntimeException: setDataSource failed: status = 0x80000000
W:     Cause (2 of 2): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{ParcelFileDescriptor->BitmapDrawable->Drawable}
W: There was 1 root cause:
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 1): class java.lang.RuntimeException: setDataSource failed: status = 0x80000000
W:   Cause (3 of 3): class com.bumptech.glide.load.engine.GlideException: Failed LoadPath{AssetFileDescriptor->Object->Drawable}, LOCAL
W: There was 1 root cause:
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:     Cause (1 of 1): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{AssetFileDescriptor->Bitmap->BitmapDrawable}
W: There was 1 root cause:
W: java.lang.RuntimeException(setDataSource failed: status = 0x80000000)
W:  call GlideException#logRootCauses(String) for more detail
W:       Cause (1 of 1): class java.lang.RuntimeException: setDataSource failed: status = 0x80000000
I: Root cause (1 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at B3.b.handles(SourceFile:36)
I: 	at K3.l.b(SourceFile:21)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (2 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (3 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (4 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (5 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (6 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (7 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (8 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (9 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (10 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (11 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (12 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (13 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (14 of 17)
I: R3.v: Mark has been invalidated, pos: 606844 markLimit: 5242880
I: 	at R3.w.reset(SourceFile:45)
I: 	at com.bumptech.glide.load.data.h.e(SourceFile:10)
I: 	at K3.l.b(SourceFile:17)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (15 of 17)
I: java.lang.RuntimeException: setDataSource failed: status = 0x80000000
I: 	at android.media.MediaMetadataRetriever._setDataSource(Native Method)
I: 	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
I: 	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:334)
I: 	at R3.F.decode(SourceFile:105)
I: 	at K3.l.b(SourceFile:31)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.f(SourceFile:223)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (16 of 17)
I: java.lang.RuntimeException: setDataSource failed: status = 0x80000000
I: 	at android.media.MediaMetadataRetriever._setDataSource(Native Method)
I: 	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
I: 	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:334)
I: 	at R3.F.decode(SourceFile:105)
I: 	at B3.a.decode(SourceFile:137)
I: 	at K3.l.b(SourceFile:31)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.f(SourceFile:223)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
I: Root cause (17 of 17)
I: java.lang.RuntimeException: setDataSource failed: status = 0x80000000
I: 	at android.media.MediaMetadataRetriever._setDataSource(Native Method)
I: 	at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:310)
I: 	at R3.F.decode(SourceFile:139)
I: 	at K3.l.b(SourceFile:31)
I: 	at K3.l.a(SourceFile:25)
I: 	at K3.y.a(SourceFile:39)
I: 	at K3.k.e(SourceFile:96)
I: 	at K3.k.d(SourceFile:16)
I: 	at K3.k.f(SourceFile:60)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.f(SourceFile:223)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.f(SourceFile:223)
I: 	at K3.k.a(SourceFile:40)
I: 	at K.u.h(SourceFile:65)
I: 	at O3.u.h(SourceFile:5)
I: 	at com.bumptech.glide.load.data.b.e(SourceFile:20)
I: 	at O3.u.e(SourceFile:25)
I: 	at K3.E.b(SourceFile:142)
I: 	at K3.k.p(SourceFile:26)
I: 	at K3.k.q(SourceFile:53)
I: 	at K3.k.run(SourceFile:24)
I: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
I: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
I: 	at E4.b.run(SourceFile:1084)
I: 	at java.lang.Thread.run(Thread.java:1012)
I: 	at N3.a.run(SourceFile:20)
D: skia: Failed to create image decoder with message 'unimplemented'
D: skia: Failed to create image decoder with message 'unimplemented'

@faramonius
Copy link

faramonius commented Sep 23, 2024

By the way, it's good that we're discussing jxl-format again. There is another bug that appears when viewing long (vertical) images. For example, screenshots of web pages. See, these are regular screenshots I took now, where two programs show what a long screenshot looks like, taken by a browser in png format and converted to lossless jxl using Image Toolbox. 1) Fossify gallery, 2) "Proof Of Concept of jpeg-xl integration in Simple Gallery".

On the first screenshot the picture is blurred, on the second one it is clear. The blurring occurs starting from some height limit.

Screenshot_2024-09-23-07-44-16-838_org fossify gallery
Screenshot_2024-09-23-07-45-33-233_fr oupson pocjxlgallery

Tech. info by image:

jxl-info -v ResizedImage_2024-09-23_07-43-32_1.jxl
2024-09-23T04:54:12.349812Z DEBUG jxl_bitstream::reader: Codestream signature found
JPEG XL image
  Image dimension: 720x5027
  Bit depth: 8 bits
  Color encoding:
    Colorspace: RGB
    White point: D65
    Primaries: sRGB
    Transfer function: sRGB
2024-09-23T04:54:12.350593Z DEBUG jxl_render::inner: Decoding 720x5027 frame width=720 height=5027 frame_type=RegularFrame encoding=Modular jpeg_upsampling=None upsampling=1 lf_level=0
2024-09-23T04:54:14.965769Z DEBUG jxl_frame: Single progressive scan downsample_factor=8 done=true
Frame #0
  Modular (maybe lossless)
  720x5027; (0, 0)

@Raffael7777
Copy link

That's weird, I have a folder with both normal jpeg and jpeg xl, and I don't need any file manager to invoke the app, I just open the album and see both jpeg and jxl images there, all this without leaving the gallery app. However it only works with jxl lossy, jxl lossless throws a "Failed to load media" error

I have tasker losslessly recompress jpegs into jxls when they are created in my DCIM folder, using termux and libjxl's cjxl command. It seems to be a dimension limitation (or maybe filesize, they correlate), not lossy vs lossless. Fossify gallery correctly generates thumbnails for and loads the jxls that are 4000x3000, but fails to do both for the ones that are 8000x6000.

I also tested a small lossless jxl I specifically encoded with modular mode, gallery had no issues displaying it.

@naveensingh naveensingh unpinned this issue Sep 23, 2024
@naveensingh
Copy link
Member

Dropping JXL support until awxkee/jxl-coder-glide#4 is resolved.

@naveensingh naveensingh reopened this Sep 24, 2024
@OkyDooky
Copy link

Glad to see a fix is in the works. And thanks for taking this so seriously, instead of just leaving in a faulty implementation. Plus, I think (and hope) that the work you did to centralize awareness of the partial/regional decoding issues will help in driving selective pressure for them to get resolved at their source.

@OkyDooky
Copy link

Speaking of, could I (or you or anyone) open an issue ticket dedicated to just tracking the decoding issue? It'd make it easier to point to for people who haven't read this thread, if nothing else.

@TPS
Copy link

TPS commented Sep 25, 2024

Speaking of, could I (or you or anyone) open an issue ticket dedicated to just tracking the decoding issue?

@OkyDooky #301awxkee/jxl-coder-glide#4?

@TPS
Copy link

TPS commented Sep 26, 2024

@naveensingh Would you mind tagging a new release so that the JxL fixed support could be published @ F-Droid?

@OkyDooky
Copy link

Speaking of, could I (or you or anyone) open an issue ticket dedicated to just tracking the decoding issue?

@OkyDooky #301awxkee/jxl-coder-glide#4?

No, these:

the resampling/zooming issue.

Fossify Gallery relies on Android's BitmapRegionDecoder to decode parts of an image instead of the whole image. BitmapRegionDecoder only supports a select number of formats. Related:

@naveensingh
Copy link
Member

naveensingh commented Sep 26, 2024

@naveensingh Would you mind tagging a new release so that the JxL fixed support could be published @ F-Droid?

It'll be released soon, just need to make some little adjustments here and there.

Update: https://github.com/FossifyOrg/Gallery/releases/tag/1.2.1

open an issue ticket dedicated to just tracking the decoding issue?

Feel free to raise one for JXL. We already have it raised for AVIF: #252

@awxkee
Copy link

awxkee commented Sep 26, 2024

That's weird, I have a folder with both normal jpeg and jpeg xl, and I don't need any file manager to invoke the app, I just open the album and see both jpeg and jxl images there, all this without leaving the gallery app. However it only works with jxl lossy, jxl lossless throws a "Failed to load media" error

I have tasker losslessly recompress jpegs into jxls when they are created in my DCIM folder, using termux and libjxl's cjxl command. It seems to be a dimension limitation (or maybe filesize, they correlate), not lossy vs lossless. Fossify gallery correctly generates thumbnails for and loads the jxls that are 4000x3000, but fails to do both for the ones that are 8000x6000.

I also tested a small lossless jxl I specifically encoded with modular mode, gallery had no issues displaying it.

Decoding images of those sizes should be fine unless Glide requested image in original size. If you checked that image is not requesting in original size and still not loading raise an issue here or here

@naveensingh naveensingh mentioned this issue Sep 27, 2024
7 tasks
@faramonius
Copy link

faramonius commented Sep 30, 2024

@awxkee
@naveensingh
Well, as of today, I see the fossify/Gallery version 1.2.1 as having these issues:

  1. as I showed above, vertically long screenshots show blurry when scaled to the screen width. The longer the picture - the more blurry it is.
  2. files larger than about 5 MB are not displayed for me, "can't load media". The vs1iho.jxl file above is one of them.
  3. gif converted to jxl - also not displayed.

Funny thing is that the old and demo version 1.1.0 of POC dev. Oupson handles all three tasks fine. Hence my question: what to do? Where to open the issue? :)

@awxkee
Copy link

awxkee commented Sep 30, 2024

@awxkee @naveensingh Well, as of today, I see the fossify/Gallery version 1.2.1 as having these issues:

1. as I showed above, vertically long screenshots show blurry when scaled to the screen width. The longer the picture - the more blurry it is.

2. files larger than about 5 MB are not displayed for me, "can't load media". The vs1iho.jxl file above is one of them.

3. gif converted to jxl - also not displayed.

Funny thing is that the old version of POC dev. Oupson handles all three tasks fine. Hence my question: what to do? Where to open the issue? :)

1 - At the moment without region decoding it is intented
2, 3 - Open here with files attached

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issue is about a new feature in the app
Projects
None yet
Development

Successfully merging a pull request may close this issue.