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 |
--------------------------------------------------------------------------------