Signal-Android/app/src/main/java/org/thoughtcrime/securesms/glide/cache/ApngBufferCacheDecoder.java

74 lines
1.9 KiB
Java

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();
}
}
}