// Copyright 2011 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file input format is based loosely on
// Tools/DumpRenderTree/ImageDiff.m

// The exact format of this tool's output to stdout is important, to match
// what the run-webkit-tests script expects.

#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/numerics/safe_conversions.h"
#include "core/fxcrt/span_io.h"
#include "testing/png_codec/png_codec.h"
#include "testing/utils/path_service.h"
#include "testing/utils/pixel_diff_util.h"

#if BUILDFLAG(IS_WIN)
#include <windows.h>
#endif

// Return codes used by this utility.
constexpr int kStatusSame = 0;
constexpr int kStatusDifferent = 1;
constexpr int kStatusError = 2;

// Color codes.
constexpr uint32_t RGBA_RED = 0x000000ff;
constexpr uint32_t RGBA_ALPHA = 0xff000000;

class Image {
 public:
  Image() = default;
  Image(int w, int h)
      : w_(w), h_(h), data_(static_cast<size_t>(w) * h * 4, 0) {}
  Image(const Image& image) = default;
  Image& operator=(const Image& other) = default;

  bool has_image() const { return w_ > 0 && h_ > 0; }
  int w() const { return w_; }
  int h() const { return h_; }
  pdfium::span<const uint8_t> span() const { return data_; }

  // Creates the image from the given filename on disk, and returns true on
  // success.
  bool CreateFromFilename(const std::string& path) {
    return CreateFromFilenameImpl(path, /*reverse_byte_order=*/false);
  }

  // Same as CreateFromFilename(), but with BGRA instead of RGBA ordering.
  bool CreateFromFilenameWithReverseByteOrder(const std::string& path) {
    return CreateFromFilenameImpl(path, /*reverse_byte_order=*/true);
  }

  void Clear() {
    w_ = h_ = 0;
    data_.clear();
  }

  // Returns the RGBA value of the pixel at the given location
  uint32_t pixel_at(int x, int y) const {
    if (!pixel_in_bounds(x, y)) {
      return 0;
    }
    return *reinterpret_cast<const uint32_t*>(&(data_[pixel_address(x, y)]));
  }

  void set_pixel_at(int x, int y, uint32_t color) {
    if (!pixel_in_bounds(x, y)) {
      return;
    }

    void* addr = &data_[pixel_address(x, y)];
    *reinterpret_cast<uint32_t*>(addr) = color;
  }

 private:
  bool CreateFromFilenameImpl(const std::string& path,
                              bool reverse_byte_order) {
    FILE* f = fopen(path.c_str(), "rb");
    if (!f) {
      return false;
    }

    std::vector<uint8_t> compressed;
    const size_t kBufSize = 1024;
    uint8_t buf[kBufSize];
    while (true) {
      auto read_span = fxcrt::spanread(buf, f);
      if (read_span.empty()) {
        break;
      }
      compressed.insert(compressed.end(), read_span.begin(), read_span.end());
    }

    fclose(f);

    data_ = png_codec::Decode(compressed, reverse_byte_order, &w_, &h_);
    if (data_.empty()) {
      Clear();
      return false;
    }
    return true;
  }

  bool pixel_in_bounds(int x, int y) const {
    return x >= 0 && x < w_ && y >= 0 && y < h_;
  }

  size_t pixel_address(int x, int y) const { return (y * w_ + x) * 4; }

  // Pixel dimensions of the image.
  int w_ = 0;
  int h_ = 0;

  std::vector<uint8_t> data_;
};

float CalculateDifferencePercentage(const Image& actual, int pixels_different) {
  // Like the WebKit ImageDiff tool, we define percentage different in terms
  // of the size of the 'actual' bitmap.
  float total_pixels =
      static_cast<float>(actual.w()) * static_cast<float>(actual.h());
  if (total_pixels == 0) {
    // When the bitmap is empty, they are 100% different.
    return 100.0f;
  }
  return 100.0f * pixels_different / total_pixels;
}

