// 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.

#include "ui/gfx/skbitmap_operations.h"

#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <algorithm>

#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkColorPriv.h"
#include "third_party/skia/include/core/SkUnPreMultiply.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"

// static
SkBitmap SkBitmapOperations::CreateInvertedBitmap(const SkBitmap& image) {
  DCHECK(image.colorType() == kN32_SkColorType);

  SkBitmap inverted;
  inverted.allocN32Pixels(image.width(), image.height());

  for (int y = 0; y < image.height(); ++y) {
    uint32_t* image_row = image.getAddr32(0, y);
    uint32_t* dst_row = inverted.getAddr32(0, y);

    for (int x = 0; x < image.width(); ++x) {
      uint32_t image_pixel = image_row[x];
      dst_row[x] = (image_pixel & 0xFF000000) |
                   (0x00FFFFFF - (image_pixel & 0x00FFFFFF));
    }
  }

  return inverted;
}

// static
SkBitmap SkBitmapOperations::CreateBlendedBitmap(const SkBitmap& first,
                                                 const SkBitmap& second,
                                                 double alpha) {
  DCHECK((alpha >= 0) && (alpha <= 1));
  DCHECK(first.width() == second.width());
  DCHECK(first.height() == second.height());
  DCHECK(first.bytesPerPixel() == second.bytesPerPixel());
  DCHECK(first.colorType() == kN32_SkColorType);

  // Optimize for case where we won't need to blend anything.
  static const double alpha_min = 1.0 / 255;
  static const double alpha_max = 254.0 / 255;
  if (alpha < alpha_min)
    return first;
  else if (alpha > alpha_max)
    return second;

  SkBitmap blended;
  blended.allocN32Pixels(first.width(), first.height());

  double first_alpha = 1 - alpha;

  for (int y = 0; y < first.height(); ++y) {
    uint32_t* first_row = first.getAddr32(0, y);
    uint32_t* second_row = second.getAddr32(0, y);
    uint32_t* dst_row = blended.getAddr32(0, y);

    for (int x = 0; x < first.width(); ++x) {
      uint32_t first_pixel = first_row[x];
      uint32_t second_pixel = second_row[x];

      int a = static_cast<int>((SkColorGetA(first_pixel) * first_alpha) +
                               (SkColorGetA(second_pixel) * alpha));
      int r = static_cast<int>((SkColorGetR(first_pixel) * first_alpha) +
                               (SkColorGetR(second_pixel) * alpha));
      int g = static_cast<int>((SkColorGetG(first_pixel) * first_alpha) +
                               (SkColorGetG(second_pixel) * alpha));
      int b = static_cast<int>((SkColorGetB(first_pixel) * first_alpha) +
                               (SkColorGetB(second_pixel) * alpha));

      dst_row[x] = SkColorSetARGB(a, r, g, b);
    }
  }

  return blended;
}

// static
SkBitmap SkBitmapOperations::CreateMaskedBitmap(const SkBitmap& rgb,
                                                const SkBitmap& alpha) {
  DCHECK(rgb.width() == alpha.width());
  DCHECK(rgb.height() == alpha.height());
  DCHECK(rgb.bytesPerPixel() == alpha.bytesPerPixel());
  DCHECK(rgb.colorType() == kN32_SkColorType);
  DCHECK(alpha.colorType() == kN32_SkColorType);

  SkBitmap masked;
  masked.allocN32Pixels(rgb.width(), rgb.height());

  for (int y = 0; y < masked.height(); ++y) {
    uint32_t* rgb_row = rgb.getAddr32(0, y);
    uint32_t* alpha_row = alpha.getAddr32(0, y);
    uint32_t* dst_row = masked.getAddr32(0, y);

    for (int x = 0; x < masked.width(); ++x) {
      unsigned alpha = SkGetPackedA32(alpha_row[x]);
      unsigned scale = SkAlpha255To256(alpha);
      dst_row[x] = SkAlphaMulQ(rgb_row[x], scale);
    }
  }

  return masked;
}

