1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "ITS-StatsImage-JNI"
18 // #define LOG_NDEBUG 0
19 #include <android/log.h>
20 #include <utils/Log.h>
21 
22 #include <jni.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <inttypes.h>
27 #include <string.h>
28 
com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv * env,jobject thiz,jbyteArray img,jint width,jint height,jint gridWidth,jint gridHeight)29 jfloatArray com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv* env, jobject thiz,
30         jbyteArray img, jint width, jint height, jint gridWidth, jint gridHeight)
31 {
32     int bufSize = (int)(env->GetArrayLength(img));
33     unsigned char *buf = (unsigned char*)env->GetByteArrayElements(img, /*is_copy*/NULL);
34 
35     // Size of the raw image.
36     const int w = width;
37     const int h = height;
38     // Size of each grid cell.
39     const int gw = gridWidth;
40     const int gh = gridHeight;
41     // Number of grid cells (rounding down to full cells only at right+bottom edges).
42     const int ngx = w / gw;
43     const int ngy = h / gh;
44 
45     float *mean = new float[ngy*ngx*4];
46     float *var = new float[ngy*ngx*4];
47     for (int gy = 0; gy < ngy; gy++) {
48         for (int gx = 0; gx < ngx; gx++) {
49             float sum[4] = {0};
50             float sumSq[4] = {0};
51             int count[4] = {0};
52             for (int y = gy*gh; y < (gy+1)*gh; y++) {
53                 int chnOffset = (y & 0x1) * 2;
54                 unsigned char *pbuf = buf + 2*y*w + 2*gx*gw;
55                 for (int x = gx*gw; x < (gx+1)*gw; x++) {
56                     // input is RAW16
57                     int byte0 = *pbuf++;
58                     int byte1 = *pbuf++;
59                     int pixelValue = (byte1 << 8) | byte0;
60                     int ch = chnOffset + (x & 1);
61                     sum[ch] += pixelValue;
62                     sumSq[ch] += pixelValue * pixelValue;
63                     count[ch] += 1;
64                 }
65             }
66             for (int ch = 0; ch < 4; ch++) {
67                 float m = (float)sum[ch] / count[ch];
68                 float mSq = (float)sumSq[ch] / count[ch];
69                 mean[gy*ngx*4 + gx*4 + ch] = m;
70                 var[gy*ngx*4 + gx*4 + ch] = mSq - m*m;
71             }
72         }
73     }
74 
75     jfloatArray ret = env->NewFloatArray(ngx*ngy*4*2);
76     env->SetFloatArrayRegion(ret, 0, ngx*ngy*4, (float*)mean);
77     env->SetFloatArrayRegion(ret, ngx*ngy*4, ngx*ngy*4, (float*)var);
78     delete [] mean;
79     delete [] var;
80     return ret;
81 }
82 
83 static JNINativeMethod gMethods[] = {
84     {  "computeStatsImage", "([BIIII)[F",
85             (void *) com_android_cts_verifier_camera_its_computeStatsImage  },
86 };
87 
register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv * env)88 int register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv* env)
89 {
90     jclass clazz = env->FindClass("com/android/cts/verifier/camera/its/StatsImage");
91 
92     return env->RegisterNatives(clazz, gMethods,
93             sizeof(gMethods) / sizeof(JNINativeMethod));
94 }
95