// Copyright 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 "core/frame/ImageBitmap.h"

#include "core/html/HTMLCanvasElement.h"
#include "core/html/HTMLVideoElement.h"
#include "core/html/ImageData.h"
#include "platform/graphics/skia/SkiaUtils.h"
#include "platform/image-decoders/ImageDecoder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "wtf/CheckedNumeric.h"
#include "wtf/PtrUtil.h"
#include "wtf/RefPtr.h"
#include <memory>

namespace blink {

static const char* imageOrientationFlipY = "flipY";
static const char* imageBitmapOptionNone = "none";

namespace {

struct ParsedOptions {
  bool flipY = false;
  bool premultiplyAlpha = true;
  bool shouldScaleInput = false;
  unsigned resizeWidth = 0;
  unsigned resizeHeight = 0;
  IntRect cropRect;
  SkFilterQuality resizeQuality = kLow_SkFilterQuality;
  // This value should be changed in the future when we support
  // createImageBitmap with higher bit depth, in the parseOptions() function.
  // For now, it is always 4.
  int bytesPerPixel = 4;
};

// The following two functions are helpers used in cropImage
static inline IntRect normalizeRect(const IntRect& rect) {
  return IntRect(std::min(rect.x(), rect.maxX()),
                 std::min(rect.y(), rect.maxY()),
                 std::max(rect.width(), -rect.width()),
                 std::max(rect.height(), -rect.height()));
}

ParsedOptions parseOptions(const ImageBitmapOptions& options,
                           Optional<IntRect> cropRect,
                           IntSize sourceSize) {
  ParsedOptions parsedOptions;
  if (options.imageOrientation() == imageOrientationFlipY) {
    parsedOptions.flipY = true;
  } else {
    parsedOptions.flipY = false;
    DCHECK(options.imageOrientation() == imageBitmapOptionNone);
  }
  if (options.premultiplyAlpha() == imageBitmapOptionNone) {
    parsedOptions.premultiplyAlpha = false;
  } else {
    parsedOptions.premultiplyAlpha = true;
    DCHECK(options.premultiplyAlpha() == "default" ||
           options.premultiplyAlpha() == "premultiply");
  }

  int sourceWidth = sourceSize.width();
  int sourceHeight = sourceSize.height();
  if (!cropRect) {
    parsedOptions.cropRect = IntRect(0, 0, sourceWidth, sourceHeight);
  } else {
    parsedOptions.cropRect = normalizeRect(*cropRect);
  }
  if (!options.hasResizeWidth() && !options.hasResizeHeight()) {
    parsedOptions.resizeWidth = parsedOptions.cropRect.width();
    parsedOptions.resizeHeight = parsedOptions.cropRect.height();
  } else if (options.hasResizeWidth() && options.hasResizeHeight()) {
    parsedOptions.resizeWidth = options.resizeWidth();
    parsedOptions.resizeHeight = options.resizeHeight();
  } else if (options.hasResizeWidth() && !options.hasResizeHeight()) {
    parsedOptions.resizeWidth = options.resizeWidth();
    parsedOptions.resizeHeight =
        ceil(static_cast<float>(options.resizeWidth()) /
             parsedOptions.cropRect.width() * parsedOptions.cropRect.height());
  } else {
    parsedOptions.resizeHeight = options.resizeHeight();
    parsedOptions.resizeWidth =
        ceil(static_cast<float>(options.resizeHeight()) /
             parsedOptions.cropRect.height() * parsedOptions.cropRect.width());
  }
  if (static_cast<int>(parsedOptions.resizeWidth) ==
          parsedOptions.cropRect.width() &&
      static_cast<int>(parsedOptions.resizeHeight) ==
          parsedOptions.cropRect.height()) {
    parsedOptions.shouldScaleInput = false;
    return parsedOptions;
  }
  parsedOptions.shouldScaleInput = true;

  if (options.resizeQuality() == "high")
    parsedOptions.resizeQuality = kHigh_SkFilterQuality;
  else if (options.resizeQuality() == "medium")
    parsedOptions.resizeQuality = kMedium_SkFilterQuality;
  else if (options.resizeQuality() == "pixelated")
    parsedOptions.resizeQuality = kNone_SkFilterQuality;
  else
    parsedOptions.resizeQuality = kLow_SkFilterQuality;
  return parsedOptions;
}

bool dstBufferSizeHasOverflow(ParsedOptions options) {
  CheckedNumeric<size_t> totalBytes = options.cropRect.width();
  totalBytes *= options.cropRect.height();
  totalBytes *= options.bytesPerPixel;
  if (!totalBytes.IsValid())
    return true;

  if (!options.shouldScaleInput)
    return false;
  totalBytes = options.resizeWidth;
  totalBytes *= options.resizeHeight;
  totalBytes *= options.bytesPerPixel;
  if (!totalBytes.IsValid())
    return true;

  return false;
}

}  // namespace

static PassRefPtr<Uint8Array> copySkImageData(SkImage* input,
                                              const SkImageInfo& info) {
  // The function dstBufferSizeHasOverflow() is being called at the beginning of
  // each ImageBitmap() constructor, which makes sure that doing
  // width * height * bytesPerPixel will never overflow size_t.
  size_t width = static_cast<size_t>(input->width());
  RefPtr<ArrayBuffer> dstBuffer =
      ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel());
  if (!dstBuffer)
    return nullptr;
  RefPtr<Uint8Array> dstPixels =
      Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
  input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0,
                    0);
  return dstPixels;
}

