/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ImageBitmap.h"

#include "BitmapImage.h"
#include "Blob.h"
#include "CSSStyleImageValue.h"
#include "CachedImage.h"
#include "ExceptionCode.h"
#include "ExceptionOr.h"
#include "FileReaderLoader.h"
#include "FileReaderLoaderClient.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
#include "HTMLImageElement.h"
#include "HTMLVideoElement.h"
#include "ImageBitmapOptions.h"
#include "ImageBuffer.h"
#include "ImageData.h"
#include "IntRect.h"
#include "JSDOMPromiseDeferred.h"
#include "JSImageBitmap.h"
#include "LayoutSize.h"
#if ENABLE(OFFSCREEN_CANVAS)
#include "OffscreenCanvas.h"
#endif
#include "RenderElement.h"
#include "SharedBuffer.h"
#include "SuspendableTimer.h"
#include <variant>
#include <wtf/IsoMallocInlines.h>
#include <wtf/Scope.h>
#include <wtf/StdLibExtras.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(ImageBitmap);

#if USE(IOSURFACE_CANVAS_BACKING_STORE)
static RenderingMode bufferRenderingMode = RenderingMode::Accelerated;
#else
static RenderingMode bufferRenderingMode = RenderingMode::Unaccelerated;
#endif

Ref<ImageBitmap> ImageBitmap::create(ScriptExecutionContext& scriptExecutionContext, const IntSize& size, DestinationColorSpace colorSpace)
{
    return create({ createImageBuffer(scriptExecutionContext, size, bufferRenderingMode, colorSpace) });
}

Ref<ImageBitmap> ImageBitmap::create(std::optional<ImageBitmapBacking>&& backingStore)
{
    return adoptRef(*new ImageBitmap(WTFMove(backingStore)));
}

RefPtr<ImageBuffer> ImageBitmap::createImageBuffer(ScriptExecutionContext& scriptExecutionContext, const FloatSize& size, RenderingMode renderingMode, DestinationColorSpace colorSpace, float resolutionScale)
{
    // FIXME: Should avoid converting color space and pixel format of image sources.
    auto imageBufferColorSpace = colorSpace.asRGB();
    if (!imageBufferColorSpace) {
#if ENABLE(DESTINATION_COLOR_SPACE_DISPLAY_P3)
        imageBufferColorSpace = DestinationColorSpace::DisplayP3();
#else
        imageBufferColorSpace = DestinationColorSpace::SRGB();
#endif
    }

    if (scriptExecutionContext.isDocument()) {
        auto& document = downcast<Document>(scriptExecutionContext);
        if (document.view() && document.view()->root()) {
            auto hostWindow = document.view()->root()->hostWindow();
            return ImageBuffer::create(size, renderingMode, ShouldUseDisplayList::No, RenderingPurpose::Canvas, resolutionScale, *imageBufferColorSpace, PixelFormat::BGRA8, hostWindow);
        }
    }

    // FIXME <https://webkit.org/b/218482> Enable worker based ImageBitmap and OffscreenCanvas drawing to use GPU Process rendering
    return ImageBuffer::create(size, renderingMode, resolutionScale, *imageBufferColorSpace, PixelFormat::BGRA8);
}

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, ImageBitmap::Source&& source, ImageBitmapOptions&& options, ImageBitmap::Promise&& promise)
{
    WTF::switchOn(source,
        [&] (auto& specificSource) {
            createPromise(scriptExecutionContext, specificSource, WTFMove(options), std::nullopt, WTFMove(promise));
        }
    );
}

Vector<std::optional<ImageBitmapBacking>> ImageBitmap::detachBitmaps(Vector<RefPtr<ImageBitmap>>&& bitmaps)
{
    Vector<std::optional<ImageBitmapBacking>> buffers;
    for (auto& bitmap : bitmaps)
        buffers.append(bitmap->takeImageBitmapBacking());
    return buffers;
}

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, ImageBitmap::Source&& source, ImageBitmapOptions&& options, int sx, int sy, int sw, int sh, ImageBitmap::Promise&& promise)
{
    // 1. If either the sw or sh arguments are specified but zero, return a promise
    //    rejected with an "RangeError" DOMException and abort these steps.
    if (!sw || !sh) {
        promise.reject(RangeError, "Cannot create ImageBitmap with a width or height of 0");
        return;
    }

    auto left = sw >= 0 ? sx : sx + sw;
    auto top = sh >= 0 ? sy : sy + sh;
    auto width = std::abs(sw);
    auto height = std::abs(sh);

    WTF::switchOn(source,
        [&] (auto& specificSource) {
            createPromise(scriptExecutionContext, specificSource, WTFMove(options), IntRect { left, top, width, height }, WTFMove(promise));
        }
    );
}

