├── settings.gradle ├── image ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── qq.png ├── cover.png ├── qrcode.png ├── 5-long-ver.jpg ├── 6-long-hor.jpg ├── pay-alipay.jpg ├── pay-wepay.jpg └── 4-video-hor.jpg ├── publish.sh ├── common-60.keystore ├── sample ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── ic_launcher_background.xml │ │ │ ├── styles.xml │ │ │ └── colors.xml │ │ ├── raw │ │ │ └── blackhole.jpg │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── blackhole.jpg │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_foreground.png │ │ ├── drawable-xxhdpi │ │ │ ├── icon_custom_back.png │ │ │ ├── icon_custom_play.png │ │ │ ├── icon_custom_share.png │ │ │ ├── icon_custom_stop.png │ │ │ └── icon_custom_download.png │ │ ├── xml │ │ │ ├── network_config.xml │ │ │ └── file_paths_public.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ └── image_progress_layout_theme_1.xml │ │ └── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ ├── java │ │ └── cc │ │ │ └── shinichi │ │ │ └── bigimageviewpager │ │ │ ├── App.java │ │ │ └── glide │ │ │ ├── MyAppGlideModule.java │ │ │ └── GlideEngine.java │ │ └── AndroidManifest.xml ├── .gitignore ├── proguard-rules.pro └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── library ├── src │ └── main │ │ ├── res │ │ ├── drawable-xhdpi │ │ │ ├── load_failed.png │ │ │ ├── ic_action_close.png │ │ │ ├── icon_video_play.png │ │ │ ├── icon_video_stop.png │ │ │ ├── icon_download_new.png │ │ │ └── icon_change_orientation.png │ │ ├── drawable-xxhdpi │ │ │ ├── load_failed.png │ │ │ ├── ic_action_close.png │ │ │ ├── icon_video_play.png │ │ │ ├── icon_video_stop.png │ │ │ ├── icon_download_new.png │ │ │ └── icon_change_orientation.png │ │ ├── values │ │ │ ├── ids.xml │ │ │ ├── strings.xml │ │ │ ├── attrs.xml │ │ │ └── style.xml │ │ ├── drawable │ │ │ ├── gray_circle_bg.xml │ │ │ ├── shape_indicator_bg.xml │ │ │ └── gray_square_circle_bg_white_stroke.xml │ │ ├── anim │ │ │ ├── fade_in.xml │ │ │ └── fade_out.xml │ │ ├── values-en-rUS │ │ │ └── strings.xml │ │ └── layout │ │ │ ├── sh_default_progress_layout.xml │ │ │ ├── sh_item_photoview.xml │ │ │ └── sh_media_controller.xml │ │ ├── java │ │ ├── cc │ │ │ └── shinichi │ │ │ │ └── library │ │ │ │ ├── view │ │ │ │ ├── listener │ │ │ │ │ ├── OnFinishListener.kt │ │ │ │ │ ├── OnCustomLayoutCallback.kt │ │ │ │ │ ├── OnPageFinishListener.kt │ │ │ │ │ ├── OnBigImageClickListener.kt │ │ │ │ │ ├── OnBigImageLongClickListener.kt │ │ │ │ │ ├── OnOriginProgressListener.kt │ │ │ │ │ ├── OnDownloadListener.kt │ │ │ │ │ ├── SimpleOnImageEventListener.kt │ │ │ │ │ ├── OnDownloadClickListener.kt │ │ │ │ │ ├── OnPageDragListener.kt │ │ │ │ │ └── OnBigImagePageChangeListener.kt │ │ │ │ ├── photoview │ │ │ │ │ ├── OnOutsidePhotoTapListener.java │ │ │ │ │ ├── OnViewDragListener.java │ │ │ │ │ ├── OnScaleChangedListener.java │ │ │ │ │ ├── OnMatrixChangedListener.java │ │ │ │ │ ├── OnViewTapListener.java │ │ │ │ │ ├── OnSingleFlingListener.java │ │ │ │ │ ├── OnPhotoTapListener.java │ │ │ │ │ ├── OnGestureListener.java │ │ │ │ │ ├── Compat.java │ │ │ │ │ └── Util.java │ │ │ │ ├── ImagePreviewAdapter.kt │ │ │ │ ├── subsampling │ │ │ │ │ ├── decoder │ │ │ │ │ │ ├── DecoderFactory.java │ │ │ │ │ │ ├── ImageDecoder.java │ │ │ │ │ │ ├── CompatDecoderFactory.java │ │ │ │ │ │ └── ImageRegionDecoder.java │ │ │ │ │ └── ImageViewState.java │ │ │ │ └── HackyViewPager.kt │ │ │ │ ├── glide │ │ │ │ ├── progress │ │ │ │ │ ├── OnProgressListener.kt │ │ │ │ │ ├── ProgressLibraryGlideModule.kt │ │ │ │ │ ├── ProgressResponseBody.kt │ │ │ │ │ └── ProgressManager.kt │ │ │ │ ├── cache │ │ │ │ │ ├── DataCacheKey.kt │ │ │ │ │ └── SafeKeyGenerator.kt │ │ │ │ ├── FileTarget.kt │ │ │ │ ├── ImageLoader.kt │ │ │ │ └── SSLSocketClient.kt │ │ │ │ ├── bean │ │ │ │ └── ImageInfo.kt │ │ │ │ ├── tool │ │ │ │ ├── common │ │ │ │ │ ├── HandlerHolder.kt │ │ │ │ │ ├── NetworkUtil.kt │ │ │ │ │ ├── ToastUtil.kt │ │ │ │ │ ├── UIUtil.kt │ │ │ │ │ ├── DeviceUtil.kt │ │ │ │ │ ├── SLog.kt │ │ │ │ │ ├── PhoneUtil.kt │ │ │ │ │ └── HttpUtil.kt │ │ │ │ ├── image │ │ │ │ │ └── UtilExt.kt │ │ │ │ └── file │ │ │ │ │ ├── SingleMediaScanner.kt │ │ │ │ │ └── ExoCacheManager.kt │ │ │ │ ├── GlobalContext.kt │ │ │ │ └── InitProvider.kt │ │ └── com │ │ │ └── bumptech │ │ │ └── glide │ │ │ └── integration │ │ │ └── webp │ │ │ ├── decoder │ │ │ ├── WebpDrawableResource.java │ │ │ ├── StreamAnimatedBitmapDecoder.java │ │ │ ├── ByteBufferAnimatedBitmapDecoder.java │ │ │ ├── WebpDrawableEncoder.java │ │ │ ├── ByteBufferBitmapWebpDecoder.java │ │ │ ├── StreamBitmapWebpDecoder.java │ │ │ ├── Utils.java │ │ │ ├── StreamWebpDecoder.java │ │ │ ├── WebpDrawableTransformation.java │ │ │ ├── WebpFrameCacheStrategy.java │ │ │ ├── ByteBufferWebpDecoder.java │ │ │ └── AnimatedWebpBitmapDecoder.java │ │ │ ├── WebpFrameInfo.java │ │ │ └── WebpFrame.java │ │ ├── jni │ │ ├── webp.h │ │ ├── libwebp │ │ │ └── src │ │ │ │ ├── demux │ │ │ │ ├── libwebpdemux.pc.in │ │ │ │ ├── Makefile.am │ │ │ │ └── libwebpdemux.rc │ │ │ │ ├── libwebp.pc.in │ │ │ │ ├── libwebpdecoder.pc.in │ │ │ │ ├── mux │ │ │ │ ├── libwebpmux.pc.in │ │ │ │ ├── Makefile.am │ │ │ │ ├── libwebpmux.rc │ │ │ │ └── animi.h │ │ │ │ ├── utils │ │ │ │ ├── filters_utils.h │ │ │ │ ├── quant_levels_utils.h │ │ │ │ ├── quant_levels_dec_utils.h │ │ │ │ ├── Makefile.am │ │ │ │ ├── color_cache_utils.c │ │ │ │ ├── random_utils.c │ │ │ │ ├── huffman_encode_utils.h │ │ │ │ ├── random_utils.h │ │ │ │ ├── filters_utils.c │ │ │ │ ├── color_cache_utils.h │ │ │ │ └── endian_inl_utils.h │ │ │ │ ├── libwebp.rc │ │ │ │ ├── dec │ │ │ │ ├── Makefile.am │ │ │ │ ├── common_dec.h │ │ │ │ └── alphai_dec.h │ │ │ │ ├── libwebpdecoder.rc │ │ │ │ ├── dsp │ │ │ │ ├── dec_sse41.c │ │ │ │ ├── quant.h │ │ │ │ └── alpha_processing_sse41.c │ │ │ │ ├── Makefile.am │ │ │ │ ├── enc │ │ │ │ ├── Makefile.am │ │ │ │ └── cost_enc.h │ │ │ │ └── webp │ │ │ │ ├── types.h │ │ │ │ ├── mux_types.h │ │ │ │ └── format_constants.h │ │ ├── Application.mk │ │ └── Android.mk │ │ └── AndroidManifest.xml ├── .gitignore └── proguard-rules.pro ├── .gitignore ├── LICENSE ├── gradle.properties └── gradlew.bat /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':sample', ':library' -------------------------------------------------------------------------------- /image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/1.jpg -------------------------------------------------------------------------------- /image/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/2.jpg -------------------------------------------------------------------------------- /image/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/3.jpg -------------------------------------------------------------------------------- /image/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/qq.png -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | ./gradlew clean publishToSonatype closeAndReleaseSonatypeStagingRepository 2 | -------------------------------------------------------------------------------- /image/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/cover.png -------------------------------------------------------------------------------- /image/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/qrcode.png -------------------------------------------------------------------------------- /common-60.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/common-60.keystore -------------------------------------------------------------------------------- /image/5-long-ver.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/5-long-ver.jpg -------------------------------------------------------------------------------- /image/6-long-hor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/6-long-hor.jpg -------------------------------------------------------------------------------- /image/pay-alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/pay-alipay.jpg -------------------------------------------------------------------------------- /image/pay-wepay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/pay-wepay.jpg -------------------------------------------------------------------------------- /image/4-video-hor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/image/4-video-hor.jpg -------------------------------------------------------------------------------- /sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | BigImageViewPager 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample/src/main/res/raw/blackhole.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/raw/blackhole.jpg -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/blackhole.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxxhdpi/blackhole.jpg -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/load_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/load_failed.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/load_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/load_failed.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/ic_action_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/ic_action_close.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/icon_video_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/icon_video_play.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/icon_video_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/icon_video_stop.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/icon_download_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/icon_download_new.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/ic_action_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/ic_action_close.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/icon_video_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/icon_video_play.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/icon_video_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/icon_video_stop.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/icon_custom_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/drawable-xxhdpi/icon_custom_back.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/icon_custom_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/drawable-xxhdpi/icon_custom_play.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/icon_custom_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/drawable-xxhdpi/icon_custom_share.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/icon_custom_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/drawable-xxhdpi/icon_custom_stop.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnFinishListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | interface OnFinishListener { 4 | 5 | fun onFinish() 6 | } -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/icon_download_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/icon_download_new.png -------------------------------------------------------------------------------- /sample/src/main/res/drawable-xxhdpi/icon_custom_download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/drawable-xxhdpi/icon_custom_download.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /sample/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #26A69A 4 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xhdpi/icon_change_orientation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xhdpi/icon_change_orientation.png -------------------------------------------------------------------------------- /library/src/main/res/drawable-xxhdpi/icon_change_orientation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SherlockGougou/BigImageViewPager/HEAD/library/src/main/res/drawable-xxhdpi/icon_change_orientation.png -------------------------------------------------------------------------------- /sample/src/main/res/xml/network_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /library/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /library/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | .idea/ 12 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | .idea/ 12 | /.idea/ 13 | -------------------------------------------------------------------------------- /library/src/main/res/drawable/gray_circle_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | .idea/ 12 | /.idea/ 13 | */release/* 14 | */debug/* 15 | 16 | gradle.properties -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnCustomLayoutCallback.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.View 5 | 6 | interface OnCustomLayoutCallback { 7 | 8 | fun onLayout(activity: Activity, parentView: View) 9 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /library/src/main/jni/webp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by liuchun on 2017/10/16. 3 | // 4 | 5 | #ifndef GLIDE_PARENT_WEBP_H 6 | #define GLIDE_PARENT_WEBP_H 7 | 8 | int initWebPImage(JNIEnv *pEnv); 9 | 10 | int initWebpBitmapFactory(JNIEnv *env); 11 | 12 | #endif //GLIDE_PARENT_WEBP_H 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sample/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /library/src/main/res/drawable/shape_indicator_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /library/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /library/src/main/res/drawable/gray_square_circle_bg_white_stroke.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /library/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/demux/libwebpdemux.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libwebpdemux 7 | Description: Library for parsing the WebP graphics format container 8 | Version: @PACKAGE_VERSION@ 9 | Requires.private: libwebp >= 0.2.0 10 | Cflags: -I${includedir} 11 | Libs: -L${libdir} -l@webp_libname_prefix@webpdemux 12 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/progress/OnProgressListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.progress 2 | 3 | /** 4 | * @author 工藤 5 | * @email qinglingou@gmail.com 6 | */ 7 | interface OnProgressListener { 8 | fun onProgress( 9 | url: String?, 10 | isComplete: Boolean, 11 | percentage: Int, 12 | bytesRead: Long, 13 | totalBytes: Long 14 | ) 15 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/libwebp.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libwebp 7 | Description: Library for the WebP graphics format 8 | Version: @PACKAGE_VERSION@ 9 | Requires.private: libsharpyuv 10 | Cflags: -I${includedir} 11 | Libs: -L${libdir} -l@webp_libname_prefix@webp 12 | Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ 13 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/libwebpdecoder.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libwebpdecoder 7 | Description: Library for the WebP graphics format (decode only) 8 | Version: @PACKAGE_VERSION@ 9 | Cflags: -I${includedir} 10 | Libs: -L${libdir} -l@webp_libname_prefix@webpdecoder 11 | Libs.private: -lm @PTHREAD_CFLAGS@ @PTHREAD_LIBS@ 12 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/mux/libwebpmux.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | 6 | Name: libwebpmux 7 | Description: Library for manipulating the WebP graphics format container 8 | Version: @PACKAGE_VERSION@ 9 | Requires.private: libwebp >= 0.2.0 10 | Cflags: -I${includedir} 11 | Libs: -L${libdir} -l@webp_libname_prefix@webpmux 12 | Libs.private: -lm 13 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnPageFinishListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | 5 | /** 6 | * @author 工藤 7 | * @email qinglingou@gmail.com 8 | * cc.shinichi.library.view.listener 9 | * create at 2018/12/19 16:23 10 | * description: 页面关闭回调 11 | */ 12 | abstract class OnPageFinishListener { 13 | abstract fun onFinish(activity: Activity) 14 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnOutsidePhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * Callback when the user tapped outside of the photo 7 | */ 8 | public interface OnOutsidePhotoTapListener { 9 | 10 | /** 11 | * The outside of the photo has been tapped 12 | */ 13 | void onOutsidePhotoTap(ImageView imageView); 14 | } 15 | -------------------------------------------------------------------------------- /sample/src/main/java/cc/shinichi/bigimageviewpager/App.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.bigimageviewpager; 2 | 3 | import android.app.Application; 4 | 5 | /** 6 | * @author 工藤 7 | * @email qinglingou@gmail.com 8 | * cc.shinichi.bigimageviewpager 9 | * create at 2019/1/10 10:26 10 | * description: 11 | */ 12 | public class App extends Application { 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | } 18 | } -------------------------------------------------------------------------------- /sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /library/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | %1$s/%2$s 3 | 查看原图 4 | 5 | 开始下载 6 | 加载失败 7 | 保存失败 8 | 成功保存到:%1$s 9 | 您拒绝了存储权限,下载失败! 10 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnBigImageClickListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.View 5 | 6 | /** 7 | * @author 工藤 8 | * @email qinglingou@gmail.com 9 | * cc.shinichi.library.view.listener 10 | * create at 2018/12/19 16:23 11 | * description: 12 | */ 13 | interface OnBigImageClickListener { 14 | /** 15 | * 点击事件 16 | */ 17 | fun onClick(activity: Activity, view: View, position: Int) 18 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnBigImageLongClickListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.View 5 | 6 | /** 7 | * @author 工藤 8 | * @email qinglingou@gmail.com 9 | * cc.shinichi.library.view.listener 10 | * create at 2018/12/19 16:24 11 | * description: 12 | */ 13 | interface OnBigImageLongClickListener { 14 | /** 15 | * 长按事件 16 | */ 17 | fun onLongClick(activity: Activity, view: View, position: Int): Boolean 18 | } -------------------------------------------------------------------------------- /library/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnOriginProgressListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.View 5 | 6 | /** 7 | * 原图加载百分比接口 8 | * 9 | * @author 工藤 10 | * @email qinglingou@gmail.com 11 | */ 12 | interface OnOriginProgressListener { 13 | /** 14 | * 加载中 15 | */ 16 | fun progress(activity: Activity, parentView: View, progress: Int) 17 | 18 | /** 19 | * 加载完成 20 | */ 21 | fun finish(activity: Activity, parentView: View) 22 | } -------------------------------------------------------------------------------- /library/src/main/res/values-en-rUS/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | %1$s/%2$s 3 | Original image 4 | 5 | Download start 6 | Load failed 7 | Save failed 8 | Saved to:%1$s 9 | You denied the storage permission and the download failed! 10 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/bean/ImageInfo.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.bean 2 | 3 | import java.io.Serializable 4 | 5 | /** 6 | * @author 工藤 7 | * @email qinglingou@gmail.com 8 | * 图片信息 9 | */ 10 | class ImageInfo : Serializable { 11 | /** 12 | * 类型 13 | */ 14 | var type: Type = Type.IMAGE // image / video 15 | 16 | /** 17 | * 缩略图 18 | */ 19 | var thumbnailUrl: String = "" 20 | 21 | /** 22 | * 原图 23 | */ 24 | var originUrl: String = "" 25 | } 26 | 27 | enum class Type { 28 | IMAGE, VIDEO 29 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnDownloadListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | 5 | /** 6 | * @author 工藤 7 | * @email qinglingou@gmail.com 8 | * cc.shinichi.library.view.listener 9 | * create at 2018/12/19 16:23 10 | * description: 下载结果回调 11 | */ 12 | abstract class OnDownloadListener { 13 | abstract fun onDownloadStart(activity: Activity, position: Int) 14 | abstract fun onDownloadSuccess(activity: Activity, position: Int) 15 | abstract fun onDownloadFailed(activity: Activity, position: Int) 16 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/SimpleOnImageEventListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import cc.shinichi.library.view.subsampling.SubsamplingScaleImageView 4 | 5 | open class SimpleOnImageEventListener : SubsamplingScaleImageView.OnImageEventListener { 6 | 7 | override fun onReady() {} 8 | 9 | override fun onImageLoaded() {} 10 | 11 | override fun onPreviewLoadError(e: Exception) {} 12 | 13 | override fun onImageLoadError(e: Exception) {} 14 | 15 | override fun onTileLoadError(e: Exception) {} 16 | 17 | override fun onPreviewReleased() {} 18 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnViewDragListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | /** 4 | * Interface definition for a callback to be invoked when the photo is experiencing a drag event 5 | */ 6 | public interface OnViewDragListener { 7 | 8 | /** 9 | * Callback for when the photo is experiencing a drag event. This cannot be invoked when the 10 | * user is scaling. 11 | * 12 | * @param dx The change of the coordinates in the x-direction 13 | * @param dy The change of the coordinates in the y-direction 14 | */ 15 | void onDrag(float dx, float dy); 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnScaleChangedListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | /** 4 | * Interface definition for callback to be invoked when attached ImageView scale changes 5 | */ 6 | public interface OnScaleChangedListener { 7 | 8 | /** 9 | * Callback for when the scale changes 10 | * 11 | * @param scaleFactor the scale factor (less than 1 for zoom out, greater than 1 for zoom in) 12 | * @param focusX focal point X position 13 | * @param focusY focal point Y position 14 | */ 15 | void onScaleChange(float scaleFactor, float focusX, float focusY); 16 | } 17 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnDownloadClickListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.View 5 | 6 | /** 7 | * @author 工藤 8 | * @email qinglingou@gmail.com 9 | * cc.shinichi.library.view.listener 10 | * create at 2018/12/19 16:23 11 | * description: 12 | */ 13 | abstract class OnDownloadClickListener { 14 | /** 15 | * 点击事件 16 | * 是否拦截下载行为 17 | */ 18 | abstract fun onClick(activity: Activity, view: View, position: Int) 19 | 20 | /** 21 | * 是否拦截下载 22 | * 23 | * @return 24 | */ 25 | abstract val isInterceptDownload: Boolean 26 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnMatrixChangedListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.graphics.RectF; 4 | 5 | /** 6 | * Interface definition for a callback to be invoked when the internal Matrix has changed for 7 | * this View. 8 | */ 9 | public interface OnMatrixChangedListener { 10 | 11 | /** 12 | * Callback for when the Matrix displaying the Drawable has changed. This could be because 13 | * the View's bounds have changed, or the user has zoomed. 14 | * 15 | * @param rect - Rectangle displaying the Drawable's new bounds. 16 | */ 17 | void onMatrixChanged(RectF rect); 18 | } 19 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnPageDragListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import android.app.Activity 4 | import android.view.MotionEvent 5 | import android.view.View 6 | 7 | /** 8 | * @author 工藤 9 | * @email qinglingou@gmail.com 10 | * cc.shinichi.library.view.listener 11 | * create at 2018/12/19 16:23 12 | * description: 页面拖拽回调 13 | */ 14 | abstract class OnPageDragListener { 15 | abstract fun onDrag( 16 | activity: Activity, 17 | parentView: View, 18 | event: MotionEvent?, 19 | translationY: Float 20 | ) 21 | 22 | abstract fun onDragEnd(activity: Activity, parentView: View) 23 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnViewTapListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.view.View; 4 | 5 | public interface OnViewTapListener { 6 | 7 | /** 8 | * A callback to receive where the user taps on a ImageView. You will receive a callback if 9 | * the user taps anywhere on the view, tapping on 'whitespace' will not be ignored. 10 | * 11 | * @param view - View the user tapped. 12 | * @param x - where the user tapped from the left of the View. 13 | * @param y - where the user tapped from the top of the View. 14 | */ 15 | void onViewTap(View view, float x, float y); 16 | } 17 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/image_progress_layout_theme_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /library/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 15 | 16 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/demux/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) 2 | lib_LTLIBRARIES = libwebpdemux.la 3 | 4 | libwebpdemux_la_SOURCES = 5 | libwebpdemux_la_SOURCES += anim_decode.c demux.c 6 | 7 | libwebpdemuxinclude_HEADERS = 8 | libwebpdemuxinclude_HEADERS += ../webp/decode.h 9 | libwebpdemuxinclude_HEADERS += ../webp/demux.h 10 | libwebpdemuxinclude_HEADERS += ../webp/mux_types.h 11 | libwebpdemuxinclude_HEADERS += ../webp/types.h 12 | noinst_HEADERS = 13 | noinst_HEADERS += ../webp/format_constants.h 14 | 15 | libwebpdemux_la_LIBADD = ../libwebp.la 16 | libwebpdemux_la_LDFLAGS = -no-undefined -version-info 2:14:0 17 | libwebpdemuxincludedir = $(includedir)/webp 18 | pkgconfig_DATA = libwebpdemux.pc 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/ImagePreviewAdapter.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view 2 | 3 | import androidx.fragment.app.Fragment 4 | import androidx.fragment.app.FragmentManager 5 | import androidx.fragment.app.FragmentStatePagerAdapter 6 | 7 | /** 8 | * 文件名: ImagePreviewAdapter2.java 9 | * 作者: kirito 10 | * 描述: ViewPager适配器 11 | * 创建时间: 2024/11/25 12 | */ 13 | class ImagePreviewAdapter( 14 | fragmentManager: FragmentManager, 15 | private val fragmentList: MutableList 16 | ) : FragmentStatePagerAdapter(fragmentManager) { 17 | 18 | override fun getItem(position: Int): Fragment { 19 | return fragmentList[position] 20 | } 21 | 22 | override fun getCount(): Int { 23 | return fragmentList.size 24 | } 25 | } -------------------------------------------------------------------------------- /sample/src/main/res/xml/file_paths_public.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/HandlerHolder.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import android.os.Message 6 | import java.lang.ref.WeakReference 7 | 8 | /** 9 | * Handler相关工具类 10 | * 11 | * 实现 os.handler的callback接口 12 | * 13 | * 在需要处直接调用handler.sendmessage...即可 14 | * implements Callback 15 | * private HandlerUtils.HandlerHolder handlerHolder; 16 | * handlerHolder = new HandlerHolder(this); 17 | */ 18 | class HandlerHolder(listener: Callback?) : Handler(Looper.getMainLooper()) { 19 | 20 | private var mListenerWeakReference: WeakReference? = WeakReference(listener) 21 | 22 | override fun handleMessage(msg: Message) { 23 | mListenerWeakReference?.get()?.handleMessage(msg) 24 | } 25 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/image/UtilExt.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.image 2 | 3 | import androidx.core.net.toUri 4 | 5 | /** 6 | * 仓库: ... 7 | * 文件名: UtilExt.java 8 | * 作者: kirito 9 | * 描述: 常用扩展类 10 | * 创建时间: 2025/8/11 11 | */ 12 | object UtilExt { 13 | 14 | fun String.isLocalFile(): Boolean { 15 | val uri = this.toUri() 16 | val scheme = uri.scheme?.lowercase() 17 | 18 | return when { 19 | scheme == "file" -> true 20 | scheme == "content" -> true 21 | scheme == "android.resource" -> true 22 | scheme == null && this.startsWith("/") -> true 23 | this.startsWith("file:///android_asset/") -> true // 特殊处理 assets 24 | else -> false 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/mux/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) 2 | lib_LTLIBRARIES = libwebpmux.la 3 | 4 | libwebpmux_la_SOURCES = 5 | libwebpmux_la_SOURCES += anim_encode.c 6 | libwebpmux_la_SOURCES += animi.h 7 | libwebpmux_la_SOURCES += muxedit.c 8 | libwebpmux_la_SOURCES += muxi.h 9 | libwebpmux_la_SOURCES += muxinternal.c 10 | libwebpmux_la_SOURCES += muxread.c 11 | 12 | libwebpmuxinclude_HEADERS = 13 | libwebpmuxinclude_HEADERS += ../webp/mux.h 14 | libwebpmuxinclude_HEADERS += ../webp/mux_types.h 15 | libwebpmuxinclude_HEADERS += ../webp/types.h 16 | noinst_HEADERS = 17 | noinst_HEADERS += ../webp/format_constants.h 18 | 19 | libwebpmux_la_LIBADD = ../libwebp.la 20 | libwebpmux_la_LDFLAGS = -no-undefined -version-info 3:13:0 -lm 21 | libwebpmuxincludedir = $(includedir)/webp 22 | pkgconfig_DATA = libwebpmux.pc 23 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnSingleFlingListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.view.MotionEvent; 4 | 5 | /** 6 | * A callback to be invoked when the ImageView is flung with a single 7 | * touch 8 | */ 9 | public interface OnSingleFlingListener { 10 | 11 | /** 12 | * A callback to receive where the user flings on a ImageView. You will receive a callback if 13 | * the user flings anywhere on the view. 14 | * 15 | * @param e1 MotionEvent the user first touch. 16 | * @param e2 MotionEvent the user last touch. 17 | * @param velocityX distance of user's horizontal fling. 18 | * @param velocityY distance of user's vertical fling. 19 | */ 20 | boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY); 21 | } 22 | -------------------------------------------------------------------------------- /library/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_BUILD_SCRIPT := Android.mk 2 | 3 | APP_ABI := armeabi armeabi-v7a arm64-v8a x86 x86_64 4 | 5 | APP_MK_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 6 | NDK_MODULE_PATH := $(APP_MK_DIR) 7 | 8 | APP_OPTIM := release 9 | 10 | APP_STL := c++_static 11 | 12 | # Make sure every shared lib includes a .note.gnu.build-id header 13 | #APP_LDFLAGS := -Wl,--build-id 14 | 15 | #NDK_TOOLCHAIN_VERSION := clang 16 | 17 | # We link our libs with static stl implementation. Because of that we need to 18 | # hide all stl related symbols to make them unaccessible from the outside. 19 | # We also need to make sure that our library does not use any stl functions 20 | # coming from other stl implementations as well 21 | 22 | # This hides all symbols exported from libc++_static 23 | GLIDE_CPP_LDFLAGS := -Wl,--gc-sections,--exclude-libs,libc++_static.a -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/NetworkUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.content.Context 4 | import android.net.ConnectivityManager 5 | import android.net.NetworkInfo 6 | 7 | /** 8 | * @author 工藤 9 | * @email qinglingou@gmail.com 10 | */ 11 | object NetworkUtil { 12 | 13 | private val TAG = "NetworkUtil" 14 | 15 | fun isWiFi(context: Context): Boolean { 16 | val info = getActiveNetworkInfo(context) 17 | val isWifi = info != null && info.isAvailable && info.type == ConnectivityManager.TYPE_WIFI 18 | SLog.d(TAG, "isWiFi: $isWifi") 19 | return isWifi 20 | } 21 | 22 | private fun getActiveNetworkInfo(context: Context): NetworkInfo? { 23 | return (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo 24 | } 25 | } -------------------------------------------------------------------------------- /library/src/main/res/layout/sh_default_progress_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 21 | 22 | -------------------------------------------------------------------------------- /library/src/main/res/values/style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnPhotoTapListener.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.widget.ImageView; 4 | 5 | /** 6 | * A callback to be invoked when the Photo is tapped with a single 7 | * tap. 8 | */ 9 | public interface OnPhotoTapListener { 10 | 11 | /** 12 | * A callback to receive where the user taps on a photo. You will only receive a callback if 13 | * the user taps on the actual photo, tapping on 'whitespace' will be ignored. 14 | * 15 | * @param view ImageView the user tapped. 16 | * @param x where the user tapped from the of the Drawable, as percentage of the 17 | * Drawable width. 18 | * @param y where the user tapped from the top of the Drawable, as percentage of the 19 | * Drawable height. 20 | */ 21 | void onPhotoTap(ImageView view, float x, float y); 22 | } 23 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/WebpDrawableResource.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import com.bumptech.glide.load.engine.Initializable; 4 | import com.bumptech.glide.load.resource.drawable.DrawableResource; 5 | 6 | /** 7 | * @author liuchun 8 | */ 9 | public class WebpDrawableResource extends DrawableResource implements Initializable { 10 | 11 | public WebpDrawableResource(WebpDrawable drawable) { 12 | super(drawable); 13 | } 14 | 15 | public Class getResourceClass() { 16 | return WebpDrawable.class; 17 | } 18 | 19 | public int getSize() { 20 | return drawable.getSize(); 21 | } 22 | 23 | public void recycle() { 24 | drawable.stop(); 25 | drawable.recycle(); 26 | } 27 | 28 | public void initialize() { 29 | drawable.getFirstFrame().prepareToDraw(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/ToastUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.content.Context 4 | import android.os.Handler 5 | import android.os.Looper 6 | import android.widget.Toast 7 | 8 | /** 9 | * @author 工藤 10 | * @email qinglingou@gmail.com 11 | */ 12 | class ToastUtil { 13 | 14 | fun showShort(context: Context, text: String?) { 15 | HANDLER.post { Toast.makeText(context.applicationContext, text, Toast.LENGTH_SHORT).show() } 16 | } 17 | 18 | fun showLong(context: Context, text: String?) { 19 | HANDLER.post { Toast.makeText(context.applicationContext, text, Toast.LENGTH_LONG).show() } 20 | } 21 | 22 | private object InnerClass { 23 | val instance = ToastUtil() 24 | } 25 | 26 | companion object { 27 | private val HANDLER = Handler(Looper.getMainLooper()) 28 | 29 | @JvmStatic 30 | val instance: ToastUtil 31 | get() = InnerClass.instance 32 | } 33 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/OnGestureListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2011, 2012 Chris Banes. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package cc.shinichi.library.view.photoview; 17 | 18 | interface OnGestureListener { 19 | 20 | void onDrag(float dx, float dy); 21 | 22 | void onFling(float startX, float startY, float velocityX, float velocityY); 23 | 24 | void onScale(float scaleFactor, float focusX, float focusY); 25 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/progress/ProgressLibraryGlideModule.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.progress 2 | 3 | import android.content.Context 4 | import com.bumptech.glide.Glide 5 | import com.bumptech.glide.Registry 6 | import com.bumptech.glide.annotation.GlideModule 7 | import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader 8 | import com.bumptech.glide.load.model.GlideUrl 9 | import com.bumptech.glide.module.LibraryGlideModule 10 | import java.io.InputStream 11 | 12 | /** 13 | * @author 工藤 14 | * @email qinglingou@gmail.com 15 | */ 16 | @GlideModule 17 | class ProgressLibraryGlideModule : LibraryGlideModule() { 18 | 19 | override fun registerComponents(context: Context, glide: Glide, registry: Registry) { 20 | super.registerComponents(context, glide, registry) 21 | registry.replace( 22 | GlideUrl::class.java, 23 | InputStream::class.java, 24 | OkHttpUrlLoader.Factory(ProgressManager.okHttpClient) 25 | ) 26 | } 27 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/UIUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.content.Context 4 | import androidx.media3.common.util.UnstableApi 5 | import cc.shinichi.library.GlobalContext 6 | 7 | /** 8 | * 文件名: UIUtil.java 9 | * 作者: kirito 10 | * 描述: UI工具 11 | * 创建时间: 2024/11/25 12 | */ 13 | object UIUtil { 14 | 15 | fun dp2px(dp: Float): Int { 16 | val scale = GlobalContext.getContext().resources.displayMetrics.density 17 | return (dp * scale + 0.5f).toInt() 18 | } 19 | 20 | fun px2dp(px: Int): Float { 21 | val scale = GlobalContext.getContext().resources.displayMetrics.density 22 | return px / scale + 0.5f 23 | } 24 | 25 | fun sp2px(sp: Float): Int { 26 | val scale = GlobalContext.getContext().resources.displayMetrics.scaledDensity 27 | return (sp * scale + 0.5f).toInt() 28 | } 29 | 30 | fun px2sp(px: Int): Float { 31 | val scale = GlobalContext.getContext().resources.displayMetrics.scaledDensity 32 | return px / scale + 0.5f 33 | } 34 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/file/SingleMediaScanner.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.file 2 | 3 | import android.content.Context 4 | import android.media.MediaScannerConnection 5 | import android.media.MediaScannerConnection.MediaScannerConnectionClient 6 | import android.net.Uri 7 | 8 | /** 9 | * @author 工藤 10 | * @email qinglingou@gmail.com 11 | * create at 2018/5/4 16:50 12 | * description:媒体扫描 13 | */ 14 | class SingleMediaScanner( 15 | context: Context?, 16 | private val path: String, 17 | private val listener: ScanListener? 18 | ) : 19 | MediaScannerConnectionClient { 20 | 21 | private val mMs: MediaScannerConnection = MediaScannerConnection(context, this) 22 | 23 | override fun onMediaScannerConnected() { 24 | mMs.scanFile(path, null) 25 | } 26 | 27 | override fun onScanCompleted(path: String, uri: Uri) { 28 | mMs.disconnect() 29 | listener?.onScanFinish() 30 | } 31 | 32 | interface ScanListener { 33 | fun onScanFinish() 34 | } 35 | 36 | init { 37 | mMs.connect() 38 | } 39 | } -------------------------------------------------------------------------------- /sample/src/main/java/cc/shinichi/bigimageviewpager/glide/MyAppGlideModule.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.bigimageviewpager.glide; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.Glide; 8 | import com.bumptech.glide.Registry; 9 | import com.bumptech.glide.annotation.GlideModule; 10 | import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; 11 | import com.bumptech.glide.load.model.GlideUrl; 12 | import com.bumptech.glide.module.AppGlideModule; 13 | 14 | import java.io.InputStream; 15 | 16 | import cc.shinichi.library.glide.progress.ProgressManager; 17 | 18 | /** 19 | * @author kirito 20 | */ 21 | @GlideModule 22 | public class MyAppGlideModule extends AppGlideModule { 23 | 24 | @Override 25 | public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { 26 | super.registerComponents(context, glide, registry); 27 | 28 | // 替换底层网络框架为okhttp3 29 | registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(ProgressManager.getOkHttpClient())); 30 | } 31 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/subsampling/decoder/DecoderFactory.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.subsampling.decoder; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.lang.reflect.InvocationTargetException; 6 | 7 | /** 8 | * Interface for {@link ImageDecoder} and {@link ImageRegionDecoder} factories. 9 | * 10 | * @param the class of decoder that will be produced. 11 | */ 12 | public interface DecoderFactory { 13 | 14 | /** 15 | * Produce a new instance of a decoder with type {@link T}. 16 | * 17 | * @return a new instance of your decoder. 18 | * @throws IllegalAccessException if the factory class cannot be instantiated. 19 | * @throws InstantiationException if the factory class cannot be instantiated. 20 | * @throws NoSuchMethodException if the factory class cannot be instantiated. 21 | * @throws InvocationTargetException if the factory class cannot be instantiated. 22 | */ 23 | @NonNull 24 | T make() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /library/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | LOCAL_MODULE := glide-webp 5 | LOCAL_SRC_FILES := \ 6 | jni_common.cpp \ 7 | webp.cpp \ 8 | 9 | CXX11_FLAGS := -std=c++11 10 | LOCAL_CFLAGS += $(CXX11_FLAGS) 11 | #LOCAL_CFLAGS += -DLOG_TAG=\"libglide-webp\" 12 | LOCAL_CFLAGS += -fvisibility=hidden 13 | #LOCAL_CFLAGS += $(FRESCO_CPP_CFLAGS) 14 | LOCAL_EXPORT_CPPFLAGS := $(CXX11_FLAGS) 15 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) 16 | LOCAL_LDLIBS := -latomic -llog -ljnigraphics 17 | LOCAL_LDFLAGS += $(GLIDE_CPP_LDFLAGS) 18 | 19 | ifeq ($(TARGET_ARCH_ABI), arm64-v8a) 20 | LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 21 | else ifeq ($(TARGET_ARCH_ABI), x86_64) 22 | LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 23 | else ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) 24 | LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 25 | else ifeq ($(TARGET_ARCH_ABI), x86) 26 | LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 27 | endif 28 | 29 | LOCAL_STATIC_LIBRARIES += c++_static 30 | LOCAL_SHARED_LIBRARIES += webp 31 | 32 | include $(BUILD_SHARED_LIBRARY) 33 | $(call import-module, libwebp) -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/cache/DataCacheKey.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.cache 2 | 3 | import com.bumptech.glide.load.Key 4 | import java.security.MessageDigest 5 | 6 | /** 7 | * @author 工藤 8 | * @email qinglingou@gmail.com 9 | * create at 2018/5/10 11:12 10 | * description: 11 | */ 12 | class DataCacheKey(val sourceKey: Key, private val signature: Key) : Key { 13 | 14 | override fun equals(o: Any?): Boolean { 15 | if (o is DataCacheKey) { 16 | return sourceKey == o.sourceKey && signature == o.signature 17 | } 18 | return false 19 | } 20 | 21 | override fun hashCode(): Int { 22 | var result = sourceKey.hashCode() 23 | result = 31 * result + signature.hashCode() 24 | return result 25 | } 26 | 27 | override fun toString(): String { 28 | return "DataCacheKey{sourceKey=$sourceKey, signature=$signature}" 29 | } 30 | 31 | override fun updateDiskCacheKey(messageDigest: MessageDigest) { 32 | sourceKey.updateDiskCacheKey(messageDigest) 33 | signature.updateDiskCacheKey(messageDigest) 34 | } 35 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/filters_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Spatial prediction using various filters 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_UTILS_FILTERS_UTILS_H_ 15 | #define WEBP_UTILS_FILTERS_UTILS_H_ 16 | 17 | #include "src/webp/types.h" 18 | #include "src/dsp/dsp.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | // Fast estimate of a potentially good filter. 25 | WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t *data, 26 | int width, int height, int stride); 27 | 28 | #ifdef __cplusplus 29 | } // extern "C" 30 | #endif 31 | 32 | #endif // WEBP_UTILS_FILTERS_UTILS_H_ 33 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | # This is generated automatically by the Android Gradle plugin. 24 | -dontwarn org.conscrypt.Conscrypt 25 | -dontwarn org.conscrypt.OpenSSLProvider 26 | 27 | # 配置 28 | -keep class cc.shinichi.library.** { *; } 29 | -keep interface cc.shinichi.library.** { *; } 30 | -dontwarn cc.shinichi.library.** -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/libwebp.rc: -------------------------------------------------------------------------------- 1 | #define APSTUDIO_READONLY_SYMBOLS 2 | 3 | #include "winres.h" 4 | 5 | #undef APSTUDIO_READONLY_SYMBOLS 6 | 7 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 8 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 9 | 10 | VS_VERSION_INFO VERSIONINFO 11 | FILEVERSION 1,0,3,2 12 | PRODUCTVERSION 1,0,3,2 13 | FILEFLAGSMASK 0x3fL 14 | #ifdef _DEBUG 15 | FILEFLAGS 0x1L 16 | #else 17 | FILEFLAGS 0x0L 18 | #endif 19 | FILEOS 0x40004L 20 | FILETYPE 0x2L 21 | FILESUBTYPE 0x0L 22 | BEGIN 23 | BLOCK 24 | "StringFileInfo" 25 | BEGIN 26 | BLOCK 27 | "040904b0" 28 | BEGIN 29 | VALUE 30 | "CompanyName", "Google, Inc." 31 | VALUE "FileDescription", "libwebp DLL" 32 | VALUE "FileVersion", "1.3.2" 33 | VALUE "InternalName", "libwebp.dll" 34 | VALUE "LegalCopyright", "Copyright (C) 2023" 35 | VALUE "OriginalFilename", "libwebp.dll" 36 | VALUE "ProductName", "WebP Image Codec" 37 | VALUE "ProductVersion", "1.3.2" 38 | END 39 | END 40 | BLOCK "VarFileInfo" 41 | BEGIN 42 | VALUE 43 | "Translation", 0x409, 1200 44 | END 45 | END 46 | 47 | #endif // English (United States) resources 48 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/subsampling/decoder/ImageDecoder.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.subsampling.decoder; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.net.Uri; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | /** 10 | * Interface for image decoding classes, allowing the default {@link android.graphics.BitmapFactory} 11 | * based on the Skia library to be replaced with a custom class. 12 | */ 13 | public interface ImageDecoder { 14 | 15 | /** 16 | * Decode an image. The URI can be in one of the following formats: 17 | *
18 | * File: file:///scard/picture.jpg 19 | *
20 | * Asset: file:///android_asset/picture.png 21 | *
22 | * Resource: android.resource://com.example.app/drawable/picture 23 | * 24 | * @param context Application context 25 | * @param uri URI of the image 26 | * @return the decoded bitmap 27 | * @throws Exception if decoding fails. 28 | */ 29 | @NonNull 30 | Bitmap decode(Context context, @NonNull Uri uri) throws Exception; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/mux/libwebpmux.rc: -------------------------------------------------------------------------------- 1 | #define APSTUDIO_READONLY_SYMBOLS 2 | 3 | #include "winres.h" 4 | 5 | #undef APSTUDIO_READONLY_SYMBOLS 6 | 7 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 8 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 9 | 10 | VS_VERSION_INFO VERSIONINFO 11 | FILEVERSION 1,0,3,2 12 | PRODUCTVERSION 1,0,3,2 13 | FILEFLAGSMASK 0x3fL 14 | #ifdef _DEBUG 15 | FILEFLAGS 0x1L 16 | #else 17 | FILEFLAGS 0x0L 18 | #endif 19 | FILEOS 0x40004L 20 | FILETYPE 0x2L 21 | FILESUBTYPE 0x0L 22 | BEGIN 23 | BLOCK 24 | "StringFileInfo" 25 | BEGIN 26 | BLOCK 27 | "040904b0" 28 | BEGIN 29 | VALUE 30 | "CompanyName", "Google, Inc." 31 | VALUE "FileDescription", "libwebpmux DLL" 32 | VALUE "FileVersion", "1.3.2" 33 | VALUE "InternalName", "libwebpmux.dll" 34 | VALUE "LegalCopyright", "Copyright (C) 2023" 35 | VALUE "OriginalFilename", "libwebpmux.dll" 36 | VALUE "ProductName", "WebP Image Muxer" 37 | VALUE "ProductVersion", "1.3.2" 38 | END 39 | END 40 | BLOCK "VarFileInfo" 41 | BEGIN 42 | VALUE 43 | "Translation", 0x409, 1200 44 | END 45 | END 46 | 47 | #endif // English (United States) resources 48 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/demux/libwebpdemux.rc: -------------------------------------------------------------------------------- 1 | #define APSTUDIO_READONLY_SYMBOLS 2 | 3 | #include "winres.h" 4 | 5 | #undef APSTUDIO_READONLY_SYMBOLS 6 | 7 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 8 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 9 | 10 | VS_VERSION_INFO VERSIONINFO 11 | FILEVERSION 1,0,3,2 12 | PRODUCTVERSION 1,0,3,2 13 | FILEFLAGSMASK 0x3fL 14 | #ifdef _DEBUG 15 | FILEFLAGS 0x1L 16 | #else 17 | FILEFLAGS 0x0L 18 | #endif 19 | FILEOS 0x40004L 20 | FILETYPE 0x2L 21 | FILESUBTYPE 0x0L 22 | BEGIN 23 | BLOCK 24 | "StringFileInfo" 25 | BEGIN 26 | BLOCK 27 | "040904b0" 28 | BEGIN 29 | VALUE 30 | "CompanyName", "Google, Inc." 31 | VALUE "FileDescription", "libwebpdemux DLL" 32 | VALUE "FileVersion", "1.3.2" 33 | VALUE "InternalName", "libwebpdemux.dll" 34 | VALUE "LegalCopyright", "Copyright (C) 2023" 35 | VALUE "OriginalFilename", "libwebpdemux.dll" 36 | VALUE "ProductName", "WebP Image Demuxer" 37 | VALUE "ProductVersion", "1.3.2" 38 | END 39 | END 40 | BLOCK "VarFileInfo" 41 | BEGIN 42 | VALUE 43 | "Translation", 0x409, 1200 44 | END 45 | END 46 | 47 | #endif // English (United States) resources 48 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dec/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) 2 | noinst_LTLIBRARIES = libwebpdecode.la 3 | 4 | libwebpdecode_la_SOURCES = 5 | libwebpdecode_la_SOURCES += alpha_dec.c 6 | libwebpdecode_la_SOURCES += alphai_dec.h 7 | libwebpdecode_la_SOURCES += buffer_dec.c 8 | libwebpdecode_la_SOURCES += common_dec.h 9 | libwebpdecode_la_SOURCES += vp8_dec.h 10 | libwebpdecode_la_SOURCES += frame_dec.c 11 | libwebpdecode_la_SOURCES += idec_dec.c 12 | libwebpdecode_la_SOURCES += io_dec.c 13 | libwebpdecode_la_SOURCES += quant_dec.c 14 | libwebpdecode_la_SOURCES += tree_dec.c 15 | libwebpdecode_la_SOURCES += vp8_dec.c 16 | libwebpdecode_la_SOURCES += vp8i_dec.h 17 | libwebpdecode_la_SOURCES += vp8l_dec.c 18 | libwebpdecode_la_SOURCES += vp8li_dec.h 19 | libwebpdecode_la_SOURCES += webp_dec.c 20 | libwebpdecode_la_SOURCES += webpi_dec.h 21 | 22 | libwebpdecodeinclude_HEADERS = 23 | libwebpdecodeinclude_HEADERS += ../webp/decode.h 24 | libwebpdecodeinclude_HEADERS += ../webp/types.h 25 | noinst_HEADERS = 26 | noinst_HEADERS += ../webp/format_constants.h 27 | 28 | libwebpdecode_la_CPPFLAGS = $(AM_CPPFLAGS) 29 | libwebpdecodeincludedir = $(includedir)/webp 30 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/subsampling/ImageViewState.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.subsampling; 2 | 3 | import android.graphics.PointF; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * Wraps the scale, center and orientation of a displayed image for easy restoration on screen rotate. 11 | */ 12 | @SuppressWarnings("WeakerAccess") 13 | public class ImageViewState implements Serializable { 14 | 15 | private final float scale; 16 | 17 | private final float centerX; 18 | 19 | private final float centerY; 20 | 21 | private final int orientation; 22 | 23 | public ImageViewState(float scale, @NonNull PointF center, int orientation) { 24 | this.scale = scale; 25 | this.centerX = center.x; 26 | this.centerY = center.y; 27 | this.orientation = orientation; 28 | } 29 | 30 | public float getScale() { 31 | return scale; 32 | } 33 | 34 | @NonNull 35 | public PointF getCenter() { 36 | return new PointF(centerX, centerY); 37 | } 38 | 39 | public int getOrientation() { 40 | return orientation; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/Compat.java: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2011, 2012 Chris Banes. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package cc.shinichi.library.view.photoview; 17 | 18 | import android.annotation.TargetApi; 19 | import android.view.View; 20 | 21 | class Compat { 22 | 23 | private static final int SIXTY_FPS_INTERVAL = 1000 / 60; 24 | 25 | public static void postOnAnimation(View view, Runnable runnable) { 26 | postOnAnimationJellyBean(view, runnable); 27 | } 28 | 29 | @TargetApi(16) 30 | private static void postOnAnimationJellyBean(View view, Runnable runnable) { 31 | view.postOnAnimation(runnable); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/HackyViewPager.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.view.MotionEvent 6 | import androidx.viewpager.widget.ViewPager 7 | 8 | /** 9 | * Hacky fix for Issue #4 and 10 | * http://code.google.com/p/android/issues/detail?id=18990 11 | * 12 | * 13 | * ScaleGestureDetector seems to mess up the touch events, which means that 14 | * ViewGroups which make use of onInterceptTouchEvent throw a lot of 15 | * IllegalArgumentException: pointerIndex out of range. 16 | * 17 | * 18 | * There's not much I can do in my code for now, but we can mask the result by 19 | * just catching the problem and ignoring it. 20 | * 21 | * @author 工藤 22 | * @email qinglingou@gmail.com 23 | */ 24 | class HackyViewPager : ViewPager { 25 | 26 | constructor(context: Context) : super(context) 27 | 28 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 29 | 30 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { 31 | return try { 32 | super.onInterceptTouchEvent(ev) 33 | } catch (e: IllegalArgumentException) { 34 | false 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/libwebpdecoder.rc: -------------------------------------------------------------------------------- 1 | #define APSTUDIO_READONLY_SYMBOLS 2 | #include "winres.h" 3 | #undef APSTUDIO_READONLY_SYMBOLS 4 | 5 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 6 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 7 | 8 | VS_VERSION_INFO VERSIONINFO 9 | FILEVERSION 1,0,3,2 10 | PRODUCTVERSION 1,0,3,2 11 | FILEFLAGSMASK 0x3fL 12 | #ifdef _DEBUG 13 | FILEFLAGS 0x1L 14 | #else 15 | FILEFLAGS 0x0L 16 | #endif 17 | FILEOS 0x40004L 18 | FILETYPE 0x2L 19 | FILESUBTYPE 0x0L 20 | BEGIN 21 | BLOCK "StringFileInfo" 22 | BEGIN 23 | BLOCK "040904b0" 24 | BEGIN 25 | VALUE "CompanyName", "Google, Inc." 26 | VALUE "FileDescription", "libwebpdecoder DLL" 27 | VALUE "FileVersion", "1.3.2" 28 | VALUE "InternalName", "libwebpdecoder.dll" 29 | VALUE "LegalCopyright", "Copyright (C) 2023" 30 | VALUE "OriginalFilename", "libwebpdecoder.dll" 31 | VALUE "ProductName", "WebP Image Decoder" 32 | VALUE "ProductVersion", "1.3.2" 33 | END 34 | END 35 | BLOCK "VarFileInfo" 36 | BEGIN 37 | VALUE "Translation", 0x409, 1200 38 | END 39 | END 40 | 41 | #endif // English (United States) resources 42 | -------------------------------------------------------------------------------- /library/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | # Please add these rules to your existing keep rules in order to suppress warnings. 24 | # This is generated automatically by the Android Gradle plugin. 25 | -dontwarn java.lang.invoke.StringConcatFactory 26 | 27 | -keep public class com.bumptech.glide.integration.webp.WebpImage { *; } 28 | -keep public class com.bumptech.glide.integration.webp.WebpFrame { *; } 29 | -keep public class com.bumptech.glide.integration.webp.WebpBitmapFactory { *; } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/cache/SafeKeyGenerator.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.cache 2 | 3 | import com.bumptech.glide.load.Key 4 | import com.bumptech.glide.util.LruCache 5 | import com.bumptech.glide.util.Util 6 | import java.security.MessageDigest 7 | import java.security.NoSuchAlgorithmException 8 | 9 | /** 10 | * @author 工藤 11 | * @email qinglingou@gmail.com 12 | * create at 2018/5/10 11:11 13 | * description: 14 | */ 15 | class SafeKeyGenerator { 16 | 17 | private val loadIdToSafeHash = LruCache(1000) 18 | 19 | fun getSafeKey(key: Key): String? { 20 | var safeKey: String? 21 | synchronized(loadIdToSafeHash) { safeKey = loadIdToSafeHash[key] } 22 | if (safeKey == null) { 23 | try { 24 | val messageDigest = MessageDigest.getInstance("SHA-256") 25 | key.updateDiskCacheKey(messageDigest) 26 | safeKey = Util.sha256BytesToHex(messageDigest.digest()) 27 | } catch (e: NoSuchAlgorithmException) { 28 | e.printStackTrace() 29 | } catch (e: Exception) { 30 | e.printStackTrace() 31 | } 32 | synchronized(loadIdToSafeHash) { loadIdToSafeHash.put(key, safeKey) } 33 | } 34 | return safeKey 35 | } 36 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/FileTarget.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide 2 | 3 | import android.graphics.drawable.Drawable 4 | import com.bumptech.glide.request.Request 5 | import com.bumptech.glide.request.target.SizeReadyCallback 6 | import com.bumptech.glide.request.target.Target 7 | import com.bumptech.glide.request.transition.Transition 8 | import java.io.File 9 | 10 | /** 11 | * @author 工藤 12 | * @email qinglingou@gmail.com 13 | * cc.shinichi.library.glide 14 | * create at 2018/11/2 17:12 15 | * description: 16 | */ 17 | open class FileTarget : Target { 18 | 19 | override fun onLoadStarted(placeholder: Drawable?) {} 20 | 21 | override fun onLoadFailed(errorDrawable: Drawable?) {} 22 | 23 | override fun onResourceReady(resource: File, transition: Transition?) {} 24 | 25 | override fun onLoadCleared(placeholder: Drawable?) {} 26 | 27 | override fun getSize(cb: SizeReadyCallback) { 28 | cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL) 29 | } 30 | 31 | override fun removeCallback(cb: SizeReadyCallback) {} 32 | 33 | override fun getRequest(): Request? { 34 | return null 35 | } 36 | 37 | override fun setRequest(request: Request?) {} 38 | 39 | override fun onStart() {} 40 | 41 | override fun onStop() {} 42 | 43 | override fun onDestroy() {} 44 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/quant_levels_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Alpha plane quantization utility 11 | // 12 | // Author: Vikas Arora (vikasa@google.com) 13 | 14 | #ifndef WEBP_UTILS_QUANT_LEVELS_UTILS_H_ 15 | #define WEBP_UTILS_QUANT_LEVELS_UTILS_H_ 16 | 17 | #include 18 | 19 | #include "src/webp/types.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | // Replace the input 'data' of size 'width'x'height' with 'num-levels' 26 | // quantized values. If not NULL, 'sse' will contain the sum of squared error. 27 | // Valid range for 'num_levels' is [2, 256]. 28 | // Returns false in case of error (data is NULL, or parameters are invalid). 29 | int QuantizeLevels(uint8_t *const data, int width, int height, int num_levels, 30 | uint64_t *const sse); 31 | 32 | #ifdef __cplusplus 33 | } // extern "C" 34 | #endif 35 | 36 | #endif // WEBP_UTILS_QUANT_LEVELS_UTILS_H_ 37 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/WebpFrameInfo.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp; 2 | 3 | 4 | 5 | public class WebpFrameInfo { 6 | public final int frameNumber; 7 | public final int xOffset; 8 | public final int yOffset; 9 | public final int width; 10 | public final int height; 11 | public final int duration; 12 | public final boolean blendPreviousFrame; 13 | public final boolean disposeBackgroundColor; 14 | 15 | WebpFrameInfo(int frameNumber, WebpFrame webpFrame) { 16 | this.frameNumber = frameNumber; 17 | this.xOffset = webpFrame.getXOffest(); 18 | this.yOffset = webpFrame.getYOffest(); 19 | this.width = webpFrame.getWidth(); 20 | this.height = webpFrame.getHeight(); 21 | this.duration = webpFrame.getDurationMs(); 22 | this.blendPreviousFrame = webpFrame.isBlendWithPreviousFrame(); 23 | this.disposeBackgroundColor = webpFrame.shouldDisposeToBackgroundColor(); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "frameNumber=" + frameNumber + ", xOffset=" + xOffset + ", yOffset=" + yOffset 29 | + ", width=" + width + ", height=" + height + ", duration=" + duration + 30 | ", blendPreviousFrame=" + blendPreviousFrame + ", disposeBackgroundColor=" + disposeBackgroundColor; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/GlobalContext.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import androidx.media3.common.util.UnstableApi 6 | import androidx.media3.datasource.cache.CacheDataSource 7 | 8 | /** 9 | * 文件名: GlobalContext.java 10 | * 作者: kirito 11 | * 描述: 全局 12 | * 创建时间: 2024/11/27 13 | */ 14 | object GlobalContext { 15 | private var application: Application? = null 16 | @UnstableApi 17 | private var cacheDataSourceFactory: CacheDataSource.Factory? = null 18 | 19 | @UnstableApi 20 | fun init(app: Application, cacheDataSourceFactory: CacheDataSource.Factory) { 21 | if (application == null) { 22 | application = app 23 | } 24 | if (this.cacheDataSourceFactory == null) { 25 | this.cacheDataSourceFactory = cacheDataSourceFactory 26 | } 27 | } 28 | 29 | fun getApplication(): Application { 30 | return application ?: throw IllegalStateException("Application is not initialized") 31 | } 32 | 33 | @UnstableApi 34 | fun getCacheDataSourceFactory(): CacheDataSource.Factory { 35 | return cacheDataSourceFactory 36 | ?: throw IllegalStateException("CacheDataSourceFactory is not initialized") 37 | } 38 | 39 | fun getContext(): Context { 40 | return getApplication().applicationContext 41 | } 42 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/quant_levels_dec_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Alpha plane de-quantization utility 11 | // 12 | // Author: Vikas Arora (vikasa@google.com) 13 | 14 | #ifndef WEBP_UTILS_QUANT_LEVELS_DEC_UTILS_H_ 15 | #define WEBP_UTILS_QUANT_LEVELS_DEC_UTILS_H_ 16 | 17 | #include "src/webp/types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | // Apply post-processing to input 'data' of size 'width'x'height' assuming that 24 | // the source was quantized to a reduced number of levels. 'stride' is in bytes. 25 | // Strength is in [0..100] and controls the amount of dithering applied. 26 | // Returns false in case of error (data is NULL, invalid parameters, 27 | // malloc failure, ...). 28 | int WebPDequantizeLevels(uint8_t *const data, int width, int height, int stride, 29 | int strength); 30 | 31 | #ifdef __cplusplus 32 | } // extern "C" 33 | #endif 34 | 35 | #endif // WEBP_UTILS_QUANT_LEVELS_DEC_UTILS_H_ 36 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/photoview/Util.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.photoview; 2 | 3 | import android.view.MotionEvent; 4 | import android.widget.ImageView; 5 | 6 | class Util { 7 | 8 | static void checkZoomLevels(float minZoom, float midZoom, float maxZoom) { 9 | if (minZoom >= midZoom) { 10 | throw new IllegalArgumentException( 11 | "Minimum zoom has to be less than Medium zoom. Call setMinimumZoom() with a more appropriate value"); 12 | } else if (midZoom >= maxZoom) { 13 | throw new IllegalArgumentException( 14 | "Medium zoom has to be less than Maximum zoom. Call setMaximumZoom() with a more appropriate value"); 15 | } 16 | } 17 | 18 | static boolean hasDrawable(ImageView imageView) { 19 | return imageView.getDrawable() != null; 20 | } 21 | 22 | static boolean isSupportedScaleType(final ImageView.ScaleType scaleType) { 23 | if (scaleType == null) { 24 | return false; 25 | } 26 | switch (scaleType) { 27 | case MATRIX: 28 | throw new IllegalStateException("Matrix scale type is not supported"); 29 | } 30 | return true; 31 | } 32 | 33 | static int getPointerIndex(int action) { 34 | return (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/StreamAnimatedBitmapDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import com.bumptech.glide.load.Options; 9 | import com.bumptech.glide.load.ResourceDecoder; 10 | import com.bumptech.glide.load.engine.Resource; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | 15 | /** 16 | * Decodes Webp {@link Bitmap Bitmaps} from {@link InputStream InputStreams}. 17 | * For Animated Webp Images 18 | * 19 | * @author liuchun 20 | */ 21 | public class StreamAnimatedBitmapDecoder implements ResourceDecoder { 22 | private final AnimatedWebpBitmapDecoder bitmapDecoder; 23 | 24 | public StreamAnimatedBitmapDecoder(AnimatedWebpBitmapDecoder bitmapDecoder) { 25 | this.bitmapDecoder = bitmapDecoder; 26 | } 27 | 28 | @Override 29 | public boolean handles(@NonNull InputStream source, @NonNull Options options) throws IOException { 30 | return bitmapDecoder.handles(source, options); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Resource decode(@NonNull InputStream source, int width, int height, @NonNull Options options) throws IOException { 36 | return bitmapDecoder.decode(source, width, height, options); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/ByteBufferAnimatedBitmapDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import com.bumptech.glide.load.Options; 9 | import com.bumptech.glide.load.ResourceDecoder; 10 | import com.bumptech.glide.load.engine.Resource; 11 | 12 | import java.io.IOException; 13 | import java.nio.ByteBuffer; 14 | 15 | /** 16 | * Decodes webp {@link Bitmap Bitmaps} from {@link ByteBuffer ByteBuffers}. 17 | * For Animated Webp Images 18 | * 19 | * @author liuchun 20 | */ 21 | public class ByteBufferAnimatedBitmapDecoder implements ResourceDecoder { 22 | private final AnimatedWebpBitmapDecoder bitmapDecoder; 23 | 24 | public ByteBufferAnimatedBitmapDecoder(AnimatedWebpBitmapDecoder bitmapDecoder) { 25 | this.bitmapDecoder = bitmapDecoder; 26 | } 27 | 28 | @Override 29 | public boolean handles(@NonNull ByteBuffer source, @NonNull Options options) throws IOException { 30 | return bitmapDecoder.handles(source, options); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public Resource decode(@NonNull ByteBuffer source, int width, int height, @NonNull Options options) throws IOException { 36 | return bitmapDecoder.decode(source, width, height, options); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/WebpDrawableEncoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.util.Log; 4 | 5 | import com.bumptech.glide.load.EncodeStrategy; 6 | import com.bumptech.glide.load.Options; 7 | import com.bumptech.glide.load.ResourceEncoder; 8 | import com.bumptech.glide.load.engine.Resource; 9 | import com.bumptech.glide.util.ByteBufferUtil; 10 | 11 | import java.io.File; 12 | import java.io.IOException; 13 | 14 | /** 15 | * Writes the original bytes of a {@link WebpDrawable} to an 16 | * {@link java.io.OutputStream}. 17 | * 18 | * @author liuchun 19 | */ 20 | public class WebpDrawableEncoder implements ResourceEncoder { 21 | private static final String TAG = "WebpEncoder"; 22 | 23 | @Override 24 | public EncodeStrategy getEncodeStrategy(Options options) { 25 | return EncodeStrategy.SOURCE; 26 | } 27 | 28 | @Override 29 | public boolean encode(Resource data, File file, Options options) { 30 | WebpDrawable drawable = data.get(); 31 | boolean success = false; 32 | try { 33 | ByteBufferUtil.toFile(drawable.getBuffer(), file); 34 | success = true; 35 | } catch (IOException e) { 36 | if (Log.isLoggable(TAG, Log.WARN)) { 37 | Log.w(TAG, "Failed to encode WebP drawable data", e); 38 | } 39 | } 40 | return success; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/file/ExoCacheManager.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.file 2 | 3 | import android.content.Context 4 | import androidx.media3.database.StandaloneDatabaseProvider 5 | import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor 6 | import androidx.media3.datasource.cache.SimpleCache 7 | import java.io.File 8 | 9 | /** 10 | * 仓库: ... 11 | * 文件名: ExoCacheManager.java 12 | * 作者: kirito 13 | * 描述: 缓存管理器 14 | * 创建时间: 2025/11/13 15 | */ 16 | object ExoCacheManager { 17 | 18 | @Volatile 19 | private var simpleCache: SimpleCache? = null 20 | 21 | fun getSimpleCache(context: Context): SimpleCache { 22 | return simpleCache ?: synchronized(this) { 23 | simpleCache ?: run { 24 | val cacheDir = File(context.cacheDir, "exo_cache") 25 | val cacheEvictor = LeastRecentlyUsedCacheEvictor(2L * 1024 * 1024 * 1024) // 2GB 26 | val databaseProvider = StandaloneDatabaseProvider(context) 27 | SimpleCache(cacheDir, cacheEvictor, databaseProvider).also { 28 | simpleCache = it 29 | } 30 | } 31 | } 32 | } 33 | 34 | fun release() { 35 | try { 36 | simpleCache?.release() 37 | } catch (e: Exception) { 38 | e.printStackTrace() 39 | } finally { 40 | simpleCache = null 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/ByteBufferBitmapWebpDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.load.Options; 8 | import com.bumptech.glide.load.ResourceDecoder; 9 | import com.bumptech.glide.load.engine.Resource; 10 | import com.bumptech.glide.util.ByteBufferUtil; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | import java.nio.ByteBuffer; 15 | 16 | /** 17 | * Decodes webp {@link Bitmap Bitmaps} from {@link ByteBuffer ByteBuffers}. 18 | * For static lossless and transparent webp 19 | * 20 | * @author liuchun 21 | */ 22 | public class ByteBufferBitmapWebpDecoder implements ResourceDecoder { 23 | private final WebpDownsampler downsampler; 24 | 25 | public ByteBufferBitmapWebpDecoder(WebpDownsampler downsampler) { 26 | this.downsampler = downsampler; 27 | } 28 | 29 | @Override 30 | public boolean handles(@NonNull ByteBuffer source, @NonNull Options options) throws IOException { 31 | return downsampler.handles(source, options); 32 | } 33 | 34 | @Override 35 | public Resource decode(@NonNull ByteBuffer source, int width, int height, @NonNull Options options) throws IOException { 36 | InputStream is = ByteBufferUtil.toStream(source); 37 | return downsampler.decode(is, width, height, options); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/StreamBitmapWebpDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.load.Options; 8 | import com.bumptech.glide.load.ResourceDecoder; 9 | import com.bumptech.glide.load.engine.Resource; 10 | import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool; 11 | 12 | import java.io.IOException; 13 | import java.io.InputStream; 14 | 15 | /** 16 | * Decodes Webp {@link Bitmap Bitmaps} from {@link InputStream InputStreams}. 17 | * For static lossless and transparent webp 18 | * 19 | * @author liuchun 20 | */ 21 | public class StreamBitmapWebpDecoder implements ResourceDecoder { 22 | private final WebpDownsampler downsampler; 23 | private final ArrayPool byteArrayPool; 24 | 25 | public StreamBitmapWebpDecoder(WebpDownsampler downsampler, ArrayPool byteArrayPool) { 26 | this.downsampler = downsampler; 27 | this.byteArrayPool = byteArrayPool; 28 | } 29 | 30 | @Override 31 | public boolean handles(@NonNull InputStream source, @NonNull Options options) throws IOException { 32 | return downsampler.handles(source, options); 33 | } 34 | 35 | @Override 36 | public Resource decode(@NonNull InputStream source, int width, int height, @NonNull Options options) throws IOException { 37 | return downsampler.decode(source, width, height, options); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dsp/dec_sse41.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // SSE4 version of some decoding functions. 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #include "src/dsp/dsp.h" 15 | 16 | #if defined(WEBP_USE_SSE41) 17 | 18 | #include 19 | #include "src/dec/vp8i_dec.h" 20 | #include "src/utils/utils.h" 21 | 22 | static void HE16_SSE41(uint8_t* dst) { // horizontal 23 | int j; 24 | const __m128i kShuffle3 = _mm_set1_epi8(3); 25 | for (j = 16; j > 0; --j) { 26 | const __m128i in = _mm_cvtsi32_si128(WebPMemToInt32(dst - 4)); 27 | const __m128i values = _mm_shuffle_epi8(in, kShuffle3); 28 | _mm_storeu_si128((__m128i*)dst, values); 29 | dst += BPS; 30 | } 31 | } 32 | 33 | //------------------------------------------------------------------------------ 34 | // Entry point 35 | 36 | extern void VP8DspInitSSE41(void); 37 | 38 | WEBP_TSAN_IGNORE_FUNCTION void VP8DspInitSSE41(void) { 39 | VP8PredLuma16[3] = HE16_SSE41; 40 | } 41 | 42 | #else // !WEBP_USE_SSE41 43 | 44 | WEBP_DSP_INIT_STUB(VP8DspInitSSE41) 45 | 46 | #endif // WEBP_USE_SSE41 47 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/DeviceUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.text.TextUtils 4 | 5 | object DeviceUtil { 6 | 7 | /** 8 | * 是否为鸿蒙系统 9 | * 10 | * @return true为鸿蒙系统 11 | */ 12 | fun isHarmonyOs(): Boolean { 13 | return try { 14 | val buildExClass = Class.forName("com.huawei.system.BuildEx") 15 | val osBrand = buildExClass.getMethod("getOsBrand").invoke(buildExClass) 16 | osBrand?.toString()?.contains("harmony", ignoreCase = true) ?: false 17 | } catch (x: Throwable) { 18 | false 19 | } 20 | } 21 | 22 | /** 23 | * 获取鸿蒙系统版本号 24 | * 25 | * @return 版本号 26 | */ 27 | fun getHarmonyVersion(): String? { 28 | return getProp("hw_sc.build.os.version", "") 29 | } 30 | 31 | /** 32 | * 获取鸿蒙系统版本号 33 | * 鸿蒙2.0版本号为6 34 | * 鸿蒙3.0版本号为8 35 | * @return 版本号 36 | */ 37 | fun getHarmonyVersionCode(): Int { 38 | return getProp("hw_sc.build.os.apiversion", "0")?.toInt() ?: 0 39 | } 40 | 41 | private fun getProp(property: String, defaultValue: String): String? { 42 | try { 43 | val spClz = Class.forName("android.os.SystemProperties") 44 | val method = spClz.getDeclaredMethod("get", String::class.java) 45 | val value = method.invoke(spClz, property) as String 46 | return if (TextUtils.isEmpty(value)) { 47 | defaultValue 48 | } else value 49 | } catch (e: Throwable) { 50 | e.printStackTrace() 51 | } 52 | return defaultValue 53 | } 54 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) 2 | noinst_LTLIBRARIES = libwebputils.la 3 | 4 | if BUILD_LIBWEBPDECODER 5 | noinst_LTLIBRARIES += libwebputilsdecode.la 6 | endif 7 | 8 | common_HEADERS = ../webp/types.h 9 | commondir = $(includedir)/webp 10 | 11 | noinst_HEADERS = 12 | noinst_HEADERS += ../dsp/cpu.h 13 | noinst_HEADERS += ../dsp/dsp.h 14 | noinst_HEADERS += ../webp/decode.h 15 | noinst_HEADERS += ../webp/encode.h 16 | noinst_HEADERS += ../webp/format_constants.h 17 | 18 | COMMON_SOURCES = 19 | COMMON_SOURCES += bit_reader_utils.c 20 | COMMON_SOURCES += bit_reader_utils.h 21 | COMMON_SOURCES += bit_reader_inl_utils.h 22 | COMMON_SOURCES += color_cache_utils.c 23 | COMMON_SOURCES += color_cache_utils.h 24 | COMMON_SOURCES += endian_inl_utils.h 25 | COMMON_SOURCES += filters_utils.c 26 | COMMON_SOURCES += filters_utils.h 27 | COMMON_SOURCES += huffman_utils.c 28 | COMMON_SOURCES += huffman_utils.h 29 | COMMON_SOURCES += quant_levels_dec_utils.c 30 | COMMON_SOURCES += quant_levels_dec_utils.h 31 | COMMON_SOURCES += rescaler_utils.c 32 | COMMON_SOURCES += rescaler_utils.h 33 | COMMON_SOURCES += random_utils.c 34 | COMMON_SOURCES += random_utils.h 35 | COMMON_SOURCES += thread_utils.c 36 | COMMON_SOURCES += thread_utils.h 37 | COMMON_SOURCES += utils.c 38 | COMMON_SOURCES += utils.h 39 | 40 | ENC_SOURCES = 41 | ENC_SOURCES += bit_writer_utils.c 42 | ENC_SOURCES += bit_writer_utils.h 43 | ENC_SOURCES += huffman_encode_utils.c 44 | ENC_SOURCES += huffman_encode_utils.h 45 | ENC_SOURCES += quant_levels_utils.c 46 | ENC_SOURCES += quant_levels_utils.h 47 | 48 | libwebputils_la_SOURCES = $(COMMON_SOURCES) $(ENC_SOURCES) 49 | 50 | if BUILD_LIBWEBPDECODER 51 | libwebputilsdecode_la_SOURCES = $(COMMON_SOURCES) 52 | endif 53 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/mux/animi.h: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Internal header for animation related functions. 11 | // 12 | // Author: Hui Su (huisu@google.com) 13 | 14 | #ifndef WEBP_MUX_ANIMI_H_ 15 | #define WEBP_MUX_ANIMI_H_ 16 | 17 | #include "src/webp/mux.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | // Picks the optimal rectangle between two pictures, starting with initial 24 | // values of offsets and dimensions that are passed in. The initial 25 | // values will be clipped, if necessary, to make sure the rectangle is 26 | // within the canvas. "use_argb" must be true for both pictures. 27 | // Parameters: 28 | // prev_canvas, curr_canvas - (in) two input pictures to compare. 29 | // is_lossless, quality - (in) encoding settings. 30 | // x_offset, y_offset, width, height - (in/out) rectangle between the two 31 | // input pictures. 32 | // Returns true on success. 33 | int WebPAnimEncoderRefineRect( 34 | const struct WebPPicture *const prev_canvas, 35 | const struct WebPPicture *const curr_canvas, 36 | int is_lossless, float quality, int *const x_offset, int *const y_offset, 37 | int *const width, int *const height); 38 | 39 | #ifdef __cplusplus 40 | } // extern "C" 41 | #endif 42 | 43 | #endif // WEBP_MUX_ANIMI_H_ 44 | -------------------------------------------------------------------------------- /library/src/main/res/layout/sh_item_photoview.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 12 | 13 | 14 | 18 | 19 | 20 | 26 | 27 | 28 | 34 | 35 | 36 | 37 | 44 | 45 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/Makefile.am: -------------------------------------------------------------------------------- 1 | # The mux and demux libraries depend on libwebp, thus the '.' to force 2 | # the build order so it's available to them. 3 | SUBDIRS = dec enc dsp utils . 4 | if BUILD_MUX 5 | SUBDIRS += mux 6 | endif 7 | if BUILD_DEMUX 8 | SUBDIRS += demux 9 | endif 10 | 11 | lib_LTLIBRARIES = libwebp.la 12 | 13 | if BUILD_LIBWEBPDECODER 14 | lib_LTLIBRARIES += libwebpdecoder.la 15 | endif 16 | 17 | common_HEADERS = 18 | common_HEADERS += webp/decode.h 19 | common_HEADERS += webp/types.h 20 | commondir = $(includedir)/webp 21 | 22 | libwebp_la_SOURCES = 23 | libwebpinclude_HEADERS = 24 | libwebpinclude_HEADERS += webp/encode.h 25 | 26 | noinst_HEADERS = 27 | noinst_HEADERS += webp/format_constants.h 28 | 29 | libwebp_la_LIBADD = 30 | libwebp_la_LIBADD += dec/libwebpdecode.la 31 | libwebp_la_LIBADD += dsp/libwebpdsp.la 32 | libwebp_la_LIBADD += enc/libwebpencode.la 33 | libwebp_la_LIBADD += utils/libwebputils.la 34 | 35 | # Use '-no-undefined' to declare that libwebp does not depend on any libraries 36 | # other than the ones listed on the command line, i.e., after linking, it will 37 | # not have unresolved symbols. Some platforms (Windows among them) require all 38 | # symbols in shared libraries to be resolved at library creation. 39 | libwebp_la_LDFLAGS = -no-undefined -version-info 8:8:1 40 | libwebpincludedir = $(includedir)/webp 41 | pkgconfig_DATA = libwebp.pc 42 | 43 | if BUILD_LIBWEBPDECODER 44 | libwebpdecoder_la_SOURCES = 45 | 46 | libwebpdecoder_la_LIBADD = 47 | libwebpdecoder_la_LIBADD += dec/libwebpdecode.la 48 | libwebpdecoder_la_LIBADD += dsp/libwebpdspdecode.la 49 | libwebpdecoder_la_LIBADD += utils/libwebputilsdecode.la 50 | 51 | libwebpdecoder_la_LDFLAGS = -no-undefined -version-info 4:8:1 52 | pkgconfig_DATA += libwebpdecoder.pc 53 | endif 54 | 55 | ${pkgconfig_DATA}: ${top_builddir}/config.status 56 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dec/common_dec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Definitions and macros common to encoding and decoding 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_DEC_COMMON_DEC_H_ 15 | #define WEBP_DEC_COMMON_DEC_H_ 16 | 17 | // intra prediction modes 18 | enum { 19 | B_DC_PRED = 0, // 4x4 modes 20 | B_TM_PRED = 1, 21 | B_VE_PRED = 2, 22 | B_HE_PRED = 3, 23 | B_RD_PRED = 4, 24 | B_VR_PRED = 5, 25 | B_LD_PRED = 6, 26 | B_VL_PRED = 7, 27 | B_HD_PRED = 8, 28 | B_HU_PRED = 9, 29 | NUM_BMODES = B_HU_PRED + 1 - B_DC_PRED, // = 10 30 | 31 | // Luma16 or UV modes 32 | DC_PRED = B_DC_PRED, V_PRED = B_VE_PRED, 33 | H_PRED = B_HE_PRED, TM_PRED = B_TM_PRED, 34 | B_PRED = NUM_BMODES, // refined I4x4 mode 35 | NUM_PRED_MODES = 4, 36 | 37 | // special modes 38 | B_DC_PRED_NOTOP = 4, 39 | B_DC_PRED_NOLEFT = 5, 40 | B_DC_PRED_NOTOPLEFT = 6, 41 | NUM_B_DC_MODES = 7 42 | }; 43 | 44 | enum { 45 | MB_FEATURE_TREE_PROBS = 3, 46 | NUM_MB_SEGMENTS = 4, 47 | NUM_REF_LF_DELTAS = 4, 48 | NUM_MODE_LF_DELTAS = 4, // I4x4, ZERO, *, SPLIT 49 | MAX_NUM_PARTITIONS = 8, 50 | // Probabilities 51 | NUM_TYPES = 4, // 0: i16-AC, 1: i16-DC, 2:chroma-AC, 3:i4-AC 52 | NUM_BANDS = 8, 53 | NUM_CTX = 3, 54 | NUM_PROBAS = 11 55 | }; 56 | 57 | #endif // WEBP_DEC_COMMON_DEC_H_ 58 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/listener/OnBigImagePageChangeListener.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.listener 2 | 3 | import cc.shinichi.library.bean.ImageInfo 4 | 5 | /** 6 | * @author 工藤 7 | * @email qinglingou@gmail.com 8 | * cc.shinichi.library.view.listener 9 | * create at 2019/1/7 11:45 10 | * description: 11 | */ 12 | interface OnBigImagePageChangeListener { 13 | /** 14 | * This method will be invoked when the current page is scrolled, either as part 15 | * of a programmatically initiated smooth scroll or a user initiated touch scroll. 16 | * 17 | * @param position Position index of the first page currently being displayed. 18 | * Page position+1 will be visible if positionOffset is nonzero. 19 | * @param positionOffset Value from [0, 1) indicating the offset from the page at position. 20 | * @param positionOffsetPixels Value in pixels indicating the offset from position. 21 | */ 22 | fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) 23 | 24 | /** 25 | * This method will be invoked when a new page becomes selected. Animation is not 26 | * necessarily complete. 27 | * 28 | * @param position Position index of the new selected page. 29 | */ 30 | fun onPageSelected(position: Int, imageInfoList: MutableList) 31 | 32 | /** 33 | * Called when the scroll state changes. Useful for discovering when the user 34 | * begins dragging, when the pager is automatically settling to the current page, 35 | * or when it is fully stopped/idle. 36 | * 37 | * @param state The new scroll state. 38 | * @see ViewPager.SCROLL_STATE_IDLE 39 | * 40 | * @see ViewPager.SCROLL_STATE_DRAGGING 41 | * 42 | * @see ViewPager.SCROLL_STATE_SETTLING 43 | */ 44 | fun onPageScrollStateChanged(state: Int) 45 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dec/alphai_dec.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Alpha decoder: internal header. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_DEC_ALPHAI_DEC_H_ 15 | #define WEBP_DEC_ALPHAI_DEC_H_ 16 | 17 | #include "src/dec/webpi_dec.h" 18 | #include "src/utils/filters_utils.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | struct VP8LDecoder; // Defined in dec/vp8li.h. 25 | 26 | typedef struct ALPHDecoder ALPHDecoder; 27 | struct ALPHDecoder { 28 | int width_; 29 | int height_; 30 | int method_; 31 | WEBP_FILTER_TYPE filter_; 32 | int pre_processing_; 33 | struct VP8LDecoder *vp8l_dec_; 34 | VP8Io io_; 35 | int use_8b_decode_; // Although alpha channel requires only 1 byte per 36 | // pixel, sometimes VP8LDecoder may need to allocate 37 | // 4 bytes per pixel internally during decode. 38 | uint8_t *output_; 39 | const uint8_t *prev_line_; // last output row (or NULL) 40 | }; 41 | 42 | //------------------------------------------------------------------------------ 43 | // internal functions. Not public. 44 | 45 | // Deallocate memory associated to dec->alpha_plane_ decoding 46 | void WebPDeallocateAlphaMemory(VP8Decoder *const dec); 47 | 48 | //------------------------------------------------------------------------------ 49 | 50 | #ifdef __cplusplus 51 | } // extern "C" 52 | #endif 53 | 54 | #endif // WEBP_DEC_ALPHAI_DEC_H_ 55 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/enc/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CPPFLAGS += -I$(top_builddir) -I$(top_srcdir) 2 | noinst_LTLIBRARIES = libwebpencode.la 3 | 4 | libwebpencode_la_SOURCES = 5 | libwebpencode_la_SOURCES += alpha_enc.c 6 | libwebpencode_la_SOURCES += analysis_enc.c 7 | libwebpencode_la_SOURCES += backward_references_cost_enc.c 8 | libwebpencode_la_SOURCES += backward_references_enc.c 9 | libwebpencode_la_SOURCES += backward_references_enc.h 10 | libwebpencode_la_SOURCES += config_enc.c 11 | libwebpencode_la_SOURCES += cost_enc.c 12 | libwebpencode_la_SOURCES += cost_enc.h 13 | libwebpencode_la_SOURCES += filter_enc.c 14 | libwebpencode_la_SOURCES += frame_enc.c 15 | libwebpencode_la_SOURCES += histogram_enc.c 16 | libwebpencode_la_SOURCES += histogram_enc.h 17 | libwebpencode_la_SOURCES += iterator_enc.c 18 | libwebpencode_la_SOURCES += near_lossless_enc.c 19 | libwebpencode_la_SOURCES += picture_enc.c 20 | libwebpencode_la_SOURCES += picture_csp_enc.c 21 | libwebpencode_la_SOURCES += picture_psnr_enc.c 22 | libwebpencode_la_SOURCES += picture_rescale_enc.c 23 | libwebpencode_la_SOURCES += picture_tools_enc.c 24 | libwebpencode_la_SOURCES += predictor_enc.c 25 | libwebpencode_la_SOURCES += quant_enc.c 26 | libwebpencode_la_SOURCES += syntax_enc.c 27 | libwebpencode_la_SOURCES += token_enc.c 28 | libwebpencode_la_SOURCES += tree_enc.c 29 | libwebpencode_la_SOURCES += vp8i_enc.h 30 | libwebpencode_la_SOURCES += vp8l_enc.c 31 | libwebpencode_la_SOURCES += vp8li_enc.h 32 | libwebpencode_la_SOURCES += webp_enc.c 33 | 34 | libwebpencodeinclude_HEADERS = 35 | libwebpencodeinclude_HEADERS += ../webp/encode.h 36 | libwebpencodeinclude_HEADERS += ../webp/types.h 37 | noinst_HEADERS = 38 | noinst_HEADERS += ../webp/format_constants.h 39 | 40 | libwebpencode_la_LIBADD = ../../sharpyuv/libsharpyuv.la 41 | libwebpencode_la_LDFLAGS = -lm 42 | libwebpencode_la_CPPFLAGS = $(AM_CPPFLAGS) 43 | libwebpencodeincludedir = $(includedir)/webp 44 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/color_cache_utils.c: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Color Cache for WebP Lossless 11 | // 12 | // Author: Jyrki Alakuijala (jyrki@google.com) 13 | 14 | #include 15 | #include 16 | #include 17 | #include "src/utils/color_cache_utils.h" 18 | #include "src/utils/utils.h" 19 | 20 | //------------------------------------------------------------------------------ 21 | // VP8LColorCache. 22 | 23 | int VP8LColorCacheInit(VP8LColorCache *const color_cache, int hash_bits) { 24 | const int hash_size = 1 << hash_bits; 25 | assert(color_cache != NULL); 26 | assert(hash_bits > 0); 27 | color_cache->colors_ = (uint32_t *) WebPSafeCalloc( 28 | (uint64_t) hash_size, sizeof(*color_cache->colors_)); 29 | if (color_cache->colors_ == NULL) return 0; 30 | color_cache->hash_shift_ = 32 - hash_bits; 31 | color_cache->hash_bits_ = hash_bits; 32 | return 1; 33 | } 34 | 35 | void VP8LColorCacheClear(VP8LColorCache *const color_cache) { 36 | if (color_cache != NULL) { 37 | WebPSafeFree(color_cache->colors_); 38 | color_cache->colors_ = NULL; 39 | } 40 | } 41 | 42 | void VP8LColorCacheCopy(const VP8LColorCache *const src, 43 | VP8LColorCache *const dst) { 44 | assert(src != NULL); 45 | assert(dst != NULL); 46 | assert(src->hash_bits_ == dst->hash_bits_); 47 | memcpy(dst->colors_, src->colors_, 48 | ((size_t) 1u << dst->hash_bits_) * sizeof(*dst->colors_)); 49 | } 50 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/Utils.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.util.Log; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | /** 10 | * @author liuchun 11 | */ 12 | class Utils { 13 | private static final String TAG = "Utils"; 14 | 15 | static int getSampleSize(int srcWidth, int srcHeight, int targetWidth, int targetHeight) { 16 | int exactSampleSize = Math.min(srcHeight / targetHeight, 17 | srcWidth / targetWidth); 18 | int powerOfTwoSampleSize = exactSampleSize == 0 ? 0 : Integer.highestOneBit(exactSampleSize); 19 | // Although functionally equivalent to 0 for BitmapFactory, 1 is a safer default for our code 20 | // than 0. 21 | int sampleSize = Math.max(1, powerOfTwoSampleSize); 22 | if (Log.isLoggable(TAG, Log.VERBOSE) && sampleSize > 1) { 23 | Log.v(TAG, "Downsampling WEBP" 24 | + ", sampleSize: " + sampleSize 25 | + ", target dimens: [" + targetWidth + "x" + targetHeight + "]" 26 | + ", actual dimens: [" + srcWidth + "x" + srcHeight + "]"); 27 | } 28 | return sampleSize; 29 | } 30 | 31 | static byte[] inputStreamToBytes(InputStream is) { 32 | final int bufferSize = 16384; 33 | ByteArrayOutputStream buffer = new ByteArrayOutputStream(bufferSize); 34 | try { 35 | int nRead; 36 | byte[] data = new byte[bufferSize]; 37 | while ((nRead = is.read(data)) != -1) { 38 | buffer.write(data, 0, nRead); 39 | } 40 | buffer.flush(); 41 | } catch (IOException e) { 42 | if (Log.isLoggable(TAG, Log.WARN)) { 43 | Log.w(TAG, "Error reading data from stream", e); 44 | } 45 | return null; 46 | } 47 | return buffer.toByteArray(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/ImageLoader.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide 2 | 3 | import android.content.Context 4 | import androidx.appcompat.app.AppCompatActivity 5 | import cc.shinichi.library.glide.cache.DataCacheKey 6 | import cc.shinichi.library.glide.cache.SafeKeyGenerator 7 | import cc.shinichi.library.tool.common.SLog 8 | import com.bumptech.glide.Glide 9 | import com.bumptech.glide.disklrucache.DiskLruCache 10 | import com.bumptech.glide.load.engine.cache.DiskCache 11 | import com.bumptech.glide.load.model.GlideUrl 12 | import com.bumptech.glide.signature.EmptySignature 13 | import java.io.File 14 | 15 | /** 16 | * @author 工藤 17 | * @email qinglingou@gmail.com 18 | * cc.shinichi.library.glide 19 | * create at 2018/5/21 15:22 20 | * description: 21 | */ 22 | object ImageLoader { 23 | 24 | private const val TAG = "ImageLoader" 25 | 26 | /** 27 | * 获取是否有某张原图的缓存 28 | * 缓存模式必须是:DiskCacheStrategy.SOURCE 才能获取到缓存文件 29 | */ 30 | fun getGlideCacheFile(context: Context, url: String?): File? { 31 | try { 32 | val dataCacheKey = DataCacheKey(GlideUrl(url), EmptySignature.obtain()) 33 | val safeKeyGenerator = SafeKeyGenerator() 34 | val safeKey = safeKeyGenerator.getSafeKey(dataCacheKey) 35 | SLog.d(TAG, "safeKey = $safeKey") 36 | val file = File(context.cacheDir, DiskCache.Factory.DEFAULT_DISK_CACHE_DIR) 37 | val diskLruCache = 38 | DiskLruCache.open(file, 1, 1, DiskCache.Factory.DEFAULT_DISK_CACHE_SIZE.toLong()) 39 | val value = diskLruCache[safeKey] 40 | return value?.getFile(0) 41 | } catch (e: Exception) { 42 | e.printStackTrace() 43 | } 44 | return null 45 | } 46 | 47 | @JvmStatic 48 | fun clearMemory(activity: AppCompatActivity) { 49 | Glide.get(activity.applicationContext).clearMemory() 50 | } 51 | 52 | @JvmStatic 53 | fun cleanDiskCache(context: Context) { 54 | Thread { Glide.get(context.applicationContext).clearDiskCache() }.start() 55 | } 56 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/random_utils.c: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Pseudo-random utilities 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #include 15 | #include "src/utils/random_utils.h" 16 | 17 | //------------------------------------------------------------------------------ 18 | 19 | // 31b-range values 20 | static const uint32_t kRandomTable[VP8_RANDOM_TABLE_SIZE] = { 21 | 0x0de15230, 0x03b31886, 0x775faccb, 0x1c88626a, 0x68385c55, 0x14b3b828, 22 | 0x4a85fef8, 0x49ddb84b, 0x64fcf397, 0x5c550289, 0x4a290000, 0x0d7ec1da, 23 | 0x5940b7ab, 0x5492577d, 0x4e19ca72, 0x38d38c69, 0x0c01ee65, 0x32a1755f, 24 | 0x5437f652, 0x5abb2c32, 0x0faa57b1, 0x73f533e7, 0x685feeda, 0x7563cce2, 25 | 0x6e990e83, 0x4730a7ed, 0x4fc0d9c6, 0x496b153c, 0x4f1403fa, 0x541afb0c, 26 | 0x73990b32, 0x26d7cb1c, 0x6fcc3706, 0x2cbb77d8, 0x75762f2a, 0x6425ccdd, 27 | 0x24b35461, 0x0a7d8715, 0x220414a8, 0x141ebf67, 0x56b41583, 0x73e502e3, 28 | 0x44cab16f, 0x28264d42, 0x73baaefb, 0x0a50ebed, 0x1d6ab6fb, 0x0d3ad40b, 29 | 0x35db3b68, 0x2b081e83, 0x77ce6b95, 0x5181e5f0, 0x78853bbc, 0x009f9494, 30 | 0x27e5ed3c 31 | }; 32 | 33 | void VP8InitRandom(VP8Random *const rg, float dithering) { 34 | memcpy(rg->tab_, kRandomTable, sizeof(rg->tab_)); 35 | rg->index1_ = 0; 36 | rg->index2_ = 31; 37 | rg->amp_ = (dithering < 0.0) ? 0 38 | : (dithering > 1.0) ? (1 << VP8_RANDOM_DITHER_FIX) 39 | : (uint32_t)((1 << VP8_RANDOM_DITHER_FIX) * dithering); 40 | } 41 | 42 | //------------------------------------------------------------------------------ 43 | 44 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/subsampling/decoder/CompatDecoderFactory.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.subsampling.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import java.lang.reflect.Constructor; 8 | import java.lang.reflect.InvocationTargetException; 9 | 10 | /** 11 | * Compatibility factory to instantiate decoders with empty public constructors. 12 | * 13 | * @param The base type of the decoder this factory will produce. 14 | */ 15 | @SuppressWarnings("WeakerAccess") 16 | public class CompatDecoderFactory implements DecoderFactory { 17 | 18 | private final Class clazz; 19 | private final Bitmap.Config bitmapConfig; 20 | 21 | /** 22 | * Construct a factory for the given class. This must have a default constructor. 23 | * 24 | * @param clazz a class that implements {@link cc.shinichi.library.view.subsampling.decoder.ImageDecoder} or {@link cc.shinichi.library.view.subsampling.decoder.ImageRegionDecoder}. 25 | */ 26 | public CompatDecoderFactory(@NonNull Class clazz) { 27 | this(clazz, null); 28 | } 29 | 30 | /** 31 | * Construct a factory for the given class. This must have a constructor that accepts a {@link Bitmap.Config} instance. 32 | * 33 | * @param clazz a class that implements {@link ImageDecoder} or {@link ImageRegionDecoder}. 34 | * @param bitmapConfig bitmap configuration to be used when loading images. 35 | */ 36 | public CompatDecoderFactory(@NonNull Class clazz, Bitmap.Config bitmapConfig) { 37 | this.clazz = clazz; 38 | this.bitmapConfig = bitmapConfig; 39 | } 40 | 41 | @Override 42 | @NonNull 43 | public T make() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { 44 | if (bitmapConfig == null) { 45 | return clazz.newInstance(); 46 | } else { 47 | Constructor ctor = clazz.getConstructor(Bitmap.Config.class); 48 | return ctor.newInstance(bitmapConfig); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 37 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /library/src/main/res/layout/sh_media_controller.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 31 | 32 | 40 | 41 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/progress/ProgressResponseBody.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.progress 2 | 3 | import android.os.Handler 4 | import android.os.Looper 5 | import okhttp3.MediaType 6 | import okhttp3.ResponseBody 7 | import okio.Buffer 8 | import okio.BufferedSource 9 | import okio.ForwardingSource 10 | import okio.Okio 11 | import okio.Source 12 | import java.io.IOException 13 | 14 | /** 15 | * @author 工藤 16 | * @email qinglingou@gmail.com 17 | */ 18 | class ProgressResponseBody internal constructor( 19 | private val url: String, 20 | private val internalProgressListener: InternalProgressListener?, 21 | private val responseBody: ResponseBody 22 | ) : ResponseBody() { 23 | 24 | override fun contentType(): MediaType? { 25 | return responseBody.contentType() 26 | } 27 | 28 | override fun contentLength(): Long { 29 | return responseBody.contentLength() 30 | } 31 | 32 | override fun source(): BufferedSource { 33 | val bufferedSource = Okio.buffer(source(responseBody.source())) 34 | return bufferedSource 35 | } 36 | 37 | private fun source(source: Source): Source { 38 | return object : ForwardingSource(source) { 39 | var totalBytesRead: Long = 0 40 | var lastTotalBytesRead: Long = 0 41 | 42 | @Throws(IOException::class) 43 | override fun read(sink: Buffer, byteCount: Long): Long { 44 | val bytesRead = super.read(sink, byteCount) 45 | totalBytesRead += if (bytesRead == -1L) 0 else bytesRead 46 | if (lastTotalBytesRead != totalBytesRead) { 47 | lastTotalBytesRead = totalBytesRead 48 | mainThreadHandler.post { 49 | internalProgressListener?.onProgress(url, totalBytesRead, contentLength()) 50 | } 51 | } 52 | return bytesRead 53 | } 54 | } 55 | } 56 | 57 | internal interface InternalProgressListener { 58 | fun onProgress(url: String?, bytesRead: Long, totalBytes: Long) 59 | } 60 | 61 | companion object { 62 | private val mainThreadHandler = Handler(Looper.getMainLooper()) 63 | } 64 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/SLog.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.util.Log 4 | import cc.shinichi.library.BuildConfig 5 | 6 | /** 7 | * 文件名: SLog.java 8 | * 作者: kirito 9 | * 描述: 内部日志打印,可以根据是否debug来决定是否打印 10 | * 创建时间: 2024/11/22 11 | */ 12 | object SLog { 13 | 14 | private const val TAG = "SLog" 15 | private val isDebug = BuildConfig.DEBUG 16 | 17 | fun d(msg: String) { 18 | if (isDebug) { 19 | Log.d(TAG, msg) 20 | } 21 | } 22 | 23 | fun e(msg: String) { 24 | if (isDebug) { 25 | Log.e(TAG, msg) 26 | } 27 | } 28 | 29 | fun i(msg: String) { 30 | if (isDebug) { 31 | Log.i(TAG, msg) 32 | } 33 | } 34 | 35 | fun w(msg: String) { 36 | if (isDebug) { 37 | Log.w(TAG, msg) 38 | } 39 | } 40 | 41 | fun v(msg: String) { 42 | if (isDebug) { 43 | Log.v(TAG, msg) 44 | } 45 | } 46 | 47 | fun d(tag: String, msg: String) { 48 | if (isDebug) { 49 | Log.d(tag, msg) 50 | } 51 | } 52 | 53 | fun e(tag: String, msg: String) { 54 | if (isDebug) { 55 | Log.e(tag, msg) 56 | } 57 | } 58 | 59 | fun i(tag: String, msg: String) { 60 | if (isDebug) { 61 | Log.i(tag, msg) 62 | } 63 | } 64 | 65 | fun w(tag: String, msg: String) { 66 | if (isDebug) { 67 | Log.w(tag, msg) 68 | } 69 | } 70 | 71 | fun v(tag: String, msg: String) { 72 | if (isDebug) { 73 | Log.v(tag, msg) 74 | } 75 | } 76 | 77 | fun d(tag: String, msg: String, tr: Throwable) { 78 | if (isDebug) { 79 | Log.d(tag, msg, tr) 80 | } 81 | } 82 | 83 | fun e(tag: String, msg: String, tr: Throwable) { 84 | if (isDebug) { 85 | Log.e(tag, msg, tr) 86 | } 87 | } 88 | 89 | fun i(tag: String, msg: String, tr: Throwable) { 90 | if (isDebug) { 91 | Log.i(tag, msg, tr) 92 | } 93 | } 94 | 95 | fun w(tag: String, msg: String, tr: Throwable?) { 96 | if (isDebug) { 97 | Log.w(tag, msg, tr) 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/huffman_encode_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Author: Jyrki Alakuijala (jyrki@google.com) 11 | // 12 | // Entropy encoding (Huffman) for webp lossless 13 | 14 | #ifndef WEBP_UTILS_HUFFMAN_ENCODE_UTILS_H_ 15 | #define WEBP_UTILS_HUFFMAN_ENCODE_UTILS_H_ 16 | 17 | #include "src/webp/types.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | // Struct for holding the tree header in coded form. 24 | typedef struct { 25 | uint8_t code; // value (0..15) or escape code (16,17,18) 26 | uint8_t extra_bits; // extra bits for escape codes 27 | } HuffmanTreeToken; 28 | 29 | // Struct to represent the tree codes (depth and bits array). 30 | typedef struct { 31 | int num_symbols; // Number of symbols. 32 | uint8_t *code_lengths; // Code lengths of the symbols. 33 | uint16_t *codes; // Symbol Codes. 34 | } HuffmanTreeCode; 35 | 36 | // Struct to represent the Huffman tree. 37 | typedef struct { 38 | uint32_t total_count_; // Symbol frequency. 39 | int value_; // Symbol value. 40 | int pool_index_left_; // Index for the left sub-tree. 41 | int pool_index_right_; // Index for the right sub-tree. 42 | } HuffmanTree; 43 | 44 | // Turn the Huffman tree into a token sequence. 45 | // Returns the number of tokens used. 46 | int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode *const tree, 47 | HuffmanTreeToken *tokens, int max_tokens); 48 | 49 | // Create an optimized tree, and tokenize it. 50 | // 'buf_rle' and 'huff_tree' are pre-allocated and the 'tree' is the constructed 51 | // huffman code tree. 52 | void VP8LCreateHuffmanTree(uint32_t *const histogram, int tree_depth_limit, 53 | uint8_t *const buf_rle, HuffmanTree *const huff_tree, 54 | HuffmanTreeCode *const huff_code); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | 60 | #endif // WEBP_UTILS_HUFFMAN_ENCODE_UTILS_H_ 61 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/StreamWebpDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | 7 | import com.bumptech.glide.integration.webp.WebpHeaderParser; 8 | import com.bumptech.glide.load.Option; 9 | import com.bumptech.glide.load.Options; 10 | import com.bumptech.glide.load.ResourceDecoder; 11 | import com.bumptech.glide.load.engine.Resource; 12 | import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool; 13 | 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.nio.ByteBuffer; 17 | 18 | 19 | /** 20 | * An {@link ResourceDecoder} that decodes {@link 21 | * WebpDrawable} from {@link InputStream} data 22 | * 23 | * @author liuchun 24 | */ 25 | public class StreamWebpDecoder implements ResourceDecoder { 26 | public static final Option DISABLE_ANIMATION = Option.memory( 27 | "com.bumptech.glide.integration.webp.decoder.StreamWebpDecoder.DisableAnimation", false); 28 | 29 | private final ResourceDecoder byteBufferDecoder; 30 | private final ArrayPool byteArrayPool; 31 | 32 | public StreamWebpDecoder(ResourceDecoder byteBufferDecoder, ArrayPool byteArrayPool) { 33 | this.byteBufferDecoder = byteBufferDecoder; 34 | this.byteArrayPool = byteArrayPool; 35 | } 36 | 37 | 38 | @Override 39 | public boolean handles(@NonNull InputStream inputStream, @NonNull Options options) throws IOException { 40 | if (options.get(DISABLE_ANIMATION)) { 41 | return false; 42 | } 43 | 44 | WebpHeaderParser.WebpImageType webpType = WebpHeaderParser.getType(inputStream, byteArrayPool); 45 | return WebpHeaderParser.isAnimatedWebpType(webpType); 46 | } 47 | 48 | @Nullable 49 | @Override 50 | public Resource decode(@NonNull InputStream inputStream, int width, int height, @NonNull Options options) throws IOException { 51 | 52 | byte[] data = Utils.inputStreamToBytes(inputStream); 53 | if (data == null) { 54 | return null; 55 | } 56 | ByteBuffer byteBuffer = ByteBuffer.wrap(data); 57 | 58 | return byteBufferDecoder.decode(byteBuffer, width, height, options); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/random_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2013 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Pseudo-random utilities 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_UTILS_RANDOM_UTILS_H_ 15 | #define WEBP_UTILS_RANDOM_UTILS_H_ 16 | 17 | #include 18 | #include "src/webp/types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #define VP8_RANDOM_DITHER_FIX 8 // fixed-point precision for dithering 25 | #define VP8_RANDOM_TABLE_SIZE 55 26 | 27 | typedef struct { 28 | int index1_, index2_; 29 | uint32_t tab_[VP8_RANDOM_TABLE_SIZE]; 30 | int amp_; 31 | } VP8Random; 32 | 33 | // Initializes random generator with an amplitude 'dithering' in range [0..1]. 34 | void VP8InitRandom(VP8Random *const rg, float dithering); 35 | 36 | // Returns a centered pseudo-random number with 'num_bits' amplitude. 37 | // (uses D.Knuth's Difference-based random generator). 38 | // 'amp' is in VP8_RANDOM_DITHER_FIX fixed-point precision. 39 | static WEBP_INLINE int VP8RandomBits2(VP8Random *const rg, int num_bits, 40 | int amp) { 41 | int diff; 42 | assert(num_bits + VP8_RANDOM_DITHER_FIX <= 31); 43 | diff = rg->tab_[rg->index1_] - rg->tab_[rg->index2_]; 44 | if (diff < 0) diff += (1u << 31); 45 | rg->tab_[rg->index1_] = diff; 46 | if (++rg->index1_ == VP8_RANDOM_TABLE_SIZE) rg->index1_ = 0; 47 | if (++rg->index2_ == VP8_RANDOM_TABLE_SIZE) rg->index2_ = 0; 48 | // sign-extend, 0-center 49 | diff = (int) ((uint32_t) diff << 1) >> (32 - num_bits); 50 | diff = (diff * amp) >> VP8_RANDOM_DITHER_FIX; // restrict range 51 | diff += 1 << (num_bits - 1); // shift back to 0.5-center 52 | return diff; 53 | } 54 | 55 | static WEBP_INLINE int VP8RandomBits(VP8Random *const rg, int num_bits) { 56 | return VP8RandomBits2(rg, num_bits, rg->amp_); 57 | } 58 | 59 | #ifdef __cplusplus 60 | } // extern "C" 61 | #endif 62 | 63 | #endif // WEBP_UTILS_RANDOM_UTILS_H_ 64 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/PhoneUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.content.res.Resources 6 | import android.util.DisplayMetrics 7 | import android.view.Display 8 | import android.view.WindowManager 9 | import cc.shinichi.library.GlobalContext 10 | 11 | 12 | /** 13 | * @author 工藤 14 | * @email qinglingou@gmail.com 15 | * cc.shinichi.drawlongpicturedemo.util 16 | * create at 2018/8/27 17:53 17 | * description: 18 | */ 19 | object PhoneUtil { 20 | 21 | private val TAG = PhoneUtil::class.java.simpleName 22 | 23 | fun getPhoneWid(): Int { 24 | val wm = GlobalContext.getContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager 25 | val display: Display = wm.defaultDisplay 26 | var screenWidth = 0 27 | val dm = DisplayMetrics() 28 | display.getRealMetrics(dm) 29 | screenWidth = dm.widthPixels 30 | return screenWidth.apply { 31 | SLog.d(TAG, "getPhoneWid: $this") 32 | } 33 | } 34 | 35 | fun getPhoneHei(): Int { 36 | val wm = GlobalContext.getContext().getSystemService(Context.WINDOW_SERVICE) as WindowManager 37 | val display = wm.defaultDisplay 38 | var screenHeight = 0 39 | 40 | val dm = DisplayMetrics() 41 | display.getRealMetrics(dm) 42 | screenHeight = dm.heightPixels 43 | return screenHeight.apply { 44 | SLog.d(TAG, "getPhoneHei: $this") 45 | } 46 | } 47 | 48 | fun getPhoneRatio(): Float { 49 | return (getPhoneHei().toFloat() / getPhoneWid().toFloat()).apply { 50 | SLog.d(TAG, "getPhoneRatio: $this") 51 | } 52 | } 53 | 54 | @SuppressLint("InternalInsetResource") 55 | fun getNavBarHeight(): Int { 56 | val resources: Resources = GlobalContext.getContext().resources 57 | val resourceId: Int = resources.getIdentifier("navigation_bar_height", "dimen", "android") 58 | return resources.getDimensionPixelSize(resourceId) 59 | } 60 | 61 | @SuppressLint("InternalInsetResource") 62 | fun getStatusBarHeight(): Int { 63 | val resources: Resources = GlobalContext.getContext().resources 64 | val resourceId: Int = resources.getIdentifier("status_bar_height", "dimen", "android") 65 | return resources.getDimensionPixelSize(resourceId) 66 | } 67 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/SSLSocketClient.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide 2 | 3 | import android.annotation.SuppressLint 4 | import java.security.SecureRandom 5 | import java.security.cert.X509Certificate 6 | import javax.net.ssl.HostnameVerifier 7 | import javax.net.ssl.SSLContext 8 | import javax.net.ssl.SSLSocketFactory 9 | import javax.net.ssl.TrustManager 10 | import javax.net.ssl.X509TrustManager 11 | 12 | /** 13 | * @author 工藤 14 | * @email qinglingou@gmail.com 15 | * cc.shinichi.library.glide.progress 16 | * create at 2018/11/2 15:55 17 | * description: 18 | */ 19 | object SSLSocketClient { 20 | 21 | val sSLSocketFactory: SSLSocketFactory 22 | get() = try { 23 | val sslContext = SSLContext.getInstance("SSL") 24 | sslContext.init(null, trustManager, SecureRandom()) 25 | sslContext.socketFactory 26 | } catch (e: Exception) { 27 | throw RuntimeException(e) 28 | } 29 | 30 | private val trustManager: Array 31 | get() = arrayOf( 32 | @SuppressLint("CustomX509TrustManager") 33 | object : X509TrustManager { 34 | @SuppressLint("TrustAllX509TrustManager") 35 | override fun checkClientTrusted(chain: Array, authType: String) { 36 | } 37 | 38 | @SuppressLint("TrustAllX509TrustManager") 39 | override fun checkServerTrusted(chain: Array, authType: String) { 40 | } 41 | 42 | override fun getAcceptedIssuers(): Array { 43 | return arrayOf() 44 | } 45 | } 46 | ) 47 | 48 | @SuppressLint("CustomX509TrustManager") 49 | fun geX509tTrustManager(): X509TrustManager { 50 | return object : X509TrustManager { 51 | @SuppressLint("TrustAllX509TrustManager") 52 | override fun checkClientTrusted(chain: Array, authType: String) { 53 | } 54 | 55 | @SuppressLint("TrustAllX509TrustManager") 56 | override fun checkServerTrusted(chain: Array, authType: String) { 57 | } 58 | 59 | override fun getAcceptedIssuers(): Array { 60 | return arrayOf() 61 | } 62 | } 63 | } 64 | 65 | val hostnameVerifier: HostnameVerifier 66 | get() = HostnameVerifier { _, _ -> true } 67 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/webp/types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Common types + memory wrappers 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_WEBP_TYPES_H_ 15 | #define WEBP_WEBP_TYPES_H_ 16 | 17 | #include // for size_t 18 | 19 | #ifndef _MSC_VER 20 | 21 | #include 22 | 23 | #if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \ 24 | (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) 25 | #define WEBP_INLINE inline 26 | #else 27 | #define WEBP_INLINE 28 | #endif 29 | #else 30 | typedef signed char int8_t; 31 | typedef unsigned char uint8_t; 32 | typedef signed short int16_t; 33 | typedef unsigned short uint16_t; 34 | typedef signed int int32_t; 35 | typedef unsigned int uint32_t; 36 | typedef unsigned long long int uint64_t; 37 | typedef long long int int64_t; 38 | #define WEBP_INLINE __forceinline 39 | #endif /* _MSC_VER */ 40 | 41 | #ifndef WEBP_EXTERN 42 | // This explicitly marks library functions and allows for changing the 43 | // signature for e.g., Windows DLL builds. 44 | # if defined(__GNUC__) && __GNUC__ >= 4 45 | # define WEBP_EXTERN extern __attribute__ ((visibility ("default"))) 46 | # else 47 | # if defined(_MSC_VER) && defined(WEBP_DLL) 48 | # define WEBP_EXTERN __declspec(dllexport) 49 | # else 50 | # define WEBP_EXTERN extern 51 | # endif 52 | # endif /* __GNUC__ >= 4 */ 53 | #endif /* WEBP_EXTERN */ 54 | 55 | // Macro to check ABI compatibility (same major revision number) 56 | #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) 57 | 58 | #ifdef __cplusplus 59 | extern "C" { 60 | #endif 61 | 62 | // Allocates 'size' bytes of memory. Returns NULL upon error. Memory 63 | // must be deallocated by calling WebPFree(). This function is made available 64 | // by the core 'libwebp' library. 65 | WEBP_EXTERN void *WebPMalloc(size_t size); 66 | 67 | // Releases memory returned by the WebPDecode*() functions (from decode.h). 68 | WEBP_EXTERN void WebPFree(void *ptr); 69 | 70 | #ifdef __cplusplus 71 | } // extern "C" 72 | #endif 73 | 74 | #endif // WEBP_WEBP_TYPES_H_ 75 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/tool/common/HttpUtil.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.tool.common 2 | 3 | import cc.shinichi.library.ImagePreview 4 | import java.io.BufferedInputStream 5 | import java.io.File 6 | import java.io.FileOutputStream 7 | import java.io.IOException 8 | import java.io.OutputStream 9 | import java.net.HttpURLConnection 10 | import java.net.MalformedURLException 11 | import java.net.URL 12 | import java.net.URLDecoder 13 | 14 | /** 15 | * HttpURLConnection 下载图片 16 | */ 17 | object HttpUtil { 18 | 19 | /** 20 | * @param urlPath 下载路径 21 | * @param downloadDir 下载存放目录 22 | * @return 返回下载文件 23 | */ 24 | fun downloadFile(urlPath: String?, fileFullName: String, downloadDir: String): File? { 25 | var file: File? = null 26 | try { 27 | // 统一资源 28 | val url = URL(urlPath) 29 | // 连接类的父类,抽象类 30 | val urlConnection = url.openConnection() 31 | // http的连接类 32 | val httpURLConnection = urlConnection as HttpURLConnection 33 | // 设定请求的方法,默认是GET 34 | httpURLConnection.requestMethod = "GET" 35 | // 设置字符编码 36 | httpURLConnection.setRequestProperty("Charset", "UTF-8") 37 | // 添加header 38 | ImagePreview.instance.headers?.apply { 39 | for (entry in this) { 40 | httpURLConnection.setRequestProperty(entry.key, entry.value) 41 | } 42 | } 43 | // 打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。 44 | httpURLConnection.connect() 45 | val bin = BufferedInputStream(httpURLConnection.inputStream) 46 | val path = downloadDir + File.separatorChar + fileFullName 47 | file = File(path) 48 | file.parentFile?.let { 49 | if (!it.exists()) { 50 | it.mkdirs() 51 | } 52 | } 53 | val out: OutputStream = FileOutputStream(file) 54 | var size = 0 55 | var len = 0 56 | val buf = ByteArray(1024) 57 | while (bin.read(buf).also { size = it } != -1) { 58 | len += size 59 | out.write(buf, 0, size) 60 | } 61 | bin.close() 62 | out.close() 63 | return file 64 | } catch (e: MalformedURLException) { 65 | e.printStackTrace() 66 | } catch (e: IOException) { 67 | e.printStackTrace() 68 | } catch (e: Exception) { 69 | e.printStackTrace() 70 | } 71 | return null 72 | } 73 | 74 | fun decode(text: String): String { 75 | return URLDecoder.decode(text) 76 | } 77 | } -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/view/subsampling/decoder/ImageRegionDecoder.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.view.subsampling.decoder; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.graphics.Point; 6 | import android.graphics.Rect; 7 | import android.net.Uri; 8 | 9 | import androidx.annotation.NonNull; 10 | 11 | /** 12 | * Interface for image decoding classes, allowing the default {@link android.graphics.BitmapRegionDecoder} 13 | * based on the Skia library to be replaced with a custom class. 14 | */ 15 | public interface ImageRegionDecoder { 16 | 17 | /** 18 | * Initialise the decoder. When possible, perform initial setup work once in this method. The 19 | * dimensions of the image must be returned. The URI can be in one of the following formats: 20 | *
21 | * File: file:///scard/picture.jpg 22 | *
23 | * Asset: file:///android_asset/picture.png 24 | *
25 | * Resource: android.resource://com.example.app/drawable/picture 26 | * 27 | * @param context Application context. A reference may be held, but must be cleared on recycle. 28 | * @param uri URI of the image. 29 | * @return Dimensions of the image. 30 | * @throws Exception if initialisation fails. 31 | */ 32 | @NonNull 33 | Point init(Context context, @NonNull Uri uri) throws Exception; 34 | 35 | /** 36 | *

