Merge "Add ability to decode only image information with ImageDecoder" into udc-dev

This commit is contained in:
Treehugger Robot
2023-05-09 17:50:18 +00:00
committed by Android (Google) Code Review
3 changed files with 128 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics;
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
import androidx.test.platform.app.InstrumentationRegistry;
import com.android.frameworks.coretests.R;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.io.IOException;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ImageDecoderTest {
private final Context mContext = InstrumentationRegistry.getInstrumentation().getContext();
@Test
public void onDecodeHeader_png_returnsPopulatedData() throws IOException {
ImageDecoder.Source src =
ImageDecoder.createSource(mContext.getResources(), R.drawable.gettysburg);
ImageDecoder.ImageInfo info = ImageDecoder.decodeHeader(src);
assertThat(info.getSize().getWidth()).isEqualTo(432);
assertThat(info.getSize().getHeight()).isEqualTo(291);
assertThat(info.getMimeType()).isEqualTo("image/png");
assertThat(info.getColorSpace()).isNotNull();
assertThat(info.getColorSpace().getModel()).isEqualTo(ColorSpace.Model.RGB);
assertThat(info.getColorSpace().getId()).isEqualTo(0);
assertThat(info.isAnimated()).isFalse();
}
@Test
public void onDecodeHeader_animatedWebP_returnsPopulatedData() throws IOException {
ImageDecoder.Source src =
ImageDecoder.createSource(mContext.getResources(), R.drawable.animated_webp);
ImageDecoder.ImageInfo info = ImageDecoder.decodeHeader(src);
assertThat(info.getSize().getWidth()).isEqualTo(278);
assertThat(info.getSize().getHeight()).isEqualTo(183);
assertThat(info.getMimeType()).isEqualTo("image/webp");
assertThat(info.getColorSpace()).isNotNull();
assertThat(info.getColorSpace().getModel()).isEqualTo(ColorSpace.Model.RGB);
assertThat(info.getColorSpace().getId()).isEqualTo(0);
assertThat(info.isAnimated()).isTrue();
}
@Test(expected = IOException.class)
public void onDecodeHeader_invalidSource_throwsException() throws IOException {
ImageDecoder.Source src = ImageDecoder.createSource(new File("/this/file/does/not/exist"));
ImageDecoder.decodeHeader(src);
}
@Test(expected = IOException.class)
public void onDecodeHeader_invalidResource_throwsException() throws IOException {
ImageDecoder.Source src =
ImageDecoder.createSource(mContext.getResources(), R.drawable.box);
ImageDecoder.decodeHeader(src);
}
}

View File

@@ -627,11 +627,19 @@ public final class ImageDecoder implements AutoCloseable {
*/ */
public static class ImageInfo { public static class ImageInfo {
private final Size mSize; private final Size mSize;
private ImageDecoder mDecoder; private final boolean mIsAnimated;
private final String mMimeType;
private final ColorSpace mColorSpace;
private ImageInfo(@NonNull ImageDecoder decoder) { private ImageInfo(
mSize = new Size(decoder.mWidth, decoder.mHeight); @NonNull Size size,
mDecoder = decoder; 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 @NonNull
public String getMimeType() { public String getMimeType() {
return mDecoder.getMimeType(); return mMimeType;
} }
/** /**
@@ -657,7 +665,7 @@ public final class ImageDecoder implements AutoCloseable {
* return an {@link AnimatedImageDrawable}.</p> * return an {@link AnimatedImageDrawable}.</p>
*/ */
public boolean isAnimated() { public boolean isAnimated() {
return mDecoder.mAnimated; return mIsAnimated;
} }
/** /**
@@ -669,7 +677,7 @@ public final class ImageDecoder implements AutoCloseable {
*/ */
@Nullable @Nullable
public ColorSpace getColorSpace() { public ColorSpace getColorSpace() {
return mDecoder.getColorSpace(); return mColorSpace;
} }
}; };
@@ -1798,13 +1806,40 @@ public final class ImageDecoder implements AutoCloseable {
private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@NonNull Source src) { @NonNull Source src) {
if (listener != null) { if (listener != null) {
ImageInfo info = new ImageInfo(this); ImageInfo info =
try { new ImageInfo(
new Size(mWidth, mHeight), mAnimated, getMimeType(), getColorSpace());
listener.onHeaderDecoded(this, info, src); listener.onHeaderDecoded(this, info, src);
} finally {
info.mDecoder = null;
} }
} }
/**
* Return {@link ImageInfo} from a {@code Source}.
*
* <p>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);
}
} }
/** /**