void CountImageSizeMismatchAsPixelDifference(const Image& baseline,
                                             const Image& actual,
                                             int* pixels_different) {
  int w = std::min(baseline.w(), actual.w());
  int h = std::min(baseline.h(), actual.h());

  // Count pixels that are a difference in size as also being different.
  int max_w = std::max(baseline.w(), actual.w());
  int max_h = std::max(baseline.h(), actual.h());
  // These pixels are off the right side, not including the lower right corner.
  *pixels_different += (max_w - w) * h;
  // These pixels are along the bottom, including the lower right corner.
  *pixels_different += (max_h - h) * max_w;
}

// Optional per-comparison measurements, reported by `--metrics`.
struct DiffMetrics {
  int raw_diff_pixels = 0;
  uint8_t max_delta = 0;
  double mse = 0.0;
  double win_mse = 0.0;
  double mean_ssim = 1.0;
  double min_window_ssim = 1.0;
};

// Computes the number of differing pixels. When `out_metrics` is non-null,
// the underlying measurements are gathered as well, at additional cost.
int PixelsDifferent(const Image& baseline,
                    const Image& actual,
                    DiffMetrics* out_metrics) {
  int w = std::min(baseline.w(), actual.w());
  int h = std::min(baseline.h(), actual.h());

  uint8_t max_delta = 0;
  int pixels_different = 0;
  uint64_t total_squared_error = 0;
  for (int y = 0; y < h; ++y) {
    for (int x = 0; x < w; ++x) {
      const uint32_t baseline_pixel = baseline.pixel_at(x, y);
      const uint32_t actual_pixel = actual.pixel_at(x, y);
      if (baseline_pixel == actual_pixel) {
        continue;
      }

      ++pixels_different;
      max_delta = std::max(
          max_delta, MaxPixelPerChannelDelta(baseline_pixel, actual_pixel));
      total_squared_error += PixelSquaredError(baseline_pixel, actual_pixel);
    }
  }

  if (out_metrics) {
    out_metrics->raw_diff_pixels = pixels_different;
    out_metrics->max_delta = max_delta;
    if (w > 0 && h > 0) {
      if (pixels_different == 0) {
        out_metrics->mse = 0.0;
        out_metrics->win_mse = 0.0;
        out_metrics->mean_ssim = 1.0;
        out_metrics->min_window_ssim = 1.0;
      } else {
        out_metrics->mse =
            static_cast<double>(total_squared_error) / (3.0 * w * h);

        std::vector<uint32_t> baseline_overlap(w * h);
        std::vector<uint32_t> actual_overlap(w * h);
        for (int y = 0; y < h; ++y) {
          for (int x = 0; x < w; ++x) {
            baseline_overlap[y * w + x] = baseline.pixel_at(x, y);
            actual_overlap[y * w + x] = actual.pixel_at(x, y);
          }
        }
        out_metrics->win_mse = CalculateMaxWindowMSE(
            baseline_overlap, static_cast<size_t>(w), actual_overlap,
            static_cast<size_t>(w), w, h, kMaxFuzzyWindowSize);
        SSIMMetrics ssim_metrics =
            CalculateSSIM(baseline_overlap, static_cast<size_t>(w),
                          actual_overlap, static_cast<size_t>(w), w, h);
        out_metrics->mean_ssim = ssim_metrics.mean_ssim;
        out_metrics->min_window_ssim = ssim_metrics.min_window_ssim;
      }
    }
  }

  CountImageSizeMismatchAsPixelDifference(baseline, actual, &pixels_different);

  return pixels_different;
}

