Merge "Add ability to decode only image information with ImageDecoder" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c5557807e9
BIN
core/tests/coretests/res/drawable-nodpi/animated_webp.webp
Normal file
BIN
core/tests/coretests/res/drawable-nodpi/animated_webp.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,12 +1806,39 @@ 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(
|
||||||
listener.onHeaderDecoded(this, info, src);
|
new Size(mWidth, mHeight), mAnimated, getMimeType(), getColorSpace());
|
||||||
} finally {
|
listener.onHeaderDecoded(this, info, src);
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user