Bug 1839170 - Refactor Snap pulling, Add Firefox Snap Core22 and GNOME 42 SDK symbols...
[gecko.git] / dom / canvas / ImageBitmap.h
blob8f95225e413c171cd02e8c99535d4ab0cca552fe
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_ImageBitmap_h
8 #define mozilla_dom_ImageBitmap_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/ImageBitmapBinding.h"
12 #include "mozilla/dom/ImageBitmapSource.h"
13 #include "mozilla/dom/TypedArray.h"
14 #include "mozilla/gfx/Rect.h"
15 #include "mozilla/Maybe.h"
16 #include "mozilla/UniquePtr.h"
17 #include "ImageData.h"
18 #include "gfxTypes.h" // for gfxAlphaType
19 #include "nsCycleCollectionParticipant.h"
21 struct JSContext;
22 struct JSStructuredCloneReader;
23 struct JSStructuredCloneWriter;
25 class nsIGlobalObject;
27 namespace mozilla {
29 class ErrorResult;
31 namespace gfx {
32 class DataSourceSurface;
33 class DrawTarget;
34 class SourceSurface;
35 } // namespace gfx
37 namespace layers {
38 class Image;
41 namespace dom {
42 class OffscreenCanvas;
44 class ArrayBufferViewOrArrayBuffer;
45 class CanvasRenderingContext2D;
46 class CreateImageBitmapFromBlob;
47 class CreateImageBitmapFromBlobTask;
48 class CreateImageBitmapFromBlobWorkerTask;
49 class File;
50 class HTMLCanvasElement;
51 class HTMLImageElement;
52 class HTMLVideoElement;
53 class ImageBitmapShutdownObserver;
54 class ImageData;
55 class ImageUtils;
56 class Promise;
57 class PostMessageEvent; // For StructuredClone between windows.
58 class SVGImageElement;
60 struct ImageBitmapCloneData final {
61 RefPtr<gfx::DataSourceSurface> mSurface;
62 gfx::IntRect mPictureRect;
63 gfxAlphaType mAlphaType;
64 bool mWriteOnly;
68 * ImageBitmap is an opaque handler to several kinds of image-like objects from
69 * HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to
70 * CanvasRenderingContext2D and Image Blob.
72 * An ImageBitmap could be painted to a canvas element.
74 * Generally, an ImageBitmap only keeps a reference to its source object's
75 * buffer, but if the source object is an ImageData, an Blob or a
76 * HTMLCanvasElement with WebGL rendering context, the ImageBitmap copy the
77 * source object's buffer.
79 class ImageBitmap final : public nsISupports, public nsWrapperCache {
80 public:
81 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
82 NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(ImageBitmap)
84 nsCOMPtr<nsIGlobalObject> GetParentObject() const { return mParent; }
86 virtual JSObject* WrapObject(JSContext* aCx,
87 JS::Handle<JSObject*> aGivenProto) override;
89 uint32_t Width() const { return mPictureRect.Width(); }
91 uint32_t Height() const { return mPictureRect.Height(); }
93 void Close();
96 * The PrepareForDrawTarget() might return null if the mPictureRect does not
97 * intersect with the size of mData.
99 already_AddRefed<gfx::SourceSurface> PrepareForDrawTarget(
100 gfx::DrawTarget* aTarget);
103 * Transfer ownership of buffer to caller. So this function call
104 * Close() implicitly.
106 already_AddRefed<layers::Image> TransferAsImage();
108 // This method returns null if the image has been already closed.
109 UniquePtr<ImageBitmapCloneData> ToCloneData() const;
111 static already_AddRefed<ImageBitmap> CreateFromSourceSurface(
112 nsIGlobalObject* aGlobal, gfx::SourceSurface* aSource, ErrorResult& aRv);
114 static already_AddRefed<ImageBitmap> CreateFromCloneData(
115 nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData);
117 static already_AddRefed<ImageBitmap> CreateFromOffscreenCanvas(
118 nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas,
119 ErrorResult& aRv);
121 static already_AddRefed<Promise> Create(nsIGlobalObject* aGlobal,
122 const ImageBitmapSource& aSrc,
123 const Maybe<gfx::IntRect>& aCropRect,
124 const ImageBitmapOptions& aOptions,
125 ErrorResult& aRv);
127 static JSObject* ReadStructuredClone(
128 JSContext* aCx, JSStructuredCloneReader* aReader,
129 nsIGlobalObject* aParent,
130 const nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
131 uint32_t aIndex);
133 static void WriteStructuredClone(
134 JSStructuredCloneWriter* aWriter,
135 nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
136 ImageBitmap* aImageBitmap, ErrorResult& aRv);
138 friend CreateImageBitmapFromBlob;
139 friend CreateImageBitmapFromBlobTask;
140 friend CreateImageBitmapFromBlobWorkerTask;
142 size_t GetAllocatedSize() const;
144 void OnShutdown();
146 bool IsWriteOnly() const { return mWriteOnly; }
147 bool IsClosed() const { return !mData; };
149 protected:
151 * The default value of aIsPremultipliedAlpha is TRUE because that the
152 * data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement,
153 * CanvasRenderingContext2D are alpha-premultiplied in default.
155 * Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it
156 * is possible to get un-premultipliedAlpha data out. But, we do not do it in
157 * the CreateInternal(from HTMLCanvasElement) method.
159 * It is also possible to decode an image which is encoded with alpha channel
160 * to be non-premultipliedAlpha. This could be applied in
161 * 1) the CreateInternal(from HTMLImageElement) method (which might trigger
162 * re-decoding if the original decoded data is alpha-premultiplied) and
163 * 2) while decoding a blob. But we do not do it in both code path too.
165 * ImageData's underlying data is triggered as non-premultipliedAlpha, so set
166 * the aIsPremultipliedAlpha to be false in the
167 * CreateInternal(from ImageData) method.
169 ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, bool aWriteOnly,
170 gfxAlphaType aAlphaType = gfxAlphaType::Premult);
172 virtual ~ImageBitmap();
174 void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
176 static already_AddRefed<ImageBitmap> CreateImageBitmapInternal(
177 nsIGlobalObject* aGlobal, gfx::SourceSurface* aSurface,
178 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
179 const bool aWriteOnly, const bool aAllocatedImageData,
180 const bool aMustCopy, const gfxAlphaType aAlphaType, ErrorResult& aRv);
182 static already_AddRefed<ImageBitmap> CreateInternal(
183 nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
184 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
185 ErrorResult& aRv);
187 static already_AddRefed<ImageBitmap> CreateInternal(
188 nsIGlobalObject* aGlobal, SVGImageElement& aImageEl,
189 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
190 ErrorResult& aRv);
192 static already_AddRefed<ImageBitmap> CreateInternal(
193 nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
194 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
195 ErrorResult& aRv);
197 static already_AddRefed<ImageBitmap> CreateInternal(
198 nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
199 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
200 ErrorResult& aRv);
202 static already_AddRefed<ImageBitmap> CreateInternal(
203 nsIGlobalObject* aGlobal, OffscreenCanvas& aOffscreenCanvas,
204 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
205 ErrorResult& aRv);
207 static already_AddRefed<ImageBitmap> CreateInternal(
208 nsIGlobalObject* aGlobal, ImageData& aImageData,
209 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
210 ErrorResult& aRv);
212 static already_AddRefed<ImageBitmap> CreateInternal(
213 nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
214 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
215 ErrorResult& aRv);
217 static already_AddRefed<ImageBitmap> CreateInternal(
218 nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
219 const Maybe<gfx::IntRect>& aCropRect, const ImageBitmapOptions& aOptions,
220 ErrorResult& aRv);
222 nsCOMPtr<nsIGlobalObject> mParent;
225 * The mData is the data buffer of an ImageBitmap, so the mData must not be
226 * null.
228 * The mSurface is a cache for drawing the ImageBitmap onto a
229 * HTMLCanvasElement. The mSurface is null while the ImageBitmap is created
230 * and then will be initialized while the PrepareForDrawTarget() method is
231 * called first time.
233 * The mSurface might just be a reference to the same data buffer of the mData
234 * if the are of mPictureRect is just the same as the mData's size. Or, it is
235 * a independent data buffer which is copied and cropped form the mData's data
236 * buffer.
238 RefPtr<layers::Image> mData;
239 RefPtr<gfx::SourceSurface> mSurface;
242 * The mPictureRect is the size of the source image in default, however, if
243 * users specify the cropping area while creating an ImageBitmap, then this
244 * mPictureRect is the cropping area.
246 * Note that if the CreateInternal() copies and crops data from the source
247 * image, then this mPictureRect is just the size of the final mData.
249 * The mPictureRect will be used at PrepareForDrawTarget() while user is going
250 * to draw this ImageBitmap into a HTMLCanvasElement.
252 gfx::IntRect mPictureRect;
254 gfxAlphaType mAlphaType;
256 RefPtr<ImageBitmapShutdownObserver> mShutdownObserver;
259 * Whether this object allocated allocated and owns the image data.
261 bool mAllocatedImageData;
264 * Write-Only flag is set to true if this image has been generated from a
265 * cross-origin source. This is the opposite of what is called 'origin-clean'
266 * in the spec.
268 bool mWriteOnly;
271 } // namespace dom
272 } // namespace mozilla
274 #endif // mozilla_dom_ImageBitmap_h