<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>
[code]</code>

<span style="font-family: monospace; line-height: 1.5em;">JNIEXPORT void JNICALL Java_com_example_CameraPreview_gaussianBlur(</span>

<span style="font-family: monospace;">JNIEnv *env,</span><br style="font-family: monospace;" /><span style="font-family: monospace;">jclass clazz,</span><br style="font-family: monospace;" /><span style="font-family: monospace;">jobject outBmp,</span><br style="font-family: monospace;" /><span style="font-family: monospace;">jByteArray inData,</span><br style="font-family: monospace;" /><span style="font-family: monospace;">jint width,</span><br style="font-family: monospace;" /><span style="font-family: monospace;">jint height)</span><br style="font-family: monospace;" /><span style="font-family: monospace;">{</span><br style="font-family: monospace;" /><span style="font-family: monospace;">// TODO: process the input and write the output</span>

<code><span style="line-height: 1.5em;">}</span></code>

<code>[/code]
</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 <a href="https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.h">processor.h</a> 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 <a href="https://github.com/9prady9/skeletons/blob/master/jni_droid_test/jni/processor.cpp">processor.cpp</a> 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 <em>gaussianBlur</em> function as member of the corresponding class. For example, we can use the jni routines we created using a java class such as shown <a href="https://github.com/9prady9/skeletons/blob/master/jni_droid_test/src/com/example/CameraPreview.java">here</a>

The entire skeleton code is avaiable on github at <a href="https://github.com/9prady9/skeletons/tree/master/jni_droid_test">template</a>