diff --git a/apps/CtsVerifier/include/colorchecker/colorcheckertest.h b/apps/CtsVerifier/include/colorchecker/colorcheckertest.h
new file mode 100644
index 0000000..f733b32
--- /dev/null
+++ b/apps/CtsVerifier/include/colorchecker/colorcheckertest.h
@@ -0,0 +1,104 @@
+/*
+ * 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 COLORCHECKERTEST_H
+#define COLORCHECKERTEST_H
+
+#include <vector>
+#include <string>
+
+#include "testingimage.h"
+#include "imagetesthandler.h"
+
+class ColorCheckerTest : public ImageTestHandler {
+public:
+    ColorCheckerTest() : ImageTestHandler() {
+        mImage = NULL;
+        mSuccess = false;
+    }
+    ColorCheckerTest(int debugHeight, int inputWidth) :
+            ImageTestHandler(debugHeight, inputWidth) {
+        mImage = NULL;
+        mSuccess = false;
+    }
+    ~ColorCheckerTest();
+
+    void addTestingImage(TestingImage* inputImage);
+    void processData();
+
+    const std::vector<std::vector<Vec2f> >* getCheckerCenterAdd() const {
+        std::vector<std::vector<Vec2f> >* returnPositions =
+                new std::vector<std::vector<Vec2f> >(
+                        4, std::vector<Vec2f>(6, Vec2f(0.f, 0.f)));
+
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0; j < 6; ++j) {
+                (*returnPositions)[i][j] = (*mMatchPositions[i][j]);
+            }
+        }
+        return (returnPositions);
+    }
+
+    const std::vector<std::vector<float> >* getCheckerRadiusAdd() const {
+        std::vector<std::vector<float> >* returnRadius=
+              new std::vector<std::vector<float> >(
+                      4, std::vector<float>(6, 0.f));
+
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0; j < 6; ++j) {
+                (*returnRadius)[i][j] = mMatchRadius[i][j];
+            }
+        }
+        return (returnRadius);
+    }
+
+    bool getSuccess() const {
+        return mSuccess;
+    }
+
+private:
+    void initializeRefColor();
+
+    void edgeDetection();
+    void computeGradient(unsigned char* layer, float* gradientMap);
+    void houghLineDetection(bool* edgeMap, float* gradientAbsolute,
+                            float* gradientDirection);
+
+    void findCheckerBoards(std::vector<std::vector<int> > linesDir1,
+                           std::vector<std::vector<int> > linesDir2);
+    Vec2f findCrossing(std::vector<int> line1, std::vector<int> line2);
+    void findBestMatch(int i1, int i2, int j1, int j2);
+
+    bool verifyPointPair(Vec2f pointUpperLeft, Vec2f pointBottomRight,
+                         Vec2f* pointCenter, Vec3i* color);
+    void verifyColorGrid();
+
+    void fillRefColorGrid();
+
+    TestingImage* mImage;
+
+    std::vector<std::vector< Vec3i* > > mCandidateColors;
+    std::vector<std::vector< Vec2f* > > mCandidatePositions;
+
+    std::vector<std::vector< Vec3i* > > mReferenceColors;
+    std::vector<std::vector< Vec2f* > > mMatchPositions;
+    std::vector<std::vector< Vec3f* > > mMatchColors;
+    std::vector<std::vector< float > > mMatchRadius;
+
+    bool mSuccess;
+};
+
+#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
index 59ca11a..e4eecef 100644
--- a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
+++ b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
@@ -22,9 +22,9 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := #com_android_cts_verifier_camera_analyzer_CameraTests.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_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
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp
new file mode 100644
index 0000000..94e3ac2
--- /dev/null
+++ b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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
+
+#define LOG_TAG "FindColorCheckerJNI"
+#include <utils/Log.h>
+#include "com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h"
+
+#include <string.h>
+#include "android/bitmap.h"
+#include "colorcheckertest.h"
+#include "testingimage.h"
+
+jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerTest(
+        JNIEnv*      env,
+        jobject      thiz,
+        jint         debugHeight,
+        jint         debugWidth) {
+    ColorCheckerTest* testHandler = new ColorCheckerTest(debugHeight,
+                                                         debugWidth);
+    long testHandlerAddress = (long)testHandler;
+    return testHandlerAddress;
+}
+
+void Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerClass(
+        JNIEnv*      env,
+        jobject      thiz,
+        jlong        inputImageAddress,
+        jlong        inputHandlerAddress) {
+    ALOGV("JNI createColorCheckerClass starts!");
+
+    TestingImage *testImage = (TestingImage*) (long) inputImageAddress;
+    ColorCheckerTest *testHandler = (ColorCheckerTest*)
+            (long) inputHandlerAddress;
+
+    testHandler->addTestingImage(testImage);
+}
+
+jboolean Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_processColorCheckerTest(
+        JNIEnv*      env,
+        jobject      thiz,
+        jlong        inputHandlerAddress) {
+
+    ColorCheckerTest *testHandler = (ColorCheckerTest*)
+            (long) inputHandlerAddress;
+    testHandler->processData();
+    return testHandler->getSuccess();
+}
+
+jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerRadiusAdd(
+        JNIEnv*      env,
+        jobject      thiz,
+        jlong        inputHandlerAddress) {
+
+    ColorCheckerTest *testHandler = (ColorCheckerTest*)
+            (long) inputHandlerAddress;
+    long rtn = (long) testHandler->getCheckerRadiusAdd();
+    return rtn;
+}
+
+jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerCenterAdd(
+        JNIEnv*      env,
+        jobject      thiz,
+        jlong        inputHandlerAddress) {
+
+    ColorCheckerTest *testHandler = (ColorCheckerTest*)
+            (long) inputHandlerAddress;
+
+    long rtn = (long) testHandler->getCheckerCenterAdd();
+    return rtn;
+}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h
new file mode 100644
index 0000000..fb87735
--- /dev/null
+++ b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h
@@ -0,0 +1,63 @@
+/*
+ * 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_COLORCHECKERTEST_H
+#define JNI_CAMERAANALYZER_COLORCHECKERTEST_H
+
+#include <jni.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT jlong JNICALL
+Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerTest(
+    JNIEnv*      env,
+    jobject      thiz,
+    jint         output_height,
+    jint         output_width);
+
+JNIEXPORT void JNICALL
+Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerClass(
+    JNIEnv *env,
+    jobject thiz,
+    jlong buffer_address,
+    jlong handler_address);
+
+JNIEXPORT jlong JNICALL
+Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerRadiusAdd(
+    JNIEnv *env,
+    jobject thiz,
+    jlong handler_address);
+
+JNIEXPORT jlong JNICALL
+Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerCenterAdd(
+    JNIEnv *env,
+    jobject thiz,
+    jlong handler_address);
+
+JNIEXPORT jboolean JNICALL
+Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_processColorCheckerTest(
+    JNIEnv*      env,
+    jobject      thiz,
+    jlong        handler_address);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/apps/CtsVerifier/lib/colorchecker/Android.mk b/apps/CtsVerifier/lib/colorchecker/Android.mk
index fcd51c4..076a89a 100644
--- a/apps/CtsVerifier/lib/colorchecker/Android.mk
+++ b/apps/CtsVerifier/lib/colorchecker/Android.mk
@@ -27,9 +27,9 @@
 LOCAL_SRC_FILES += testingimage.cpp \
                    vec3.cpp \
                    vec2.cpp \
-                   #imagetesthandler.cpp \
-                   whitebalancetest.cpp \
+                   imagetesthandler.cpp \
                    colorcheckertest.cpp \
+                   #whitebalancetest.cpp \
                    exposurecompensationtest.cpp \
                    autolocktest.cpp \
                    meteringtest.cpp
diff --git a/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp b/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
new file mode 100644
index 0000000..bc421eb
--- /dev/null
+++ b/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
@@ -0,0 +1,943 @@
+/*
+ * 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
+
+#define LOG_TAG "ColorCheckerTest"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <cmath>
+#include <string>
+
+#include "vec2.h"
+#include "vec3.h"
+#include "colorcheckertest.h"
+
+const float GAMMA_CORRECTION = 2.2f;
+ColorCheckerTest::~ColorCheckerTest() {
+    ALOGV("Deleting color checker test handler");
+
+    if (mImage != NULL) {
+        delete mImage;
+    }
+    ALOGV("Image deleted");
+
+    int numHorizontalLines = mCandidateColors.size();
+    int numVerticalLines = mCandidateColors[0].size();
+
+    for (int i = 0; i < numHorizontalLines; ++i) {
+        for (int j = 0; j < numVerticalLines; ++j) {
+            if (mCandidateColors[i][j] != NULL) {
+                delete mCandidateColors[i][j];
+            }
+            if (mCandidatePositions[i][j] != NULL) {
+                delete mCandidatePositions[i][j];
+            }
+        }
+    }
+    ALOGV("Candidates deleted!");
+
+    for (int i = 0; i < 4; ++i) {
+        for (int j = 0; j < 6; ++j) {
+            if (mMatchPositions[i][j] != NULL) {
+                delete mMatchPositions[i][j];
+            }
+            if (mReferenceColors[i][j] != NULL) {
+                delete mReferenceColors[i][j];
+            }
+            if (mMatchColors[i][j] != NULL) {
+                delete mMatchColors[i][j];
+            }
+        }
+    }
+}
+
+// Adds a new image to the test handler.
+void ColorCheckerTest::addTestingImage(TestingImage* inputImage) {
+    if (mImage != NULL) {
+        delete mImage;
+    }
+    mImage = NULL;
+    ALOGV("Original image deleted");
+    mImage = inputImage;
+
+    if ((mImage->getHeight() == getDebugHeight()) &&
+        (mImage->getWidth() == getDebugWidth())) {
+        copyDebugImage(getDebugHeight(), getDebugWidth(), mImage->getImage());
+    }
+}
+
+void ColorCheckerTest::processData() {
+    mSuccess = false;
+    initializeRefColor();
+    edgeDetection();
+}
+
+void ColorCheckerTest::initializeRefColor() {
+    mReferenceColors.resize(4, std::vector<Vec3i*>(6, NULL));
+    mMatchPositions.resize(4, std::vector<Vec2f*>(6, NULL));
+    mMatchColors.resize(4, std::vector<Vec3f*>(6, NULL));
+    mMatchRadius.resize(4, std::vector<float>(6, 0.f));
+
+    mReferenceColors[0][0]= new Vec3i(115, 82, 68);
+    mReferenceColors[0][1]= new Vec3i(194, 150, 130);
+    mReferenceColors[0][2]= new Vec3i(98, 122, 157);
+    mReferenceColors[0][3]= new Vec3i(87, 108, 67);
+    mReferenceColors[0][4]= new Vec3i(133, 128, 177);
+    mReferenceColors[0][5]= new Vec3i(103, 189, 170);
+    mReferenceColors[1][0]= new Vec3i(214, 126, 44);
+    mReferenceColors[1][1]= new Vec3i(80, 91, 166);
+    mReferenceColors[1][2]= new Vec3i(193, 90, 99);
+    mReferenceColors[1][3]= new Vec3i(94,  60, 108);
+    mReferenceColors[1][4]= new Vec3i(157, 188, 64);
+    mReferenceColors[1][5]= new Vec3i(224, 163, 46);
+    mReferenceColors[2][0]= new Vec3i(56, 61, 150);
+    mReferenceColors[2][1]= new Vec3i(70, 148, 73);
+    mReferenceColors[2][2]= new Vec3i(175, 54, 60);
+    mReferenceColors[2][3]= new Vec3i(231, 199, 31);
+    mReferenceColors[2][4]= new Vec3i(187, 86, 149);
+    mReferenceColors[2][5]= new Vec3i(8, 133, 161);
+    mReferenceColors[3][0]= new Vec3i(243, 243, 242);
+    mReferenceColors[3][1]= new Vec3i(200, 200, 200);
+    mReferenceColors[3][2]= new Vec3i(160, 160, 160);
+    mReferenceColors[3][3]= new Vec3i(122, 122, 121);
+    mReferenceColors[3][4]= new Vec3i(85, 85, 85);
+    mReferenceColors[3][5]= new Vec3i(52, 52, 52);
+}
+
+void ColorCheckerTest::edgeDetection() {
+    int width = mImage->getWidth();
+    int height = mImage->getHeight();
+
+    bool* edgeMap = new bool[height * width];
+    unsigned char* grayImage = new unsigned char[height * width];
+
+    // If the image is a color image and can be converted to a luminance layer
+    if (mImage->rgbToGrayScale(grayImage)) {
+        float* gradientMap = new float[height * width * 2];
+
+        // Computes the gradient image on the luminance layer.
+        computeGradient(grayImage, gradientMap);
+
+        float* gradientMagnitude = new float[height * width];
+        int* gradientDirectionInt = new int[height * width];
+        float* gradientDirection = new float[height * width];
+
+        // Computes the absolute gradient of the image without padding.
+        for (int i = 1; i < height - 1; ++i) {
+            for (int j = 1; j < width - 1; ++j) {
+                gradientMagnitude[i * width + j] =
+                        sqrt(gradientMap[(i * width + j) * 2] *
+                             gradientMap[(i * width + j) * 2] +
+                             gradientMap[(i * width + j ) * 2 + 1] *
+                             gradientMap[(i * width + j ) * 2 + 1]);
+
+                // Computes the gradient direction of the image.
+                if (gradientMap[(i * width + j) * 2] == 0 ) {
+                    // If the vertical gradient is 0, the edge is horizontal
+                    // Mark the gradient direction as 90 degrees.
+                    gradientDirectionInt[i * width + j] = 2;
+                    gradientDirection[i * width + j] = 90.0f;
+                } else {
+                    // Otherwise the atan operation is valid and can decide
+                    // the gradient direction of the edge.
+                    float gradient = atan(gradientMap[(i * width + j) * 2 + 1]
+                            / gradientMap[(i * width + j) * 2])
+                            / (M_PI / 4);
+
+                    gradientDirection[i * width + j] = gradient * 45.0f;
+
+                    // Maps the gradient direction to 4 major directions with
+                    // 0 mapped to up and 2 mapped to right.
+                    if (gradient - floor(gradient) > 0.5) {
+                        gradientDirectionInt[i * width + j] =
+                                (static_cast<int>(ceil(gradient)) + 4) % 4;
+                    } else {
+                        gradientDirectionInt[i * width + j] =
+                                (static_cast<int>(floor(gradient)) + 4) % 4;
+                    }
+                }
+            }
+        }
+
+        // Compute a boolean map to show whether a pixel is on the edge.
+        for (int i = 1; i < height - 1; ++i) {
+            for (int j = 1; j < width - 1; ++j) {
+                edgeMap[i * width + j] = false;
+
+                switch (gradientDirectionInt[i * width + j]) {
+                    case 0:
+                        // If the gradient points rightwards, the pixel is
+                        // on an edge if it has a larger absolute gradient than
+                        // pixels on its left and right sides.
+                        if ((gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[i * width + j + 1]) &&
+                            (gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[i * width + j - 1])) {
+                            edgeMap[i * width + j] = true;
+                        }
+                        break;
+                    case 1:
+                        // If the gradient points right-downwards, the pixel is
+                        // on an edge if it has a larger absolute gradient than
+                        // pixels on its upper left and bottom right sides.
+                        if ((gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i + 1) * width + j + 1]) &&
+                            (gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i - 1) * width + j - 1])) {
+                            edgeMap[i * width + j] = true;
+                        }
+                        break;
+                    case 2:
+                        // If the gradient points upwards, the pixel is
+                        // on an edge if it has a larger absolute gradient than
+                        // pixels on its up and down sides.
+                        if ((gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i + 1) * width + j]) &&
+                            (gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i - 1) * width + j])) {
+                            edgeMap[i * width + j] = true;
+                        }
+                        break;
+                    case 3:
+                        // If the gradient points right-upwards, the pixel is
+                        // on an edge if it has a larger absolute gradient than
+                        // pixels on its bottom left and upper right sides.
+                        if ((gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i - 1) * width + j + 1]) &&
+                            (gradientMagnitude[i * width + j] >=
+                                gradientMagnitude[(i + 1) * width + j - 1])) {
+                            edgeMap[i * width + j] = true;
+                        }
+                  }
+
+             }
+        }
+
+        houghLineDetection(edgeMap, gradientMagnitude, gradientDirection);
+
+        // Cleans up
+        delete[] gradientMap;
+        delete[] gradientDirectionInt;
+        delete[] gradientMagnitude;
+        delete[] gradientDirection;
+
+    } else {
+        LOGE("Not a color image!");
+    }
+
+    delete[] edgeMap;
+    delete[] grayImage;
+}
+
+// Runs the hough voting algorithm to find the grid of the color checker
+// with the edge map, gradient direction and gradient magnitude as inputs.
+void ColorCheckerTest::houghLineDetection(bool* edgeMap,
+                                          float* gradientMagnitude,
+                                          float* gradientDirection) {
+    // Constructs a graph for Hough voting. The vertical axis counts the vote
+    // for a certain angle. The horizontal axis counts the vote for the distance
+    // of a line from the origin of the image.
+    int houghHeight = 180;
+    int houghWidth = 200;
+    int houghCounts[houghHeight][houghWidth];
+    int houghSum[houghHeight][houghWidth];
+
+    int** houghVote;
+    houghVote = new int*[180];
+    for (int i = 0; i < 180; ++i) {
+        houghVote[i] = new int[200];
+    }
+
+    for (int i = 0; i < houghHeight; ++i) {
+        for (int j = 0; j < houghWidth; ++j) {
+            houghCounts[i][j] = 0;
+            houghVote[i][j] = 0;
+            houghSum[i][j] = 0;
+        }
+    }
+
+    // Vectors to record lines in two orthogonal directions.
+    // Each line is represented by its direction and its distance to the origin.
+    std::vector<std::vector<int> > verticalLines;
+    std::vector<std::vector<int> > horizontalLines;
+    float radius;
+    int height = mImage->getHeight();
+    int width = mImage->getWidth();
+
+    // Processes the signicant edge pixels and cast vote for the corresponding
+    // edge passing this pixel.
+    for (int i = 1; i < height - 1; ++i) {
+        for (int j = 1; j < width - 1; ++j) {
+            // Sets threashold for the gradient magnitude to discount noises
+            if (edgeMap[i * width + j] &&
+                (gradientMagnitude[i * width + j] > 15)) {
+                int shiftedAngle;
+
+                // Shifts angles for 45 degrees so the vertical and horizontal
+                // direction is mapped to 45 and 135 degrees to avoid padding.
+                // This uses the assumption that the color checker is placed
+                // roughly parallel to the image boarders. So that the edges
+                // at the angle of 45 will be rare.
+                shiftedAngle = (static_cast<int>(
+                        -gradientDirection[i * width + j]) + 225 % 180);
+                float shiftedAngleRad = static_cast<float>(shiftedAngle)
+                        * M_PI / 180.0f;
+
+                // Computes the distance of the line from the origin.
+                float a, b;
+                a = static_cast<float>(i - j) / sqrt(2.0f);
+                b = static_cast<float>(i + j) / sqrt(2.0f);
+                radius = a * sin(shiftedAngleRad) - b * cos(shiftedAngleRad);
+
+                // Adds one vote for the line. The line's angle is shifted by
+                // 45 degrees to avoid avoid padding for the vertical lines,
+                // which is more common than diagonal lines. The line's
+                // distance is mapped to [0, 200] from [-200, 200].
+                ++houghCounts[shiftedAngle][static_cast<int>((radius / 2.0f) +
+                                                              100.0f)];
+
+                drawPoint(i, j, Vec3i(255, 255, 255));
+            }
+        }
+    }
+
+    int houghAngleSum[houghHeight];
+    int primaryVerticalAngle, primaryHorizontalAngle;
+    int max1 = 0;
+    int max2 = 0;
+
+    // Looking for the two primary angles of the lines.
+    for (int i = 5; i < houghHeight - 5; ++i) {
+        houghAngleSum[i] = 0;
+        for (int j = 0; j < houghWidth; ++j) {
+            for (int l = -5; l <= 5; ++l) {
+                houghSum[i][j] += houghCounts[i + l][j];
+            }
+            houghAngleSum[i] += houghSum[i][j];
+        }
+
+        if ((i < houghHeight / 2) && (houghAngleSum[i] > max1)) {
+            max1 = houghAngleSum[i];
+            primaryVerticalAngle = i;
+        } else if ((i > houghHeight / 2) && (houghAngleSum[i] > max2)) {
+            max2 = houghAngleSum[i];
+            primaryHorizontalAngle = i;
+        }
+    }
+
+    ALOGV("Primary angles are %d, %d",
+         primaryVerticalAngle, primaryHorizontalAngle);
+
+    int angle;
+
+    // For each primary angle, look for the highest voted lines.
+    for (int k = 0; k < 2; ++k) {
+        if (k == 0) {
+            angle = primaryVerticalAngle;
+        } else {
+            angle = primaryHorizontalAngle;
+        }
+
+        std::vector<int> line(2);
+        for (int j = 2; j < houghWidth - 2; ++j) {
+            houghVote[angle][j] = houghSum[angle][j];
+            houghSum[angle][j] = 0;
+        }
+
+        // For each radius, average the vote with nearby ones.
+        for (int j = 2; j < houghWidth - 2; ++j) {
+            for (int m = -2; m <= 2; ++m) {
+                houghSum[angle][j] += houghVote[angle][j + m];
+            }
+        }
+
+        bool isCandidate[houghWidth];
+
+        // Find whether a lines is a candidate by rejecting the ones that have
+        // lower vote than others in the neighborhood.
+        for (int j = 2; j < houghWidth - 2; ++j) {
+            isCandidate[j] = true;
+            for (int m = -2; ((isCandidate[j]) && (m <= 2)); ++m) {
+                if ((houghSum[angle][j] < 20) ||
+                    (houghSum[angle][j] < houghSum[angle][j + m])) {
+                    isCandidate[j] = false;
+                }
+            }
+        }
+
+        int iter1 = 0;
+        int iter2 = 0;
+        int count = 0;
+
+        // Finds the lines that are not too close to each other and add to the
+        // detected lines.
+        while (iter2 < houghWidth) {
+            while ((!isCandidate[iter2]) && (iter2 < houghWidth)) {
+                ++iter2;
+            }
+            if ((isCandidate[iter2]) && (iter2 - iter1 < 5)) {
+                iter1 = (iter2 + iter1) / 2;
+                ++iter2;
+            } else {
+                line[0] = angle;
+                line[1] = (iter1 - 100) * 2;
+                if (iter1 != 0) {
+                    if (k == 0) {
+                        verticalLines.push_back(line);
+                        Vec3i color(verticalLines.size() * 20, 0, 0);
+                        drawLine(line[0], line[1], color);
+                    } else {
+                        horizontalLines.push_back(line);
+                        Vec3i color(0, horizontalLines.size() * 20, 0);
+                        drawLine(line[0], line[1], color);
+                    }
+                }
+                iter1 = iter2;
+                ++iter2;
+                ALOGV("pushing back line %d %d", line[0], line[1]);
+            }
+        }
+    }
+
+    ALOGV("Numbers of lines in each direction is %d, %d",
+         verticalLines.size(), horizontalLines.size());
+
+    for (int i = 0; i < 180; ++i) {
+        delete[] houghVote[i];
+    }
+    delete[] houghVote;
+
+    findCheckerBoards(verticalLines, horizontalLines);
+}
+
+// Computes the gradient in both x and y direction of a layer
+void ColorCheckerTest::computeGradient(unsigned char* layer,
+                                       float* gradientMap) {
+    int width = mImage->getWidth();
+    int height = mImage->getHeight();
+
+    // Computes the gradient in the whole image except the image boarders.
+    for (int i = 1; i < height - 1; ++i) {
+        for (int j = 1; j < width - 1; ++j) {
+            gradientMap[(i * width + j) * 2] =
+                    0.5f * (layer[i * width + j + 1] -
+                            layer[i * width + j - 1]);
+            gradientMap[(i * width + j) * 2 + 1] =
+                    0.5f * (layer[(i + 1) * width + j] -
+                           layer[(i - 1) * width + j]);
+        }
+    }
+}
+
+// Tries to find the checker boards with the highest voted lines
+void ColorCheckerTest::findCheckerBoards(
+        std::vector<std::vector<int> > verticalLines,
+        std::vector<std::vector<int> > horizontalLines) {
+    ALOGV("Start looking for Color checker");
+    int numVerticalLines = verticalLines.size();
+    int numHorizontalLines = horizontalLines.size();
+    Vec2f pointUpperLeft;
+    Vec2f pointBottomRight;
+
+    mCandidateColors.resize(numHorizontalLines - 1);
+    mCandidatePositions.resize(numHorizontalLines - 1);
+
+    for (int i = numVerticalLines - 1; i >= 1; --i) {
+        for (int j = 0; j < numHorizontalLines - 1; ++j) {
+            // Finds the upper left and bottom right corner of each rectangle
+            // formed by two neighboring highest voted lines.
+            pointUpperLeft = findCrossing(verticalLines[i], horizontalLines[j]);
+            pointBottomRight = findCrossing(verticalLines[i - 1],
+                                            horizontalLines[j + 1]);
+
+            Vec3i* color = new Vec3i();
+            Vec2f* pointCenter = new Vec2f();
+            // Verifies if they are separated by a reasonable distance.
+            if (verifyPointPair(pointUpperLeft, pointBottomRight,
+                                pointCenter, color)) {
+                mCandidatePositions[j].push_back(pointCenter);
+                mCandidateColors[j].push_back(color);
+            } else {
+                mCandidatePositions[j].push_back(NULL);
+                mCandidateColors[j].push_back(NULL);
+                delete color;
+                delete pointCenter;
+            }
+        }
+    }
+
+    // Verifies whether the current line candidates form a valid color checker.
+    verifyColorGrid();
+}
+
+// Returns the corssing point of two lines given the lines.
+Vec2f ColorCheckerTest::findCrossing(std::vector<int> line1,
+                                     std::vector<int> line2) {
+    Vec2f crossingPoint;
+    float r1 = static_cast<float>(line1[1]);
+    float r2 = static_cast<float>(line2[1]);
+    float ang1, ang2;
+    float y1, y2;
+
+    ang1 = static_cast<float>(line1[0]) / 180.0f * M_PI;
+    ang2 = static_cast<float>(line2[0]) / 180.0f * M_PI;
+
+    float x, y;
+    x = (r1 * cos(ang2) - r2 * cos(ang1)) / sin(ang1 - ang2);
+    y = (r1 * sin(ang2) - r2 * sin(ang1)) / sin(ang1 - ang2);
+
+    crossingPoint.set((x + y) / sqrt(2.0), (y - x) / sqrt(2.0));
+
+    //ALOGV("Crosspoint at (%f, %f)", crossingPoint.x(), crossingPoint.y());
+    return crossingPoint;
+}
+
+// Verifies whether two opposite corners on a quadrilateral actually can be
+// the two corners of a color checker.
+bool ColorCheckerTest::verifyPointPair(Vec2f pointUpperLeft,
+                                       Vec2f pointBottomRight,
+                                       Vec2f* pointCenter,
+                                       Vec3i* color) {
+    bool success = true;
+
+    /** 5 and 30 are the threshold tuned for resolution 640*480*/
+    if ((pointUpperLeft.x() < 0) ||
+        (pointUpperLeft.x() >= mImage->getHeight()) ||
+        (pointUpperLeft.y() < 0) ||
+        (pointUpperLeft.y() >= mImage->getWidth()) ||
+        (pointBottomRight.x() < 0) ||
+        (pointBottomRight.x() >= mImage->getHeight()) ||
+        (pointBottomRight.y() < 0) ||
+        (pointBottomRight.y() >= mImage->getWidth()) ||
+        (abs(pointUpperLeft.x() - pointBottomRight.x()) <= 5) ||
+        (abs(pointUpperLeft.y() - pointBottomRight.y()) <= 5) ||
+        (abs(pointUpperLeft.x() - pointBottomRight.x()) >= 30) ||
+        (abs(pointUpperLeft.y() - pointBottomRight.y()) >= 30)) {
+
+        // If any of the quadrilateral corners are out of the image or if
+        // the distance between them are too large or too big, the quadrilateral
+        // could not be one of the checkers
+        success = false;
+    } else {
+        // Find the checker center if the corners of the rectangle meet criteria
+        pointCenter->set((pointUpperLeft.x() + pointBottomRight.x()) / 2.0f,
+                       (pointUpperLeft.y() + pointBottomRight.y()) / 2.0f);
+        color->set(mImage->getPixelValue(*pointCenter).r(),
+                   mImage->getPixelValue(*pointCenter).g(),
+                   mImage->getPixelValue(*pointCenter).b());
+        ALOGV("Color at (%f, %f) is (%d, %d, %d)", pointCenter->x(), pointCenter->y(),color->r(), color->g(), color->b());
+    }
+    return success;
+}
+
+// Verifies the color checker centers and finds the match between the detected
+// color checker and the reference MacBeth color checker
+void ColorCheckerTest::verifyColorGrid() {
+    ALOGV("Start looking for Color Grid");
+    int numHorizontalLines = mCandidateColors.size();
+    int numVerticalLines = mCandidateColors[0].size();
+    bool success = false;
+
+    // Computes the standard deviation of one row/column of the proposed color
+    // checker. Discards the row/column if the std is below a threshold.
+    for (int i = 0; i < numHorizontalLines; ++i) {
+        Vec3f meanColor(0.f, 0.f, 0.f);
+        int numNonZero = 0;
+
+        for (int j = 0; j < numVerticalLines; ++j) {
+            if (mCandidateColors[i][j] != NULL) {
+                ALOGV("candidate color (%d, %d) is (%d, %d, %d)", i, j, mCandidateColors[i][j]->r(), mCandidateColors[i][j]->g(), mCandidateColors[i][j]->b());
+
+                meanColor = meanColor + (*mCandidateColors[i][j]);
+                ++numNonZero;
+            }
+        }
+        if (numNonZero > 0) {
+            meanColor = meanColor / numNonZero;
+        }
+        ALOGV("Mean color for vertical direction computed!");
+
+        float std = 0;
+        for (int j = 0; j < numVerticalLines; ++j) {
+            if (mCandidateColors[i][j] != NULL) {
+                std += mCandidateColors[i][j]->squareDistance<float>(meanColor);
+            }
+        }
+        if (numNonZero > 0) {
+            std = sqrt(std / (3 * numNonZero));
+        }
+        ALOGV("st. deviation for the %d dir1 is %d", i, static_cast<int>(std));
+
+        if ((std <= 30) && (numNonZero > 1)) {
+            for (int j = 0; j < numVerticalLines; ++j) {
+                if (mCandidateColors[i][j] != NULL) {
+                    delete mCandidateColors[i][j];
+                    mCandidateColors[i][j] = NULL;
+                }
+            }
+        }
+    }
+
+    // Discards the column/row of the color checker if the std is below a
+    // threshold.
+    for (int j = 0; j < numVerticalLines; ++j) {
+        Vec3f meanColor(0.f, 0.f, 0.f);
+        int numNonZero = 0;
+
+        for (int i = 0; i < numHorizontalLines; ++i) {
+            if (mCandidateColors[i][j] != NULL) {
+                meanColor = meanColor + (*mCandidateColors[i][j]);
+                ++numNonZero;
+            }
+        }
+        if (numNonZero > 0) {
+            meanColor = meanColor / numNonZero;
+        }
+
+        float std = 0;
+        for (int i = 0; i < numHorizontalLines; ++i) {
+            if (mCandidateColors[i][j] != NULL) {
+                std += mCandidateColors[i][j]->squareDistance<float>(meanColor);
+            }
+        }
+        if (numNonZero > 0) {
+            std = sqrt(std / (3 * numNonZero));
+        }
+
+        ALOGV("st. deviation for the %d dir2 is %d", j, static_cast<int>(std));
+
+        if ((std <= 30) && (numNonZero > 1)) {
+            for (int i = 0; i < numHorizontalLines; ++i) {
+                if (mCandidateColors[i][j] != NULL) {
+                    delete mCandidateColors[i][j];
+                    mCandidateColors[i][j] = NULL;
+                }
+            }
+        }
+    }
+
+    for (int i = 0; i < numHorizontalLines; ++i) {
+        for (int j = 0; j < numVerticalLines; ++j) {
+            if (mCandidateColors[i][j] != NULL) {
+                ALOGV("position (%d, %d) is at (%f, %f) with color (%d, %d, %d)",
+                     i, j,
+                     mCandidatePositions[i][j]->x(),
+                     mCandidatePositions[i][j]->y(),
+                     mCandidateColors[i][j]->r(),
+                     mCandidateColors[i][j]->g(),
+                     mCandidateColors[i][j]->b());
+            } else {
+                ALOGV("position (%d, %d) is 0", i, j);
+            }
+        }
+    }
+
+    // Finds the match between the detected color checker and the reference
+    // MacBeth color checker.
+    int rowStart = 0;
+    int rowEnd = 0;
+
+    // Loops until all dectected color checker has been processed.
+    while (!success) {
+        int columnStart = 0;
+        int columnEnd = 0;
+        bool isRowStart = false;
+        bool isRowEnd = true;
+
+        // Finds the row start of the next block of detected color checkers.
+        while ((!isRowStart) && (rowStart <  numHorizontalLines)) {
+            for (int j = 0; j < numVerticalLines; ++j) {
+                if (mCandidateColors[rowStart][j] != NULL) {
+                    isRowStart = true;
+                }
+            }
+            ++rowStart;
+        }
+        rowStart--;
+        rowEnd = rowStart;
+        ALOGV("rowStart is %d", rowStart);
+
+        // Finds the row end of the next block of detected color checkers.
+        while ((isRowEnd) && (rowEnd < numHorizontalLines)) {
+            isRowEnd = false;
+            for (int j = 0; j < numVerticalLines; ++j) {
+                if (mCandidateColors[rowEnd][j] != NULL) {
+                    isRowEnd= true;
+                }
+            }
+            if (isRowEnd) {
+                ++rowEnd;
+            }
+        }
+        if ((!isRowEnd) && isRowStart) {
+            rowEnd--;
+        }
+        if ((isRowEnd) && (rowEnd == numHorizontalLines)) {
+            rowEnd--;
+            isRowEnd = false;
+        }
+        ALOGV("rowEnd is %d", rowEnd);
+
+        // Matches color checkers between the start row and the end row.
+        bool successVertical = false;
+
+        while (!successVertical) {
+            bool isColumnEnd = true;
+            bool isColumnStart = false;
+
+            // Finds the start column of the next block of color checker
+            while ((!isColumnStart) && (columnStart < numVerticalLines)) {
+                if (mCandidateColors[rowStart][columnStart] != NULL) {
+                    isColumnStart = true;
+                }
+                ++columnStart;
+            }
+            columnStart--;
+            columnEnd = columnStart;
+
+            // Finds the end column of the next block of color checker
+            while ((isColumnEnd) && (columnEnd < numVerticalLines)) {
+                isColumnEnd = false;
+                if (mCandidateColors[rowStart][columnEnd] != NULL)
+                    isColumnEnd = true;
+                if (isColumnEnd) {
+                    ++columnEnd;
+                }
+            }
+
+            if ((!isColumnEnd) && isColumnStart) {
+                columnEnd--;
+            }
+            if ((isColumnEnd) && (columnEnd == numVerticalLines)) {
+                columnEnd--;
+                isColumnEnd = false;
+            }
+
+            // Finds the best match on the MacBeth reference color checker for
+            // the continuous block of detected color checker
+            if (isRowStart && (!isRowEnd) &&
+                isColumnStart && (!isColumnEnd)) {
+                findBestMatch(rowStart, rowEnd, columnStart, columnEnd);
+            }
+            ALOGV("FindBestMatch for %d, %d, %d, %d", rowStart,
+                 rowEnd, columnStart, columnEnd);
+
+            // If the column search finishes, go out of the loop
+            if (columnEnd >= numVerticalLines - 1) {
+                successVertical = true;
+            } else {
+                columnStart = columnEnd + 1;
+            }
+        }
+        ALOGV("Continuing to search for direction 1");
+
+        // If the row search finishes, go out of the loop
+        if (rowEnd >= numHorizontalLines - 1) {
+            success = true;
+        } else {
+            rowStart = rowEnd + 1;
+        }
+    }
+
+    for (int i = 0; i < 4; ++i) {
+        for (int j = 0; j < 6; ++j) {
+            if (mMatchPositions[i][j] != NULL) {
+                ALOGV("Reference Match position for (%d, %d) is (%f, %f)", i, j,
+                     mMatchPositions[i][j]->x(), mMatchPositions[i][j]->y());
+            }
+        }
+    }
+
+    fillRefColorGrid();
+}
+
+// Finds the best match on the MacBeth color checker for the continuous block of
+// detected color checkers bounded by row i1, row i2 and column j1 and column j2
+// Assumes that the subsample is less than 4*6.
+void ColorCheckerTest::findBestMatch(int i1, int i2, int j1, int j2) {
+    int numHorizontalGrid = i2 - i1 + 1;
+    int numVerticalGrid = j2 - j1 + 1;
+
+    if (((numHorizontalGrid > 1) || (numVerticalGrid > 1)) &&
+        (numHorizontalGrid <= 4) && (numVerticalGrid <= 6)) {
+        ALOGV("i1, j2, j1, j2 is %d, %d, %d, %d", i1, i2, j1, j2);
+        float minError;
+        float error = 0.f;
+        int horizontalMatch, verticalMatch;
+
+        // Finds the match start point where the error is minimized.
+        for (int i = 0; i < numHorizontalGrid; ++i) {
+            for (int j = 0; j < numVerticalGrid; ++j) {
+                error += mCandidateColors[i1 + i][j1 + j]->squareDistance<int>(
+                        *mReferenceColors[i][j]);
+            }
+        }
+        ALOGV("Error is %f", error);
+        minError = error;
+        horizontalMatch = 0;
+        verticalMatch = 0;
+
+        for (int i = 0; i <= 4 - numHorizontalGrid; ++i) {
+            for (int j = 0; j <= 6 - numVerticalGrid; ++j) {
+                error = 0.f;
+
+                for (int id = 0; id < numHorizontalGrid; ++id) {
+                    for (int jd = 0; jd < numVerticalGrid; ++jd) {
+                        error += mCandidateColors[i1 + id][j1 + jd]->
+                                squareDistance<int>(
+                                        *mReferenceColors[i + id][j + jd]);
+                    }
+                }
+
+                if (error < minError) {
+                    minError = error;
+                    horizontalMatch = i;
+                    verticalMatch = j;
+                }
+                ALOGV("Processed %d, %d and error is %f", i, j, error );
+            }
+        }
+
+        for (int id = 0; id < numHorizontalGrid; ++id) {
+            for (int jd = 0; jd < numVerticalGrid; ++jd) {
+                mMatchPositions[horizontalMatch + id][verticalMatch + jd] =
+                         new Vec2f(mCandidatePositions[i1 + id][j1 + jd]->x(),
+                                   mCandidatePositions[i1 + id][j1 + jd]->y());
+            }
+        }
+        ALOGV("Grid match starts at %d, %d", horizontalMatch, verticalMatch);
+    }
+}
+
+// Finds the boundary of a color checker by its color similarity to the center.
+// Also predicts the location of unmatched checkers.
+void ColorCheckerTest::fillRefColorGrid() {
+    int rowStart = 0;
+    int columnStart = 0;
+    bool foundStart = true;
+
+    for (int i = 0; (i < 4) && foundStart; ++i) {
+        for (int j = 0; (j < 6) && foundStart; ++j) {
+            if (mMatchPositions[i][j] != NULL) {
+                rowStart = i;
+                columnStart = j;
+                foundStart = false;
+            }
+        }
+    }
+    ALOGV("First match found at (%d, %d)", rowStart, columnStart);
+
+    float rowDistance, columnDistance;
+    rowDistance = 0;
+    columnDistance = 0;
+    int numRowGrids = 0;
+    int numColumnGrids = 0;
+
+    for (int i = rowStart; i < 4; ++i) {
+        for (int j = columnStart; j < 6; ++j) {
+            if (mMatchPositions[i][j] != NULL) {
+                if (i > rowStart) {
+                    ++numRowGrids;
+                    rowDistance += (mMatchPositions[i][j]->x() -
+                                mMatchPositions[rowStart][columnStart]->x()) /
+                                static_cast<float>(i - rowStart);
+                }
+                if (j > columnStart) {
+                    ++numColumnGrids;
+                    columnDistance += (mMatchPositions[i][j]->y() -
+                                mMatchPositions[rowStart][columnStart]->y()) /
+                                static_cast<float>(j - columnStart);
+                }
+            }
+        }
+    }
+
+    if ((numRowGrids > 0) && (numColumnGrids > 0)) {
+        rowDistance = rowDistance / numRowGrids;
+        columnDistance = columnDistance / numColumnGrids;
+        ALOGV("delta is %f, %f", rowDistance, columnDistance);
+
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0 ; j < 6; ++j) {
+                if (mMatchPositions[i][j] == NULL) {
+                    mMatchPositions[i][j] = new Vec2f(
+                            mMatchPositions[rowStart][columnStart]->x() +
+                                    (i - rowStart) * rowDistance,
+                            mMatchPositions[rowStart][columnStart]->y() +
+                                    (j - columnStart) * columnDistance);
+                }
+            }
+        }
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0; j < 6; ++j) {
+                float radius = 0;
+                Vec3i color = mImage->getPixelValue(*mMatchPositions[i][j]);
+                Vec3f meanColor(0.f , 0.f, 0.f);
+
+                int numPixels = 0;
+                for (int ii  = static_cast<int>(mMatchPositions[i][j]->x() -
+                                                rowDistance/2);
+                     ii <= static_cast<int>(mMatchPositions[i][j]->x() +
+                                            rowDistance/2);
+                     ++ii) {
+                    for (int jj = static_cast<int>(mMatchPositions[i][j]->y() -
+                                                   columnDistance/2);
+                         jj <= static_cast<int>(mMatchPositions[i][j]->y() +
+                                                columnDistance/2);
+                         ++jj) {
+                        Vec3i pixelColor = mImage->getPixelValue(ii,jj);
+                        float error = color.squareDistance<int>(pixelColor);
+
+                        if (error < 200.f) {
+                            drawPoint(ii, jj, *mReferenceColors[i][j]);
+                            meanColor = meanColor + pixelColor;
+                            numPixels++;
+                            Vec2i pixelPosition(ii, jj);
+
+                            if (pixelPosition.squareDistance<float>(
+                                    *mMatchPositions[i][j]) > radius) {
+                                radius = pixelPosition.squareDistance<float>(
+                                        *mMatchPositions[i][j]);
+                            }
+                        }
+                    }
+                }
+
+                /** Computes the radius of the checker.
+                 * The above computed radius is the squared distance to the
+                 * furthest point with a matching color. To be conservative, we
+                 * only consider an area with radius half of the above computed
+                 * value. Since radius is computed as a squared root, the one
+                 * that will be recorded is 1/4 of the above computed value.
+                 */
+                mMatchRadius[i][j] = radius / 4.f;
+                mMatchColors[i][j] = new Vec3f(meanColor / numPixels);
+
+                ALOGV("Reference color at (%d, %d) is (%d, %d, %d)", i, j,
+                     mReferenceColors[i][j]->r(),
+                     mReferenceColors[i][j]->g(),
+                     mReferenceColors[i][j]->b());
+                ALOGV("Average color at (%d, %d) is (%f, %f, %f)", i, j,
+                     mMatchColors[i][j]->r(),
+                     mMatchColors[i][j]->g(),
+                     mMatchColors[i][j]->b());
+                ALOGV("Radius is %f", mMatchRadius[i][j]);
+            }
+        }
+
+        mSuccess = true;
+    }
+}
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
index 8cce754..d31bd4a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
@@ -206,7 +206,8 @@
         }
         mCamera.startPreview();
         CameraTests.setCamera(mCamera);