static sk_sp<SkImage> newSkImageFromRaster(const SkImageInfo& info,
                                           PassRefPtr<Uint8Array> imagePixels,
                                           size_t imageRowBytes) {
  SkPixmap pixmap(info, imagePixels->data(), imageRowBytes);
  return SkImage::MakeFromRaster(pixmap,
                                 [](const void*, void* pixels) {
                                   static_cast<Uint8Array*>(pixels)->deref();
                                 },
                                 imagePixels.leakRef());
}

static void swizzleImageData(unsigned char* srcAddr,
                             size_t height,
                             size_t bytesPerRow,
                             bool flipY) {
  if (flipY) {
    for (size_t i = 0; i < height / 2; i++) {
      size_t topRowStartPosition = i * bytesPerRow;
      size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow;
      if (kN32_SkColorType == kBGRA_8888_SkColorType) {  // needs to swizzle
        for (size_t j = 0; j < bytesPerRow; j += 4) {
          std::swap(srcAddr[topRowStartPosition + j],
                    srcAddr[bottomRowStartPosition + j + 2]);
          std::swap(srcAddr[topRowStartPosition + j + 1],
                    srcAddr[bottomRowStartPosition + j + 1]);
          std::swap(srcAddr[topRowStartPosition + j + 2],
                    srcAddr[bottomRowStartPosition + j]);
          std::swap(srcAddr[topRowStartPosition + j + 3],
                    srcAddr[bottomRowStartPosition + j + 3]);
        }
      } else {
        std::swap_ranges(srcAddr + topRowStartPosition,
                         srcAddr + topRowStartPosition + bytesPerRow,
                         srcAddr + bottomRowStartPosition);
      }
    }
  } else {
    if (kN32_SkColorType == kBGRA_8888_SkColorType)  // needs to swizzle
      for (size_t i = 0; i < height * bytesPerRow; i += 4)
        std::swap(srcAddr[i], srcAddr[i + 2]);
  }
}

static sk_sp<SkImage> flipSkImageVertically(SkImage* input,
                                            AlphaDisposition alphaOp) {
  size_t width = static_cast<size_t>(input->width());
  size_t height = static_cast<size_t>(input->height());
  SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(),
                                          (alphaOp == PremultiplyAlpha)
                                              ? kPremul_SkAlphaType
                                              : kUnpremul_SkAlphaType);
  size_t imageRowBytes = width * info.bytesPerPixel();
  RefPtr<Uint8Array> imagePixels = copySkImageData(input, info);
  if (!imagePixels)
    return nullptr;
  for (size_t i = 0; i < height / 2; i++) {
    size_t topFirstElement = i * imageRowBytes;
    size_t topLastElement = (i + 1) * imageRowBytes;
    size_t bottomFirstElement = (height - 1 - i) * imageRowBytes;
    std::swap_ranges(imagePixels->data() + topFirstElement,
                     imagePixels->data() + topLastElement,
                     imagePixels->data() + bottomFirstElement);
  }
  return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes);
}

