// Copyright (c) 2012 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.

#ifndef UI_GFX_COLOR_ANALYSIS_H_
#define UI_GFX_COLOR_ANALYSIS_H_

#include <stdint.h>

#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/matrix3_f.h"
#include "ui/gfx/gfx_export.h"

class SkBitmap;

namespace color_utils {

struct HSL;

// This class exposes the sampling method to the caller, which allows
// stubbing out for things like unit tests. Might be useful to pass more
// arguments into the GetSample method in the future (such as which
// cluster is being worked on, etc.).
//
// Note: Samplers should be deterministic, as the same image may be analyzed
// twice with two sampler instances and the results displayed side-by-side
// to the user.
class GFX_EXPORT KMeanImageSampler {
 public:
  virtual int GetSample(int width, int height) = 0;

 protected:
  KMeanImageSampler();
  virtual ~KMeanImageSampler();
};

// This sampler will pick pixels from an evenly spaced grid.
class GFX_EXPORT GridSampler : public KMeanImageSampler {
  public:
   GridSampler();
   ~GridSampler() override;

   int GetSample(int width, int height) override;

  private:
   // The number of times GetSample has been called.
   int calls_;
};

// Returns the color in an ARGB |image| that is closest in RGB-space to the
// provided |color|. Exported for testing.
GFX_EXPORT SkColor FindClosestColor(const uint8_t* image, int width, int height,
                                    SkColor color);

// Returns an SkColor that represents the calculated dominant color in the
// image. This uses a KMean clustering algorithm to find clusters of pixel
// colors in RGB space.
// |png|/|bitmap| represents the data of a png/bitmap encoded image.
// |lower_bound| represents the minimum bound of HSL values to allow.
// |upper_bound| represents the maximum bound of HSL values to allow.
// See color_utils::IsWithinHSLRange() for description of these bounds.
//
// RGB KMean Algorithm (N clusters, M iterations):
// 1.Pick N starting colors by randomly sampling the pixels. If you see a
//   color you already saw keep sampling. After a certain number of tries
//   just remove the cluster and continue with N = N-1 clusters (for an image
//   with just one color this should devolve to N=1). These colors are the
//   centers of your N clusters.
// 2.For each pixel in the image find the cluster that it is closest to in RGB
//   space. Add that pixel's color to that cluster (we keep a sum and a count
//   of all of the pixels added to the space, so just add it to the sum and
//   increment count).
// 3.Calculate the new cluster centroids by getting the average color of all of
//   the pixels in each cluster (dividing the sum by the count).
// 4.See if the new centroids are the same as the old centroids.
//     a) If this is the case for all N clusters than we have converged and
//        can move on.
//     b) If any centroid moved, repeat step 2 with the new centroids for up
//        to M iterations.
// 5.Once the clusters have converged or M iterations have been tried, sort
//   the clusters by weight (where weight is the number of pixels that make up
//   this cluster).
// 6.Going through the sorted list of clusters, pick the first cluster with the
//   largest weight that's centroid falls between |lower_bound| and
//   |upper_bound|. Return that color.
//   If no color fulfills that requirement return the color with the largest
//   weight regardless of whether or not it fulfills the equation above.
GFX_EXPORT SkColor
    CalculateKMeanColorOfPNG(scoped_refptr<base::RefCountedMemory> png,
                             const HSL& lower_bound,
                             const HSL& upper_bound,
                             KMeanImageSampler* sampler);
// Computes a dominant color using the above algorithm and reasonable defaults
// for |lower_bound|, |upper_bound| and |sampler|.
GFX_EXPORT SkColor CalculateKMeanColorOfPNG(
    scoped_refptr<base::RefCountedMemory> png);

// Computes a dominant color for the first |height| rows of |bitmap| using the
// above algorithm and a reasonable default sampler. If |find_closest| is true,
// the returned color will be the closest color to the true K-mean color that
// actually appears in the image; if false, the true color is returned
// regardless of whether it actually appears.
GFX_EXPORT SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap,
                                               int height,
                                               const HSL& lower_bound,
                                               const HSL& upper_bound,
                                               bool find_closest);

// Computes a dominant color using the above algorithm and reasonable defaults
// for |lower_bound|, |upper_bound| and |sampler|.
GFX_EXPORT SkColor CalculateKMeanColorOfBitmap(const SkBitmap& bitmap);

// These enums specify general values to look for when calculating prominent
// colors from an image. For example, a "light vibrant" prominent color would
// tend to be brighter and more saturated. The best combination of color
// attributes depends on how you plan to apply the color.
enum class LumaRange {
  LIGHT,
  NORMAL,
  DARK,
};

enum class SaturationRange {
  VIBRANT,
  MUTED,
};

struct ColorProfile {
  ColorProfile() = default;
  ColorProfile(LumaRange l, SaturationRange s) : luma(l), saturation(s) {}

  LumaRange luma = LumaRange::DARK;
  SaturationRange saturation = SaturationRange::MUTED;
};

// Returns a vector of RGB colors that represents the bitmap based on the
// |color_profiles| provided. For each value, if a value is succesfully
// calculated, the calculated value is fully opaque. For failure, the calculated
// value is transparent.
GFX_EXPORT std::vector<SkColor> CalculateProminentColorsOfBitmap(
    const SkBitmap& bitmap,
    const std::vector<ColorProfile>& color_profiles);

// Compute color covariance matrix for the input bitmap.
GFX_EXPORT gfx::Matrix3F ComputeColorCovariance(const SkBitmap& bitmap);

// Apply a color reduction transform defined by |color_transform| vector to
// |source_bitmap|. The result is put into |target_bitmap|, which is expected
// to be initialized to the required size and type (SkBitmap::kA8_Config).
// If |fit_to_range|, result is transfored linearly to fit 0-0xFF range.
// Otherwise, data is clipped.
// Returns true if the target has been computed.
GFX_EXPORT bool ApplyColorReduction(const SkBitmap& source_bitmap,
                                   const gfx::Vector3dF& color_transform,
                                   bool fit_to_range,
                                   SkBitmap* target_bitmap);

// Compute a monochrome image representing the principal color component of
// the |source_bitmap|. The result is stored in |target_bitmap|, which must be
// initialized to the required size and type (SkBitmap::kA8_Config).
// Returns true if the conversion succeeded. Note that there might be legitimate
// reasons for the process to fail even if all input was correct. This is a
// condition the caller must be able to handle.
GFX_EXPORT bool ComputePrincipalComponentImage(const SkBitmap& source_bitmap,
                                              SkBitmap* target_bitmap);

}  // namespace color_utils

#endif  // UI_GFX_COLOR_ANALYSIS_H_