static bool taintsOrigin(CachedImage& cachedImage)
{
    auto* image = cachedImage.image();
    if (!image)
        return false;

    if (image->sourceURL().protocolIsData())
        return false;

    if (!image->hasSingleSecurityOrigin())
        return true;

    if (!cachedImage.isCORSSameOrigin())
        return true;

    return false;
}

#if ENABLE(VIDEO)
static bool taintsOrigin(SecurityOrigin* origin, HTMLVideoElement& video)
{
    if (!video.hasSingleSecurityOrigin())
        return true;

    if (video.player()->didPassCORSAccessCheck())
        return false;

    auto url = video.currentSrc();
    if (url.protocolIsData())
        return false;

    return !origin->canRequest(url);
}
#endif

// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#cropped-to-the-source-rectangle-with-formatting
static ExceptionOr<IntRect> croppedSourceRectangleWithFormatting(IntSize inputSize, ImageBitmapOptions& options, std::optional<IntRect> rect)
{
    // 2. If either or both of resizeWidth and resizeHeight members of options are less
    //    than or equal to 0, then return a promise rejected with "InvalidStateError"
    //    DOMException and abort these steps.
    if ((options.resizeWidth && options.resizeWidth.value() <= 0) || (options.resizeHeight && options.resizeHeight.value() <= 0))
        return Exception { InvalidStateError, "Invalid resize dimensions" };

    // 3. If sx, sy, sw and sh are specified, let sourceRectangle be a rectangle whose
    //    corners are the four points (sx, sy), (sx+sw, sy),(sx+sw, sy+sh), (sx,sy+sh).
    //    Otherwise let sourceRectangle be a rectangle whose corners are the four points
    //    (0,0), (width of input, 0), (width of input, height of input), (0, height of
    //    input).
    auto sourceRectangle = rect.value_or(IntRect { 0, 0, inputSize.width(), inputSize.height() });

    // 4. Clip sourceRectangle to the dimensions of input.
    sourceRectangle.intersect(IntRect { 0, 0, inputSize.width(), inputSize.height() });

    return { WTFMove(sourceRectangle) };
}

static IntSize outputSizeForSourceRectangle(IntRect sourceRectangle, ImageBitmapOptions& options)
{
    // 5. Let outputWidth be determined as follows:
    auto outputWidth = [&] () -> int {
        if (options.resizeWidth)
            return options.resizeWidth.value();
        if (options.resizeHeight)
            return ceil(sourceRectangle.width() * static_cast<double>(options.resizeHeight.value()) / sourceRectangle.height());
        return sourceRectangle.width();
    }();

    // 6. Let outputHeight be determined as follows:
    auto outputHeight = [&] () -> int {
        if (options.resizeHeight)
            return options.resizeHeight.value();
        if (options.resizeWidth)
            return ceil(sourceRectangle.height() * static_cast<double>(options.resizeWidth.value()) / sourceRectangle.width());
        return sourceRectangle.height();
    }();

    return { outputWidth, outputHeight };
}

static InterpolationQuality interpolationQualityForResizeQuality(ImageBitmapOptions::ResizeQuality resizeQuality)
{
    switch (resizeQuality) {
    case ImageBitmapOptions::ResizeQuality::Pixelated:
        return InterpolationQuality::DoNotInterpolate;
    case ImageBitmapOptions::ResizeQuality::Low:
        return InterpolationQuality::Default; // Low is the default.
    case ImageBitmapOptions::ResizeQuality::Medium:
        return InterpolationQuality::Medium;
    case ImageBitmapOptions::ResizeQuality::High:
        return InterpolationQuality::High;
    }
    ASSERT_NOT_REACHED();
    return InterpolationQuality::Default;
}

static AlphaPremultiplication alphaPremultiplicationForPremultiplyAlpha(ImageBitmapOptions::PremultiplyAlpha premultiplyAlpha)
{
    // The default is to premultiply - this is the least surprising behavior.
    if (premultiplyAlpha == ImageBitmapOptions::PremultiplyAlpha::None)
        return AlphaPremultiplication::Unpremultiplied;
    return AlphaPremultiplication::Premultiplied;
}

