CameraITS: Add stats image format.

Bug: 23980354
Change-Id: I8414093d77ab2be9f335bde85ec06ab86df62fd9
diff --git a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
new file mode 100644
index 0000000..16dff85
--- /dev/null
+++ b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ITS-StatsImage-JNI"
+// #define LOG_NDEBUG 0
+#include <android/log.h>
+#include <utils/Log.h>
+
+#include <jni.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <inttypes.h>
+#include <string.h>
+
+jfloatArray com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv* env, jobject thiz,
+        jbyteArray img, jint width, jint height, jint gridWidth, jint gridHeight)
+{
+    int bufSize = (int)(env->GetArrayLength(img));
+    unsigned char *buf = (unsigned char*)env->GetByteArrayElements(img, /*is_copy*/NULL);
+
+    // Size of the raw image.
+    const int w = width;
+    const int h = height;
+    // Size of each grid cell.
+    const int gw = gridWidth;
+    const int gh = gridHeight;
+    // Number of grid cells (rounding down to full cells only at right+bottom edges).
+    const int ngx = w / gw;
+    const int ngy = h / gh;
+
+    float *mean = new float[ngy*ngx*4];
+    float *var = new float[ngy*ngx*4];
+    for (int gy = 0; gy < ngy; gy++) {
+        for (int gx = 0; gx < ngx; gx++) {
+            float sum[4] = {0};
+            float sumSq[4] = {0};
+            int count[4] = {0};
+            for (int y = gy*gh; y < (gy+1)*gh; y++) {
+                int chnOffset = (y & 0x1) * 2;
+                unsigned char *pbuf = buf + 2*y*w + 2*gx*gw;
+                for (int x = gx*gw; x < (gx+1)*gw; x++) {
+                    // input is RAW16
+                    int byte0 = *pbuf++;
+                    int byte1 = *pbuf++;
+                    int pixelValue = (byte1 << 8) | byte0;
+                    int ch = chnOffset + (x & 1);
+                    sum[ch] += pixelValue;
+                    sumSq[ch] += pixelValue * pixelValue;
+                    count[ch] += 1;
+                }
+            }
+            for (int ch = 0; ch < 4; ch++) {
+                float m = (float)sum[ch] / count[ch];
+                float mSq = (float)sumSq[ch] / count[ch];
+                mean[gy*ngx*4 + gx*4 + ch] = m;
+                var[gy*ngx*4 + gx*4 + ch] = mSq - m*m;
+            }
+        }
+    }
+
+    jfloatArray ret = env->NewFloatArray(ngx*ngy*4*2);
+    env->SetFloatArrayRegion(ret, 0, ngx*ngy*4, (float*)mean);
+    env->SetFloatArrayRegion(ret, ngx*ngy*4, ngx*ngy*4, (float*)var);
+    delete [] mean;
+    delete [] var;
+    return ret;
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "computeStatsImage", "([BIIII)[F",
+            (void *) com_android_cts_verifier_camera_its_computeStatsImage  },
+};
+
+int register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("com/android/cts/verifier/camera/its/StatsImage");
+
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}