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

Commit dfc3c061 authored by Ivan Chiang's avatar Ivan Chiang Committed by android-build-merger
Browse files

Merge "Fix can't create thumbnail and wrong orientation issue" into qt-dev am: b037feb1

am: 2f189364

Change-Id: Ie5bc39d51f1aaa4136501d721fa7a3d0c7f362ae
parents 5e5bd2b9 2f189364
Loading
Loading
Loading
Loading
+26 −3
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package android.content;

import static android.provider.DocumentsContract.EXTRA_ORIENTATION;

import android.accounts.Account;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -40,6 +42,7 @@ import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.graphics.ImageDecoder.ImageInfo;
import android.graphics.ImageDecoder.Source;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
@@ -56,6 +59,7 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.storage.StorageManager;
import android.system.Int32Ref;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -3563,9 +3567,14 @@ public abstract class ContentResolver implements ContentInterface {
        // Convert to Point, since that's what the API is defined as
        final Bundle opts = new Bundle();
        opts.putParcelable(EXTRA_SIZE, Point.convert(size));

        return ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> {
            return content.openTypedAssetFile(uri, "image/*", opts, signal);
        final Int32Ref orientation = new Int32Ref(0);

        Bitmap bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> {
            final AssetFileDescriptor afd = content.openTypedAssetFile(uri, "image/*", opts,
                    signal);
            final Bundle extras = afd.getExtras();
            orientation.value = (extras != null) ? extras.getInt(EXTRA_ORIENTATION, 0) : 0;
            return afd;
        }), (ImageDecoder decoder, ImageInfo info, Source source) -> {
            decoder.setAllocator(allocator);

@@ -3581,6 +3590,20 @@ public abstract class ContentResolver implements ContentInterface {
                decoder.setTargetSampleSize(sample);
            }
        });

        // Transform the bitmap if requested. We use a side-channel to
        // communicate the orientation, since EXIF thumbnails don't contain
        // the rotation flags of the original image.
        if (orientation.value != 0) {
            final int width = bitmap.getWidth();
            final int height = bitmap.getHeight();

            final Matrix m = new Matrix();
            m.setRotate(orientation.value, width / 2, height / 2);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
        }

        return bitmap;
    }

    /** {@hide} */
+13 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
import android.graphics.Point;
import android.media.ExifInterface;
import android.media.MediaFile;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -1698,6 +1699,18 @@ public final class DocumentsContract {
        } catch (IOException e) {
        }

        // Use ImageDecoder to do full image decode of heif format file
        // will have right orientation. So, we don't need to add orientation
        // information into extras.
        final String mimeType = MediaFile.getMimeTypeForFile(file.getName());
        if (mimeType.equals("image/heif")
                || mimeType.equals("image/heif-sequence")
                || mimeType.equals("image/heic")
                || mimeType.equals("image/heic-sequence")) {
            return new AssetFileDescriptor(pfd, 0 /* startOffset */,
                    AssetFileDescriptor.UNKNOWN_LENGTH, null /* extras */);
        }

        return new AssetFileDescriptor(pfd, 0, AssetFileDescriptor.UNKNOWN_LENGTH, extras);
    }

+52 −5
Original line number Diff line number Diff line
@@ -244,30 +244,77 @@ public class ThumbnailUtils {

        final Resizer resizer = new Resizer(size, signal);
        final String mimeType = MediaFile.getMimeTypeForFile(file.getName());
        Bitmap bitmap = null;
        ExifInterface exif = null;
        int orientation = 0;

        // get orientation
        if (MediaFile.isExifMimeType(mimeType)) {
            exif = new ExifInterface(file);
            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
                case ExifInterface.ORIENTATION_ROTATE_90:
                    orientation = 90;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    orientation = 180;
                    break;
                case ExifInterface.ORIENTATION_ROTATE_270:
                    orientation = 270;
                    break;
            }
        }

        boolean isHeifFile = false;

        if (mimeType.equals("image/heif")
                || mimeType.equals("image/heif-sequence")
                || mimeType.equals("image/heic")
                || mimeType.equals("image/heic-sequence")) {
            isHeifFile = true;
            try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
                retriever.setDataSource(file.getAbsolutePath());
                return retriever.getThumbnailImageAtIndex(-1,
                bitmap = retriever.getThumbnailImageAtIndex(-1,
                        new MediaMetadataRetriever.BitmapParams(), size.getWidth(),
                        size.getWidth() * size.getHeight());
            } catch (RuntimeException e) {
                throw new IOException("Failed to create thumbnail", e);
            }
        } else if (MediaFile.isExifMimeType(mimeType)) {
            final ExifInterface exif = new ExifInterface(file);
        }

        if (bitmap == null && exif != null) {
            final byte[] raw = exif.getThumbnailBytes();
            if (raw != null) {
                return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
                try {
                    bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
                } catch (ImageDecoder.DecodeException e) {
                    Log.w(TAG, e);
                }
            }
        }

        // Checkpoint before going deeper
        if (signal != null) signal.throwIfCanceled();

        return ImageDecoder.decodeBitmap(ImageDecoder.createSource(file), resizer);
        if (bitmap == null) {
            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(file), resizer);
            // Use ImageDecoder to do full image decode of heif format file
            // will have right orientation. Don't rotate the bitmap again.
            if (isHeifFile) {
                return bitmap;
            }
        }

        // Transform the bitmap if the orientation of the image is not 0.
        if (orientation != 0 && bitmap != null) {
            final int width = bitmap.getWidth();
            final int height = bitmap.getHeight();

            final Matrix m = new Matrix();
            m.setRotate(orientation, width / 2, height / 2);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
        }

        return bitmap;
    }

    /**