Updated Cts Camera Verifier properties.
Change-Id: Ib1606ed9492e887a175cc13ef4a55ff4776c68a6
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 5dc71f5..7b8fa3d 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -5,9 +5,9 @@
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.
@@ -27,17 +27,25 @@
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.NFC" />
+ <uses-feature android:name="android.hardware.camera.front"
+ android:required="false" />
+ <uses-feature android:name="android.hardware.camera.autofocus"
+ android:required="false" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
-
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-feature android:name="android.hardware.usb.accessory" />
+ <uses-sdk android:minSdkVersion="10" />
+
<!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application android:label="@string/app_name"
+ <application android:label="@string/app_name"
android:icon="@drawable/icon"
- android:backupAgent="VerifierBackupAgent"
+ android:backupAgent="VerifierBackupAgent"
android:debuggable="true">
-
+
+ <uses-library android:name="com.android.future.usb.accessory" />
<meta-data android:name="com.google.android.backup.api_key"
android:value="AEdPqrEAAAAIbK6ldcOzoeRtQ1u1dFVJ1A7KetRhit-a1Xa82Q" />
@@ -63,13 +71,9 @@
android:resource="@xml/accessory_filter" />
</activity>
- <activity android:name=".ReportViewerActivity"
- android:configChanges="keyboardHidden|orientation"
- android:label="@string/report_viewer" />
-
- <provider android:name=".TestResultsProvider"
+ <provider android:name=".TestResultsProvider"
android:authorities="com.android.cts.verifier.testresultsprovider" />
-
+
<activity android:name=".admin.PolicySerializationTestActivity"
android:label="@string/da_policy_serialization_test"
android:configChanges="keyboardHidden|orientation">
@@ -116,7 +120,7 @@
<meta-data android:name="test_category" android:value="@string/test_category_networking" />
<meta-data android:name="test_required_features" android:value="android.hardware.bluetooth" />
</activity>
-
+
<activity android:name=".bluetooth.BluetoothToggleActivity"
android:label="@string/bt_toggle_bluetooth"
android:configChanges="keyboardHidden|orientation">
@@ -138,7 +142,7 @@
<meta-data android:name="test_category" android:value="@string/bt_device_communication" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
</activity>
-
+
<activity android:name=".bluetooth.InsecureServerActivity"
android:label="@string/bt_insecure_server"
android:configChanges="keyboardHidden|orientation">
@@ -160,7 +164,7 @@
<meta-data android:name="test_category" android:value="@string/bt_device_communication" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
</activity>
-
+
<activity android:name=".bluetooth.InsecureClientActivity"
android:label="@string/bt_insecure_client"
android:configChanges="keyboardHidden|orientation">
@@ -182,7 +186,7 @@
<meta-data android:name="test_category" android:value="@string/bt_device_communication" />
<meta-data android:name="test_parent" android:value="com.android.cts.verifier.bluetooth.BluetoothTestActivity" />
</activity>
-
+
<activity android:name=".bluetooth.ConnectionAccessClientActivity"
android:label="@string/bt_connection_access_client"
android:configChanges="keyboardHidden|orientation">
@@ -198,7 +202,7 @@
android:label="@string/bt_device_picker"
android:configChanges="keyboardHidden|orientation" />
- <activity android:name=".suid.SuidFilesActivity"
+ <activity android:name=".suid.SuidFilesActivity"
android:label="@string/suid_files"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
@@ -293,12 +297,19 @@
<service android:name=".audioquality.ExperimentService" />
<activity android:name=".camera.analyzer.CameraAnalyzerActivity"
- android:label="@string/camera_analyzer">
+ android:label="@string/camera_analyzer"
+ android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_camera" />
+
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+ </intent-filter>
+ <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
+ android:resource="@xml/accessory_filter_adk" />
</activity>
<activity android:name=".usb.UsbAccessoryTestActivity"
@@ -314,4 +325,4 @@
</application>
-</manifest>
+</manifest>
diff --git a/apps/CtsVerifier/include/colorchecker/colorchecker.h b/apps/CtsVerifier/include/colorchecker/colorchecker.h
deleted file mode 100644
index 5409b04..0000000
--- a/apps/CtsVerifier/include/colorchecker/colorchecker.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef COLORCHECKER_H
-#define COLORCHECKER_H
-
-/** Detects the 6x4 Xrite ColorChecker Classic pattern in the input image,
- * and calculates the average color value per patch.
- *
- * All squares in the colorchecker pattern have to be fully visible,
- * and the whole pattern should fill at least 1/3 of the image
- * width. The pattern cannot be facing away from the camera at a very
- * large angle (>45 degrees). If multiple 6x4 grids can be found, the
- * one that is most front-facing will be returned.
- *
- * The average color is returned as a floating-point value per
- * channel, linearized by an inverse gamma transform and normalized
- * to 0-1 (255 = 1). The linearization is only approximate.
- *
- * @param inputImage Source image to detect the pattern in. Assumed
- * to be a 3-channel interleaved image. Row-major
- * @param width Width of input image
- * @param height Height of input image
- * @param patchColors Output 6x4 3-channel image of average patch
- * values. Allocated by caller. Pass in NULL if
- * the average values aren't needed.
- * @param outputImage Resized inputImage with overlaid grid detection
- * diagnostics. Image width is approximately 160
- * pixels. Pass in NULL if the diagnostic image
- * isn't needed.
- * @param outputWidth Actual width of outputImage.
- * @param outputHeight Actual height of outputImage.
- *
- * @return true if a grid was found, false otherwise. If false, the
- * input variables are unchanged.
- */
-bool findColorChecker(const unsigned char *image,
- int width,
- int rowSpan,
- int height,
- float *patchColors,
- unsigned char **outputImage,
- int *outputWidth,
- int *outputHeight);
-
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
index ccc0998..59ca11a 100644
--- a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
+++ b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
@@ -16,12 +16,18 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
+include external/stlport/libstlport.mk
LOCAL_MODULE := libcameraanalyzer
LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := com_android_cts_verifier_camera_analyzer_ColorChecker.cpp
+LOCAL_SRC_FILES := #com_android_cts_verifier_camera_analyzer_CameraTests.cpp \
+ com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp \
+ com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.cpp \
+ com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.cpp \
+ com_android_cts_verifier_camera_analyzer_AutoLockTest.cpp \
+ com_android_cts_verifier_camera_analyzer_MeteringTest.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include/colorchecker $(JNI_H_INCLUDE)
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.cpp
deleted file mode 100644
index 4d247ab..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.cpp
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include "com_android_cts_verifier_camera_analyzer_ColorChecker.h"
-
-#include "utils/Log.h"
-#include "android/bitmap.h"
-#include "colorchecker.h"
-
-jboolean Java_com_android_cts_verifier_camera_analyzer_ColorChecker_findNative(
- JNIEnv* env,
- jobject thiz,
- jobject inputBitmap) {
-
- // Verify that we can handle the input bitmap
- AndroidBitmapInfo inputInfo;
- AndroidBitmap_getInfo(env, inputBitmap, &inputInfo);
- if (inputInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
- inputInfo.format != ANDROID_BITMAP_FORMAT_RGB_565) {
- LOGE("Only RGBA_8888 and RGB_565 bitmaps are supported, was given type %d.", inputInfo.format);
- return JNI_FALSE;
- }
-
- // Get some references to the fields and class type of ColorChecker
- jclass thizCls = env->GetObjectClass(thiz);
- jfieldID patchId = env->GetFieldID(thizCls, "mPatchValues", "[F");
- jfieldID outputId = env->GetFieldID(thizCls, "mDebugOutput", "Landroid/graphics/Bitmap;");
- jfloatArray patchValues = (jfloatArray)env->GetObjectField(thiz, patchId);
-
- // Get raw inputs and outputs ready
-
- uint8_t *inputBuffer;
- int result = AndroidBitmap_lockPixels(
- env,
- inputBitmap,
- reinterpret_cast<void**>(&inputBuffer) );
-
- if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to lock input bitmap");
- return JNI_FALSE;
- }
-
- float *patchRawArray = env->GetFloatArrayElements(patchValues,
- NULL);
-
- uint8_t *outputImage = NULL;
- int outputWidth, outputHeight;
-
- // Find the color checker
- bool success;
- uint8_t *inputBufferRGBA = NULL;
- int inputStride;
- bool freeInputRGBA = false;
- switch (inputInfo.format) {
- case ANDROID_BITMAP_FORMAT_RGB_565: {
- // First convert to RGBA_8888
- inputBufferRGBA = new uint8_t[inputInfo.width *
- inputInfo.height *
- 4];
- inputStride = inputInfo.width * 4;
- uint8_t *outP = inputBufferRGBA;
- for (int y = 0; y < inputInfo.height; y++ ) {
- uint16_t *inP = (uint16_t*)(&inputBuffer[y * inputInfo.stride]);
- for (int x = 0; x < inputInfo.width; x++) {
- *(outP++) = ( ((*inP) >> 0) & 0x001F) << 3;
- *(outP++) = ( ((*inP) >> 5) & 0x003F) << 2;
- *(outP++) = ( ((*inP) >> 11) & 0x001F) << 3;
- outP++;
- inP++;
- }
- }
- freeInputRGBA = true;
- break;
- }
- case ANDROID_BITMAP_FORMAT_RGBA_8888:
- // Already in RGBA
- inputBufferRGBA = inputBuffer;
- inputStride = inputInfo.stride;
- break;
- }
-
- success = findColorChecker(inputBufferRGBA,
- inputInfo.width,
- inputStride,
- inputInfo.height,
- patchRawArray,
- &outputImage,
- &outputWidth,
- &outputHeight);
-
- // Clean up raw inputs/outputs
- env->ReleaseFloatArrayElements(patchValues, patchRawArray, 0);
- result = AndroidBitmap_unlockPixels(env, inputBitmap);
- if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to unlock input bitmap");
- return JNI_FALSE;
- }
-
- if (freeInputRGBA) {
- delete inputBufferRGBA;
- }
-
- // Create debug bitmap from output image data
- if (outputImage != NULL) {
- // Get method handles, create inputs to createBitmap
- jclass bitmapClass =
- env->FindClass("android/graphics/Bitmap");
- jclass bitmapConfigClass =
- env->FindClass("android/graphics/Bitmap$Config");
-
- jmethodID createBitmap = env->GetStaticMethodID(
- bitmapClass, "createBitmap",
- "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
-
- jmethodID getConfig = env->GetStaticMethodID(
- bitmapConfigClass, "valueOf",
- "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
-
- // Create bitmap config and bitmap
- jstring bitmapConfigValue = env->NewStringUTF("ARGB_8888");
- jobject rgbaConfig = env->CallStaticObjectMethod(bitmapConfigClass,
- getConfig,
- bitmapConfigValue);
- jobject outputBitmap = env->CallStaticObjectMethod(bitmapClass,
- createBitmap,
- outputWidth,
- outputHeight,
- rgbaConfig);
- // Copy output image into it
- uint8_t *outputBuffer;
- int result = AndroidBitmap_lockPixels(
- env,
- outputBitmap,
- reinterpret_cast<void**>(&outputBuffer) );
-
- if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to lock output bitmap");
- return JNI_FALSE;
- }
-
- memcpy(outputBuffer, outputImage, outputWidth * outputHeight * 4);
-
- result = AndroidBitmap_unlockPixels(env, outputBitmap);
- if (result != ANDROID_BITMAP_RESUT_SUCCESS) {
- LOGE("Unable to unlock output bitmap");
- return JNI_FALSE;
- }
-
- // Write new Bitmap reference into mDebugOutput class member
- env->SetObjectField(thiz, outputId, outputBitmap);
-
- delete outputImage;
- }
- if (!success) return JNI_FALSE;
-
- return JNI_TRUE;
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.h
deleted file mode 100644
index a9b4487..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorChecker.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#ifndef JNI_CAMERAANALYZER_COLORCHECKER_H
-#define JNI_CAMERAANALYZER_COLORCHECKER_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jboolean JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorChecker_findNative(
- JNIEnv *env,
- jobject thiz,
- jobject inputBitmap);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* JNI_CAMERAANALYZER_COLORCHECKER_H */
diff --git a/apps/CtsVerifier/lib/colorchecker/Android.mk b/apps/CtsVerifier/lib/colorchecker/Android.mk
index 97f0089..8d0a741 100644
--- a/apps/CtsVerifier/lib/colorchecker/Android.mk
+++ b/apps/CtsVerifier/lib/colorchecker/Android.mk
@@ -24,7 +24,16 @@
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libcolorchecker
-LOCAL_SRC_FILES += colorchecker.cpp
+LOCAL_SRC_FILES += #testingimage.cpp \
+ vec3.cpp \
+ vec2.cpp \
+ imagetesthandler.cpp \
+ whitebalancetest.cpp \
+ colorcheckertest.cpp \
+ exposurecompensationtest.cpp \
+ autolocktest.cpp \
+ meteringtest.cpp
+
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include/colorchecker
LOCAL_SHARED_LIBRARIES := libstlport \
libcutils \
diff --git a/apps/CtsVerifier/lib/colorchecker/colorchecker.cpp b/apps/CtsVerifier/lib/colorchecker/colorchecker.cpp
deleted file mode 100644
index a7431f6..0000000
--- a/apps/CtsVerifier/lib/colorchecker/colorchecker.cpp
+++ /dev/null
@@ -1,714 +0,0 @@
-/*
- * Copyright (C) 2011 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_NDEBUG 0
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include "colorchecker.h"
-#include "grouping.h"
-#include <string>
-#include <vector>
-#include <set>
-#include <algorithm>
-#include <cmath>
-
-const int totalChannels = 4; // Input image channel count
-const int colorChannels = 3; // Input image color channel count
-const float gammaCorrection = 2.2; // Assumed gamma curve on input
-const int thresholdSq = 675; // Threshold on pixel difference to be considered
- // part of the same patch
-
-class PixelId {
- public:
- int id;
- const unsigned char *p;
-
- PixelId(): id(0), p(NULL) {}
-
- bool operator!=(const PixelId &other) const {
- int dR = ((int)p[0] - other.p[0]) * ((int)p[0] - other.p[0]);
- int dG = ((int)p[1] - other.p[1]) * ((int)p[1] - other.p[1]);
- int dB = ((int)p[2] - other.p[2]) * ((int)p[2] - other.p[2]);
- int distSq = dR + dG + dB;
- if (distSq > thresholdSq) return true;
- else return false;
- }
-};
-
-class ImageField: public Field<PixelId> {
- public:
- ImageField(int width, int height, const unsigned char *data):
- mWidth(width), mHeight(height), pData(data) {
- }
-
- PixelId operator() (int y, int x) const {
- PixelId pId;
- pId.p = pData + (y * mWidth + x ) * totalChannels;
- if (mask.size() != 0) {
- pId.id = mask[y][x];
- }
- return pId;
- }
-
- int getWidth() const { return mWidth; }
- int getHeight() const { return mHeight; }
- private:
- int mWidth;
- int mHeight;
- const unsigned char *pData;
-};
-
-class PixelGroup {
- public:
- PixelGroup(int id, const ImageField *src):
- mId(id),
- mMinX(1e7),
- mMinY(1e7),
- mMaxX(0),
- mMaxY(0),
- mArea(0),
- mSrc(src),
- mRNeighbor(NULL),
- mDNeighbor(NULL),
- mLNeighbor(NULL),
- mUNeighbor(NULL) {
- mSum[0] = 0;
- mSum[1] = 0;
- mSum[2] = 0;
- }
-
- struct IdCompare {
- bool operator() (const PixelGroup* l, const PixelGroup* r) const {
- return l->getId() < r->getId();
- }
- };
-
- void growGroup(int x, int y) {
- if (x < mMinX) mMinX = x;
- if (x > mMaxX) mMaxX = x;
- if (y < mMinY) mMinY = y;
- if (y > mMaxY) mMaxY = y;
- mArea++;
- const unsigned char *p = (*mSrc)(y,x).p;
- mSum[0] += p[0];
- mSum[1] += p[1];
- mSum[2] += p[2];
- }
-
- int getId() const {
- return mId;
- }
-
- int getArea() const {
- return mArea;
- }
-
- int getBoundArea() const {
- return (mMaxX - mMinX) * (mMaxY - mMinY);
- }
-
- float getApproxAspectRatio() const {
- return ((float)(mMaxY - mMinY)) / (mMaxX - mMinX);
- }
-
- void getApproxCenter(int *x, int *y) const {
- *x = (mMaxX + mMinX)/2;
- *y = (mMaxY + mMinY)/2;
- }
-
- void getBoundingBox(int *x1, int *y1, int *x2, int *y2) const {
- *x1 = mMinX;
- *x2 = mMaxX;
- *y1 = mMinY;
- *y2 = mMaxY;
- }
-
- void getAvgValue(unsigned char *p) const {
- p[0] = mSum[0] / mArea;
- p[1] = mSum[1] / mArea;
- p[2] = mSum[2] / mArea;
- }
-
- bool operator<(const PixelGroup &other) const {
- return mArea < other.getArea();
- }
-
- typedef std::set<PixelGroup*, PixelGroup::IdCompare> IdSet;
- typedef std::set<PixelGroup*, PixelGroup::IdCompare>::iterator IdSetIter;
-
- void findNeighbors(IdSet &candidates) {
- int cX, cY;
- getApproxCenter(&cX, &cY);
- int rDistSq = 1e9; // Larger than any reasonable image distance
- int dDistSq = rDistSq;
-
- for (IdSetIter neighbor = candidates.begin();
- neighbor != candidates.end();
- neighbor++) {
- if (*neighbor == this) continue;
- int nX, nY;
- (*neighbor)->getApproxCenter(&nX, &nY);
- // 'right' means slope between (-1/3, 1/3), positive X change
- if ( (nX - cX) > 0 ) {
- float slope = ((float)(nY - cY)) / (nX - cX);
- if (slope > -0.33 && slope < 0.33) {
- int distSq = (nX - cX) * (nX - cX) + (nY - cY) * (nY - cY);
- if (distSq < rDistSq) {
- setRNeighbor(*neighbor);
- rDistSq = distSq;
- }
- }
- }
- // 'down' means inv slope between (-1/3, 1/3), positive Y change
- if ( (nY - cY) > 0) {
- float invSlope = ((float)(nX - cX)) / (nY - cY);
- if (invSlope > -0.33 && invSlope < 0.33) {
- int distSq = (nX - cX) * (nX - cX) + (nY - cY) * (nY - cY);
- if (distSq < dDistSq) {
- setDNeighbor(*neighbor);
- dDistSq = distSq;
- }
- }
- }
- }
- // Do reverse links if possible
- if (getRNeighbor() != NULL) {
- getRNeighbor()->setLNeighbor(this);
- }
- if (getDNeighbor() != NULL) {
- getDNeighbor()->setUNeighbor(this);
- }
-
- }
-
- void setRNeighbor(PixelGroup *rNeighbor) {
- mRNeighbor = rNeighbor;
- }
-
- PixelGroup* getRNeighbor(int distance = 1) {
- PixelGroup *current = this;
- for (int i=0; i < distance; i++) {
- if (current != NULL) {
- current = current->mRNeighbor;
- } else break;
- }
- return current;
- }
-
- void setDNeighbor(PixelGroup *dNeighbor) {
- mDNeighbor = dNeighbor;
- }
-
- PixelGroup* getDNeighbor(int distance = 1) {
- PixelGroup *current = this;
- for (int i=0; i < distance; i++) {
- if (current != NULL) {
- current = current->mDNeighbor;
- } else break;
- }
- return current;
- }
-
- void setLNeighbor(PixelGroup *lNeighbor) {
- mLNeighbor = lNeighbor;
- }
-
- PixelGroup* getLNeighbor(int distance = 1) {
- PixelGroup *current = this;
- for (int i=0; i < distance; i++) {
- if (current != NULL) {
- current = current->mLNeighbor;
- } else break;
- }
- return current;
- }
-
- void setUNeighbor(PixelGroup *uNeighbor) {
- mUNeighbor = uNeighbor;
- }
-
- PixelGroup* getUNeighbor(int distance = 1) {
- PixelGroup *current = this;
- for (int i=0; i < distance; i++) {
- if (current != NULL) {
- current = current->mUNeighbor;
- } else break;
- }
- return current;
- }
-
- float distanceSqTo(const PixelGroup* other) {
- int mX, mY;
- getApproxCenter(&mX, &mY);
- int oX, oY;
- other->getApproxCenter(&oX, &oY);
- int dx = (oX - mX);
- int dy = (oY - mY);
- return dx * dx + dy * dy;
- }
-
- float distanceTo(const PixelGroup* other) {
- return sqrt( distanceSqTo(other) );
- }
-
- private:
- int mId;
- int mMinX, mMinY;
- int mMaxX, mMaxY;
- int mArea;
- int mSum[3];
- const ImageField *mSrc;
-
- PixelGroup *mRNeighbor;
- PixelGroup *mDNeighbor;
- PixelGroup *mLNeighbor;
- PixelGroup *mUNeighbor;
-};
-
-/* Scales input down by factor of outScale to output. Assumes input size is
- * exactly output size times scale */
-void downsample(const unsigned char *input,
- unsigned char *output,
- int rowSpan,
- int outWidth,
- int outHeight,
- int outScale) {
- for (int oY = 0, iY = 0; oY < outHeight; oY++, iY += outScale) {
- for (int oX = 0, iX = 0; oX < outWidth; oX++, iX += outScale) {
- short out[3] = {0,0,0};
- const unsigned char *in = input + iY * rowSpan + iX * totalChannels;
- for (int j = 0; j < outScale; j++) {
- for (int k = 0; k < outScale; k++) {
- for (int i = 0; i < colorChannels; i++) {
- out[i] += in[i];
- }
- in += totalChannels;
- }
- in += rowSpan - outScale * totalChannels;
- }
- output[0] = out[0] / (outScale * outScale);
- output[1] = out[1] / (outScale * outScale);
- output[2] = out[2] / (outScale * outScale);
- output += totalChannels;
- }
- }
-}
-
-void drawLine(unsigned char *image,
- int rowSpan,
- int x0, int y0,
- int x1, int y1,
- int r, int g, int b) {
- if ((x0 == x1) && (y0 == y1)) {
- unsigned char *p = &image[(y0 * rowSpan + x0) * totalChannels];
- if (r != -1) p[0] = r;
- if (g != -1) p[1] = g;
- if (b != -1) p[2] = b;
- return;
- }
- if ( std::abs(x1-x0) > std::abs(y1-y0) ) {
- if (x0 > x1) {
- std::swap(x0, x1);
- std::swap(y0, y1);
- }
- float slope = (float)(y1 - y0) / (x1 - x0);
- for (int x = x0; x <= x1; x++) {
- int y = y0 + slope * (x - x0);
- unsigned char *p = &image[(y * rowSpan + x) * totalChannels];
- if (r != -1) p[0] = r;
- if (g != -1) p[1] = g;
- if (b != -1) p[2] = b;
- }
- } else {
- if (y0 > y1) {
- std::swap(x0, x1);
- std::swap(y0, y1);
- }
- float invSlope = (float)(x1 - x0) / (y1 - y0);
- for (int y = y0; y <= y1; y++) {
- int x = x0 + invSlope * (y - y0);
- unsigned char *p = &image[(y*rowSpan + x) * totalChannels];
- if (r != -1) p[0] = r;
- if (g != -1) p[1] = g;
- if (b != -1) p[2] = b;
- }
- }
-
-}
-bool findColorChecker(const unsigned char *image,
- int width,
- int rowSpan,
- int height,
- float *patchColors,
- unsigned char **outputImage,
- int *outputWidth,
- int *outputHeight) {
- int64_t startTime = systemTime();
-
- const int outTargetWidth = 160;
- const int outScale = width / outTargetWidth;
- const int outWidth = width / outScale;
- const int outHeight = height / outScale;
- ALOGV("Debug image dimensions: %d, %d", outWidth, outHeight);
-
- unsigned char *output = new unsigned char[outWidth * outHeight * totalChannels];
-
- unsigned char *outP;
- unsigned char *inP;
-
- // First step, downsample for speed/noise reduction
- downsample(image, output, rowSpan, outWidth, outHeight, outScale);
-
- // Find connected components (groups)
- ImageField outField(outWidth, outHeight, output);
- Grouping(&outField);
-
- // Calculate component bounds and areas
- std::vector<PixelGroup> groups;
- groups.reserve(outField.id_no);
- for (int i = 0; i < outField.id_no; i++) {
- groups.push_back(PixelGroup(i + 1, &outField));
- }
-
- inP = output;
- for (int y = 0; y < outHeight; y++) {
- for (int x = 0; x < outWidth; x++) {
- groups[ outField(y, x).id - 1].growGroup(x, y);
- }
- }
-
- // Filter out groups that are too small, too large, or have too
- // non-square aspect ratio
- PixelGroup::IdSet candidateGroups;
-
- // Maximum/minimum width assuming pattern is fully visible and >
- // 1/3 the image in width
- const int maxPatchWidth = outWidth / 6;
- const int minPatchWidth = outWidth / 3 / 7;
- const int maxPatchArea = maxPatchWidth * maxPatchWidth;
- const int minPatchArea = minPatchWidth * minPatchWidth;
- // Assuming nearly front-on view of target, so aspect ratio should
- // be quite close to square
- const float maxAspectRatio = 5.f / 4.f;
- const float minAspectRatio = 4.f / 5.f;
- for (int i = 0; i < (int)groups.size(); i++) {
- float aspect = groups[i].getApproxAspectRatio();
- if (aspect < minAspectRatio || aspect > maxAspectRatio) continue;
- // Check both boundary box area, and actual pixel count - they
- // should both be within bounds for a roughly square patch.
- int boundArea = groups[i].getBoundArea();
- if (boundArea < minPatchArea || boundArea > maxPatchArea) continue;
- int area = groups[i].getArea();
- if (area < minPatchArea || area > maxPatchArea) continue;
- candidateGroups.insert(&groups[i]);
- }
-
- // Find neighbors for candidate groups. O(n^2), but not many
- // candidates to go through
- for (PixelGroup::IdSetIter group = candidateGroups.begin();
- group != candidateGroups.end();
- group++) {
- (*group)->findNeighbors(candidateGroups);
- }
-
- // Try to find a plausible 6x4 grid by taking each pixel group as
- // the candidate top-left corner and try to build a grid from
- // it. Assumes no missing patches.
- float bestError = -1;
- std::vector<int> bestGrid(6 * 4,0);
- for (PixelGroup::IdSetIter group = candidateGroups.begin();
- group != candidateGroups.end();
- group++) {
- int dex, dey; (*group)->getApproxCenter(&dex, &dey);
- std::vector<int> grid(6 * 4, 0);
- PixelGroup *tl = *group;
- PixelGroup *bl, *tr, *br;
-
- // Find the bottom-left and top-right corners
- if ( (bl = tl->getDNeighbor(3)) == NULL ||
- (tr = tl->getRNeighbor(5)) == NULL ) continue;
- ALOGV("Candidate at %d, %d", dex, dey);
- ALOGV(" Got BL and TR");
-
- // Find the bottom-right corner
- if ( tr->getDNeighbor(3) == NULL ) {
- ALOGV(" No BR from TR");
- continue;
- }
- br = tr->getDNeighbor(3);
- if ( br != bl->getRNeighbor(5) ) {
- ALOGV(" BR from TR and from BL don't agree");
- continue;
- }
- br->getApproxCenter(&dex, &dey);
- ALOGV(" Got BR corner at %d, %d", dex, dey);
-
- // Check that matching grid edge lengths are about the same
- float gridTopWidth = tl->distanceTo(tr);
- float gridBotWidth = bl->distanceTo(br);
-
- if (gridTopWidth / gridBotWidth < minAspectRatio ||
- gridTopWidth / gridBotWidth > maxAspectRatio) continue;
- ALOGV(" Got reasonable widths: %f %f", gridTopWidth, gridBotWidth);
-
- float gridLeftWidth = tl->distanceTo(bl);
- float gridRightWidth = tr->distanceTo(br);
-
- if (gridLeftWidth / gridRightWidth < minAspectRatio ||
- gridLeftWidth / gridRightWidth > maxAspectRatio) continue;
- ALOGV(" Got reasonable heights: %f %f", gridLeftWidth, gridRightWidth);
-
- // Calculate average grid spacing
- float gridAvgXGap = (gridTopWidth + gridBotWidth) / 2 / 5;
- float gridAvgYGap = (gridLeftWidth + gridRightWidth) / 2 / 3;
-
- // Calculate total error between average grid spacing and
- // actual spacing Uses difference in expected squared distance
- // and actual squared distance
- float error = 0;
- for (int x = 0; x < 6; x++) {
- for (int y = 0; y < 4; y++) {
- PixelGroup *node;
- node = tl->getRNeighbor(x)->getDNeighbor(y);
- if (node == NULL) {
- error += outWidth * outWidth;
- grid[y * 6 + x] = 0;
- } else {
- grid[y * 6 + x] = node->getId();
- if (node == tl) continue;
- float dist = tl->distanceSqTo(node);
- float expXDist = (gridAvgXGap * x);
- float expYDist = (gridAvgYGap * y);
- float expDist = expXDist * expXDist + expYDist * expYDist;
- error += fabs(dist - expDist);
- }
- }
- }
- if (bestError == -1 ||
- bestError > error) {
- bestGrid = grid;
- bestError = error;
- ALOGV(" Best candidate, error %f", error);
- }
- }
-
- // Check if a grid wasn't found
- if (bestError == -1) {
- ALOGV("No color checker found!");
- }
-
- // Make sure black square is in bottom-right corner
- if (bestError != -1) {
- unsigned char tlValues[3];
- unsigned char brValues[3];
- int tlId = bestGrid[0];
- int brId = bestGrid[23];
-
- groups[tlId - 1].getAvgValue(tlValues);
- groups[brId - 1].getAvgValue(brValues);
-
- int tlSum = tlValues[0] + tlValues[1] + tlValues[2];
- int brSum = brValues[0] + brValues[1] + brValues[2];
- if (brSum > tlSum) {
- // Grid is upside down, need to flip!
- ALOGV("Flipping grid to put grayscale ramp at bottom");
- bestGrid = std::vector<int>(bestGrid.rbegin(), bestGrid.rend());
- }
- }
-
- // Output average patch colors if requested
- if (bestError != -1 && patchColors != NULL) {
- for (int n = 0; n < 6 * 4 * colorChannels; n++) patchColors[n] = -1.f;
-
- // Scan over original input image for grid regions, degamma, average
- for (int px = 0; px < 6; px++) {
- for (int py = 0; py < 4; py++) {
- int id = bestGrid[py * 6 + px];
- if (id == 0) continue;
-
- PixelGroup &patch = groups[id - 1];
- int startX, startY;
- int endX, endY;
- patch.getBoundingBox(&startX, &startY, &endX, &endY);
-
- float sum[colorChannels] = {0.f};
- int count = 0;
- for (int y = startY; y <= endY; y++) {
- for (int x = startX; x < endX; x++) {
- if (outField(y,x).id != id) continue;
- for (int iY = y * outScale;
- iY < (y + 1) * outScale;
- iY++) {
- const unsigned char *inP = image +
- (iY * rowSpan)
- + (x * outScale * totalChannels);
- for (int iX = 0; iX < outScale; iX++) {
- for (int c = 0; c < colorChannels; c++) {
- // Convert to float and normalize
- float v = inP[c] / 255.f;
- // Gamma correct to get back to
- // roughly linear data
- v = pow(v, gammaCorrection);
- // Sum it up
- sum[c] += v;
- }
- count++;
- inP += totalChannels;
- }
- }
- }
- }
- for (int c = 0 ; c < colorChannels; c++) {
- patchColors[ (py * 6 + px) * colorChannels + c ] =
- sum[c] / count;
- }
- }
- }
- // Print out patch colors
- IF_ALOGV() {
- for (int y = 0; y < 4; y++) {
- char tmpMsg[256];
- int cnt = 0;
- cnt = snprintf(tmpMsg, 256, "%02d:", y + 1);
- for (int x = 0; x < 6; x++) {
- int id = bestGrid[y * 6 + x];
- if (id != 0) {
- float *p = &patchColors[ (y * 6 + x) * colorChannels];
- cnt += snprintf(tmpMsg + cnt, 256 - cnt,
- "\t(%.3f,%.3f,%.3f)", p[0], p[1], p[2]);
- } else {
- cnt += snprintf(tmpMsg + cnt, 256 - cnt,
- "\t(xxx,xxx,xxx)");
- }
- }
- ALOGV("%s", tmpMsg);
- }
- }
- }
-
- // Draw output if requested
- if (outputImage != NULL) {
- *outputImage = output;
- *outputWidth = outWidth;
- *outputHeight = outHeight;
-
- // Draw all candidate group bounds
- for (PixelGroup::IdSetIter group = candidateGroups.begin();
- group != candidateGroups.end();
- group++) {
-
- int x,y;
- (*group)->getApproxCenter(&x, &y);
-
- // Draw candidate bounding box
- int x0, y0, x1, y1;
- (*group)->getBoundingBox(&x0, &y0, &x1, &y1);
- drawLine(output, outWidth,
- x0, y0, x1, y0,
- 255, 0, 0);
- drawLine(output, outWidth,
- x1, y0, x1, y1,
- 255, 0, 0);
- drawLine(output, outWidth,
- x1, y1, x0, y1,
- 255, 0, 0);
- drawLine(output, outWidth,
- x0, y1, x0, y0,
- 255, 0, 0);
-
- // Draw lines between neighbors
- // Red for to-right and to-below of me connections
- const PixelGroup *neighbor;
- if ( (neighbor = (*group)->getRNeighbor()) != NULL) {
- int nX, nY;
- neighbor->getApproxCenter(&nX, &nY);
- drawLine(output,
- outWidth,
- x, y, nX, nY,
- 255, -1, -1);
- }
- if ( (neighbor = (*group)->getDNeighbor()) != NULL) {
- int nX, nY;
- neighbor->getApproxCenter(&nX, &nY);
- drawLine(output,
- outWidth,
- x, y, nX, nY,
- 255, -1, -1);
- }
- // Blue for to-left or to-above of me connections
- if ( (neighbor = (*group)->getLNeighbor()) != NULL) {
- int nX, nY;
- neighbor->getApproxCenter(&nX, &nY);
- drawLine(output,
- outWidth,
- x, y, nX, nY,
- -1, -1, 255);
- }
- if ( (neighbor = (*group)->getUNeighbor()) != NULL) {
- int nX, nY;
- neighbor->getApproxCenter(&nX, &nY);
- drawLine(output,
- outWidth,
- x, y, nX, nY,
- -1, -1, 255);
- }
- }
-
- // Mark found grid patch pixels
- if (bestError != -1) {
- for (int x=0; x < 6; x++) {
- for (int y =0; y < 4; y++) {
- int id = bestGrid[y * 6 + x];
- if (id != 0) {
- int x0, y0, x1, y1;
- groups[id - 1].getBoundingBox(&x0, &y0, &x1, &y1);
- // Fill patch pixels with blue
- for (int px = x0; px < x1; px++) {
- for (int py = y0; py < y1; py++) {
- if (outField(py,px).id != id) continue;
- unsigned char *p =
- &output[(py * outWidth + px)
- * totalChannels];
- p[0] = 0;
- p[1] = 0;
- p[2] = 255;
-
- }
- }
- drawLine(output, outWidth,
- x0, y0, x1, y1,
- 0, 255, 0);
- drawLine(output, outWidth,
- x0, y1, x0, y1,
- 0, 255, 0);
- }
- }
- }
- }
-
- } else {
- delete output;
- }
-
- int64_t endTime = systemTime();
- ALOGV("Process time: %f ms",
- (endTime - startTime) / 1000000.);
-
- if (bestError == -1) return false;
-
- return true;
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/grouping.h b/apps/CtsVerifier/lib/colorchecker/grouping.h
deleted file mode 100755
index 3125f55..0000000
--- a/apps/CtsVerifier/lib/colorchecker/grouping.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include <vector>
-#include <utility>
-
-#ifndef FILTERPACK_CALIBRATION_GROUPING_H
-#define FILTERPACK_CALIBRATION_GROUPING_H
-
-// To use the Grouping function, derive one class from Field.
-// Field class provides the interface for the Grouping function.
-// FF_ID is the pixel class used to compare values,
-// != operator must be defined in this class
-// region number of the pixel
-
-typedef std::vector <std::vector<int> > MASK;
-typedef std::pair<int, int> POS;
-// FF_ID needs to implement the operator !=
-// bool operator != (const FF_ID &id)
-template <class FF_ID>
-class Field {
- public:
- int id_no;
- MASK mask;
- virtual FF_ID operator () (int y, int x) const =0 ;
- virtual int getWidth() const = 0;
- virtual int getHeight() const= 0;
- virtual ~Field() {}
-};
-
-template < class FF_ID>
-void FloodFill(int sx,
- int sy,
- int id_no,
- const FF_ID &id,
- Field<FF_ID> *pField,
- POS *new_pos) {
- std::vector<POS> stack;
- stack.push_back(POS(sx,sy));
- while (stack.size() > 0) {
- sx = stack.back().first;
- sy = stack.back().second;
- stack.pop_back();
-
- // fill the current line
- int x;
- for (x = sx-1; x >= 0; x--)
- {
- if (pField->mask[sy][x]!=0) break;
- if (id != (*pField)(sy,x)) {
- new_pos->first = x;
- new_pos->second =sy;
- break;
- }
- pField->mask[sy][x] = id_no;
- }
- int startx = x;
- for (x = sx;x < pField->getWidth(); x++) {
- if (pField->mask[sy][x]!=0) break;
- if (id != (*pField)(sy,x)) {
- new_pos->first = x;
- new_pos->second =sy;
- break;
- }
- pField->mask[sy][x] = id_no;
- }
- int endx = x;
- if (endx >= pField->getWidth()) endx = pField->getWidth() - 1;
- if (startx < 0) startx = 0;
- // push the adjacent spans to the stack
- if (sy>0) {
- int bNew = true;
- for (x = endx; x >= startx; x--) {
- if (pField->mask[sy-1][x] != 0 || id != (*pField)(sy-1,x) ) {
- bNew = true;
- continue;
- }
- if (bNew) {
- stack.push_back( POS(x, sy-1));
- bNew = false;
- }
- }
- }
- if (sy < (pField->getHeight() - 1)) {
- int bNew = true;
- for (x = endx; x >= startx; x--) {
- if (pField->mask[sy+1][x]!=0 || id != (*pField)(sy+1,x)) {
- bNew = true;
- continue;
- }
- if (bNew) {
- stack.push_back( POS(x, sy+1));
- bNew = false;
- }
- }
- }
- }
-}
-
-// Group the pixels in Field based on the FF_ID != operator.
-// All pixels will be labeled from 1. The total number of unique groups(regions)
-// is (pField->id_no - 1) after the call
-// The labeasl of the pixels are stored in the mask member of Field.
-
-template <class FF_ID>
-void Grouping(Field <FF_ID> *pField) {
- int width = pField->getWidth();
- int height = pField->getHeight();
- pField->mask = MASK(height, std::vector<int> (width, 0) );
-
- FF_ID id;
- pField->id_no = 1;
- int sx = width / 2, sy = height / 2;
- POS new_pos(-1,-1);
- while (1) {
- id = (*pField)(sy,sx);
- int id_no = pField->id_no;
- new_pos.first = -1;
- new_pos.second = -1;
- FloodFill(sx, sy, id_no, id, pField, &new_pos);
- if (new_pos.first < 0) // no new position found, during the flood fill
- {
- const int kNumOfRetries = 10;
- // try 10 times for the new unfilled position
- for (int i = 0; i < kNumOfRetries; i++) {
- sx = rand() % width;
- sy = rand() % height;
- if (pField->mask[sy][sx] == 0) {
- new_pos.first = sx;
- new_pos.second = sy;
- break;
- }
- }
- if (new_pos.first < 0) { // still failed, search the whole image
- for (int y = 0; y < height && new_pos.first < 0; y++)
- for (int x = 0; x < width; x++) {
- if (pField->mask[y][x] == 0) {
- new_pos.first = x;
- new_pos.second = y;
- break;
- }
- }
- }
- if (new_pos.first < 0) break; // finished
- }
- sx = new_pos.first;
- sy = new_pos.second;
- pField->id_no++;
- }
-}
-
-#endif
diff --git a/apps/CtsVerifier/res/layout/ca_main.xml b/apps/CtsVerifier/res/layout/ca_main.xml
index 98ec049..c41bcf6 100644
--- a/apps/CtsVerifier/res/layout/ca_main.xml
+++ b/apps/CtsVerifier/res/layout/ca_main.xml
@@ -19,25 +19,60 @@
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
- <Button android:id="@+id/runbutton" android:layout_width="fill_parent"
- android:layout_height="wrap_content" android:text="@string/ca_run_label" />
- <TextView android:id="@+id/resulttext" android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/ca_result_label"
- android:textSize="15sp" />
+ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal" android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <!--Button android:id="@+id/focusmodesbutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_focus_modes_label"
+ android:layout_weight="1" /-->
+ <Button android:id="@+id/findcheckerboardbutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_find_checkerboard_label"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/meteringbutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_metering_label"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/exposurecompensationbutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_exposure_test_label"
+ android:layout_weight="1"/>
+
+ <Button android:id="@+id/whitebalancebutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_wb_test_label"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/lockbutton" android:layout_width="0px"
+ android:layout_height="wrap_content" android:text="@string/ca_lock_test_label"
+ android:layout_weight="1" />
+ </LinearLayout>
<LinearLayout android:orientation="horizontal"
- android:layout_width="fill_parent" android:layout_height="wrap_content">
+ android:layout_width="fill_parent" android:layout_height="0px"
+ android:layout_weight="1">
- <SurfaceView android:id="@+id/cameraview" android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_weight="1" />
+ <SurfaceView android:id="@+id/cameraview" android:layout_height="fill_parent"
+ android:layout_width="wrap_content"
+ android:layout_weight="0" />
- <ImageView android:id="@+id/resultview" android:layout_height="match_parent"
- android:layout_width="match_parent"
- android:layout_weight="1" />
+ <LinearLayout android:orientation="vertical"
+ android:layout_width="fill_parent" android:layout_height="match_parent"
+ android:layout_weight="1">
+
+ <ListView android:id="@+id/ca_tests"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_marginLeft="10px"/>
+
+ <ImageView android:id="@+id/resultview" android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:layout_weight="1" />
+ </LinearLayout>
</LinearLayout>
+
+ <include layout="@layout/pass_fail_buttons" />
+
</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/ca_row.xml b/apps/CtsVerifier/res/layout/ca_row.xml
new file mode 100644
index 0000000..0e09793
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/ca_row.xml
@@ -0,0 +1,19 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ >
+ <TextView
+ android:id="@+id/caTestName"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="10px"
+ />
+ <TextView
+ android:id="@+id/caTestResult"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:layout_marginLeft="10px"
+ />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/menu/ca_menu.xml b/apps/CtsVerifier/res/menu/ca_menu.xml
new file mode 100644
index 0000000..c33e7e8
--- /dev/null
+++ b/apps/CtsVerifier/res/menu/ca_menu.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+</menu>
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index cbb98a9..0b449a5 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -101,7 +101,7 @@
<string name="da_screen_lock_test">Screen Lock Test</string>
<string name="da_screen_lock_info">This test checks that the DevicePolicyManager\'s lockNow
method immediately locks the screen. It should lock the screen immediately despite any
- settings that may specify a timeout.\n\nClick the \"Force Lock\" button to lock the screen.
+ settings that may specify a timeout.\n\nClick the \"Force Lock\" button to lock the screen.
Your screen should be locked and require the password to be entered.
</string>
<string name="da_force_lock">Force Lock</string>
@@ -372,8 +372,14 @@
<!-- Strings for Camera Analyzer -->
<string name="camera_analyzer">Camera Analyzer</string>
- <string name="ca_run_label">Find color checker</string>
- <string name="ca_result_label">Patch values will be here</string>
+ <string name="ca_find_checkerboard_label">Find color checker</string>
+ <string name="ca_exposure_test_label">Exposure Comp. Test</string>
+ <string name="ca_result_label">Results will be here</string>
+ <string name="ca_wb_test_label">White Balance Test</string>
+ <string name="ca_lock_test_label">Auto Exposure Lock Test</string>
+ <string name="ca_metering_label">Metering Area Test</string>
+ <string name="ca_focus_modes_label">Focus Modes Test</string>
+ <string name="ca_info">This test checks the image quality of the camera of this device. It requires a MacBeth 4x6 color checker. With an ADK board and a lamp connected to it on the Relay 1 port, all tests can be run automatically. Without the ADK board, all the tests except the Auto Exposure Lock Test can be run automatically and the Auto Exposure Lock Test will require users to turn on/off a lamp according to the instruction given. </string>
<!-- Strings for USB accessory test activity -->
<string name="usb_accessory_test">USB Accessory Test</string>
diff --git a/apps/CtsVerifier/res/xml/accessory_filter_adk.xml b/apps/CtsVerifier/res/xml/accessory_filter_adk.xml
new file mode 100644
index 0000000..a5dc89a
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/accessory_filter_adk.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <usb-accessory model="DemoKit" manufacturer="Google" version="1.0"/>
+</resources>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
deleted file mode 100644
index b50dd9e..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-package com.android.cts.verifier.camera.analyzer;
-
-import com.android.cts.verifier.R;
-
-import android.app.Activity;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.os.Bundle;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.io.IOException;
-
-public class CameraAnalyzerActivity extends Activity {
-
- Bitmap mInputImage;
- TextView mResultText;
- SurfaceView mCameraView;
- ImageView mResultView;
- Camera mCamera;
- boolean mProcessingPicture = false;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.ca_main);
-
- findViewById(R.id.runbutton).setOnClickListener(mRunListener);
-
- mCameraView = (SurfaceView)findViewById(R.id.cameraview);
- mResultView = (ImageView)findViewById(R.id.resultview);
- mResultText = (TextView)findViewById(R.id.resulttext);
- mCameraView.getHolder().addCallback(mSurfaceChangeListener);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- mCamera = Camera.open(0);
- Camera.Parameters params = mCamera.getParameters();
- params.setPictureFormat(ImageFormat.JPEG);
- mCamera.setParameters(params);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- mCamera.release();
- }
-
- private View.OnClickListener mRunListener = new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!mProcessingPicture) {
- mCamera.takePicture(null, null, null, mJpegListener);
- mProcessingPicture = true;
- }
- }
- };
-
- private Camera.PictureCallback mJpegListener = new Camera.PictureCallback() {
- public void onPictureTaken(byte[] data, Camera mCamera) {
- mCamera.startPreview();
- mInputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
- ColorChecker checker = new ColorChecker(mInputImage);
- mResultView.setImageBitmap(checker.getDebugOutput());
- if (checker.isValid()) {
- String patchValueTxt = new String();
- for (int y = 0; y < 4; y++) {
- for (int x = 0; x < 6; x++) {
- patchValueTxt +=
- String.format("[ %.3f, %.3f, %.3f] ",
- checker.getPatchValue(x,y,0),
- checker.getPatchValue(x,y,1),
- checker.getPatchValue(x,y,2));
- }
- patchValueTxt += "\n";
- }
- mResultText.setText(patchValueTxt);
- } else {
- mResultText.setText("Can't find color checker!");
- }
- mProcessingPicture = false;
- }
- };
-
- private SurfaceHolder.Callback mSurfaceChangeListener =
- new SurfaceHolder.Callback() {
- @Override
- public void surfaceChanged(SurfaceHolder holder,
- int format,
- int width,
- int height) {
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- try {
- mCamera.setPreviewDisplay(mCameraView.getHolder());
- } catch (IOException e) {
- throw new RuntimeException("Unable to connect camera to display: " + e);
- }
- mCamera.startPreview();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
-
- };
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorChecker.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorChecker.java
deleted file mode 100644
index c9df24a..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorChecker.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.cts.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-
-/** The ColorChecker class is used to locate a Xrite Classic Color Checker grid
- * pattern in an image, and return the average value of each color patch.
- *
- * The pattern is a 6x4 grid of square color patches. The detection routine
- * assumes the pattern is placed roughly facing the camera, with the long size
- * roughly horizontal. It doesn't matter whether the pattern is upside down or
- * not - the returned array will have the grayscale squares of the pattern on
- * the bottom row.
- */
-class ColorChecker {
-
- private float[] mPatchValues;
- private Bitmap mDebugOutput;
- private boolean mSuccess = false;
-
- /** Construct a ColorChecker from a source Bitmap.
- *
- * @param source The source image to scan through for the 6x4 Xrite Classic
- * Color Checker pattern.
- */
- public ColorChecker(Bitmap source) {
- mPatchValues = new float[6 * 4 * 3];
- mSuccess = findNative(source);
- }
-
- /** Returns whether the ColorChecker pattern was found in the source bitmap
- *
- * @return true if the pattern was found in the source Bitmap. false
- * otherwise.
- */
- public boolean isValid() {
- return mSuccess;
- }
-
- /** Returns patch RGB triplet for patch (x, y), or null if the pattern wasn't
- * found.
- *
- * @param x Column of the patch
- * @param y Row of the patch
- * @return A 3-entry float array representing the R, G, and B values of the
- * patch in roughly linear luminance, mapped to the 0-1 range.
- */
- public float[] getPatchRGB(int x, int y) {
- if (!mSuccess) throw new RuntimeException("No color checker found!");
- float[] rgb = {
- mPatchValues[(y * 6 + x) * 3 + 0],
- mPatchValues[(y * 6 + x) * 3 + 1],
- mPatchValues[(y * 6 + x) * 3 + 2]
- };
- return rgb;
- }
-
- /** Returns patch (x, y) color channel c.
- *
- * @param x Column of the patch
- * @param y Row of the patch
- * @param c Color channel of the patch (0 = R, 1 = G, 2 = B)
- * @return The float value for that color channel in roughly linear
- * luminance, mapped to the 0-1 range.
- */
- public float getPatchValue(int x, int y, int c) {
- if (!mSuccess) throw new RuntimeException("No color checker found!");
- return mPatchValues[(y * 6 + x) * 3 + c];
- }
-
- /** Returns debug Bitmap image showing detected candidate patches and the
- * grid if it was found. Valid even if the pattern wasn't found. Candiate
- * patches will have red bounding boxes. In addition, patches that are part
- * of the color checker pattern are have a green diagonal, and all their
- * member pixels are colored in solid blue.
- *
- * @return A low-resolution version of the source Bitmap with overlaid
- * detection results.
- */
- public Bitmap getDebugOutput() {
- return mDebugOutput;
- }
-
- native boolean findNative(Bitmap input);
-
- static {
- System.loadLibrary("cameraanalyzer");
- }
-}
\ No newline at end of file