void ImageBitmap::resolveWithBlankImageBuffer(ScriptExecutionContext& scriptExecutionContext, bool originClean, Promise&& promise)
{
    // Source rectangle likely doesn't intersect the source image.
    // Behavior isn't well specified, but WPT tests expect no Promise rejection (and of course no crashes).
    // Resolve Promise with a blank 1x1 ImageBitmap.
    auto bitmapData = createImageBuffer(scriptExecutionContext, FloatSize(1, 1), bufferRenderingMode, DestinationColorSpace::SRGB());

    // 9. If the origin of image's image is not the same origin as the origin specified by the
    //    entry settings object, then set the origin-clean flag of the ImageBitmap object's
    //    bitmap to false.
    OptionSet<SerializationState> serializationState;
    if (originClean)
        serializationState.add(SerializationState::OriginClean);
    
    // 7. Create a new ImageBitmap object.
    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    // 10. Return a new promise, but continue running these steps in parallel.
    // 11. Resolve the promise with the new ImageBitmap object as the value.
    promise.resolve(WTFMove(imageBitmap));
}

// FIXME: More steps from https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#cropped-to-the-source-rectangle-with-formatting

// 7. Place input on an infinite transparent black grid plane, positioned so that its
//    top left corner is at the origin of the plane, with the x-coordinate increasing
//    to the right, and the y-coordinate increasing down, and with each pixel in the
//    input image data occupying a cell on the plane's grid.

// 8. Let output be the rectangle on the plane denoted by sourceRectangle.

// 9. Scale output to the size specified by outputWidth and outputHeight. The user
//    agent should use the value of the resizeQuality option to guide the choice of
//    scaling algorithm.

// 10. If the value of the imageOrientation member of options is "flipY", output must
//     be flipped vertically, disregarding any image orientation metadata of the source
//     (such as EXIF metadata), if any.

// 11. If image is an img element or a Blob object, let val be the value of the
//     colorSpaceConversion member of options, and then run these substeps:
//
//     1. If val is "default", the color space conversion behavior is implementation-specific,
//        and should be chosen according to the color space that the implementation uses for
//        drawing images onto the canvas.
//
//     2. If val is "none", output must be decoded without performing any color space
//        conversions. This means that the image decoding algorithm must ignore color profile
//        metadata embedded in the source data as well as the display device color profile.

// 12. Let val be the value of premultiplyAlpha member of options, and then run these substeps:
//
//     1. If val is "default", the alpha premultiplication behavior is implementation-specific,
//        and should be chosen according to implementation deems optimal for drawing images
//        onto the canvas.
//
//     2. If val is "premultiply", the output that is not premultiplied by alpha must have its
//        color components multiplied by alpha and that is premultiplied by alpha must be left
//        untouched.
//
//     3. If val is "none", the output that is not premultiplied by alpha must be left untouched
//        and that is premultiplied by alpha must have its color components divided by alpha.

