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 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 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