static sk_sp<SkImage> premulSkImageToUnPremul(SkImage* input) {
  SkImageInfo info = SkImageInfo::Make(input->width(), input->height(),
                                       kN32_SkColorType, kUnpremul_SkAlphaType);
  RefPtr<Uint8Array> dstPixels = copySkImageData(input, info);
  if (!dstPixels)
    return nullptr;
  return newSkImageFromRaster(
      info, std::move(dstPixels),
      static_cast<size_t>(input->width()) * info.bytesPerPixel());
}

static sk_sp<SkImage> unPremulSkImageToPremul(SkImage* input) {
  SkImageInfo info = SkImageInfo::Make(input->width(), input->height(),
                                       kN32_SkColorType, kPremul_SkAlphaType);
  RefPtr<Uint8Array> dstPixels = copySkImageData(input, info);
  if (!dstPixels)
    return nullptr;
  return newSkImageFromRaster(
      info, std::move(dstPixels),
      static_cast<size_t>(input->width()) * info.bytesPerPixel());
}

sk_sp<SkImage> ImageBitmap::getSkImageFromDecoder(
    std::unique_ptr<ImageDecoder> decoder) {
  if (!decoder->frameCount())
    return nullptr;
  ImageFrame* frame = decoder->frameBufferAtIndex(0);
  if (!frame || frame->getStatus() != ImageFrame::FrameComplete)
    return nullptr;
  DCHECK(!frame->bitmap().isNull() && !frame->bitmap().empty());
  return frame->finalizePixelsAndGetImage();
}

bool ImageBitmap::isResizeOptionValid(const ImageBitmapOptions& options,
                                      ExceptionState& exceptionState) {
  if ((options.hasResizeWidth() && options.resizeWidth() == 0) ||
      (options.hasResizeHeight() && options.resizeHeight() == 0)) {
    exceptionState.throwDOMException(
        InvalidStateError,
        "The resizeWidth or/and resizeHeight is equal to 0.");
    return false;
  }
  return true;
}

bool ImageBitmap::isSourceSizeValid(int sourceWidth,
                                    int sourceHeight,
                                    ExceptionState& exceptionState) {
  if (!sourceWidth || !sourceHeight) {
    exceptionState.throwDOMException(
        IndexSizeError, String::format("The source %s provided is 0.",
                                       sourceWidth ? "height" : "width"));
    return false;
  }
  return true;
}

