diff options
| -rw-r--r-- | core/jni/android/graphics/ImageDecoder.cpp | 27 | ||||
| -rw-r--r-- | graphics/java/android/graphics/ImageDecoder.java | 47 |
2 files changed, 39 insertions, 35 deletions
diff --git a/core/jni/android/graphics/ImageDecoder.cpp b/core/jni/android/graphics/ImageDecoder.cpp index c2375641bc65..ec03f82b17e0 100644 --- a/core/jni/android/graphics/ImageDecoder.cpp +++ b/core/jni/android/graphics/ImageDecoder.cpp @@ -46,7 +46,7 @@ static jmethodID gImageDecoder_constructorMethodID; static jmethodID gPoint_constructorMethodID; static jmethodID gIncomplete_constructorMethodID; static jmethodID gCorrupt_constructorMethodID; -static jmethodID gCallback_onExceptionMethodID; +static jmethodID gCallback_onPartialImageMethodID; static jmethodID gPostProcess_postProcessMethodID; static jmethodID gCanvas_constructorMethodID; static jmethodID gCanvas_releaseMethodID; @@ -276,7 +276,7 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong SkAndroidCodec::AndroidOptions options; options.fSampleSize = sampleSize; auto result = codec->getAndroidPixels(decodeInfo, bm.getPixels(), bm.rowBytes(), &options); - jobject jexception = env->ExceptionOccurred(); + jthrowable jexception = env->ExceptionOccurred(); if (jexception) { env->ExceptionClear(); } @@ -287,12 +287,14 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong break; case SkCodec::kIncompleteInput: if (jcallback && !jexception) { - jexception = env->NewObject(gIncomplete_class, gIncomplete_constructorMethodID); + jexception = (jthrowable) env->NewObject(gIncomplete_class, + gIncomplete_constructorMethodID); } break; case SkCodec::kErrorInInput: if (jcallback && !jexception) { - jexception = env->NewObject(gCorrupt_class, gCorrupt_constructorMethodID); + jexception = (jthrowable) env->NewObject(gCorrupt_class, + gCorrupt_constructorMethodID); } break; default: @@ -303,9 +305,14 @@ static jobject ImageDecoder_nDecodeBitmap(JNIEnv* env, jobject /*clazz*/, jlong } if (jexception) { - // FIXME: Do not provide a way for the client to force the method to return null. - if (!env->CallBooleanMethod(jcallback, gCallback_onExceptionMethodID, jexception) || - env->ExceptionCheck()) { + bool throwException = !env->CallBooleanMethod(jcallback, gCallback_onPartialImageMethodID, + jexception); + if (env->ExceptionCheck()) { + return nullptr; + } + + if (throwException) { + env->Throw(jexception); return nullptr; } } @@ -512,7 +519,7 @@ static const JNINativeMethod gImageDecoderMethods[] = { { "nCreate", "([BII)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateByteArray }, { "nCreate", "(Ljava/io/InputStream;[B)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateInputStream }, { "nCreate", "(Ljava/io/FileDescriptor;)Landroid/graphics/ImageDecoder;", (void*) ImageDecoder_nCreateFd }, - { "nDecodeBitmap", "(JLandroid/graphics/ImageDecoder$OnExceptionListener;Landroid/graphics/PostProcess;IILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;", + { "nDecodeBitmap", "(JLandroid/graphics/ImageDecoder$OnPartialImageListener;Landroid/graphics/PostProcess;IILandroid/graphics/Rect;ZIZZZ)Landroid/graphics/Bitmap;", (void*) ImageDecoder_nDecodeBitmap }, { "nGetSampledSize","(JI)Landroid/graphics/Point;", (void*) ImageDecoder_nGetSampledSize }, { "nGetPadding", "(JLandroid/graphics/Rect;)V", (void*) ImageDecoder_nGetPadding }, @@ -533,8 +540,8 @@ int register_android_graphics_ImageDecoder(JNIEnv* env) { gCorrupt_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ImageDecoder$CorruptException")); gCorrupt_constructorMethodID = GetMethodIDOrDie(env, gCorrupt_class, "<init>", "()V"); - jclass callback_class = FindClassOrDie(env, "android/graphics/ImageDecoder$OnExceptionListener"); - gCallback_onExceptionMethodID = GetMethodIDOrDie(env, callback_class, "onException", "(Ljava/io/IOException;)Z"); + jclass callback_class = FindClassOrDie(env, "android/graphics/ImageDecoder$OnPartialImageListener"); + gCallback_onPartialImageMethodID = GetMethodIDOrDie(env, callback_class, "onPartialImage", "(Ljava/io/IOException;)Z"); jclass postProcess_class = FindClassOrDie(env, "android/graphics/PostProcess"); gPostProcess_postProcessMethodID = GetMethodIDOrDie(env, postProcess_class, "postProcess", "(Landroid/graphics/Canvas;II)I"); diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index 94b219abaf0e..419e2b7e4818 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -239,7 +239,7 @@ public final class ImageDecoder implements AutoCloseable { }; /** - * Supplied to onException if the provided data is incomplete. + * Supplied to onPartialImage if the provided data is incomplete. * * Will never be thrown by ImageDecoder. * @@ -252,7 +252,7 @@ public final class ImageDecoder implements AutoCloseable { * * May be thrown if there is nothing to display. * - * If supplied to onException, there may be a correct partial image to + * If supplied to onPartialImage, there may be a correct partial image to * display. */ public static class CorruptException extends IOException {}; @@ -275,17 +275,21 @@ public final class ImageDecoder implements AutoCloseable { /** * Optional listener supplied to the ImageDecoder. */ - public static interface OnExceptionListener { + public static interface OnPartialImageListener { /** - * Called when there is a problem in the stream or in the data. - * FIXME: Report how much of the image has been decoded? + * Called when there is only a partial image to display. * - * @param e IOException containing information about the error. - * @return True to create and return a {@link Drawable}/ - * {@link Bitmap} with partial data. False to return - * {@code null}. True is the default. + * If the input is incomplete or contains an error, this listener lets + * the client know that and allows them to optionally bypass the rest + * of the decode/creation process. + * + * @param e IOException containing information about the error that + * interrupted the decode. + * @return True (which is the default) to create and return a + * {@link Drawable}/{@link Bitmap} with partial data. False to + * abort the decode and throw the {@link java.io.IOException}. */ - public boolean onException(IOException e); + public boolean onPartialImage(IOException e); }; // Fields @@ -302,8 +306,8 @@ public final class ImageDecoder implements AutoCloseable { private boolean mAsAlphaMask = false; private Rect mCropRect; - private PostProcess mPostProcess; - private OnExceptionListener mOnExceptionListener; + private PostProcess mPostProcess; + private OnPartialImageListener mOnPartialImageListener; // Objects for interacting with the input. private InputStream mInputStream; @@ -557,13 +561,13 @@ public final class ImageDecoder implements AutoCloseable { } /** - * Set (replace) the {@link OnExceptionListener} on this object. + * Set (replace) the {@link OnPartialImageListener} on this object. * * Will be called if there is an error in the input. Without one, a * partial {@link Bitmap} will be created. */ - public void setOnExceptionListener(OnExceptionListener l) { - mOnExceptionListener = l; + public void setOnPartialImageListener(OnPartialImageListener l) { + mOnPartialImageListener = l; } /** @@ -712,7 +716,7 @@ public final class ImageDecoder implements AutoCloseable { } Bitmap bm = nDecodeBitmap(decoder.mNativePtr, - decoder.mOnExceptionListener, + decoder.mOnPartialImageListener, decoder.mPostProcess, decoder.mDesiredWidth, decoder.mDesiredHeight, @@ -722,13 +726,6 @@ public final class ImageDecoder implements AutoCloseable { false, // mRequireUnpremultiplied decoder.mPreferRamOverQuality, decoder.mAsAlphaMask); - if (bm == null) { - // FIXME: bm should never be null. Currently a return value - // of false from onException will result in bm being null. What - // is the right API to choose to discard partial Bitmaps? - return null; - } - Resources res = src.getResources(); if (res == null) { bm.setDensity(Bitmap.DENSITY_NONE); @@ -786,7 +783,7 @@ public final class ImageDecoder implements AutoCloseable { decoder.checkState(); return nDecodeBitmap(decoder.mNativePtr, - decoder.mOnExceptionListener, + decoder.mOnPartialImageListener, decoder.mPostProcess, decoder.mDesiredWidth, decoder.mDesiredHeight, @@ -821,7 +818,7 @@ public final class ImageDecoder implements AutoCloseable { private static native ImageDecoder nCreate(FileDescriptor fd) throws IOException; @NonNull private static native Bitmap nDecodeBitmap(long nativePtr, - OnExceptionListener listener, + OnPartialImageListener listener, PostProcess postProcess, int width, int height, Rect cropRect, boolean mutable, |