Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 121ef98b authored by Leon Scroggins III's avatar Leon Scroggins III
Browse files

Add an asset source for ImageDecoder

Bug: 74545298
Test: I6a633553bbb5ff26d84aaf5371b8b43a770afd4f

This allows using ImageDecoder to decode a file in the "assets"
directory of an app.

Change-Id: I2193f052cc2e16c55c7f68f7e51e07cd24ee4df9
parent 1eccac89
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -13608,6 +13608,7 @@ package android.graphics {
    method public void close();
    method public static android.graphics.ImageDecoder.Source createSource(android.content.res.Resources, int);
    method public static android.graphics.ImageDecoder.Source createSource(android.content.ContentResolver, android.net.Uri);
    method public static android.graphics.ImageDecoder.Source createSource(android.content.res.AssetManager, java.lang.String);
    method public static android.graphics.ImageDecoder.Source createSource(java.nio.ByteBuffer);
    method public static android.graphics.ImageDecoder.Source createSource(java.io.File);
    method public static android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
+53 −34
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.content.res.AssetManager.AssetInputStream;
import android.content.res.Resources;
import android.graphics.drawable.AnimatedImageDrawable;
@@ -294,25 +295,13 @@ public final class ImageDecoder implements AutoCloseable {

        @Override
        public ImageDecoder createImageDecoder() throws IOException {
            ImageDecoder decoder = null;
            synchronized (this) {
                if (mAssetInputStream == null) {
                    throw new IOException("Cannot reuse AssetInputStreamSource");
                }
                AssetInputStream ais = mAssetInputStream;
                mAssetInputStream = null;
                try {
                    long asset = ais.getNativeAsset();
                    decoder = nCreate(asset);
                } finally {
                    if (decoder == null) {
                        IoUtils.closeQuietly(ais);
                    } else {
                        decoder.mInputStream = ais;
                        decoder.mOwnsInputStream = true;
                    }
                }
                return decoder;
                return createFromAsset(ais);
            }
        }
    }
@@ -336,13 +325,10 @@ public final class ImageDecoder implements AutoCloseable {

        @Override
        public ImageDecoder createImageDecoder() throws IOException {
            // This is just used in order to access the underlying Asset and
            // keep it alive. FIXME: Can we skip creating this object?
            InputStream is = null;
            ImageDecoder decoder = null;
            TypedValue value = new TypedValue();
            try {
                is = mResources.openRawResource(mResId, value);
            // This is just used in order to access the underlying Asset and
            // keep it alive.
            InputStream is = mResources.openRawResource(mResId, value);

            if (value.density == TypedValue.DENSITY_DEFAULT) {
                mResDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -350,18 +336,43 @@ public final class ImageDecoder implements AutoCloseable {
                mResDensity = value.density;
            }

                long asset = ((AssetInputStream) is).getNativeAsset();
            return createFromAsset((AssetInputStream) is);
        }
    }

    /**
     *  ImageDecoder will own the AssetInputStream.
     */
    private static ImageDecoder createFromAsset(AssetInputStream ais) throws IOException {
        ImageDecoder decoder = null;
        try {
            long asset = ais.getNativeAsset();
            decoder = nCreate(asset);
        } finally {
            if (decoder == null) {
                    IoUtils.closeQuietly(is);
                IoUtils.closeQuietly(ais);
            } else {
                    decoder.mInputStream = is;
                decoder.mInputStream = ais;
                decoder.mOwnsInputStream = true;
            }
        }
        return decoder;
    }

    private static class AssetSource extends Source {
        AssetSource(@NonNull AssetManager assets, @NonNull String fileName) {
            mAssets = assets;
            mFileName = fileName;
        }

        private final AssetManager mAssets;
        private final String mFileName;

        @Override
        public ImageDecoder createImageDecoder() throws IOException {
            InputStream is = mAssets.open(mFileName);
            return createFromAsset((AssetInputStream) is);
        }
    }

    private static class FileSource extends Source {
@@ -580,6 +591,14 @@ public final class ImageDecoder implements AutoCloseable {
        return new ContentResolverSource(cr, uri, res);
    }

    /**
     * Create a new {@link Source} from a file in the "assets" directory.
     */
    @NonNull
    public static Source createSource(@NonNull AssetManager assets, @NonNull String fileName) {
        return new AssetSource(assets, fileName);
    }

    /**
     * Create a new {@link Source} from a byte array.
     *