tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ImageBitmap.h (10309B)


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