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 {
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}.</p>
*/
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}.
*
* <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);
}
}