// 13. Return output.

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<HTMLImageElement>& imageElement, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // 2. If image is not completely available, then return a promise rejected with
    // an "InvalidStateError" DOMException and abort these steps.

    auto* cachedImage = imageElement->cachedImage();
    if (!cachedImage || !imageElement->complete()) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap that is not completely available");
        return;
    }

    // 3. If image's media data has no intrinsic dimensions (e.g. it's a vector graphic
    //    with no specified content size), and both or either of the resizeWidth and
    //    resizeHeight options are not specified, then return a promise rejected with
    //    an "InvalidStateError" DOMException and abort these steps.

    auto imageSize = cachedImage->imageSizeForRenderer(imageElement->renderer(), 1.0f);
    if ((!imageSize.width() || !imageSize.height()) && (!options.resizeWidth || !options.resizeHeight)) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from a source with no intrinsic size without providing resize dimensions");
        return;
    }

    // 4. If image's media data has no intrinsic dimensions (e.g. it's a vector graphics
    //    with no specified content size), it should be rendered to a bitmap of the size
    //    specified by the resizeWidth and the resizeHeight options.

    if (!imageSize.width() && !imageSize.height()) {
        imageSize.setWidth(options.resizeWidth.value());
        imageSize.setHeight(options.resizeHeight.value());
    }

    // 5. If the sw and sh arguments are not specified and image's media data has both or
    //    either of its intrinsic width and intrinsic height values equal to 0, then return
    //    a promise rejected with an "InvalidStateError" DOMException and abort these steps.
    // 6. If the sh argument is not specified and image's media data has an intrinsic height
    //    of 0, then return a promise rejected with an "InvalidStateError" DOMException and
    //    abort these steps.

    // FIXME: It's unclear how these steps can happen, since step 4 required setting a
    // width and height for the image.

    if (!rect && (!imageSize.width() || !imageSize.height())) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from a source with no intrinsic size without providing dimensions");
        return;
    }

    // 8. Let the ImageBitmap object's bitmap data be a copy of image's media data, cropped to
    //    the source rectangle with formatting. If this is an animated image, the ImageBitmap
    //    object's bitmap data must only be taken from the default image of the animation (the
    //    one that the format defines is to be used when animation is not supported or is disabled),
    //    or, if there is no such image, the first frame of the animation.

    auto sourceRectangle = croppedSourceRectangleWithFormatting(roundedIntSize(imageSize), options, WTFMove(rect));
    if (sourceRectangle.hasException()) {
        promise.reject(sourceRectangle.releaseException());
        return;
    }

    auto imageForRenderer = cachedImage->imageForRenderer(imageElement->renderer());
    if (!imageForRenderer) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from image that can't be rendered");
        return;
    }

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, imageForRenderer->colorSpace());
    if (!bitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, !taintsOrigin(*cachedImage), WTFMove(promise));
        return;
    }

    auto orientation = imageForRenderer->orientation();
    if (orientation == ImageOrientation::FromImage)
        orientation = ImageOrientation::None;

    FloatRect destRect(FloatPoint(), outputSize);
    bitmapData->context().drawImage(*imageForRenderer, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(orientation) });

    // 9. If the origin of image's image is not the same origin as the origin specified by the
    //    entry settings object, then set the origin-clean flag of the ImageBitmap object's
    //    bitmap to false.
    OptionSet<SerializationState> serializationState;
    if (!taintsOrigin(*cachedImage))
        serializationState.add(SerializationState::OriginClean);

    if (alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha) == AlphaPremultiplication::Premultiplied)
        serializationState.add(SerializationState::PremultiplyAlpha);

    // 7. Create a new ImageBitmap object.
    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    // 10. Return a new promise, but continue running these steps in parallel.
    // 11. Resolve the promise with the new ImageBitmap object as the value.

    promise.resolve(WTFMove(imageBitmap));
}

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<HTMLCanvasElement>& canvasElement, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    createPromise(scriptExecutionContext, *canvasElement, WTFMove(options), WTFMove(rect), WTFMove(promise));
}

#if ENABLE(OFFSCREEN_CANVAS)
void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<OffscreenCanvas>& canvasElement, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    createPromise(scriptExecutionContext, *canvasElement, WTFMove(options), WTFMove(rect), WTFMove(promise));
}
#endif

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, CanvasBase& canvas, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // 2. If the canvas element's bitmap has either a horizontal dimension or a vertical
    //    dimension equal to zero, then return a promise rejected with an "InvalidStateError"
    //    DOMException and abort these steps.
    auto size = canvas.size();
    if (!size.width() || !size.height()) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from a canvas that has zero width or height");
        return;
    }

    // 4. Let the ImageBitmap object's bitmap data be a copy of the canvas element's bitmap
    //    data, cropped to the source rectangle with formatting.

    auto sourceRectangle = croppedSourceRectangleWithFormatting(size, options, WTFMove(rect));
    if (sourceRectangle.hasException()) {
        promise.reject(sourceRectangle.releaseException());
        return;
    }

    auto imageForRender = canvas.copiedImage();
    if (!imageForRender) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from canvas that can't be rendered");
        return;
    }

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, imageForRender->colorSpace());

    if (!bitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, canvas.originClean(), WTFMove(promise));
        return;
    }

    FloatRect destRect(FloatPoint(), outputSize);
    bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });

    // 5. Set the origin-clean flag of the ImageBitmap object's bitmap to the same value as
    //    the origin-clean flag of the canvas element's bitmap.
    OptionSet<SerializationState> serializationState;
    if (canvas.originClean())
        serializationState.add(SerializationState::OriginClean);

    if (alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha) == AlphaPremultiplication::Premultiplied)
        serializationState.add(SerializationState::PremultiplyAlpha);

    // 3. Create a new ImageBitmap object.
    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    // 6. Return a new promise, but continue running these steps in parallel.
    // 7. Resolve the promise with the new ImageBitmap object as the value.

    promise.resolve(WTFMove(imageBitmap));
}

