blob: b7c96e2630a5bdce88aaf4512bd61184fff795db [file] [log] [blame]
Timothy Knight67d8ec92015-08-31 13:14:46 -07001/*
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
29jfloatArray com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv* env, jobject thiz,
Timothy Knightff3032b2017-02-01 15:10:51 -080030 // The full pixel array read off the sensor.
31 jbyteArray img,
32 jint width, jint height,
33 // The active array crop region.
34 jint aax, jint aay, jint aaw, jint aah,
35 // The size of each grid cell to use when computing stats from the active array.
36 jint gridWidth, jint gridHeight)
Timothy Knight67d8ec92015-08-31 13:14:46 -070037{
38 int bufSize = (int)(env->GetArrayLength(img));
39 unsigned char *buf = (unsigned char*)env->GetByteArrayElements(img, /*is_copy*/NULL);
40
Timothy Knightff3032b2017-02-01 15:10:51 -080041 // Size of the full raw image pixel array.
42 const int paw = width;
43 const int pah = height;
Timothy Knight67d8ec92015-08-31 13:14:46 -070044 // Size of each grid cell.
45 const int gw = gridWidth;
46 const int gh = gridHeight;
47 // Number of grid cells (rounding down to full cells only at right+bottom edges).
Timothy Knightff3032b2017-02-01 15:10:51 -080048 const int ngx = aaw / gw;
49 const int ngy = aah / gh;
Timothy Knight67d8ec92015-08-31 13:14:46 -070050
51 float *mean = new float[ngy*ngx*4];
52 float *var = new float[ngy*ngx*4];
Timothy Knightff3032b2017-02-01 15:10:51 -080053 // For each grid cell ...
Timothy Knight67d8ec92015-08-31 13:14:46 -070054 for (int gy = 0; gy < ngy; gy++) {
55 for (int gx = 0; gx < ngx; gx++) {
56 float sum[4] = {0};
57 float sumSq[4] = {0};
58 int count[4] = {0};
Timothy Knightff3032b2017-02-01 15:10:51 -080059 // Iterate over pixels in the grid cell
60 for (int y = aay+gy*gh; y < aay+(gy+1)*gh; y++) {
Timothy Knight67d8ec92015-08-31 13:14:46 -070061 int chnOffset = (y & 0x1) * 2;
Timothy Knightff3032b2017-02-01 15:10:51 -080062 unsigned char *pbuf = buf + 2*y*paw + 2*gx*gw + 2*aax;
63 for (int x = aax+gx*gw; x < aax+(gx+1)*gw; x++) {
Timothy Knight67d8ec92015-08-31 13:14:46 -070064 // input is RAW16
65 int byte0 = *pbuf++;
66 int byte1 = *pbuf++;
67 int pixelValue = (byte1 << 8) | byte0;
68 int ch = chnOffset + (x & 1);
69 sum[ch] += pixelValue;
70 sumSq[ch] += pixelValue * pixelValue;
71 count[ch] += 1;
72 }
73 }
74 for (int ch = 0; ch < 4; ch++) {
75 float m = (float)sum[ch] / count[ch];
76 float mSq = (float)sumSq[ch] / count[ch];
77 mean[gy*ngx*4 + gx*4 + ch] = m;
78 var[gy*ngx*4 + gx*4 + ch] = mSq - m*m;
79 }
80 }
81 }
82
83 jfloatArray ret = env->NewFloatArray(ngx*ngy*4*2);
84 env->SetFloatArrayRegion(ret, 0, ngx*ngy*4, (float*)mean);
85 env->SetFloatArrayRegion(ret, ngx*ngy*4, ngx*ngy*4, (float*)var);
86 delete [] mean;
87 delete [] var;
88 return ret;
89}
90
91static JNINativeMethod gMethods[] = {
Timothy Knightff3032b2017-02-01 15:10:51 -080092 { "computeStatsImage", "([BIIIIIIII)[F",
Timothy Knight67d8ec92015-08-31 13:14:46 -070093 (void *) com_android_cts_verifier_camera_its_computeStatsImage },
94};
95
96int register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv* env)
97{
98 jclass clazz = env->FindClass("com/android/cts/verifier/camera/its/StatsImage");
99
100 return env->RegisterNatives(clazz, gMethods,
101 sizeof(gMethods) / sizeof(JNINativeMethod));
102}