// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/test/pixel_comparator.h"

#include <algorithm>

#include "base/logging.h"
#include "ui/gfx/geometry/rect.h"

namespace cc {

ExactPixelComparator::ExactPixelComparator(const bool discard_alpha)
    : discard_alpha_(discard_alpha) {
}

bool ExactPixelComparator::Compare(const SkBitmap& actual_bmp,
                                   const SkBitmap& expected_bmp) const {
  // Number of pixels with an error
  int error_pixels_count = 0;

  gfx::Rect error_bounding_rect = gfx::Rect();

  // Check that bitmaps have identical dimensions.
  DCHECK(actual_bmp.width() == expected_bmp.width() &&
         actual_bmp.height() == expected_bmp.height());

  SkAutoLockPixels lock_actual_bmp(actual_bmp);
  SkAutoLockPixels lock_expected_bmp(expected_bmp);

  for (int x = 0; x < actual_bmp.width(); ++x) {
    for (int y = 0; y < actual_bmp.height(); ++y) {
      SkColor actual_color = actual_bmp.getColor(x, y);
      SkColor expected_color = expected_bmp.getColor(x, y);
      if (discard_alpha_) {
        actual_color = SkColorSetA(actual_color, 0);
        expected_color = SkColorSetA(expected_color, 0);
      }
      if (actual_color != expected_color) {
        ++error_pixels_count;
        error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
      }
    }
  }

  if (error_pixels_count != 0) {
    LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count;
    LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
    return false;
  }

  return true;
}

FuzzyPixelComparator::FuzzyPixelComparator(
    const bool discard_alpha,
    const float error_pixels_percentage_limit,
    const float small_error_pixels_percentage_limit,
    const float avg_abs_error_limit,
    const int max_abs_error_limit,
    const int small_error_threshold)
    : discard_alpha_(discard_alpha),
      error_pixels_percentage_limit_(error_pixels_percentage_limit),
      small_error_pixels_percentage_limit_(small_error_pixels_percentage_limit),
      avg_abs_error_limit_(avg_abs_error_limit),
      max_abs_error_limit_(max_abs_error_limit),
      small_error_threshold_(small_error_threshold) {
}

bool FuzzyPixelComparator::Compare(const SkBitmap& actual_bmp,
                                   const SkBitmap& expected_bmp) const {
  // Number of pixels with an error
  int error_pixels_count = 0;
  // Number of pixels with a small error
  int small_error_pixels_count = 0;
  // The per channel sums of absolute errors over all pixels.
  int64 sum_abs_error_r = 0;
  int64 sum_abs_error_g = 0;
  int64 sum_abs_error_b = 0;
  int64 sum_abs_error_a = 0;
  // The per channel maximum absolute errors over all pixels.
  int max_abs_error_r = 0;
  int max_abs_error_g = 0;
  int max_abs_error_b = 0;
  int max_abs_error_a = 0;

  gfx::Rect error_bounding_rect = gfx::Rect();

  // Check that bitmaps have identical dimensions.
  DCHECK(actual_bmp.width() == expected_bmp.width() &&
         actual_bmp.height() == expected_bmp.height());

  // Check that bitmaps are not empty.
  DCHECK(actual_bmp.width() > 0 && actual_bmp.height() > 0);

  SkAutoLockPixels lock_actual_bmp(actual_bmp);
  SkAutoLockPixels lock_expected_bmp(expected_bmp);

  for (int x = 0; x < actual_bmp.width(); ++x) {
    for (int y = 0; y < actual_bmp.height(); ++y) {
      SkColor actual_color = actual_bmp.getColor(x, y);
      SkColor expected_color = expected_bmp.getColor(x, y);
      if (discard_alpha_) {
        actual_color = SkColorSetA(actual_color, 0);
        expected_color = SkColorSetA(expected_color, 0);
      }

      if (actual_color != expected_color) {
        ++error_pixels_count;

        // Compute per channel errors
        int error_r = SkColorGetR(actual_color) - SkColorGetR(expected_color);
        int error_g = SkColorGetG(actual_color) - SkColorGetG(expected_color);
        int error_b = SkColorGetB(actual_color) - SkColorGetB(expected_color);
        int error_a = SkColorGetA(actual_color) - SkColorGetA(expected_color);
        int abs_error_r = std::abs(error_r);
        int abs_error_g = std::abs(error_g);
        int abs_error_b = std::abs(error_b);
        int abs_error_a = std::abs(error_a);

        // Increment small error counter if error is below threshold
        if (abs_error_r <= small_error_threshold_ &&
            abs_error_g <= small_error_threshold_ &&
            abs_error_b <= small_error_threshold_ &&
            abs_error_a <= small_error_threshold_)
          ++small_error_pixels_count;

        // Update per channel maximum absolute errors
        max_abs_error_r = std::max(max_abs_error_r, abs_error_r);
        max_abs_error_g = std::max(max_abs_error_g, abs_error_g);
        max_abs_error_b = std::max(max_abs_error_b, abs_error_b);
        max_abs_error_a = std::max(max_abs_error_a, abs_error_a);

        // Update per channel absolute error sums
        sum_abs_error_r += abs_error_r;
        sum_abs_error_g += abs_error_g;
        sum_abs_error_b += abs_error_b;
        sum_abs_error_a += abs_error_a;
      }
    }
  }

  // Compute error metrics from collected data
  int pixels_count = actual_bmp.width() * actual_bmp.height();
  float error_pixels_percentage = 0.0f;
  float small_error_pixels_percentage = 0.0f;
  if (pixels_count > 0) {
    error_pixels_percentage = static_cast<float>(error_pixels_count) /
        pixels_count * 100.0f;
    small_error_pixels_percentage =
        static_cast<float>(small_error_pixels_count) / pixels_count * 100.0f;
  }
  float avg_abs_error_r = 0.0f;
  float avg_abs_error_g = 0.0f;
  float avg_abs_error_b = 0.0f;
  float avg_abs_error_a = 0.0f;
  if (error_pixels_count > 0) {
    avg_abs_error_r = static_cast<float>(sum_abs_error_r) / error_pixels_count;
    avg_abs_error_g = static_cast<float>(sum_abs_error_g) / error_pixels_count;
    avg_abs_error_b = static_cast<float>(sum_abs_error_b) / error_pixels_count;
    avg_abs_error_a = static_cast<float>(sum_abs_error_a) / error_pixels_count;
  }

  if (error_pixels_percentage > error_pixels_percentage_limit_ ||
      small_error_pixels_percentage > small_error_pixels_percentage_limit_ ||
      avg_abs_error_r > avg_abs_error_limit_ ||
      avg_abs_error_g > avg_abs_error_limit_ ||
      avg_abs_error_b > avg_abs_error_limit_ ||
      avg_abs_error_a > avg_abs_error_limit_ ||
      max_abs_error_r > max_abs_error_limit_ ||
      max_abs_error_g > max_abs_error_limit_ ||
      max_abs_error_b > max_abs_error_limit_ ||
      max_abs_error_a > max_abs_error_limit_) {
    LOG(ERROR) << "Percentage of pixels with an error: "
               << error_pixels_percentage;
    LOG(ERROR) << "Percentage of pixels with errors not greater than "
               << small_error_threshold_ << ": "
               << small_error_pixels_percentage;
    LOG(ERROR) << "Average absolute error (excluding identical pixels): "
               << "R=" << avg_abs_error_r << " "
               << "G=" << avg_abs_error_g << " "
               << "B=" << avg_abs_error_b << " "
               << "A=" << avg_abs_error_a;
    LOG(ERROR) << "Largest absolute error: "
               << "R=" << max_abs_error_r << " "
               << "G=" << max_abs_error_g << " "
               << "B=" << max_abs_error_b << " "
               << "A=" << max_abs_error_a;

      for (int x = 0; x < actual_bmp.width(); ++x) {
        for (int y = 0; y < actual_bmp.height(); ++y) {
          SkColor actual_color = actual_bmp.getColor(x, y);
          SkColor expected_color = expected_bmp.getColor(x, y);
          if (discard_alpha_) {
            actual_color = SkColorSetA(actual_color, 0);
            expected_color = SkColorSetA(expected_color, 0);
          }
          if (actual_color != expected_color)
            error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
        }
      }
      LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
    return false;
  } else {
    return true;
  }
}

}  // namespace cc