int HistogramPixelsDifferent(const Image& baseline, const Image& actual) {
  // TODO(johnme): Consider using a joint histogram instead, as described in
  // "Comparing Images Using Joint Histograms" by Pass & Zabih
  // http://www.cs.cornell.edu/~rdz/papers/pz-jms99.pdf

  int w = std::min(baseline.w(), actual.w());
  int h = std::min(baseline.h(), actual.h());

  // Count occurrences of each RGBA pixel value of baseline in the overlap.
  std::map<uint32_t, int32_t> baseline_histogram;
  for (int y = 0; y < h; ++y) {
    for (int x = 0; x < w; ++x) {
      // hash_map operator[] inserts a 0 (default constructor) if key not found.
      ++baseline_histogram[baseline.pixel_at(x, y)];
    }
  }

  // Compute pixels different in the histogram of the overlap.
  int pixels_different = 0;
  for (int y = 0; y < h; ++y) {
    for (int x = 0; x < w; ++x) {
      uint32_t actual_rgba = actual.pixel_at(x, y);
      auto it = baseline_histogram.find(actual_rgba);
      if (it != baseline_histogram.end() && it->second > 0) {
        --it->second;
      } else {
        ++pixels_different;
      }
    }
  }

  CountImageSizeMismatchAsPixelDifference(baseline, actual, &pixels_different);
  return pixels_different;
}

void PrintHelp(const std::string& binary_name) {
  fprintf(
      stderr,
      "Usage:\n"
      "  %s OPTIONS <compare_file> <reference_file>\n"
      "    Compares two files on disk, returning 0 when they are the same.\n"
      "    Passing \"--histogram\" additionally calculates a diff of the\n"
      "    RGBA value histograms (which is resistant to shifts in layout).\n"
      "    Passing \"--reverse-byte-order\" additionally assumes the\n"
      "    compare file has BGRA byte ordering.\n"
      "    Passing \"--metrics\" additionally prints a machine-readable line\n"
      "    of measurements.\n"
      "    Under \"--histogram\" or \"--metrics\", the comparison result is\n"
      "    reported in the output rather than through the exit code, which\n"
      "    then indicates only whether the comparison could be performed.\n\n"
      "  %s --diff <compare_file> <reference_file> <output_file>\n"
      "    Compares two files on disk, and if they differ, outputs an image\n"
      "    to <output_file> that visualizes the differing pixels as red\n"
      "    dots.\n\n"
      "  %s --subtract <compare_file> <reference_file> <output_file>\n"
      "    Compares two files on disk, and if they differ, outputs an image\n"
      "    to <output_file> that visualizes the difference as a scaled\n"
      "    subtraction of pixel values.\n",
      binary_name.c_str(), binary_name.c_str(), binary_name.c_str());
}

int CompareImages(const std::string& binary_name,
                  const std::string& file1,
                  const std::string& file2,
                  bool compare_histograms,
                  bool reverse_byte_order,
                  bool report_metrics) {
  Image actual_image;
  Image baseline_image;

  bool actual_load_result =
      reverse_byte_order
          ? actual_image.CreateFromFilenameWithReverseByteOrder(file1)
          : actual_image.CreateFromFilename(file1);
  if (!actual_load_result) {
    fprintf(stderr, "%s: Unable to open file \"%s\"\n", binary_name.c_str(),
            file1.c_str());
    return kStatusError;
  }
  if (!baseline_image.CreateFromFilename(file2)) {
    fprintf(stderr, "%s: Unable to open file \"%s\"\n", binary_name.c_str(),
            file2.c_str());
    return kStatusError;
  }

  if (compare_histograms) {
    int pixels_different =
        HistogramPixelsDifferent(actual_image, baseline_image);
    float percent =
        CalculateDifferencePercentage(actual_image, pixels_different);
    const char* passed = percent > 0.0 ? "failed" : "passed";
    UNSAFE_TODO(printf("histogram diff: %01.2f%% %s (%d pixels differ)\n",
                       percent, passed, pixels_different));
  }

  const char* const diff_name = compare_histograms ? "exact diff" : "diff";
  DiffMetrics metrics;
  int pixels_different = PixelsDifferent(actual_image, baseline_image,
                                         report_metrics ? &metrics : nullptr);

  float percent = CalculateDifferencePercentage(actual_image, pixels_different);
  const char* const passed = percent > 0.0 ? "failed" : "passed";

  if (report_metrics) {
    int overlap_w = std::min(actual_image.w(), baseline_image.w());
    int overlap_h = std::min(actual_image.h(), baseline_image.h());
    const size_t last_separator = file1.rfind(PATH_SEPARATOR);
    std::string base_name = last_separator != std::string::npos
                                ? file1.substr(last_separator + 1)
                                : file1;

    printf(
        "%s: actual_w=%d actual_h=%d expected_w=%d expected_h=%d pixels=%d "
        "total=%d max_delta=%u mse=%.6f win_mse=%.6f mean_ssim=%.6f "
        "min_window_ssim=%.6f\n",
        base_name.c_str(), actual_image.w(), actual_image.h(),
        baseline_image.w(), baseline_image.h(), metrics.raw_diff_pixels,
        overlap_w * overlap_h, metrics.max_delta, metrics.mse, metrics.win_mse,
        metrics.mean_ssim, metrics.min_window_ssim);
  }

  UNSAFE_TODO(printf("%s: %01.2f%% %s (%d pixels differ)\n", diff_name, percent,
                     passed, pixels_different));

  if (compare_histograms || report_metrics) {
    // Measurement modes: the result is reported in the output above, leaving
    // the exit code to indicate only whether the comparison could be
    // performed at all.
    return kStatusSame;
  }
  if (percent > 0.0) {
    // failure: The WebKit version also writes the difference image to
    // stdout, which seems excessive for our needs.
    return kStatusDifferent;
  }
  // success
  return kStatusSame;
}

