diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | ad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/canvas/ImageBitmap.h | |
parent | 15477ed9af4859dacb069040b5d4de600803d3bc (diff) | |
download | aura-central-ad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299.tar.gz |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/canvas/ImageBitmap.h')
-rw-r--r-- | dom/canvas/ImageBitmap.h | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h new file mode 100644 index 000000000..2119c6bda --- /dev/null +++ b/dom/canvas/ImageBitmap.h @@ -0,0 +1,290 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_ImageBitmap_h +#define mozilla_dom_ImageBitmap_h + +#include "mozilla/Attributes.h" +#include "mozilla/dom/ImageBitmapSource.h" +#include "mozilla/dom/TypedArray.h" +#include "mozilla/gfx/Rect.h" +#include "mozilla/Maybe.h" +#include "mozilla/UniquePtr.h" +#include "nsCycleCollectionParticipant.h" + +struct JSContext; +struct JSStructuredCloneReader; +struct JSStructuredCloneWriter; + +class nsIGlobalObject; + +namespace mozilla { + +class ErrorResult; + +namespace gfx { +class DataSourceSurface; +class DrawTarget; +class SourceSurface; +} + +namespace layers { +class Image; +} + +namespace dom { +class OffscreenCanvas; + +namespace workers { +class WorkerStructuredCloneClosure; +} + +class ArrayBufferViewOrArrayBuffer; +class CanvasRenderingContext2D; +struct ChannelPixelLayout; +class CreateImageBitmapFromBlob; +class CreateImageBitmapFromBlobTask; +class CreateImageBitmapFromBlobWorkerTask; +class File; +class HTMLCanvasElement; +class HTMLImageElement; +class HTMLVideoElement; +enum class ImageBitmapFormat : uint32_t; +class ImageData; +class ImageUtils; +template<typename T> class MapDataIntoBufferSource; +class Promise; +class PostMessageEvent; // For StructuredClone between windows. + +struct ImageBitmapCloneData final +{ + RefPtr<gfx::DataSourceSurface> mSurface; + gfx::IntRect mPictureRect; + bool mIsPremultipliedAlpha; + bool mIsCroppingAreaOutSideOfSourceImage; +}; + +/* + * ImageBitmap is an opaque handler to several kinds of image-like objects from + * HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to + * CanvasRenderingContext2D and Image Blob. + * + * An ImageBitmap could be painted to a canvas element. + * + * Generally, an ImageBitmap only keeps a reference to its source object's + * buffer, but if the source object is an ImageData, an Blob or a + * HTMLCanvasElement with WebGL rendering context, the ImageBitmap copy the + * source object's buffer. + */ +class ImageBitmap final : public nsISupports, + public nsWrapperCache +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageBitmap) + + nsCOMPtr<nsIGlobalObject> GetParentObject() const { return mParent; } + + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; + + uint32_t Width() const + { + return mPictureRect.Width(); + } + + uint32_t Height() const + { + return mPictureRect.Height(); + } + + void Close(); + + /* + * The PrepareForDrawTarget() might return null if the mPictureRect does not + * intersect with the size of mData. + */ + already_AddRefed<gfx::SourceSurface> + PrepareForDrawTarget(gfx::DrawTarget* aTarget); + + /* + * Transfer ownership of buffer to caller. So this function call + * Close() implicitly. + */ + already_AddRefed<layers::Image> + TransferAsImage(); + + UniquePtr<ImageBitmapCloneData> + ToCloneData() const; + + static already_AddRefed<ImageBitmap> + CreateFromCloneData(nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData); + + static already_AddRefed<ImageBitmap> + CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal, + OffscreenCanvas& aOffscreenCanvas, + ErrorResult& aRv); + + static already_AddRefed<Promise> + Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<Promise> + Create(nsIGlobalObject* aGlobal, + const ImageBitmapSource& aBuffer, + int32_t aOffset, int32_t aLength, + mozilla::dom::ImageBitmapFormat aFormat, + const Sequence<mozilla::dom::ChannelPixelLayout>& aLayout, + ErrorResult& aRv); + + static JSObject* + ReadStructuredClone(JSContext* aCx, + JSStructuredCloneReader* aReader, + nsIGlobalObject* aParent, + const nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces, + uint32_t aIndex); + + static bool + WriteStructuredClone(JSStructuredCloneWriter* aWriter, + nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces, + ImageBitmap* aImageBitmap); + + // Mozilla Extensions + static bool ExtensionsEnabled(JSContext* aCx, JSObject* aObj); + + friend CreateImageBitmapFromBlob; + friend CreateImageBitmapFromBlobTask; + friend CreateImageBitmapFromBlobWorkerTask; + + template<typename T> + friend class MapDataIntoBufferSource; + + // Mozilla Extensions + ImageBitmapFormat + FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats, + ErrorResult& aRv); + + int32_t + MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv); + + already_AddRefed<Promise> + MapDataInto(JSContext* aCx, + ImageBitmapFormat aFormat, + const ArrayBufferViewOrArrayBuffer& aBuffer, + int32_t aOffset, ErrorResult& aRv); + +protected: + + /* + * The default value of aIsPremultipliedAlpha is TRUE because that the + * data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, + * CanvasRenderingContext2D are alpha-premultiplied in default. + * + * Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it + * is possible to get un-premultipliedAlpha data out. But, we do not do it in + * the CreateInternal(from HTMLCanvasElement) method. + * + * It is also possible to decode an image which is encoded with alpha channel + * to be non-premultipliedAlpha. This could be applied in + * 1) the CreateInternal(from HTMLImageElement) method (which might trigger + * re-decoding if the original decoded data is alpha-premultiplied) and + * 2) while decoding a blob. But we do not do it in both code path too. + * + * ImageData's underlying data is triggered as non-premultipliedAlpha, so set + * the aIsPremultipliedAlpha to be false in the + * CreateInternal(from ImageData) method. + */ + ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, + bool aIsPremultipliedAlpha = true); + + virtual ~ImageBitmap(); + + void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv); + + void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize, + const Maybe<gfx::IntRect>& aCroppingRect); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + static already_AddRefed<ImageBitmap> + CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap, + const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); + + nsCOMPtr<nsIGlobalObject> mParent; + + /* + * The mData is the data buffer of an ImageBitmap, so the mData must not be + * null. + * + * The mSurface is a cache for drawing the ImageBitmap onto a + * HTMLCanvasElement. The mSurface is null while the ImageBitmap is created + * and then will be initialized while the PrepareForDrawTarget() method is + * called first time. + * + * The mSurface might just be a reference to the same data buffer of the mData + * if the are of mPictureRect is just the same as the mData's size. Or, it is + * a independent data buffer which is copied and cropped form the mData's data + * buffer. + */ + RefPtr<layers::Image> mData; + RefPtr<gfx::SourceSurface> mSurface; + + /* + * This is used in the ImageBitmap-Extensions implementation. + * ImageUtils is a wrapper to layers::Image, which add some common methods for + * accessing the layers::Image's data. + */ + UniquePtr<ImageUtils> mDataWrapper; + + /* + * The mPictureRect is the size of the source image in default, however, if + * users specify the cropping area while creating an ImageBitmap, then this + * mPictureRect is the cropping area. + * + * Note that if the CreateInternal() copies and crops data from the source + * image, then this mPictureRect is just the size of the final mData. + * + * The mPictureRect will be used at PrepareForDrawTarget() while user is going + * to draw this ImageBitmap into a HTMLCanvasElement. + */ + gfx::IntRect mPictureRect; + + const bool mIsPremultipliedAlpha; + + /* + * Set mIsCroppingAreaOutSideOfSourceImage if image bitmap was cropped to the + * source rectangle so that it contains any transparent black pixels (cropping + * area is outside of the source image). + * This is used in mapDataInto() to check if we should reject promise with + * IndexSizeError. + */ + bool mIsCroppingAreaOutSideOfSourceImage; + +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ImageBitmap_h + + |