summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/ContentResolver.java29
-rw-r--r--core/java/android/provider/DocumentsContract.java13
2 files changed, 39 insertions, 3 deletions
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 5f34f1b2bc0d..804677648d09 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -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} */
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 4632b7553ca0..4ac485099da8 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -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);
}