// The parameter imageFormat indicates whether the first parameter "image" is
// unpremultiplied or not.  imageFormat = PremultiplyAlpha means the image is in
// premuliplied format For example, if the image is already in unpremultiplied
// format and we want the created ImageBitmap in the same format, then we don't
// need to use the ImageDecoder to decode the image.
static PassRefPtr<StaticBitmapImage> cropImage(
    Image* image,
    const ParsedOptions& parsedOptions,
    AlphaDisposition imageFormat = PremultiplyAlpha,
    ImageDecoder::GammaAndColorProfileOption colorSpaceOp =
        ImageDecoder::GammaAndColorProfileApplied) {
  ASSERT(image);
  IntRect imgRect(IntPoint(), IntSize(image->width(), image->height()));
  const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect);

  // In the case when cropRect doesn't intersect the source image and it
  // requires a umpremul image We immediately return a transparent black image
  // with cropRect.size()
  if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) {
    SkImageInfo info =
        SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight,
                          kN32_SkColorType, kUnpremul_SkAlphaType);
    RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
        static_cast<size_t>(info.width()) * info.height(),
        info.bytesPerPixel());
    if (!dstBuffer)
      return nullptr;
    RefPtr<Uint8Array> dstPixels =
        Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
    return StaticBitmapImage::create(newSkImageFromRaster(
        info, std::move(dstPixels),
        static_cast<size_t>(info.width()) * info.bytesPerPixel()));
  }

  sk_sp<SkImage> skiaImage = image->imageForCurrentFrame();
  // Attempt to get raw unpremultiplied image data, executed only when skiaImage
  // is premultiplied.
  if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) ||
        !skiaImage) &&
       image->data() && imageFormat == PremultiplyAlpha) ||
      colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) {
    std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create(
        image->data(), true,
        parsedOptions.premultiplyAlpha ? ImageDecoder::AlphaPremultiplied
                                       : ImageDecoder::AlphaNotPremultiplied,
        colorSpaceOp));
    if (!decoder)
      return nullptr;
    skiaImage = ImageBitmap::getSkImageFromDecoder(std::move(decoder));
    if (!skiaImage)
      return nullptr;
  }

  if (parsedOptions.cropRect == srcRect && !parsedOptions.shouldScaleInput) {
    sk_sp<SkImage> croppedSkImage = skiaImage->makeSubset(srcRect);
    if (parsedOptions.flipY)
      return StaticBitmapImage::create(flipSkImageVertically(
          croppedSkImage.get(), parsedOptions.premultiplyAlpha
                                    ? PremultiplyAlpha
                                    : DontPremultiplyAlpha));
    // Special case: The first parameter image is unpremul but we need to turn
    // it into premul.
    if (parsedOptions.premultiplyAlpha && imageFormat == DontPremultiplyAlpha)
      return StaticBitmapImage::create(
          unPremulSkImageToPremul(croppedSkImage.get()));
    // Call preroll to trigger image decoding.
    croppedSkImage->preroll();
    return StaticBitmapImage::create(std::move(croppedSkImage));
  }

  sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
      parsedOptions.resizeWidth, parsedOptions.resizeHeight);
  if (!surface)
    return nullptr;
  if (srcRect.isEmpty())
    return StaticBitmapImage::create(surface->makeImageSnapshot());

  SkScalar dstLeft = std::min(0, -parsedOptions.cropRect.x());
  SkScalar dstTop = std::min(0, -parsedOptions.cropRect.y());
  if (parsedOptions.cropRect.x() < 0)
    dstLeft = -parsedOptions.cropRect.x();
  if (parsedOptions.cropRect.y() < 0)
    dstTop = -parsedOptions.cropRect.y();
  if (parsedOptions.flipY) {
    surface->getCanvas()->translate(0, surface->height());
    surface->getCanvas()->scale(1, -1);
  }
  if (parsedOptions.shouldScaleInput) {
    SkRect drawSrcRect = SkRect::MakeXYWH(
        parsedOptions.cropRect.x(), parsedOptions.cropRect.y(),
        parsedOptions.cropRect.width(), parsedOptions.cropRect.height());
    SkRect drawDstRect = SkRect::MakeXYWH(0, 0, parsedOptions.resizeWidth,
                                          parsedOptions.resizeHeight);
    SkPaint paint;
    paint.setFilterQuality(parsedOptions.resizeQuality);
    surface->getCanvas()->drawImageRect(skiaImage, drawSrcRect, drawDstRect,
                                        &paint);
  } else {
    surface->getCanvas()->drawImage(skiaImage, dstLeft, dstTop);
  }
  skiaImage = surface->makeImageSnapshot();

  if (parsedOptions.premultiplyAlpha) {
    if (imageFormat == DontPremultiplyAlpha)
      return StaticBitmapImage::create(
          unPremulSkImageToPremul(skiaImage.get()));
    return StaticBitmapImage::create(std::move(skiaImage));
  }
  return StaticBitmapImage::create(premulSkImageToUnPremul(skiaImage.get()));
}

ImageBitmap::ImageBitmap(HTMLImageElement* image,
                         Optional<IntRect> cropRect,
                         Document* document,
                         const ImageBitmapOptions& options) {
  RefPtr<Image> input = image->cachedImage()->getImage();
  ParsedOptions parsedOptions =
      parseOptions(options, cropRect, image->bitmapSourceSize());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;

  if (options.colorSpaceConversion() == "none")
    m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha,
                        ImageDecoder::GammaAndColorProfileIgnored);
  else
    m_image = cropImage(input.get(), parsedOptions, PremultiplyAlpha,
                        ImageDecoder::GammaAndColorProfileApplied);
  if (!m_image)
    return;
  // In the case where the source image is lazy-decoded, m_image may not be in
  // a decoded state, we trigger it here.
  sk_sp<SkImage> skImage = m_image->imageForCurrentFrame();
  SkPixmap pixmap;
  if (!skImage->isTextureBacked() && !skImage->peekPixels(&pixmap)) {
    sk_sp<SkSurface> surface =
        SkSurface::MakeRasterN32Premul(skImage->width(), skImage->height());
    surface->getCanvas()->drawImage(skImage, 0, 0);
    m_image = StaticBitmapImage::create(surface->makeImageSnapshot());
  }
  if (!m_image)
    return;
  m_image->setOriginClean(
      !image->wouldTaintOrigin(document->getSecurityOrigin()));
  m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}