bool CreateImageDiff(const Image& image1, const Image& image2, Image* out) {
  int union_w = std::max(image1.w(), image2.w());
  int union_h = std::max(image1.h(), image2.h());
  int inter_w = std::min(image1.w(), image2.w());
  int inter_h = std::min(image1.h(), image2.h());
  *out = Image(union_w, union_h);
  bool same = (image1.w() == image2.w()) && (image1.h() == image2.h());

  for (int y = 0; y < union_h; ++y) {
    for (int x = 0; x < union_w; ++x) {
      if (x < inter_w && y < inter_h) {
        uint32_t base_pixel = image1.pixel_at(x, y);
        if (base_pixel != image2.pixel_at(x, y)) {
          // Set differing pixels red.
          out->set_pixel_at(x, y, RGBA_RED | RGBA_ALPHA);
          same = false;
        } else {
          // Set same pixels as faded.
          uint32_t alpha = base_pixel & RGBA_ALPHA;
          uint32_t new_pixel = base_pixel - ((alpha / 2) & RGBA_ALPHA);
          out->set_pixel_at(x, y, new_pixel);
        }
      } else {
        // Set out-of-bounds pixels red.
        out->set_pixel_at(x, y, RGBA_RED | RGBA_ALPHA);
        same = false;
      }
    }
  }

  return same;
}

bool SubtractImages(const Image& image1, const Image& image2, Image* out) {
  int union_w = std::max(image1.w(), image2.w());
  int union_h = std::max(image1.h(), image2.h());
  int inter_w = std::min(image1.w(), image2.w());
  int inter_h = std::min(image1.h(), image2.h());
  *out = Image(union_w, union_h);
  bool same = (image1.w() == image2.w()) && (image1.h() == image2.h());

  for (int y = 0; y < union_h; ++y) {
    for (int x = 0; x < union_w; ++x) {
      if (x < inter_w && y < inter_h) {
        uint32_t pixel1 = image1.pixel_at(x, y);
        int32_t r1 = pixel1 & 0xff;
        int32_t g1 = (pixel1 >> 8) & 0xff;
        int32_t b1 = (pixel1 >> 16) & 0xff;

        uint32_t pixel2 = image2.pixel_at(x, y);
        int32_t r2 = pixel2 & 0xff;
        int32_t g2 = (pixel2 >> 8) & 0xff;
        int32_t b2 = (pixel2 >> 16) & 0xff;

        int32_t delta_r = r1 - r2;
        int32_t delta_g = g1 - g2;
        int32_t delta_b = b1 - b2;
        same &= (delta_r == 0 && delta_g == 0 && delta_b == 0);

        delta_r = std::clamp(128 + delta_r * 8, 0, 255);
        delta_g = std::clamp(128 + delta_g * 8, 0, 255);
        delta_b = std::clamp(128 + delta_b * 8, 0, 255);

        uint32_t new_pixel = RGBA_ALPHA;
        new_pixel |= delta_r;
        new_pixel |= (delta_g << 8);
        new_pixel |= (delta_b << 16);
        out->set_pixel_at(x, y, new_pixel);
      } else {
        out->set_pixel_at(x, y, RGBA_RED | RGBA_ALPHA);
        same = false;
      }
    }
  }
  return same;
}

