|
Packit |
f0b94e |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
Packit |
f0b94e |
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#ifndef mozilla_dom_ImageBitmap_h
|
|
Packit |
f0b94e |
#define mozilla_dom_ImageBitmap_h
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "mozilla/Attributes.h"
|
|
Packit |
f0b94e |
#include "mozilla/dom/ImageBitmapSource.h"
|
|
Packit |
f0b94e |
#include "mozilla/dom/TypedArray.h"
|
|
Packit |
f0b94e |
#include "mozilla/gfx/Rect.h"
|
|
Packit |
f0b94e |
#include "mozilla/Maybe.h"
|
|
Packit |
f0b94e |
#include "mozilla/UniquePtr.h"
|
|
Packit |
f0b94e |
#include "gfxTypes.h" // for gfxAlphaType
|
|
Packit |
f0b94e |
#include "nsCycleCollectionParticipant.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
struct JSContext;
|
|
Packit |
f0b94e |
struct JSStructuredCloneReader;
|
|
Packit |
f0b94e |
struct JSStructuredCloneWriter;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class nsIGlobalObject;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace mozilla {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class ErrorResult;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace gfx {
|
|
Packit |
f0b94e |
class DataSourceSurface;
|
|
Packit |
f0b94e |
class DrawTarget;
|
|
Packit |
f0b94e |
class SourceSurface;
|
|
Packit |
f0b94e |
} // namespace gfx
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace layers {
|
|
Packit |
f0b94e |
class Image;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
namespace dom {
|
|
Packit |
f0b94e |
class OffscreenCanvas;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
class ArrayBufferViewOrArrayBuffer;
|
|
Packit |
f0b94e |
class CanvasRenderingContext2D;
|
|
Packit |
f0b94e |
struct ChannelPixelLayout;
|
|
Packit |
f0b94e |
class CreateImageBitmapFromBlob;
|
|
Packit |
f0b94e |
class CreateImageBitmapFromBlobTask;
|
|
Packit |
f0b94e |
class CreateImageBitmapFromBlobWorkerTask;
|
|
Packit |
f0b94e |
class File;
|
|
Packit |
f0b94e |
class HTMLCanvasElement;
|
|
Packit |
f0b94e |
class HTMLImageElement;
|
|
Packit |
f0b94e |
class HTMLVideoElement;
|
|
Packit |
f0b94e |
enum class ImageBitmapFormat : uint8_t;
|
|
Packit |
f0b94e |
class ImageData;
|
|
Packit |
f0b94e |
class ImageUtils;
|
|
Packit |
f0b94e |
template <typename T>
|
|
Packit |
f0b94e |
class MapDataIntoBufferSource;
|
|
Packit |
f0b94e |
class Promise;
|
|
Packit |
f0b94e |
class PostMessageEvent; // For StructuredClone between windows.
|
|
Packit |
f0b94e |
class ImageBitmapShutdownObserver;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
struct ImageBitmapCloneData final {
|
|
Packit |
f0b94e |
RefPtr<gfx::DataSourceSurface> mSurface;
|
|
Packit |
f0b94e |
gfx::IntRect mPictureRect;
|
|
Packit |
f0b94e |
gfxAlphaType mAlphaType;
|
|
Packit |
f0b94e |
bool mIsCroppingAreaOutSideOfSourceImage;
|
|
Packit |
f0b94e |
bool mWriteOnly;
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* ImageBitmap is an opaque handler to several kinds of image-like objects from
|
|
Packit |
f0b94e |
* HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to
|
|
Packit |
f0b94e |
* CanvasRenderingContext2D and Image Blob.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* An ImageBitmap could be painted to a canvas element.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Generally, an ImageBitmap only keeps a reference to its source object's
|
|
Packit |
f0b94e |
* buffer, but if the source object is an ImageData, an Blob or a
|
|
Packit |
f0b94e |
* HTMLCanvasElement with WebGL rendering context, the ImageBitmap copy the
|
|
Packit |
f0b94e |
* source object's buffer.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
class ImageBitmap final : public nsISupports, public nsWrapperCache {
|
|
Packit |
f0b94e |
public:
|
|
Packit |
f0b94e |
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
Packit |
f0b94e |
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageBitmap)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsCOMPtr<nsIGlobalObject> GetParentObject() const { return mParent; }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
virtual JSObject* WrapObject(JSContext* aCx,
|
|
Packit |
f0b94e |
JS::Handle<JSObject*> aGivenProto) override;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
uint32_t Width() const { return mPictureRect.Width(); }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
uint32_t Height() const { return mPictureRect.Height(); }
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void Close();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* The PrepareForDrawTarget() might return null if the mPictureRect does not
|
|
Packit |
f0b94e |
* intersect with the size of mData.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
already_AddRefed<gfx::SourceSurface> PrepareForDrawTarget(
|
|
Packit |
f0b94e |
gfx::DrawTarget* aTarget);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Transfer ownership of buffer to caller. So this function call
|
|
Packit |
f0b94e |
* Close() implicitly.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
already_AddRefed<layers::Image> TransferAsImage();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
UniquePtr<ImageBitmapCloneData> ToCloneData() const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateFromCloneData(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateFromOffscreenCanvas(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas,
|
|
Packit |
f0b94e |
ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<Promise> Create(nsIGlobalObject* aGlobal,
|
|
Packit |
f0b94e |
const ImageBitmapSource& aSrc,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect,
|
|
Packit |
f0b94e |
ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<Promise> Create(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, const ImageBitmapSource& aBuffer,
|
|
Packit |
f0b94e |
int32_t aOffset, int32_t aLength, mozilla::dom::ImageBitmapFormat aFormat,
|
|
Packit |
f0b94e |
const Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
|
|
Packit |
f0b94e |
ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static JSObject* ReadStructuredClone(
|
|
Packit |
f0b94e |
JSContext* aCx, JSStructuredCloneReader* aReader,
|
|
Packit |
f0b94e |
nsIGlobalObject* aParent,
|
|
Packit |
f0b94e |
const nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
|
|
Packit |
f0b94e |
uint32_t aIndex);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static bool WriteStructuredClone(
|
|
Packit |
f0b94e |
JSStructuredCloneWriter* aWriter,
|
|
Packit |
f0b94e |
nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
|
|
Packit |
f0b94e |
ImageBitmap* aImageBitmap);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
friend CreateImageBitmapFromBlob;
|
|
Packit |
f0b94e |
friend CreateImageBitmapFromBlobTask;
|
|
Packit |
f0b94e |
friend CreateImageBitmapFromBlobWorkerTask;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
template <typename T>
|
|
Packit |
f0b94e |
friend class MapDataIntoBufferSource;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Mozilla Extensions
|
|
Packit |
f0b94e |
ImageBitmapFormat FindOptimalFormat(
|
|
Packit |
f0b94e |
const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
|
|
Packit |
f0b94e |
ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
int32_t MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
already_AddRefed<Promise> MapDataInto(
|
|
Packit |
f0b94e |
JSContext* aCx, ImageBitmapFormat aFormat,
|
|
Packit |
f0b94e |
const ArrayBufferViewOrArrayBuffer& aBuffer, int32_t aOffset,
|
|
Packit |
f0b94e |
ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
size_t GetAllocatedSize() const;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void OnShutdown();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
bool IsWriteOnly() const
|
|
Packit |
f0b94e |
{
|
|
Packit |
f0b94e |
return mWriteOnly;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
protected:
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* The default value of aIsPremultipliedAlpha is TRUE because that the
|
|
Packit |
f0b94e |
* data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement,
|
|
Packit |
f0b94e |
* CanvasRenderingContext2D are alpha-premultiplied in default.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it
|
|
Packit |
f0b94e |
* is possible to get un-premultipliedAlpha data out. But, we do not do it in
|
|
Packit |
f0b94e |
* the CreateInternal(from HTMLCanvasElement) method.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* It is also possible to decode an image which is encoded with alpha channel
|
|
Packit |
f0b94e |
* to be non-premultipliedAlpha. This could be applied in
|
|
Packit |
f0b94e |
* 1) the CreateInternal(from HTMLImageElement) method (which might trigger
|
|
Packit |
f0b94e |
* re-decoding if the original decoded data is alpha-premultiplied) and
|
|
Packit |
f0b94e |
* 2) while decoding a blob. But we do not do it in both code path too.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* ImageData's underlying data is triggered as non-premultipliedAlpha, so set
|
|
Packit |
f0b94e |
* the aIsPremultipliedAlpha to be false in the
|
|
Packit |
f0b94e |
* CreateInternal(from ImageData) method.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
|
Packit |
f0b94e |
bool aWriteOnly,
|
|
Packit |
f0b94e |
gfxAlphaType aAlphaType = gfxAlphaType::Premult);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
virtual ~ImageBitmap();
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void SetIsCroppingAreaOutSideOfSourceImage(
|
|
Packit |
f0b94e |
const gfx::IntSize& aSourceSize,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCroppingRect);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, ImageData& aImageData,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
static already_AddRefed<ImageBitmap> CreateInternal(
|
|
Packit |
f0b94e |
nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
|
Packit |
f0b94e |
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsCOMPtr<nsIGlobalObject> mParent;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* The mData is the data buffer of an ImageBitmap, so the mData must not be
|
|
Packit |
f0b94e |
* null.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* The mSurface is a cache for drawing the ImageBitmap onto a
|
|
Packit |
f0b94e |
* HTMLCanvasElement. The mSurface is null while the ImageBitmap is created
|
|
Packit |
f0b94e |
* and then will be initialized while the PrepareForDrawTarget() method is
|
|
Packit |
f0b94e |
* called first time.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* The mSurface might just be a reference to the same data buffer of the mData
|
|
Packit |
f0b94e |
* if the are of mPictureRect is just the same as the mData's size. Or, it is
|
|
Packit |
f0b94e |
* a independent data buffer which is copied and cropped form the mData's data
|
|
Packit |
f0b94e |
* buffer.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
RefPtr<layers::Image> mData;
|
|
Packit |
f0b94e |
RefPtr<gfx::SourceSurface> mSurface;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* This is used in the ImageBitmap-Extensions implementation.
|
|
Packit |
f0b94e |
* ImageUtils is a wrapper to layers::Image, which add some common methods for
|
|
Packit |
f0b94e |
* accessing the layers::Image's data.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
UniquePtr<ImageUtils> mDataWrapper;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* The mPictureRect is the size of the source image in default, however, if
|
|
Packit |
f0b94e |
* users specify the cropping area while creating an ImageBitmap, then this
|
|
Packit |
f0b94e |
* mPictureRect is the cropping area.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* Note that if the CreateInternal() copies and crops data from the source
|
|
Packit |
f0b94e |
* image, then this mPictureRect is just the size of the final mData.
|
|
Packit |
f0b94e |
*
|
|
Packit |
f0b94e |
* The mPictureRect will be used at PrepareForDrawTarget() while user is going
|
|
Packit |
f0b94e |
* to draw this ImageBitmap into a HTMLCanvasElement.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
gfx::IntRect mPictureRect;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const gfxAlphaType mAlphaType;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
RefPtr<ImageBitmapShutdownObserver> mShutdownObserver;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Set mIsCroppingAreaOutSideOfSourceImage if image bitmap was cropped to the
|
|
Packit |
f0b94e |
* source rectangle so that it contains any transparent black pixels (cropping
|
|
Packit |
f0b94e |
* area is outside of the source image).
|
|
Packit |
f0b94e |
* This is used in mapDataInto() to check if we should reject promise with
|
|
Packit |
f0b94e |
* IndexSizeError.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool mIsCroppingAreaOutSideOfSourceImage;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Whether this object allocated allocated and owns the image data.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool mAllocatedImageData;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
/*
|
|
Packit |
f0b94e |
* Write-Only flag is set to true if this image has been generated from a
|
|
Packit |
f0b94e |
* cross-origin source. This is the opposite of what is called 'origin-clean'
|
|
Packit |
f0b94e |
* in the spec.
|
|
Packit |
f0b94e |
*/
|
|
Packit |
f0b94e |
bool mWriteOnly;
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
} // namespace dom
|
|
Packit |
f0b94e |
} // namespace mozilla
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#endif // mozilla_dom_ImageBitmap_h
|