ImageBitmap::ImageBitmap(HTMLVideoElement* video,
                         Optional<IntRect> cropRect,
                         Document* document,
                         const ImageBitmapOptions& options) {
  IntSize playerSize;
  if (video->webMediaPlayer())
    playerSize = video->webMediaPlayer()->naturalSize();
  ParsedOptions parsedOptions =
      parseOptions(options, cropRect, video->bitmapSourceSize());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;

  std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(
      IntSize(parsedOptions.resizeWidth, parsedOptions.resizeHeight), NonOpaque,
      DoNotInitializeImagePixels);
  if (!buffer)
    return;

  IntPoint dstPoint =
      IntPoint(-parsedOptions.cropRect.x(), -parsedOptions.cropRect.y());
  if (parsedOptions.flipY) {
    buffer->canvas()->translate(0, buffer->size().height());
    buffer->canvas()->scale(1, -1);
  }
  SkPaint paint;
  if (parsedOptions.shouldScaleInput) {
    float scaleRatioX = static_cast<float>(parsedOptions.resizeWidth) /
                        parsedOptions.cropRect.width();
    float scaleRatioY = static_cast<float>(parsedOptions.resizeHeight) /
                        parsedOptions.cropRect.height();
    buffer->canvas()->scale(scaleRatioX, scaleRatioY);
    paint.setFilterQuality(parsedOptions.resizeQuality);
  }
  buffer->canvas()->translate(dstPoint.x(), dstPoint.y());
  video->paintCurrentFrame(
      buffer->canvas(),
      IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())),
      parsedOptions.shouldScaleInput ? &paint : nullptr);

  sk_sp<SkImage> skiaImage =
      buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
  if (!parsedOptions.premultiplyAlpha)
    skiaImage = premulSkImageToUnPremul(skiaImage.get());
  if (!skiaImage)
    return;
  m_image = StaticBitmapImage::create(std::move(skiaImage));
  m_image->setOriginClean(
      !video->wouldTaintOrigin(document->getSecurityOrigin()));
  m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}

ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
                         Optional<IntRect> cropRect,
                         const ImageBitmapOptions& options) {
  ASSERT(canvas->isPaintable());
  RefPtr<Image> input = canvas->copiedImage(BackBuffer, PreferAcceleration);
  ParsedOptions parsedOptions =
      parseOptions(options, cropRect, canvas->bitmapSourceSize());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;

  bool isPremultiplyAlphaReverted = false;
  if (!parsedOptions.premultiplyAlpha) {
    parsedOptions.premultiplyAlpha = true;
    isPremultiplyAlphaReverted = true;
  }
  m_image = cropImage(input.get(), parsedOptions);
  if (!m_image)
    return;
  if (isPremultiplyAlphaReverted) {
    parsedOptions.premultiplyAlpha = false;
    m_image = StaticBitmapImage::create(
        premulSkImageToUnPremul(m_image->imageForCurrentFrame().get()));
  }
  if (!m_image)
    return;
  m_image->setOriginClean(canvas->originClean());
  m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}

