From 953f9094a2ec14594fa8501d5f3e2d9e300b1b62 Mon Sep 17 00:00:00 2001 From: Wei-Ta Chen Date: Fri, 3 Dec 2010 14:06:18 -0800 Subject: [PATCH] Add inPreferQualityOverSpeed into BitmapFactory.Options. The new field allows a developer to use a more accurate by slightly slower IDCT method in JPEG decode. This in turns improves the quality of the reconstructed image. The field by default is not set and thus does not affect existing applications. Bug: 3238925 Change-Id: I93d55b7226e47a43e639325cd1a677694d6f2ee4 --- core/jni/android/graphics/BitmapFactory.cpp | 7 +++++++ core/jni/android/graphics/BitmapFactory.h | 1 + core/jni/android/graphics/BitmapRegionDecoder.cpp | 4 ++++ graphics/java/android/graphics/BitmapFactory.java | 11 +++++++++++ 4 files changed, 23 insertions(+) diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 3b2406ce40d47..e72e2b6f16d46 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -27,6 +27,7 @@ jfieldID gOptions_ditherFieldID; jfieldID gOptions_purgeableFieldID; jfieldID gOptions_shareableFieldID; jfieldID gOptions_nativeAllocFieldID; +jfieldID gOptions_preferQualityOverSpeedFieldID; jfieldID gOptions_widthFieldID; jfieldID gOptions_heightFieldID; jfieldID gOptions_mimeFieldID; @@ -185,6 +186,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, bool isPurgeable = forcePurgeable || (allowPurgeable && optionsPurgeable(env, options)); bool reportSizeToVM = optionsReportSizeToVM(env, options); + bool preferQualityOverSpeed = false; if (NULL != options) { sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID); @@ -199,6 +201,8 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); prefConfig = GraphicsJNI::getNativeBitmapConfig(env, jconfig); doDither = env->GetBooleanField(options, gOptions_ditherFieldID); + preferQualityOverSpeed = env->GetBooleanField(options, + gOptions_preferQualityOverSpeedFieldID); } SkImageDecoder* decoder = SkImageDecoder::Factory(stream); @@ -208,6 +212,7 @@ static jobject doDecode(JNIEnv* env, SkStream* stream, jobject padding, decoder->setSampleSize(sampleSize); decoder->setDitherImage(doDither); + decoder->setPreferQualityOverSpeed(preferQualityOverSpeed); NinePatchPeeker peeker(decoder); JavaPixelAllocator javaAllocator(env, reportSizeToVM); @@ -557,6 +562,8 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) { gOptions_purgeableFieldID = getFieldIDCheck(env, gOptions_class, "inPurgeable", "Z"); gOptions_shareableFieldID = getFieldIDCheck(env, gOptions_class, "inInputShareable", "Z"); gOptions_nativeAllocFieldID = getFieldIDCheck(env, gOptions_class, "inNativeAlloc", "Z"); + gOptions_preferQualityOverSpeedFieldID = getFieldIDCheck(env, gOptions_class, + "inPreferQualityOverSpeed", "Z"); gOptions_widthFieldID = getFieldIDCheck(env, gOptions_class, "outWidth", "I"); gOptions_heightFieldID = getFieldIDCheck(env, gOptions_class, "outHeight", "I"); gOptions_mimeFieldID = getFieldIDCheck(env, gOptions_class, "outMimeType", "Ljava/lang/String;"); diff --git a/core/jni/android/graphics/BitmapFactory.h b/core/jni/android/graphics/BitmapFactory.h index f868434620f10..9ae61bcc875ee 100644 --- a/core/jni/android/graphics/BitmapFactory.h +++ b/core/jni/android/graphics/BitmapFactory.h @@ -11,6 +11,7 @@ extern jfieldID gOptions_ditherFieldID; extern jfieldID gOptions_purgeableFieldID; extern jfieldID gOptions_shareableFieldID; extern jfieldID gOptions_nativeAllocFieldID; +extern jfieldID gOptions_preferQualityOverSpeedFieldID; extern jfieldID gOptions_widthFieldID; extern jfieldID gOptions_heightFieldID; extern jfieldID gOptions_mimeFieldID; diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp index bf18d558a55c9..91a82026235bf 100644 --- a/core/jni/android/graphics/BitmapRegionDecoder.cpp +++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp @@ -191,6 +191,7 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b int sampleSize = 1; SkBitmap::Config prefConfig = SkBitmap::kNo_Config; bool doDither = true; + bool preferQualityOverSpeed = false; if (NULL != options) { sampleSize = env->GetIntField(options, gOptions_sampleSizeFieldID); @@ -202,9 +203,12 @@ static jobject nativeDecodeRegion(JNIEnv* env, jobject, SkBitmapRegionDecoder *b jobject jconfig = env->GetObjectField(options, gOptions_configFieldID); prefConfig = GraphicsJNI::getNativeBitmapConfig(env, jconfig); doDither = env->GetBooleanField(options, gOptions_ditherFieldID); + preferQualityOverSpeed = env->GetBooleanField(options, + gOptions_preferQualityOverSpeedFieldID); } decoder->setDitherImage(doDither); + decoder->setPreferQualityOverSpeed(preferQualityOverSpeed); SkBitmap* bitmap = new SkBitmap; SkAutoTDelete adb(bitmap); AutoDecoderCancel adc(options, decoder); diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java index ea5ed6b161a3c..8450c3a621511 100644 --- a/graphics/java/android/graphics/BitmapFactory.java +++ b/graphics/java/android/graphics/BitmapFactory.java @@ -204,11 +204,22 @@ public class BitmapFactory { */ public boolean inNativeAlloc; + /** + * If inPreferQualityOverSpeed is set to true, the decoder will try to + * decode the reconstructed image to a higher quality even at the + * expense of the decoding speed. Currently the field only affects JPEG + * decode, in the case of which a more accurate, but slightly slower, + * IDCT method will be used instead. + * @hide + */ + public boolean inPreferQualityOverSpeed; + /** * The resulting width of the bitmap, set independent of the state of * inJustDecodeBounds. However, if there is an error trying to decode, * outWidth will be set to -1. */ + public int outWidth; /**