#if ENABLE(VIDEO)
void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<HTMLVideoElement>& video, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // https://html.spec.whatwg.org/multipage/#dom-createimagebitmap
    // WHATWG HTML 2102913b313078cd8eeac7e81e6a8756cbd3e773
    // Steps 3-7.
    // (Step 3 is handled in croppedSourceRectangleWithFormatting.)

    // 4. Check the usability of the image argument. If this throws an exception
    //    or returns bad, then return p rejected with an "InvalidStateError"
    //    DOMException.
    if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap before the HTMLVideoElement has data");
        return;
    }

    // 6.1. If image's networkState attribute is NETWORK_EMPTY, then return p
    //      rejected with an "InvalidStateError" DOMException.
    if (video->networkState() == HTMLMediaElement::NETWORK_EMPTY) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap before the HTMLVideoElement has data");
        return;
    }

    // 6.2. Set imageBitmap's bitmap data to a copy of the frame at the current
    //      playback position, at the media resource's intrinsic width and
    //      intrinsic height (i.e., after any aspect-ratio correction has been
    //      applied), cropped to the source rectangle with formatting.
    auto size = video->player() ? roundedIntSize(video->player()->naturalSize()) : IntSize();
    auto maybeSourceRectangle = croppedSourceRectangleWithFormatting(size, options, WTFMove(rect));
    if (maybeSourceRectangle.hasException()) {
        promise.reject(maybeSourceRectangle.releaseException());
        return;
    }
    auto sourceRectangle = maybeSourceRectangle.releaseReturnValue();

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle, options);

    auto colorSpace = video->colorSpace();
    if (!colorSpace)
        colorSpace = DestinationColorSpace::SRGB();

    // FIXME: Add support for pixel formats to ImageBitmap.
    auto bitmapData = video->createBufferForPainting(outputSize, bufferRenderingMode, *colorSpace, PixelFormat::BGRA8);
    if (!bitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, !taintsOrigin(scriptExecutionContext.securityOrigin(), *video), WTFMove(promise));
        return;
    }

    {
        GraphicsContext& c = bitmapData->context();
        GraphicsContextStateSaver stateSaver(c);
        c.clip(FloatRect(FloatPoint(), outputSize));
        auto scaleX = float(outputSize.width()) / float(sourceRectangle.width());
        auto scaleY = float(outputSize.height()) / float(sourceRectangle.height());
        if (options.orientation == ImageBitmapOptions::Orientation::FlipY) {
            c.scale(FloatSize(scaleX, -scaleY));
            c.translate(IntPoint(-sourceRectangle.location().x(), sourceRectangle.location().y() - outputSize.height()));
        } else {
            c.scale(FloatSize(scaleX, scaleY));
            c.translate(-sourceRectangle.location());
        }
        video->paintCurrentFrameInContext(c, FloatRect(FloatPoint(), size));
    }

    // 6.3. If the origin of image's video is not same origin with entry
    //      settings object's origin, then set the origin-clean flag of
    //      image's bitmap to false.
    OptionSet<SerializationState> serializationState;
    if (!taintsOrigin(scriptExecutionContext.securityOrigin(), *video))
        serializationState.add(SerializationState::OriginClean);

    if (alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha) == AlphaPremultiplication::Premultiplied)
        serializationState.add(SerializationState::PremultiplyAlpha);

    // 5. Let imageBitmap be a new ImageBitmap object.
    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    // 6.4.1. Resolve p with imageBitmap.
    promise.resolve(WTFMove(imageBitmap));
}
#endif

