diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 7e58b273f0..e21af85655 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -14614,11 +14614,6 @@ already_AddRefed nsGlobalWindow::CreateImageBitmap(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); } @@ -14627,11 +14622,6 @@ nsGlobalWindow::CreateImageBitmap(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); } @@ -14646,13 +14636,8 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage, 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; - } + aRv.Throw(NS_ERROR_TYPE_ERR); + return nullptr; } // https://html.spec.whatwg.org/#structured-cloning diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index 7aaf4e74d8..e7bc1f08c8 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -1867,217 +1867,6 @@ ImageBitmap::MapDataInto(JSContext* aCx, 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 -CreateImageFromBufferSourceRawData(const uint8_t*aBufferData, - uint32_t aBufferLength, - mozilla::dom::ImageBitmapFormat aFormat, - const Sequence& 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& 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 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 surface = dstDataSurface; - RefPtr 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(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(aBufferData + uLayout.mOffset); - data.mCrChannel = const_cast(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 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 { - RefPtrimage = 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& 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 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& mLayout; -}; - /*static*/ already_AddRefed ImageBitmap::Create(nsIGlobalObject* aGlobal, const ImageBitmapSource& aBuffer, @@ -2094,69 +1883,7 @@ ImageBitmap::Create(nsIGlobalObject* aGlobal, 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 data; - if (NS_IsMainThread()) { - data = CreateImageFromBufferSourceRawData(bufferData + aOffset, bufferLength, - aFormat, aLayout); - } else { - RefPtr 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 = new ImageBitmap(aGlobal, data, false); - - // 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); - + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); return promise.forget(); } diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h index c2a02370d6..f677ad6642 100644 --- a/dom/canvas/ImageBitmap.h +++ b/dom/canvas/ImageBitmap.h @@ -45,7 +45,6 @@ class WorkerStructuredCloneClosure; class ArrayBufferViewOrArrayBuffer; class CanvasRenderingContext2D; -struct ChannelPixelLayout; class CreateImageBitmapFromBlob; class CreateImageBitmapFromBlobTask; class CreateImageBitmapFromBlobWorkerTask; diff --git a/dom/canvas/ImageBitmapSource.h b/dom/canvas/ImageBitmapSource.h index 6eb52f2631..a95cb7c10d 100644 --- a/dom/canvas/ImageBitmapSource.h +++ b/dom/canvas/ImageBitmapSource.h @@ -10,9 +10,8 @@ namespace mozilla { namespace dom { // So we don't have to forward declare this elsewhere. -class HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer; -typedef HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrBlobOrImageDataOrCanvasRenderingContext2DOrImageBitmapOrArrayBufferViewOrArrayBuffer - ImageBitmapSource; +class HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData; +typedef HTMLImageElementOrHTMLCanvasElementOrHTMLVideoElementOrImageBitmapOrBlobOrCanvasRenderingContext2DOrImageData ImageBitmapSource; } } diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl index 3cfabff12e..d1471ed72d 100644 --- a/dom/webidl/ImageBitmap.webidl +++ b/dom/webidl/ImageBitmap.webidl @@ -10,25 +10,17 @@ * 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 - HTMLVideoElement or HTMLCanvasElement or + HTMLVideoElement or + ImageBitmap) CanvasImageSourceExcludedSVG; + +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 { diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index ef6abc25e2..6a05dfaa08 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -450,11 +450,6 @@ already_AddRefed WorkerGlobalScope::CreateImageBitmap(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); } @@ -463,11 +458,6 @@ WorkerGlobalScope::CreateImageBitmap(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); } @@ -486,13 +476,8 @@ WorkerGlobalScope::CreateImageBitmap(const ImageBitmapSource& aImage, 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; - } + aRv.Throw(NS_ERROR_TYPE_ERR); + return nullptr; } // https://html.spec.whatwg.org/#structured-cloning