awxkee / jxl-coder-glide

JPEG XL Glide android plugin
Apache License 2.0
10 stars 2 forks source link

Can't build the sample #2

Closed AndroidDeveloperLB closed 1 month ago

AndroidDeveloperLB commented 1 month ago

When I try, I get this error:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
> Error while evaluating property 'compilerOptions.jvmTarget' of task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
   > Failed to calculate the value of property 'jvmTarget'.
      > Unknown Kotlin JVM target: 21

image

Can you please update the sample, and also show there how to use it for apps that use the View stuff, not only of Compose?

AndroidDeveloperLB commented 1 month ago

I also tried to create my own sample, and it fails to show the image when "wrap_content" is used for either width or height (or both). It doesn't show anything at all:

jpegxlTest.zip

awxkee commented 1 month ago

When I try, I get this error:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
> Error while evaluating property 'compilerOptions.jvmTarget' of task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
   > Failed to calculate the value of property 'jvmTarget'.
      > Unknown Kotlin JVM target: 21

image

Can you please update the sample, and also show there how to use it for apps that use the View stuff, not only of Compose?

Hi,

Set gradle JDK version to 17. Perhaps there are some issues with some plugins or Android Studio or compiler or something else and I'm not really want to dig the rabbit hole of gradle issues.

I also tried to create my own sample, and it fails to show the image when "wrap_content" is used for either width or height (or both). It doesn't show anything at all:

jpegxlTest.zip

To use any glide plugins you must have in project AppGlideModule activated with ksp/kapt. This is noted behaviour in in README, and noted in glide.

Add stub, at least and your app will work.

@GlideModule
class GlideModule: AppGlideModule() {

}

I'll add small sample with View's later.

awxkee commented 1 month ago

Here is glide doc

AndroidDeveloperLB commented 1 month ago

Weird. I thought I've already added the file. Also weird that when the size is fixed it worked fine. I still don't get why Glide needs the module file. Should have a default behavior running out of the box. Anyway, I've added the module, and it still didn't help and got the same result. When it's not a fixed size, it's not working.

Please check: jpegxlTest.zip

awxkee commented 1 month ago

When I try, I get this error:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
> Error while evaluating property 'compilerOptions.jvmTarget' of task ':jxlcoderglide:kaptGenerateStubsDebugKotlin'.
   > Failed to calculate the value of property 'jvmTarget'.
      > Unknown Kotlin JVM target: 21

image

Can you please update the sample, and also show there how to use it for apps that use the View stuff, not only of Compose?

Did forcing gradle jdk to 17 help?

Weird. I thought I've already added the file. Also weird that when the size is fixed it worked fine. I still don't get why Glide needs the module file. Should have a default behavior running out of the box. Anyway, I've added the module, and it still didn't help and got the same result. When it's not a fixed size, it's not working.

Please check: jpegxlTest.zip

I can't reproduce, your example working from the box. Perhaps there should be some exception if you don't get any image, is'n it?

Screenshot 2024-09-19 at 20 12 16
awxkee commented 1 month ago

As I got kotlin do not support java 21, and this looks like you build system chosen 21 jdk as default and fails due to this. So settings gradle jdk to 17 should help

AndroidDeveloperLB commented 1 month ago

The sample I've created (which doesn't seem to be so different than the one of the repository, just uses ImageView instead) builds fine. The issue is the result of running on Pixel 6 with Android 14. Here, I will show you a video:

studio64_2024-09-19_22-54-01_1.zip

The logs:

22:55:38.243 Glide       com.lb.jpegxltest                            Root cause (1 of 5) (Ask Gemini)
                                                                      java.lang.RuntimeException: setDataSourceCallback failed: status = 0x80000000
                                                                        at android.media.MediaMetadataRetriever._setDataSource(Native Method)
                                                                        at android.media.MediaMetadataRetriever.setDataSource(MediaMetadataRetriever.java:407)
                                                                        at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initializeRetriever(VideoDecoder.java:517)
                                                                        at com.bumptech.glide.load.resource.bitmap.VideoDecoder$ByteBufferInitializer.initializeRetriever(VideoDecoder.java:512)
                                                                        at com.bumptech.glide.load.resource.bitmap.VideoDecoder.decode(VideoDecoder.java:192)
                                                                        at com.bumptech.glide.load.resource.bitmap.BitmapDrawableDecoder.decode(BitmapDrawableDecoder.java:58)
                                                                        at com.bumptech.glide.load.engine.DecodePath.decodeResourceWithList(DecodePath.java:92)
                                                                        at com.bumptech.glide.load.engine.DecodePath.decodeResource(DecodePath.java:70)
                                                                        at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:59)
                                                                        at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:76)
                                                                        at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:57)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:539)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:503)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:489)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:434)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:399)
                                                                        at com.bumptech.glide.load.engine.SourceGenerator.onDataFetcherReady(SourceGenerator.java:239)
                                                                        at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:100)
                                                                        at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:62)
                                                                        at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:77)
                                                                        at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:75)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:311)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:280)
                                                                        at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:235)
                                                                        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
                                                                        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
                                                                        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:424)
                                                                        at java.lang.Thread.run(Thread.java:1012)
                                                                        at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultPriorityThreadFactory$1.run(GlideExecutor.java:383)