int DiffImages(const std::string& binary_name,
               const std::string& file1,
               const std::string& file2,
               const std::string& out_file,
               bool do_subtraction,
               bool reverse_byte_order) {
  Image actual_image;
  Image baseline_image;

  bool actual_load_result =
      reverse_byte_order
          ? actual_image.CreateFromFilenameWithReverseByteOrder(file1)
          : actual_image.CreateFromFilename(file1);

  if (!actual_load_result) {
    fprintf(stderr, "%s: Unable to open file \"%s\"\n", binary_name.c_str(),
            file1.c_str());
    return kStatusError;
  }
  if (!baseline_image.CreateFromFilename(file2)) {
    fprintf(stderr, "%s: Unable to open file \"%s\"\n", binary_name.c_str(),
            file2.c_str());
    return kStatusError;
  }

  Image diff_image;
  bool same = do_subtraction
                  ? SubtractImages(baseline_image, actual_image, &diff_image)
                  : CreateImageDiff(baseline_image, actual_image, &diff_image);
  if (same) {
    return kStatusSame;
  }

  std::vector<uint8_t> png_encoding = png_codec::EncodeRGBA(
      diff_image.span(), diff_image.w(), diff_image.h(), diff_image.w() * 4);
  if (png_encoding.empty()) {
    return kStatusError;
  }

  FILE* f = fopen(out_file.c_str(), "wb");
  if (!f) {
    return kStatusError;
  }

  if (fxcrt::spanwrite(png_encoding, f) != png_encoding.size()) {
    return kStatusError;
  }

  return kStatusDifferent;
}

int main(int argc, const char* argv[]) {
  bool histograms = false;
  bool produce_diff_image = false;
  bool produce_image_subtraction = false;
  bool reverse_byte_order = false;
  bool report_metrics = false;
  std::string filename1;
  std::string filename2;
  std::string diff_filename;

  // Strip the path from the first arg
  const char* last_separator = UNSAFE_TODO(strrchr(argv[0], PATH_SEPARATOR));
  std::string binary_name =
      last_separator ? UNSAFE_TODO(last_separator + 1) : argv[0];

  int i;
  for (i = 1; i < argc; ++i) {
    const char* arg = UNSAFE_TODO(argv[i]);
    if (UNSAFE_TODO(strstr(arg, "--")) != arg) {
      break;
    }
    if (UNSAFE_TODO(strcmp(arg, "--histogram")) == 0) {
      histograms = true;
    } else if (UNSAFE_TODO(strcmp(arg, "--diff")) == 0) {
      produce_diff_image = true;
    } else if (UNSAFE_TODO(strcmp(arg, "--subtract")) == 0) {
      produce_image_subtraction = true;
    } else if (UNSAFE_TODO(strcmp(arg, "--reverse-byte-order")) == 0) {
      reverse_byte_order = true;
    } else if (UNSAFE_TODO(strcmp(arg, "--metrics")) == 0) {
      report_metrics = true;
    }
  }
  if (i < argc) {
    filename1 = UNSAFE_TODO(argv[i++]);
  }
  if (i < argc) {
    filename2 = UNSAFE_TODO(argv[i++]);
  }
  if (i < argc) {
    diff_filename = UNSAFE_TODO(argv[i++]);
  }

  if (produce_diff_image || produce_image_subtraction) {
    if (!diff_filename.empty()) {
      return DiffImages(binary_name, filename1, filename2, diff_filename,
                        produce_image_subtraction, reverse_byte_order);
    }
  } else if (!filename2.empty()) {
    return CompareImages(binary_name, filename1, filename2, histograms,
                         reverse_byte_order, report_metrics);
  }

  PrintHelp(binary_name);
  return kStatusError;
}
