diff --git a/api/current.txt b/api/current.txt index 1a56525ab1531..cf33181970971 100644 --- a/api/current.txt +++ b/api/current.txt @@ -12244,6 +12244,7 @@ package android.graphics { field public int inTargetDensity; field public byte[] inTempStorage; field public deprecated boolean mCancel; + field public android.graphics.Bitmap.Config outConfig; field public int outHeight; field public java.lang.String outMimeType; field public int outWidth; diff --git a/api/system-current.txt b/api/system-current.txt index 06411d08dccd1..251855c9da0e1 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -12833,6 +12833,7 @@ package android.graphics { field public int inTargetDensity; field public byte[] inTempStorage; field public deprecated boolean mCancel; + field public android.graphics.Bitmap.Config outConfig; field public int outHeight; field public java.lang.String outMimeType; field public int outWidth; diff --git a/api/test-current.txt b/api/test-current.txt index cde9bdc63faa2..ba632bd8111ca 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -12278,6 +12278,7 @@ package android.graphics { field public int inTargetDensity; field public byte[] inTempStorage; field public deprecated boolean mCancel; + field public android.graphics.Bitmap.Config outConfig; field public int outHeight; field public java.lang.String outMimeType; field public int outWidth; diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 19d4848e16560..2aa16b281884e 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -39,6 +39,7 @@ jfieldID gOptions_targetDensityFieldID; jfieldID gOptions_widthFieldID; jfieldID gOptions_heightFieldID; jfieldID gOptions_mimeFieldID; +jfieldID gOptions_outConfigFieldID; jfieldID gOptions_mCancelID; jfieldID gOptions_bitmapFieldID; @@ -47,6 +48,9 @@ jfieldID gBitmap_ninePatchInsetsFieldID; jclass gInsetStruct_class; jmethodID gInsetStruct_constructorMethodID; +jclass gBitmapConfig_class; +jmethodID gBitmapConfig_nativeToConfigMethodID; + using namespace android; jstring encodedFormatToString(JNIEnv* env, SkEncodedImageFormat format) { @@ -298,6 +302,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding env->SetIntField(options, gOptions_widthFieldID, -1); env->SetIntField(options, gOptions_heightFieldID, -1); env->SetObjectField(options, gOptions_mimeFieldID, 0); + env->SetObjectField(options, gOptions_outConfigFieldID, 0); jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); prefColorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig); @@ -352,6 +357,9 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding scaledHeight = codec->getInfo().height() / sampleSize; } + // Set the decode colorType + SkColorType decodeColorType = codec->computeOutputColorType(prefColorType); + // Set the options and return if the client only wants the size. if (options != NULL) { jstring mimeType = encodedFormatToString( @@ -363,6 +371,20 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding env->SetIntField(options, gOptions_heightFieldID, scaledHeight); env->SetObjectField(options, gOptions_mimeFieldID, mimeType); + SkColorType outColorType = decodeColorType; + // Scaling can affect the output color type + if (willScale || scale != 1.0f) { + outColorType = colorTypeForScaledOutput(outColorType); + } + + jint configID = GraphicsJNI::colorTypeToLegacyBitmapConfig(outColorType); + if (isHardware) { + configID = GraphicsJNI::kHardware_LegacyBitmapConfig; + } + jobject config = env->CallStaticObjectMethod(gBitmapConfig_class, + gBitmapConfig_nativeToConfigMethodID, configID); + env->SetObjectField(options, gOptions_outConfigFieldID, config); + if (onlyDecodeSize) { return nullptr; } @@ -409,10 +431,6 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding decodeAllocator = &defaultAllocator; } - // Set the decode colorType. This is necessary because we can't always support - // the requested colorType. - SkColorType decodeColorType = codec->computeOutputColorType(prefColorType); - // Construct a color table for the decode if necessary sk_sp colorTable(nullptr); SkPMColor* colorPtr = nullptr; @@ -747,6 +765,8 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) { gOptions_widthFieldID = GetFieldIDOrDie(env, options_class, "outWidth", "I"); gOptions_heightFieldID = GetFieldIDOrDie(env, options_class, "outHeight", "I"); gOptions_mimeFieldID = GetFieldIDOrDie(env, options_class, "outMimeType", "Ljava/lang/String;"); + gOptions_outConfigFieldID = GetFieldIDOrDie(env, options_class, "outConfig", + "Landroid/graphics/Bitmap$Config;"); gOptions_mCancelID = GetFieldIDOrDie(env, options_class, "mCancel", "Z"); jclass bitmap_class = FindClassOrDie(env, "android/graphics/Bitmap"); @@ -758,6 +778,11 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) { gInsetStruct_constructorMethodID = GetMethodIDOrDie(env, gInsetStruct_class, "", "(IIIIIIIIFIF)V"); + gBitmapConfig_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, + "android/graphics/Bitmap$Config")); + gBitmapConfig_nativeToConfigMethodID = GetStaticMethodIDOrDie(env, gBitmapConfig_class, + "nativeToConfig", "(I)Landroid/graphics/Bitmap$Config;"); + return android::RegisterMethodsOrDie(env, "android/graphics/BitmapFactory", gMethods, NELEM(gMethods)); } diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index ed9b5f4c2046e..5d7310167b7c0 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -287,21 +287,7 @@ void GraphicsJNI::point_to_jpointf(const SkPoint& r, JNIEnv* env, jobject obj) env->SetFloatField(obj, gPointF_yFieldID, SkScalarToFloat(r.fY)); } -// This enum must keep these int values, to match the int values -// in the java Bitmap.Config enum. -enum LegacyBitmapConfig { - kNo_LegacyBitmapConfig = 0, - kA8_LegacyBitmapConfig = 1, - kIndex8_LegacyBitmapConfig = 2, - kRGB_565_LegacyBitmapConfig = 3, - kARGB_4444_LegacyBitmapConfig = 4, - kARGB_8888_LegacyBitmapConfig = 5, - kRGBA_16F_LegacyBitmapConfig = 6, - kHardware_LegacyBitmapConfig = 7, - - kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig -}; - +// See enum values in GraphicsJNI.h jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) { switch (colorType) { case kRGBA_F16_SkColorType: diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index e899db5592bcf..8a1ef6ee5d340 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -24,6 +24,21 @@ struct Typeface; class GraphicsJNI { public: + // This enum must keep these int values, to match the int values + // in the java Bitmap.Config enum. + enum LegacyBitmapConfig { + kNo_LegacyBitmapConfig = 0, + kA8_LegacyBitmapConfig = 1, + kIndex8_LegacyBitmapConfig = 2, + kRGB_565_LegacyBitmapConfig = 3, + kARGB_4444_LegacyBitmapConfig = 4, + kARGB_8888_LegacyBitmapConfig = 5, + kRGBA_16F_LegacyBitmapConfig = 6, + kHardware_LegacyBitmapConfig = 7, + + kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig + }; + // returns true if an exception is set (and dumps it out to the Log) static bool hasException(JNIEnv*); diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index 64a726babce05..a3c6c6edb3ada 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -350,10 +350,16 @@ public class BitmapFactory { /** * If known, this string is set to the mimetype of the decoded image. - * If not know, or there is an error, it is set to null. + * If not known, or there is an error, it is set to null. */ public String outMimeType; + /** + * If known, the config the decoded bitmap will have. + * If not known, or there is an error, it is set to null. + */ + public Bitmap.Config outConfig; + /** * Temp storage to use for decoding. Suggest 16K or so. */