-        //ColorCheckerTest.getSingletonTest().updateCamera();
+
+        ColorCheckerTest.getSingletonTest().updateCamera();
         //WhiteBalanceTest.getSingletonTest().updateCamera();
         //ExposureCompensationTest.getSingletonTest().updateCamera();
         //MeteringTest.getSingletonTest().updateCamera();
@@ -304,10 +305,10 @@
         @Override
         public void onClick(View v) {
             Log.v(TAG, "Running new color checker finding tests!");
-            /*ColorCheckerTest colorCheckerTest = ColorCheckerTest.getSingletonTest();
+            ColorCheckerTest colorCheckerTest = ColorCheckerTest.getSingletonTest();
 
             mCurrentTest = colorCheckerTest;
-            initializeAdapter();*/
+            initializeAdapter();
         }
     };
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java
new file mode 100644
index 0000000..dd2a966
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java
@@ -0,0 +1,293 @@
+/*
+ * 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;
+import android.graphics.BitmapFactory;
+import android.hardware.Camera;
+import android.util.Log;
+import android.widget.ImageView;
+
+import java.util.List;
+
+/** Locates a Xrite Classic Color Checker grid pattern in an image, stores the
+ * center positions and the color checker radius, and provides a function to
+ * get the memory address of these two properties.
+ *
+ * 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 also assumes that the grey squares are in the bottom
+ * row.
+ */
+public class ColorCheckerTest extends CameraTests {
+
+    private static final String TAG = "ColorCheckerTest";
+
+    /** Memory address of the image class instance that contains the image. */
+    private long mClassAddress;
+    /** Memory address of the image test class instance. */
+    private long mTestHandler;
+    /** Thread lock. */
+    private final Object mProcessingImage = new Object();
+    /** Boolean to tell whether auto focus has succeded.*/
+    private boolean mAutoFocusSuccess;
+    /** Boolean to tell whether auto focus is supported.*/
+    private boolean mAutoFocusEnabled = false;
+    /** Singleton instance of the class.*/
+    private static ColorCheckerTest singletonTest = null;
+
+    private boolean mFindCheckerSuccess = false;
+
+    /**
+     * Constructs a <code>ColorCheckerTest</code> instance with a given
+     * Camera pointer.
+     */
+    private ColorCheckerTest() {
+        super();
+    }
+
+    /**
+     * Updates the camera and parameter when the activity switches camera.
+     */
+    public void updateCamera() {
+        Camera.Parameters params = mTestCamera.getParameters();
+        List<String> supportedFocusModes = params.getSupportedFocusModes();
+
+        // Sets camera focus mode to Auto focus if it is supported.
+        if (supportedFocusModes.contains(params.FOCUS_MODE_AUTO)) {
+            Log.v(TAG, "Auto focus possible");
+            params.setFocusMode(params.FOCUS_MODE_AUTO);
+            mTestCamera.setParameters(params);
+            mAutoFocusEnabled = true;
+        } else {
+            mAutoFocusEnabled = false;
+        }
+    }
+
+    public static synchronized ColorCheckerTest getSingletonTest() {
+        if (singletonTest == null) {
+            Log.v(TAG, "Creating a new ColorCheckerTest instance");
+            singletonTest = new ColorCheckerTest();
+            singletonTest.initializeTest();
+        }
+        return singletonTest;
+    }
+
+    private void initializeTest() {
+        // Creates a native test handler with a 120x160 pixel debug output
+        mTestHandler = createColorCheckerTest(120, 160);
+    }
+
+    @Override
+    public synchronized void run(int index) {
+        Log.v(TAG, "ColorCheckerTest thread started!");
+        mAutoFocusSuccess = false;
+        mFindCheckerSuccess = false;
+        // Sets camera focus mode to Auto focus if it is supported.
+        if (mAutoFocusEnabled) {
+            while (!mAutoFocusSuccess) {
+                // Starts the auto focus process of the camera.
+                mTestCamera.autoFocus(mAutoFocusListener);
+
+                // Locks thread until the camera finishes taking picture.
+                synchronized (mProcessingImage) {
+                    try{
+                        Log.v(TAG, "Start waiting for Image");
+                        mProcessingImage.wait();
+                    } catch (InterruptedException e) {
+                        Log.v(TAG, "Callback wait fails!");
+                    }
+                }
+            }
+        } else {
+            mTestCamera.takePicture(null, null, null, mTestJpegListener);
+            synchronized (mProcessingImage) {
+                try{
+                    Log.v(TAG, "Start waiting for Image");
+                    mProcessingImage.wait();
+                } catch (InterruptedException e) {
+                    Log.v(TAG, "Callback wait fails!");
+                }
+            }
+        }
+
+        // Launches the native method to find the color checker in the image.
+        mFindCheckerSuccess = processColorCheckerTest(mTestHandler);
+        // Displays the debug output from the native test handler instance.
+        displayHandlerDebugOutput(mTestHandler);
+
+        Log.v(TAG, "Callback has returned!");
+    }
+
+    private Camera.AutoFocusCallback mAutoFocusListener = new Camera.AutoFocusCallback() {
+        public void onAutoFocus(boolean mSuccess, Camera mCamera) {
+            if (mSuccess) {
+                mAutoFocusSuccess = true;
+                Log.v(TAG, "Autofocus success!");
+                mCamera.takePicture(null, null, null, mTestJpegListener);
+            } else {
+                try{
+                    Log.v(TAG, "Autofocus failed. Please adjust!");
+                    Thread.sleep(4000);
+                    Log.v(TAG, "END Waiting");
+                } catch (InterruptedException e){}
+
+                synchronized (mProcessingImage) {
+                    mProcessingImage.notifyAll();
+                }
+            }
+        }
+    };
+
+    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
+        public void onPictureTaken(byte[] data, Camera mCamera) {
+            Log.v(TAG, "Shutter pressed down!");
+
+            // Changes the focus mode to fixed to avoid focus shift after
+            // auto focus is successful.
+            //Camera.Parameters params = mCamera.getParameters();
+            //params.setFocusMode(params.FOCUS_MODE_FIXED);
+            //mCamera.setParameters(params);
+
+            // Decodes the camera data to Bitmap and creates a native image
+            // class with the Bitmap.
+            Bitmap inputImage;
+            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
+            long bufferAddress = findNative(inputImage);
+            Log.v(TAG, "findNative method finishes");
+
+            // Cleans up the Bitmap memory space.
+            inputImage.recycle();
+            data = null;
+            inputImage = null;
+            System.gc();
+
+            // Constructs a test handler class to handle the image.
+            createColorCheckerClass(bufferAddress, mTestHandler);
+
+            mCamera.startPreview();
+
+            // Notifies the thread lock the image capture is done.
+            synchronized (mProcessingImage) {
+                mProcessingImage.notifyAll();
+            }
+        }
+    };
+
+    /**
+     * Overrides the base class method and use the memory addresses of the
+     * checker centers and radius computed by the native test handler class
+     * to update the values stored in the base class.
+     *
+     * @return <code>true</code> indicating a memory address upload is needed.
+     */
+    @Override
+    public boolean copyCheckerAddress() {
+        if (mFindCheckerSuccess) {
+            setCheckerAddress(getColorCheckerCenterAdd(mTestHandler),
+                              getColorCheckerRadiusAdd(mTestHandler));
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public void cleanUp() {
+        cleanUpHandler(mTestHandler);
+    }
+
+    @Override
+    public String getTestName() {
+        return "Color Checker test: \n";
+    }
+
+    @Override
+    public String getTestName(int index) {
+        return "Find color checker";
+    }
+
+    @Override
+    public String getResult(int index) {
+        if (mFindCheckerSuccess) {
+          return "Passed";
+        } else {
+          return "Failed";
+        }
+    }
+
+    @Override
+    public int getNumTests() {
+        return 1;
+    }
+
+    /**
+     * Gets the memory address of the vector storing the color checker centers
+     * from the native test handler instance.
+     *
+     * @param handlerAddress the memory address of the native test handler
+     * instance
+     *
+     * @return memory address of the native vector storing the color checker
+     * centers' coordinates
+     */
+    private native long getColorCheckerRadiusAdd(long handlerAddress);
+
+    /**
+     * Gets the memory address of the vector storing the color checker radius
+     * from the native test handler instance.
+     *
+     * @param handlerAddress the memory address of the native test handler
+     * instance.
+     *
+     * @return memory address of the native vector storing the color checker
+     * centers' coordinates
+     */
+    private native long getColorCheckerCenterAdd(long handlerAddress);
+
+    /**
+     * Creates a native color checker test handler instance.
+     *
+     * @param outputWidth the desired width for the debug output
+     * @param outputHeight the desired height of the debug output
+     *
+     * @return memory address of the native test handler instance
+     */
+    private native long createColorCheckerTest(int outputWidth, int outputHeight);
+
+    /**
+     * Loads a native image class instances and extracts data from it to add
+     * to the test handler.
+     *
+     * @param bufferAddress the memory address of the image class instance
+     * @param handlerAddress the memory address of the test handler instance
+     */
+    private native void createColorCheckerClass(long bufferAddress, long handlerAddress);
+
+    /**
+     * Processes the data in the native test handler instance. Computes test
+     * results with all the data and construct a debug image or debug text
+     * outputs.
+     *
+     * @param handlerAddress the memory address of the test handler instance
+     */
+    private native boolean processColorCheckerTest(long handlerAddress);
+
+    static {
+        System.loadLibrary("cameraanalyzer");
+    }
+}