// static
SkBitmap SkBitmapOperations::CreateButtonBackground(SkColor color,
                                                    const SkBitmap& image,
                                                    const SkBitmap& mask) {
  // Despite this assert, it seems like image is actually unpremultiplied.
  // The math producing dst_row[x] below is a correct SrcOver when
  // bg_* are premultiplied and img_* are unpremultiplied.
  DCHECK(image.colorType() == kN32_SkColorType);
  DCHECK(mask.colorType() == kN32_SkColorType);

  SkBitmap background;
  background.allocN32Pixels(mask.width(), mask.height());

  double bg_a = SkColorGetA(color);
  double bg_r = SkColorGetR(color) * (bg_a / 255.0);
  double bg_g = SkColorGetG(color) * (bg_a / 255.0);
  double bg_b = SkColorGetB(color) * (bg_a / 255.0);

  for (int y = 0; y < mask.height(); ++y) {
    uint32_t* dst_row = background.getAddr32(0, y);
    uint32_t* image_row = image.getAddr32(0, y % image.height());
    uint32_t* mask_row = mask.getAddr32(0, y);

    for (int x = 0; x < mask.width(); ++x) {
      uint32_t image_pixel = image_row[x % image.width()];

      double img_a = SkColorGetA(image_pixel);
      double img_r = SkColorGetR(image_pixel);
      double img_g = SkColorGetG(image_pixel);
      double img_b = SkColorGetB(image_pixel);

      double img_alpha = img_a / 255.0;
      double img_inv = 1 - img_alpha;

      double mask_a = static_cast<double>(SkColorGetA(mask_row[x])) / 255.0;

      dst_row[x] = SkColorSetARGB(
          // This is pretty weird; why not the usual SrcOver alpha?
          static_cast<int>(std::min(255.0, bg_a + img_a) * mask_a),
          static_cast<int>(((bg_r * img_inv) + (img_r * img_alpha)) * mask_a),
          static_cast<int>(((bg_g * img_inv) + (img_g * img_alpha)) * mask_a),
          static_cast<int>(((bg_b * img_inv) + (img_b * img_alpha)) * mask_a));
    }
  }

  return background;
}

namespace {
namespace HSLShift {

// TODO(viettrungluu): Some things have yet to be optimized at all.

// Notes on and conventions used in the following code
//
// Conventions:
//  - R, G, B, A = obvious; as variables: |r|, |g|, |b|, |a| (see also below)
//  - H, S, L = obvious; as variables: |h|, |s|, |l| (see also below)
//  - variables derived from S, L shift parameters: |sdec| and |sinc| for S
//    increase and decrease factors, |ldec| and |linc| for L (see also below)
//
// To try to optimize HSL shifts, we do several things:
//  - Avoid unpremultiplying (then processing) then premultiplying. This means
//    that R, G, B values (and also L, but not H and S) should be treated as
//    having a range of 0..A (where A is alpha).
//  - Do things in integer/fixed-point. This avoids costly conversions between
//    floating-point and integer, though I should study the tradeoff more
//    carefully (presumably, at some point of processing complexity, converting
//    and processing using simpler floating-point code will begin to win in
//    performance). Also to be studied is the speed/type of floating point
//    conversions; see, e.g., <http://www.stereopsis.com/sree/fpu2006.html>.
//
// Conventions for fixed-point arithmetic
//  - Each function has a constant denominator (called |den|, which should be a
//    power of 2), appropriate for the computations done in that function.
//  - A value |x| is then typically represented by a numerator, named |x_num|,
//    so that its actual value is |x_num / den| (casting to floating-point
//    before division).
//  - To obtain |x_num| from |x|, simply multiply by |den|, i.e., |x_num = x *
//    den| (casting appropriately).
//  - When necessary, a value |x| may also be represented as a numerator over
//    the denominator squared (set |den2 = den * den|). In such a case, the
//    corresponding variable is called |x_num2| (so that its actual value is
//    |x_num^2 / den2|.
//  - The representation of the product of |x| and |y| is be called |x_y_num| if
//    |x * y == x_y_num / den|, and |xy_num2| if |x * y == x_y_num2 / den2|. In
//    the latter case, notice that one can calculate |x_y_num2 = x_num * y_num|.

// Routine used to process a line; typically specialized for specific kinds of
// HSL shifts (to optimize).
typedef void (*LineProcessor)(const color_utils::HSL&,
                              const SkPMColor*,
                              SkPMColor*,
                              int width);

enum OperationOnH { kOpHNone = 0, kOpHShift, kNumHOps };
enum OperationOnS { kOpSNone = 0, kOpSDec, kOpSInc, kNumSOps };
enum OperationOnL { kOpLNone = 0, kOpLDec, kOpLInc, kNumLOps };

// Epsilon used to judge when shift values are close enough to various critical
// values (typically 0.5, which yields a no-op for S and L shifts. 1/256 should
// be small enough, but let's play it safe>
const double epsilon = 0.0005;

// Line processor: default/universal (i.e., old-school).
void LineProcDefault(const color_utils::HSL& hsl_shift,
                     const SkPMColor* in,
                     SkPMColor* out,
                     int width) {
  for (int x = 0; x < width; x++) {
    out[x] = SkPreMultiplyColor(color_utils::HSLShift(
        SkUnPreMultiply::PMColorToColor(in[x]), hsl_shift));
  }
}

// Line processor: no-op (i.e., copy).
void LineProcCopy(const color_utils::HSL& hsl_shift,
                  const SkPMColor* in,
                  SkPMColor* out,
                  int width) {
  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon);
  DCHECK(hsl_shift.l < 0 || fabs(hsl_shift.l - 0.5) < HSLShift::epsilon);
  memcpy(out, in, static_cast<size_t>(width) * sizeof(out[0]));
}

// Line processor: H no-op, S no-op, L decrease.
void LineProcHnopSnopLdec(const color_utils::HSL& hsl_shift,
                          const SkPMColor* in,
                          SkPMColor* out,
                          int width) {
  const uint32_t den = 65536;

  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon);
  DCHECK(hsl_shift.l <= 0.5 - HSLShift::epsilon && hsl_shift.l >= 0);