awxkee commented 1 month ago

Your OS/OS version/Glide version made a decision that it is some kind of video, tried to retrieve and sure - failed. I don't know what exactly to offer at the moment.

Even more strange that for fixed size it decides that it is not video.

Can you confirm that JxlCoderByteBufferDecoder.decode or JxlCoderByteBufferDecoder.handles is even fired?

awxkee commented 1 month ago

By the way it looks like more to OS/Glide bug rather that plugin to me

AndroidDeveloperLB commented 1 month ago

@awxkee Please explain exactly how to check what you want to test. I don't think I see "Jxl" anywhere in the logs. I tried to write "package:mine Jxl" in the filter of LogCat, and didn't see anything. You are running the exact same project, and it works fine for you? Are you seeing something weird that I forgot to change in the code, perhaps?

By OS, you mean Android, or Windows? I've now tried to run on emulator with Android 14 and on another device with Android 14 (Honor Magic 4 pro). Still same issue.

Can you please share an APK that's generated right from the project I've shared? Don't change it at all please... Here's my APK. Please test it too:

app-debug.zip

awxkee commented 1 month ago

Sorry, I haven't check your second sources with full attention and made a little mess.

You've added GlideModule, however don't activate glide ksp plugin. Activate it in gradle file, it should work.

Here is apk, it's working. app-debug.apk.zip

AndroidDeveloperLB commented 1 month ago

@awxkee Oh this:

    ksp ("com.github.bumptech.glide:ksp:${GLIDE_VERSION}")

I've made it a comment because I thought it's causing the issue. Tried various things.

Sorry for the trouble. Please update the sample though.

awxkee commented 1 month ago

As I got kotlin do not support java 21, and this looks like you build system chosen 21 jdk as default and fails due to this. So settings gradle jdk to 17 should help

Did you try to force gradle jdk to 17? I especially don’t set any specific in project, there are always jdk version comes from your own ide. You can easily check gradle files and note there are no signs of 21 then it is definitely comes from your build system.

AndroidDeveloperLB commented 1 month ago

@awxkee You mean in the gradle kts ? Why do I need to change it? And to what exactly ? It's an Android project you've also created via Android Studio, no? And my sample also showed it works without me changing anything?

awxkee commented 1 month ago

Here is setting.

Screenshot 2024-09-19 at 23 12 19

I don't know exactly when it is choose and why and which version and why sometimes it stops working. Probably projects have some from plugins/libraries that not compatible with jdk 17 and release still not made. Just bump versions up doesn't helping and I am not really want to waste a few hours to digging this. This gradle things are too unpredictable.

awxkee commented 1 month ago

This things like waste the whole day to fix for 21 JDK ( which gives nothing ) instead of 17 is definitely don't have any sense to me.

awxkee commented 1 month ago

If you are ready do explore the depths of this I'm glad to accept PR.

AndroidDeveloperLB commented 1 month ago

@awxkee The IDE uses this:

image

I don't see the option to use Amazon 17 . So, I tried to update the sample much further. Now it builds fine. Here:

https://github.com/awxkee/jxl-coder-glide/pull/3

Let me know when you use it.

awxkee commented 1 month ago

Awesome! This works! Thanks for your time. I'll add sample with View's soon.

awxkee commented 1 month ago

Updated sample with ImageView now is in master. You can check this out. So I think all your issues has been resolved, closing for now.

Feel free to contact if you have any more issues.

AndroidDeveloperLB commented 1 month ago

Well I have a few questions:

  1. OK to use as I did in my sample, meaning via R.raw... ?
  2. I don't get the "lawyer" terminology when it comes to licenses. Is it ok to use the library in a closed-sourced app? What should I do? Need to have credits to it?
  3. What is the "GlideImage"? Something special that Glide offers for Compose? Why don't they have it for ImageView? Because ImageView is being extended already by the support library, or something? It's just that I'm have 0 experience with Compose except for some POCs I've tried. I never understood why people like to switch to it... Some actually told me they regret switching.
awxkee commented 1 month ago