37 | * Decode a region of the image with the given sample size. This method is called off the UI 38 | * thread so it can safely load the image on the current thread. It is called from 39 | * {@link android.os.AsyncTask}s running in an executor that may have multiple threads, so 40 | * implementations must be thread safe. Adding synchronized to the method signature 41 | * is the simplest way to achieve this, but bear in mind the {@link #recycle()} method can be 42 | * called concurrently. 43 | *

44 | * See {@link SkiaImageRegionDecoder} and {@link SkiaPooledImageRegionDecoder} for examples of 45 | * internal locking and synchronization. 46 | *

47 | * 48 | * @param sRect Source image rectangle to decode. 49 | * @param sampleSize Sample size. 50 | * @return The decoded region. It is safe to return null if decoding fails. 51 | */ 52 | @NonNull 53 | Bitmap decodeRegion(@NonNull Rect sRect, int sampleSize); 54 | 55 | /** 56 | * Status check. Should return false before initialisation and after recycle. 57 | * 58 | * @return true if the decoder is ready to be used. 59 | */ 60 | boolean isReady(); 61 | 62 | /** 63 | * This method will be called when the decoder is no longer required. It should clean up any resources still in use. 64 | */ 65 | void recycle(); 66 | 67 | } 68 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/enc/cost_enc.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Cost tables for level and modes. 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #ifndef WEBP_ENC_COST_ENC_H_ 15 | #define WEBP_ENC_COST_ENC_H_ 16 | 17 | #include 18 | #include 19 | #include "src/enc/vp8i_enc.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | // On-the-fly info about the current set of residuals. Handy to avoid 26 | // passing zillions of params. 27 | typedef struct VP8Residual VP8Residual; 28 | struct VP8Residual { 29 | int first; 30 | int last; 31 | const int16_t *coeffs; 32 | 33 | int coeff_type; 34 | ProbaArray *prob; 35 | StatsArray *stats; 36 | CostArrayPtr costs; 37 | }; 38 | 39 | void VP8InitResidual(int first, int coeff_type, 40 | VP8Encoder *const enc, VP8Residual *const res); 41 | 42 | int VP8RecordCoeffs(int ctx, const VP8Residual *const res); 43 | 44 | // Record proba context used. 45 | static WEBP_INLINE int VP8RecordStats(int bit, proba_t *const stats) { 46 | proba_t p = *stats; 47 | // An overflow is inbound. Note we handle this at 0xfffe0000u instead of 48 | // 0xffff0000u to make sure p + 1u does not overflow. 49 | if (p >= 0xfffe0000u) { 50 | p = ((p + 1u) >> 1) & 0x7fff7fffu; // -> divide the stats by 2. 51 | } 52 | // record bit count (lower 16 bits) and increment total count (upper 16 bits). 53 | p += 0x00010000u + bit; 54 | *stats = p; 55 | return bit; 56 | } 57 | 58 | // Cost of coding one event with probability 'proba'. 59 | static WEBP_INLINE int VP8BitCost(int bit, uint8_t proba) { 60 | return !bit ? VP8EntropyCost[proba] : VP8EntropyCost[255 - proba]; 61 | } 62 | 63 | // Level cost calculations 64 | extern const uint16_t VP8LevelCodes[MAX_VARIABLE_LEVEL][2]; 65 | void VP8CalculateLevelCosts(VP8EncProba *const proba); 66 | static WEBP_INLINE int VP8LevelCost(const uint16_t *const table, int level) { 67 | return VP8LevelFixedCosts[level] 68 | + table[(level > MAX_VARIABLE_LEVEL) ? MAX_VARIABLE_LEVEL : level]; 69 | } 70 | 71 | // Mode costs 72 | extern const uint16_t VP8FixedCostsUV[4]; 73 | extern const uint16_t VP8FixedCostsI16[4]; 74 | extern const uint16_t VP8FixedCostsI4[NUM_BMODES][NUM_BMODES][NUM_BMODES]; 75 | 76 | //------------------------------------------------------------------------------ 77 | 78 | #ifdef __cplusplus 79 | } // extern "C" 80 | #endif 81 | 82 | #endif // WEBP_ENC_COST_ENC_H_ 83 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/WebpDrawableTransformation.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | 6 | import com.bumptech.glide.Glide; 7 | import com.bumptech.glide.load.Transformation; 8 | import com.bumptech.glide.load.engine.Resource; 9 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 10 | import com.bumptech.glide.load.resource.bitmap.BitmapResource; 11 | import com.bumptech.glide.util.Preconditions; 12 | 13 | import java.security.MessageDigest; 14 | 15 | /** 16 | * An {@link Transformation} that wraps a transformation for a 17 | * {@link Bitmap} and can apply it to every frame of any 18 | * {@link WebpDrawable}. 19 | * 20 | * @author liuchun 21 | */ 22 | public class WebpDrawableTransformation implements Transformation { 23 | private final Transformation wrapped; 24 | 25 | public WebpDrawableTransformation(Transformation wrapped) { 26 | this.wrapped = Preconditions.checkNotNull(wrapped); 27 | } 28 | 29 | @Override 30 | public Resource transform(Context context, Resource resource, int outWidth, int outHeight) { 31 | WebpDrawable drawable = resource.get(); 32 | 33 | // The drawable needs to be initialized with the correct width and height in order for a view 34 | // displaying it to end up with the right dimensions. Since our transformations may arbitrarily 35 | // modify the dimensions of our GIF, here we create a stand in for a frame and pass it to the 36 | // transformation to see what the final transformed dimensions will be so that our drawable can 37 | // report the correct intrinsic width and height. 38 | BitmapPool bitmapPool = Glide.get(context).getBitmapPool(); 39 | Bitmap firstFrame = drawable.getFirstFrame(); 40 | Resource bitmapResource = new BitmapResource(firstFrame, bitmapPool); 41 | Resource transformed = wrapped.transform(context, bitmapResource, outWidth, outHeight); 42 | if (!bitmapResource.equals(transformed)) { 43 | bitmapResource.recycle(); 44 | } 45 | Bitmap transformedFrame = transformed.get(); 46 | 47 | drawable.setFrameTransformation(wrapped, transformedFrame); 48 | return resource; 49 | } 50 | 51 | @Override 52 | public boolean equals(Object o) { 53 | if (o instanceof WebpDrawableTransformation) { 54 | WebpDrawableTransformation other = (WebpDrawableTransformation) o; 55 | return wrapped.equals(other.wrapped); 56 | } 57 | return false; 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | return wrapped.hashCode(); 63 | } 64 | 65 | @Override 66 | public void updateDiskCacheKey(MessageDigest messageDigest) { 67 | wrapped.updateDiskCacheKey(messageDigest); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/WebpFrameCacheStrategy.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | /** 4 | * author: liuchun 5 | * date: 2019-05-15 6 | */ 7 | public final class WebpFrameCacheStrategy { 8 | 9 | public static final WebpFrameCacheStrategy NONE = new Builder().noCache().build(); 10 | 11 | public static final WebpFrameCacheStrategy AUTO = new Builder().cacheAuto().build(); 12 | 13 | public static final WebpFrameCacheStrategy ALL = new Builder().cacheAll().build(); 14 | 15 | public enum CacheControl { 16 | CACHE_NONE, 17 | CACHE_LIMITED, 18 | CACHE_AUTO, 19 | CACHE_ALL, 20 | } 21 | 22 | private CacheControl mCacheStrategy; 23 | private int mCacheSize; 24 | 25 | private WebpFrameCacheStrategy(Builder builder) { 26 | this.mCacheStrategy = builder.cacheControl; 27 | this.mCacheSize = builder.cacheSize; 28 | } 29 | 30 | public CacheControl getCacheControl() { 31 | return this.mCacheStrategy; 32 | } 33 | 34 | public boolean noCache() { 35 | return mCacheStrategy == CacheControl.CACHE_NONE; 36 | } 37 | 38 | public boolean cacheAuto() { 39 | return mCacheStrategy == CacheControl.CACHE_AUTO; 40 | } 41 | 42 | public boolean cacheAll() { 43 | return mCacheStrategy == CacheControl.CACHE_ALL; 44 | } 45 | 46 | public int getCacheSize() { 47 | return this.mCacheSize; 48 | } 49 | 50 | public final static class Builder { 51 | private CacheControl cacheControl; 52 | private int cacheSize; 53 | 54 | public Builder noCache() { 55 | this.cacheControl = CacheControl.CACHE_NONE; 56 | return this; 57 | } 58 | 59 | public Builder cacheAll() { 60 | this.cacheControl = CacheControl.CACHE_ALL; 61 | return this; 62 | } 63 | 64 | public Builder cacheAuto() { 65 | this.cacheControl = CacheControl.CACHE_AUTO; 66 | return this; 67 | } 68 | 69 | public Builder cacheLimited() { 70 | this.cacheControl = CacheControl.CACHE_LIMITED; 71 | return this; 72 | } 73 | 74 | public Builder cacheControl(CacheControl control) { 75 | this.cacheControl = control; 76 | return this; 77 | } 78 | 79 | public Builder cacheSize(int cacheSize) { 80 | this.cacheSize = cacheSize; 81 | if (cacheSize == 0) { 82 | this.cacheControl = CacheControl.CACHE_NONE; 83 | } else if (cacheSize == Integer.MAX_VALUE) { 84 | this.cacheControl = CacheControl.CACHE_ALL; 85 | } else { 86 | this.cacheControl = CacheControl.CACHE_LIMITED; 87 | } 88 | return this; 89 | } 90 | 91 | public WebpFrameCacheStrategy build() { 92 | return new WebpFrameCacheStrategy(this); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/filters_utils.c: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // filter estimation 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #include "src/utils/filters_utils.h" 15 | #include 16 | #include 17 | 18 | // ----------------------------------------------------------------------------- 19 | // Quick estimate of a potentially interesting filter mode to try. 20 | 21 | #define SMAX 16 22 | #define SDIFF(a, b) (abs((a) - (b)) >> 4) // Scoring diff, in [0..SMAX) 23 | 24 | static WEBP_INLINE int GradientPredictor(uint8_t a, uint8_t b, uint8_t c) { 25 | const int g = a + b - c; 26 | return ((g & ~0xff) == 0) ? g : (g < 0) ? 0 : 255; // clip to 8bit 27 | } 28 | 29 | WEBP_FILTER_TYPE WebPEstimateBestFilter(const uint8_t *data, 30 | int width, int height, int stride) { 31 | int i, j; 32 | int bins[WEBP_FILTER_LAST][SMAX]; 33 | memset(bins, 0, sizeof(bins)); 34 | 35 | // We only sample every other pixels. That's enough. 36 | for (j = 2; j < height - 1; j += 2) { 37 | const uint8_t *const p = data + j * stride; 38 | int mean = p[0]; 39 | for (i = 2; i < width - 1; i += 2) { 40 | const int diff0 = SDIFF(p[i], mean); 41 | const int diff1 = SDIFF(p[i], p[i - 1]); 42 | const int diff2 = SDIFF(p[i], p[i - width]); 43 | const int grad_pred = 44 | GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]); 45 | const int diff3 = SDIFF(p[i], grad_pred); 46 | bins[WEBP_FILTER_NONE][diff0] = 1; 47 | bins[WEBP_FILTER_HORIZONTAL][diff1] = 1; 48 | bins[WEBP_FILTER_VERTICAL][diff2] = 1; 49 | bins[WEBP_FILTER_GRADIENT][diff3] = 1; 50 | mean = (3 * mean + p[i] + 2) >> 2; 51 | } 52 | } 53 | { 54 | int filter; 55 | WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE; 56 | int best_score = 0x7fffffff; 57 | for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) { 58 | int score = 0; 59 | for (i = 0; i < SMAX; ++i) { 60 | if (bins[filter][i] > 0) { 61 | score += i; 62 | } 63 | } 64 | if (score < best_score) { 65 | best_score = score; 66 | best_filter = (WEBP_FILTER_TYPE) filter; 67 | } 68 | } 69 | return best_filter; 70 | } 71 | } 72 | 73 | #undef SMAX 74 | #undef SDIFF 75 | 76 | //------------------------------------------------------------------------------ 77 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dsp/quant.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | 10 | #ifndef WEBP_DSP_QUANT_H_ 11 | #define WEBP_DSP_QUANT_H_ 12 | 13 | #include 14 | 15 | #include "src/dsp/dsp.h" 16 | #include "src/webp/types.h" 17 | 18 | #if defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && \ 19 | !defined(WEBP_HAVE_NEON_RTCD) 20 | #include 21 | 22 | #define IsFlat IsFlat_NEON 23 | 24 | static uint32_t horizontal_add_uint32x4(const uint32x4_t a) { 25 | #if WEBP_AARCH64 26 | return vaddvq_u32(a); 27 | #else 28 | const uint64x2_t b = vpaddlq_u32(a); 29 | const uint32x2_t c = vadd_u32(vreinterpret_u32_u64(vget_low_u64(b)), 30 | vreinterpret_u32_u64(vget_high_u64(b))); 31 | return vget_lane_u32(c, 0); 32 | #endif 33 | } 34 | 35 | static WEBP_INLINE int IsFlat(const int16_t* levels, int num_blocks, 36 | int thresh) { 37 | const int16x8_t tst_ones = vdupq_n_s16(-1); 38 | uint32x4_t sum = vdupq_n_u32(0); 39 | 40 | for (int i = 0; i < num_blocks; ++i) { 41 | // Set DC to zero. 42 | const int16x8_t a_0 = vsetq_lane_s16(0, vld1q_s16(levels), 0); 43 | const int16x8_t a_1 = vld1q_s16(levels + 8); 44 | 45 | const uint16x8_t b_0 = vshrq_n_u16(vtstq_s16(a_0, tst_ones), 15); 46 | const uint16x8_t b_1 = vshrq_n_u16(vtstq_s16(a_1, tst_ones), 15); 47 | 48 | sum = vpadalq_u16(sum, b_0); 49 | sum = vpadalq_u16(sum, b_1); 50 | 51 | levels += 16; 52 | } 53 | return thresh >= (int)horizontal_add_uint32x4(sum); 54 | } 55 | 56 | #else 57 | 58 | #define IsFlat IsFlat_C 59 | 60 | static WEBP_INLINE int IsFlat(const int16_t *levels, int num_blocks, 61 | int thresh) { 62 | int score = 0; 63 | while (num_blocks-- > 0) { // TODO(skal): refine positional scoring? 64 | int i; 65 | for (i = 1; i < 16; ++i) { // omit DC, we're only interested in AC 66 | score += (levels[i] != 0); 67 | if (score > thresh) return 0; 68 | } 69 | levels += 16; 70 | } 71 | return 1; 72 | } 73 | 74 | #endif // defined(WEBP_USE_NEON) && !defined(WEBP_ANDROID_NEON) && 75 | // !defined(WEBP_HAVE_NEON_RTCD) 76 | 77 | static WEBP_INLINE int IsFlatSource16(const uint8_t *src) { 78 | const uint32_t v = src[0] * 0x01010101u; 79 | int i; 80 | for (i = 0; i < 16; ++i) { 81 | if (memcmp(src + 0, &v, 4) || memcmp(src + 4, &v, 4) || 82 | memcmp(src + 8, &v, 4) || memcmp(src + 12, &v, 4)) { 83 | return 0; 84 | } 85 | src += BPS; 86 | } 87 | return 1; 88 | } 89 | 90 | #endif // WEBP_DSP_QUANT_H_ 91 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | ## For more details on how to configure your build environment visit 2 | # http://www.gradle.org/docs/current/userguide/build_environment.html 3 | # 4 | # Specifies the JVM arguments used for the daemon process. 5 | # The setting is particularly useful for tweaking memory settings. 6 | # Default value: -Xmx1024m -XX:MaxPermSize=256m 7 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 8 | # 9 | # When configured, Gradle will run in incubating parallel mode. 10 | # This option should only be used with decoupled projects. More details, visit 11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 12 | org.gradle.parallel=true 13 | org.gradle.jvmargs=-Xmx4096m 14 | #Sat Sep 02 12:19:06 CST 2023 15 | android.enableJetifier=true 16 | android.nonFinalResIds=false 17 | android.nonTransitiveRClass=false 18 | android.useAndroidX=true 19 | android.disableAutomaticComponentCreation=true 20 | 21 | NDK_VERSION=25.2.9519653 22 | 23 | # ============================================================================= 24 | # --- MAVEN CENTRAL PUBLISHING PROPERTIES --- 25 | # ============================================================================= 26 | 27 | # --- Project Information --- 28 | # You can change the version here. Use -SNAPSHOT for development versions. 29 | VERSION_NAME=androidx-8.4.8 30 | GROUP_ID=com.gouqinglin 31 | ARTIFACT_ID=BigImageViewPager 32 | 33 | # --- POM Metadata --- 34 | POM_DESCRIPTION=An Android library for viewing large images and videos with gesture support, including features like zooming, panning, and progress display. 35 | POM_URL=https://github.com/SherlockGougou/BigImageViewPager 36 | POM_SCM_URL=https://github.com/SherlockGougou/BigImageViewPager.git 37 | POM_SCM_CONNECTION=scm:git:github.com/SherlockGougou/BigImageViewPager.git 38 | POM_SCM_DEV_CONNECTION=scm:git:ssh://github.com/SherlockGougou/BigImageViewPager.git 39 | 40 | # --- License Information --- 41 | POM_LICENSE_NAME=The Apache License, Version 2.0 42 | POM_LICENSE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 43 | POM_LICENSE_DIST=repo 44 | 45 | # --- Developer Information --- 46 | POM_DEVELOPER_ID=SherlockGougou 47 | POM_DEVELOPER_NAME=SherlockGougou 48 | POM_DEVELOPER_EMAIL=qinglingou@gmail.com 49 | 50 | # --- Sonatype OSSRH Credentials --- 51 | # *** IMPORTANT *** 52 | # You need to create an account on Sonatype JIRA to get these credentials. 53 | # https://central.sonatype.org/publish/publish-guide/#initial-setup 54 | ossrhUsername= 55 | ossrhPassword= 56 | 57 | # --- GPG Signing Credentials --- 58 | # *** IMPORTANT *** 59 | # You need to generate a GPG key to sign your artifacts. 60 | # On macOS, you can use `brew install gpg` and then `gpg --gen-key`. 61 | # Use `gpg --list-secret-keys` to find your key ID (the 8-digit hex string). 62 | # The keyId is the last 8 characters of the sec key. 63 | signing.keyId= 64 | signing.password= 65 | # The secret key ring file. For gpg 2.1+, you may need to export it first: 66 | # gpg --export-secret-keys > ~/.gnupg/secring.gpg 67 | # You can provide an absolute path to your secret key ring file. 68 | signing.secretKeyRingFile= -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/color_cache_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Color Cache for WebP Lossless 11 | // 12 | // Authors: Jyrki Alakuijala (jyrki@google.com) 13 | // Urvang Joshi (urvang@google.com) 14 | 15 | #ifndef WEBP_UTILS_COLOR_CACHE_UTILS_H_ 16 | #define WEBP_UTILS_COLOR_CACHE_UTILS_H_ 17 | 18 | #include 19 | 20 | #include "src/dsp/dsp.h" 21 | #include "src/webp/types.h" 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | // Main color cache struct. 28 | typedef struct { 29 | uint32_t *colors_; // color entries 30 | int hash_shift_; // Hash shift: 32 - hash_bits_. 31 | int hash_bits_; 32 | } VP8LColorCache; 33 | 34 | static const uint32_t kHashMul = 0x1e35a7bdu; 35 | 36 | static WEBP_UBSAN_IGNORE_UNSIGNED_OVERFLOW WEBP_INLINE 37 | int VP8LHashPix(uint32_t argb, int shift) { 38 | return (int) ((argb * kHashMul) >> shift); 39 | } 40 | 41 | static WEBP_INLINE uint32_t 42 | VP8LColorCacheLookup( 43 | const VP8LColorCache *const cc, uint32_t key) { 44 | assert((key >> cc->hash_bits_) == 0u); 45 | return cc->colors_[key]; 46 | } 47 | 48 | static WEBP_INLINE void VP8LColorCacheSet(const VP8LColorCache *const cc, 49 | uint32_t key, uint32_t argb) { 50 | assert((key >> cc->hash_bits_) == 0u); 51 | cc->colors_[key] = argb; 52 | } 53 | 54 | static WEBP_INLINE void VP8LColorCacheInsert(const VP8LColorCache *const cc, 55 | uint32_t argb) { 56 | const int key = VP8LHashPix(argb, cc->hash_shift_); 57 | cc->colors_[key] = argb; 58 | } 59 | 60 | static WEBP_INLINE int VP8LColorCacheGetIndex(const VP8LColorCache *const cc, 61 | uint32_t argb) { 62 | return VP8LHashPix(argb, cc->hash_shift_); 63 | } 64 | 65 | // Return the key if cc contains argb, and -1 otherwise. 66 | static WEBP_INLINE int VP8LColorCacheContains(const VP8LColorCache *const cc, 67 | uint32_t argb) { 68 | const int key = VP8LHashPix(argb, cc->hash_shift_); 69 | return (cc->colors_[key] == argb) ? key : -1; 70 | } 71 | 72 | //------------------------------------------------------------------------------ 73 | 74 | // Initializes the color cache with 'hash_bits' bits for the keys. 75 | // Returns false in case of memory error. 76 | int VP8LColorCacheInit(VP8LColorCache *const color_cache, int hash_bits); 77 | 78 | void VP8LColorCacheCopy(const VP8LColorCache *const src, 79 | VP8LColorCache *const dst); 80 | 81 | // Delete the memory associated to color cache. 82 | void VP8LColorCacheClear(VP8LColorCache *const color_cache); 83 | 84 | //------------------------------------------------------------------------------ 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif // WEBP_UTILS_COLOR_CACHE_UTILS_H_ 91 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/InitProvider.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library 2 | 3 | import android.app.Application 4 | import android.content.ContentProvider 5 | import android.content.ContentValues 6 | import android.database.Cursor 7 | import android.net.Uri 8 | import androidx.media3.common.util.UnstableApi 9 | import androidx.media3.database.StandaloneDatabaseProvider 10 | import androidx.media3.datasource.DefaultDataSource 11 | import androidx.media3.datasource.DefaultHttpDataSource 12 | import androidx.media3.datasource.cache.CacheDataSource 13 | import androidx.media3.datasource.cache.LeastRecentlyUsedCacheEvictor 14 | import androidx.media3.datasource.cache.SimpleCache 15 | import java.io.File 16 | 17 | /** 18 | * 文件名: InitProvider.java 19 | * 作者: kirito 20 | * 描述: 初始化 21 | * 创建时间: 2024/11/27 22 | */ 23 | @UnstableApi 24 | class InitProvider : ContentProvider() { 25 | 26 | private var application: Application? = null 27 | 28 | override fun onCreate(): Boolean { 29 | // 获取 Application 实例 30 | val application = context?.applicationContext as? Application 31 | if (application != null) { 32 | // 在这里进行初始化操作 33 | this.application = application 34 | initializeLibrary(application) 35 | } 36 | return true // 返回 true 表示成功初始化 37 | } 38 | 39 | fun getApplication(): Application? { 40 | return application 41 | } 42 | 43 | private fun initializeLibrary(application: Application) { 44 | // downloadDirectory 45 | val downloadDirectory = File(application.cacheDir, "media_cache") 46 | // maxBytes 500MB 47 | val maxBytes = 500 * 1024 * 1024L 48 | // Note: This should be a singleton in your app. 49 | val databaseProvider = StandaloneDatabaseProvider(application) 50 | // An on-the-fly cache should evict media when reaching a maximum disk space limit. 51 | val cache = SimpleCache( 52 | downloadDirectory, 53 | LeastRecentlyUsedCacheEvictor(maxBytes), 54 | databaseProvider 55 | ) 56 | val dataSourceFactory = DefaultDataSource.Factory( 57 | application, 58 | DefaultHttpDataSource.Factory() 59 | ) 60 | // Configure the DataSource.Factory with the cache and factory for the desired HTTP stack. 61 | val cacheDataSourceFactory = 62 | CacheDataSource.Factory() 63 | .setCache(cache) 64 | .setUpstreamDataSourceFactory(dataSourceFactory) 65 | GlobalContext.init(application, cacheDataSourceFactory) 66 | } 67 | 68 | override fun query( 69 | uri: Uri, projection: Array?, selection: String?, 70 | selectionArgs: Array?, sortOrder: String? 71 | ): Cursor? = null 72 | 73 | override fun insert(uri: Uri, values: ContentValues?): Uri? = null 74 | 75 | override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int = 0 76 | 77 | override fun update( 78 | uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array? 79 | ): Int = 0 80 | 81 | override fun getType(uri: Uri): String? = null 82 | } -------------------------------------------------------------------------------- /sample/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #009688 4 | #009688 5 | #009688 6 | 7 | 8 | #00000000 9 | 10 | 11 | #FF757575 12 | 13 | #B37D7D7D 14 | 15 | #80757575 16 | 17 | #4D757575 18 | 19 | 20 | #FFFFFFFF 21 | #F2FFFFFF 22 | #E6FFFFFF 23 | #D9FFFFFF 24 | #CCFFFFFF 25 | #BFFFFFFF 26 | #B3FFFFFF 27 | #A6FFFFFF 28 | #99FFFFFF 29 | #8CFFFFFF 30 | #80FFFFFF 31 | #73FFFFFF 32 | #66FFFFFF 33 | #59FFFFFF 34 | #4DFFFFFF 35 | #40FFFFFF 36 | #33FFFFFF 37 | #26FFFFFF 38 | #1AFFFFFF 39 | #0DFFFFFF 40 | 41 | 42 | #FF000000 43 | #F2000000 44 | #E6000000 45 | #D9000000 46 | #CC000000 47 | #B000000F 48 | #B3000000 49 | #A6000000 50 | #99000000 51 | #8C000000 52 | #80000000 53 | #73000000 54 | #66000000 55 | #59000000 56 | #4D000000 57 | #40000000 58 | #33000000 59 | #26000000 60 | #1A000000 61 | #0D000000 62 | 63 | 64 | #FF808080 65 | 66 | #FFFF0000 67 | 68 | #FFFFD700 69 | 70 | #FFFFFF00 71 | 72 | #FF008000 73 | 74 | #FF0000FF 75 | 76 | #FF800080 77 | 78 | #FFFFC0CB 79 | 80 | #FFFFA500 81 | 82 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/utils/endian_inl_utils.h: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Endian related functions. 11 | 12 | #ifndef WEBP_UTILS_ENDIAN_INL_UTILS_H_ 13 | #define WEBP_UTILS_ENDIAN_INL_UTILS_H_ 14 | 15 | #ifdef HAVE_CONFIG_H 16 | #include "src/webp/config.h" 17 | #endif 18 | 19 | #include "src/dsp/dsp.h" 20 | #include "src/webp/types.h" 21 | 22 | #if defined(WORDS_BIGENDIAN) 23 | #define HToLE32 BSwap32 24 | #define HToLE16 BSwap16 25 | #else 26 | #define HToLE32(x) (x) 27 | #define HToLE16(x) (x) 28 | #endif 29 | 30 | #if !defined(HAVE_CONFIG_H) 31 | #if LOCAL_GCC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) 32 | #define HAVE_BUILTIN_BSWAP16 33 | #endif 34 | #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32) 35 | #define HAVE_BUILTIN_BSWAP32 36 | #endif 37 | #if LOCAL_GCC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64) 38 | #define HAVE_BUILTIN_BSWAP64 39 | #endif 40 | #endif // !HAVE_CONFIG_H 41 | 42 | static WEBP_INLINE uint16_t 43 | BSwap16(uint16_t 44 | x) { 45 | #if defined(HAVE_BUILTIN_BSWAP16) 46 | return __builtin_bswap16(x); 47 | #elif defined(_MSC_VER) 48 | return _byteswap_ushort(x); 49 | #else 50 | // gcc will recognize a 'rorw $8, ...' here: 51 | return (x >> 8) | ((x & 0xff) << 8); 52 | #endif // HAVE_BUILTIN_BSWAP16 53 | } 54 | 55 | static WEBP_INLINE uint32_t 56 | BSwap32(uint32_t 57 | x) { 58 | #if defined(WEBP_USE_MIPS32_R2) 59 | uint32_t ret; 60 | __asm__ volatile ( 61 | "wsbh %[ret], %[x] \n\t" 62 | "rotr %[ret], %[ret], 16 \n\t" 63 | : [ret]"=r"(ret) 64 | : [x]"r"(x) 65 | ); 66 | return ret; 67 | #elif defined(HAVE_BUILTIN_BSWAP32) 68 | return __builtin_bswap32(x); 69 | #elif defined(__i386__) || defined(__x86_64__) 70 | uint32_t swapped_bytes; 71 | __asm__ volatile("bswap %0" : "=r"(swapped_bytes) : "0"(x)); 72 | return 73 | swapped_bytes; 74 | #elif defined(_MSC_VER) 75 | return (uint32_t)_byteswap_ulong(x); 76 | #else 77 | return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24); 78 | #endif // HAVE_BUILTIN_BSWAP32 79 | } 80 | 81 | static WEBP_INLINE uint64_t 82 | BSwap64(uint64_t 83 | x) { 84 | #if defined(HAVE_BUILTIN_BSWAP64) 85 | return __builtin_bswap64(x); 86 | #elif defined(__x86_64__) 87 | uint64_t swapped_bytes; 88 | __asm__ volatile("bswapq %0" : "=r"(swapped_bytes) : "0"(x)); 89 | return swapped_bytes; 90 | #elif defined(_MSC_VER) 91 | return (uint64_t)_byteswap_uint64(x); 92 | #else // generic code for swapping 64-bit values (suggested by bdb@) 93 | x = ((x & 0xffffffff00000000ull) >> 32) | ((x & 0x00000000ffffffffull) << 32); 94 | x = ((x & 0xffff0000ffff0000ull) >> 16) | ((x & 0x0000ffff0000ffffull) << 16); 95 | x = ((x & 0xff00ff00ff00ff00ull) >> 8) | ((x & 0x00ff00ff00ff00ffull) << 8); 96 | return 97 | x; 98 | #endif // HAVE_BUILTIN_BSWAP64 99 | } 100 | 101 | #endif // WEBP_UTILS_ENDIAN_INL_UTILS_H_ 102 | -------------------------------------------------------------------------------- /sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | 4 | android { 5 | signingConfigs { 6 | debug { 7 | storeFile file('../common-60.keystore') 8 | storePassword '000000' 9 | keyAlias '000000' 10 | keyPassword '000000' 11 | } 12 | release { 13 | storeFile file('../common-60.keystore') 14 | storePassword '000000' 15 | keyAlias '000000' 16 | keyPassword '000000' 17 | } 18 | } 19 | namespace 'cc.shinichi.bigimageviewpager' 20 | compileSdkVersion 34 21 | defaultConfig { 22 | applicationId "cc.shinichi.bigimageviewpager" 23 | minSdkVersion 24 24 | targetSdkVersion 34 25 | versionCode 1000 26 | versionName "1000" 27 | signingConfig signingConfigs.debug 28 | multiDexEnabled true 29 | } 30 | splits { 31 | abi { 32 | enable true 33 | reset() // 清空之前的配置 34 | //noinspection ChromeOsAbiSupport 35 | include 'armeabi-v7a', 'arm64-v8a' // 指定要打包的 ABI 类型 36 | universalApk false // 是否生成包含所有 ABI 的通用 APK 37 | } 38 | } 39 | buildTypes { 40 | release { 41 | minifyEnabled false 42 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 43 | } 44 | } 45 | compileOptions { 46 | sourceCompatibility JavaVersion.VERSION_11 47 | targetCompatibility JavaVersion.VERSION_11 48 | } 49 | sourceSets { 50 | main { 51 | jniLibs.srcDirs = ['libs'] 52 | } 53 | } 54 | lint { 55 | abortOnError false 56 | } 57 | packagingOptions { 58 | jniLibs { 59 | useLegacyPackaging true 60 | } 61 | } 62 | } 63 | 64 | repositories { 65 | google() 66 | mavenCentral() 67 | } 68 | 69 | dependencies { 70 | implementation fileTree(include: ['*.jar'], dir: 'libs') 71 | implementation 'androidx.constraintlayout:constraintlayout:2.1.3' 72 | implementation 'androidx.appcompat:appcompat:1.4.1' 73 | implementation 'com.google.android.material:material:1.5.0' 74 | implementation 'androidx.recyclerview:recyclerview:1.2.1' 75 | implementation "androidx.core:core-ktx:1.6.0" 76 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 77 | 78 | // PictureSelector basic (Necessary) 79 | implementation 'io.github.lucksiege:pictureselector:v3.11.2' 80 | 81 | // glide 82 | def glideVersion = "4.16.0" 83 | implementation "com.github.bumptech.glide:glide:${glideVersion}" 84 | annotationProcessor "com.github.bumptech.glide:compiler:${glideVersion}" 85 | implementation "com.github.bumptech.glide:okhttp3-integration:${glideVersion}" 86 | 87 | // ExoPlayer https://developer.android.com/media/media3/exoplayer/hello-world?hl=zh-cn#groovy 88 | def media3Version = "1.4.1" 89 | implementation "androidx.media3:media3-exoplayer:${media3Version}" 90 | implementation "androidx.media3:media3-exoplayer-dash:${media3Version}" 91 | implementation "androidx.media3:media3-ui:${media3Version}" 92 | 93 | // library 94 | // implementation 'com.gouqinglin:BigImageViewPager:androidx-8.4.7' 95 | implementation project(':library') 96 | } -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/ByteBufferWebpDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.annotation.Nullable; 8 | 9 | import com.bumptech.glide.Glide; 10 | import com.bumptech.glide.integration.webp.WebpHeaderParser; 11 | import com.bumptech.glide.integration.webp.WebpImage; 12 | import com.bumptech.glide.load.Option; 13 | import com.bumptech.glide.load.Options; 14 | import com.bumptech.glide.load.ResourceDecoder; 15 | import com.bumptech.glide.load.Transformation; 16 | import com.bumptech.glide.load.engine.Resource; 17 | import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool; 18 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 19 | import com.bumptech.glide.load.resource.UnitTransformation; 20 | import com.bumptech.glide.load.resource.gif.GifBitmapProvider; 21 | 22 | import java.io.IOException; 23 | import java.nio.ByteBuffer; 24 | 25 | /** 26 | * An {@link ResourceDecoder} that decodes {@link 27 | * WebpDrawable} from {@link ByteBuffer} data 28 | * 29 | * @author liuchun 30 | */ 31 | public class ByteBufferWebpDecoder implements ResourceDecoder { 32 | public static final Option DISABLE_ANIMATION = Option.memory( 33 | "com.bumptech.glide.integration.webp.decoder.ByteBufferWebpDecoder.DisableAnimation", false); 34 | 35 | private final Context mContext; 36 | private final BitmapPool mBitmapPool; 37 | private final GifBitmapProvider mProvider; 38 | 39 | public ByteBufferWebpDecoder(Context context) { 40 | this(context, Glide.get(context).getArrayPool(), 41 | Glide.get(context).getBitmapPool()); 42 | } 43 | 44 | public ByteBufferWebpDecoder(Context context, ArrayPool byteArrayPool, BitmapPool bitmapPool) { 45 | this.mContext = context.getApplicationContext(); 46 | this.mBitmapPool = bitmapPool; 47 | this.mProvider = new GifBitmapProvider(bitmapPool, byteArrayPool); 48 | } 49 | 50 | @Override 51 | public boolean handles(@NonNull ByteBuffer source, @NonNull Options options) throws IOException { 52 | if (options.get(DISABLE_ANIMATION)) { 53 | return false; 54 | } 55 | 56 | WebpHeaderParser.WebpImageType webpType = WebpHeaderParser.getType(source); 57 | return WebpHeaderParser.isAnimatedWebpType(webpType); 58 | } 59 | 60 | @Nullable 61 | @Override 62 | public Resource decode(@NonNull ByteBuffer source, int width, int height, @NonNull Options options) throws IOException { 63 | 64 | int length = source.remaining(); 65 | byte[] data = new byte[length]; 66 | source.get(data, 0, length); 67 | 68 | WebpImage webp = WebpImage.create(data); 69 | 70 | int sampleSize = Utils.getSampleSize(webp.getWidth(), webp.getHeight(), width, height); 71 | WebpFrameCacheStrategy cacheStrategy = options.get(WebpFrameLoader.FRAME_CACHE_STRATEGY); 72 | WebpDecoder webpDecoder = new WebpDecoder(mProvider, webp, source, sampleSize, cacheStrategy); 73 | webpDecoder.advance(); 74 | Bitmap firstFrame = webpDecoder.getNextFrame(); 75 | if (firstFrame == null) { 76 | return null; 77 | } 78 | 79 | Transformation unitTransformation = UnitTransformation.get(); 80 | 81 | return new WebpDrawableResource(new WebpDrawable(mContext, webpDecoder, mBitmapPool, unitTransformation, width, height, 82 | firstFrame)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/decoder/AnimatedWebpBitmapDecoder.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp.decoder; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.bumptech.glide.integration.webp.WebpHeaderParser; 8 | import com.bumptech.glide.integration.webp.WebpImage; 9 | import com.bumptech.glide.load.Option; 10 | import com.bumptech.glide.load.Options; 11 | import com.bumptech.glide.load.engine.Resource; 12 | import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool; 13 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 14 | import com.bumptech.glide.load.resource.bitmap.BitmapResource; 15 | import com.bumptech.glide.load.resource.gif.GifBitmapProvider; 16 | 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | import java.nio.ByteBuffer; 20 | 21 | /** 22 | * Decode the animated webp image and obtain the first frame bitmap 23 | * 24 | * @author liuchun 25 | */ 26 | public class AnimatedWebpBitmapDecoder { 27 | public static final Option DISABLE_BITMAP = Option.memory( 28 | "com.bumptech.glide.integration.webp.decoder.AnimatedWebpBitmapDecoder.DisableBitmap", false); 29 | 30 | private final ArrayPool mArrayPool; 31 | private final BitmapPool mBitmapPool; 32 | private final GifBitmapProvider mProvider; 33 | 34 | public AnimatedWebpBitmapDecoder(ArrayPool byteArrayPool, BitmapPool bitmapPool) { 35 | mArrayPool = byteArrayPool; 36 | mBitmapPool = bitmapPool; 37 | mProvider = new GifBitmapProvider(bitmapPool, byteArrayPool); 38 | } 39 | 40 | public boolean handles(InputStream source, @NonNull Options options) throws IOException { 41 | if (options.get(DISABLE_BITMAP)) { 42 | return false; 43 | } 44 | WebpHeaderParser.WebpImageType webpType = WebpHeaderParser.getType(source, mArrayPool); 45 | return WebpHeaderParser.isAnimatedWebpType(webpType); 46 | } 47 | 48 | public boolean handles(ByteBuffer source, @NonNull Options options) throws IOException { 49 | if (options.get(DISABLE_BITMAP)) { 50 | return false; 51 | } 52 | WebpHeaderParser.WebpImageType webpType = WebpHeaderParser.getType(source); 53 | return WebpHeaderParser.isAnimatedWebpType(webpType); 54 | } 55 | 56 | public Resource decode(InputStream source, int width, int height, 57 | Options options) throws IOException { 58 | byte[] data = Utils.inputStreamToBytes(source); 59 | if (data == null) { 60 | return null; 61 | } 62 | ByteBuffer byteBuffer = ByteBuffer.wrap(data); 63 | return decode(byteBuffer, width, height, options); 64 | } 65 | 66 | public Resource decode(ByteBuffer source, int width, int height, 67 | Options options) throws IOException { 68 | int length = source.remaining(); 69 | byte[] data = new byte[length]; 70 | source.get(data, 0, length); 71 | 72 | WebpImage webp = WebpImage.create(data); 73 | 74 | int sampleSize = Utils.getSampleSize(webp.getWidth(), webp.getHeight(), width, height); 75 | WebpDecoder webpDecoder = new WebpDecoder(mProvider, webp, source, sampleSize); 76 | try { 77 | webpDecoder.advance(); 78 | Bitmap firstFrame = webpDecoder.getNextFrame(); 79 | return BitmapResource.obtain(firstFrame, mBitmapPool); 80 | } finally { 81 | // release the resources 82 | webpDecoder.clear(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/webp/mux_types.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Data-types common to the mux and demux libraries. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_MUX_TYPES_H_ 15 | #define WEBP_WEBP_MUX_TYPES_H_ 16 | 17 | #include // memset() 18 | #include "./types.h" 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | // Note: forward declaring enumerations is not allowed in (strict) C and C++, 25 | // the types are left here for reference. 26 | // typedef enum WebPFeatureFlags WebPFeatureFlags; 27 | // typedef enum WebPMuxAnimDispose WebPMuxAnimDispose; 28 | // typedef enum WebPMuxAnimBlend WebPMuxAnimBlend; 29 | typedef struct WebPData WebPData; 30 | 31 | // VP8X Feature Flags. 32 | typedef enum WebPFeatureFlags { 33 | ANIMATION_FLAG = 0x00000002, 34 | XMP_FLAG = 0x00000004, 35 | EXIF_FLAG = 0x00000008, 36 | ALPHA_FLAG = 0x00000010, 37 | ICCP_FLAG = 0x00000020, 38 | 39 | ALL_VALID_FLAGS = 0x0000003e 40 | } WebPFeatureFlags; 41 | 42 | // Dispose method (animation only). Indicates how the area used by the current 43 | // frame is to be treated before rendering the next frame on the canvas. 44 | typedef enum WebPMuxAnimDispose { 45 | WEBP_MUX_DISPOSE_NONE, // Do not dispose. 46 | WEBP_MUX_DISPOSE_BACKGROUND // Dispose to background color. 47 | } WebPMuxAnimDispose; 48 | 49 | // Blend operation (animation only). Indicates how transparent pixels of the 50 | // current frame are blended with those of the previous canvas. 51 | typedef enum WebPMuxAnimBlend { 52 | WEBP_MUX_BLEND, // Blend. 53 | WEBP_MUX_NO_BLEND // Do not blend. 54 | } WebPMuxAnimBlend; 55 | 56 | // Data type used to describe 'raw' data, e.g., chunk data 57 | // (ICC profile, metadata) and WebP compressed image data. 58 | // 'bytes' memory must be allocated using WebPMalloc() and such. 59 | struct WebPData { 60 | const uint8_t *bytes; 61 | size_t size; 62 | }; 63 | 64 | // Initializes the contents of the 'webp_data' object with default values. 65 | static WEBP_INLINE void WebPDataInit(WebPData *webp_data) { 66 | if (webp_data != NULL) { 67 | memset(webp_data, 0, sizeof(*webp_data)); 68 | } 69 | } 70 | 71 | // Clears the contents of the 'webp_data' object by calling WebPFree(). 72 | // Does not deallocate the object itself. 73 | static WEBP_INLINE void WebPDataClear(WebPData *webp_data) { 74 | if (webp_data != NULL) { 75 | WebPFree((void *) webp_data->bytes); 76 | WebPDataInit(webp_data); 77 | } 78 | } 79 | 80 | // Allocates necessary storage for 'dst' and copies the contents of 'src'. 81 | // Returns true on success. 82 | static WEBP_INLINE int WebPDataCopy(const WebPData *src, WebPData *dst) { 83 | if (src == NULL || dst == NULL) return 0; 84 | WebPDataInit(dst); 85 | if (src->bytes != NULL && src->size != 0) { 86 | dst->bytes = (uint8_t *) WebPMalloc(src->size); 87 | if (dst->bytes == NULL) return 0; 88 | memcpy((void *) dst->bytes, src->bytes, src->size); 89 | dst->size = src->size; 90 | } 91 | return 1; 92 | } 93 | 94 | #ifdef __cplusplus 95 | } // extern "C" 96 | #endif 97 | 98 | #endif // WEBP_WEBP_MUX_TYPES_H_ 99 | -------------------------------------------------------------------------------- /library/src/main/java/cc/shinichi/library/glide/progress/ProgressManager.kt: -------------------------------------------------------------------------------- 1 | package cc.shinichi.library.glide.progress 2 | 3 | import android.text.TextUtils 4 | import cc.shinichi.library.ImagePreview 5 | import cc.shinichi.library.glide.SSLSocketClient 6 | import cc.shinichi.library.glide.progress.ProgressResponseBody.InternalProgressListener 7 | import okhttp3.Headers 8 | import okhttp3.OkHttpClient 9 | import java.util.Collections 10 | import java.util.concurrent.TimeUnit 11 | 12 | /** 13 | * @author 工藤 14 | * @email qinglingou@gmail.com 15 | */ 16 | object ProgressManager { 17 | 18 | private val listenersMap = Collections.synchronizedMap(HashMap()) 19 | 20 | private val LISTENER = object : InternalProgressListener { 21 | override fun onProgress(url: String?, bytesRead: Long, totalBytes: Long) { 22 | val percentage = (bytesRead * 1f / totalBytes * 100f).toInt() 23 | val isComplete = percentage >= 100 24 | listenersMap.let { 25 | for (listener in it.values) { 26 | listener.onProgress(url, isComplete, percentage, bytesRead, totalBytes) 27 | } 28 | } 29 | if (isComplete) { 30 | removeListener(url) 31 | } 32 | } 33 | } 34 | 35 | @JvmStatic 36 | val okHttpClient: OkHttpClient 37 | get() { 38 | val builder = OkHttpClient.Builder() 39 | builder.addNetworkInterceptor { chain -> 40 | val request = chain.request() 41 | val response = chain.proceed(request) 42 | val headersBuilder = Headers.Builder() 43 | val url = request.url().toString() 44 | // 如果url中包含任意一个关键字,就添加监听 45 | val hostKeywordList = ImagePreview.instance.hostKeywordList 46 | var needAddHeader = false 47 | if (hostKeywordList.isNullOrEmpty()) { 48 | needAddHeader = false 49 | } else { 50 | for (item in hostKeywordList) { 51 | if (url.contains(item)) { 52 | needAddHeader = true 53 | break 54 | } 55 | } 56 | } 57 | if (needAddHeader) { 58 | // 通过set,替换原本的header 59 | ImagePreview.instance.headers?.forEach { 60 | headersBuilder.set(it.key, it.value) 61 | } 62 | } 63 | response.newBuilder() 64 | .headers(headersBuilder.build()) 65 | .body( 66 | response.body() 67 | ?.let { ProgressResponseBody(request.url().toString(), LISTENER, it) }) 68 | .build() 69 | } 70 | .sslSocketFactory( 71 | SSLSocketClient.sSLSocketFactory, 72 | SSLSocketClient.geX509tTrustManager() 73 | ) 74 | .hostnameVerifier(SSLSocketClient.hostnameVerifier) 75 | builder.connectTimeout(30, TimeUnit.SECONDS) 76 | builder.writeTimeout(30, TimeUnit.SECONDS) 77 | builder.readTimeout(30, TimeUnit.SECONDS) 78 | return builder.build() 79 | } 80 | 81 | @JvmStatic 82 | fun addListener(url: String?, listener: OnProgressListener?) { 83 | if (!TextUtils.isEmpty(url)) { 84 | listenersMap[url] = listener 85 | listener?.onProgress(url, false, 1, 0, 0) 86 | } 87 | } 88 | 89 | private fun removeListener(url: String?) { 90 | if (!TextUtils.isEmpty(url)) { 91 | listenersMap.remove(url) 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /library/src/main/java/com/bumptech/glide/integration/webp/WebpFrame.java: -------------------------------------------------------------------------------- 1 | package com.bumptech.glide.integration.webp; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.Keep; 6 | 7 | /** 8 | * Inner model class housing metadata for each animated webp frame. 9 | * 10 | * @see Container Specification 11 | * 12 | * @author liuchun 13 | */ 14 | @Keep 15 | public class WebpFrame { 16 | 17 | // See comment in fixFrameDuration below. 18 | static final int MIN_FRAME_DURATION_MS = 11; 19 | static final int FRAME_DURATION_MS_FOR_MIN = 100; 20 | 21 | // Access from Native 22 | @Keep 23 | private long mNativePtr; 24 | /** 25 | * XOffset, YOffset, Frame Width, Frame Height 26 | */ 27 | int ix, iy, iw, ih; 28 | /** 29 | * Delay, in milliseconds, to next frame. 30 | */ 31 | int delay; 32 | /** 33 | * Indicates how transparent pixels of the current frame are to be 34 | * blended with corresponding pixels of the previous canvas 35 | */ 36 | boolean blendPreviousFrame; 37 | /** 38 | * Indicates how the current frame is to be treated after it has been 39 | * displayed (before rendering the next frame) on the canvas: 40 | */ 41 | boolean disposeBackgroundColor; 42 | 43 | // Called from JNI 44 | WebpFrame(long nativePtr, int xOffset, int yOffset, int width, int height, 45 | int delay, boolean blendPreviousFrame, boolean disposeBackgroundColor) { 46 | 47 | this.mNativePtr = nativePtr; 48 | this.ix = xOffset; 49 | this.iy = yOffset; 50 | this.iw = width; 51 | this.ih = height; 52 | this.delay = delay; 53 | this.blendPreviousFrame = blendPreviousFrame; 54 | this.disposeBackgroundColor = disposeBackgroundColor; 55 | fixFrameDuration(); 56 | } 57 | 58 | /** 59 | * Adjust the frame duration to respect logic for minimum frame duration times 60 | */ 61 | private void fixFrameDuration() { 62 | // We follow Chrome's behavior which comes from Firefox. 63 | // Comment from Chrome's ImageSource.cpp follows: 64 | // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 65 | // a duration of <= 10 ms. See and 66 | // for more information. 67 | if (delay < MIN_FRAME_DURATION_MS) { 68 | delay = FRAME_DURATION_MS_FOR_MIN; 69 | } 70 | } 71 | 72 | @Override 73 | protected void finalize() throws Throwable { 74 | nativeFinalize(); 75 | } 76 | 77 | public void dispose() { 78 | nativeDispose(); 79 | } 80 | 81 | public void renderFrame(int width, int height, Bitmap bitmap) { 82 | nativeRenderFrame(width, height, bitmap); 83 | } 84 | 85 | public int getWidth() { 86 | return iw; 87 | } 88 | 89 | public int getHeight() { 90 | return ih; 91 | } 92 | 93 | public int getDurationMs() { 94 | return delay; 95 | } 96 | 97 | public int getXOffest() { 98 | return ix; 99 | } 100 | 101 | public int getYOffest() { 102 | return iy; 103 | } 104 | 105 | public boolean shouldDisposeToBackgroundColor() { 106 | return disposeBackgroundColor; 107 | } 108 | 109 | public boolean isBlendWithPreviousFrame() { 110 | return blendPreviousFrame; 111 | } 112 | 113 | private native void nativeRenderFrame(int width, int height, Bitmap bitmap); 114 | private native void nativeDispose(); 115 | private native void nativeFinalize(); 116 | } 117 | -------------------------------------------------------------------------------- /sample/src/main/java/cc/shinichi/bigimageviewpager/glide/GlideEngine.java: -------------------------------------------------------------------------------- 1 | package cc.shinichi.bigimageviewpager.glide; 2 | 3 | import android.content.Context; 4 | import android.widget.ImageView; 5 | 6 | import com.bumptech.glide.Glide; 7 | import com.bumptech.glide.load.resource.bitmap.CenterCrop; 8 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners; 9 | import com.luck.picture.lib.engine.ImageEngine; 10 | import com.luck.picture.lib.utils.ActivityCompatHelper; 11 | 12 | import cc.shinichi.bigimageviewpager.R; 13 | 14 | /** 15 | * @author:luck 16 | * @date:2019-11-13 17:02 17 | * @describe:Glide加载引擎 18 | */ 19 | public class GlideEngine implements ImageEngine { 20 | 21 | private GlideEngine() { 22 | } 23 | 24 | public static GlideEngine createGlideEngine() { 25 | return InstanceHolder.instance; 26 | } 27 | 28 | /** 29 | * 加载图片 30 | * 31 | * @param context 上下文 32 | * @param url 资源url 33 | * @param imageView 图片承载控件 34 | */ 35 | @Override 36 | public void loadImage(Context context, String url, ImageView imageView) { 37 | if (!ActivityCompatHelper.assertValidRequest(context)) { 38 | return; 39 | } 40 | Glide.with(context) 41 | .load(url) 42 | .into(imageView); 43 | } 44 | 45 | @Override 46 | public void loadImage(Context context, ImageView imageView, String url, int maxWidth, int maxHeight) { 47 | if (!ActivityCompatHelper.assertValidRequest(context)) { 48 | return; 49 | } 50 | Glide.with(context) 51 | .load(url) 52 | .override(maxWidth, maxHeight) 53 | .into(imageView); 54 | } 55 | 56 | /** 57 | * 加载相册目录封面 58 | * 59 | * @param context 上下文 60 | * @param url 图片路径 61 | * @param imageView 承载图片ImageView 62 | */ 63 | @Override 64 | public void loadAlbumCover(Context context, String url, ImageView imageView) { 65 | if (!ActivityCompatHelper.assertValidRequest(context)) { 66 | return; 67 | } 68 | Glide.with(context) 69 | .asBitmap() 70 | .load(url) 71 | .override(180, 180) 72 | .sizeMultiplier(0.5f) 73 | .transform(new CenterCrop(), new RoundedCorners(8)) 74 | .placeholder(R.drawable.ps_image_placeholder) 75 | .into(imageView); 76 | } 77 | 78 | /** 79 | * 加载图片列表图片 80 | * 81 | * @param context 上下文 82 | * @param url 图片路径 83 | * @param imageView 承载图片ImageView 84 | */ 85 | @Override 86 | public void loadGridImage(Context context, String url, ImageView imageView) { 87 | if (!ActivityCompatHelper.assertValidRequest(context)) { 88 | return; 89 | } 90 | Glide.with(context) 91 | .load(url) 92 | .override(200, 200) 93 | .centerCrop() 94 | .placeholder(R.drawable.ps_image_placeholder) 95 | .into(imageView); 96 | } 97 | 98 | @Override 99 | public void pauseRequests(Context context) { 100 | if (!ActivityCompatHelper.assertValidRequest(context)) { 101 | return; 102 | } 103 | Glide.with(context).pauseRequests(); 104 | } 105 | 106 | @Override 107 | public void resumeRequests(Context context) { 108 | if (!ActivityCompatHelper.assertValidRequest(context)) { 109 | return; 110 | } 111 | Glide.with(context).resumeRequests(); 112 | } 113 | 114 | private static final class InstanceHolder { 115 | static final GlideEngine instance = new GlideEngine(); 116 | } 117 | } -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/webp/format_constants.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Internal header for constants related to WebP file format. 11 | // 12 | // Author: Urvang (urvang@google.com) 13 | 14 | #ifndef WEBP_WEBP_FORMAT_CONSTANTS_H_ 15 | #define WEBP_WEBP_FORMAT_CONSTANTS_H_ 16 | 17 | // Create fourcc of the chunk from the chunk tag characters. 18 | #define MKFOURCC(a, b, c, d) ((a) | (b) << 8 | (c) << 16 | (uint32_t)(d) << 24) 19 | 20 | // VP8 related constants. 21 | #define VP8_SIGNATURE 0x9d012a // Signature in VP8 data. 22 | #define VP8_MAX_PARTITION0_SIZE (1 << 19) // max size of mode partition 23 | #define VP8_MAX_PARTITION_SIZE (1 << 24) // max size for token partition 24 | #define VP8_FRAME_HEADER_SIZE 10 // Size of the frame header within VP8 data. 25 | 26 | // VP8L related constants. 27 | #define VP8L_SIGNATURE_SIZE 1 // VP8L signature size. 28 | #define VP8L_MAGIC_BYTE 0x2f // VP8L signature byte. 29 | #define VP8L_IMAGE_SIZE_BITS 14 // Number of bits used to store 30 | // width and height. 31 | #define VP8L_VERSION_BITS 3 // 3 bits reserved for version. 32 | #define VP8L_VERSION 0 // version 0 33 | #define VP8L_FRAME_HEADER_SIZE 5 // Size of the VP8L frame header. 34 | 35 | #define MAX_PALETTE_SIZE 256 36 | #define MAX_CACHE_BITS 11 37 | #define HUFFMAN_CODES_PER_META_CODE 5 38 | #define ARGB_BLACK 0xff000000 39 | 40 | #define DEFAULT_CODE_LENGTH 8 41 | #define MAX_ALLOWED_CODE_LENGTH 15 42 | 43 | #define NUM_LITERAL_CODES 256 44 | #define NUM_LENGTH_CODES 24 45 | #define NUM_DISTANCE_CODES 40 46 | #define CODE_LENGTH_CODES 19 47 | 48 | #define MIN_HUFFMAN_BITS 2 // min number of Huffman bits 49 | #define MAX_HUFFMAN_BITS 9 // max number of Huffman bits 50 | 51 | #define TRANSFORM_PRESENT 1 // The bit to be written when next data 52 | // to be read is a transform. 53 | #define NUM_TRANSFORMS 4 // Maximum number of allowed transform 54 | // in a bitstream. 55 | typedef enum { 56 | PREDICTOR_TRANSFORM = 0, 57 | CROSS_COLOR_TRANSFORM = 1, 58 | SUBTRACT_GREEN_TRANSFORM = 2, 59 | COLOR_INDEXING_TRANSFORM = 3 60 | } VP8LImageTransformType; 61 | 62 | // Alpha related constants. 63 | #define ALPHA_HEADER_LEN 1 64 | #define ALPHA_NO_COMPRESSION 0 65 | #define ALPHA_LOSSLESS_COMPRESSION 1 66 | #define ALPHA_PREPROCESSED_LEVELS 1 67 | 68 | // Mux related constants. 69 | #define TAG_SIZE 4 // Size of a chunk tag (e.g. "VP8L"). 70 | #define CHUNK_SIZE_BYTES 4 // Size needed to store chunk's size. 71 | #define CHUNK_HEADER_SIZE 8 // Size of a chunk header. 72 | #define RIFF_HEADER_SIZE 12 // Size of the RIFF header ("RIFFnnnnWEBP"). 73 | #define ANMF_CHUNK_SIZE 16 // Size of an ANMF chunk. 74 | #define ANIM_CHUNK_SIZE 6 // Size of an ANIM chunk. 75 | #define VP8X_CHUNK_SIZE 10 // Size of a VP8X chunk. 76 | 77 | #define MAX_CANVAS_SIZE (1 << 24) // 24-bit max for VP8X width/height. 78 | #define MAX_IMAGE_AREA (1ULL << 32) // 32-bit max for width x height. 79 | #define MAX_LOOP_COUNT (1 << 16) // maximum value for loop-count 80 | #define MAX_DURATION (1 << 24) // maximum duration 81 | #define MAX_POSITION_OFFSET (1 << 24) // maximum frame x/y offset 82 | 83 | // Maximum chunk payload is such that adding the header and padding won't 84 | // overflow a uint32_t. 85 | #define MAX_CHUNK_PAYLOAD (~0U - CHUNK_HEADER_SIZE - 1) 86 | 87 | #endif // WEBP_WEBP_FORMAT_CONSTANTS_H_ 88 | -------------------------------------------------------------------------------- /library/src/main/jni/libwebp/src/dsp/alpha_processing_sse41.c: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All Rights Reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the COPYING file in the root of the source 5 | // tree. An additional intellectual property rights grant can be found 6 | // in the file PATENTS. All contributing project authors may 7 | // be found in the AUTHORS file in the root of the source tree. 8 | // ----------------------------------------------------------------------------- 9 | // 10 | // Utilities for processing transparent channel, SSE4.1 variant. 11 | // 12 | // Author: Skal (pascal.massimino@gmail.com) 13 | 14 | #include "src/dsp/dsp.h" 15 | 16 | #if defined(WEBP_USE_SSE41) 17 | 18 | #include 19 | 20 | //------------------------------------------------------------------------------ 21 | 22 | static int ExtractAlpha_SSE41(const uint8_t* WEBP_RESTRICT argb, 23 | int argb_stride, int width, int height, 24 | uint8_t* WEBP_RESTRICT alpha, int alpha_stride) { 25 | // alpha_and stores an 'and' operation of all the alpha[] values. The final 26 | // value is not 0xff if any of the alpha[] is not equal to 0xff. 27 | uint32_t alpha_and = 0xff; 28 | int i, j; 29 | const __m128i all_0xff = _mm_set1_epi32(~0); 30 | __m128i all_alphas = all_0xff; 31 | 32 | // We must be able to access 3 extra bytes after the last written byte 33 | // 'src[4 * width - 4]', because we don't know if alpha is the first or the 34 | // last byte of the quadruplet. 35 | const int limit = (width - 1) & ~15; 36 | const __m128i kCstAlpha0 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 37 | -1, -1, -1, -1, 12, 8, 4, 0); 38 | const __m128i kCstAlpha1 = _mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 39 | 12, 8, 4, 0, -1, -1, -1, -1); 40 | const __m128i kCstAlpha2 = _mm_set_epi8(-1, -1, -1, -1, 12, 8, 4, 0, 41 | -1, -1, -1, -1, -1, -1, -1, -1); 42 | const __m128i kCstAlpha3 = _mm_set_epi8(12, 8, 4, 0, -1, -1, -1, -1, 43 | -1, -1, -1, -1, -1, -1, -1, -1); 44 | for (j = 0; j < height; ++j) { 45 | const __m128i* src = (const __m128i*)argb; 46 | for (i = 0; i < limit; i += 16) { 47 | // load 64 argb bytes 48 | const __m128i a0 = _mm_loadu_si128(src + 0); 49 | const __m128i a1 = _mm_loadu_si128(src + 1); 50 | const __m128i a2 = _mm_loadu_si128(src + 2); 51 | const __m128i a3 = _mm_loadu_si128(src + 3); 52 | const __m128i b0 = _mm_shuffle_epi8(a0, kCstAlpha0); 53 | const __m128i b1 = _mm_shuffle_epi8(a1, kCstAlpha1); 54 | const __m128i b2 = _mm_shuffle_epi8(a2, kCstAlpha2); 55 | const __m128i b3 = _mm_shuffle_epi8(a3, kCstAlpha3); 56 | const __m128i c0 = _mm_or_si128(b0, b1); 57 | const __m128i c1 = _mm_or_si128(b2, b3); 58 | const __m128i d0 = _mm_or_si128(c0, c1); 59 | // store 60 | _mm_storeu_si128((__m128i*)&alpha[i], d0); 61 | // accumulate sixteen alpha 'and' in parallel 62 | all_alphas = _mm_and_si128(all_alphas, d0); 63 | src += 4; 64 | } 65 | for (; i < width; ++i) { 66 | const uint32_t alpha_value = argb[4 * i]; 67 | alpha[i] = alpha_value; 68 | alpha_and &= alpha_value; 69 | } 70 | argb += argb_stride; 71 | alpha += alpha_stride; 72 | } 73 | // Combine the sixteen alpha 'and' into an 8-bit mask. 74 | alpha_and |= 0xff00u; // pretend the upper bits [8..15] were tested ok. 75 | alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff)); 76 | return (alpha_and == 0xffffu); 77 | } 78 | 79 | //------------------------------------------------------------------------------ 80 | // Entry point 81 | 82 | extern void WebPInitAlphaProcessingSSE41(void); 83 | 84 | WEBP_TSAN_IGNORE_FUNCTION void WebPInitAlphaProcessingSSE41(void) { 85 | WebPExtractAlpha = ExtractAlpha_SSE41; 86 | } 87 | 88 | #else // !WEBP_USE_SSE41 89 | 90 | WEBP_DSP_INIT_STUB(WebPInitAlphaProcessingSSE41) 91 | 92 | #endif // WEBP_USE_SSE41 93 | --------------------------------------------------------------------------------