ImageBitmap::ImageBitmap(const void* pixelData,
                         uint32_t width,
                         uint32_t height,
                         bool isImageBitmapPremultiplied,
                         bool isImageBitmapOriginClean) {
  SkImageInfo info = SkImageInfo::MakeN32(
      width, height,
      isImageBitmapPremultiplied ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
  SkPixmap pixmap(info, pixelData, info.bytesPerPixel() * width);
  m_image = StaticBitmapImage::create(SkImage::MakeRasterCopy(pixmap));
  if (!m_image)
    return;
  m_image->setPremultiplied(isImageBitmapPremultiplied);
  m_image->setOriginClean(isImageBitmapOriginClean);
}

static sk_sp<SkImage> scaleSkImage(sk_sp<SkImage> skImage,
                                   unsigned resizeWidth,
                                   unsigned resizeHeight,
                                   SkFilterQuality resizeQuality) {
  SkImageInfo resizedInfo = SkImageInfo::Make(
      resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType);
  RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
      resizeWidth * resizeHeight, resizedInfo.bytesPerPixel());
  if (!dstBuffer)
    return nullptr;
  RefPtr<Uint8Array> resizedPixels =
      Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
  SkPixmap pixmap(
      resizedInfo, resizedPixels->data(),
      static_cast<size_t>(resizeWidth) * resizedInfo.bytesPerPixel());
  skImage->scalePixels(pixmap, resizeQuality);
  return SkImage::MakeFromRaster(pixmap,
                                 [](const void*, void* pixels) {
                                   static_cast<Uint8Array*>(pixels)->deref();
                                 },
                                 resizedPixels.release().leakRef());
}