  uint32_t ldec_num = static_cast<uint32_t>(hsl_shift.l * 2 * den);
  for (int x = 0; x < width; x++) {
    uint32_t a = SkGetPackedA32(in[x]);
    uint32_t r = SkGetPackedR32(in[x]);
    uint32_t g = SkGetPackedG32(in[x]);
    uint32_t b = SkGetPackedB32(in[x]);
    r = r * ldec_num / den;
    g = g * ldec_num / den;
    b = b * ldec_num / den;
    out[x] = SkPackARGB32(a, r, g, b);
  }
}

// Line processor: H no-op, S no-op, L increase.
void LineProcHnopSnopLinc(const color_utils::HSL& hsl_shift,
                          const SkPMColor* in,
                          SkPMColor* out,
                          int width) {
  const uint32_t den = 65536;

  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s < 0 || fabs(hsl_shift.s - 0.5) < HSLShift::epsilon);
  DCHECK(hsl_shift.l >= 0.5 + HSLShift::epsilon && hsl_shift.l <= 1);

  uint32_t linc_num = static_cast<uint32_t>((hsl_shift.l - 0.5) * 2 * den);
  for (int x = 0; x < width; x++) {
    uint32_t a = SkGetPackedA32(in[x]);
    uint32_t r = SkGetPackedR32(in[x]);
    uint32_t g = SkGetPackedG32(in[x]);
    uint32_t b = SkGetPackedB32(in[x]);
    r += (a - r) * linc_num / den;
    g += (a - g) * linc_num / den;
    b += (a - b) * linc_num / den;
    out[x] = SkPackARGB32(a, r, g, b);
  }
}

// Saturation changes modifications in RGB
//
// (Note that as a further complication, the values we deal in are
// premultiplied, so R/G/B values must be in the range 0..A. For mathematical
// purposes, one may as well use r=R/A, g=G/A, b=B/A. Without loss of
// generality, assume that R/G/B values are in the range 0..1.)
//
// Let Max = max(R,G,B), Min = min(R,G,B), and Med be the median value. Then L =
// (Max+Min)/2. If L is to remain constant, Max+Min must also remain constant.
//
// For H to remain constant, first, the (numerical) order of R/G/B (from
// smallest to largest) must remain the same. Second, all the ratios
// (R-G)/(Max-Min), (R-B)/(Max-Min), (G-B)/(Max-Min) must remain constant (of
// course, if Max = Min, then S = 0 and no saturation change is well-defined,
// since H is not well-defined).
//
// Let C_max be a colour with value Max, C_min be one with value Min, and C_med
// the remaining colour. Increasing saturation (to the maximum) is accomplished
// by increasing the value of C_max while simultaneously decreasing C_min and
// changing C_med so that the ratios are maintained; for the latter, it suffices
// to keep (C_med-C_min)/(C_max-C_min) constant (and equal to
// (Med-Min)/(Max-Min)).

