/work/obj-fuzz/dist/include/mozilla/dom/ImageBitmap.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef mozilla_dom_ImageBitmap_h |
8 | | #define mozilla_dom_ImageBitmap_h |
9 | | |
10 | | #include "mozilla/Attributes.h" |
11 | | #include "mozilla/dom/ImageBitmapSource.h" |
12 | | #include "mozilla/dom/TypedArray.h" |
13 | | #include "mozilla/gfx/Rect.h" |
14 | | #include "mozilla/Maybe.h" |
15 | | #include "mozilla/UniquePtr.h" |
16 | | #include "gfxTypes.h" // for gfxAlphaType |
17 | | #include "nsCycleCollectionParticipant.h" |
18 | | |
19 | | struct JSContext; |
20 | | struct JSStructuredCloneReader; |
21 | | struct JSStructuredCloneWriter; |
22 | | |
23 | | class nsIGlobalObject; |
24 | | |
25 | | namespace mozilla { |
26 | | |
27 | | class ErrorResult; |
28 | | |
29 | | namespace gfx { |
30 | | class DataSourceSurface; |
31 | | class DrawTarget; |
32 | | class SourceSurface; |
33 | | } |
34 | | |
35 | | namespace layers { |
36 | | class Image; |
37 | | } |
38 | | |
39 | | namespace dom { |
40 | | class OffscreenCanvas; |
41 | | |
42 | | class ArrayBufferViewOrArrayBuffer; |
43 | | class CanvasRenderingContext2D; |
44 | | struct ChannelPixelLayout; |
45 | | class CreateImageBitmapFromBlob; |
46 | | class CreateImageBitmapFromBlobTask; |
47 | | class CreateImageBitmapFromBlobWorkerTask; |
48 | | class File; |
49 | | class HTMLCanvasElement; |
50 | | class HTMLImageElement; |
51 | | class HTMLVideoElement; |
52 | | enum class ImageBitmapFormat : uint8_t; |
53 | | class ImageData; |
54 | | class ImageUtils; |
55 | | template<typename T> class MapDataIntoBufferSource; |
56 | | class Promise; |
57 | | class PostMessageEvent; // For StructuredClone between windows. |
58 | | class ImageBitmapShutdownObserver; |
59 | | |
60 | | struct ImageBitmapCloneData final |
61 | | { |
62 | | RefPtr<gfx::DataSourceSurface> mSurface; |
63 | | gfx::IntRect mPictureRect; |
64 | | gfxAlphaType mAlphaType; |
65 | | bool mIsCroppingAreaOutSideOfSourceImage; |
66 | | }; |
67 | | |
68 | | /* |
69 | | * ImageBitmap is an opaque handler to several kinds of image-like objects from |
70 | | * HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, ImageData to |
71 | | * CanvasRenderingContext2D and Image Blob. |
72 | | * |
73 | | * An ImageBitmap could be painted to a canvas element. |
74 | | * |
75 | | * Generally, an ImageBitmap only keeps a reference to its source object's |
76 | | * buffer, but if the source object is an ImageData, an Blob or a |
77 | | * HTMLCanvasElement with WebGL rendering context, the ImageBitmap copy the |
78 | | * source object's buffer. |
79 | | */ |
80 | | class ImageBitmap final : public nsISupports, |
81 | | public nsWrapperCache |
82 | | { |
83 | | public: |
84 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
85 | | NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageBitmap) |
86 | | |
87 | 0 | nsCOMPtr<nsIGlobalObject> GetParentObject() const { return mParent; } |
88 | | |
89 | | virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; |
90 | | |
91 | | uint32_t Width() const |
92 | 0 | { |
93 | 0 | return mPictureRect.Width(); |
94 | 0 | } |
95 | | |
96 | | uint32_t Height() const |
97 | 0 | { |
98 | 0 | return mPictureRect.Height(); |
99 | 0 | } |
100 | | |
101 | | void Close(); |
102 | | |
103 | | /* |
104 | | * The PrepareForDrawTarget() might return null if the mPictureRect does not |
105 | | * intersect with the size of mData. |
106 | | */ |
107 | | already_AddRefed<gfx::SourceSurface> |
108 | | PrepareForDrawTarget(gfx::DrawTarget* aTarget); |
109 | | |
110 | | /* |
111 | | * Transfer ownership of buffer to caller. So this function call |
112 | | * Close() implicitly. |
113 | | */ |
114 | | already_AddRefed<layers::Image> |
115 | | TransferAsImage(); |
116 | | |
117 | | // This method returns null if the image has been already closed. |
118 | | UniquePtr<ImageBitmapCloneData> |
119 | | ToCloneData() const; |
120 | | |
121 | | static already_AddRefed<ImageBitmap> |
122 | | CreateFromCloneData(nsIGlobalObject* aGlobal, ImageBitmapCloneData* aData); |
123 | | |
124 | | static already_AddRefed<ImageBitmap> |
125 | | CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal, |
126 | | OffscreenCanvas& aOffscreenCanvas, |
127 | | ErrorResult& aRv); |
128 | | |
129 | | static already_AddRefed<Promise> |
130 | | Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aSrc, |
131 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
132 | | |
133 | | static already_AddRefed<Promise> |
134 | | Create(nsIGlobalObject* aGlobal, |
135 | | const ImageBitmapSource& aBuffer, |
136 | | int32_t aOffset, int32_t aLength, |
137 | | mozilla::dom::ImageBitmapFormat aFormat, |
138 | | const Sequence<mozilla::dom::ChannelPixelLayout>& aLayout, |
139 | | ErrorResult& aRv); |
140 | | |
141 | | static JSObject* |
142 | | ReadStructuredClone(JSContext* aCx, |
143 | | JSStructuredCloneReader* aReader, |
144 | | nsIGlobalObject* aParent, |
145 | | const nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces, |
146 | | uint32_t aIndex); |
147 | | |
148 | | static bool |
149 | | WriteStructuredClone(JSStructuredCloneWriter* aWriter, |
150 | | nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces, |
151 | | ImageBitmap* aImageBitmap); |
152 | | |
153 | | friend CreateImageBitmapFromBlob; |
154 | | friend CreateImageBitmapFromBlobTask; |
155 | | friend CreateImageBitmapFromBlobWorkerTask; |
156 | | |
157 | | template<typename T> |
158 | | friend class MapDataIntoBufferSource; |
159 | | |
160 | | // Mozilla Extensions |
161 | | ImageBitmapFormat |
162 | | FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats, |
163 | | ErrorResult& aRv); |
164 | | |
165 | | int32_t |
166 | | MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv); |
167 | | |
168 | | already_AddRefed<Promise> |
169 | | MapDataInto(JSContext* aCx, |
170 | | ImageBitmapFormat aFormat, |
171 | | const ArrayBufferViewOrArrayBuffer& aBuffer, |
172 | | int32_t aOffset, ErrorResult& aRv); |
173 | | |
174 | | size_t GetAllocatedSize() const; |
175 | | |
176 | | void OnShutdown(); |
177 | | |
178 | | protected: |
179 | | |
180 | | /* |
181 | | * The default value of aIsPremultipliedAlpha is TRUE because that the |
182 | | * data stored in HTMLImageElement, HTMLVideoElement, HTMLCanvasElement, |
183 | | * CanvasRenderingContext2D are alpha-premultiplied in default. |
184 | | * |
185 | | * Actually, if one HTMLCanvasElement's rendering context is WebGLContext, it |
186 | | * is possible to get un-premultipliedAlpha data out. But, we do not do it in |
187 | | * the CreateInternal(from HTMLCanvasElement) method. |
188 | | * |
189 | | * It is also possible to decode an image which is encoded with alpha channel |
190 | | * to be non-premultipliedAlpha. This could be applied in |
191 | | * 1) the CreateInternal(from HTMLImageElement) method (which might trigger |
192 | | * re-decoding if the original decoded data is alpha-premultiplied) and |
193 | | * 2) while decoding a blob. But we do not do it in both code path too. |
194 | | * |
195 | | * ImageData's underlying data is triggered as non-premultipliedAlpha, so set |
196 | | * the aIsPremultipliedAlpha to be false in the |
197 | | * CreateInternal(from ImageData) method. |
198 | | */ |
199 | | ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, |
200 | | gfxAlphaType aAlphaType = gfxAlphaType::Premult); |
201 | | |
202 | | virtual ~ImageBitmap(); |
203 | | |
204 | | void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv); |
205 | | |
206 | | void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize, |
207 | | const Maybe<gfx::IntRect>& aCroppingRect); |
208 | | |
209 | | static already_AddRefed<ImageBitmap> |
210 | | CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl, |
211 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
212 | | |
213 | | static already_AddRefed<ImageBitmap> |
214 | | CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl, |
215 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
216 | | |
217 | | static already_AddRefed<ImageBitmap> |
218 | | CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl, |
219 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
220 | | |
221 | | static already_AddRefed<ImageBitmap> |
222 | | CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData, |
223 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
224 | | |
225 | | static already_AddRefed<ImageBitmap> |
226 | | CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx, |
227 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
228 | | |
229 | | static already_AddRefed<ImageBitmap> |
230 | | CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap, |
231 | | const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv); |
232 | | |
233 | | nsCOMPtr<nsIGlobalObject> mParent; |
234 | | |
235 | | /* |
236 | | * The mData is the data buffer of an ImageBitmap, so the mData must not be |
237 | | * null. |
238 | | * |
239 | | * The mSurface is a cache for drawing the ImageBitmap onto a |
240 | | * HTMLCanvasElement. The mSurface is null while the ImageBitmap is created |
241 | | * and then will be initialized while the PrepareForDrawTarget() method is |
242 | | * called first time. |
243 | | * |
244 | | * The mSurface might just be a reference to the same data buffer of the mData |
245 | | * if the are of mPictureRect is just the same as the mData's size. Or, it is |
246 | | * a independent data buffer which is copied and cropped form the mData's data |
247 | | * buffer. |
248 | | */ |
249 | | RefPtr<layers::Image> mData; |
250 | | RefPtr<gfx::SourceSurface> mSurface; |
251 | | |
252 | | /* |
253 | | * This is used in the ImageBitmap-Extensions implementation. |
254 | | * ImageUtils is a wrapper to layers::Image, which add some common methods for |
255 | | * accessing the layers::Image's data. |
256 | | */ |
257 | | UniquePtr<ImageUtils> mDataWrapper; |
258 | | |
259 | | /* |
260 | | * The mPictureRect is the size of the source image in default, however, if |
261 | | * users specify the cropping area while creating an ImageBitmap, then this |
262 | | * mPictureRect is the cropping area. |
263 | | * |
264 | | * Note that if the CreateInternal() copies and crops data from the source |
265 | | * image, then this mPictureRect is just the size of the final mData. |
266 | | * |
267 | | * The mPictureRect will be used at PrepareForDrawTarget() while user is going |
268 | | * to draw this ImageBitmap into a HTMLCanvasElement. |
269 | | */ |
270 | | gfx::IntRect mPictureRect; |
271 | | |
272 | | const gfxAlphaType mAlphaType; |
273 | | |
274 | | RefPtr<ImageBitmapShutdownObserver> mShutdownObserver; |
275 | | |
276 | | /* |
277 | | * Set mIsCroppingAreaOutSideOfSourceImage if image bitmap was cropped to the |
278 | | * source rectangle so that it contains any transparent black pixels (cropping |
279 | | * area is outside of the source image). |
280 | | * This is used in mapDataInto() to check if we should reject promise with |
281 | | * IndexSizeError. |
282 | | */ |
283 | | bool mIsCroppingAreaOutSideOfSourceImage; |
284 | | |
285 | | /* |
286 | | * Whether this object allocated allocated and owns the image data. |
287 | | */ |
288 | | bool mAllocatedImageData; |
289 | | }; |
290 | | |
291 | | } // namespace dom |
292 | | } // namespace mozilla |
293 | | |
294 | | #endif // mozilla_dom_ImageBitmap_h |
295 | | |
296 | | |