mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-31 00:36:14 +00:00
Add support for rendering APNGs.
This commit is contained in:
committed by
Cody Henthorne
parent
1d2ffe56fb
commit
250402e9b9
@@ -22,6 +22,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
@@ -32,6 +33,7 @@ import com.google.android.gms.security.ProviderInstaller;
|
||||
|
||||
import org.conscrypt.Conscrypt;
|
||||
import org.signal.aesgcmprovider.AesGcmProvider;
|
||||
import org.signal.glide.SignalGlideCodecs;
|
||||
import org.signal.ringrtc.CallManager;
|
||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||
@@ -127,6 +129,7 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||
initializePendingMessages();
|
||||
initializeBlobProvider();
|
||||
initializeCleanup();
|
||||
initializeGlideCodecs();
|
||||
|
||||
FeatureFlags.init();
|
||||
NotificationChannels.create(this);
|
||||
@@ -378,6 +381,35 @@ public class ApplicationContext extends MultiDexApplication implements DefaultLi
|
||||
});
|
||||
}
|
||||
|
||||
private void initializeGlideCodecs() {
|
||||
SignalGlideCodecs.setLogProvider(new org.signal.glide.Log.Provider() {
|
||||
@Override
|
||||
public void v(@NonNull String tag, @NonNull String message) {
|
||||
Log.v(tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void d(@NonNull String tag, @NonNull String message) {
|
||||
Log.d(tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void i(@NonNull String tag, @NonNull String message) {
|
||||
Log.i(tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void w(@NonNull String tag, @NonNull String message) {
|
||||
Log.w(tag, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void e(@NonNull String tag, @NonNull String message, @Nullable Throwable throwable) {
|
||||
Log.e(tag, message, throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context base) {
|
||||
super.attachBaseContext(DynamicLanguageContextWrapper.updateContext(base, TextSecurePreferences.getLanguage(base)));
|
||||
|
||||
73
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngBufferCacheDecoder.java
vendored
Normal file
73
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngBufferCacheDecoder.java
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.signal.glide.apng.decode.APNGDecoder;
|
||||
import org.signal.glide.apng.decode.APNGParser;
|
||||
import org.signal.glide.common.io.ByteBufferReader;
|
||||
import org.signal.glide.common.loader.ByteBufferLoader;
|
||||
import org.signal.glide.common.loader.Loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ApngBufferCacheDecoder implements ResourceDecoder<ByteBuffer, APNGDecoder> {
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull ByteBuffer source, @NonNull Options options) {
|
||||
return APNGParser.isAPNG(new ByteBufferReader(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<APNGDecoder> decode(@NonNull final ByteBuffer source, int width, int height, @NonNull Options options) throws IOException {
|
||||
if (!APNGParser.isAPNG(new ByteBufferReader(source))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Loader loader = new ByteBufferLoader() {
|
||||
@Override
|
||||
public ByteBuffer getByteBuffer() {
|
||||
source.position(0);
|
||||
return source;
|
||||
}
|
||||
};
|
||||
|
||||
return new FrameSeqDecoderResource(new APNGDecoder(loader, null), source.limit());
|
||||
}
|
||||
|
||||
private static class FrameSeqDecoderResource implements Resource<APNGDecoder> {
|
||||
private final APNGDecoder decoder;
|
||||
private final int size;
|
||||
|
||||
FrameSeqDecoderResource(@NonNull APNGDecoder decoder, int size) {
|
||||
this.decoder = decoder;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull Class<APNGDecoder> getResourceClass() {
|
||||
return APNGDecoder.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull APNGDecoder get() {
|
||||
return this.decoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
this.decoder.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
48
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngFrameDrawableTranscoder.java
vendored
Normal file
48
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngFrameDrawableTranscoder.java
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.resource.drawable.DrawableResource;
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
|
||||
|
||||
import org.signal.glide.apng.APNGDrawable;
|
||||
import org.signal.glide.apng.decode.APNGDecoder;
|
||||
|
||||
public class ApngFrameDrawableTranscoder implements ResourceTranscoder<APNGDecoder, Drawable> {
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<Drawable> transcode(@NonNull Resource<APNGDecoder> toTranscode, @NonNull Options options) {
|
||||
APNGDecoder decoder = toTranscode.get();
|
||||
APNGDrawable drawable = new APNGDrawable(decoder);
|
||||
|
||||
drawable.setAutoPlay(false);
|
||||
drawable.setLoopLimit(0);
|
||||
|
||||
return new DrawableResource<Drawable>(drawable) {
|
||||
@Override
|
||||
public @NonNull Class<Drawable> getResourceClass() {
|
||||
return Drawable.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
44
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngStreamCacheDecoder.java
vendored
Normal file
44
app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngStreamCacheDecoder.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.signal.glide.apng.decode.APNGDecoder;
|
||||
import org.signal.glide.apng.decode.APNGParser;
|
||||
import org.signal.glide.common.io.StreamReader;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ApngStreamCacheDecoder implements ResourceDecoder<InputStream, APNGDecoder> {
|
||||
|
||||
private final ResourceDecoder<ByteBuffer, APNGDecoder> byteBufferDecoder;
|
||||
|
||||
public ApngStreamCacheDecoder(ResourceDecoder<ByteBuffer, APNGDecoder> byteBufferDecoder) {
|
||||
this.byteBufferDecoder = byteBufferDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull InputStream source, @NonNull Options options) {
|
||||
return APNGParser.isAPNG(new StreamReader(source));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<APNGDecoder> decode(@NonNull final InputStream source, int width, int height, @NonNull Options options) throws IOException {
|
||||
byte[] data = Util.readFully(source);
|
||||
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(data);
|
||||
return byteBufferDecoder.decode(byteBuffer, width, height, options);
|
||||
}
|
||||
}
|
||||
|
||||
51
app/src/main/java/org/thoughtcrime/securesms/glide/cache/EncryptedApngCacheEncoder.java
vendored
Normal file
51
app/src/main/java/org/thoughtcrime/securesms/glide/cache/EncryptedApngCacheEncoder.java
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.EncodeStrategy;
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceEncoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.signal.glide.apng.decode.APNGDecoder;
|
||||
import org.signal.glide.common.loader.Loader;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class EncryptedApngCacheEncoder extends EncryptedCoder implements ResourceEncoder<APNGDecoder> {
|
||||
|
||||
private static final String TAG = Log.tag(EncryptedApngCacheEncoder.class);
|
||||
|
||||
private final byte[] secret;
|
||||
|
||||
public EncryptedApngCacheEncoder(@NonNull byte[] secret) {
|
||||
this.secret = secret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull EncodeStrategy getEncodeStrategy(@NonNull Options options) {
|
||||
return EncodeStrategy.SOURCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean encode(@NonNull Resource<APNGDecoder> data, @NonNull File file, @NonNull Options options) {
|
||||
try {
|
||||
Loader loader = data.get().getLoader();
|
||||
InputStream input = loader.obtain().toInputStream();
|
||||
OutputStream output = createEncryptedOutputStream(secret, file);
|
||||
|
||||
Util.copy(input, output);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class EncryptedBitmapCacheDecoder extends EncryptedCoder implements ResourceDecoder<File, Bitmap> {
|
||||
|
||||
private static final String TAG = EncryptedBitmapCacheDecoder.class.getSimpleName();
|
||||
|
||||
private final StreamBitmapDecoder streamBitmapDecoder;
|
||||
private final byte[] secret;
|
||||
|
||||
public EncryptedBitmapCacheDecoder(@NonNull byte[] secret, @NonNull StreamBitmapDecoder streamBitmapDecoder) {
|
||||
this.secret = secret;
|
||||
this.streamBitmapDecoder = streamBitmapDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull File source, @NonNull Options options)
|
||||
throws IOException
|
||||
{
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return streamBitmapDecoder.handles(inputStream, options);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<Bitmap> decode(@NonNull File source, int width, int height, @NonNull Options options)
|
||||
throws IOException
|
||||
{
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return streamBitmapDecoder.decode(inputStream, width, height, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,8 +33,6 @@ public class EncryptedBitmapResourceEncoder extends EncryptedCoder implements Re
|
||||
@SuppressWarnings("EmptyCatchBlock")
|
||||
@Override
|
||||
public boolean encode(@NonNull Resource<Bitmap> data, @NonNull File file, @NonNull Options options) {
|
||||
Log.i(TAG, "Encrypted resource encoder running: " + file.toString());
|
||||
|
||||
Bitmap bitmap = data.get();
|
||||
Bitmap.CompressFormat format = getFormat(bitmap, options);
|
||||
int quality = options.get(BitmapEncoder.COMPRESSION_QUALITY);
|
||||
|
||||
44
app/src/main/java/org/thoughtcrime/securesms/glide/cache/EncryptedCacheDecoder.java
vendored
Normal file
44
app/src/main/java/org/thoughtcrime/securesms/glide/cache/EncryptedCacheDecoder.java
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class EncryptedCacheDecoder<DecodeType> extends EncryptedCoder implements ResourceDecoder<File, DecodeType> {
|
||||
|
||||
private static final String TAG = Log.tag(EncryptedCacheDecoder.class);
|
||||
|
||||
private final byte[] secret;
|
||||
private final ResourceDecoder<InputStream, DecodeType> decoder;
|
||||
|
||||
public EncryptedCacheDecoder(byte[] secret, ResourceDecoder<InputStream, DecodeType> decoder) {
|
||||
this.secret = secret;
|
||||
this.decoder = decoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull File source, @NonNull Options options) throws IOException {
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return decoder.handles(inputStream, options);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<DecodeType> decode(@NonNull File source, int width, int height, @NonNull Options options) throws IOException {
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return decoder.decode(inputStream, width, height, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,8 +30,6 @@ public class EncryptedCacheEncoder extends EncryptedCoder implements Encoder<Inp
|
||||
@SuppressWarnings("EmptyCatchBlock")
|
||||
@Override
|
||||
public boolean encode(@NonNull InputStream data, @NonNull File file, @NonNull Options options) {
|
||||
Log.i(TAG, "Encrypted cache encoder running: " + file.toString());
|
||||
|
||||
byte[] buffer = byteArrayPool.get(ArrayPool.STANDARD_BUFFER_SIZE_BYTES, byte[].class);
|
||||
|
||||
try (OutputStream outputStream = createEncryptedOutputStream(secret, file)) {
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.thoughtcrime.securesms.glide.cache;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import com.bumptech.glide.load.Options;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
import com.bumptech.glide.load.resource.gif.StreamGifDecoder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class EncryptedGifCacheDecoder extends EncryptedCoder implements ResourceDecoder<File, GifDrawable> {
|
||||
|
||||
private static final String TAG = EncryptedGifCacheDecoder.class.getSimpleName();
|
||||
|
||||
private final byte[] secret;
|
||||
private final StreamGifDecoder gifDecoder;
|
||||
|
||||
public EncryptedGifCacheDecoder(@NonNull byte[] secret, @NonNull StreamGifDecoder gifDecoder) {
|
||||
this.secret = secret;
|
||||
this.gifDecoder = gifDecoder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handles(@NonNull File source, @NonNull Options options) {
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return gifDecoder.handles(inputStream, options);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Resource<GifDrawable> decode(@NonNull File source, int width, int height, @NonNull Options options) throws IOException {
|
||||
Log.i(TAG, "Encrypted GIF cache decoder running...");
|
||||
try (InputStream inputStream = createEncryptedInputStream(secret, source)) {
|
||||
return gifDecoder.decode(inputStream, width, height, options);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.mms;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
@@ -27,14 +29,18 @@ import org.thoughtcrime.securesms.contacts.avatars.ContactPhoto;
|
||||
import org.thoughtcrime.securesms.crypto.AttachmentSecret;
|
||||
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
|
||||
import org.thoughtcrime.securesms.giph.model.ChunkedImageUrl;
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngBufferCacheDecoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedApngCacheEncoder;
|
||||
import org.thoughtcrime.securesms.glide.ChunkedImageUrlLoader;
|
||||
import org.thoughtcrime.securesms.glide.ContactPhotoLoader;
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngFrameDrawableTranscoder;
|
||||
import org.thoughtcrime.securesms.glide.OkHttpUrlLoader;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedBitmapCacheDecoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.ApngStreamCacheDecoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedBitmapResourceEncoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedCacheDecoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedCacheEncoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedGifCacheDecoder;
|
||||
import org.thoughtcrime.securesms.glide.cache.EncryptedGifDrawableResourceEncoder;
|
||||
import org.signal.glide.apng.decode.APNGDecoder;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentStreamUriLoader.AttachmentModel;
|
||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri;
|
||||
import org.thoughtcrime.securesms.stickers.StickerRemoteUri;
|
||||
@@ -42,6 +48,7 @@ import org.thoughtcrime.securesms.stickers.StickerRemoteUriLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@GlideModule
|
||||
public class SignalGlideModule extends AppGlideModule {
|
||||
@@ -63,14 +70,25 @@ public class SignalGlideModule extends AppGlideModule {
|
||||
byte[] secret = attachmentSecret.getModernKey();
|
||||
|
||||
registry.prepend(File.class, File.class, UnitModelLoader.Factory.getInstance());
|
||||
registry.prepend(InputStream.class, new EncryptedCacheEncoder(secret, glide.getArrayPool()));
|
||||
registry.prepend(File.class, Bitmap.class, new EncryptedBitmapCacheDecoder(secret, new StreamBitmapDecoder(new Downsampler(registry.getImageHeaderParsers(), context.getResources().getDisplayMetrics(), glide.getBitmapPool(), glide.getArrayPool()), glide.getArrayPool())));
|
||||
registry.prepend(File.class, GifDrawable.class, new EncryptedGifCacheDecoder(secret, new StreamGifDecoder(registry.getImageHeaderParsers(), new ByteBufferGifDecoder(context, registry.getImageHeaderParsers(), glide.getBitmapPool(), glide.getArrayPool()), glide.getArrayPool())));
|
||||
|
||||
registry.prepend(BlurHash.class, Bitmap.class, new BlurHashResourceDecoder());
|
||||
registry.prepend(InputStream.class, new EncryptedCacheEncoder(secret, glide.getArrayPool()));
|
||||
|
||||
registry.prepend(Bitmap.class, new EncryptedBitmapResourceEncoder(secret));
|
||||
registry.prepend(File.class, Bitmap.class, new EncryptedCacheDecoder<>(secret, new StreamBitmapDecoder(new Downsampler(registry.getImageHeaderParsers(), context.getResources().getDisplayMetrics(), glide.getBitmapPool(), glide.getArrayPool()), glide.getArrayPool())));
|
||||
|
||||
registry.prepend(GifDrawable.class, new EncryptedGifDrawableResourceEncoder(secret));
|
||||
registry.prepend(File.class, GifDrawable.class, new EncryptedCacheDecoder<>(secret, new StreamGifDecoder(registry.getImageHeaderParsers(), new ByteBufferGifDecoder(context, registry.getImageHeaderParsers(), glide.getBitmapPool(), glide.getArrayPool()), glide.getArrayPool())));
|
||||
|
||||
ApngBufferCacheDecoder apngBufferCacheDecoder = new ApngBufferCacheDecoder();
|
||||
ApngStreamCacheDecoder apngStreamCacheDecoder = new ApngStreamCacheDecoder(apngBufferCacheDecoder);
|
||||
|
||||
registry.prepend(InputStream.class, APNGDecoder.class, apngStreamCacheDecoder);
|
||||
registry.prepend(ByteBuffer.class, APNGDecoder.class, apngBufferCacheDecoder);
|
||||
registry.prepend(APNGDecoder.class, new EncryptedApngCacheEncoder(secret));
|
||||
registry.prepend(File.class, APNGDecoder.class, new EncryptedCacheDecoder<>(secret, apngStreamCacheDecoder));
|
||||
registry.register(APNGDecoder.class, Drawable.class, new ApngFrameDrawableTranscoder());
|
||||
|
||||
registry.prepend(BlurHash.class, Bitmap.class, new BlurHashResourceDecoder());
|
||||
|
||||
registry.append(ContactPhoto.class, InputStream.class, new ContactPhotoLoader.Factory(context));
|
||||
registry.append(DecryptableUri.class, InputStream.class, new DecryptableStreamUriLoader.Factory(context));
|
||||
|
||||
Reference in New Issue
Block a user