From 65327c05c4040a580edba906d8ac517a664d63fd Mon Sep 17 00:00:00 2001
From: Jernej Virag
Date: Wed, 3 May 2023 14:30:45 +0200
Subject: Add ability to decode only image information with ImageDecoder
This creates a @hide API which only retrieves ImageInfo object without
continuing the decode of full image. It mirrors
BitmapOptions.inJustDecodeBounds behaviour and allows checking
dimensions and color space configuration of images without proceeding to
full decode (if able).
Bug: 280572656
Test: atest android.graphics.ImageDecoderTest
android.graphics.cts.ImageDecoderTest
Change-Id: I704ec6c41d76f655222da7ee322e3b0e4954533d
---
graphics/java/android/graphics/ImageDecoder.java | 61 +++++++++++++++++++-----
1 file changed, 48 insertions(+), 13 deletions(-)
(limited to 'graphics/java/android')
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index dd4b58eb83dc..b2da233fc21e 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -627,11 +627,19 @@ public final class ImageDecoder implements AutoCloseable {
*/
public static class ImageInfo {
private final Size mSize;
- private ImageDecoder mDecoder;
+ private final boolean mIsAnimated;
+ private final String mMimeType;
+ private final ColorSpace mColorSpace;
- private ImageInfo(@NonNull ImageDecoder decoder) {
- mSize = new Size(decoder.mWidth, decoder.mHeight);
- mDecoder = decoder;
+ private ImageInfo(
+ @NonNull Size size,
+ boolean isAnimated,
+ @NonNull String mimeType,
+ @Nullable ColorSpace colorSpace) {
+ mSize = size;
+ mIsAnimated = isAnimated;
+ mMimeType = mimeType;
+ mColorSpace = colorSpace;
}
/**
@@ -647,7 +655,7 @@ public final class ImageDecoder implements AutoCloseable {
*/
@NonNull
public String getMimeType() {
- return mDecoder.getMimeType();
+ return mMimeType;
}
/**
@@ -657,7 +665,7 @@ public final class ImageDecoder implements AutoCloseable {
* return an {@link AnimatedImageDrawable}.
*/
public boolean isAnimated() {
- return mDecoder.mAnimated;
+ return mIsAnimated;
}
/**
@@ -669,7 +677,7 @@ public final class ImageDecoder implements AutoCloseable {
*/
@Nullable
public ColorSpace getColorSpace() {
- return mDecoder.getColorSpace();
+ return mColorSpace;
}
};
@@ -1798,12 +1806,39 @@ public final class ImageDecoder implements AutoCloseable {
private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@NonNull Source src) {
if (listener != null) {
- ImageInfo info = new ImageInfo(this);
- try {
- listener.onHeaderDecoded(this, info, src);
- } finally {
- info.mDecoder = null;
- }
+ ImageInfo info =
+ new ImageInfo(
+ new Size(mWidth, mHeight), mAnimated, getMimeType(), getColorSpace());
+ listener.onHeaderDecoded(this, info, src);
+ }
+ }
+
+ /**
+ * Return {@link ImageInfo} from a {@code Source}.
+ *
+ * Returns the same {@link ImageInfo} object that a usual decoding process would return as
+ * part of {@link OnHeaderDecodedListener}.
+ *
+ * @param src representing the encoded image.
+ * @return ImageInfo describing the image.
+ * @throws IOException if {@code src} is not found, is an unsupported format, or cannot be
+ * decoded for any reason.
+ * @hide
+ */
+ @WorkerThread
+ @NonNull
+ public static ImageInfo decodeHeader(@NonNull Source src) throws IOException {
+ Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "ImageDecoder#decodeHeader");
+ try (ImageDecoder decoder = src.createImageDecoder(true /*preferAnimation*/)) {
+ // We don't want to leak decoder so resolve all properties immediately.
+ return new ImageInfo(
+ new Size(decoder.mWidth, decoder.mHeight),
+ decoder.mAnimated,
+ decoder.getMimeType(),
+ decoder.getColorSpace());
+ } finally {
+ // Close the ImageDecoder#decodeHeader trace.
+ Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
}
--
cgit v1.2.3-59-g8ed1b