Included new base classes for Camera Analyzer.

- Vec2 class is the class to represent coordinates.
- Vec3 class is the class to represent pixel value. TestingImage class is the
class to represent an input image.

Change-Id: Ia57ebb9837327e2bdac46b6836b56fae960800c1
diff --git a/apps/CtsVerifier/include/colorchecker/testingimage.h b/apps/CtsVerifier/include/colorchecker/testingimage.h
new file mode 100644
index 0000000..f9649d5
--- /dev/null
+++ b/apps/CtsVerifier/include/colorchecker/testingimage.h
@@ -0,0 +1,69 @@
+/*
+ * 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 TESTINGIMAGE_H
+#define TESTINGIMAGE_H
+
+#include <vector>
+#include "vec3.h"
+#include "vec2.h"
+
+// Implements a class for image representation.
+class TestingImage {
+  public:
+    // Constructs a new instance with the inputImage's row and column counts.
+    // No change in size.
+    TestingImage(const unsigned char* inputImage,
+                 int inputWidth, int inputHeight,
+                 int inputChannels, int inputRowSpan);
+    // Constructs a new instance with an inputImage but resize it to a given
+    // new size.
+    TestingImage(const unsigned char* inputImage,
+                 int inputHeight, int inputWidth,
+                 int inputChannel, int inputRowSpan,
+                 int newHeight, int newWidth);
+    virtual ~TestingImage();
+
+    // Reads the pixel value of a given location.
+    int getPixelValue(int row, int column, int channel) const;
+    Vec3i getPixelValue(int row, int column) const;
+    Vec3i getPixelValue(const Vec2i &pixelPosition) const;
+    Vec3i getPixelValue(const Vec2f &pixelPosition) const;
+
+    inline const unsigned char* getImage() const { return mImage; }
+    inline int getWidth() const { return mWidth; }
+    inline int getHeight() const { return mHeight; }
+    inline int getChannels() const { return mChannels; }
+    inline int getRowSpan() const { return mRowSpan; }
+
+    // Reads the colors of a color checker in the image with the given checker
+    // coordinates including centers and radius.
+    const std::vector<Vec3f>* getColorChecker(
+            int rowStart, int rowEnd, int columnStart, int columnEnd,
+            const std::vector<std::vector< Vec2f > >* centerAddress,
+            const std::vector<std::vector< float > >* radiusAddress) const;
+
+    // Computes the luminance value of a color image.
+    bool rgbToGrayScale(unsigned char* grayLayer) const;
+
+  private:
+    unsigned char* mImage;
+    int mWidth;
+    int mHeight;
+    int mRowSpan;
+    int mChannels;
+};
+
+#endif
diff --git a/apps/CtsVerifier/include/colorchecker/vec2.h b/apps/CtsVerifier/include/colorchecker/vec2.h
new file mode 100644
index 0000000..9de614c
--- /dev/null
+++ b/apps/CtsVerifier/include/colorchecker/vec2.h
@@ -0,0 +1,77 @@
+/*
+ * 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 VEC2_H
+#define VEC2_H
+
+#include <assert.h>
+#include <cmath>
+
+// Implements a class to represent the location of a pixel.
+template <class T>
+class Vec2{
+  public:
+    Vec2(T inputX, T inputY) {
+        mX = inputX;
+        mY = inputY;
+    }
+
+    Vec2() {}
+
+    inline Vec2<T> operator+ (const Vec2<T> &param) const {
+        Vec2<T> temp(mX + param.x(), mY + param.y());
+        return temp;
+    }
+
+    inline Vec2<T> operator- (const Vec2<T> &param) const {
+        Vec2<T> temp(mX - param.x(), mY - param.y());
+        return temp;
+    }
+
+    inline Vec2<float> operator/ (const int param) const {
+        Vec2<float> temp();
+        assert(param != 0);
+        temp.set(static_cast<float>(mX) / static_cast<float>(param),
+                 static_cast<float>(mY) / static_cast<float>(param));
+
+        return temp;
+    }
+
+    template <class U>
+    float squareDistance(const Vec2<U> &param) const {
+        int difference = 0.f;
+        difference = (static_cast<float>(mX) - static_cast<float>(param.x())) *
+              (static_cast<float>(mX) - static_cast<float>(param.x())) +
+              (static_cast<float>(mY) - static_cast<float>(param.y())) *
+              (static_cast<float>(mY) - static_cast<float>(param.y()));
+        return difference;
+    }
+
+    inline T x() const { return mX; }
+    inline T y() const { return mY; }
+
+    inline void set(const T inputX, const T inputY) {
+        mX = inputX;
+        mY = inputY;
+    }
+
+  private:
+    T mX;
+    T mY;
+};
+
+typedef Vec2<int> Vec2i;
+typedef Vec2<float> Vec2f;
+#endif
diff --git a/apps/CtsVerifier/include/colorchecker/vec3.h b/apps/CtsVerifier/include/colorchecker/vec3.h
new file mode 100644
index 0000000..1d48188
--- /dev/null
+++ b/apps/CtsVerifier/include/colorchecker/vec3.h
@@ -0,0 +1,116 @@
+/*
+ * 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 VEC3_H
+#define VEC3_H
+
+#include <assert.h>
+#include <cmath>
+
+// Implementes a class to represent the pixel value in a 3-dimensional color
+// space. The colors are all represented by int as it is mostly used as RGB.
+template <class T>
+class Vec3{
+  public:
+    Vec3(T inputRed, T inputGreen, T inputBlue) {
+        mRed = inputRed;
+        mGreen = inputGreen;
+        mBlue = inputBlue;
+    }
+
+    Vec3() {}
+
+    template <class U>
+    inline Vec3<T> operator+ (const Vec3<U> &param) const {
+        Vec3<T> temp(mRed + param.r(), mGreen + param.g(), mBlue + param.b());
+        return temp;
+    }
+
+    inline Vec3<T> operator- (const Vec3<T> &param) const {
+        Vec3<T> temp(mRed - param.r(), mGreen - param.g(), mBlue - param.b());
+        return temp;
+    }
+
+    inline Vec3<T> operator* (const int param) const {
+        Vec3<T> temp(mRed * param, mGreen * param, mBlue * param);
+        return temp;
+    }
+
+    template <class U>
+    inline Vec3<float> operator* (const Vec3<U> &param) const {
+        Vec3<float> temp(mRed * static_cast<U>(param.r()),
+                         mGreen * static_cast<U>(param.g()),
+                         mBlue * static_cast<U>(param.b()));
+        return temp;
+    }
+
+
+    inline Vec3<float> operator/ (const int param) const {
+        Vec3<float> temp;
+        assert(param != 0);
+        temp.set(static_cast<float>(mRed) / static_cast<float>(param),
+                 static_cast<float>(mGreen) / static_cast<float>(param),
+                 static_cast<float>(mBlue) / static_cast<float>(param));
+        return temp;
+    }
+
+    template <class U>
+    inline Vec3<float> operator/ (const Vec3<U> &param) const {
+        Vec3<float> temp;
+        assert((param.r() != 0.f) && (param.g() != 0.f) && (param.b() != 0.f));
+        temp.set(static_cast<float>(mRed) / static_cast<float>(param.r()),
+                 static_cast<float>(mGreen) / static_cast<float>(param.g()),
+                 static_cast<float>(mBlue) / static_cast<float>(param.b()));
+        return temp;
+    }
+
+    template <class U>
+    float squareDistance(const Vec3<U> &param) const {
+        float difference = 0.f;
+        difference = static_cast<float>(mRed - param.r()) *
+                static_cast<float>(mRed - param.r()) +
+                static_cast<float>(mGreen - param.g()) *
+                static_cast<float>(mGreen - param.g()) +
+                static_cast<float>(mBlue - param.b()) *
+                static_cast<float>(mBlue - param.b());
+        return difference;
+    }
+
+    // Assumes conversion from sRGB to luminance.
+    float convertToLuminance() const {
+        return (0.299 * static_cast<float>(mRed) +
+                0.587 * static_cast<float>(mGreen) +
+                0.114 * static_cast<float>(mBlue));
+    }
+
+    inline T r() const { return mRed; }
+    inline T g() const { return mGreen; }
+    inline T b() const { return mBlue; }
+
+    inline void set(const T inputRed, const T inputGreen, const T inputBlue){
+        mRed = inputRed;
+        mGreen = inputGreen;
+        mBlue = inputBlue;
+    }
+
+  private:
+    T mRed;
+    T mGreen;
+    T mBlue;
+};
+
+typedef Vec3<int> Vec3i;
+typedef Vec3<float> Vec3f;
+#endif
diff --git a/apps/CtsVerifier/lib/colorchecker/Android.mk b/apps/CtsVerifier/lib/colorchecker/Android.mk
index 8d0a741..fcd51c4 100644
--- a/apps/CtsVerifier/lib/colorchecker/Android.mk
+++ b/apps/CtsVerifier/lib/colorchecker/Android.mk
@@ -24,10 +24,10 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libcolorchecker
 
-LOCAL_SRC_FILES += #testingimage.cpp \
+LOCAL_SRC_FILES += testingimage.cpp \
                    vec3.cpp \
                    vec2.cpp \
-                   imagetesthandler.cpp \
+                   #imagetesthandler.cpp \
                    whitebalancetest.cpp \
                    colorcheckertest.cpp \
                    exposurecompensationtest.cpp \
diff --git a/apps/CtsVerifier/lib/colorchecker/testingimage.cpp b/apps/CtsVerifier/lib/colorchecker/testingimage.cpp
new file mode 100644
index 0000000..30725ec
--- /dev/null
+++ b/apps/CtsVerifier/lib/colorchecker/testingimage.cpp
@@ -0,0 +1,186 @@
+/*
+ * 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 "TestingImage"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+#include <string.h>
+#include <cmath>
+#include <vector>
+#include "vec3.h"
+
+#include "testingimage.h"
+
+const float GAMMA_CORRECTION = 2.2f;
+
+// Constructs an instance with the given image byte array.
+TestingImage::TestingImage(const unsigned char* inputImage,
+                           int inputHeight, int inputWidth,
+                           int inputChannel, int inputRowSpan) {
+    mImage = new unsigned char[inputRowSpan * inputHeight];
+
+    ALOGV("mImage format created! with size as %d, %d, %d",
+         inputRowSpan, inputHeight, inputChannel);
+    mWidth = inputWidth;
+    mHeight = inputHeight;
+    mChannels = inputChannel;
+    mRowSpan = mWidth * mChannels;
+
+    for (int i = 0; i < mHeight; ++i) {
+        for (int j = 0; j < mWidth; ++j) {
+            for (int k = 0; k < mChannels; ++k) {
+                mImage[i * mRowSpan + j* mChannels + k] =
+                        inputImage[i * inputRowSpan + j * inputChannel + k];
+            }
+        }
+    }
+    ALOGV("mImage converted!");
+}
+
+// Constructs an instance with the given image and resize it to a new size.
+TestingImage::TestingImage(const unsigned char* inputImage,
+                           int inputHeight, int inputWidth,
+                           int inputChannel, int inputRowSpan,
+                           int newHeight, int newWidth) {
+    mImage = new unsigned char[newHeight * newWidth * inputChannel];
+
+    ALOGV("mImage format created! with size as %d, %d, %d",
+         newHeight, newWidth, inputChannel);
+    mHeight = newHeight;
+    mWidth = newWidth;
+    mChannels = inputChannel;
+    mRowSpan = mWidth * mChannels;
+
+    // Computes how many pixels in the original image corresponds to one pixel
+    // in the new image.
+    int heightScale = inputHeight / newHeight;
+    int widthScale = inputWidth / newWidth;
+
+    // Average the corresponding pixels in the original image to compute the
+    // pixel value of the new image.
+    for (int i = 0; i < mHeight; ++i) {
+        for (int j = 0; j < mWidth; ++j) {
+            for (int k = 0; k < mChannels; ++k) {
+                int pixelValue = 0;
+
+                for (int l = 0; l < heightScale; ++l) {
+                    for (int m = 0; m < widthScale; ++m) {
+                        pixelValue += inputImage[
+                                (i * heightScale + l) * inputRowSpan
+                                + (j * widthScale + m) * inputChannel + k];
+                    }
+                }
+                pixelValue = pixelValue / (heightScale * widthScale);
+                mImage[i * mRowSpan + j * mChannels + k] =
+                        (unsigned char) pixelValue;
+            }
+        }
+    }
+}
+
+TestingImage::~TestingImage() {
+    if (mImage!=NULL) {
+        delete[] mImage;
+    }
+}
+
+int TestingImage::getPixelValue(int row, int column, int channel) const {
+    return (int)mImage[row * mRowSpan + column * mChannels + channel];
+}
+
+Vec3i TestingImage::getPixelValue(int row, int column) const {
+    Vec3i current_color(getPixelValue(row, column, 0),
+                        getPixelValue(row, column, 1),
+                        getPixelValue(row, column, 2));
+    return current_color;
+}
+
+Vec3i TestingImage::getPixelValue(const Vec2i &pixelPosition) const {
+    return getPixelValue(pixelPosition.x(), pixelPosition.y());
+}
+
+Vec3i TestingImage::getPixelValue(const Vec2f &pixelPosition) const {
+    return getPixelValue(static_cast<int>(pixelPosition.x()),
+                         static_cast<int>(pixelPosition.y()));
+}
+
+// Returns a vector of the colors in the requested block of color checkers.
+// The vector is formatted by going through the block from left to right and
+// from top to bottom.
+const std::vector<Vec3f>* TestingImage::getColorChecker(
+      int rowStart, int rowEnd, int columnStart, int columnEnd,
+      const std::vector<std::vector< Vec2f > >* centerAddress,
+      const std::vector<std::vector< float > >* radiusAddress) const {
+    std::vector<Vec3f>* checkerColors = new std::vector<Vec3f>;
+
+    // Average the pixel values of the pixels within the given radius to the
+    // given center position.
+    for (int i = rowStart; i < rowEnd; ++i) {
+        for (int j = columnStart; j < columnEnd; ++j) {
+            float radius = sqrt((*radiusAddress)[i][j]);
+            Vec2f center((*centerAddress)[i][j].x(),
+                               (*centerAddress)[i][j].y());
+            Vec3f meanColor(0.f, 0.f, 0.f);
+            int numPixels = 0;
+
+            for (int ii = static_cast<int>(center.x() - radius);
+                 ii < static_cast<int>(center.x() + radius); ++ii) {
+                for (int jj = static_cast<int>(center.y() - radius);
+                     jj < static_cast<int>(center.y() + radius); ++jj) {
+
+                    Vec2i pixelPosition(ii,jj);
+                    if (pixelPosition.squareDistance<float>(center) <
+                        (*radiusAddress)[i][j]) {
+                        meanColor = meanColor + getPixelValue(pixelPosition);
+                        ++numPixels;
+                    }
+                }
+            }
+            meanColor = meanColor / numPixels;
+            checkerColors->push_back(meanColor);
+        }
+    }
+
+    return checkerColors;
+}
+
+bool TestingImage::rgbToGrayScale(unsigned char* grayLayer) const {
+    if (mChannels == 4) {
+        for (int i = 0; i < mWidth; i++) {
+            for (int j = 0; j < mHeight; j++) {
+                float redLinear = pow(getPixelValue(j, i, 0),
+                                       GAMMA_CORRECTION);
+                float greenLinear = pow(getPixelValue(j,i,1),
+                                         GAMMA_CORRECTION);
+                float blueLinear = pow(getPixelValue(j,i,2),
+                                        GAMMA_CORRECTION);
+
+                // Computes the luminance value
+                grayLayer[j * mWidth + i] =
+                        (unsigned char)((int)pow((0.299f * redLinear
+                                                  + 0.587f * greenLinear
+                                                  + 0.114f * blueLinear),
+                                                  1/GAMMA_CORRECTION));
+            }
+        }
+
+        return true;
+    } else {
+
+        return false;
+    }
+}
diff --git a/apps/CtsVerifier/lib/colorchecker/vec2.cpp b/apps/CtsVerifier/lib/colorchecker/vec2.cpp
new file mode 100644
index 0000000..29736bb
--- /dev/null
+++ b/apps/CtsVerifier/lib/colorchecker/vec2.cpp
@@ -0,0 +1,22 @@
+/*
+ * 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 "Vec2"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#include "vec2.h"
diff --git a/apps/CtsVerifier/lib/colorchecker/vec3.cpp b/apps/CtsVerifier/lib/colorchecker/vec3.cpp
new file mode 100644
index 0000000..ac16620
--- /dev/null
+++ b/apps/CtsVerifier/lib/colorchecker/vec3.cpp
@@ -0,0 +1,22 @@
+/*
+ * 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 "Vec3"
+#include <utils/Log.h>
+#include <utils/Timers.h>
+
+#include "vec3.h"