Frank-Rainer Grahl 3 months ago
parent
commit
1cdc413ca4

+ 669 - 0
mozilla-release/patches/1500733-1-65a1.patch

@@ -0,0 +1,669 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330543 -7200
+#      Tue Oct 23 23:35:43 2018 +0200
+# Node ID dac317f3cd311d70772b55ee65c5ba3051e60fe3
+# Parent  aacb3c78382069b8b7800724331b3e64d051c1f2
+Bug 1500733 - Remove the support for BufferSource in createImageBitmap, r=aosmond
+
+diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
+--- a/dom/base/nsGlobalWindow.cpp
++++ b/dom/base/nsGlobalWindow.cpp
+@@ -15016,58 +15016,28 @@ nsGlobalWindow::FireOnNewGlobalObject()
+ #error "Never include windows.h in this file!"
+ #endif
+ 
+ already_AddRefed<Promise>
+ nsGlobalWindow::CreateImageBitmap(JSContext* aCx,
+                                   const ImageBitmapSource& aImage,
+                                   ErrorResult& aRv)
+ {
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    return nullptr;
+-  }
+-
+   return ImageBitmap::Create(this, aImage, Nothing(), aRv);
+ }
+ 
+ already_AddRefed<Promise>
+ nsGlobalWindow::CreateImageBitmap(JSContext* aCx,
+                                   const ImageBitmapSource& aImage,
+                                   int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
+                                   ErrorResult& aRv)
+ {
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    return nullptr;
+-  }
+-
+   return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
+ }
+ 
+-already_AddRefed<mozilla::dom::Promise>
+-nsGlobalWindow::CreateImageBitmap(JSContext* aCx,
+-                                  const ImageBitmapSource& aImage,
+-                                  int32_t aOffset, int32_t aLength,
+-                                  ImageBitmapFormat aFormat,
+-                                  const Sequence<ChannelPixelLayout>& aLayout,
+-                                  ErrorResult& aRv)
+-{
+-  if (!DOMPrefs::ImageBitmapExtensionsEnabled()) {
+-    aRv.Throw(NS_ERROR_TYPE_ERR);
+-    return nullptr;
+-  }
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
+-                               aRv);
+-  }
+-  aRv.Throw(NS_ERROR_TYPE_ERR);
+-  return nullptr;
+-}
+-
+ // Helper called by methods that move/resize the window,
+ // to ensure the presContext (if any) is aware of resolution
+ // change that may happen in multi-monitor configuration.
+ void
+ nsGlobalWindow::CheckForDPIChange()
+ {
+   if (mDocShell) {
+     RefPtr<nsPresContext> presContext;
+diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
+--- a/dom/base/nsGlobalWindow.h
++++ b/dom/base/nsGlobalWindow.h
+@@ -1254,25 +1254,16 @@ public:
+                     mozilla::ErrorResult& aRv);
+ 
+   already_AddRefed<mozilla::dom::Promise>
+   CreateImageBitmap(JSContext* aCx,
+                     const mozilla::dom::ImageBitmapSource& aImage,
+                     int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
+                     mozilla::ErrorResult& aRv);
+ 
+-  already_AddRefed<mozilla::dom::Promise>
+-  CreateImageBitmap(JSContext* aCx,
+-                    const mozilla::dom::ImageBitmapSource& aImage,
+-                    int32_t aOffset, int32_t aLength,
+-                    mozilla::dom::ImageBitmapFormat aFormat,
+-                    const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
+-                    mozilla::ErrorResult& aRv);
+-
+-
+   // ChromeWindow bits.  Do NOT call these unless your window is in
+   // fact an nsGlobalChromeWindow.
+   uint16_t WindowState();
+   bool IsFullyOccluded();
+   nsIBrowserDOMWindow* GetBrowserDOMWindowOuter();
+   nsIBrowserDOMWindow* GetBrowserDOMWindow(mozilla::ErrorResult& aError);
+   void SetBrowserDOMWindowOuter(nsIBrowserDOMWindow* aBrowserWindow);
+   void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow,
+diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
+--- a/dom/canvas/ImageBitmap.cpp
++++ b/dom/canvas/ImageBitmap.cpp
+@@ -1435,17 +1435,17 @@ ImageBitmap::Create(nsIGlobalObject* aGl
+                "Creating ImageBitmap from CanvasRenderingContext2D off the main thread.");
+     imageBitmap = CreateInternal(aGlobal, aSrc.GetAsCanvasRenderingContext2D(), aCropRect, aRv);
+   } else if (aSrc.IsImageBitmap()) {
+     imageBitmap = CreateInternal(aGlobal, aSrc.GetAsImageBitmap(), aCropRect, aRv);
+   } else if (aSrc.IsBlob()) {
+     AsyncCreateImageBitmapFromBlob(promise, aGlobal, aSrc.GetAsBlob(), aCropRect);
+     return promise.forget();
+   } else {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
++    MOZ_CRASH("Unsupported type!");
+     return nullptr;
+   }
+ 
+   if (!aRv.Failed()) {
+     AsyncFulfillImageBitmapPromise(promise, imageBitmap);
+   }
+ 
+   return promise.forget();
+@@ -1831,312 +1831,16 @@ ImageBitmap::MapDataInto(JSContext* aCx,
+       return promise.forget();
+     }
+   }
+ 
+   AsyncMapDataIntoBufferSource(aCx, promise, this, aBuffer, aOffset, aFormat);
+   return promise.forget();
+ }
+ 
+-// ImageBitmapFactories extensions.
+-static SurfaceFormat
+-ImageFormatToSurfaceFromat(mozilla::dom::ImageBitmapFormat aFormat)
+-{
+-  switch(aFormat) {
+-  case ImageBitmapFormat::RGBA32:
+-    return SurfaceFormat::R8G8B8A8;
+-  case ImageBitmapFormat::BGRA32:
+-    return SurfaceFormat::B8G8R8A8;
+-  case ImageBitmapFormat::RGB24:
+-    return SurfaceFormat::R8G8B8;
+-  case ImageBitmapFormat::BGR24:
+-    return SurfaceFormat::B8G8R8;
+-  case ImageBitmapFormat::GRAY8:
+-    return SurfaceFormat::A8;
+-  case ImageBitmapFormat::HSV:
+-    return SurfaceFormat::HSV;
+-  case ImageBitmapFormat::Lab:
+-    return SurfaceFormat::Lab;
+-  case ImageBitmapFormat::DEPTH:
+-    return SurfaceFormat::Depth;
+-  default:
+-    return SurfaceFormat::UNKNOWN;
+-  }
+-}
+-
+-static already_AddRefed<layers::Image>
+-CreateImageFromBufferSourceRawData(const uint8_t*aBufferData,
+-                                   uint32_t aBufferLength,
+-                                   mozilla::dom::ImageBitmapFormat aFormat,
+-                                   const Sequence<ChannelPixelLayout>& aLayout)
+-{
+-  MOZ_ASSERT(aBufferData);
+-  MOZ_ASSERT(aBufferLength > 0);
+-
+-  switch(aFormat) {
+-  case ImageBitmapFormat::RGBA32:
+-  case ImageBitmapFormat::BGRA32:
+-  case ImageBitmapFormat::RGB24:
+-  case ImageBitmapFormat::BGR24:
+-  case ImageBitmapFormat::GRAY8:
+-  case ImageBitmapFormat::HSV:
+-  case ImageBitmapFormat::Lab:
+-  case ImageBitmapFormat::DEPTH:
+-  {
+-    const nsTArray<ChannelPixelLayout>& channels = aLayout;
+-    MOZ_ASSERT(channels.Length() != 0, "Empty Channels.");
+-
+-    const SurfaceFormat srcFormat = ImageFormatToSurfaceFromat(aFormat);
+-    const uint32_t srcStride = channels[0].mStride;
+-    const IntSize srcSize(channels[0].mWidth, channels[0].mHeight);
+-
+-    RefPtr<DataSourceSurface> dstDataSurface =
+-      Factory::CreateDataSourceSurfaceWithStride(srcSize, srcFormat, srcStride);
+-
+-    if (NS_WARN_IF(!dstDataSurface)) {
+-      return nullptr;
+-    }
+-
+-    // Copy the raw data into the newly created DataSourceSurface.
+-    DataSourceSurface::ScopedMap dstMap(dstDataSurface, DataSourceSurface::WRITE);
+-    if (NS_WARN_IF(!dstMap.IsMapped())) {
+-      return nullptr;
+-    }
+-
+-    const uint8_t* srcBufferPtr = aBufferData;
+-    uint8_t* dstBufferPtr = dstMap.GetData();
+-
+-    for (int i = 0; i < srcSize.height; ++i) {
+-      memcpy(dstBufferPtr, srcBufferPtr, srcStride);
+-      srcBufferPtr += srcStride;
+-      dstBufferPtr += dstMap.GetStride();
+-    }
+-
+-    // Create an Image from the BGRA SourceSurface.
+-    RefPtr<SourceSurface> surface = dstDataSurface;
+-    RefPtr<layers::Image> image = CreateImageFromSurface(surface);
+-
+-    if (NS_WARN_IF(!image)) {
+-      return nullptr;
+-    }
+-
+-    return image.forget();
+-  }
+-  case ImageBitmapFormat::YUV444P:
+-  case ImageBitmapFormat::YUV422P:
+-  case ImageBitmapFormat::YUV420P:
+-  case ImageBitmapFormat::YUV420SP_NV12:
+-  case ImageBitmapFormat::YUV420SP_NV21:
+-  {
+-    // Prepare the PlanarYCbCrData.
+-    const ChannelPixelLayout& yLayout = aLayout[0];
+-    const ChannelPixelLayout& uLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[1] : aLayout[2];
+-    const ChannelPixelLayout& vLayout = aFormat != ImageBitmapFormat::YUV420SP_NV21 ? aLayout[2] : aLayout[1];
+-
+-    layers::PlanarYCbCrData data;
+-
+-    // Luminance buffer
+-    data.mYChannel = const_cast<uint8_t*>(aBufferData + yLayout.mOffset);
+-    data.mYStride = yLayout.mStride;
+-    data.mYSize = gfx::IntSize(yLayout.mWidth, yLayout.mHeight);
+-    data.mYSkip = yLayout.mSkip;
+-
+-    // Chroma buffers
+-    data.mCbChannel = const_cast<uint8_t*>(aBufferData + uLayout.mOffset);
+-    data.mCrChannel = const_cast<uint8_t*>(aBufferData + vLayout.mOffset);
+-    data.mCbCrStride = uLayout.mStride;
+-    data.mCbCrSize = gfx::IntSize(uLayout.mWidth, uLayout.mHeight);
+-    data.mCbSkip = uLayout.mSkip;
+-    data.mCrSkip = vLayout.mSkip;
+-
+-    // Picture rectangle.
+-    // We set the picture rectangle to exactly the size of the source image to
+-    // keep the full original data.
+-    data.mPicX = 0;
+-    data.mPicY = 0;
+-    data.mPicSize = data.mYSize;
+-
+-    // Create a layers::Image and set data.
+-    if (aFormat == ImageBitmapFormat::YUV444P ||
+-        aFormat == ImageBitmapFormat::YUV422P ||
+-        aFormat == ImageBitmapFormat::YUV420P) {
+-      RefPtr<layers::PlanarYCbCrImage> image =
+-        new layers::RecyclingPlanarYCbCrImage(new layers::BufferRecycleBin());
+-
+-      if (NS_WARN_IF(!image)) {
+-        return nullptr;
+-      }
+-
+-      // Set Data.
+-      if (NS_WARN_IF(!image->CopyData(data))) {
+-        return nullptr;
+-      }
+-
+-      return image.forget();
+-    } else {
+-      RefPtr<layers::NVImage>image = new layers::NVImage();
+-
+-      if (NS_WARN_IF(!image)) {
+-        return nullptr;
+-      }
+-
+-      // Set Data.
+-      if (NS_WARN_IF(!image->SetData(data))) {
+-        return nullptr;
+-      }
+-
+-      return image.forget();
+-    }
+-  }
+-  default:
+-    return nullptr;
+-  }
+-}
+-
+-/*
+- * This is a synchronous task.
+- * This class is used to create a layers::CairoImage from raw data in the main
+- * thread. While creating an ImageBitmap from an BufferSource, we need to create
+- * a SouceSurface from the BufferSource raw data and then set the SourceSurface
+- * into a layers::CairoImage. However, the layers::CairoImage asserts the
+- * setting operation in the main thread, so if we are going to create an
+- * ImageBitmap from an BufferSource off the main thread, we post an event to the
+- * main thread to create a layers::CairoImage from an BufferSource raw data.
+- *
+- * TODO: Once the layers::CairoImage is constructible off the main thread, which
+- *       means the SouceSurface could be released anywhere, we do not need this
+- *       task anymore.
+- */
+-class CreateImageFromBufferSourceRawDataInMainThreadSyncTask final :
+-  public WorkerMainThreadRunnable
+-{
+-public:
+-  CreateImageFromBufferSourceRawDataInMainThreadSyncTask(const uint8_t* aBuffer,
+-                                                         uint32_t aBufferLength,
+-                                                         mozilla::dom::ImageBitmapFormat aFormat,
+-                                                         const Sequence<ChannelPixelLayout>& aLayout,
+-                                                         /*output*/ layers::Image** aImage)
+-  : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
+-                             NS_LITERAL_CSTRING("ImageBitmap-extensions :: Create Image from BufferSource Raw Data"))
+-  , mImage(aImage)
+-  , mBuffer(aBuffer)
+-  , mBufferLength(aBufferLength)
+-  , mFormat(aFormat)
+-  , mLayout(aLayout)
+-  {
+-    MOZ_ASSERT(!(*aImage), "Don't pass an existing Image into CreateImageFromBufferSourceRawDataInMainThreadSyncTask.");
+-  }
+-
+-  bool MainThreadRun() override
+-  {
+-    RefPtr<layers::Image> image =
+-      CreateImageFromBufferSourceRawData(mBuffer, mBufferLength, mFormat, mLayout);
+-
+-    if (NS_WARN_IF(!image)) {
+-      return true;
+-    }
+-
+-    image.forget(mImage);
+-
+-    return true;
+-  }
+-
+-private:
+-  layers::Image** mImage;
+-  const uint8_t* mBuffer;
+-  uint32_t mBufferLength;
+-  mozilla::dom::ImageBitmapFormat mFormat;
+-  const Sequence<ChannelPixelLayout>& mLayout;
+-};
+-
+-/*static*/ already_AddRefed<Promise>
+-ImageBitmap::Create(nsIGlobalObject* aGlobal,
+-                    const ImageBitmapSource& aBuffer,
+-                    int32_t aOffset, int32_t aLength,
+-                    mozilla::dom::ImageBitmapFormat aFormat,
+-                    const Sequence<ChannelPixelLayout>& aLayout,
+-                    ErrorResult& aRv)
+-{
+-  MOZ_ASSERT(aGlobal);
+-
+-  RefPtr<Promise> promise = Promise::Create(aGlobal, aRv);
+-
+-  if (NS_WARN_IF(aRv.Failed())) {
+-    return nullptr;
+-  }
+-
+-  uint8_t* bufferData = nullptr;
+-  uint32_t bufferLength = 0;
+-
+-  if (aBuffer.IsArrayBuffer()) {
+-    const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
+-    buffer.ComputeLengthAndData();
+-    bufferData = buffer.Data();
+-    bufferLength = buffer.Length();
+-  } else if (aBuffer.IsArrayBufferView()) {
+-    const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
+-    bufferView.ComputeLengthAndData();
+-    bufferData = bufferView.Data();
+-    bufferLength = bufferView.Length();
+-  } else {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    return promise.forget();
+-  }
+-
+-  MOZ_ASSERT(bufferData && bufferLength > 0, "Cannot read data from BufferSource.");
+-
+-  // Check the buffer.
+-  if (((uint32_t)(aOffset + aLength) > bufferLength)) {
+-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+-    return promise.forget();
+-  }
+-
+-  // Create and Crop the raw data into a layers::Image
+-  RefPtr<layers::Image> data;
+-  if (NS_IsMainThread()) {
+-    data = CreateImageFromBufferSourceRawData(bufferData + aOffset, bufferLength,
+-                                              aFormat, aLayout);
+-  } else {
+-    RefPtr<CreateImageFromBufferSourceRawDataInMainThreadSyncTask> task =
+-      new CreateImageFromBufferSourceRawDataInMainThreadSyncTask(bufferData + aOffset,
+-                                                                 bufferLength,
+-                                                                 aFormat,
+-                                                                 aLayout,
+-                                                                 getter_AddRefs(data));
+-    task->Dispatch(Terminating, aRv);
+-    if (aRv.Failed()) {
+-      return promise.forget();
+-    }
+-  }
+-
+-  if (NS_WARN_IF(!data)) {
+-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-    return promise.forget();
+-  }
+-
+-  // Create an ImageBimtap.
+-  // Assume the data from an external buffer is not alpha-premultiplied.
+-  RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aGlobal, data,
+-                                                    gfxAlphaType::NonPremult);
+-
+-  imageBitmap->mAllocatedImageData = true;
+-
+-  // We don't need to call SetPictureRect() here because there is no cropping
+-  // supported and the ImageBitmap's mPictureRect is the size of the source
+-  // image in default
+-
+-  // We don't need to set mIsCroppingAreaOutSideOfSourceImage here because there
+-  // is no cropping supported and the mIsCroppingAreaOutSideOfSourceImage is
+-  // false in default.
+-
+-  AsyncFulfillImageBitmapPromise(promise, imageBitmap);
+-
+-  return promise.forget();
+-}
+-
+ size_t
+ ImageBitmap::GetAllocatedSize() const
+ {
+   if (!mAllocatedImageData) {
+     return 0;
+   }
+ 
+   // Calculate how many bytes are used.
+diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h
+--- a/dom/canvas/ImageBitmap.h
++++ b/dom/canvas/ImageBitmap.h
+@@ -36,17 +36,16 @@ namespace layers {
+ class Image;
+ }
+ 
+ namespace dom {
+ class OffscreenCanvas;
+ 
+ class ArrayBufferViewOrArrayBuffer;
+ class CanvasRenderingContext2D;
+-struct ChannelPixelLayout;
+ class CreateImageBitmapFromBlob;
+ class CreateImageBitmapFromBlobTask;
+ class CreateImageBitmapFromBlobWorkerTask;
+ class File;
+ class HTMLCanvasElement;
+ class HTMLImageElement;
+ class HTMLVideoElement;
+ enum class ImageBitmapFormat : uint8_t;
+@@ -124,24 +123,16 @@ public:
+   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
+diff --git a/dom/canvas/ImageBitmapSource.h b/dom/canvas/ImageBitmapSource.h
+--- a/dom/canvas/ImageBitmapSource.h
++++ b/dom/canvas/ImageBitmapSource.h
+@@ -6,16 +6,15 @@
+ 
+ #ifndef mozilla_dom_ImageBitmapSource_h
+ #define mozilla_dom_ImageBitmapSource_h
+ 
+ namespace mozilla {
+ namespace dom {
+ 
+ // So we don't have to forward declare this elsewhere.
+-class HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer;
+-typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer
+-        ImageBitmapSource;
++class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData;
++typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource;
+ 
+ }
+ }
+ 
+ #endif
+diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl
+--- a/dom/webidl/ImageBitmap.webidl
++++ b/dom/webidl/ImageBitmap.webidl
+@@ -5,35 +5,27 @@
+  *
+  * The origin of this IDL file is
+  * https://html.spec.whatwg.org/multipage/webappapis.html#images
+  *
+  * The origin of the extended IDL file is
+  * http://w3c.github.io/mediacapture-worker/#imagebitmap-extensions
+  */
+ 
+-// Extensions
+-// Bug 1141979 - [FoxEye] Extend ImageBitmap with interfaces to access its
+-// underlying image data
+-//
+-// Note:
+-// Our overload resolution implementation doesn't deal with a union as the
+-// distinguishing argument which means we cannot overload functions via union
+-// types, a.k.a. we cannot overload createImageBitmap() via ImageBitmapSource
+-// and BufferSource. Here, we work around this issue by adding the BufferSource
+-// into ImageBitmapSource.
++// This is needed because we don't support SVG element as canvas image source.
++// See bug 1500768.
++typedef (HTMLImageElement or
++         HTMLCanvasElement or
++         HTMLVideoElement or
++         ImageBitmap) CanvasImageSourceExcludedSVG;
+ 
+-typedef (HTMLImageElement or
+-         HTMLVideoElement or
+-         HTMLCanvasElement or
++typedef (CanvasImageSourceExcludedSVG or
+          Blob or
+-         ImageData or
+-         CanvasRenderingContext2D or
+-         ImageBitmap or
+-         BufferSource) ImageBitmapSource;
++         CanvasRenderingContext2D or // This is out of spec.
++         ImageData) ImageBitmapSource;
+ 
+ [Exposed=(Window,Worker)]
+ interface ImageBitmap {
+   [Constant]
+   readonly attribute unsigned long width;
+   [Constant]
+   readonly attribute unsigned long height;
+ };
+diff --git a/dom/webidl/WindowOrWorkerGlobalScope.webidl b/dom/webidl/WindowOrWorkerGlobalScope.webidl
+--- a/dom/webidl/WindowOrWorkerGlobalScope.webidl
++++ b/dom/webidl/WindowOrWorkerGlobalScope.webidl
+@@ -63,23 +63,8 @@ partial interface WindowOrWorkerGlobalSc
+    readonly attribute IDBFactory? indexedDB;
+ };
+ 
+ // https://w3c.github.io/ServiceWorker/#self-caches
+ partial interface WindowOrWorkerGlobalScope {
+   [Throws, Func="mozilla::dom::DOMPrefs::DOMCachesEnabled", SameObject]
+   readonly attribute CacheStorage caches;
+ };
+-
+-// Mozilla extensions
+-partial interface WindowOrWorkerGlobalScope {
+-  // Extensions to ImageBitmap bits.
+-  // Bug 1141979 - [FoxEye] Extend ImageBitmap with interfaces to access its
+-  // underlying image data
+-  //
+-  // Note:
+-  // Overloaded functions cannot have different "extended attributes",
+-  // so I cannot add preference on the extended version of createImageBitmap().
+-  // To work around, I will then check the preference at run time and throw if
+-  // the preference is set to be false.
+-  [Throws]
+-  Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage, long aOffset, long aLength, ImageBitmapFormat aFormat, ImagePixelLayout aLayout);
+-};
+diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp
+--- a/dom/workers/WorkerScope.cpp
++++ b/dom/workers/WorkerScope.cpp
+@@ -447,60 +447,28 @@ WorkerGlobalScope::GetIndexedDB(ErrorRes
+   return indexedDB.forget();
+ }
+ 
+ already_AddRefed<Promise>
+ WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
+                                      const ImageBitmapSource& aImage,
+                                      ErrorResult& aRv)
+ {
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    return nullptr;
+-  }
+-
+   return ImageBitmap::Create(this, aImage, Nothing(), aRv);
+ }
+ 
+ already_AddRefed<Promise>
+ WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
+                                      const ImageBitmapSource& aImage,
+                                      int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
+                                      ErrorResult& aRv)
+ {
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    return nullptr;
+-  }
+-
+   return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv);
+ }
+ 
+-already_AddRefed<mozilla::dom::Promise>
+-WorkerGlobalScope::CreateImageBitmap(JSContext* aCx,
+-                                     const ImageBitmapSource& aImage,
+-                                     int32_t aOffset, int32_t aLength,
+-                                     ImageBitmapFormat aFormat,
+-                                     const Sequence<ChannelPixelLayout>& aLayout,
+-                                     ErrorResult& aRv)
+-{
+-  if (!DOMPrefs::ImageBitmapExtensionsEnabled()) {
+-    aRv.Throw(NS_ERROR_TYPE_ERR);
+-    return nullptr;
+-  }
+-
+-  if (aImage.IsArrayBuffer() || aImage.IsArrayBufferView()) {
+-    return ImageBitmap::Create(this, aImage, aOffset, aLength, aFormat, aLayout,
+-                               aRv);
+-  } else {
+-    aRv.Throw(NS_ERROR_TYPE_ERR);
+-    return nullptr;
+-  }
+-}
+-
+ nsresult
+ WorkerGlobalScope::Dispatch(TaskCategory aCategory,
+                             already_AddRefed<nsIRunnable>&& aRunnable)
+ {
+   return EventTargetFor(aCategory)->Dispatch(std::move(aRunnable),
+                                              NS_DISPATCH_NORMAL);
+ }
+ 
+diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h
+--- a/dom/workers/WorkerScope.h
++++ b/dom/workers/WorkerScope.h
+@@ -179,24 +179,16 @@ public:
+                     const ImageBitmapSource& aImage, ErrorResult& aRv);
+ 
+   already_AddRefed<Promise>
+   CreateImageBitmap(JSContext* aCx,
+                     const ImageBitmapSource& aImage,
+                     int32_t aSx, int32_t aSy, int32_t aSw, int32_t aSh,
+                     ErrorResult& aRv);
+ 
+-  already_AddRefed<mozilla::dom::Promise>
+-  CreateImageBitmap(JSContext* aCx,
+-                    const ImageBitmapSource& aImage,
+-                    int32_t aOffset, int32_t aLength,
+-                    mozilla::dom::ImageBitmapFormat aFormat,
+-                    const mozilla::dom::Sequence<mozilla::dom::ChannelPixelLayout>& aLayout,
+-                    mozilla::ErrorResult& aRv);
+-
+   bool
+   WindowInteractionAllowed() const
+   {
+     return mWindowInteractionsAllowed > 0;
+   }
+ 
+   void
+   AllowWindowInteraction()