#if ENABLE(CSS_TYPED_OM)
void ImageBitmap::createPromise(ScriptExecutionContext&, RefPtr<CSSStyleImageValue>&, ImageBitmapOptions&&, std::optional<IntRect>, ImageBitmap::Promise&& promise)
{
    promise.reject(InvalidStateError, "Not implemented");
}
#endif

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<ImageBitmap>& existingImageBitmap, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // 2. If image's [[Detached]] internal slot value is true, return a promise
    //    rejected with an "InvalidStateError" DOMException and abort these steps.
    if (existingImageBitmap->isDetached() || !existingImageBitmap->buffer()) {
        promise.reject(InvalidStateError, "Cannot create ImageBitmap from a detached ImageBitmap");
        return;
    }

    // 4. Let the ImageBitmap object's bitmap data be a copy of the image argument's
    //    bitmap data, cropped to the source rectangle with formatting.
    auto sourceRectangle = croppedSourceRectangleWithFormatting(existingImageBitmap->buffer()->truncatedLogicalSize(), options, WTFMove(rect));
    if (sourceRectangle.hasException()) {
        promise.reject(sourceRectangle.releaseException());
        return;
    }

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, existingImageBitmap->buffer()->colorSpace());

    if (!bitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, existingImageBitmap->originClean(), WTFMove(promise));
        return;
    }

    auto imageForRender = existingImageBitmap->buffer()->copyImage();

    FloatRect destRect(FloatPoint(), outputSize);
    bitmapData->context().drawImage(*imageForRender, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });

    // 5. Set the origin-clean flag of the ImageBitmap object's bitmap to the same
    //    value as the origin-clean flag of the bitmap of the image argument.
    OptionSet<SerializationState> serializationState;
    if (existingImageBitmap->originClean())
        serializationState.add(SerializationState::OriginClean);

    if (alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha) == AlphaPremultiplication::Premultiplied) {
        serializationState.add(SerializationState::PremultiplyAlpha);

        // At least in the Core Graphics backend, when creating an ImageBitmap from
        // an ImageBitmap, the alpha channel of bitmapData isn't premultiplied even
        // though the alpha mode of the internal surface claims it is. Instruct
        // users of this ImageBitmap to ignore the internal surface's alpha mode.
        serializationState.add(SerializationState::ForciblyPremultiplyAlpha);
    }

    // 3. Create a new ImageBitmap object.
    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    // 6. Return a new promise, but continue running these steps in parallel.
    // 7. Resolve the promise with the new ImageBitmap object as the value.
    promise.resolve(WTFMove(imageBitmap));
}

class ImageBitmapImageObserver final : public RefCounted<ImageBitmapImageObserver>, public ImageObserver {
public:
    static Ref<ImageBitmapImageObserver> create(String mimeType, long long expectedContentLength, const URL& sourceUrl)
    {
        return adoptRef(*new ImageBitmapImageObserver(mimeType, expectedContentLength, sourceUrl));
    }

    URL sourceUrl() const override { return m_sourceUrl; }
    String mimeType() const override { return m_mimeType; }
    long long expectedContentLength() const override { return m_expectedContentLength; }

    void decodedSizeChanged(const Image&, long long) override { }

    void didDraw(const Image&) override { }

    bool canDestroyDecodedData(const Image&) override { return true; }
    void imageFrameAvailable(const Image&, ImageAnimatingState, const IntRect* = nullptr, DecodingStatus = DecodingStatus::Invalid) override { }
    void changedInRect(const Image&, const IntRect* = nullptr) override { }
    void scheduleRenderingUpdate(const Image&) override { }

private:
    ImageBitmapImageObserver(String mimeType, long long expectedContentLength, const URL& sourceUrl)
        : m_mimeType(mimeType)
        , m_expectedContentLength(expectedContentLength)
        , m_sourceUrl(sourceUrl)
    { }

    String m_mimeType;
    long long m_expectedContentLength;
    URL m_sourceUrl;
};