// Line processor: H no-op, S decrease, L no-op.
void LineProcHnopSdecLnop(const color_utils::HSL& hsl_shift,
                          const SkPMColor* in,
                          SkPMColor* out,
                          int width) {
  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon);
  DCHECK(hsl_shift.l < 0 || fabs(hsl_shift.l - 0.5) < HSLShift::epsilon);

  const int32_t denom = 65536;
  int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom);
  for (int x = 0; x < width; x++) {
    int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x]));
    int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x]));
    int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x]));
    int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x]));

    int32_t vmax, vmin;
    if (r > g) {  // This uses 3 compares rather than 4.
      vmax = std::max(r, b);
      vmin = std::min(g, b);
    } else {
      vmax = std::max(g, b);
      vmin = std::min(r, b);
    }

    // Use denom * L to avoid rounding.
    int32_t denom_l = (vmax + vmin) * (denom / 2);
    int32_t s_numer_l = (vmax + vmin) * s_numer / 2;

    r = (denom_l + r * s_numer - s_numer_l) / denom;
    g = (denom_l + g * s_numer - s_numer_l) / denom;
    b = (denom_l + b * s_numer - s_numer_l) / denom;
    out[x] = SkPackARGB32(a, r, g, b);
  }
}

// Line processor: H no-op, S decrease, L decrease.
void LineProcHnopSdecLdec(const color_utils::HSL& hsl_shift,
                          const SkPMColor* in,
                          SkPMColor* out,
                          int width) {
  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon);
  DCHECK(hsl_shift.l >= 0 && hsl_shift.l <= 0.5 - HSLShift::epsilon);

  // Can't be too big since we need room for denom*denom and a bit for sign.
  const int32_t denom = 1024;
  int32_t l_numer = static_cast<int32_t>(hsl_shift.l * 2 * denom);
  int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom);
  for (int x = 0; x < width; x++) {
    int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x]));
    int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x]));
    int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x]));
    int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x]));

    int32_t vmax, vmin;
    if (r > g) {  // This uses 3 compares rather than 4.
      vmax = std::max(r, b);
      vmin = std::min(g, b);
    } else {
      vmax = std::max(g, b);
      vmin = std::min(r, b);
    }

    // Use denom * L to avoid rounding.
    int32_t denom_l = (vmax + vmin) * (denom / 2);
    int32_t s_numer_l = (vmax + vmin) * s_numer / 2;

    r = (denom_l + r * s_numer - s_numer_l) * l_numer / (denom * denom);
    g = (denom_l + g * s_numer - s_numer_l) * l_numer / (denom * denom);
    b = (denom_l + b * s_numer - s_numer_l) * l_numer / (denom * denom);
    out[x] = SkPackARGB32(a, r, g, b);
  }
}

// Line processor: H no-op, S decrease, L increase.
void LineProcHnopSdecLinc(const color_utils::HSL& hsl_shift,
                          const SkPMColor* in,
                          SkPMColor* out,
                          int width) {
  DCHECK(hsl_shift.h < 0);
  DCHECK(hsl_shift.s >= 0 && hsl_shift.s <= 0.5 - HSLShift::epsilon);
  DCHECK(hsl_shift.l >= 0.5 + HSLShift::epsilon && hsl_shift.l <= 1);

  // Can't be too big since we need room for denom*denom and a bit for sign.
  const int32_t denom = 1024;
  int32_t l_numer = static_cast<int32_t>((hsl_shift.l - 0.5) * 2 * denom);
  int32_t s_numer = static_cast<int32_t>(hsl_shift.s * 2 * denom);
  for (int x = 0; x < width; x++) {
    int32_t a = static_cast<int32_t>(SkGetPackedA32(in[x]));
    int32_t r = static_cast<int32_t>(SkGetPackedR32(in[x]));
    int32_t g = static_cast<int32_t>(SkGetPackedG32(in[x]));
    int32_t b = static_cast<int32_t>(SkGetPackedB32(in[x]));

    int32_t vmax, vmin;
    if (r > g) {  // This uses 3 compares rather than 4.
      vmax = std::max(r, b);
      vmin = std::min(g, b);
    } else {
      vmax = std::max(g, b);
      vmin = std::min(r, b);
    }

    // Use denom * L to avoid rounding.
    int32_t denom_l = (vmax + vmin) * (denom / 2);
    int32_t s_numer_l = (vmax + vmin) * s_numer / 2;

    r = denom_l + r * s_numer - s_numer_l;
    g = denom_l + g * s_numer - s_numer_l;
    b = denom_l + b * s_numer - s_numer_l;

    r = (r * denom + (a * denom - r) * l_numer) / (denom * denom);
    g = (g * denom + (a * denom - g) * l_numer) / (denom * denom);
    b = (b * denom + (a * denom - b) * l_numer) / (denom * denom);
    out[x] = SkPackARGB32(a, r, g, b);
  }
}