ImageBitmap::ImageBitmap(ImageData* data,
                         Optional<IntRect> cropRect,
                         const ImageBitmapOptions& options) {
  // TODO(xidachen): implement the resize option
  IntRect dataSrcRect = IntRect(IntPoint(), data->size());
  ParsedOptions parsedOptions =
      parseOptions(options, cropRect, data->bitmapSourceSize());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;
  IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect)
                             : dataSrcRect;

  // treat non-premultiplyAlpha as a special case
  if (!parsedOptions.premultiplyAlpha) {
    unsigned char* srcAddr = data->data()->data();

    // Using kN32 type, swizzle input if necessary.
    SkImageInfo info = SkImageInfo::Make(
        parsedOptions.cropRect.width(), parsedOptions.cropRect.height(),
        kN32_SkColorType, kUnpremul_SkAlphaType);
    size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel());
    size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width();
    size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.width();
    sk_sp<SkImage> skImage;
    if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) {
      swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow,
                       parsedOptions.flipY);
      skImage =
          SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow));
      // restore the original ImageData
      swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow,
                       parsedOptions.flipY);
    } else {
      RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull(
          static_cast<size_t>(parsedOptions.cropRect.height()) *
              parsedOptions.cropRect.width(),
          bytesPerPixel);
      if (!dstBuffer)
        return;
      RefPtr<Uint8Array> copiedDataBuffer =
          Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength());
      if (!srcRect.isEmpty()) {
        IntPoint srcPoint = IntPoint(
            (parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0,
            (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0);
        IntPoint dstPoint = IntPoint(
            (parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(),
            (parsedOptions.cropRect.y() >= 0) ? 0
                                              : -parsedOptions.cropRect.y());
        int copyHeight = data->size().height() - srcPoint.y();
        if (parsedOptions.cropRect.height() < copyHeight)
          copyHeight = parsedOptions.cropRect.height();
        int copyWidth = data->size().width() - srcPoint.x();
        if (parsedOptions.cropRect.width() < copyWidth)
          copyWidth = parsedOptions.cropRect.width();
        for (int i = 0; i < copyHeight; i++) {
          size_t srcStartCopyPosition =
              (i + srcPoint.y()) * srcPixelBytesPerRow +
              srcPoint.x() * bytesPerPixel;
          size_t srcEndCopyPosition =
              srcStartCopyPosition + copyWidth * bytesPerPixel;
          size_t dstStartCopyPosition;
          if (parsedOptions.flipY)
            dstStartCopyPosition =
                (parsedOptions.cropRect.height() - 1 - dstPoint.y() - i) *
                    dstPixelBytesPerRow +
                dstPoint.x() * bytesPerPixel;
          else
            dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow +
                                   dstPoint.x() * bytesPerPixel;
          for (size_t j = 0; j < srcEndCopyPosition - srcStartCopyPosition;
               j++) {
            // swizzle when necessary
            if (kN32_SkColorType == kBGRA_8888_SkColorType) {
              if (j % 4 == 0)
                copiedDataBuffer->data()[dstStartCopyPosition + j] =
                    srcAddr[srcStartCopyPosition + j + 2];
              else if (j % 4 == 2)
                copiedDataBuffer->data()[dstStartCopyPosition + j] =
                    srcAddr[srcStartCopyPosition + j - 2];
              else
                copiedDataBuffer->data()[dstStartCopyPosition + j] =
                    srcAddr[srcStartCopyPosition + j];
            } else {
              copiedDataBuffer->data()[dstStartCopyPosition + j] =
                  srcAddr[srcStartCopyPosition + j];
            }
          }
        }
      }
      skImage = newSkImageFromRaster(info, std::move(copiedDataBuffer),
                                     dstPixelBytesPerRow);
    }
    if (!skImage)
      return;
    if (parsedOptions.shouldScaleInput)
      m_image = StaticBitmapImage::create(scaleSkImage(
          skImage, parsedOptions.resizeWidth, parsedOptions.resizeHeight,
          parsedOptions.resizeQuality));
    else
      m_image = StaticBitmapImage::create(skImage);
    if (!m_image)
      return;
    m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
    return;
  }

  std::unique_ptr<ImageBuffer> buffer = ImageBuffer::create(
      parsedOptions.cropRect.size(), NonOpaque, DoNotInitializeImagePixels);
  if (!buffer)
    return;

  if (srcRect.isEmpty()) {
    m_image = StaticBitmapImage::create(buffer->newSkImageSnapshot(
        PreferNoAcceleration, SnapshotReasonUnknown));
    return;
  }

  IntPoint dstPoint = IntPoint(std::min(0, -parsedOptions.cropRect.x()),
                               std::min(0, -parsedOptions.cropRect.y()));
  if (parsedOptions.cropRect.x() < 0)
    dstPoint.setX(-parsedOptions.cropRect.x());
  if (parsedOptions.cropRect.y() < 0)
    dstPoint.setY(-parsedOptions.cropRect.y());
  buffer->putByteArray(Unmultiplied, data->data()->data(), data->size(),
                       srcRect, dstPoint);
  sk_sp<SkImage> skImage =
      buffer->newSkImageSnapshot(PreferNoAcceleration, SnapshotReasonUnknown);
  if (parsedOptions.flipY)
    skImage = flipSkImageVertically(skImage.get(), PremultiplyAlpha);
  if (!skImage)
    return;
  if (parsedOptions.shouldScaleInput) {
    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(
        parsedOptions.resizeWidth, parsedOptions.resizeHeight);
    if (!surface)
      return;
    SkPaint paint;
    paint.setFilterQuality(parsedOptions.resizeQuality);
    SkRect dstDrawRect =
        SkRect::MakeWH(parsedOptions.resizeWidth, parsedOptions.resizeHeight);
    surface->getCanvas()->drawImageRect(skImage, dstDrawRect, &paint);
    skImage = surface->makeImageSnapshot();
  }
  m_image = StaticBitmapImage::create(std::move(skImage));
}

ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
                         Optional<IntRect> cropRect,
                         const ImageBitmapOptions& options) {
  RefPtr<Image> input = bitmap->bitmapImage();
  if (!input)
    return;
  ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;

  m_image = cropImage(input.get(), parsedOptions, bitmap->isPremultiplied()
                                                      ? PremultiplyAlpha
                                                      : DontPremultiplyAlpha);
  if (!m_image)
    return;
  m_image->setOriginClean(bitmap->originClean());
  m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}

ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image,
                         Optional<IntRect> cropRect,
                         const ImageBitmapOptions& options) {
  bool originClean = image->originClean();
  RefPtr<Image> input = image;
  ParsedOptions parsedOptions = parseOptions(options, cropRect, input->size());
  if (dstBufferSizeHasOverflow(parsedOptions))
    return;

  m_image = cropImage(input.get(), parsedOptions);
  if (!m_image)
    return;

  m_image->setOriginClean(originClean);
  m_image->setPremultiplied(parsedOptions.premultiplyAlpha);
}

ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) {
  m_image = image;
}

PassRefPtr<StaticBitmapImage> ImageBitmap::transfer() {
  ASSERT(!isNeutered());
  m_isNeutered = true;
  m_image->transfer();
  return m_image.release();
}

ImageBitmap::~ImageBitmap() {}

ImageBitmap* ImageBitmap::create(HTMLImageElement* image,
                                 Optional<IntRect> cropRect,
                                 Document* document,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(image, cropRect, document, options);
}

