/*
 * 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;
const float COLOR_ERROR_THRESHOLD = 200.f;
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 {
        ALOGE("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 numHorizontalLines = mCandidateColors.size();
    int numVerticalLines;
    if (numHorizontalLines > 0) {
        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];
                }
            }
            mCandidateColors[i].clear();
            mCandidatePositions[i].clear();
        }
    }
    mCandidateColors.clear();
    mCandidatePositions.clear();

    ALOGV("Candidates deleted!");

    numVerticalLines = verticalLines.size();
    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);
                ALOGV("Color at (%d, %d) is (%d, %d, %d)", j, i,color->r(), color->g(), color->b());

            } else {
                mCandidatePositions[j].push_back(NULL);
                mCandidateColors[j].push_back(NULL);
                delete color;
                delete pointCenter;
            }
        }
    }

    ALOGV("Candidates Number (%d, %d)", mCandidateColors.size(), mCandidateColors[0].size());
    // 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()) ||
        (std::abs(pointUpperLeft.x() - pointBottomRight.x()) <= 5) ||
        (std::abs(pointUpperLeft.y() - pointBottomRight.y()) <= 5) ||
        (std::abs(pointUpperLeft.x() - pointBottomRight.x()) >= 30) ||
        (std::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) {
                if (mCandidateColors[i1 + i][j1 + j] != NULL) {
                    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) {
                        if (mCandidateColors[i1 + id][j1 + jd] != NULL) {
                            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) {
                if (mCandidatePositions[i1 + id][j1 + jd] != NULL) {
                    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) {
                        if ((ii >= 0) && (ii < mImage->getHeight()) &&
                            (jj >= 0) && (jj < mImage->getWidth())) {
                            Vec3i pixelColor = mImage->getPixelValue(ii,jj);
                            float error = color.squareDistance<int>(pixelColor);

                            if (error < COLOR_ERROR_THRESHOLD) {
                                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;
    }
}