const LineProcessor kLineProcessors[kNumHOps][kNumSOps][kNumLOps] = {
  { // H: kOpHNone
    { // S: kOpSNone
      LineProcCopy,         // L: kOpLNone
      LineProcHnopSnopLdec, // L: kOpLDec
      LineProcHnopSnopLinc  // L: kOpLInc
    },
    { // S: kOpSDec
      LineProcHnopSdecLnop, // L: kOpLNone
      LineProcHnopSdecLdec, // L: kOpLDec
      LineProcHnopSdecLinc  // L: kOpLInc
    },
    { // S: kOpSInc
      LineProcDefault, // L: kOpLNone
      LineProcDefault, // L: kOpLDec
      LineProcDefault  // L: kOpLInc
    }
  },
  { // H: kOpHShift
    { // S: kOpSNone
      LineProcDefault, // L: kOpLNone
      LineProcDefault, // L: kOpLDec
      LineProcDefault  // L: kOpLInc
    },
    { // S: kOpSDec
      LineProcDefault, // L: kOpLNone
      LineProcDefault, // L: kOpLDec
      LineProcDefault  // L: kOpLInc
    },
    { // S: kOpSInc
      LineProcDefault, // L: kOpLNone
      LineProcDefault, // L: kOpLDec
      LineProcDefault  // L: kOpLInc
    }
  }
};

}  // namespace HSLShift
}  // namespace

// static
SkBitmap SkBitmapOperations::CreateHSLShiftedBitmap(
    const SkBitmap& bitmap,
    const color_utils::HSL& hsl_shift) {
  // Default to NOPs.
  HSLShift::OperationOnH H_op = HSLShift::kOpHNone;
  HSLShift::OperationOnS S_op = HSLShift::kOpSNone;
  HSLShift::OperationOnL L_op = HSLShift::kOpLNone;

  if (hsl_shift.h >= 0 && hsl_shift.h <= 1)
    H_op = HSLShift::kOpHShift;

  // Saturation shift: 0 -> fully desaturate, 0.5 -> NOP, 1 -> fully saturate.
  if (hsl_shift.s >= 0 && hsl_shift.s <= (0.5 - HSLShift::epsilon))
    S_op = HSLShift::kOpSDec;
  else if (hsl_shift.s >= (0.5 + HSLShift::epsilon))
    S_op = HSLShift::kOpSInc;

  // Lightness shift: 0 -> black, 0.5 -> NOP, 1 -> white.
  if (hsl_shift.l >= 0 && hsl_shift.l <= (0.5 - HSLShift::epsilon))
    L_op = HSLShift::kOpLDec;
  else if (hsl_shift.l >= (0.5 + HSLShift::epsilon))
    L_op = HSLShift::kOpLInc;

  HSLShift::LineProcessor line_proc =
      HSLShift::kLineProcessors[H_op][S_op][L_op];

  DCHECK(bitmap.empty() == false);
  DCHECK(bitmap.colorType() == kN32_SkColorType);

  SkBitmap shifted;
  shifted.allocN32Pixels(bitmap.width(), bitmap.height());

  // Loop through the pixels of the original bitmap.
  for (int y = 0; y < bitmap.height(); ++y) {
    SkPMColor* pixels = bitmap.getAddr32(0, y);
    SkPMColor* tinted_pixels = shifted.getAddr32(0, y);

    (*line_proc)(hsl_shift, pixels, tinted_pixels, bitmap.width());
  }

  return shifted;
}

// static
SkBitmap SkBitmapOperations::CreateTiledBitmap(const SkBitmap& source,
                                               int src_x, int src_y,
                                               int dst_w, int dst_h) {
  DCHECK(source.colorType() == kN32_SkColorType);

  SkBitmap cropped;
  cropped.allocN32Pixels(dst_w, dst_h);

  // Loop through the pixels of the original bitmap.
  for (int y = 0; y < dst_h; ++y) {
    int y_pix = (src_y + y) % source.height();
    while (y_pix < 0)
      y_pix += source.height();

    uint32_t* source_row = source.getAddr32(0, y_pix);
    uint32_t* dst_row = cropped.getAddr32(0, y);

    for (int x = 0; x < dst_w; ++x) {
      int x_pix = (src_x + x) % source.width();
      while (x_pix < 0)
        x_pix += source.width();

      dst_row[x] = source_row[x_pix];
    }
  }

  return cropped;
}