ImageBitmap* ImageBitmap::create(HTMLVideoElement* video,
                                 Optional<IntRect> cropRect,
                                 Document* document,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(video, cropRect, document, options);
}

ImageBitmap* ImageBitmap::create(HTMLCanvasElement* canvas,
                                 Optional<IntRect> cropRect,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(canvas, cropRect, options);
}

ImageBitmap* ImageBitmap::create(ImageData* data,
                                 Optional<IntRect> cropRect,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(data, cropRect, options);
}

ImageBitmap* ImageBitmap::create(ImageBitmap* bitmap,
                                 Optional<IntRect> cropRect,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(bitmap, cropRect, options);
}

ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image,
                                 Optional<IntRect> cropRect,
                                 const ImageBitmapOptions& options) {
  return new ImageBitmap(std::move(image), cropRect, options);
}

ImageBitmap* ImageBitmap::create(PassRefPtr<StaticBitmapImage> image) {
  return new ImageBitmap(std::move(image));
}

ImageBitmap* ImageBitmap::create(const void* pixelData,
                                 uint32_t width,
                                 uint32_t height,
                                 bool isImageBitmapPremultiplied,
                                 bool isImageBitmapOriginClean) {
  return new ImageBitmap(pixelData, width, height, isImageBitmapPremultiplied,
                         isImageBitmapOriginClean);
}

void ImageBitmap::close() {
  if (!m_image || m_isNeutered)
    return;
  m_image.clear();
  m_isNeutered = true;
}

// static
ImageBitmap* ImageBitmap::take(ScriptPromiseResolver*, sk_sp<SkImage> image) {
  return ImageBitmap::create(StaticBitmapImage::create(std::move(image)));
}

PassRefPtr<Uint8Array> ImageBitmap::copyBitmapData(AlphaDisposition alphaOp,
                                                   DataColorFormat format) {
  SkImageInfo info = SkImageInfo::Make(
      width(), height(),
      (format == RGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType,
      (alphaOp == PremultiplyAlpha) ? kPremul_SkAlphaType
                                    : kUnpremul_SkAlphaType);
  RefPtr<Uint8Array> dstPixels =
      copySkImageData(m_image->imageForCurrentFrame().get(), info);
  return dstPixels.release();
}

unsigned long ImageBitmap::width() const {
  if (!m_image)
    return 0;
  ASSERT(m_image->width() > 0);
  return m_image->width();
}

unsigned long ImageBitmap::height() const {
  if (!m_image)
    return 0;
  ASSERT(m_image->height() > 0);
  return m_image->height();
}

bool ImageBitmap::isAccelerated() const {
  return m_image && (m_image->isTextureBacked() || m_image->hasMailbox());
}

IntSize ImageBitmap::size() const {
  if (!m_image)
    return IntSize();
  ASSERT(m_image->width() > 0 && m_image->height() > 0);
  return IntSize(m_image->width(), m_image->height());
}

ScriptPromise ImageBitmap::createImageBitmap(ScriptState* scriptState,
                                             EventTarget& eventTarget,
                                             Optional<IntRect> cropRect,
                                             const ImageBitmapOptions& options,
                                             ExceptionState& exceptionState) {
  if ((cropRect &&
       !isSourceSizeValid(cropRect->width(), cropRect->height(),
                          exceptionState)) ||
      !isSourceSizeValid(width(), height(), exceptionState))
    return ScriptPromise();
  if (!isResizeOptionValid(options, exceptionState))
    return ScriptPromise();
  return ImageBitmapSource::fulfillImageBitmap(scriptState,
                                               create(this, cropRect, options));
}

PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(
    SourceImageStatus* status,
    AccelerationHint,
    SnapshotReason,
    const FloatSize&) const {
  *status = NormalSourceImageStatus;
  return m_image ? m_image : nullptr;
}

void ImageBitmap::adjustDrawRects(FloatRect* srcRect,
                                  FloatRect* dstRect) const {}

FloatSize ImageBitmap::elementSize(const FloatSize&) const {
  return FloatSize(width(), height());
}

DEFINE_TRACE(ImageBitmap) {}

}  // namespace blink
