Loading core/jni/android/graphics/AnimatedImageDrawable.cpp +11 −12 Original line number Diff line number Diff line Loading @@ -35,14 +35,14 @@ static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID; // Note: jpostProcess holds a handle to the ImageDecoder. static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, jlong nativeImageDecoder, jobject jpostProcess, jint width, jint height, jobject jsubset) { jint width, jint height, jlong colorSpaceHandle, jboolean extended, jobject jsubset) { if (nativeImageDecoder == 0) { doThrowIOE(env, "Cannot create AnimatedImageDrawable from null!"); return 0; } auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder); const SkISize scaledSize = SkISize::Make(width, height); SkIRect subset; if (jsubset) { GraphicsJNI::jrect_to_irect(env, jsubset, &subset); Loading @@ -50,15 +50,8 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, subset = SkIRect::MakeWH(width, height); } auto info = imageDecoder->mCodec->getInfo(); bool hasRestoreFrame = false; if (imageDecoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) { if (width < info.width() && height < info.height()) { // WebP will scale its SkBitmap to the scaled size. // FIXME: b/73529447 GIF should do the same. info = info.makeWH(width, height); } } else { if (imageDecoder->mCodec->getEncodedFormat() != SkEncodedImageFormat::kWEBP) { const int frameCount = imageDecoder->mCodec->codec()->getFrameCount(); for (int i = 0; i < frameCount; ++i) { SkCodec::FrameInfo frameInfo; Loading @@ -73,6 +66,12 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, } } auto info = imageDecoder->mCodec->getInfo().makeWH(width, height) .makeColorSpace(GraphicsJNI::getNativeColorSpace(colorSpaceHandle)); if (extended) { info = info.makeColorType(kRGBA_F16_SkColorType); } size_t bytesUsed = info.computeMinByteSize(); // SkAnimatedImage has one SkBitmap for decoding, plus an extra one if there is a // kRestorePrevious frame. AnimatedImageDrawable has two SkPictures storing the current Loading @@ -96,7 +95,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, sk_sp<SkAnimatedImage> animatedImg = SkAnimatedImage::Make(std::move(imageDecoder->mCodec), scaledSize, subset, info, subset, std::move(picture)); if (!animatedImg) { doThrowIOE(env, "Failed to create drawable"); Loading Loading @@ -246,7 +245,7 @@ static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, j } static const JNINativeMethod gAnimatedImageDrawableMethods[] = { { "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate }, { "nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J",(void*) AnimatedImageDrawable_nCreate }, { "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer }, { "nDraw", "(JJ)J", (void*) AnimatedImageDrawable_nDraw }, { "nSetAlpha", "(JI)V", (void*) AnimatedImageDrawable_nSetAlpha }, Loading graphics/java/android/graphics/ImageDecoder.java +25 −12 Original line number Diff line number Diff line Loading @@ -1642,14 +1642,16 @@ public final class ImageDecoder implements AutoCloseable { mTempStorage = null; } private void checkState() { private void checkState(boolean animated) { if (mNativePtr == 0) { throw new IllegalStateException("Cannot use closed ImageDecoder!"); } checkSubset(mDesiredWidth, mDesiredHeight, mCropRect); if (mAllocator == ALLOCATOR_HARDWARE) { // animated ignores the allocator, so no need to check for incompatible // fields. if (!animated && mAllocator == ALLOCATOR_HARDWARE) { if (mMutable) { throw new IllegalStateException("Cannot make mutable HARDWARE Bitmap!"); } Loading @@ -1673,21 +1675,30 @@ public final class ImageDecoder implements AutoCloseable { } } private boolean checkForExtended() { if (mDesiredColorSpace == null) { return false; } return mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB); } private long getColorSpacePtr() { if (mDesiredColorSpace == null) { return 0; } return mDesiredColorSpace.getNativeInstance(); } @WorkerThread @NonNull private Bitmap decodeBitmapInternal() throws IOException { checkState(); long colorSpacePtr = 0; boolean extended = false; if (mDesiredColorSpace != null) { colorSpacePtr = mDesiredColorSpace.getNativeInstance(); extended = mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB); } checkState(false); return nDecodeBitmap(mNativePtr, this, mPostProcessor != null, mDesiredWidth, mDesiredHeight, mCropRect, mMutable, mAllocator, mUnpremultipliedRequired, mConserveMemory, mDecodeAsAlphaMask, colorSpacePtr, extended); mConserveMemory, mDecodeAsAlphaMask, getColorSpacePtr(), checkForExtended()); } private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, Loading Loading @@ -1753,9 +1764,11 @@ public final class ImageDecoder implements AutoCloseable { // mPostProcessor exists. ImageDecoder postProcessPtr = decoder.mPostProcessor == null ? null : decoder; decoder.checkState(true); Drawable d = new AnimatedImageDrawable(decoder.mNativePtr, postProcessPtr, decoder.mDesiredWidth, decoder.mDesiredHeight, srcDensity, decoder.mDesiredHeight, decoder.getColorSpacePtr(), decoder.checkForExtended(), srcDensity, src.computeDstDensity(), decoder.mCropRect, decoder.mInputStream, decoder.mAssetFd); // d has taken ownership of these objects. Loading graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +6 −6 Original line number Diff line number Diff line Loading @@ -291,8 +291,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { */ public AnimatedImageDrawable(long nativeImageDecoder, @Nullable ImageDecoder decoder, int width, int height, int srcDensity, int dstDensity, Rect cropRect, InputStream inputStream, AssetFileDescriptor afd) long colorSpaceHandle, boolean extended, int srcDensity, int dstDensity, Rect cropRect, InputStream inputStream, AssetFileDescriptor afd) throws IOException { width = Bitmap.scaleFromDensity(width, srcDensity, dstDensity); height = Bitmap.scaleFromDensity(height, srcDensity, dstDensity); Loading @@ -309,8 +309,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { mIntrinsicHeight = cropRect.height(); } mState = new State(nCreate(nativeImageDecoder, decoder, width, height, cropRect), inputStream, afd); mState = new State(nCreate(nativeImageDecoder, decoder, width, height, colorSpaceHandle, extended, cropRect), inputStream, afd); final long nativeSize = nNativeByteSize(mState.mNativePtr); NativeAllocationRegistry registry = new NativeAllocationRegistry( Loading Loading @@ -574,8 +574,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private static native long nCreate(long nativeImageDecoder, @Nullable ImageDecoder decoder, int width, int height, Rect cropRect) throws IOException; @Nullable ImageDecoder decoder, int width, int height, long colorSpaceHandle, boolean extended, Rect cropRect) throws IOException; @FastNative private static native long nGetNativeFinalizer(); private static native long nDraw(long nativePtr, long canvasNativePtr); Loading Loading
core/jni/android/graphics/AnimatedImageDrawable.cpp +11 −12 Original line number Diff line number Diff line Loading @@ -35,14 +35,14 @@ static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID; // Note: jpostProcess holds a handle to the ImageDecoder. static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, jlong nativeImageDecoder, jobject jpostProcess, jint width, jint height, jobject jsubset) { jint width, jint height, jlong colorSpaceHandle, jboolean extended, jobject jsubset) { if (nativeImageDecoder == 0) { doThrowIOE(env, "Cannot create AnimatedImageDrawable from null!"); return 0; } auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder); const SkISize scaledSize = SkISize::Make(width, height); SkIRect subset; if (jsubset) { GraphicsJNI::jrect_to_irect(env, jsubset, &subset); Loading @@ -50,15 +50,8 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, subset = SkIRect::MakeWH(width, height); } auto info = imageDecoder->mCodec->getInfo(); bool hasRestoreFrame = false; if (imageDecoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) { if (width < info.width() && height < info.height()) { // WebP will scale its SkBitmap to the scaled size. // FIXME: b/73529447 GIF should do the same. info = info.makeWH(width, height); } } else { if (imageDecoder->mCodec->getEncodedFormat() != SkEncodedImageFormat::kWEBP) { const int frameCount = imageDecoder->mCodec->codec()->getFrameCount(); for (int i = 0; i < frameCount; ++i) { SkCodec::FrameInfo frameInfo; Loading @@ -73,6 +66,12 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, } } auto info = imageDecoder->mCodec->getInfo().makeWH(width, height) .makeColorSpace(GraphicsJNI::getNativeColorSpace(colorSpaceHandle)); if (extended) { info = info.makeColorType(kRGBA_F16_SkColorType); } size_t bytesUsed = info.computeMinByteSize(); // SkAnimatedImage has one SkBitmap for decoding, plus an extra one if there is a // kRestorePrevious frame. AnimatedImageDrawable has two SkPictures storing the current Loading @@ -96,7 +95,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/, sk_sp<SkAnimatedImage> animatedImg = SkAnimatedImage::Make(std::move(imageDecoder->mCodec), scaledSize, subset, info, subset, std::move(picture)); if (!animatedImg) { doThrowIOE(env, "Failed to create drawable"); Loading Loading @@ -246,7 +245,7 @@ static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, j } static const JNINativeMethod gAnimatedImageDrawableMethods[] = { { "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate }, { "nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J",(void*) AnimatedImageDrawable_nCreate }, { "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer }, { "nDraw", "(JJ)J", (void*) AnimatedImageDrawable_nDraw }, { "nSetAlpha", "(JI)V", (void*) AnimatedImageDrawable_nSetAlpha }, Loading
graphics/java/android/graphics/ImageDecoder.java +25 −12 Original line number Diff line number Diff line Loading @@ -1642,14 +1642,16 @@ public final class ImageDecoder implements AutoCloseable { mTempStorage = null; } private void checkState() { private void checkState(boolean animated) { if (mNativePtr == 0) { throw new IllegalStateException("Cannot use closed ImageDecoder!"); } checkSubset(mDesiredWidth, mDesiredHeight, mCropRect); if (mAllocator == ALLOCATOR_HARDWARE) { // animated ignores the allocator, so no need to check for incompatible // fields. if (!animated && mAllocator == ALLOCATOR_HARDWARE) { if (mMutable) { throw new IllegalStateException("Cannot make mutable HARDWARE Bitmap!"); } Loading @@ -1673,21 +1675,30 @@ public final class ImageDecoder implements AutoCloseable { } } private boolean checkForExtended() { if (mDesiredColorSpace == null) { return false; } return mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB); } private long getColorSpacePtr() { if (mDesiredColorSpace == null) { return 0; } return mDesiredColorSpace.getNativeInstance(); } @WorkerThread @NonNull private Bitmap decodeBitmapInternal() throws IOException { checkState(); long colorSpacePtr = 0; boolean extended = false; if (mDesiredColorSpace != null) { colorSpacePtr = mDesiredColorSpace.getNativeInstance(); extended = mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB) || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB); } checkState(false); return nDecodeBitmap(mNativePtr, this, mPostProcessor != null, mDesiredWidth, mDesiredHeight, mCropRect, mMutable, mAllocator, mUnpremultipliedRequired, mConserveMemory, mDecodeAsAlphaMask, colorSpacePtr, extended); mConserveMemory, mDecodeAsAlphaMask, getColorSpacePtr(), checkForExtended()); } private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, Loading Loading @@ -1753,9 +1764,11 @@ public final class ImageDecoder implements AutoCloseable { // mPostProcessor exists. ImageDecoder postProcessPtr = decoder.mPostProcessor == null ? null : decoder; decoder.checkState(true); Drawable d = new AnimatedImageDrawable(decoder.mNativePtr, postProcessPtr, decoder.mDesiredWidth, decoder.mDesiredHeight, srcDensity, decoder.mDesiredHeight, decoder.getColorSpacePtr(), decoder.checkForExtended(), srcDensity, src.computeDstDensity(), decoder.mCropRect, decoder.mInputStream, decoder.mAssetFd); // d has taken ownership of these objects. Loading
graphics/java/android/graphics/drawable/AnimatedImageDrawable.java +6 −6 Original line number Diff line number Diff line Loading @@ -291,8 +291,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { */ public AnimatedImageDrawable(long nativeImageDecoder, @Nullable ImageDecoder decoder, int width, int height, int srcDensity, int dstDensity, Rect cropRect, InputStream inputStream, AssetFileDescriptor afd) long colorSpaceHandle, boolean extended, int srcDensity, int dstDensity, Rect cropRect, InputStream inputStream, AssetFileDescriptor afd) throws IOException { width = Bitmap.scaleFromDensity(width, srcDensity, dstDensity); height = Bitmap.scaleFromDensity(height, srcDensity, dstDensity); Loading @@ -309,8 +309,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { mIntrinsicHeight = cropRect.height(); } mState = new State(nCreate(nativeImageDecoder, decoder, width, height, cropRect), inputStream, afd); mState = new State(nCreate(nativeImageDecoder, decoder, width, height, colorSpaceHandle, extended, cropRect), inputStream, afd); final long nativeSize = nNativeByteSize(mState.mNativePtr); NativeAllocationRegistry registry = new NativeAllocationRegistry( Loading Loading @@ -574,8 +574,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 { private static native long nCreate(long nativeImageDecoder, @Nullable ImageDecoder decoder, int width, int height, Rect cropRect) throws IOException; @Nullable ImageDecoder decoder, int width, int height, long colorSpaceHandle, boolean extended, Rect cropRect) throws IOException; @FastNative private static native long nGetNativeFinalizer(); private static native long nDraw(long nativePtr, long canvasNativePtr); Loading