// static
SkBitmap SkBitmapOperations::DownsampleByTwoUntilSize(const SkBitmap& bitmap,
                                                      int min_w, int min_h) {
  if ((bitmap.width() <= min_w) || (bitmap.height() <= min_h) ||
      (min_w < 0) || (min_h < 0))
    return bitmap;

  // Since bitmaps are refcounted, this copy will be fast.
  SkBitmap current = bitmap;
  while ((current.width() >= min_w * 2) && (current.height() >= min_h * 2) &&
         (current.width() > 1) && (current.height() > 1))
    current = DownsampleByTwo(current);
  return current;
}

// static
SkBitmap SkBitmapOperations::DownsampleByTwo(const SkBitmap& bitmap) {
  // Handle the nop case.
  if ((bitmap.width() <= 1) || (bitmap.height() <= 1))
    return bitmap;

  SkBitmap result;
  result.allocN32Pixels((bitmap.width() + 1) / 2, (bitmap.height() + 1) / 2);

  const int resultLastX = result.width() - 1;
  const int srcLastX = bitmap.width() - 1;

  for (int dest_y = 0; dest_y < result.height(); ++dest_y) {
    const int src_y = dest_y << 1;
    const SkPMColor* SK_RESTRICT cur_src0 = bitmap.getAddr32(0, src_y);
    const SkPMColor* SK_RESTRICT cur_src1 = cur_src0;
    if (src_y + 1 < bitmap.height())
      cur_src1 = bitmap.getAddr32(0, src_y + 1);

    SkPMColor* SK_RESTRICT cur_dst = result.getAddr32(0, dest_y);

    for (int dest_x = 0; dest_x <= resultLastX; ++dest_x) {
      // This code is based on downsampleby2_proc32 in SkBitmap.cpp. It is very
      // clever in that it does two channels at once: alpha and green ("ag")
      // and red and blue ("rb"). Each channel gets averaged across 4 pixels
      // to get the result.
      int bump_x = (dest_x << 1) < srcLastX;
      SkPMColor tmp, ag, rb;

      // Top left pixel of the 2x2 block.
      tmp = cur_src0[0];
      ag = (tmp >> 8) & 0xFF00FF;
      rb = tmp & 0xFF00FF;

      // Top right pixel of the 2x2 block.
      tmp = cur_src0[bump_x];
      ag += (tmp >> 8) & 0xFF00FF;
      rb += tmp & 0xFF00FF;

      // Bottom left pixel of the 2x2 block.
      tmp = cur_src1[0];
      ag += (tmp >> 8) & 0xFF00FF;
      rb += tmp & 0xFF00FF;

      // Bottom right pixel of the 2x2 block.
      tmp = cur_src1[bump_x];
      ag += (tmp >> 8) & 0xFF00FF;
      rb += tmp & 0xFF00FF;

      // Put the channels back together, dividing each by 4 to get the average.
      // |ag| has the alpha and green channels shifted right by 8 bits from
      // there they should end up, so shifting left by 6 gives them in the
      // correct position divided by 4.
      *cur_dst++ = ((rb >> 2) & 0xFF00FF) | ((ag << 6) & 0xFF00FF00);

      cur_src0 += 2;
      cur_src1 += 2;
    }
  }

  return result;
}

// static
SkBitmap SkBitmapOperations::UnPreMultiply(const SkBitmap& bitmap) {
  if (bitmap.isNull())
    return bitmap;
  if (bitmap.isOpaque())
    return bitmap;

  const SkImageInfo& opaque_info =
      bitmap.info().makeAlphaType(kOpaque_SkAlphaType);
  SkBitmap opaque_bitmap;
  opaque_bitmap.allocPixels(opaque_info);

  for (int y = 0; y < opaque_bitmap.height(); y++) {
    for (int x = 0; x < opaque_bitmap.width(); x++) {
      uint32_t src_pixel = *bitmap.getAddr32(x, y);
      uint32_t* dst_pixel = opaque_bitmap.getAddr32(x, y);
      SkColor unmultiplied = SkUnPreMultiply::PMColorToColor(src_pixel);
      *dst_pixel = unmultiplied;
    }
  }

  return opaque_bitmap;
}

