Load bitmap resources entirely from native code.

Change-Id: I6660baec241794c40611bce79b7f9ce9479e52ba
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 2abb777..f60a7be 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -337,19 +337,26 @@
      */
     public static Bitmap decodeResource(Resources res, int id, Options opts) {
         Bitmap bm = null;
-
+        InputStream is = null; 
+        
         try {
             final TypedValue value = new TypedValue();
-            final InputStream is = res.openRawResource(id, value);
+            is = res.openRawResource(id, value);
 
             bm = decodeResourceStream(res, value, is, null, opts);
-            is.close();
-        } catch (java.io.IOException e) {
+        } catch (Exception e) {
             /*  do nothing.
                 If the exception happened on open, bm will be null.
                 If it happened on close, bm is still valid.
             */
+        } finally {
+            try {
+                if (is != null) is.close();
+            } catch (IOException e) {
+                // Ignore
+            }
         }
+
         return bm;
     }
 
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 3001c743..536f71c 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -16,19 +16,15 @@
 
 package android.renderscript;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Array;
-
 import java.io.IOException;
 import java.io.InputStream;
 
 import android.content.res.Resources;
+import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.os.Bundle;
-import android.renderscript.Type;
-import android.util.Config;
 import android.util.Log;
+import android.util.TypedValue;
 
 /**
  * @hide
@@ -52,7 +48,7 @@
     }
 
     public void data(int[] d) {
-        int size = 0;
+        int size;
         if(mType != null && mType.mElement != null) {
             size = mType.mElement.mSize;
             for(int ct=0; ct < mType.mValues.length; ct++) {
@@ -71,7 +67,7 @@
     }
 
     public void data(float[] d) {
-        int size = 0;
+        int size;
         if(mType != null && mType.mElement != null) {
             size = mType.mElement.mSize;
             for(int ct=0; ct < mType.mValues.length; ct++) {
@@ -245,8 +241,29 @@
     static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
         throws IllegalArgumentException {
 
-        Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
-        return createFromBitmap(rs, b, dstFmt, genMips);
+        InputStream is = null;
+        try {
+            final TypedValue value = new TypedValue();
+            is = res.openRawResource(id, value);
+
+            int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
+            int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mPredefinedID, genMips,
+                    asset);
+
+            return new Allocation(allocationId, rs, null);            
+        } catch (Exception e) {
+            // Ignore
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+            }
+        }
+
+        return null;
     }
 
     static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index ee7b702..0f188f6 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -16,13 +16,10 @@
 
 package android.renderscript;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.lang.reflect.Field;
 
-import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.renderscript.Type;
+import android.graphics.BitmapFactory;
 import android.util.Config;
 import android.util.Log;
 import android.view.Surface;
@@ -35,6 +32,7 @@
 public class RenderScript {
     static final String LOG_TAG = "libRS_jni";
     private static final boolean DEBUG  = false;
+    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
     private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
 
 
@@ -43,6 +41,7 @@
      * We use a class initializer to allow the native code to cache some
      * field offsets.
      */
+    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
     private static boolean sInitialized;
     native private static void _nInit();
 
@@ -95,6 +94,7 @@
     native int  nAllocationCreateSized(int elem, int count);
     native int  nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
     native int  nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
+    native int  nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
 
     native void nAllocationUploadToTexture(int alloc, int baseMioLevel);
     native void nAllocationUploadToBufferObject(int alloc);
@@ -188,6 +188,7 @@
 
     private int     mDev;
     private int     mContext;
+    @SuppressWarnings({"FieldCanBeLocal"})
     private Surface mSurface;
 
     private static boolean mElementsInitialized = false;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 2550181..3ed3327 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -26,7 +26,13 @@
 #include <ui/Surface.h>
 
 #include <core/SkBitmap.h>
+#include <core/SkPixelRef.h>
+#include <core/SkStream.h>
+#include <core/SkTemplates.h>
+#include <images/SkImageDecoder.h>
 
+#include <utils/Asset.h>
+#include <utils/ResourceTypes.h>
 
 #include "jni.h"
 #include "JNIHelp.h"
@@ -397,6 +403,32 @@
 }
 
 static int
+nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jint native_asset)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+
+    Asset* asset = reinterpret_cast<Asset*>(native_asset);
+    SkBitmap bitmap;
+    SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
+            &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+
+    SkBitmap::Config config = bitmap.getConfig();
+
+    RsElementPredefined e = SkBitmapToPredefined(config);
+
+    if (e != RS_ELEMENT_USER_U8) {
+        bitmap.lockPixels();
+        const int w = bitmap.width();
+        const int h = bitmap.height();
+        const void* ptr = bitmap.getPixels();
+        jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
+        bitmap.unlockPixels();
+        return id;
+    }
+    return 0;
+}
+
+static int
 nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
 {
     RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -1239,6 +1271,7 @@
 {"nAllocationCreateSized",         "(II)I",                                (void*)nAllocationCreateSized },
 {"nAllocationCreateFromBitmap",    "(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
 {"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I",      (void*)nAllocationCreateFromBitmapBoxed },
+{"nAllocationCreateFromAssetStream","(IZI)I",                              (void*)nAllocationCreateFromAssetStream },
 {"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
 {"nAllocationUploadToBufferObject","(I)V",                                 (void*)nAllocationUploadToBufferObject },
 {"nAllocationData",                "(I[II)V",                              (void*)nAllocationData_i },