Skip to content

Commit f5e78ed

Browse files
sjuddglide-copybara-robot
authored andcommittedJan 26, 2022
Internal change
PiperOrigin-RevId: 424362058
1 parent 979459c commit f5e78ed

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.bumptech.glide.integration.avif;
2+
3+
import android.graphics.Bitmap;
4+
import android.util.Log;
5+
import com.bumptech.glide.load.Options;
6+
import com.bumptech.glide.load.ResourceDecoder;
7+
import com.bumptech.glide.load.engine.Resource;
8+
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
9+
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
10+
import com.bumptech.glide.util.Preconditions;
11+
import java.nio.ByteBuffer;
12+
import javax.annotation.Nullable;
13+
import org.aomedia.avif.android.AvifDecoder;
14+
import org.aomedia.avif.android.AvifDecoder.Info;
15+
16+
/** A Glide {@link ResourceDecoder} capable of decoding Avif images. */
17+
public final class AvifByteBufferBitmapDecoder implements ResourceDecoder<ByteBuffer, Bitmap> {
18+
private static final String TAG = "AvifBitmapDecoder";
19+
20+
private final BitmapPool bitmapPool;
21+
22+
public AvifByteBufferBitmapDecoder(BitmapPool bitmapPool) {
23+
this.bitmapPool = Preconditions.checkNotNull(bitmapPool);
24+
}
25+
26+
private ByteBuffer maybeCopyBuffer(ByteBuffer source) {
27+
// Native calls can only access ByteBuffer if isDirect() is true. Otherwise, we would have to
28+
// make a copy into a direct ByteBuffer.
29+
if (source.isDirect()) {
30+
return source;
31+
}
32+
ByteBuffer sourceCopy = ByteBuffer.allocateDirect(source.remaining());
33+
sourceCopy.put(source);
34+
sourceCopy.flip();
35+
return sourceCopy;
36+
}
37+
38+
@Override
39+
@Nullable
40+
public Resource<Bitmap> decode(ByteBuffer source, int width, int height, Options options) {
41+
ByteBuffer sourceCopy = maybeCopyBuffer(source);
42+
Info info = new Info();
43+
if (!AvifDecoder.getInfo(sourceCopy, sourceCopy.remaining(), info)) {
44+
if (Log.isLoggable(TAG, Log.ERROR)) {
45+
Log.e(TAG, "Requested to decode byte buffer which cannot be handled by AvifDecoder");
46+
}
47+
return null;
48+
}
49+
Bitmap bitmap =
50+
bitmapPool.get(
51+
info.width,
52+
info.height,
53+
(info.depth == 8) ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGBA_F16);
54+
if (!AvifDecoder.decode(sourceCopy, sourceCopy.remaining(), bitmap)) {
55+
if (Log.isLoggable(TAG, Log.ERROR)) {
56+
Log.e(TAG, "Failed to decode ByteBuffer as Avif.");
57+
}
58+
bitmapPool.put(bitmap);
59+
return null;
60+
}
61+
return BitmapResource.obtain(bitmap, bitmapPool);
62+
}
63+
64+
@Override
65+
public boolean handles(ByteBuffer source, Options options) {
66+
return AvifDecoder.isAvifImage(maybeCopyBuffer(source));
67+
}
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.bumptech.glide.integration.avif;
2+
3+
import android.content.Context;
4+
import android.graphics.Bitmap;
5+
import androidx.annotation.NonNull;
6+
import com.bumptech.glide.Glide;
7+
import com.bumptech.glide.Registry;
8+
import com.bumptech.glide.annotation.GlideModule;
9+
import com.bumptech.glide.module.LibraryGlideModule;
10+
import java.io.InputStream;
11+
import java.nio.ByteBuffer;
12+
13+
/** Glide support for AVIF Images. */
14+
@GlideModule
15+
public final class AvifGlideModule extends LibraryGlideModule {
16+
17+
@Override
18+
public void registerComponents(
19+
@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
20+
// Add the Avif ResourceDecoders before any of the available system decoders. This ensures that
21+
// the integration will be preferred for Avif images.
22+
AvifByteBufferBitmapDecoder byteBufferBitmapDecoder =
23+
new AvifByteBufferBitmapDecoder(glide.getBitmapPool());
24+
registry.prepend(ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder);
25+
AvifStreamBitmapDecoder streamBitmapDecoder =
26+
new AvifStreamBitmapDecoder(
27+
registry.getImageHeaderParsers(), byteBufferBitmapDecoder, glide.getArrayPool());
28+
registry.prepend(InputStream.class, Bitmap.class, streamBitmapDecoder);
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.bumptech.glide.integration.avif;
2+
3+
import android.graphics.Bitmap;
4+
import com.bumptech.glide.load.ImageHeaderParser;
5+
import com.bumptech.glide.load.ImageHeaderParser.ImageType;
6+
import com.bumptech.glide.load.ImageHeaderParserUtils;
7+
import com.bumptech.glide.load.Options;
8+
import com.bumptech.glide.load.ResourceDecoder;
9+
import com.bumptech.glide.load.engine.Resource;
10+
import com.bumptech.glide.load.engine.bitmap_recycle.ArrayPool;
11+
import com.bumptech.glide.util.ByteBufferUtil;
12+
import com.bumptech.glide.util.Preconditions;
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.util.List;
16+
import javax.annotation.Nullable;
17+
18+
/** A Glide {@link ResourceDecoder} capable of decoding Avif Images. */
19+
public final class AvifStreamBitmapDecoder implements ResourceDecoder<InputStream, Bitmap> {
20+
private static final String TAG = "AvifStreamBitmapDecoder";
21+
22+
private final List<ImageHeaderParser> parsers;
23+
private final AvifByteBufferBitmapDecoder avifByteBufferDecoder;
24+
private final ArrayPool arrayPool;
25+
26+
public AvifStreamBitmapDecoder(
27+
List<ImageHeaderParser> parsers,
28+
AvifByteBufferBitmapDecoder avifByteBufferDecoder,
29+
ArrayPool arrayPool) {
30+
this.parsers = parsers;
31+
this.avifByteBufferDecoder = Preconditions.checkNotNull(avifByteBufferDecoder);
32+
this.arrayPool = Preconditions.checkNotNull(arrayPool);
33+
}
34+
35+
@Override
36+
@Nullable
37+
public Resource<Bitmap> decode(InputStream source, int width, int height, Options options)
38+
throws IOException {
39+
return avifByteBufferDecoder.decode(ByteBufferUtil.fromStream(source), width, height, options);
40+
}
41+
42+
@Override
43+
public boolean handles(InputStream source, Options options) throws IOException {
44+
return ImageType.AVIF.equals(ImageHeaderParserUtils.getType(parsers, source, arrayPool));
45+
}
46+
}

0 commit comments

Comments
 (0)
Please sign in to comment.