<h2>Code</h2>
I used to use java (jython to be precise) when i used to work as WebSphere (Yes, an IBM product) administrator a really long time back. After such a long gap, i had to look into java again when i needed to do some native level programming for android app.

My final target was to do some image processing on camera feed. Out of habit (c/c++), i wanted to start with a header to declare the methods that i saw i would need later. Searching through google gave me couple of options on how to generate the required headers.
<ul>
	<li>Use <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javah.html">javah</a> and generate</li>
	<li>Write them yourself</li>
</ul>
I took the second route. After a bit of playing with the tedious naming convention for jni functions, i use the following macro to create my function declarations.
<code>
#define DECLARE(returnType,fullClassName,func,...) \
JNIEXPORT returnType JNICALL Java_##fullClassName##_##func(JNIEnv *env, jclass clazz,__VA_ARGS__);
</code>

An example declaration of function that takes <a href="http://www.fourcc.org/yuv.php#NV21">NV21</a> format data as input and writes output to bitmap will be as follows:
<code>
DECLARE(void,com_example_CameraPreview,gaussianBlur,jobject outBmp, jbyteArray inData, jint width, jint height)
</code>

I like it this way because it makes my header more readable than it will be if generated using javah. Once the headers are generated, i moved onto actual code.

Unless you have multiple functions that share same number of input parameters and identical logic, it is hard to abstract the actual code using a macro. In anycase, i don't like macros with logic as it makes life hard to debug later. So, I had to write the full signature when implementing the function.
<code>
JNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(
JNIEnv *env,
jclass clazz,
jobject outBmp,
jByteArray inData,
jint width,
jint height)
{
// TODO: process the input and write the output
}
</code>

With appropriate inclusion of headers and putting together everything we have done so far, the header file and source file will look as below.

Click processor.h to see the full source code for function declarations. I have included couple of extra android related headers which are required to read bitmap files and print debug messages from jni routines. The c-string pointed by macro <em>app_name</em> can be used to prune the output of command <em>adb logcat</em> to get only the messages that are associated with our jni routines. All you would need to do is to pass on the value of <em>app_name</em> to adb as an option as shown below. It is quite useful when you are debugging problems that are related to accuracy of results.
<code>
adb logcat -s "JNIProcessor"
</code>

Next comes the cpp file. I have added more skeleton code that is required to get to a stage when you have access to the image data. It includes some standard andoird NDK library calls:
<ul>
	<li><em>AndroidBitmap_getInfo</em> - used to get bitmap details like width, height, stride, format.</li>
	<li><em>AndroidBitmap_lockPixels</em> - used to get a pointer to the memory location of image data. Once a lockPixels is called, it has to be followed by a unlockPixels at some point later in the code. Probably creates a copy of original bitmap data which the jvm needs to free up when we are done using it.</li>
	<li><em>GetPrimitiveArrayCritical</em> - As the name suggets, this is some kind of performance critical call. Hence, we should take care of the code that runs between a Get and Release calls runs as fast as possible and doesn't stall execution. As per <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html">Oracle's java documenatation</a>, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via GetPrimitiveArrayCritical. So, just be careful when you use this function.</li>
	<li><em>ReleasePrimitiveArrayCritical</em> - used to release the memory space requested by previous GetPrimitiveArrayCritical. call.</li>
	<li><em>AndroidBitmap_unlockPixels</em> - used to release memory space used by a previous lockPixels call.</li>
</ul>
There are couple of other functions that are not related to JNI.
<ul>
	<li><em>throwJavaExceptio</em> - convenience function used to throw java exceptions from within jni routines.</li>
	<li><em>blur_helper</em> - helper function that converts nv21 format to rgba8888 and does blur operation on the converted data.</li>
</ul>
Click processor.cpp to see the full source code for function implementations. A navie implementation of gaussian blur for function <em>gblur</em> can be done very easily using a for loop.

I will cover the function <em>convertNV21toRGBA8888</em> in a future post. Will try to do two versions
<ul>
	<li>pure c method</li>
	<li>opencl kernel for Snapdragon mobile device</li>
</ul>
<h2>Build (for Linux)</h2>
blah blah blah, i can't use raw code!. Lets build it. Android-ndk provides a very useful tool ndk-build. We need to setup some stuff to run the build command <em>ndk-build</em>.
<ol>
	<li>Do <em>mkdir -p ~/jni_droid_test</em> OR Go to root folder of your android application</li>
	<li>Ensure android-ndk installed and environment variable <em>ANDROID_NDK</em> is pointing to ndk installation root</li>
	<li>Ensure environment variable <em>PATH</em> has the path <em>$ANDROID_NDK</em> appened to it</li>
	<li>Do <em>mkdir -p ~/jni_droid_test/jni</em></li>
	<li>Do <em>touch Android.mk and Application.mk</em> and prepare the content of the files as directed below</li>
	<li>Do <em>ndk-build</em> from <em>~/jni_droid_test</em></li>
</ol>
<h3>Android.mk</h3>
<code>
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNIProcessor
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := processor.cpp
LOCAL_CPPFLAGS := -fexceptions
LOCAL_LDLIBS := -ljnigraphics -llog
include $(BUILD_SHARED_LIBRARY)
</code>
<em>LOCAL_MODULE := JNIProcessor</em> sets the name of the shared library we are going to build. <em>LOCAL_ARM_MODE := arm</em> declares that library should be built for 32-bit ARM architecture instead of the 16-bit default. <em>LOCAL_SRC_FILES</em> variables should point to all the source files we want to compile, in our case processor.cpp. <em>LOCAL_CPPFLAGS</em> declares that we would be using c++ exceptions in our code. The flags <em>-ljnigraphics</em>, <em>--llog</em> are used for accessing bitmap, print functions respectively. Finally, the line <em>include $(BUILD_SHARED_LIBRARY)</em> that says we want a shared library. In case you want a static version, do the following <em>include $(BUILD_STATIC_LIBRARY)</em>
<h3>Application.mk</h3>
<code>
APP_OPTIM := release
APP_STL := gnustl_static
APP_PLATFORM:= android-14
</code>

<em>APP_STL</em> is used to state that the library we are going to build will require static version of GNU STL. <em>APP_PLATFORM</em> should be your target-platorm. <em>APP_OPTIM</em> declares that this is a release version of the library. Should you need a debug version, just do <em>APP_OPTIM := debug</em>.
<h2>Use the shared library</h2>
Now, all you need to do to use the function would be load the library when java class is loaded by JVM and declare the gaussianBlur function as member of the corresponding class. For example, say we have a java class shown as below
<code>
package com.example;
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback {
static {
System.loadLibrary("JNIProcessor");
}
private void gaussianBlur(Bitmap out, byte[] in, int width, int height);
private Bitmap mTexture;
private int width, height;
////TODO: constructors (setup configuration of mTexture like width and height)
////TODO: Code for surfaceCreated(), surfaceChanged(), surfaceDestroyed()
public void onPreviewFrame(byte[] data, Camera camera) {
gaussianBlur(mTexture,data,width,height);
invalidate();
}
////TODO: Code onDraw() method that can draw the processed bitmap on to canvas
}
</code>