Loading core/jni/android/graphics/ImageDecoder.cpp +17 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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: Loading @@ -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; } } Loading Loading @@ -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 }, Loading @@ -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"); Loading graphics/java/android/graphics/ImageDecoder.java +22 −25 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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 {}; Loading @@ -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 Loading @@ -303,7 +307,7 @@ public final class ImageDecoder implements AutoCloseable { private Rect mCropRect; private PostProcess mPostProcess; private OnExceptionListener mOnExceptionListener; private OnPartialImageListener mOnPartialImageListener; // Objects for interacting with the input. private InputStream mInputStream; Loading Loading @@ -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; } /** Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading
core/jni/android/graphics/ImageDecoder.cpp +17 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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(); } Loading @@ -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: Loading @@ -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; } } Loading Loading @@ -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 }, Loading @@ -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"); Loading
graphics/java/android/graphics/ImageDecoder.java +22 −25 Original line number Diff line number Diff line Loading @@ -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. * Loading @@ -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 {}; Loading @@ -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 Loading @@ -303,7 +307,7 @@ public final class ImageDecoder implements AutoCloseable { private Rect mCropRect; private PostProcess mPostProcess; private OnExceptionListener mOnExceptionListener; private OnPartialImageListener mOnPartialImageListener; // Objects for interacting with the input. private InputStream mInputStream; Loading Loading @@ -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; } /** Loading Loading @@ -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, Loading @@ -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); Loading Loading @@ -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, Loading Loading @@ -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, Loading