Do JPEG tile-based decoding.

Change-Id: I5c1b4ac3c02eb4350ef0ba9a7877b22cfd730cfb
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 5659ba2..204bb74 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -46,6 +46,10 @@
     doThrow(env, "java/lang/OutOfMemoryError", msg);
 }
 
+void doThrowIOE(JNIEnv* env, const char* msg) {
+    doThrow(env, "java/lang/IOException", msg);
+}
+
 bool GraphicsJNI::hasException(JNIEnv *env) {
     if (env->ExceptionCheck() != 0) {
         LOGE("*** Uncaught exception returned from Java call!\n");
@@ -165,6 +169,9 @@
 static jclass   gBitmapConfig_class;
 static jfieldID gBitmapConfig_nativeInstanceID;
 
+static jclass   gLargeBitmap_class;
+static jmethodID gLargeBitmap_constructorMethodID;
+
 static jclass   gCanvas_class;
 static jfieldID gCanvas_nativeInstanceID;
 
@@ -370,6 +377,23 @@
     }
     return obj;
 }
+jobject GraphicsJNI::createLargeBitmap(JNIEnv* env, SkLargeBitmap* bitmap)
+{
+    SkASSERT(bitmap != NULL);
+
+    jobject obj = env->AllocObject(gLargeBitmap_class);
+    if (hasException(env)) {
+        obj = NULL;
+        return obj;
+    }
+    if (obj) {
+        env->CallVoidMethod(obj, gLargeBitmap_constructorMethodID, (jint)bitmap);
+        if (hasException(env)) {
+            obj = NULL;
+        }
+    }
+    return obj;
+}
 
 jobject GraphicsJNI::createRegion(JNIEnv* env, SkRegion* region)
 {
@@ -502,6 +526,35 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+JavaMemoryUsageReporter::JavaMemoryUsageReporter(JNIEnv* env)
+    : fEnv(env), fTotalSize(0) {}
+
+JavaMemoryUsageReporter::~JavaMemoryUsageReporter() {
+    jlong jtotalSize = fTotalSize;
+    fEnv->CallVoidMethod(gVMRuntime_singleton,
+            gVMRuntime_trackExternalFreeMethodID,
+            jtotalSize);
+}
+
+bool JavaMemoryUsageReporter::reportMemory(size_t memorySize) {
+    jlong jsize = memorySize;  // the VM wants longs for the size
+    bool r = fEnv->CallBooleanMethod(gVMRuntime_singleton,
+            gVMRuntime_trackExternalAllocationMethodID,
+            jsize);
+    if (GraphicsJNI::hasException(fEnv)) {
+        return false;
+    }
+    if (!r) {
+        LOGE("VM won't let us allocate %zd bytes\n", memorySize);
+        doThrowOOME(fEnv, "bitmap size exceeds VM budget");
+        return false;
+    }
+    fTotalSize += memorySize;
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 static jclass make_globalref(JNIEnv* env, const char classname[])
 {
     jclass c = env->FindClass(classname);
@@ -547,6 +600,9 @@
     gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
                                             "(IZ[BI)V");
 
+    gLargeBitmap_class = make_globalref(env, "android/graphics/LargeBitmap");
+    gLargeBitmap_constructorMethodID = env->GetMethodID(gLargeBitmap_class, "<init>", "(I)V");
+
     gBitmapConfig_class = make_globalref(env, "android/graphics/Bitmap$Config");
     gBitmapConfig_nativeInstanceID = getFieldIDCheck(env, gBitmapConfig_class,
                                                      "nativeInt", "I");