Coverage Report

Created: 2018-09-25 14:53

/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