class PendingImageBitmap final : public ActiveDOMObject, public FileReaderLoaderClient {
    WTF_MAKE_FAST_ALLOCATED;
public:
    static void fetch(ScriptExecutionContext& scriptExecutionContext, RefPtr<Blob>&& blob, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
    {
        if (scriptExecutionContext.activeDOMObjectsAreStopped())
            return;
        auto pendingImageBitmap = new PendingImageBitmap(scriptExecutionContext, WTFMove(blob), WTFMove(options), WTFMove(rect), WTFMove(promise));
        pendingImageBitmap->start(scriptExecutionContext);
    }

private:
    PendingImageBitmap(ScriptExecutionContext& scriptExecutionContext, RefPtr<Blob>&& blob, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
        : ActiveDOMObject(&scriptExecutionContext)
        , m_blobLoader(FileReaderLoader::ReadAsArrayBuffer, this)
        , m_blob(WTFMove(blob))
        , m_options(WTFMove(options))
        , m_rect(WTFMove(rect))
        , m_promise(WTFMove(promise))
        , m_createImageBitmapTimer(&scriptExecutionContext, *this, &PendingImageBitmap::createImageBitmapAndResolvePromise)
    {
        suspendIfNeeded();
        m_createImageBitmapTimer.suspendIfNeeded();
    }

    void start(ScriptExecutionContext& scriptExecutionContext)
    {
        m_blobLoader.start(&scriptExecutionContext, *m_blob);
    }

    // ActiveDOMObject

    const char* activeDOMObjectName() const final
    {
        return "PendingImageBitmap";
    }

    void stop() final
    {
        delete this;
    }

    // FileReaderLoaderClient

    void didStartLoading() override
    {
    }

    void didReceiveData() override
    {
    }

    void didFinishLoading() override
    {
        createImageBitmapAndResolvePromiseSoon(m_blobLoader.arrayBufferResult());
    }

    void didFail(ExceptionCode) override
    {
        createImageBitmapAndResolvePromiseSoon(nullptr);
    }

    void createImageBitmapAndResolvePromiseSoon(RefPtr<ArrayBuffer>&& arrayBuffer)
    {
        ASSERT(!m_createImageBitmapTimer.isActive());
        m_arrayBufferToProcess = WTFMove(arrayBuffer);
        m_createImageBitmapTimer.startOneShot(0_s);
    }

    void createImageBitmapAndResolvePromise()
    {
        auto destroyOnExit = makeScopeExit([this] {
            delete this;
        });

        if (!m_arrayBufferToProcess) {
            m_promise.reject(InvalidStateError, "An error occured reading the Blob argument to createImageBitmap");
            return;
        }

        ImageBitmap::createFromBuffer(*scriptExecutionContext(), m_arrayBufferToProcess.releaseNonNull(), m_blob->type(), m_blob->size(), m_blobLoader.url(), WTFMove(m_options), WTFMove(m_rect), WTFMove(m_promise));
    }

    FileReaderLoader m_blobLoader;
    RefPtr<Blob> m_blob;
    ImageBitmapOptions m_options;
    std::optional<IntRect> m_rect;
    ImageBitmap::Promise m_promise;
    SuspendableTimer m_createImageBitmapTimer;
    RefPtr<ArrayBuffer> m_arrayBufferToProcess;
};

void ImageBitmap::createFromBuffer(ScriptExecutionContext& scriptExecutionContext, Ref<ArrayBuffer>&& arrayBuffer, String mimeType, long long expectedContentLength, const URL& sourceURL, ImageBitmapOptions&& options, std::optional<IntRect> rect, Promise&& promise)
{
    if (!arrayBuffer->byteLength()) {
        promise.reject(InvalidStateError, "Cannot create an ImageBitmap from an empty buffer");
        return;
    }

    auto sharedBuffer = SharedBuffer::create(static_cast<const char*>(arrayBuffer->data()), arrayBuffer->byteLength());
    auto observer = ImageBitmapImageObserver::create(mimeType, expectedContentLength, sourceURL);
    auto image = BitmapImage::create(observer.ptr());
    auto result = image->setData(sharedBuffer.copyRef(), true);
    if (result != EncodedDataStatus::Complete || image->isNull()) {
        promise.reject(InvalidStateError, "Cannot decode the data in the argument to createImageBitmap");
        return;
    }

    auto sourceRectangle = croppedSourceRectangleWithFormatting(roundedIntSize(image->size()), options, rect);
    if (sourceRectangle.hasException()) {
        promise.reject(sourceRectangle.releaseException());
        return;
    }

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, image->colorSpace());
    if (!bitmapData) {
        promise.reject(InvalidStateError, "Cannot create an image buffer from the argument to createImageBitmap");
        return;
    }

    FloatRect destRect(FloatPoint(), outputSize);
    bitmapData->context().drawImage(image, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });

    OptionSet<SerializationState> serializationState = SerializationState::OriginClean;
    if (alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha) == AlphaPremultiplication::Premultiplied)
        serializationState.add(SerializationState::PremultiplyAlpha);

    auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData), serializationState));

    promise.resolve(WTFMove(imageBitmap));
}

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<Blob>& blob, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // 2. Return a new promise, but continue running these steps in parallel.
    PendingImageBitmap::fetch(scriptExecutionContext, WTFMove(blob), WTFMove(options), WTFMove(rect), WTFMove(promise));
}

