summaryrefslogtreecommitdiff
path: root/dom/canvas/ImageBitmap.h
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commitad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/canvas/ImageBitmap.h
parent15477ed9af4859dacb069040b5d4de600803d3bc (diff)
downloadaura-central-ad18d877ddd2a44d98fa12ccd3dbbcf4d0ac4299.tar.gz
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/canvas/ImageBitmap.h')
-rw-r--r--dom/canvas/ImageBitmap.h290
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
+
+