// static
SkBitmap SkBitmapOperations::CreateTransposedBitmap(const SkBitmap& image) {
  DCHECK(image.colorType() == kN32_SkColorType);

  SkBitmap transposed;
  transposed.allocN32Pixels(image.height(), image.width());

  for (int y = 0; y < image.height(); ++y) {
    uint32_t* image_row = image.getAddr32(0, y);
    for (int x = 0; x < image.width(); ++x) {
      uint32_t* dst = transposed.getAddr32(y, x);
      *dst = image_row[x];
    }
  }

  return transposed;
}

// static
SkBitmap SkBitmapOperations::CreateColorMask(const SkBitmap& bitmap,
                                             SkColor c) {
  DCHECK(bitmap.colorType() == kN32_SkColorType);

  SkBitmap color_mask;
  color_mask.allocN32Pixels(bitmap.width(), bitmap.height());
  color_mask.eraseARGB(0, 0, 0, 0);

  SkCanvas canvas(color_mask);

  SkPaint paint;
  paint.setColorFilter(SkColorFilter::MakeModeFilter(c, SkBlendMode::kSrcIn));
  canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint);
  return color_mask;
}

// static
SkBitmap SkBitmapOperations::CreateDropShadow(
    const SkBitmap& bitmap,
    const gfx::ShadowValues& shadows) {
  DCHECK(bitmap.colorType() == kN32_SkColorType);

  // Shadow margin insets are negative values because they grow outside.
  // Negate them here as grow direction is not important and only pixel value
  // is of interest here.
  gfx::Insets shadow_margin = -gfx::ShadowValue::GetMargin(shadows);

  SkBitmap image_with_shadow;
  image_with_shadow.allocN32Pixels(bitmap.width() + shadow_margin.width(),
                                   bitmap.height() + shadow_margin.height());
  image_with_shadow.eraseARGB(0, 0, 0, 0);

  SkCanvas canvas(image_with_shadow);
  canvas.translate(SkIntToScalar(shadow_margin.left()),
                   SkIntToScalar(shadow_margin.top()));

  SkPaint paint;
  for (size_t i = 0; i < shadows.size(); ++i) {
    const gfx::ShadowValue& shadow = shadows[i];
    SkBitmap shadow_image = SkBitmapOperations::CreateColorMask(bitmap,
                                                                shadow.color());

    // The blur is halved to produce a shadow that correctly fits within the
    // |shadow_margin|.
    SkScalar sigma = SkDoubleToScalar(shadow.blur() / 2);
    paint.setImageFilter(SkBlurImageFilter::Make(sigma, sigma, nullptr));

    canvas.saveLayer(0, &paint);
    canvas.drawBitmap(shadow_image,
                      SkIntToScalar(shadow.x()),
                      SkIntToScalar(shadow.y()));
    canvas.restore();
  }

  canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0));
  return image_with_shadow;
}

// static
SkBitmap SkBitmapOperations::Rotate(const SkBitmap& source,
                                    RotationAmount rotation) {
  // SkCanvas::drawBitmap() fails silently with unpremultiplied SkBitmap.
  DCHECK_NE(source.info().alphaType(), kUnpremul_SkAlphaType);

  SkBitmap result;
  SkScalar angle = SkFloatToScalar(0.0f);

  switch (rotation) {
   case ROTATION_90_CW:
     angle = SkFloatToScalar(90.0f);
     result.allocN32Pixels(source.height(), source.width());
     break;
   case ROTATION_180_CW:
     angle = SkFloatToScalar(180.0f);
     result.allocN32Pixels(source.width(), source.height());
     break;
   case ROTATION_270_CW:
     angle = SkFloatToScalar(270.0f);
     result.allocN32Pixels(source.height(), source.width());
     break;
  }

  SkCanvas canvas(result);
  canvas.clear(SkColorSetARGB(0, 0, 0, 0));

  canvas.translate(SkFloatToScalar(result.width() * 0.5f),
                   SkFloatToScalar(result.height() * 0.5f));
  canvas.rotate(angle);
  canvas.translate(-SkFloatToScalar(source.width() * 0.5f),
                   -SkFloatToScalar(source.height() * 0.5f));
  canvas.drawBitmap(source, 0, 0);
  canvas.flush();

  return result;
}