void ImageBitmap::createPromise(ScriptExecutionContext& scriptExecutionContext, RefPtr<ImageData>& imageData, ImageBitmapOptions&& options, std::optional<IntRect> rect, ImageBitmap::Promise&& promise)
{
    // 6.1. Let buffer be image's data attribute value's [[ViewedArrayBuffer]]
    //      internal slot.
    // 6.2. If IsDetachedBuffer(buffer) is true, then return p rejected with an
    //      "InvalidStateError" DOMException.
    if (imageData->data().isDetached()) {
        promise.reject(InvalidStateError, "ImageData's viewed buffer has been detached");
        return;
    }

    // 6.3. Set imageBitmap's bitmap data to image's image data, cropped to the
    //      source rectangle with formatting.
    auto sourceRectangle = croppedSourceRectangleWithFormatting(imageData->size(), options, WTFMove(rect));
    if (sourceRectangle.hasException()) {
        promise.reject(sourceRectangle.releaseException());
        return;
    }

    auto outputSize = outputSizeForSourceRectangle(sourceRectangle.returnValue(), options);
    auto bitmapData = createImageBuffer(scriptExecutionContext, outputSize, bufferRenderingMode, toDestinationColorSpace(imageData->colorSpace()));

    if (!bitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, true, WTFMove(promise));
        return;
    }

    // If no cropping, resizing, flipping, etc. are needed, then simply use the
    // resulting ImageBuffer directly.
    auto alphaPremultiplication = alphaPremultiplicationForPremultiplyAlpha(options.premultiplyAlpha);
    if (sourceRectangle.returnValue().location().isZero() && sourceRectangle.returnValue().size() == imageData->size() && sourceRectangle.returnValue().size() == outputSize && options.orientation == ImageBitmapOptions::Orientation::None) {
        bitmapData->putPixelBuffer(imageData->pixelBuffer(), sourceRectangle.releaseReturnValue(), { }, alphaPremultiplication);
        
        auto imageBitmap = create(ImageBitmapBacking(WTFMove(bitmapData)));
        // The result is implicitly origin-clean, and alpha premultiplication has already been handled.
        promise.resolve(WTFMove(imageBitmap));
        return;
    }

    // 6.3. Set imageBitmap's bitmap data to image's image data, cropped to the
    //      source rectangle with formatting.
    auto tempBitmapData = createImageBuffer(scriptExecutionContext, imageData->size(), bufferRenderingMode, toDestinationColorSpace(imageData->colorSpace()));
    if (!tempBitmapData) {
        resolveWithBlankImageBuffer(scriptExecutionContext, true, WTFMove(promise));
        return;
    }
    tempBitmapData->putPixelBuffer(imageData->pixelBuffer(), IntRect(0, 0, imageData->width(), imageData->height()), { }, alphaPremultiplication);
    FloatRect destRect(FloatPoint(), outputSize);
    bitmapData->context().drawImageBuffer(*tempBitmapData, destRect, sourceRectangle.releaseReturnValue(), { interpolationQualityForResizeQuality(options.resizeQuality), options.resolvedImageOrientation(ImageOrientation::None) });

    // 6.4.1. Resolve p with ImageBitmap.
    auto imageBitmap = create({ WTFMove(bitmapData) });
    // The result is implicitly origin-clean, and alpha premultiplication has already been handled.
    promise.resolve(WTFMove(imageBitmap));
}

ImageBitmap::ImageBitmap(std::optional<ImageBitmapBacking>&& backingStore)
    : m_backingStore(WTFMove(backingStore))
{
    ASSERT_IMPLIES(m_backingStore, m_backingStore->buffer());
    updateMemoryCost();
}

ImageBitmap::~ImageBitmap()
{
    if (isMainThread())
        return;
    if (auto imageBuffer = takeImageBuffer())
        callOnMainThread([imageBuffer = WTFMove(imageBuffer)] { });
}

std::optional<ImageBitmapBacking> ImageBitmap::takeImageBitmapBacking()
{
    auto result = std::exchange(m_backingStore, std::nullopt);
    if (result)
        updateMemoryCost();
    return result;
}

RefPtr<ImageBuffer> ImageBitmap::takeImageBuffer()
{
    if (auto backingStore = takeImageBitmapBacking())
        return backingStore->takeImageBuffer();
    ASSERT(isDetached());
    return nullptr;
}

void ImageBitmap::updateMemoryCost()
{
    if (m_backingStore) {
        if (auto imageBuffer = m_backingStore->buffer()) {
            m_memoryCost = imageBuffer->memoryCost();
            return;
        }
    }
    m_memoryCost = 0;
}

size_t ImageBitmap::memoryCost() const
{
    return m_memoryCost;
}

} // namespace WebCore