+ 895 - 0
mozilla-release/patches/1500733-2-65a1.patch

@@ -0,0 +1,895 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330544 -7200
+#      Tue Oct 23 23:35:44 2018 +0200
+# Node ID 3c81d4cb6aea693144608f2f78eb4b893b2687f3
+# Parent  a7c6e8df6af66a65199c468118afb46ca6cd8bdc
+Bug 1500733 - Remove ImageBitmap.mapDataInto, r=aosmond
+
+diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf
+--- a/dom/bindings/Bindings.conf
++++ b/dom/bindings/Bindings.conf
+@@ -492,20 +492,16 @@ DOMInterfaces = {
+     'headerFile': 'IDBEvents.h',
+ },
+ 
+ 'IID': {
+     'nativeType': 'nsIJSID',
+     'headerFile': 'xpcjsid.h',
+ },
+ 
+-'ImageBitmap': {
+-    'implicitJSContext': [ 'mapDataInto' ],
+-},
+-
+ 'ImageCapture': {
+     'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
+ },
+ 
+ 'ImageData': {
+     'wrapperCache': False,
+ },
+ 
+diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
+--- a/dom/canvas/ImageBitmap.cpp
++++ b/dom/canvas/ImageBitmap.cpp
+@@ -512,17 +512,16 @@ HasRasterImage(HTMLImageElement& aImageE
+ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
+                          gfxAlphaType aAlphaType)
+   : mParent(aGlobal)
+   , mData(aData)
+   , mSurface(nullptr)
+   , mDataWrapper(new ImageUtils(mData))
+   , mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
+   , mAlphaType(aAlphaType)
+-  , mIsCroppingAreaOutSideOfSourceImage(false)
+   , mAllocatedImageData(false)
+ {
+   MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
+ 
+   mShutdownObserver = new ImageBitmapShutdownObserver(this);
+   mShutdownObserver->RegisterObserver();
+ }
+ 
+@@ -559,33 +558,16 @@ ImageBitmap::OnShutdown()
+ }
+ 
+ void
+ ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv)
+ {
+   mPictureRect = FixUpNegativeDimension(aRect, aRv);
+ }
+ 
+-void
+-ImageBitmap::SetIsCroppingAreaOutSideOfSourceImage(const IntSize& aSourceSize,
+-                                                   const Maybe<IntRect>& aCroppingRect)
+-{
+-  // No cropping at all.
+-  if (aCroppingRect.isNothing()) {
+-    mIsCroppingAreaOutSideOfSourceImage = false;
+-    return;
+-  }
+-
+-  if (aCroppingRect->X() < 0 || aCroppingRect->Y() < 0 ||
+-      aCroppingRect->Width() > aSourceSize.width ||
+-      aCroppingRect->Height() > aSourceSize.height) {
+-    mIsCroppingAreaOutSideOfSourceImage = true;
+-  }
+-}
+-
+ static already_AddRefed<SourceSurface>
+ ConvertColorFormatIfNeeded(RefPtr<SourceSurface> aSurface)
+ {
+   const SurfaceFormat srcFormat = aSurface->GetFormat();
+   if (srcFormat == SurfaceFormat::R8G8B8A8 ||
+       srcFormat == SurfaceFormat::B8G8R8A8 ||
+       srcFormat == SurfaceFormat::R8G8B8X8 ||
+       srcFormat == SurfaceFormat::B8G8R8X8 ||
+@@ -785,17 +767,16 @@ ImageBitmap::TransferAsImage()
+ }
+ 
+ UniquePtr<ImageBitmapCloneData>
+ ImageBitmap::ToCloneData() const
+ {
+   UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
+   result->mPictureRect = mPictureRect;
+   result->mAlphaType = mAlphaType;
+-  result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage;
+   RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
+   result->mSurface = surface->GetDataSurface();
+   MOZ_ASSERT(result->mSurface);
+ 
+   return result;
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+@@ -803,19 +784,16 @@ ImageBitmap::CreateFromCloneData(nsIGlob
+                                  ImageBitmapCloneData* aData)
+ {
+   RefPtr<layers::Image> data = CreateImageFromSurface(aData->mSurface);
+ 
+   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mAlphaType);
+ 
+   ret->mAllocatedImageData = true;
+ 
+-  ret->mIsCroppingAreaOutSideOfSourceImage =
+-    aData->mIsCroppingAreaOutSideOfSourceImage;
+-
+   ErrorResult rv;
+   ret->SetPictureRect(aData->mPictureRect, rv);
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateFromOffscreenCanvas(nsIGlobalObject* aGlobal,
+                                        OffscreenCanvas& aOffscreenCanvas,
+@@ -882,19 +860,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+ 
+   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ 
+   // Set the picture rectangle.
+   if (ret && aCropRect.isSome()) {
+     ret->SetPictureRect(aCropRect.ref(), aRv);
+   }
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
+-
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl,
+                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
+ {
+   aVideoEl.MarkAsContentSource(mozilla::dom::HTMLVideoElement::CallerAPI::CREATE_IMAGEBITMAP);
+@@ -928,19 +903,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+   }
+   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data);
+ 
+   // Set the picture rectangle.
+   if (ret && aCropRect.isSome()) {
+     ret->SetPictureRect(aCropRect.ref(), aRv);
+   }
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  ret->SetIsCroppingAreaOutSideOfSourceImage(data->GetSize(), aCropRect);
+-
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvasEl,
+                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
+ {
+   if (aCanvasEl.Width() == 0 || aCanvasEl.Height() == 0) {
+@@ -993,19 +965,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+     ret->mAllocatedImageData = true;
+   }
+ 
+   // Set the picture rectangle.
+   if (ret && aCropRect.isSome()) {
+     ret->SetPictureRect(cropRect, aRv);
+   }
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
+-
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
+                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
+ {
+   // Copy data into SourceSurface.
+@@ -1057,19 +1026,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+   // Create an ImageBimtap.
+   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, alphaType);
+ 
+   ret->mAllocatedImageData = true;
+ 
+   // The cropping information has been handled in the CreateImageFromRawData()
+   // function.
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  ret->SetIsCroppingAreaOutSideOfSourceImage(imageSize, aCropRect);
+-
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& aCanvasCtx,
+                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
+ {
+   // Check origin-clean.
+@@ -1102,19 +1068,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+ 
+   ret->mAllocatedImageData = true;
+ 
+   // Set the picture rectangle.
+   if (ret && aCropRect.isSome()) {
+     ret->SetPictureRect(aCropRect.ref(), aRv);
+   }
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
+-
+   return ret.forget();
+ }
+ 
+ /* static */ already_AddRefed<ImageBitmap>
+ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
+                             const Maybe<IntRect>& aCropRect, ErrorResult& aRv)
+ {
+   if (!aImageBitmap.mData) {
+@@ -1125,24 +1088,16 @@ ImageBitmap::CreateInternal(nsIGlobalObj
+   RefPtr<layers::Image> data = aImageBitmap.mData;
+   RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aImageBitmap.mAlphaType);
+ 
+   // Set the picture rectangle.
+   if (ret && aCropRect.isSome()) {
+     ret->SetPictureRect(aCropRect.ref(), aRv);
+   }
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  if (aImageBitmap.mIsCroppingAreaOutSideOfSourceImage == true) {
+-    ret->mIsCroppingAreaOutSideOfSourceImage = true;
+-  } else {
+-    ret->SetIsCroppingAreaOutSideOfSourceImage(aImageBitmap.mPictureRect.Size(),
+-                                               aCropRect);
+-  }
+-
+   return ret.forget();
+ }
+ 
+ class FulfillImageBitmapPromise
+ {
+ protected:
+   FulfillImageBitmapPromise(Promise* aPromise, ImageBitmap* aImageBitmap)
+   : mPromise(aPromise)
+@@ -1462,25 +1417,26 @@ ImageBitmap::ReadStructuredClone(JSConte
+   MOZ_ASSERT(aReader);
+   // aParent might be null.
+ 
+   uint32_t picRectX_;
+   uint32_t picRectY_;
+   uint32_t picRectWidth_;
+   uint32_t picRectHeight_;
+   uint32_t alphaType_;
+-  uint32_t isCroppingAreaOutSideOfSourceImage_;
++  uint32_t dummy;
+ 
+   if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
+       !JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
+-      !JS_ReadUint32Pair(aReader, &alphaType_,
+-                                  &isCroppingAreaOutSideOfSourceImage_)) {
++      !JS_ReadUint32Pair(aReader, &alphaType_, &dummy)) {
+     return nullptr;
+   }
+ 
++  MOZ_ASSERT(dummy == 0);
++
+   int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
+   int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
+   int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
+   int32_t picRectHeight = BitwiseCast<int32_t>(picRectHeight_);
+   const auto alphaType = BitwiseCast<gfxAlphaType>(alphaType_);
+ 
+   // Create a new ImageBitmap.
+   MOZ_ASSERT(!aClonedSurfaces.IsEmpty());
+@@ -1491,19 +1447,16 @@ ImageBitmap::ReadStructuredClone(JSConte
+   // can GC (because in some cases it can!), and a return statement with a
+   // JSObject* type means that JSObject* is on the stack as a raw pointer
+   // while destructors are running.
+   JS::Rooted<JS::Value> value(aCx);
+   {
+     RefPtr<layers::Image> img = CreateImageFromSurface(aClonedSurfaces[aIndex]);
+     RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(aParent, img, alphaType);
+ 
+-    imageBitmap->mIsCroppingAreaOutSideOfSourceImage =
+-      isCroppingAreaOutSideOfSourceImage_;
+-
+     ErrorResult error;
+     imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
+                                         picRectWidth, picRectHeight), error);
+     if (NS_WARN_IF(error.Failed())) {
+       error.SuppressException();
+       return nullptr;
+     }
+ 
+@@ -1525,26 +1478,24 @@ ImageBitmap::WriteStructuredClone(JSStru
+   MOZ_ASSERT(aWriter);
+   MOZ_ASSERT(aImageBitmap);
+ 
+   const uint32_t picRectX = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.x);
+   const uint32_t picRectY = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.y);
+   const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
+   const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
+   const uint32_t alphaType = BitwiseCast<uint32_t>(aImageBitmap->mAlphaType);
+-  const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0;
+ 
+   // Indexing the cloned surfaces and send the index to the receiver.
+   uint32_t index = aClonedSurfaces.Length();
+ 
+   if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEBITMAP, index)) ||
+       NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectX, picRectY)) ||
+       NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
+-      NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType,
+-                                              isCroppingAreaOutSideOfSourceImage))) {
++      NS_WARN_IF(!JS_WriteUint32Pair(aWriter, alphaType, 0))) {
+     return false;
+   }
+ 
+   RefPtr<SourceSurface> surface =
+     aImageBitmap->mData->GetAsSourceSurface();
+   RefPtr<DataSourceSurface> snapshot = surface->GetDataSurface();
+   RefPtr<DataSourceSurface> dstDataSurface;
+   {
+@@ -1605,242 +1556,16 @@ ImageBitmap::MappedDataLength(ImageBitma
+ 
+   if (aFormat == mDataWrapper->GetFormat()) {
+     return mDataWrapper->GetBufferLength();
+   } else {
+     return CalculateImageBufferSize(aFormat, Width(), Height());
+   }
+ }
+ 
+-template<typename T>
+-class MapDataIntoBufferSource
+-{
+-protected:
+-  MapDataIntoBufferSource(JSContext* aCx,
+-                          Promise *aPromise,
+-                          ImageBitmap *aImageBitmap,
+-                          const T& aBuffer,
+-                          int32_t aOffset,
+-                          ImageBitmapFormat aFormat)
+-  : mPromise(aPromise)
+-  , mImageBitmap(aImageBitmap)
+-  , mBuffer(aCx, aBuffer.Obj())
+-  , mOffset(aOffset)
+-  , mFormat(aFormat)
+-  {
+-    MOZ_ASSERT(mPromise);
+-    MOZ_ASSERT(JS_IsArrayBufferObject(mBuffer) ||
+-               JS_IsArrayBufferViewObject(mBuffer));
+-  }
+-
+-  virtual ~MapDataIntoBufferSource() = default;
+-
+-  void DoMapDataIntoBufferSource()
+-  {
+-    ErrorResult error;
+-
+-    if (!mImageBitmap->mDataWrapper) {
+-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_AVAILABLE);
+-      mPromise->MaybeReject(error);
+-      return;
+-    }
+-
+-    // Prepare destination buffer.
+-    uint8_t* bufferData = nullptr;
+-    uint32_t bufferLength = 0;
+-    bool isSharedMemory = false;
+-    if (JS_IsArrayBufferObject(mBuffer)) {
+-      js::GetArrayBufferLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
+-    } else if (JS_IsArrayBufferViewObject(mBuffer)) {
+-      js::GetArrayBufferViewLengthAndData(mBuffer, &bufferLength, &isSharedMemory, &bufferData);
+-    } else {
+-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_IMPLEMENTED);
+-      mPromise->MaybeReject(error);
+-      return;
+-    }
+-
+-    if (NS_WARN_IF(!bufferData) || NS_WARN_IF(!bufferLength)) {
+-      error.ThrowWithCustomCleanup(NS_ERROR_NOT_AVAILABLE);
+-      mPromise->MaybeReject(error);
+-      return;
+-    }
+-
+-    // Check length.
+-    const int32_t neededBufferLength =
+-      mImageBitmap->MappedDataLength(mFormat, error);
+-
+-    if (((int32_t)bufferLength - mOffset) < neededBufferLength) {
+-      error.ThrowWithCustomCleanup(NS_ERROR_DOM_INDEX_SIZE_ERR);
+-      mPromise->MaybeReject(error);
+-      return;
+-    }
+-
+-    // Call ImageBitmapFormatUtils.
+-    UniquePtr<ImagePixelLayout> layout =
+-      mImageBitmap->mDataWrapper->MapDataInto(bufferData,
+-                                              mOffset,
+-                                              bufferLength,
+-                                              mFormat,
+-                                              error);
+-
+-    if (NS_WARN_IF(!layout)) {
+-      mPromise->MaybeReject(error);
+-      return;
+-    }
+-
+-    mPromise->MaybeResolve(*layout);
+-  }
+-
+-  RefPtr<Promise> mPromise;
+-  RefPtr<ImageBitmap> mImageBitmap;
+-  JS::PersistentRooted<JSObject*> mBuffer;
+-  int32_t mOffset;
+-  ImageBitmapFormat mFormat;
+-};
+-
+-template<typename T>
+-class MapDataIntoBufferSourceTask final : public Runnable,
+-                                          public MapDataIntoBufferSource<T>
+-{
+-public:
+-  MapDataIntoBufferSourceTask(JSContext* aCx,
+-                              Promise* aPromise,
+-                              ImageBitmap* aImageBitmap,
+-                              const T& aBuffer,
+-                              int32_t aOffset,
+-                              ImageBitmapFormat aFormat)
+-    : Runnable("dom::MapDataIntoBufferSourceTask")
+-    , MapDataIntoBufferSource<T>(aCx,
+-                                 aPromise,
+-                                 aImageBitmap,
+-                                 aBuffer,
+-                                 aOffset,
+-                                 aFormat)
+-  {
+-  }
+-
+-  virtual ~MapDataIntoBufferSourceTask() = default;
+-
+-  NS_IMETHOD Run() override
+-  {
+-    MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
+-    return NS_OK;
+-  }
+-};
+-
+-template<typename T>
+-class MapDataIntoBufferSourceWorkerTask final : public WorkerSameThreadRunnable,
+-                                                public MapDataIntoBufferSource<T>
+-{
+-public:
+-  MapDataIntoBufferSourceWorkerTask(JSContext* aCx,
+-                                    Promise *aPromise,
+-                                    ImageBitmap *aImageBitmap,
+-                                    const T& aBuffer,
+-                                    int32_t aOffset,
+-                                    ImageBitmapFormat aFormat)
+-  : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()),
+-    MapDataIntoBufferSource<T>(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat)
+-  {
+-  }
+-
+-  virtual ~MapDataIntoBufferSourceWorkerTask() = default;
+-
+-  bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
+-  {
+-    MapDataIntoBufferSource<T>::DoMapDataIntoBufferSource();
+-    return true;
+-  }
+-};
+-
+-void AsyncMapDataIntoBufferSource(JSContext* aCx,
+-                                  Promise *aPromise,
+-                                  ImageBitmap *aImageBitmap,
+-                                  const ArrayBufferViewOrArrayBuffer& aBuffer,
+-                                  int32_t aOffset,
+-                                  ImageBitmapFormat aFormat)
+-{
+-  MOZ_ASSERT(aCx);
+-  MOZ_ASSERT(aPromise);
+-  MOZ_ASSERT(aImageBitmap);
+-
+-  if (NS_IsMainThread()) {
+-    nsCOMPtr<nsIRunnable> task;
+-
+-    if (aBuffer.IsArrayBuffer()) {
+-      const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
+-      task = new MapDataIntoBufferSourceTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
+-    } else if (aBuffer.IsArrayBufferView()) {
+-      const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
+-      task = new MapDataIntoBufferSourceTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
+-    }
+-
+-    NS_DispatchToCurrentThread(task); // Actually, to the main-thread.
+-  } else {
+-    RefPtr<WorkerSameThreadRunnable> task;
+-
+-    if (aBuffer.IsArrayBuffer()) {
+-      const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer();
+-      task = new MapDataIntoBufferSourceWorkerTask<ArrayBuffer>(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat);
+-    } else if (aBuffer.IsArrayBufferView()) {
+-      const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView();
+-      task = new MapDataIntoBufferSourceWorkerTask<ArrayBufferView>(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat);
+-    }
+-
+-    task->Dispatch(); // Actually, to the current worker-thread.
+-  }
+-}
+-
+-already_AddRefed<Promise>
+-ImageBitmap::MapDataInto(JSContext* aCx,
+-                         ImageBitmapFormat aFormat,
+-                         const ArrayBufferViewOrArrayBuffer& aBuffer,
+-                         int32_t aOffset, ErrorResult& aRv)
+-{
+-  MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto().");
+-
+-  RefPtr<Promise> promise = Promise::Create(mParent, aRv);
+-
+-  if (NS_WARN_IF(aRv.Failed())) {
+-    return nullptr;
+-  }
+-
+-  if (!mDataWrapper) {
+-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-    return promise.forget();
+-
+-  }
+-
+-  // Check for cases that should throws.
+-  // Case 1:
+-  // 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),
+-  // then reject promise with IndexSizeError and abort these steps.
+-  if (mIsCroppingAreaOutSideOfSourceImage) {
+-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+-    return promise.forget();
+-  }
+-
+-  // Case 2:
+-  // If the image bitmap is going to be accessed in YUV422/YUV422 series with a
+-  // cropping area starts at an odd x or y coordinate.
+-  if (aFormat == ImageBitmapFormat::YUV422P ||
+-      aFormat == ImageBitmapFormat::YUV420P ||
+-      aFormat == ImageBitmapFormat::YUV420SP_NV12 ||
+-      aFormat == ImageBitmapFormat::YUV420SP_NV21) {
+-    if ((mPictureRect.x & 1) || (mPictureRect.y & 1)) {
+-      aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+-      return promise.forget();
+-    }
+-  }
+-
+-  AsyncMapDataIntoBufferSource(aCx, promise, this, aBuffer, aOffset, aFormat);
+-  return promise.forget();
+-}
+-
+ size_t
+ ImageBitmap::GetAllocatedSize() const
+ {
+   if (!mAllocatedImageData) {
+     return 0;
+   }
+ 
+   // Calculate how many bytes are used.
+@@ -2066,20 +1791,16 @@ CreateImageBitmapFromBlob::DecodeAndCrop
+   if (NS_WARN_IF(NS_FAILED(aStatus))) {
+     mPromise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
+     return;
+   }
+ 
+   // Create ImageBitmap object.
+   RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, aImage);
+ 
+-  // Set mIsCroppingAreaOutSideOfSourceImage.
+-  imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(mSourceSize,
+-                                                     mOriginalCropRect);
+-
+   if (mCropRect.isSome()) {
+     ErrorResult rv;
+     imageBitmap->SetPictureRect(mCropRect.ref(), rv);
+ 
+     if (rv.Failed()) {
+       mPromise->MaybeReject(rv);
+       return;
+     }
+diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h
+--- a/dom/canvas/ImageBitmap.h
++++ b/dom/canvas/ImageBitmap.h
+@@ -46,27 +46,25 @@ class CreateImageBitmapFromBlobTask;
+ class CreateImageBitmapFromBlobWorkerTask;
+ class File;
+ class HTMLCanvasElement;
+ class HTMLImageElement;
+ class HTMLVideoElement;
+ enum class ImageBitmapFormat : uint8_t;
+ class ImageData;
+ class ImageUtils;
+-template<typename T> class MapDataIntoBufferSource;
+ class Promise;
+ class PostMessageEvent; // For StructuredClone between windows.
+ class ImageBitmapShutdownObserver;
+ 
+ struct ImageBitmapCloneData final
+ {
+   RefPtr<gfx::DataSourceSurface> mSurface;
+   gfx::IntRect mPictureRect;
+   gfxAlphaType mAlphaType;
+-  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.
+@@ -139,33 +137,24 @@ public:
+   WriteStructuredClone(JSStructuredCloneWriter* aWriter,
+                        nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
+                        ImageBitmap* aImageBitmap);
+ 
+   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);
+-
+   size_t GetAllocatedSize() const;
+ 
+   void OnShutdown();
+ 
+ protected:
+ 
+   /*
+    * The default value of aIsPremultipliedAlpha is TRUE because that the
+@@ -188,19 +177,16 @@ protected:
+    */
+   ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
+               gfxAlphaType aAlphaType = gfxAlphaType::Premult);
+ 
+   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);
+ 
+@@ -259,25 +245,16 @@ protected:
+    */
+   gfx::IntRect mPictureRect;
+ 
+   const gfxAlphaType mAlphaType;
+ 
+   RefPtr<ImageBitmapShutdownObserver> mShutdownObserver;
+ 
+   /*
+-   * 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;
+-
+-  /*
+    * Whether this object allocated allocated and owns the image data.
+    */
+   bool mAllocatedImageData;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+diff --git a/dom/canvas/ImageUtils.cpp b/dom/canvas/ImageUtils.cpp
+--- a/dom/canvas/ImageUtils.cpp
++++ b/dom/canvas/ImageUtils.cpp
+@@ -118,48 +118,16 @@ public:
+   GetBufferLength() const
+   {
+     DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ);
+     const uint32_t stride = map.GetStride();
+     const IntSize size = Surface()->GetSize();
+     return (uint32_t)(size.height * stride);
+   }
+ 
+-  virtual UniquePtr<ImagePixelLayout>
+-  MapDataInto(uint8_t* aBuffer,
+-              uint32_t aOffset,
+-              uint32_t aBufferLength,
+-              ImageBitmapFormat aFormat,
+-              ErrorResult& aRv) const
+-  {
+-    DataSourceSurface::ScopedMap map(Surface(), DataSourceSurface::READ);
+-    if (!map.IsMapped()) {
+-      aRv.Throw(NS_ERROR_ILLEGAL_VALUE);
+-      return nullptr;
+-    }
+-
+-    // Copy or convert data.
+-    UniquePtr<ImagePixelLayout> srcLayout =
+-      CreateDefaultPixelLayout(GetFormat(), Surface()->GetSize().width,
+-                               Surface()->GetSize().height, map.GetStride());
+-
+-    // Prepare destination buffer.
+-    uint8_t* dstBuffer = aBuffer + aOffset;
+-    UniquePtr<ImagePixelLayout> dstLayout =
+-      CopyAndConvertImageData(GetFormat(), map.GetData(), srcLayout.get(),
+-                              aFormat, dstBuffer);
+-
+-    if (!dstLayout) {
+-      aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-      return nullptr;
+-    }
+-
+-    return dstLayout;
+-  }
+-
+ protected:
+   Impl() {}
+ 
+   DataSourceSurface* Surface() const
+   {
+     if (!mSurface) {
+       RefPtr<SourceSurface> surface = mImage->GetAsSourceSurface();
+       MOZ_ASSERT(surface);
+@@ -196,41 +164,16 @@ public:
+   uint32_t GetBufferLength() const override
+   {
+     if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
+       return mImage->AsPlanarYCbCrImage()->GetDataSize();
+     }
+     return mImage->AsNVImage()->GetBufferSize();
+   }
+ 
+-  UniquePtr<ImagePixelLayout> MapDataInto(uint8_t* aBuffer,
+-                                          uint32_t aOffset,
+-                                          uint32_t aBufferLength,
+-                                          ImageBitmapFormat aFormat,
+-                                          ErrorResult& aRv) const override
+-  {
+-    // Prepare source buffer and pixel layout.
+-    const PlanarYCbCrData* data = GetPlanarYCbCrData();
+-
+-    UniquePtr<ImagePixelLayout> srcLayout =
+-      CreatePixelLayoutFromPlanarYCbCrData(data);
+-
+-    // Do conversion.
+-    UniquePtr<ImagePixelLayout> dstLayout =
+-      CopyAndConvertImageData(GetFormat(), data->mYChannel, srcLayout.get(),
+-                              aFormat, aBuffer+aOffset);
+-
+-    if (!dstLayout) {
+-      aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-      return nullptr;
+-    }
+-
+-    return dstLayout;
+-  }
+-
+ private:
+   const PlanarYCbCrData* GetPlanarYCbCrData() const
+   {
+     if (mImage->GetFormat() == ImageFormat::PLANAR_YCBCR) {
+       return mImage->AsPlanarYCbCrImage()->GetData();
+     }
+     return mImage->AsNVImage()->GetData();
+   }
+@@ -270,22 +213,10 @@ ImageUtils::GetFormat() const
+ 
+ uint32_t
+ ImageUtils::GetBufferLength() const
+ {
+   MOZ_ASSERT(mImpl);
+   return mImpl->GetBufferLength();
+ }
+ 
+-UniquePtr<ImagePixelLayout>
+-ImageUtils::MapDataInto(uint8_t* aBuffer,
+-                        uint32_t aOffset,
+-                        uint32_t aBufferLength,
+-                        ImageBitmapFormat aFormat,
+-                        ErrorResult& aRv) const
+-{
+-  MOZ_ASSERT(mImpl);
+-  MOZ_ASSERT(aBuffer, "Map data into a null buffer.");
+-  return mImpl->MapDataInto(aBuffer, aOffset, aBufferLength, aFormat, aRv);
+-}
+-
+ } // namespace dom
+ } // namespace mozilla
+diff --git a/dom/canvas/ImageUtils.h b/dom/canvas/ImageUtils.h
+--- a/dom/canvas/ImageUtils.h
++++ b/dom/canvas/ImageUtils.h
+@@ -27,20 +27,16 @@ typedef nsTArray<ChannelPixelLayout> Ima
+ 
+ /*
+  * ImageUtils is a wrapper around layers::Image. It provides three unified
+  * methods to all sub-classes of layers::Image, which are:
+  *
+  * (1) GetFormat() converts the image's format into ImageBitmapFormat enum.
+  * (2) GetBufferLength() returns the number of bytes that are used to store
+  *     the image's underlying raw data.
+- * (3) MapDataInto() writes the image's underlying raw data into a given
+- *     ArrayBuffer in the given format. (If the given format is different from
+- *     the existing format, the ImageUtils uses the ImageBitmapFormatUtils to
+- *     performa color conversion.)
+  *
+  * In theory, the functionalities of this class could be merged into the
+  * interface of layers::Image. However, this is designed as a isolated wrapper
+  * because we don't want to pollute the layers::Image's interface with methods
+  * that are only meaningful to the ImageBitmap.
+  */
+ class ImageUtils
+ {
+@@ -54,20 +50,16 @@ public:
+ 
+   explicit ImageUtils(layers::Image* aImage);
+   ~ImageUtils();
+ 
+   ImageBitmapFormat GetFormat() const;
+ 
+   uint32_t GetBufferLength() const;
+ 
+-  UniquePtr<ImagePixelLayout>
+-  MapDataInto(uint8_t* aBuffer, uint32_t aOffset, uint32_t aBufferLength,
+-              ImageBitmapFormat aFormat, ErrorResult& aRv) const;
+-
+ protected:
+   Impl* mImpl;
+ };
+ 
+ } // namespace dom
+ } // namespace mozilla
+ 
+ #endif /* mozilla_dom_ImageBitmapFormatUtils_h */
+diff --git a/dom/canvas/test/imagebitmap_extensions.js b/dom/canvas/test/imagebitmap_extensions.js
+--- a/dom/canvas/test/imagebitmap_extensions.js
++++ b/dom/canvas/test/imagebitmap_extensions.js
+@@ -518,9 +518,9 @@ function doOneDrawTest(sourceFromat, tol
+         resolve();
+       },
+       function(ev) {
+         failed(ev);
+         reject(ev);
+       }
+     );
+   });
+-}
+\ No newline at end of file
++}
+diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl
+--- a/dom/webidl/ImageBitmap.webidl
++++ b/dom/webidl/ImageBitmap.webidl
+@@ -394,11 +394,9 @@ dictionary ChannelPixelLayout {
+ 
+ typedef sequence<ChannelPixelLayout> ImagePixelLayout;
+ 
+ partial interface ImageBitmap {
+     [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+     ImageBitmapFormat               findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
+     [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+     long                            mappedDataLength (ImageBitmapFormat aFormat);
+-    [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+-    Promise<ImagePixelLayout> mapDataInto (ImageBitmapFormat aFormat, BufferSource aBuffer, long aOffset);
+ };

+ 139 - 0
mozilla-release/patches/1500733-3-65a1.patch

@@ -0,0 +1,139 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330544 -7200
+#      Tue Oct 23 23:35:44 2018 +0200
+# Node ID 17ac83c08f67ff1e3846c375de8d5dd0851580b3
+# Parent  ac9e79c0bda893c0d7b3a34c4cc651b69d72889a
+Bug 1500733 - Remove ImageBitmap.mappedDataLength, r=aosmond
+
+diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
+--- a/dom/canvas/ImageBitmap.cpp
++++ b/dom/canvas/ImageBitmap.cpp
+@@ -1541,31 +1541,16 @@ ImageBitmap::FindOptimalFormat(const Opt
+     if (optimalFormat == ImageBitmapFormat::EndGuard_) {
+       aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+     }
+ 
+     return optimalFormat;
+   }
+ }
+ 
+-int32_t
+-ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv)
+-{
+-  if (!mDataWrapper) {
+-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-    return 0;
+-  }
+-
+-  if (aFormat == mDataWrapper->GetFormat()) {
+-    return mDataWrapper->GetBufferLength();
+-  } else {
+-    return CalculateImageBufferSize(aFormat, Width(), Height());
+-  }
+-}
+-
+ size_t
+ ImageBitmap::GetAllocatedSize() const
+ {
+   if (!mAllocatedImageData) {
+     return 0;
+   }
+ 
+   // Calculate how many bytes are used.
+diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h
+--- a/dom/canvas/ImageBitmap.h
++++ b/dom/canvas/ImageBitmap.h
+@@ -142,19 +142,16 @@ public:
+   friend CreateImageBitmapFromBlobTask;
+   friend CreateImageBitmapFromBlobWorkerTask;
+ 
+   // Mozilla Extensions
+   ImageBitmapFormat
+   FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
+                     ErrorResult& aRv);
+ 
+-  int32_t
+-  MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
+-
+   size_t GetAllocatedSize() const;
+ 
+   void OnShutdown();
+ 
+ protected:
+ 
+   /*
+    * The default value of aIsPremultipliedAlpha is TRUE because that the
+diff --git a/dom/canvas/ImageBitmapUtils.cpp b/dom/canvas/ImageBitmapUtils.cpp
+--- a/dom/canvas/ImageBitmapUtils.cpp
++++ b/dom/canvas/ImageBitmapUtils.cpp
+@@ -2725,26 +2725,16 @@ uint8_t
+ GetChannelCountOfImageFormat(ImageBitmapFormat aFormat)
+ {
+   UtilsUniquePtr format = Utils::GetUtils(aFormat);
+   MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+ 
+   return format->GetChannelCount();
+ }
+ 
+-uint32_t
+-CalculateImageBufferSize(ImageBitmapFormat aFormat,
+-                         uint32_t aWidth, uint32_t aHeight)
+-{
+-  UtilsUniquePtr format = Utils::GetUtils(aFormat);
+-  MOZ_ASSERT(format, "Cannot get a valid ImageBitmapFormatUtils instance.");
+-
+-  return format->NeededBufferSize(aWidth, aHeight);
+-}
+-
+ UniquePtr<ImagePixelLayout>
+ CopyAndConvertImageData(ImageBitmapFormat aSrcFormat,
+                         const uint8_t* aSrcBuffer,
+                         const ImagePixelLayout* aSrcLayout,
+                         ImageBitmapFormat aDstFormat,
+                         uint8_t* aDstBuffer)
+ {
+   MOZ_ASSERT(aSrcBuffer, "Convert color from a null buffer.");
+diff --git a/dom/canvas/ImageBitmapUtils.h b/dom/canvas/ImageBitmapUtils.h
+--- a/dom/canvas/ImageBitmapUtils.h
++++ b/dom/canvas/ImageBitmapUtils.h
+@@ -44,24 +44,16 @@ CreatePixelLayoutFromPlanarYCbCrData(con
+ 
+ /*
+  * Get the number of channels of the given ImageBitmapFormat.
+  */
+ uint8_t
+ GetChannelCountOfImageFormat(ImageBitmapFormat aFormat);
+ 
+ /*
+- * Get the needed buffer size to store the image data in the given
+- * ImageBitmapFormat with the given width and height.
+- */
+-uint32_t
+-CalculateImageBufferSize(ImageBitmapFormat aFormat,
+-                         uint32_t aWidth, uint32_t aHeight);
+-
+-/*
+  * This function always copies the image data in _aSrcBuffer_ into _aDstBuffer_
+  * and it also performs color conversion if the _aSrcFormat_ and the
+  * _aDstFormat_ are different.
+  *
+  * The source image is stored in the _aSrcBuffer_ and the corresponding pixel
+  * layout is described by the _aSrcLayout_.
+  *
+  * The copied and converted image will be stored in the _aDstBuffer_, which
+diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl
+--- a/dom/webidl/ImageBitmap.webidl
++++ b/dom/webidl/ImageBitmap.webidl
+@@ -392,11 +392,9 @@ dictionary ChannelPixelLayout {
+     required unsigned long              skip;
+ };
+ 
+ typedef sequence<ChannelPixelLayout> ImagePixelLayout;
+ 
+ partial interface ImageBitmap {
+     [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+     ImageBitmapFormat               findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
+-    [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+-    long                            mappedDataLength (ImageBitmapFormat aFormat);
+ };

+ 99 - 0
mozilla-release/patches/1500733-4-65a1.patch

@@ -0,0 +1,99 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330544 -7200
+#      Tue Oct 23 23:35:44 2018 +0200
+# Node ID e324b60281ddc58a514dc84db048431a64312a01
+# Parent  96efb52c531ca39bd92a8cc59174f5eda19cb520
+Bug 1500733 - Remove ImageBitmap.findOptimalFormat, r=aosmond
+
+diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp
+--- a/dom/canvas/ImageBitmap.cpp
++++ b/dom/canvas/ImageBitmap.cpp
+@@ -1512,45 +1512,16 @@ ImageBitmap::WriteStructuredClone(JSStru
+   if (NS_WARN_IF(!dstDataSurface)) {
+     return false;
+   }
+   Factory::CopyDataSourceSurface(snapshot, dstDataSurface);
+   aClonedSurfaces.AppendElement(dstDataSurface);
+   return true;
+ }
+ 
+-// ImageBitmap extensions.
+-ImageBitmapFormat
+-ImageBitmap::FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
+-                               ErrorResult& aRv)
+-{
+-  if (!mDataWrapper) {
+-    aRv.Throw(NS_ERROR_NOT_AVAILABLE);
+-    return ImageBitmapFormat::EndGuard_;
+-  }
+-
+-  ImageBitmapFormat platformFormat = mDataWrapper->GetFormat();
+-
+-  if (!aPossibleFormats.WasPassed() ||
+-      aPossibleFormats.Value().Contains(platformFormat)) {
+-    return platformFormat;
+-  } else {
+-    // If no matching is found, FindBestMatchingFromat() returns
+-    // ImageBitmapFormat::EndGuard_ and we throw an exception.
+-    ImageBitmapFormat optimalFormat =
+-      FindBestMatchingFromat(platformFormat, aPossibleFormats.Value());
+-
+-    if (optimalFormat == ImageBitmapFormat::EndGuard_) {
+-      aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+-    }
+-
+-    return optimalFormat;
+-  }
+-}
+-
+ size_t
+ ImageBitmap::GetAllocatedSize() const
+ {
+   if (!mAllocatedImageData) {
+     return 0;
+   }
+ 
+   // Calculate how many bytes are used.
+diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h
+--- a/dom/canvas/ImageBitmap.h
++++ b/dom/canvas/ImageBitmap.h
+@@ -137,21 +137,16 @@ public:
+   WriteStructuredClone(JSStructuredCloneWriter* aWriter,
+                        nsTArray<RefPtr<gfx::DataSourceSurface>>& aClonedSurfaces,
+                        ImageBitmap* aImageBitmap);
+ 
+   friend CreateImageBitmapFromBlob;
+   friend CreateImageBitmapFromBlobTask;
+   friend CreateImageBitmapFromBlobWorkerTask;
+ 
+-  // Mozilla Extensions
+-  ImageBitmapFormat
+-  FindOptimalFormat(const Optional<Sequence<ImageBitmapFormat>>& aPossibleFormats,
+-                    ErrorResult& aRv);
+-
+   size_t GetAllocatedSize() const;
+ 
+   void OnShutdown();
+ 
+ protected:
+ 
+   /*
+    * The default value of aIsPremultipliedAlpha is TRUE because that the
+diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl
+--- a/dom/webidl/ImageBitmap.webidl
++++ b/dom/webidl/ImageBitmap.webidl
+@@ -388,13 +388,8 @@ dictionary ChannelPixelLayout {
+     required unsigned long              width;
+     required unsigned long              height;
+     required ChannelPixelLayoutDataType dataType;
+     required unsigned long              stride;
+     required unsigned long              skip;
+ };
+ 
+ typedef sequence<ChannelPixelLayout> ImagePixelLayout;
+-
+-partial interface ImageBitmap {
+-    [Throws, Func="mozilla::dom::DOMPrefs::ImageBitmapExtensionsEnabled"]
+-    ImageBitmapFormat               findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
+-};

+ 1955 - 0
mozilla-release/patches/1500733-5-65a1.patch

@@ -0,0 +1,1955 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330544 -7200
+#      Tue Oct 23 23:35:44 2018 +0200
+# Node ID 8b5a4cd42d40d1ff27ec63265960f7e6fd43dfea
+# Parent  e324b60281ddc58a514dc84db048431a64312a01
+Bug 1500733 - Remove tests, r=aosmond
+
+diff --git a/dom/canvas/test/imagebitmap_extensions.html b/dom/canvas/test/imagebitmap_extensions.html
+deleted file mode 100644
+--- a/dom/canvas/test/imagebitmap_extensions.html
++++ /dev/null
+@@ -1,49 +0,0 @@
+-<!DOCTYPE HTML>
+-<head>
+-  <title>Test ImageBitmap Extensions (Bug 1141979)</title>
+-  <meta charset="utf-8">
+-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+-</head>
+-<body>
+-<script src="imagebitmap_extensions_prepareSources.js"></script>
+-<script src="imagebitmap_extensions_data.js"></script>
+-<script src="imagebitmap_extensions.js"></script>
+-<script type="text/javascript">
+-
+-runTests();
+-
+-function ok(expect, msg) {
+-  window.parent.postMessage({"type": "status", status: !!expect, msg: msg}, "*");
+-}
+-
+-function runTests() {
+-
+-  prepareSources().
+-    then( function() { return Promise.all([testAccessing_randomTest("Video", gVideo, 20), // video might use slightly different frames
+-                                           testAccessing_randomTest("Image", gImage, 0),
+-                                           testAccessing_randomTest("Canvas", gCanvas, 0),
+-                                           testAccessing_randomTest("Ctx", gCtx, 0),
+-                                           testAccessing_randomTest("ImageData", gImageData, 0),
+-                                           testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
+-                                           testAccessing_randomTest("PNG", gPNGBlob, 0),
+-                                           testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
+-                                          ]); }).
+-    then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("Video", gVideo, 20), // video might use slightly different frames
+-                                           testCreateFromArrayBffer_randomTest("Image", gImage, 0),
+-                                           testCreateFromArrayBffer_randomTest("Canvas", gCanvas, 0),
+-                                           testCreateFromArrayBffer_randomTest("Ctx", gCtx, 0),
+-                                           testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
+-                                           testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
+-                                           testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
+-                                           testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
+-                                          ]); }).
+-    then(testDraw()).
+-    then(testExceptions).
+-    then(testColorConversions()).
+-    then(function() { return testInvalidAccess([gVideo, gImage, gCanvas, gCtx, gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
+-    then(function() {window.parent.postMessage({"type": "finish"}, "*");}, function(ev) { failed(ev); window.parent.postMessage({"type": "finish"}, "*"); });
+-}
+-
+-</script>
+-</body>
+diff --git a/dom/canvas/test/imagebitmap_extensions.js b/dom/canvas/test/imagebitmap_extensions.js
+deleted file mode 100644
+--- a/dom/canvas/test/imagebitmap_extensions.js
++++ /dev/null
+@@ -1,526 +0,0 @@
+-function failed(ex) {
+-  ok(false, "Promise failure: " + ex);
+-}
+-
+-function isPixel(sourceType, bitmapFormat, imageData, bitmapImageData, x, y, tolerance) {
+-  if (imageData.width != bitmapImageData.width ||
+-    imageData.height != bitmapImageData.height) {
+-    ok(false, "Wrong dimension");
+-  }
+-
+-  var index = 4 * (y * imageData.width + x);
+-
+-  var pr = imageData.data[index+0],
+-      pg = imageData.data[index+1],
+-      pb = imageData.data[index+2],
+-      pa = imageData.data[index+3];
+-
+-  if (bitmapFormat == "RGBA32" || bitmapFormat == "RGBX32") {
+-    var bpr = bitmapImageData.data[index+0],
+-        bpg = bitmapImageData.data[index+1],
+-        bpb = bitmapImageData.data[index+2],
+-        bpa = bitmapImageData.data[index+3];
+-  }
+-  else if (bitmapFormat == "BGRA32" || bitmapFormat == "BGRX32") {
+-    var bpb = bitmapImageData.data[index+0],
+-        bpg = bitmapImageData.data[index+1],
+-        bpr = bitmapImageData.data[index+2],
+-        bpa = bitmapImageData.data[index+3];
+-  }
+-  else {
+-    // format might be one of the followings: "R5G6B5", "A8", "YUV", ""
+-    ok(false, "Not supported ImageFormat: " + bitmapFormat);
+-  }
+-
+-  ok(pr - tolerance <= bpr && bpr <= pr + tolerance &&
+-     pg - tolerance <= bpg && bpg <= pg + tolerance &&
+-     pb - tolerance <= bpb && bpb <= pb + tolerance &&
+-     pa - tolerance <= bpa && bpa <= pa + tolerance,
+-     "pixel[" + x + "][" + y + "]: " + sourceType + " is "+pr+","+pg+","+pb+","+pa+"; ImageBitmap is "+ bpr + "," + bpg + "," + bpb + "," + bpa);
+-}
+-
+-function promiseThrows(p, name) {
+-  var didThrow;
+-  return p.then(function() { didThrow = false; },
+-                function() { didThrow = true; })
+-          .then(function() { ok(didThrow, name); });
+-}
+-
+-function testExceptions() {
+-  return Promise.all([
+-    promiseThrows(testColorConversion("GRAY8", "RGBA32", undefined, true), "[Exception] Cannot convert from GRAY8 to RGBA32"),
+-    promiseThrows(testColorConversion("GRAY8", "BGRA32", undefined, true), "[Exception] Cannot convert from GRAY8 to BGRA32"),
+-    promiseThrows(testColorConversion("GRAY8", "RGB24", undefined, true), "[Exception] Cannot convert from GRAY8 to RGB24"),
+-    promiseThrows(testColorConversion("GRAY8", "BGR24", undefined, true), "[Exception] Cannot convert from GRAY8 to BGR24"),
+-    promiseThrows(testColorConversion("GRAY8", "YUV444P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV444P"),
+-    promiseThrows(testColorConversion("GRAY8", "YUV422P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV422P"),
+-    promiseThrows(testColorConversion("GRAY8", "YUV420P", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420P"),
+-    promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV12"),
+-    promiseThrows(testColorConversion("GRAY8", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from GRAY8 to YUV420SP_NV21"),
+-    promiseThrows(testColorConversion("GRAY8", "HSV", undefined, true), "[Exception] Cannot convert from GRAY8 to HSV"),
+-    promiseThrows(testColorConversion("GRAY8", "Lab", undefined, true), "[Exception] Cannot convert from GRAY8 to Lab"),
+-    promiseThrows(testColorConversion("GRAY8", "DEPTH", undefined, true), "[Exception] Cannot convert from GRAY8 to DEPTH"),
+-
+-    promiseThrows(testColorConversion("DEPTH", "RGBA32", undefined, true), "[Exception] Cannot convert from DEPTH to RGBA32"),
+-    promiseThrows(testColorConversion("DEPTH", "BGRA32", undefined, true), "[Exception] Cannot convert from DEPTH to BGRA32"),
+-    promiseThrows(testColorConversion("DEPTH", "RGB24", undefined, true), "[Exception] Cannot convert from DEPTH to RGB24"),
+-    promiseThrows(testColorConversion("DEPTH", "BGR24", undefined, true), "[Exception] Cannot convert from DEPTH to BGR24"),
+-    promiseThrows(testColorConversion("DEPTH", "GRAY8", undefined, true), "[Exception] Cannot convert from DEPTH to GRAY8"),
+-    promiseThrows(testColorConversion("DEPTH", "YUV444P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV444P"),
+-    promiseThrows(testColorConversion("DEPTH", "YUV422P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV422P"),
+-    promiseThrows(testColorConversion("DEPTH", "YUV420P", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420P"),
+-    promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV12", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV12"),
+-    promiseThrows(testColorConversion("DEPTH", "YUV420SP_NV21", undefined, true), "[Exception] Cannot convert from DEPTH to YUV420SP_NV21"),
+-    promiseThrows(testColorConversion("DEPTH", "HSV", undefined, true), "[Exception] Cannot convert from DEPTH to HSV"),
+-    promiseThrows(testColorConversion("DEPTH", "Lab", undefined, true), "[Exception] Cannot convert from DEPTH to Lab"),
+-
+-    promiseThrows(testColorConversion("RGBA32", "DEPTH", undefined, true), "[Exception] Cannot convert from RGBA32 to DEPTH"),
+-    promiseThrows(testColorConversion("BGRA32", "DEPTH", undefined, true), "[Exception] Cannot convert from BGRA32 to DEPTH"),
+-    promiseThrows(testColorConversion("RGB24", "DEPTH", undefined, true), "[Exception] Cannot convert from RGB24 to DEPTH"),
+-    promiseThrows(testColorConversion("BGR24", "DEPTH", undefined, true), "[Exception] Cannot convert from BGR24 to DEPTH"),
+-    promiseThrows(testColorConversion("YUV444P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV444P to DEPTH"),
+-    promiseThrows(testColorConversion("YUV422P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV422P to DEPTH"),
+-    promiseThrows(testColorConversion("YUV420P", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420P to DEPTH"),
+-    promiseThrows(testColorConversion("YUV420SP_NV12", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV12 to DEPTH"),
+-    promiseThrows(testColorConversion("YUV420SP_NV21", "DEPTH", undefined, true), "[Exception] Cannot convert from YUV420SP_NV21 to DEPTH"),
+-    promiseThrows(testColorConversion("HSV", "DEPTH", undefined, true), "[Exception] Cannot convert from HSV to DEPTH"),
+-    promiseThrows(testColorConversion("Lab", "DEPTH", undefined, true), "[Exception] Cannot convert from Lab to DEPTH"),
+-  ]);
+-}
+-
+-function testInvalidAccess(sources) {
+-
+-  function callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source) {
+-    return new Promise(function(resolve, reject) {
+-      var p = createImageBitmap(source, -1, -1, 2, 2);
+-      p.then(
+-        function(bitmap) {
+-          var format = bitmap.findOptimalFormat();
+-          var length = bitmap.mappedDataLength(format);
+-          var buffer = new ArrayBuffer(length);
+-          bitmap.mapDataInto(format, buffer, 0).then(
+-            function(layout) { resolve(); },
+-            function(error) { reject(error); }
+-          );
+-        },
+-        function() { resolve(); });
+-    });
+-  };
+-
+-  var testCases = sources.map( function(source) {
+-    return promiseThrows(callMapDataIntoWithImageBitmapCroppedOutSideOfTheSourceImage(source),
+-                         "[Exception] mapDataInto() should throw with transparent black."); });
+-
+-  return Promise.all(testCases);
+-}
+-
+-function testColorConversions() {
+-  return Promise.all([// From RGBA32
+-                      testColorConversion("RGBA32", "RGBA32"),
+-                      testColorConversion("RGBA32", "BGRA32"),
+-                      testColorConversion("RGBA32", "RGB24"),
+-                      testColorConversion("RGBA32", "BGR24"),
+-                      testColorConversion("RGBA32", "GRAY8"),
+-                      testColorConversion("RGBA32", "YUV444P"),
+-                      testColorConversion("RGBA32", "YUV422P"),
+-                      testColorConversion("RGBA32", "YUV420P", 2),
+-                      testColorConversion("RGBA32", "YUV420SP_NV12"),
+-                      testColorConversion("RGBA32", "YUV420SP_NV21"),
+-                      testColorConversion("RGBA32", "HSV", 0.01),
+-                      testColorConversion("RGBA32", "Lab", 0.5),
+-
+-                      // From BGRA32
+-                      testColorConversion("BGRA32", "RGBA32"),
+-                      testColorConversion("BGRA32", "BGRA32"),
+-                      testColorConversion("BGRA32", "RGB24"),
+-                      testColorConversion("BGRA32", "BGR24"),
+-                      testColorConversion("BGRA32", "GRAY8"),
+-                      testColorConversion("BGRA32", "YUV444P", 3),
+-                      testColorConversion("BGRA32", "YUV422P", 2),
+-                      testColorConversion("BGRA32", "YUV420P", 2),
+-                      testColorConversion("BGRA32", "YUV420SP_NV12", 2),
+-                      testColorConversion("BGRA32", "YUV420SP_NV21", 2),
+-                      testColorConversion("BGRA32", "HSV", 0.01),
+-                      testColorConversion("BGRA32", "Lab", 0.5),
+-
+-                      // From RGB24
+-                      testColorConversion("RGB24", "RGBA32"),
+-                      testColorConversion("RGB24", "BGRA32"),
+-                      testColorConversion("RGB24", "RGB24"),
+-                      testColorConversion("RGB24", "BGR24"),
+-                      testColorConversion("RGB24", "GRAY8"),
+-                      testColorConversion("RGB24", "YUV444P"),
+-                      testColorConversion("RGB24", "YUV422P"),
+-                      testColorConversion("RGB24", "YUV420P"),
+-                      testColorConversion("RGB24", "YUV420SP_NV12"),
+-                      testColorConversion("RGB24", "YUV420SP_NV21"),
+-                      testColorConversion("RGB24", "HSV", 0.01),
+-                      testColorConversion("RGB24", "Lab", 0.5),
+-
+-                      // From BGR24
+-                      testColorConversion("BGR24", "RGBA32"),
+-                      testColorConversion("BGR24", "BGRA32"),
+-                      testColorConversion("BGR24", "RGB24"),
+-                      testColorConversion("BGR24", "BGR24"),
+-                      testColorConversion("BGR24", "GRAY8"),
+-                      testColorConversion("BGR24", "YUV444P"),
+-                      testColorConversion("BGR24", "YUV422P"),
+-                      testColorConversion("BGR24", "YUV420P"),
+-                      testColorConversion("BGR24", "YUV420SP_NV12"),
+-                      testColorConversion("BGR24", "YUV420SP_NV21"),
+-                      testColorConversion("BGR24", "HSV", 0.01),
+-                      testColorConversion("BGR24", "Lab", 0.5),
+-
+-                      // From YUV444P
+-                      testColorConversion("YUV444P", "RGBA32"),
+-                      testColorConversion("YUV444P", "BGRA32"),
+-                      testColorConversion("YUV444P", "RGB24"),
+-                      testColorConversion("YUV444P", "BGR24"),
+-                      testColorConversion("YUV444P", "GRAY8"),
+-                      testColorConversion("YUV444P", "YUV444P"),
+-                      testColorConversion("YUV444P", "YUV422P", 4),
+-                      testColorConversion("YUV444P", "YUV420P", 3),
+-                      testColorConversion("YUV444P", "YUV420SP_NV12", 3),
+-                      testColorConversion("YUV444P", "YUV420SP_NV21", 3),
+-                      testColorConversion("YUV444P", "HSV", 0.01),
+-                      testColorConversion("YUV444P", "Lab", 0.01),
+-
+-                      // From YUV422P
+-                      testColorConversion("YUV422P", "RGBA32"),
+-                      testColorConversion("YUV422P", "BGRA32", 2),
+-                      testColorConversion("YUV422P", "RGB24"),
+-                      testColorConversion("YUV422P", "BGR24"),
+-                      testColorConversion("YUV422P", "GRAY8"),
+-                      testColorConversion("YUV422P", "YUV444P", 3),
+-                      testColorConversion("YUV422P", "YUV422P"),
+-                      testColorConversion("YUV422P", "YUV420P"),
+-                      testColorConversion("YUV422P", "YUV420SP_NV12"),
+-                      testColorConversion("YUV422P", "YUV420SP_NV21"),
+-                      testColorConversion("YUV422P", "HSV", 0.01),
+-                      testColorConversion("YUV422P", "Lab", 0.01),
+-
+-                      // From YUV420P
+-                      testColorConversion("YUV420P", "RGBA32", 2),
+-                      testColorConversion("YUV420P", "BGRA32", 2),
+-                      testColorConversion("YUV420P", "RGB24"),
+-                      testColorConversion("YUV420P", "BGR24"),
+-                      testColorConversion("YUV420P", "GRAY8"),
+-                      testColorConversion("YUV420P", "YUV444P", 3),
+-                      testColorConversion("YUV420P", "YUV422P", 1),
+-                      testColorConversion("YUV420P", "YUV420P"),
+-                      testColorConversion("YUV420P", "YUV420SP_NV12"),
+-                      testColorConversion("YUV420P", "YUV420SP_NV21"),
+-                      testColorConversion("YUV420P", "HSV", 0.01),
+-                      testColorConversion("YUV420P", "Lab", 0.01),
+-
+-                      // From NV12
+-                      testColorConversion("YUV420SP_NV12", "RGBA32"),
+-                      testColorConversion("YUV420SP_NV12", "BGRA32", 2),
+-                      testColorConversion("YUV420SP_NV12", "RGB24"),
+-                      testColorConversion("YUV420SP_NV12", "BGR24"),
+-                      testColorConversion("YUV420SP_NV12", "GRAY8"),
+-                      testColorConversion("YUV420SP_NV12", "YUV444P", 3),
+-                      testColorConversion("YUV420SP_NV12", "YUV422P", 1),
+-                      testColorConversion("YUV420SP_NV12", "YUV420P"),
+-                      testColorConversion("YUV420SP_NV12", "YUV420SP_NV12"),
+-                      testColorConversion("YUV420SP_NV12", "YUV420SP_NV21"),
+-                      testColorConversion("YUV420SP_NV12", "HSV", 0.01),
+-                      testColorConversion("YUV420SP_NV12", "Lab", 0.01),
+-
+-                      // From NV21
+-                      testColorConversion("YUV420SP_NV21", "RGBA32"),
+-                      testColorConversion("YUV420SP_NV21", "BGRA32", 2),
+-                      testColorConversion("YUV420SP_NV21", "RGB24"),
+-                      testColorConversion("YUV420SP_NV21", "BGR24"),
+-                      testColorConversion("YUV420SP_NV21", "GRAY8"),
+-                      testColorConversion("YUV420SP_NV21", "YUV444P", 3),
+-                      testColorConversion("YUV420SP_NV21", "YUV422P", 1),
+-                      testColorConversion("YUV420SP_NV21", "YUV420P"),
+-                      testColorConversion("YUV420SP_NV21", "YUV420SP_NV12"),
+-                      testColorConversion("YUV420SP_NV21", "YUV420SP_NV21"),
+-                      testColorConversion("YUV420SP_NV21", "HSV", 0.01),
+-                      testColorConversion("YUV420SP_NV21", "Lab", 0.01),
+-
+-                      // From HSV
+-                      testColorConversion("HSV", "RGBA32"),
+-                      testColorConversion("HSV", "BGRA32"),
+-                      testColorConversion("HSV", "RGB24"),
+-                      testColorConversion("HSV", "BGR24"),
+-                      testColorConversion("HSV", "GRAY8"),
+-                      testColorConversion("HSV", "YUV444P"),
+-                      testColorConversion("HSV", "YUV422P"),
+-                      testColorConversion("HSV", "YUV420P"),
+-                      testColorConversion("HSV", "YUV420SP_NV12"),
+-                      testColorConversion("HSV", "YUV420SP_NV21"),
+-                      testColorConversion("HSV", "HSV", 0),
+-                      testColorConversion("HSV", "Lab", 0.5),
+-
+-                      // From Lab
+-                      testColorConversion("Lab", "RGBA32", 1),
+-                      testColorConversion("Lab", "BGRA32", 1),
+-                      testColorConversion("Lab", "RGB24", 1),
+-                      testColorConversion("Lab", "BGR24", 1),
+-                      testColorConversion("Lab", "GRAY8", 1),
+-                      testColorConversion("Lab", "YUV444P", 1),
+-                      testColorConversion("Lab", "YUV422P", 1),
+-                      testColorConversion("Lab", "YUV420P", 1),
+-                      testColorConversion("Lab", "YUV420SP_NV12", 1),
+-                      testColorConversion("Lab", "YUV420SP_NV21", 1),
+-                      testColorConversion("Lab", "HSV", 0.5),
+-                      testColorConversion("Lab", "Lab", 0),
+-
+-                      // From GRAY8
+-                      testColorConversion("GRAY8", "GRAY8"),
+-
+-                      // From DEPTH
+-                      testColorConversion("DEPTH", "DEPTH", 0, Uint16Array),
+-                     ]);
+-}
+-
+-function testDraw() {
+-  return Promise.all([doOneDrawTest("RGB24"),
+-                      doOneDrawTest("BGR24"),
+-                      doOneDrawTest("YUV444P", 5),
+-                      doOneDrawTest("YUV422P", 2),
+-                      doOneDrawTest("YUV420P", 2),
+-                      doOneDrawTest("YUV420SP_NV12", 2),
+-                      doOneDrawTest("YUV420SP_NV21", 2),
+-                      doOneDrawTest("HSV", 2),
+-                      doOneDrawTest("Lab", 2)]);
+-}
+-
+-// Create an ImageBitmap, _bitmap_, from the _source_.
+-// Read the underlying data of _bitmap_ into _bitmapBuffer_.
+-// Compare the _bitmapBuffer_ with gGroundTruthImageData.
+-function testAccessing_randomTest(sourceType, source, duration) {
+-  return new Promise(function(resolve, reject) {
+-    var p  = createImageBitmap(source);
+-    p.then(
+-      function(bitmap) {
+-        bitmapFormat = "RGBA32";
+-        var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
+-
+-        var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
+-        var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
+-        var promise = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
+-        promise.then(
+-          function(bitmapPixelLayout) {
+-            // Prepare.
+-            bitmapImageData = new ImageData(bitmapBufferView, bitmap.width, bitmap.height);
+-
+-            // Test.
+-            for (var t = 0; t < 50; ++t) {
+-              var randomX = Math.floor(Math.random() * 240);
+-              var randomY = Math.floor(Math.random() * 175);
+-              isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData, randomX, randomY, duration);
+-            }
+-
+-            resolve();
+-          },
+-          function(ev) { failed(ev); reject(); });
+-      },
+-      function(ev) { failed(ev); reject(); });
+-  });
+-}
+-
+-// Create an ImageBitmap, _bitmap_, from the _source_.
+-// Read the underlying data of _bitmap_ into _bitmapBuffer_.
+-// Create another ImageBitmap, _bitmap2_, from _bitmapBuffer_.
+-// Read the underlying data of _bitmap2_ into _bitmapBuffer2_.
+-// Compare the _bitmapBuffer2_ with gGroundTruthImageData.
+-function testCreateFromArrayBffer_randomTest(sourceType, source, duration) {
+-  return new Promise(function(resolve, reject) {
+-    var p  = createImageBitmap(source);
+-    p.then(
+-      function(bitmap) {
+-        bitmapFormat = "RGBA32";
+-        var bitmapBufferLength = bitmap.mappedDataLength(bitmapFormat);
+-
+-        var bitmapBuffer = new ArrayBuffer(bitmapBufferLength);
+-        var bitmapBufferView = new Uint8ClampedArray(bitmapBuffer, 0, bitmapBufferLength);
+-        var promiseMapDataInto = bitmap.mapDataInto(bitmapFormat, bitmapBuffer, 0);
+-        promiseMapDataInto.then(
+-          function(bitmapPixelLayout) {
+-            // Create a new ImageBitmap from an ArrayBuffer.
+-            var p2 = createImageBitmap(bitmapBufferView,
+-                                       0,
+-                                       bitmapBufferLength,
+-                                       bitmapFormat,
+-                                       bitmapPixelLayout);
+-
+-            p2.then(
+-              function(bitmap2) {
+-                bitmapFormat2 = "RGBA32";
+-                var bitmapBufferLength2 = bitmap2.mappedDataLength(bitmapFormat2);
+-
+-                var bitmapBuffer2 = new ArrayBuffer(bitmapBufferLength2);
+-                var bitmapBufferView2 = new Uint8ClampedArray(bitmapBuffer2, 0, bitmapBufferLength2);
+-                var promise2 = bitmap2.mapDataInto(bitmapFormat2, bitmapBuffer2, 0);
+-                promise2.then(
+-                  function(bitmapPixelLayout2) {
+-                    // Prepare.
+-                    var bitmapImageData2 = new ImageData(bitmapBufferView2, bitmap2.width, bitmap2.height);
+-
+-                    // Test.
+-                    for (var t = 0; t < 50; ++t) {
+-                      var randomX = Math.floor(Math.random() * 240);
+-                      var randomY = Math.floor(Math.random() * 175);
+-                      isPixel(sourceType, "RGBA32", gGroundTruthImageData, bitmapImageData2, randomX, randomY, duration);
+-                    }
+-
+-                    resolve();
+-                  },
+-                  function(ev) { failed(ev); reject(); });
+-              },
+-              function(ev) { console.log("p2 rejected!"); failed(ev); reject(); });
+-          },
+-          function(ev) { console.log("promiseMapDataInto rejected!"); failed(ev); reject(); });
+-      },
+-      function(ev) { failed(ev); reject(); });
+-  });
+-}
+-
+-function testColorConversion(sourceFromat, destinationFormat, tolerance, shouldThrow) {
+-
+-  tolerance = tolerance || 0;
+-  shouldThrow = shouldThrow || false;
+-
+-  return new Promise(function(resolve, reject) {
+-    var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
+-
+-    ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
+-    ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
+-
+-    // printInfo(sourceFromat, srcData);
+-    // printInfo(destinationFormat, dstData);
+-
+-    // Create a new ImageBitmap from an ArrayBuffer.
+-    var p = createImageBitmap(srcData.buffer,
+-                              0,
+-                              srcData.bufferLength,
+-                              srcData.format,
+-                              srcData.pixelLayout);
+-
+-    p.then(
+-      function(srcBitmap) {
+-        ok(!!srcBitmap, "Should get a valid srcBitmap.");
+-        ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
+-                                                          " should equal to sourceFromat:" + sourceFromat);
+-
+-        var dstBufferLength = srcBitmap.mappedDataLength(destinationFormat);
+-        var dstBuffer = new ArrayBuffer(dstBufferLength);
+-        var dstBufferView = new dstData.ArrayType(dstBuffer, 0, dstBufferLength / dstData.ArrayType.BYTES_PER_ELEMENT);
+-
+-        // Do color conversion here.
+-        var p2 = srcBitmap.mapDataInto(destinationFormat, dstBuffer, 0);
+-        p2.then(
+-          function(dstPixelLayout) {
+-            var dataPixalLayout = dstData.pixelLayout;
+-
+-            // Check pixel layout.
+-            ok(dstPixelLayout.length == dstData.channelCount, "dstPixelLayout.length:" + dstPixelLayout.length +
+-                                                              " should equal to dstData.channelCount:" + dstData.channelCount);
+-
+-            for (var c = 0; c < dstData.channelCount; ++c) {
+-              var dstChannelLayout = dstPixelLayout[c];
+-              var dataChannelLayout = dataPixalLayout[c];
+-              ok(dstChannelLayout.width == dataChannelLayout.width, "channel[" + c + "] dstChannelLayout.width:" + dstChannelLayout.width + " should equal to dataChannelLayout.width:" + dataChannelLayout.width);
+-              ok(dstChannelLayout.height == dataChannelLayout.height, "channel[" + c + "] dstChannelLayout.height:" + dstChannelLayout.height + " should equal to dataChannelLayout.height:" + dataChannelLayout.height);
+-              ok(dstChannelLayout.skip == dataChannelLayout.skip, "channel[" + c + "] dstChannelLayout.skip:" + dstChannelLayout.skip + " should equal to dataChannelLayout.skip:" + dataChannelLayout.skip);
+-
+-              for (var i = 0; i < dstChannelLayout.height; ++i) {
+-                for (var j = 0; j < dstChannelLayout.width; ++j) {
+-                  var byteOffset = dstChannelLayout.offset + i * dstChannelLayout.stride + j * (dstChannelLayout.skip + 1) * dstData.ArrayType.BYTES_PER_ELEMENT;
+-                  var view = new dstData.ArrayType(dstBuffer, byteOffset, 1);
+-                  var dstBufferViewValue = view[0];
+-                  var dstDataValue = dstData.getPixelValue(i, j, c);
+-                  ok(Math.abs(dstBufferViewValue - dstDataValue) <= tolerance,
+-                     "[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ") channnel(" + c +
+-                     "): dstBufferViewValue:" + dstBufferViewValue +
+-                     " should equal to dstDataValue:" + dstDataValue);
+-                }
+-              }
+-            }
+-
+-            resolve();
+-          },
+-          function(ev) {
+-            // If the "mapDataInto" throws, the flow goes here.
+-            if (!shouldThrow) { failed(ev); }
+-            reject();
+-          }
+-        );
+-      },
+-      function(ev) {
+-        reject(ev);
+-      }
+-    );
+-  });
+-}
+-
+-function doOneDrawTest(sourceFromat, tolerance) {
+-  tolerance = tolerance || 0;
+-  var destinationFormat = "RGBA32";
+-
+-  return new Promise(function(resolve, reject) {
+-
+-    var [srcData, dstData] = getTestData(sourceFromat, destinationFormat);
+-    ok(!!srcData, "Get valid srcData of type:" + sourceFromat);
+-    ok(!!dstData, "Get valid dstData of type:" + destinationFormat);
+-
+-    var p = createImageBitmap(srcData.buffer,
+-                              0,
+-                              srcData.bufferLength,
+-                              srcData.format,
+-                              srcData.pixelLayout);
+-
+-    p.then(
+-      function(srcBitmap) {
+-        ok(!!srcBitmap, "Should get a valid srcBitmap.");
+-        ok(srcBitmap.findOptimalFormat() == sourceFromat, "srcBitmap.findOptimalFormat():" + srcBitmap.findOptimalFormat() +
+-                                                          " should equal to sourceFromat:" + sourceFromat);
+-
+-        var canvas = document.createElement("canvas");
+-        canvas.width = srcBitmap.width;
+-        canvas.height = srcBitmap.height;
+-        var ctx = canvas.getContext("2d");
+-
+-        ctx.drawImage(srcBitmap, 0, 0, srcBitmap.width, srcBitmap.height);
+-
+-        // Get an ImageData from the canvas.
+-        var imageData = ctx.getImageData(0, 0, srcBitmap.width, srcBitmap.height);
+-
+-        for (var i = 0; i < srcBitmap.height; ++i) {
+-          for (var j = 0; j < srcBitmap.width; ++j) {
+-            var pixelOffset = i * srcBitmap.width * dstData.channelCount + j * dstData.channelCount;
+-            var dstImageDataValue_R = imageData.data[pixelOffset + 0];
+-            var dstImageDataValue_G = imageData.data[pixelOffset + 1];
+-            var dstImageDataValue_B = imageData.data[pixelOffset + 2];
+-            var dstImageDataValue_A = imageData.data[pixelOffset + 3];
+-
+-            var logPrefix = "[" + sourceFromat + " -> " + destinationFormat + "] pixel(" + i + "," + j + ")";
+-
+-            var dstDataValue_R = dstData.getPixelValue(i, j, 0);
+-            var dstDataValue_G = dstData.getPixelValue(i, j, 1);
+-            var dstDataValue_B = dstData.getPixelValue(i, j, 2);
+-            var dstDataValue_A = dstData.getPixelValue(i, j, 3);
+-            ok(Math.abs(dstImageDataValue_R - dstDataValue_R) <= tolerance,
+-               logPrefix + "channnel(R): dstImageDataValue:" + dstImageDataValue_R + " should equal to dstDataValue_R: " + dstDataValue_R);
+-            ok(Math.abs(dstImageDataValue_G - dstDataValue_G) <= tolerance,
+-               logPrefix + "channnel(G): dstImageDataValue:" + dstImageDataValue_G + " should equal to dstDataValue_G: " + dstDataValue_G);
+-            ok(Math.abs(dstImageDataValue_B - dstDataValue_B) <= tolerance,
+-               logPrefix + "channnel(B): dstImageDataValue:" + dstImageDataValue_B + " should equal to dstDataValue_B: " + dstDataValue_B);
+-            ok(Math.abs(dstImageDataValue_A - dstDataValue_A) <= tolerance,
+-               logPrefix + "channnel(A): dstImageDataValue:" + dstImageDataValue_A + " should equal to dstDataValue_A: " + dstDataValue_A);
+-          }
+-        }
+-
+-        resolve();
+-      },
+-      function(ev) {
+-        failed(ev);
+-        reject(ev);
+-      }
+-    );
+-  });
+-}
+diff --git a/dom/canvas/test/imagebitmap_extensions_data.js b/dom/canvas/test/imagebitmap_extensions_data.js
+deleted file mode 100644
+--- a/dom/canvas/test/imagebitmap_extensions_data.js
++++ /dev/null
+@@ -1,1066 +0,0 @@
+-class Image {
+-  constructor(channelCount, format, ArrayType) {
+-    this.channelCount = channelCount;
+-    this.format = format;
+-    this.ArrayType = ArrayType;
+-    this.pixelLayout = [];
+-    this.buffer = undefined;
+-    this.data = undefined;
+-  };
+-};
+-
+-class TypedSimpleImage extends Image {
+-  constructor(width, height, channelCount, format, ArrayType) {
+-    super(channelCount, format, ArrayType);
+-    this.width = width;
+-    this.height = height;
+-    this.stride = this.width * this.channelCount * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.bufferLength = this.height * this.stride;
+-    this.buffer = new ArrayBuffer(this.bufferLength);
+-    this.data = new this.ArrayType(this.buffer, 0, this.height * this.width * this.channelCount);
+-
+-    // initialize pixel layout
+-    for (var c = 0; c < this.channelCount; ++c) {
+-      this.pixelLayout.push({offset:c * this.ArrayType.BYTES_PER_ELEMENT,
+-                             width:this.width,
+-                             height:this.height,
+-                             dataType:"uint8",
+-                             stride:this.stride,
+-                             skip:(this.channelCount - 1)});
+-    }
+-  };
+-
+-  getPixelValue(i, j, c) {
+-    var dataChannelLayout = this.pixelLayout[c];
+-    return this.data[i * this.width * this.channelCount + j * this.channelCount + c];
+-  }
+-};
+-
+-class Uint8SimpleImage extends TypedSimpleImage {
+-  constructor(width, height, channelCount, format) {
+-    super(width, height, channelCount, format, Uint8ClampedArray);
+-  };
+-};
+-
+-class Uint16SimpleImage extends TypedSimpleImage {
+-  constructor(width, height, channelCount, format) {
+-    super(width, height, channelCount, format, Uint16Array);
+-  };
+-};
+-
+-class FloatSimpleImage extends TypedSimpleImage {
+-  constructor(width, height, channelCount, format) {
+-    super(width, height, channelCount, format, Float32Array);
+-  };
+-};
+-
+-class DoubleSimpleImage extends TypedSimpleImage {
+-  constructor(width, height, channelCount, format) {
+-    super(width, height, channelCount, format, Float64Array);
+-  };
+-};
+-
+-class RGBA32Data extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 4, "RGBA32");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 0;   this.data[i + 3] = 255;
+-    this.data[i + 4] = 255; this.data[i + 5] = 0;   this.data[i + 6] = 0;   this.data[i + 7] = 255;
+-    this.data[i + 8] = 0;   this.data[i + 9] = 255; this.data[i + 10] = 0;  this.data[i + 11] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 255;  this.data[i + 3] = 255;
+-    this.data[i + 4] = 255; this.data[i + 5] = 255; this.data[i + 6] = 0;    this.data[i + 7] = 255;
+-    this.data[i + 8] = 0;   this.data[i + 9] = 255; this.data[i + 10] = 255; this.data[i + 11] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 255;  this.data[i + 1] = 0;   this.data[i + 2] = 255;  this.data[i + 3] = 255;
+-    this.data[i + 4] = 255;  this.data[i + 5] = 255; this.data[i + 6] = 255;  this.data[i + 7] = 255;
+-    this.data[i + 8] = 128;  this.data[i + 9] = 128; this.data[i + 10] = 128; this.data[i + 11] = 255;
+-  };
+-};
+-
+-class BGRA32Data extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 4, "BGRA32");
+-
+-    var i = 0;
+-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 0;   this.data[i + 3] = 255;
+-    this.data[i + 6] = 255; this.data[i + 5] = 0;   this.data[i + 4] = 0;   this.data[i + 7] = 255;
+-    this.data[i + 10] = 0;  this.data[i + 9] = 255; this.data[i + 8] = 0;   this.data[i + 11] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 255;  this.data[i + 3] = 255;
+-    this.data[i + 6] = 255; this.data[i + 5] = 255; this.data[i + 4] = 0;    this.data[i + 7] = 255;
+-    this.data[i + 10] = 0;  this.data[i + 9] = 255; this.data[i + 8] = 255;  this.data[i + 11] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 2] = 255;  this.data[i + 1] = 0;   this.data[i + 0] = 255; this.data[i + 3] = 255;
+-    this.data[i + 6] = 255;  this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 7] = 255;
+-    this.data[i + 10] = 128; this.data[i + 9] = 128; this.data[i + 8] = 128; this.data[i + 11] = 255;
+-  };
+-};
+-
+-class RGB24Data extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "RGB24");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 0;
+-    this.data[i + 3] = 255; this.data[i + 4] = 0;   this.data[i + 5] = 0;
+-    this.data[i + 6] = 0;   this.data[i + 7] = 255; this.data[i + 8] = 0;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 0;   this.data[i + 1] = 0;   this.data[i + 2] = 255;
+-    this.data[i + 3] = 255; this.data[i + 4] = 255; this.data[i + 5] = 0;
+-    this.data[i + 6] = 0;   this.data[i + 7] = 255; this.data[i + 8] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 255;  this.data[i + 1] = 0;   this.data[i + 2] = 255;
+-    this.data[i + 3] = 255;  this.data[i + 4] = 255; this.data[i + 5] = 255;
+-    this.data[i + 6] = 128;  this.data[i + 7] = 128; this.data[i + 8] = 128;
+-  };
+-};
+-
+-class BGR24Data extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "BGR24");
+-
+-    var i = 0;
+-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 0;
+-    this.data[i + 5] = 255; this.data[i + 4] = 0;   this.data[i + 3] = 0;
+-    this.data[i + 8] = 0;   this.data[i + 7] = 255; this.data[i + 6] = 0;
+-
+-    i += this.stride;
+-    this.data[i + 2] = 0;   this.data[i + 1] = 0;   this.data[i + 0] = 255;
+-    this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 3] = 0;
+-    this.data[i + 8] = 0;   this.data[i + 7] = 255; this.data[i + 6] = 255;
+-
+-    i += this.stride;
+-    this.data[i + 2] = 255; this.data[i + 1] = 0;   this.data[i + 0] = 255;
+-    this.data[i + 5] = 255; this.data[i + 4] = 255; this.data[i + 3] = 255;
+-    this.data[i + 8] = 128; this.data[i + 7] = 128; this.data[i + 6] = 128;
+-  };
+-};
+-
+-class Gray8Data extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 1, "GRAY8");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0;   this.data[i + 1] = 76;   this.data[i + 2] = 149;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 29;   this.data[i + 1] = 225;   this.data[i + 2] = 178;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 105; this.data[i + 1] = 255;   this.data[i + 2] = 127;
+-  };
+-};
+-
+-class RGBA32DataFromYUV444PData extends Uint8SimpleImage {
+-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
+-
+-    // Get the exact format.
+-    var channelCount_ = !!alphaIndex ? 4 : 3;
+-    var format_;
+-    if (redIndex == 0) {
+-      if (channelCount_ == 3) {
+-        format_ = "RGBA32";
+-      } else  {
+-        format_ = "RGB24";
+-      }
+-    } else if (redIndex == 2) {
+-      if (channelCount_ == 3) {
+-        format_ = "BGRA32";
+-      } else  {
+-        format_ = "BGR24";
+-      }
+-    } else {
+-      return undefined;
+-    }
+-
+-    // Call parent's consturctor.
+-    super(3, 3, channelCount_, format_);
+-
+-    // Calculate parameters for setting data.
+-    var rIndex = redIndex;        // 0 or 2
+-    var gIndex = 1;
+-    var bIndex = redIndex ^ 2;    // 0 or 2
+-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
+-    var shift0 = 0;
+-    var shift1 = channelCount_;
+-    var shift2 = channelCount_ * 2;
+-
+-    // Set the data.
+-    var i = 0;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 0;   this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 254; this.data[i + gIndex + shift1] = 0;   this.data[i + bIndex + shift1] = 0;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 1;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 0;   this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 251;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 253; this.data[i + gIndex + shift1] = 253; this.data[i + bIndex + shift1] = 2;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 252;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 255; this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 252;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 253; this.data[i + gIndex + shift1] = 253; this.data[i + bIndex + shift1] = 253;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
+-  };
+-};
+-
+-class RGBA32DataFromYUV422PData extends Uint8SimpleImage {
+-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
+-
+-    // Get the exact format.
+-    var channelCount_ = !!alphaIndex ? 4 : 3;
+-    var format_;
+-    if (redIndex == 0) {
+-      if (channelCount_ == 3) {
+-        format_ = "RGBA32";
+-      } else  {
+-        format_ = "RGB24";
+-      }
+-    } else if (redIndex == 2) {
+-      if (channelCount_ == 3) {
+-        format_ = "BGRA32";
+-      } else  {
+-        format_ = "BGR24";
+-      }
+-    } else {
+-      return undefined;
+-    }
+-
+-    // Call parent's consturctor.
+-    super(3, 3, channelCount_, format_);
+-
+-    // Calculate parameters for setting data.
+-    var rIndex = redIndex;        // 0 or 2
+-    var gIndex = 1;
+-    var bIndex = redIndex ^ 2;    // 0 or 2
+-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
+-    var shift0 = 0;
+-    var shift1 = channelCount_;
+-    var shift2 = channelCount_ * 2;
+-
+-    // Set the data.
+-    var i = 0;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 89;  this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 165; this.data[i + gIndex + shift1] = 38;  this.data[i + bIndex + shift1] = 38;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 1;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 28;  this.data[i + gIndex + shift0] = 28;  this.data[i + bIndex + shift0] = 28;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 224; this.data[i + gIndex + shift1] = 224; this.data[i + bIndex + shift1] = 224;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 253; this.data[i + bIndex + shift2] = 252;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 180; this.data[i + gIndex + shift0] = 52;  this.data[i + bIndex + shift0] = 178;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 200; this.data[i + bIndex + shift1] = 255;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
+-  };
+-};
+-
+-class RGBA32DataFromYUV420PData extends Uint8SimpleImage {
+-  constructor(redIndex, greenIndex, blueIndex, alphaIndex) {
+-
+-    // Get the exact format.
+-    var channelCount_ = !!alphaIndex ? 4 : 3;
+-    var format_;
+-    if (redIndex == 0) {
+-      if (channelCount_ == 3) {
+-        format_ = "RGBA32";
+-      } else  {
+-        format_ = "RGB24";
+-      }
+-    } else if (redIndex == 2) {
+-      if (channelCount_ == 3) {
+-        format_ = "BGRA32";
+-      } else  {
+-        format_ = "BGR24";
+-      }
+-    } else {
+-      return undefined;
+-    }
+-
+-    // Call parent's consturctor.
+-    super(3, 3, channelCount_, format_);
+-
+-    // Calculate parameters for setting data.
+-    var rIndex = redIndex;        // 0 or 2
+-    var gIndex = 1;
+-    var bIndex = redIndex ^ 2;    // 0 or 2
+-    var aIndex = alphaIndex || 0; // If alphaIndex == undefined --> aIndex = 0;
+-    var shift0 = 0;
+-    var shift1 = channelCount_;
+-    var shift2 = channelCount_ * 2;
+-
+-    // Set the data.
+-    var i = 0;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 44;  this.data[i + gIndex + shift0] = 0;   this.data[i + bIndex + shift0] = 0;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 120; this.data[i + gIndex + shift1] = 57;  this.data[i + bIndex + shift1] = 58;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 0;   this.data[i + gIndex + shift2] = 238; this.data[i + bIndex + shift2] = 112;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 73;  this.data[i + gIndex + shift0] = 9;   this.data[i + bIndex + shift0] = 11;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 205; this.data[i + bIndex + shift1] = 206;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 12;  this.data[i + gIndex + shift2] = 255; this.data[i + bIndex + shift2] = 141;
+-
+-    i += this.stride;
+-    this.data[i + aIndex + shift0] = 255;   this.data[i + rIndex + shift0] = 180; this.data[i + gIndex + shift0] = 52;  this.data[i + bIndex + shift0] = 178;
+-    this.data[i + aIndex + shift1] = 255;   this.data[i + rIndex + shift1] = 255; this.data[i + gIndex + shift1] = 200; this.data[i + bIndex + shift1] = 255;
+-    this.data[i + aIndex + shift2] = 255;   this.data[i + rIndex + shift2] = 127; this.data[i + gIndex + shift2] = 127; this.data[i + bIndex + shift2] = 127;
+-  };
+-};
+-
+-class Gray8DataFromYUVData extends Uint8SimpleImage {
+-  constructor() {
+-    super(3, 3, 1, "GRAY8");
+-
+-    var i = 0;
+-    this.data[i + 0] = 16;  this.data[i + 1] = 82;   this.data[i + 2] = 144;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 41;  this.data[i + 1] = 210;  this.data[i + 2] = 169;
+-
+-    i += this.stride;
+-    this.data[i + 0] = 107; this.data[i + 1] = 235;  this.data[i + 2] = 126;
+-  };
+-};
+-
+-class YUVImage extends Image {
+-  constructor(yWidth, yHeight, uWidth, uHeight, vWidth, vHeight, format) {
+-    super(3, format, Uint8ClampedArray);
+-    this.yWidth = yWidth;
+-    this.yHeight = yHeight;
+-    this.yStride = this.yWidth * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.uWidth = uWidth;
+-    this.uHeight = uHeight;
+-    this.uStride = this.uWidth * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.vWidth = vWidth;
+-    this.vHeight = vHeight;
+-    this.vStride = this.vWidth * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.bufferLength = this.yHeight * this.yStride +
+-                        this.uHeight * this.uStride +
+-                        this.vHeight * this.vStride
+-    this.buffer = new ArrayBuffer(this.bufferLength);
+-    this.data = new this.ArrayType(this.buffer, 0, this.bufferLength);
+-    this.yData = new this.ArrayType(this.buffer, 0, this.yHeight * this.yStride);
+-    this.uData = new this.ArrayType(this.buffer,
+-                                    this.yHeight * this.yStride,
+-                                    this.uHeight * this.uStride);
+-    this.vData = new this.ArrayType(this.buffer,
+-                                    this.yHeight * this.yStride + this.uHeight * this.uStride,
+-                                    this.vHeight * this.vStride);
+-
+-    // Initialize pixel layout.
+-    // y channel.
+-    this.pixelLayout.push({offset:0,
+-                           width:this.yWidth,
+-                           height:this.yHeight,
+-                           dataType:"uint8",
+-                           stride:this.yStride,
+-                           skip:0});
+-
+-    // u channel.
+-    this.pixelLayout.push({offset:(this.yHeight * this.yStride),
+-                           width:this.uWidth,
+-                           height:this.uHeight,
+-                           dataType:"uint8",
+-                           stride:this.uStride,
+-                           skip:0});
+-
+-    // v channel.
+-    this.pixelLayout.push({offset:(this.yHeight * this.yStride + this.uHeight * this.uStride),
+-                           width:this.vWidth,
+-                           height:this.vHeight,
+-                           dataType:"uint8",
+-                           stride:this.vStride,
+-                           skip:0});
+-  };
+-
+-  getPixelValue(i, j, c) {
+-    var dataChannelLayout = this.pixelLayout[c];
+-    return this.data[dataChannelLayout.offset + i * dataChannelLayout.stride + j * (dataChannelLayout.skip + 1)];
+-  }
+-};
+-
+-class YUV444PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 3, 3, 3, 3, "YUV444P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 128; this.uData[1] = 90;  this.uData[2] = 54;
+-    this.uData[3] = 240; this.uData[4] = 16;  this.uData[5] = 166;
+-    this.uData[6] = 202; this.uData[7] = 128; this.uData[8] = 128;
+-
+-    this.vData[0] = 128; this.vData[1] = 240; this.vData[2] = 34;
+-    this.vData[3] = 110; this.vData[4] = 146; this.vData[5] = 16;
+-    this.vData[6] = 222; this.vData[7] = 128; this.vData[8] = 128;
+-  }
+-};
+-
+-class YUV444PDataFromYUV422PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 3, 3, 3, 3, "YUV444P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 108; this.uData[1] = 81;  this.uData[2] = 53;
+-    this.uData[3] = 126; this.uData[4] = 112; this.uData[5] = 98;
+-    this.uData[6] = 144; this.uData[7] = 144; this.uData[8] = 144;
+-
+-    this.vData[0] = 182; this.vData[1] = 108; this.vData[2] = 33;
+-    this.vData[3] = 166; this.vData[4] = 109; this.vData[5] = 51;
+-    this.vData[6] = 150; this.vData[7] = 110; this.vData[8] = 70;
+-  }
+-};
+-
+-class YUV444PDataFromYUV420PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 3, 3, 3, 3, "YUV444P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 118; this.uData[1] = 113; this.uData[2] = 109;
+-    this.uData[3] = 140; this.uData[4] = 128; this.uData[5] = 117;
+-    this.uData[6] = 162; this.uData[7] = 144; this.uData[8] = 126;
+-
+-    this.vData[0] = 154; this.vData[1] = 90;  this.vData[2] = 24;
+-    this.vData[3] = 163; this.vData[4] = 119; this.vData[5] = 75;
+-    this.vData[6] = 172; this.vData[7] = 149; this.vData[8] = 126;
+-  }
+-};
+-
+-class YUV422PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 3, 2, 3, "YUV422P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 109; this.uData[1] = 54;
+-    this.uData[2] = 128; this.uData[3] = 166;
+-    this.uData[4] = 165; this.uData[5] = 128;
+-
+-    this.vData[0] = 184; this.vData[1] = 34;
+-    this.vData[2] = 128; this.vData[3] = 16;
+-    this.vData[4] = 175; this.vData[5] = 128;
+-  }
+-};
+-
+-class YUV422PDataFromYUV444PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 3, 2, 3, "YUV422P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 133; this.uData[1] = 78;
+-    this.uData[2] = 164; this.uData[3] = 109;
+-    this.uData[4] = 180; this.uData[5] = 125;
+-
+-    this.vData[0] = 145; this.vData[1] = 74;
+-    this.vData[2] = 165; this.vData[3] = 95;
+-    this.vData[4] = 175; this.vData[5] = 105;
+-  }
+-};
+-
+-class YUV422PDataFromYUV420PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 3, 2, 3, "YUV422P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 119; this.uData[1] = 110;
+-    this.uData[2] = 149; this.uData[3] = 121;
+-    this.uData[4] = 164; this.uData[5] = 127;
+-
+-    this.vData[0] = 156; this.vData[1] = 25;
+-    this.vData[2] = 168; this.vData[3] = 93;
+-    this.vData[4] = 174; this.vData[5] = 127;
+-  }
+-};
+-
+-class YUV420PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, 2, 2, "YUV420P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 119; this.uData[1] = 110;
+-    this.uData[2] = 165; this.uData[3] = 128;
+-
+-    this.vData[0] = 156; this.vData[1] = 25;
+-    this.vData[2] = 175; this.vData[3] = 128;
+-  }
+-};
+-
+-class YUV420PDataFromYUV444PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, 2, 2, "YUV420P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 133; this.uData[1] = 78;
+-    this.uData[2] = 181; this.uData[3] = 126;
+-
+-    this.vData[0] = 145; this.vData[1] = 74;
+-    this.vData[2] = 176; this.vData[3] = 106;
+-  }
+-};
+-
+-class YUV420PDataFromYUV422PData extends YUVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, 2, 2, "YUV420P");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    this.uData[0] = 109; this.uData[1] = 54;
+-    this.uData[2] = 147; this.uData[3] = 147;
+-
+-    this.vData[0] = 184; this.vData[1] = 34;
+-    this.vData[2] = 152; this.vData[3] = 72;
+-  }
+-};
+-
+-class NVImage extends Image {
+-  constructor(yWidth, yHeight, uvWidth, uvHeight, format) {
+-    super(3, format, Uint8ClampedArray);
+-    this.yWidth = yWidth;
+-    this.yHeight = yHeight;
+-    this.yStride = this.yWidth * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.uvWidth = uvWidth;
+-    this.uvHeight = uvHeight;
+-    this.uvStride = this.uvWidth * 2 * this.ArrayType.BYTES_PER_ELEMENT;
+-    this.bufferLength = this.yHeight * this.yStride + this.uvHeight * this.uvStride;
+-    this.buffer = new ArrayBuffer(this.bufferLength);
+-    this.data = new this.ArrayType(this.buffer, 0, this.bufferLength);
+-    this.yData = new this.ArrayType(this.buffer, 0, this.yHeight * this.yStride);
+-    this.uvData = new this.ArrayType(this.buffer,
+-                                     this.yHeight * this.yStride,
+-                                     this.uvHeight * this.uvStride);
+-
+-    // Initialize pixel layout.
+-    // y channel.
+-    this.pixelLayout.push({offset:0,
+-                           width:this.yWidth,
+-                           height:this.yHeight,
+-                           dataType:"uint8",
+-                           stride:this.yStride,
+-                           skip:0});
+-    // v channel.
+-    this.pixelLayout.push({offset:(this.yHeight * this.yStride),
+-                           width:this.uvWidth,
+-                           height:this.uvHeight,
+-                           dataType:"uint8",
+-                           stride:this.uvStride,
+-                           skip:1});
+-
+-    // u channel.
+-    this.pixelLayout.push({offset:(this.yHeight * this.yStride + this.ArrayType.BYTES_PER_ELEMENT),
+-                           width:this.uvWidth,
+-                           height:this.uvHeight,
+-                           dataType:"uint8",
+-                           stride:this.uvStride,
+-                           skip:1});
+-  };
+-
+-  getPixelValue(i, j, c) {
+-    var dataChannelLayout = this.pixelLayout[c];
+-    return this.data[dataChannelLayout.offset + i * dataChannelLayout.stride + j * (dataChannelLayout.skip + 1)];
+-  }
+-};
+-
+-class NV12Data extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV12");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // U
+-    this.uvData[0] = 119;
+-    this.uvData[2] = 110;
+-    this.uvData[4] = 165;
+-    this.uvData[6] = 128;
+-
+-    // V
+-    this.uvData[1] = 156;
+-    this.uvData[3] = 25;
+-    this.uvData[5] = 175;
+-    this.uvData[7] = 128;
+-  };
+-};
+-
+-class NV12DataFromYUV444PData extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV12");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // U
+-    this.uvData[0] = 133;
+-    this.uvData[2] = 78;
+-    this.uvData[4] = 181;
+-    this.uvData[6] = 126;
+-
+-    // V
+-    this.uvData[1] = 145;
+-    this.uvData[3] = 74;
+-    this.uvData[5] = 176;
+-    this.uvData[7] = 106;
+-  };
+-};
+-
+-class NV12DataFromYUV422PData extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV12");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // U
+-    this.uvData[0] = 109;
+-    this.uvData[2] = 54;
+-    this.uvData[4] = 147;
+-    this.uvData[6] = 147;
+-
+-    // V
+-    this.uvData[1] = 184;
+-    this.uvData[3] = 34;
+-    this.uvData[5] = 152;
+-    this.uvData[7] = 72;
+-  };
+-};
+-
+-class NV21Data extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV21");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // U
+-    this.uvData[1] = 119;
+-    this.uvData[3] = 110;
+-    this.uvData[5] = 165;
+-    this.uvData[7] = 128;
+-
+-    // V
+-    this.uvData[0] = 156;
+-    this.uvData[2] = 25;
+-    this.uvData[4] = 175;
+-    this.uvData[6] = 128;
+-  };
+-};
+-
+-class NV21DataFromYUV444PData extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV12");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // V
+-    this.uvData[1] = 133;
+-    this.uvData[3] = 78;
+-    this.uvData[5] = 181;
+-    this.uvData[7] = 126;
+-
+-    // U
+-    this.uvData[0] = 145;
+-    this.uvData[2] = 74;
+-    this.uvData[4] = 176;
+-    this.uvData[6] = 106;
+-  };
+-};
+-
+-class NV21DataFromYUV422PData extends NVImage {
+-  constructor() {
+-    super(3, 3, 2, 2, "YUV420SP_NV12");
+-
+-    this.yData[0] = 16;  this.yData[1] = 82;  this.yData[2] = 144;
+-    this.yData[3] = 41;  this.yData[4] = 210; this.yData[5] = 169;
+-    this.yData[6] = 107; this.yData[7] = 235; this.yData[8] = 126;
+-
+-    // V
+-    this.uvData[1] = 109;
+-    this.uvData[3] = 54;
+-    this.uvData[5] = 147;
+-    this.uvData[7] = 147;
+-
+-    // U
+-    this.uvData[0] = 184;
+-    this.uvData[2] = 34;
+-    this.uvData[4] = 152;
+-    this.uvData[6] = 72;
+-  };
+-};
+-
+-class HSVData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;   this.data[i + 1] = 0.0; this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 0.0;   this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 120.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 240.0; this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
+-    this.data[i + 3] = 60.0;  this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 180.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 300.0; this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
+-    this.data[i + 3] = 0.0;   this.data[i + 4] = 0.0; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 0.0;   this.data[i + 7] = 0.0; this.data[i + 8] = 0.50196081;
+-  };
+-};
+-
+-class HSVDataFromLabData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;   this.data[i + 1] = 0.0; this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 0.0;   this.data[i + 4] = 1.0; this.data[i + 5] = 0.996078;
+-    this.data[i + 6] = 120.0; this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 240.0;       this.data[i + 1] = 1.0; this.data[i + 2] = 1.0;
+-    this.data[i + 3] = 60.235294;   this.data[i + 4] = 1.0; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 179.764706;  this.data[i + 7] = 1.0; this.data[i + 8] = 1.0;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 300.0;       this.data[i + 1] = 1.0;       this.data[i + 2] = 1.0;
+-    this.data[i + 3] = 0.0;         this.data[i + 4] = 0.003922;  this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 59.999998;   this.data[i + 7] = 0.007813;  this.data[i + 8] = 0.501961;
+-  };
+-};
+-
+-class HSVDataFromYUV444PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 1.0000000001003937;  this.data[i + 5] = 0.996078431372549;
+-    this.data[i + 6] = 120.23715415017372;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 240.0;               this.data[i + 1] = 1.0000000001015936;  this.data[i + 2] = 0.984313725490196;
+-    this.data[i + 3] = 59.99999999390438;   this.data[i + 4] = 0.9920948617608696;  this.data[i + 5] = 0.9921568627450981;
+-    this.data[i + 6] = 179.76284584377885;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 300.7058823588706;   this.data[i + 1] = 1.0000000001;        this.data[i + 2] = 1.0;
+-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.9921568627450981;
+-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
+-  };
+-};
+-
+-class HSVDataFromYUV422PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 1.0000000002865168; this.data[i + 2] = 0.34901960784313724;
+-    this.data[i + 3] = 0.0;                 this.data[i + 4] = 0.7696969698515151; this.data[i + 5] = 0.6470588235294118;
+-    this.data[i + 6] = 120.23715415017372;  this.data[i + 7] = 1.0000000001007905; this.data[i + 8] = 0.9921568627450981;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 0;                   this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.10980392156862745;
+-    this.data[i + 3] = 0;                   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.8784313725490196;
+-    this.data[i + 6] = 179.76284584377885;  this.data[i + 7] = 1.0000000001007905;  this.data[i + 8] = 0.9921568627450981;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 300.93750001176636;  this.data[i + 1] = 0.7111111112527777;  this.data[i + 2] = 0.7058823529411765;
+-    this.data[i + 3] = 300.0000000278182;   this.data[i + 4] = 0.21568627460980394; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
+-  };
+-};
+-
+-class HSVDataFromYUV420PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 1.0000000005795455;  this.data[i + 2] = 0.17254901960784313;
+-    this.data[i + 3] = 359.04761904800455;  this.data[i + 4] = 0.5250000002125;     this.data[i + 5] = 0.47058823529411764;
+-    this.data[i + 6] = 148.23529411462184;  this.data[i + 7] = 1.000000000107143;   this.data[i + 8] = 0.9333333333333333;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 358.1250000007471;   this.data[i + 1] = 0.8767123291164385;  this.data[i + 2] = 0.28627450980392155;
+-    this.data[i + 3] = 358.800000000612;    this.data[i + 4] = 0.196078431472549;   this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 151.85185184850937;  this.data[i + 7] = 0.9529411765705882;  this.data[i + 8] = 1.0;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 300.93750001176636;  this.data[i + 1] = 0.7111111112527777;  this.data[i + 2] = 0.7058823529411765;
+-    this.data[i + 3] = 300.0000000278182;   this.data[i + 4] = 0.21568627460980394; this.data[i + 5] = 1.0;
+-    this.data[i + 6] = 0.0;                 this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.4980392156862745;
+-  };
+-};
+-
+-class LabData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "Lab");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;       this.data[i + 1] = 0.0;         this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 53.240585; this.data[i + 4] = 80.094185;   this.data[i + 5] = 67.201538;
+-    this.data[i + 6] = 87.7351;   this.data[i + 7] = -86.181252;  this.data[i + 8] = 83.177483;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 32.29567;  this.data[i + 1] = 79.186989;   this.data[i + 2] = -107.86176;
+-    this.data[i + 3] = 97.139511; this.data[i + 4] = -21.552414;  this.data[i + 5] = 94.475792;
+-    this.data[i + 6] = 91.113297; this.data[i + 7] = -48.088551;  this.data[i + 8] = -14.130962;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 60.323502; this.data[i + 1] = 98.235161;   this.data[i + 2] = -60.825493;
+-    this.data[i + 3] = 100.0;     this.data[i + 4] = 0.0;         this.data[i + 5] = 0.0;
+-    this.data[i + 6] = 53.585014; this.data[i + 7] = 0.0;         this.data[i + 8] = 0.0;
+-  };
+-};
+-
+-class LabDataFromYUV444PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 0.0;                 this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 53.034610465388056;  this.data[i + 4] = 79.85590203914461;   this.data[i + 5] = 67.0016253024788;
+-    this.data[i + 6] = 87.11875689267448;   this.data[i + 7] = -85.65429374039535;  this.data[i + 8] = 82.60623202041464;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 31.720345672804157;  this.data[i + 1] = 78.24367895044873;   this.data[i + 2] = -106.5768337072531;
+-    this.data[i + 3] = 96.46792120648958;   this.data[i + 4] = -21.409519847697347; this.data[i + 5] = 93.77548135780542;
+-    this.data[i + 6] = 90.44660871821826;   this.data[i + 7] = -48.089026724461526; this.data[i + 8] = -13.571034820412686;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 60.151950936932494;  this.data[i + 1] = 97.82071254270292;   this.data[i + 2] = -59.43734830934828;
+-    this.data[i + 3] = 99.30958687208283;   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.0;
+-    this.data[i + 6] = 53.19277745493915;   this.data[i + 7] = 0.0;                 this.data[i + 8] = 0.0;
+-  };
+-};
+-
+-class LabDataFromYUV422PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 16.127781199491146; this.data[i + 1] = 37.16386506574049;  this.data[i + 2] = 25.043689417354877;
+-    this.data[i + 3] = 36.981683077525915; this.data[i + 4] = 50.903511613481115; this.data[i + 5] = 32.31142038484883;
+-    this.data[i + 6] = 87.11875689267448;  this.data[i + 7] = -85.65429374039535; this.data[i + 8] = 82.60623202041464;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 10.268184311230112; this.data[i + 1] = 0.0;                 this.data[i + 2] = 0.0;
+-    this.data[i + 3] = 89.1772802290269;   this.data[i + 4] = 0.0;                 this.data[i + 5] = 0.0;
+-    this.data[i + 6] = 90.44660871821826;  this.data[i + 7] = -48.089026724461526; this.data[i + 8] = -13.571034820412686;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 46.144074613608296; this.data[i + 1] = 65.16894552944552;  this.data[i + 2] = -40.267933584999625;
+-    this.data[i + 3] = 86.8938834807636;   this.data[i + 4] = 28.462923575986455; this.data[i + 5] = -19.464966592414633;
+-    this.data[i + 6] = 53.19277745493915;  this.data[i + 7] = 0.0;                this.data[i + 8] = 0.0;
+-  };
+-};
+-
+-class LabDataFromYUV420PData extends FloatSimpleImage {
+-  constructor() {
+-    super(3, 3, 3, "HSV");
+-
+-    var i = 0;
+-    this.data[i + 0] = 4.838519820745088;  this.data[i + 1] = 21.141105340568455; this.data[i + 2] = 7.645700032099379;
+-    this.data[i + 3] = 32.31563239702677;  this.data[i + 4] = 27.57546933915833;  this.data[i + 5] = 12.300896526188554;
+-    this.data[i + 6] = 83.08065258991849;  this.data[i + 7] = -73.895752859582;   this.data[i + 8] = 47.405921341516176;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 13.450503010545155; this.data[i + 1] = 29.406984528513203;  this.data[i + 2] = 16.333350166067607;
+-    this.data[i + 3] = 86.69267491397105;  this.data[i + 4] = 17.77388194061319;   this.data[i + 5] = 6.21670853560361;
+-    this.data[i + 6] = 88.693447032887;    this.data[i + 7] = -74.34828426368617;  this.data[i + 8] = 40.64106565615555;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 46.144074613608296; this.data[i + 1] = 65.16894552944552;  this.data[i + 2] = -40.267933584999625;
+-    this.data[i + 3] = 86.8938834807636;   this.data[i + 4] = 28.462923575986455; this.data[i + 5] = -19.464966592414633;
+-    this.data[i + 6] = 53.19277745493915;  this.data[i + 7] = 0.0;                this.data[i + 8] = 0.0;
+-  };
+-};
+-
+-class DepthData extends Uint16SimpleImage {
+-  constructor() {
+-    super(3, 3, 1, "DEPTH");
+-
+-    var i = 0;
+-    this.data[i + 0] = 2;   this.data[i + 1] = 4;   this.data[i + 2] = 8;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 16;  this.data[i + 1] = 32;  this.data[i + 2] = 64;
+-
+-    i += this.width * this.channelCount;
+-    this.data[i + 0] = 128; this.data[i + 1] = 256; this.data[i + 2] = 512;
+-  };
+-};
+-
+-function getData(format, originalFormat) {
+-  if (format == "RGBA32") {
+-    if (originalFormat == "YUV444P") {
+-      return new RGBA32DataFromYUV444PData(0, 1, 2, 3);
+-    } else if (originalFormat == "YUV422P") {
+-      return new RGBA32DataFromYUV422PData(0, 1, 2, 3);
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new RGBA32DataFromYUV420PData(0, 1, 2, 3);
+-    } else {
+-      return new RGBA32Data();
+-    }
+-  } else if (format == "BGRA32") {
+-    if (originalFormat == "YUV444P") {
+-      return new RGBA32DataFromYUV444PData(2, 1, 0, 3);
+-    } else if (originalFormat == "YUV422P") {
+-      return new RGBA32DataFromYUV422PData(2, 1, 0, 3);
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new RGBA32DataFromYUV420PData(2, 1, 0, 3);
+-    } else {
+-      return new BGRA32Data();
+-    }
+-  } else if (format == "RGB24") {
+-    if (originalFormat == "YUV444P") {
+-      return new RGBA32DataFromYUV444PData(0, 1, 2);
+-    } else if (originalFormat == "YUV422P") {
+-      return new RGBA32DataFromYUV422PData(0, 1, 2);
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new RGBA32DataFromYUV420PData(0, 1, 2);
+-    } else {
+-      return new RGB24Data();
+-    }
+-  } else if (format == "BGR24") {
+-    if (originalFormat == "YUV444P") {
+-      return new RGBA32DataFromYUV444PData(2, 1, 0);
+-    } else if (originalFormat == "YUV422P") {
+-      return new RGBA32DataFromYUV422PData(2, 1, 0);
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new RGBA32DataFromYUV420PData(2, 1, 0);
+-    } else {
+-      return new BGR24Data();
+-    }
+-  } else if (format == "GRAY8") {
+-    if (originalFormat == "YUV444P" ||
+-        originalFormat == "YUV422P" ||
+-        originalFormat == "YUV420P" ||
+-        originalFormat == "YUV420SP_NV12" ||
+-        originalFormat == "YUV420SP_NV21") {
+-      return  new Gray8DataFromYUVData();
+-    } else {
+-      return new Gray8Data();
+-    }
+-  } else if (format == "YUV444P") {
+-    if (originalFormat == "YUV422P") {
+-      return new YUV444PDataFromYUV422PData();
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new YUV444PDataFromYUV420PData();
+-    } else {
+-      return new YUV444PData();
+-    }
+-  } else if (format == "YUV422P") {
+-    if (originalFormat == "YUV444P") {
+-      return new YUV422PDataFromYUV444PData();
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new YUV422PDataFromYUV420PData();
+-    } else {
+-      return new YUV422PData();
+-    }
+-  } else if (format == "YUV420P") {
+-    if (originalFormat == "YUV444P") {
+-      return new YUV420PDataFromYUV444PData();
+-    } else if (originalFormat == "YUV422P") {
+-      return new YUV420PDataFromYUV422PData();
+-    } else {
+-      return new YUV420PData();
+-    }
+-  } else if (format == "YUV420SP_NV12") {
+-    if (originalFormat == "YUV444P") {
+-      return new NV12DataFromYUV444PData();
+-    } else if (originalFormat == "YUV422P") {
+-      return new NV12DataFromYUV422PData();
+-    } else {
+-      return new NV12Data();
+-    }
+-  } else if (format == "YUV420SP_NV21") {
+-    if (originalFormat == "YUV444P") {
+-      return new NV21DataFromYUV444PData();
+-    } else if (originalFormat == "YUV422P") {
+-      return new NV21DataFromYUV422PData();
+-    } else {
+-      return new NV21Data();
+-    }
+-  } else if (format == "HSV") {
+-    if (originalFormat == "YUV444P") {
+-      return new HSVDataFromYUV444PData();
+-    } else if (originalFormat == "YUV422P") {
+-      return new HSVDataFromYUV422PData();
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new HSVDataFromYUV420PData();
+-    } else if (originalFormat == "Lab") {
+-      return new HSVDataFromLabData();
+-    } else {
+-      return new HSVData();
+-    }
+-  } else if (format == "Lab") {
+-    if (originalFormat == "YUV444P") {
+-      return new LabDataFromYUV444PData();
+-    } else if (originalFormat == "YUV422P") {
+-      return new LabDataFromYUV422PData();
+-    } else if (originalFormat == "YUV420P" ||
+-               originalFormat == "YUV420SP_NV12" ||
+-               originalFormat == "YUV420SP_NV21") {
+-      return new LabDataFromYUV420PData();
+-    } else {
+-      return new LabData();
+-    }
+-  } else if (format == "DEPTH") {
+-    return new DepthData();
+-  }
+-}
+-
+-function getTestData(sourceFromat, destinationFormat) {
+-  return [getData(sourceFromat), getData(destinationFormat, sourceFromat)];
+-}
+\ No newline at end of file
+diff --git a/dom/canvas/test/imagebitmap_extensions_on_worker.js b/dom/canvas/test/imagebitmap_extensions_on_worker.js
+deleted file mode 100644
+--- a/dom/canvas/test/imagebitmap_extensions_on_worker.js
++++ /dev/null
+@@ -1,47 +0,0 @@
+-importScripts("imagebitmap_extensions_data.js");
+-importScripts("imagebitmap_extensions.js");
+-
+-var gGroundTruthImageData;
+-var gImageData;
+-var gImageBitmap;
+-var gPNGBlob;
+-var gJPEGBlob;
+-
+-onmessage = function(event) {
+-  if (event.data.type == "setSources") {
+-    gGroundTruthImageData = event.data.groundTruthImageData;
+-    gImageData = event.data.imageData;
+-    gImageBitmap = event.data.imageBitmap;
+-    gPNGBlob = event.data.pngBlob;
+-    gJPEGBlob = event.data.jpegBlob;
+-
+-    ok(!!gGroundTruthImageData, "Get gGroundTruthImageData!");
+-    ok(!!gImageData, "Get gImageData!");
+-    ok(!!gImageBitmap, "Get gImageBitmap!");
+-    ok(!!gPNGBlob, "Get gPNGBlob!");
+-    ok(!!gJPEGBlob, "Get gJPEGBlob!");
+-
+-    runTests();
+-  }
+-};
+-
+-function ok(expect, msg) {
+-  postMessage({"type": "status", status: !!expect, msg: msg});
+-}
+-
+-function runTests() {
+-  testExceptions().
+-  then(testColorConversions()).
+-  then( function() { return Promise.all([testAccessing_randomTest("ImageData", gImageData, 0),
+-                                         testAccessing_randomTest("ImageBitmap", gImageBitmap, 0),
+-                                         testAccessing_randomTest("PNG", gPNGBlob, 0),
+-                                         testAccessing_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
+-                                        ]); }).
+-  then( function() { return Promise.all([testCreateFromArrayBffer_randomTest("ImageData", gImageData, 0),
+-                                         testCreateFromArrayBffer_randomTest("ImageBitmap", gImageBitmap, 0),
+-                                         testCreateFromArrayBffer_randomTest("PNG", gPNGBlob, 0),
+-                                         testCreateFromArrayBffer_randomTest("JPEG", gJPEGBlob, 10) // JPEG loses information
+-                                        ]); }).
+-  then(function() { return testInvalidAccess([gImageData, gImageBitmap, gPNGBlob, gJPEGBlob]); } ).
+-  then(function() {postMessage({"type": "finish"});}, function(ev) { failed(ev); postMessage({"type": "finish"}); });
+-}
+\ No newline at end of file
+diff --git a/dom/canvas/test/imagebitmap_extensions_prepareSources.js b/dom/canvas/test/imagebitmap_extensions_prepareSources.js
+deleted file mode 100644
+--- a/dom/canvas/test/imagebitmap_extensions_prepareSources.js
++++ /dev/null
+@@ -1,94 +0,0 @@
+-var gImage;
+-var gVideo;
+-var gCanvas;
+-var gCtx;
+-var gImageData;
+-var gImageBitmap;
+-var gPNGBlob;
+-var gJPEGBlob;
+-
+-var gGroundTruthImageData;
+-
+-function prepareSources() {
+-  gVideo = document.createElement("video");
+-  gVideo.src = "http://example.com/tests/dom/canvas/test/crossorigin/video.sjs?name=tests/dom/canvas/test/320x240.ogv&type=video/ogg&cors=anonymous";
+-  gVideo.crossOrigin = "anonymous";
+-  gVideo.autoplay = "true"
+-
+-
+-  gCanvas = document.createElement("canvas");
+-  gCtx = gCanvas.getContext("2d");
+-
+-  var resolver;
+-  var promise = new Promise(function(resolve, reject) {
+-    resolver = resolve;
+-  });
+-
+-  // Prepare video.
+-  gVideo.onloadeddata = function() {
+-    ok(gVideo, "[Prepare Sources] gVideo is ok.");
+-
+-    // Prepare canvas.
+-    gCanvas.width = gVideo.videoWidth;
+-    gCanvas.height = gVideo.videoHeight;
+-    gCtx.drawImage(gVideo, 0, 0);
+-    ok(gCanvas, "[Prepare Sources] gCanvas is ok.");
+-    ok(gCtx, "[Prepare Sources] gCtx is ok.");
+-
+-    // Prepare gGroundTruthImageData.
+-    gGroundTruthImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
+-    ok(gGroundTruthImageData, "[Prepare Sources] gGroundTruthImageData is ok.");
+-
+-    // Prepare image.
+-    gImage = document.createElement("img");
+-    gImage.src = gCanvas.toDataURL();
+-    var resolverImage;
+-    var promiseImage = new Promise(function(resolve, reject) {
+-      resolverImage = resolve;
+-    });
+-    gImage.onload = function() {
+-      resolverImage(true);
+-    }
+-
+-    // Prepare ImageData.
+-    gImageData = gCtx.getImageData(0, 0, gCanvas.width, gCanvas.height);
+-    ok(gImageData, "[Prepare Sources] gImageData is ok.");
+-
+-    // Prepapre PNG Blob.
+-    var promisePNGBlob = new Promise(function(resolve, reject) {
+-      gCanvas.toBlob(function(blob) {
+-        gPNGBlob = blob;
+-        ok(gPNGBlob, "[Prepare Sources] gPNGBlob is ok.");
+-        resolve(true);
+-      });
+-    });
+-
+-    // Prepare JPEG Blob.
+-    var promiseJPEGBlob = new Promise(function(resolve, reject) {
+-      gCanvas.toBlob(function(blob) {
+-        gJPEGBlob = blob;
+-        ok(gJPEGBlob, "[Prepare Sources] gJPEGBlob is ok.");
+-        resolve(true);
+-      }, "image/jpeg", 1.00);
+-    });
+-
+-    // Prepare ImageBitmap.
+-    var promiseImageBitmap = new Promise(function(resolve, reject) {
+-      var p = createImageBitmap(gCanvas);
+-      p.then(function(bitmap) {
+-        gImageBitmap = bitmap;
+-        ok(gImageBitmap, "[Prepare Sources] gImageBitmap is ok.");
+-        resolve(true);
+-      });
+-    });
+-
+-    resolver(Promise.all([
+-      promiseImage,
+-      promisePNGBlob,
+-      promiseJPEGBlob,
+-      promiseImageBitmap
+-    ]))
+-  }
+-
+-  return promise;
+-}
+\ No newline at end of file
+diff --git a/dom/canvas/test/mochitest.ini b/dom/canvas/test/mochitest.ini
+--- a/dom/canvas/test/mochitest.ini
++++ b/dom/canvas/test/mochitest.ini
+@@ -21,21 +21,16 @@ support-files =
+   image_rgrg-256x256.png
+   image_rrgg-256x256.png
+   image_transparent.png
+   image_transparent50.png
+   image_yellow.png
+   image_yellow75.png
+   imagebitmap_bug1239300.js
+   imagebitmap_bug1239752.js
+-  imagebitmap_extensions.html
+-  imagebitmap_extensions.js
+-  imagebitmap_extensions_data.js
+-  imagebitmap_extensions_on_worker.js
+-  imagebitmap_extensions_prepareSources.js
+   imagebitmap_on_worker.js
+   imagebitmap_structuredclone.js
+   imagebitmap_structuredclone_iframe.html
+   imagebitmap_structuredclone_utils.js
+   offscreencanvas.js
+   offscreencanvas_mask.svg
+   offscreencanvas_neuter.js
+   offscreencanvas_serviceworker_inner.html
+@@ -233,25 +228,16 @@ support-files = file_drawWindow_source.h
+ [test_imagebitmap.html]
+ skip-if = android_version == '17' || android_version == '19' # bug 1336581
+ tags = imagebitmap
+ [test_imagebitmap_close.html]
+ tags = imagebitmap
+ [test_imagebitmap_cropping.html]
+ skip-if = android_version >= '17' # bug 1336581
+ tags = imagebitmap
+-[test_imagebitmap_extensions.html]
+-skip-if = android_version >= '17' # bug 1336581
+-tags = imagebitmap
+-[test_imagebitmap_extensions_on_worker.html]
+-skip-if = android_version == '19' # bug 1338256
+-tags = imagebitmap
+-[test_imagebitmap_on_worker.html]
+-skip-if = android_version >= '17' # bug 1336581
+-tags = imagebitmap
+ [test_imagebitmap_structuredclone.html]
+ tags = imagebitmap
+ [test_imagebitmap_structuredclone_iframe.html]
+ tags = imagebitmap
+ [test_imagebitmap_structuredclone_window.html]
+ tags = imagebitmap
+ [test_imagebitmap_transfer.html]
+ tags = imagebitmap
+diff --git a/dom/canvas/test/test_imagebitmap_extensions.html b/dom/canvas/test/test_imagebitmap_extensions.html
+deleted file mode 100644
+--- a/dom/canvas/test/test_imagebitmap_extensions.html
++++ /dev/null
+@@ -1,37 +0,0 @@
+-<!DOCTYPE HTML>
+-<heand>
+-  <title>Test ImageBitmap Extensions (Bug 1141979)</title>
+-  <meta charset="utf-8">
+-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+-</head>
+-<body>
+-  <div id="content"><div>
+-  <script type="text/javascript">
+-    SimpleTest.waitForExplicitFinish();
+-
+-    // The createImageBitmap() method is part of Window whose
+-    // prototype was created before the preference is set. So I create another
+-    // iframe with the right preference setting so that the
+-    // createImageBitmap() will be visible.
+-    SpecialPowers.pushPrefEnv({'set': [
+-      ['canvas.imagebitmap_extensions.enabled', true],
+-      ['gfx.ycbcr.accurate-conversion', true]
+-    ]}, function() {
+-      var div = document.getElementById("content");
+-      ok(div, "Parent exists");
+-
+-      var ifr = document.createElement("iframe");
+-      ifr.setAttribute('src', "imagebitmap_extensions.html");
+-      div.appendChild(ifr);
+-    });
+-
+-    window.onmessage = function(event) {
+-      if (event.data.type == "status") {
+-        ok(event.data.status, event.data.msg);
+-      } else if (event.data.type == "finish") {
+-        SimpleTest.finish();
+-      }
+-    }
+-  </script>
+-</body>
+diff --git a/dom/canvas/test/test_imagebitmap_extensions_on_worker.html b/dom/canvas/test/test_imagebitmap_extensions_on_worker.html
+deleted file mode 100644
+--- a/dom/canvas/test/test_imagebitmap_extensions_on_worker.html
++++ /dev/null
+@@ -1,39 +0,0 @@
+-<!DOCTYPE HTML>
+-<heand>
+-  <title>Test ImageBitmap Extensions On Worker (Bug 1141979)</title>
+-  <meta charset="utf-8">
+-  <script src="/tests/SimpleTest/SimpleTest.js"></script>
+-  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+-</head>
+-<body>
+-  <div id="content"><div>
+-  <script src="imagebitmap_extensions_prepareSources.js"></script>
+-  <script type="text/javascript">
+-
+-    var worker;
+-
+-    SimpleTest.waitForExplicitFinish();
+-    SpecialPowers.pushPrefEnv({'set': [
+-      ['canvas.imagebitmap_extensions.enabled', true]
+-    ]}, function() {
+-          worker = new Worker("imagebitmap_extensions_on_worker.js");
+-          worker.onmessage = function(event) {
+-            if (event.data.type == "status") {
+-              ok(event.data.status, event.data.msg);
+-            } else if (event.data.type == "finish") {
+-              SimpleTest.finish();
+-            }
+-          };
+-
+-          ok(!!worker, "Worker created successfully.");
+-          prepareSources().then(function() {
+-            worker.postMessage({"type": "setSources",
+-                                "groundTruthImageData": gGroundTruthImageData,
+-                                "imageData": gImageData,
+-                                "imageBitmap": gImageBitmap,
+-                                "pngBlob": gPNGBlob,
+-                                "jpegBlob": gJPEGBlob});
+-          });
+-    });
+-  </script>
+-</body>

+ 70 - 0
mozilla-release/patches/1500733-6-65a1.patch

@@ -0,0 +1,70 @@
+# HG changeset patch
+# User Andrea Marchesini <amarchesini@mozilla.com>
+# Date 1540330544 -7200
+#      Tue Oct 23 23:35:44 2018 +0200
+# Node ID 1dee16fa95e5257ecef4c8edf5e325732a4aa7dc
+# Parent  f24b78596a4edaaab41a93096cf442176a7ae66d
+Bug 1500733 - Remove canvas.imagebitmap_extensions.enabled preference, r=aosmond
+
+diff --git a/dom/base/DOMPrefsInternal.h b/dom/base/DOMPrefsInternal.h
+--- a/dom/base/DOMPrefsInternal.h
++++ b/dom/base/DOMPrefsInternal.h
+@@ -14,17 +14,16 @@
+ //     DOMPrefs::FooBar()
+ //   * The second argument is the name of the pref.
+ // 
+ //   DOM_WEBIDL_PREF(FooBar)
+ //
+ //   * This defines DOMPrefs::FooBar(JSContext* aCx, JSObject* aObj);
+ //     This is allows the use of DOMPrefs in WebIDL files.
+ 
+-DOM_PREF(ImageBitmapExtensionsEnabled, "canvas.imagebitmap_extensions.enabled")
+ DOM_PREF(DOMCachesEnabled, "dom.caches.enabled")
+ DOM_PREF(DOMCachesTestingEnabled, "dom.caches.testing.enabled")
+ DOM_PREF(PerformanceLoggingEnabled, "dom.performance.enable_user_timing_logging")
+ DOM_PREF(NotificationEnabled, "dom.webnotifications.enabled")
+ DOM_PREF(NotificationEnabledInServiceWorkers, "dom.webnotifications.serviceworker.enabled")
+ DOM_PREF(NotificationRIEnabled, "dom.webnotifications.requireinteraction.enabled")
+ DOM_PREF(ServiceWorkersEnabled, "dom.serviceWorkers.enabled")
+ DOM_PREF(ServiceWorkersTestingEnabled, "dom.serviceWorkers.testing.enabled")
+@@ -36,17 +35,16 @@ DOM_PREF(RequestContextEnabled, "dom.req
+ DOM_PREF(OffscreenCanvasEnabled, "gfx.offscreencanvas.enabled")
+ DOM_PREF(WebkitBlinkDirectoryPickerEnabled, "dom.webkitBlink.dirPicker.enabled")
+ DOM_PREF(NetworkInformationEnabled, "dom.netinfo.enabled")
+ DOM_PREF(FetchObserverEnabled, "dom.fetchObserver.enabled")
+ DOM_PREF(ResistFingerprintingEnabled, "privacy.resistFingerprinting")
+ DOM_PREF(DevToolsEnabled, "devtools.enabled")
+ DOM_PREF(PerformanceObserverEnabled, "dom.enable_performance_observer")
+ 
+-DOM_WEBIDL_PREF(ImageBitmapExtensionsEnabled)
+ DOM_WEBIDL_PREF(DOMCachesEnabled)
+ DOM_WEBIDL_PREF(NotificationEnabledInServiceWorkers)
+ DOM_WEBIDL_PREF(NotificationRIEnabled)
+ DOM_WEBIDL_PREF(ServiceWorkersEnabled)
+ DOM_WEBIDL_PREF(StorageManagerEnabled)
+ DOM_WEBIDL_PREF(PromiseRejectionEventsEnabled)
+ DOM_WEBIDL_PREF(PushEnabled)
+ DOM_WEBIDL_PREF(StreamsEnabled)
+diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
+--- a/modules/libpref/init/all.js
++++ b/modules/libpref/init/all.js
+@@ -1108,19 +1108,16 @@ pref("ui.scrollToClick", 0);
+ pref("canvas.focusring.enabled", true);
+ pref("canvas.customfocusring.enabled", false);
+ pref("canvas.hitregions.enabled", false);
+ pref("canvas.filters.enabled", true);
+ // Add support for canvas path objects
+ pref("canvas.path.enabled", true);
+ pref("canvas.capturestream.enabled", true);
+ 
+-// Disable the ImageBitmap-extensions for now.
+-pref("canvas.imagebitmap_extensions.enabled", false);
+-
+ // We want the ability to forcibly disable platform a11y, because
+ // some non-a11y-related components attempt to bring it up.  See bug
+ // 538530 for details about Windows; we have a pref here that allows it
+ // to be disabled for performance and testing resons.
+ // See bug 761589 for the crossplatform aspect.
+ //
+ // This pref is checked only once, and the browser needs a restart to
+ // pick up any changes.

+ 7 - 1
mozilla-release/patches/series

@@ -7120,6 +7120,12 @@ TOP-1906540-mozdevice-removal-mozilla-25320.patch
 1465585-3a-std-62a1.patch
 1462883-1no2-63a1.patch
 1462883-3-63a1.patch
-1566482-70a1.patch
+1500733-1-65a1.patch
+1500733-2-65a1.patch
+1500733-3-65a1.patch
+1500733-4-65a1.patch
+1500733-5-65a1.patch
+1500733-6-65a1.patch
 1559403-1-69a1.patch
 1559403-2-69a1.patch
+1566482-70a1.patch