1 - Glide plugins do not have access to what is loading only to ByteBuffer so everything that glide itself can load to ByteBuffer shoud be fine. So, any plugin is just a delegate that check a ByteBuffer for ability to intercept, and if it is, tries to load. Any your custom loaders, resources or other things should be completely fine since it handled by different glide layers. 2 - Apache and BSD-3 allows use almost absolutely free use, except patenting this code as it yours. You can choose the license that you knows best, or fits you best. You shouldn't make any credits for this library. 3 - GlideImage is a wrapper for Compose ImageView from Glide. Some things easier to do in Compose, some things are not, this is just a technology, and as any tech stack, have advantages ( some simple screens and many things are easier ), and some complex screens are not. Even sometimes complex screens in Compose may be harder than in views. For this project I generated just first that studio has offered :)

awxkee commented 1 month ago

libjxl, and jxl-coder that drives this lib here also licensed under BSD-3/Apache for jxl-coder and libjxl as BSD-3 so in common you shouldn't worry for closed source projects or make any mentions

awxkee commented 1 month ago

And if you will copy contents of this repo into your app both of licenses required then to keep an original header note in each file that it is licensed under Apache or Bsd, and for Apache, you can’t submit then this code ( just copied part from here ) as patent code.

So if you choose Apache, copied this repo in your project and want to patent the project some consultation with lawyer might be needed, otherwise almost nothing required

AndroidDeveloperLB commented 1 month ago

Those rules are only if I create a new repository out of this, no? I can use the repository as a dependency freely for all purposes, right?

awxkee commented 1 month ago

Yes, this repo you can use freely for all purposes

AndroidDeveloperLB commented 1 month ago

@awxkee OK thanks

AndroidDeveloperLB commented 3 weeks ago

@awxkee Say, I've now tried to compare APK size before and after adding this library. Adding Glide alone, it adds around 300KB. However, adding the jxl dependency from here, it adds around 33.5MB more. A part of it is for Intel architecture support so can be easily removed, of ~25MB, as such:

    defaultConfig {
        ...
        ndk {
            abiFilters.addAll(arrayOf("arm64-v8a", "armeabi-v7a"
//                    , "x86", "x86_64"
            ))
        }
    }

Still, 33.5-25 is 8.5MB (ARM 32/64 only) for just one dependency, and that's only of the "lib" folder. Somehow the real number is around 13-14MB compared to without Glide&JXL dependencies.

Why does it take so much? Any way to squeeze it further? The point of me using this library is to reduce the space the app uses. For this to be worth it, I would have to use plenty of images in an app...

awxkee commented 3 weeks ago

Sadly but there is not so many ways to decrease size completely. Main size comes from libjxl itself, even I recompile for you or you recompile without encoding support and remove all features for size there still will be around 4-6 mb for aarch64 + armv7. In common if you are not targeting for very specific devices with armv7 you can drop it support also.

Here is breakdown, even if remove some features by hands at best it will be only half of that size. Probably it is possible to detach jxlthreads by the speed price.

Screenshot 2024-09-30 at 23 12 32

By the way in my experience you want to reduce images in the app ( highly likely not with high fidelity ) you actually want avif. With quality about 55-58% ( it is not same as JPG in real life it is exceptional quality ) it will be almost twice less than JXL. And on the phone many of avif decoders performs much better than JXL. If you wish to try avif glide have an integrated avif decoder, not the fastest one, however good, and will cost you another ~300kb on top of glide. I may always say that best to choose JXL if you want to server from remote photos in exceptional quality or losslessly transcoded from JPEG, otherway it better go with avif. AVIF size is smaller on good quality, decoders works faster, if decoder not overloaded with features for all platform size will be around 1mb

AndroidDeveloperLB commented 3 weeks ago

@awxkee I see. But as I've seen, JXL seems to be better than AVIF in various ways. I think I will use it, but on a project that has plenty of high-quality images. Which AVIF library do you know for Glide, that is as you said, just adding 300kb?

awxkee commented 3 weeks ago

JXL outperforms AVIF only at high fidelity photos at very high quality not at any other sense, it is noted behaviour even in marketing materials or at transcoding old JPEG for sure. Also it is better at encoding, but I thinks at our case it is not really have sense because often at mobile we're not interested in any encoding at all.

Here you may take glide avif integration.

AndroidDeveloperLB commented 3 weeks ago

@awxkee Weird. A lot say they want it for Android , and IOS seems to support JXL: https://issuetracker.google.com/u/0/issues/259900694 And for some reason on Chromium it seems to be denied, with mentions of "JPEG AI", which is something I didn't even hear of yet: https://issues.chromium.org/issues/40168998#comment436 I also saw various comparisons and usually JXL is better. Example: https://tonisagrista.com/blog/2023/jpegxl-vs-avif/#lossless-compression

Could be nice to have support for both but with a tiny footprint, so that we could have the IDE choose for us which is best in terms of space. Of course, it's making the OS handle more and more standards, with no clear winner that overcomes all, but would such a thing even exist...

About AVIF, thank you. Is this all? No annoying license that forces me to do anything? How come for AVIF there is no special page? No Github repository?

awxkee commented 3 weeks ago

@awxkee Weird. A lot say they want it for Android , and IOS seems to support JXL: https://issuetracker.google.com/u/0/issues/259900694

JPEG XL have few significant advantages for common use case it is almost losless storing user photos/camera photos in JPEG XL in better compression ratio than JPEG/HEVC. Jpeg bit exact converting to jxl with -20% file size in average ( I personally don't get this idea in full, for 1-5% quality loss it can be converted to AVIF with -70% but ok, why not ? ). And ability to encode pictures on the phone, because if you'll try to encode AVIF on the phone especially on low-tier or medium-tier devices it is something just crazy. I don't know why google denies that.

IOS seems to support JXL: Only from iOS 16, and they compiled it without threads support, so speed of opening images is quite surprising.

Could be nice to have support for both but with a tiny footprint

Even google add this it will take years before you can use it without external deps. In external deps is not easy because a lib in common should support encoding this twice the size, and doing 2 separate libs twice the efforts :) Also there is tons of features in both formats many pixel types, HDR, color profiles which android do not implemented, or implement and do not exposed as public API, so they need to be rewritten from scratch and this make more binary size also, or even much more tricky configuring with many lib options.

About AVIF, thank you. Is this all? No annoying license that forces me to do anything?

AVIF is licensed under BSD-2 which is probably one is the most open licenses.

How come for AVIF there is no special page? No Github repository?

I have almost 10 repos as part of AVIF for iOS and android :)

AndroidDeveloperLB commented 3 weeks ago

@awxkee

  1. You mean that AVIF is faster to encode on Android than WEBP and JXL ?
  2. Is it possible perhaps for JXL to split dependencies? For example one for encode and one for decode?
  3. BSD-2 is ok to use inside a closed source app? No need to make it open source ? No need to give credit or something?
  4. I don't understand what it means "I have almost 10 repos as part of AVIF for iOS and android ". I talked about the dependency that you've linked to. I can't find the repository that's related to it, of implementation "com.github.bumptech.glide:avif-integration:4.14.2" .
awxkee commented 3 weeks ago
  1. You mean that AVIF is faster to encode on Android than WEBP and JXL ?

I mean it is absolutely incredible hungry to resources and slow, often low-tier devices will just crash with OOM.

  1. Is it possible perhaps for JXL to split dependencies? For example one for encode and one for decode?

Yes but it will require a lot of efforts, and there is one final problem that for users who wants to use an encoder and decoder altogether due to same native binaries it will require manual reconfigure jni libs in gradle or triple size if libs will be just renamed.

  1. BSD-2 is ok to use inside a closed source app? No need to make it open source ? No need to give credit or something?

Yes, BSD-2 is free to use.

4. I don't understand what it means "I have almost 10 repos as part of AVIF for iOS and android ". I talked about the dependency that you've linked to. I can't find the repository that's related to it, of implementation "com.github.bumptech.glide:avif-integration:4.14.2" .

Ah ok, I misunderstood a question

AndroidDeveloperLB commented 3 weeks ago
  1. I think this might explain why even on my computer, saving to JXL takes some time, sometimes, and I have a good PC...
  2. Too bad
  3. Nice. Android 14 actually has it, so I wonder what's best to do if you wish to support from before as well. Glide automatically uses the one of Android 14? Is it even better than the library?
  4. So you don't know the answer?
awxkee commented 3 weeks ago
  1. I think this might explain why even on my computer, saving to JXL takes some time, sometimes, and I have a good PC...

And actually JXL significantly faster than AVIF :)

3. Nice. Android 14 actually has it, so I wonder what's best to do if you wish to support from before as well. Glide automatically uses the one of Android 14? Is it even better than the library?

If there are no plugins it will definitely try native OS methods to decode, otherwise I don't know, probably this question better be addressed to glide team or docs how that works.

4. So you don't know the answer?

I don't know, I'm not related to glide team in any ways. Here is the plugin repository. Someday it took some time to understand where is it.

AndroidDeveloperLB commented 3 weeks ago
  1. JXL is faster than AVIF? In both decoding and encoding?
  2. ok
  3. Oh it's part of the repository itself? But then how can I subscribe to new versions of it?
awxkee commented 3 weeks ago
  1. JXL is faster than AVIF? In both decoding and encoding?

Only in encoding at the moment.

3. Oh it's part of the repository itself? But then how can I subscribe to new versions of it?

🤷‍♂️