diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index f484c59e53..6658db318c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -562,10 +562,6 @@ DOMInterfaces = { 'headerFile': 'xpcjsid.h', }, -'ImageBitmap': { - 'implicitJSContext': [ 'mapDataInto' ], -}, - 'ImageCapture': { 'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' } }, diff --git a/dom/canvas/ImageBitmap.cpp b/dom/canvas/ImageBitmap.cpp index c38f6d1650..d7df938aaa 100644 --- a/dom/canvas/ImageBitmap.cpp +++ b/dom/canvas/ImageBitmap.cpp @@ -412,7 +412,6 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData, , mDataWrapper(new ImageUtils(mData)) , mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height) , mIsPremultipliedAlpha(aIsPremultipliedAlpha) - , mIsCroppingAreaOutSideOfSourceImage(false) , mWriteOnly(aWriteOnly) { MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor."); @@ -442,23 +441,6 @@ ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv) mPictureRect = FixUpNegativeDimension(aRect, aRv); } -void -ImageBitmap::SetIsCroppingAreaOutSideOfSourceImage(const IntSize& aSourceSize, - const Maybe& 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 ConvertColorFormatIfNeeded(RefPtr aSurface) { @@ -702,7 +684,6 @@ ImageBitmap::ToCloneData() const UniquePtr result(new ImageBitmapCloneData()); result->mPictureRect = mPictureRect; result->mIsPremultipliedAlpha = mIsPremultipliedAlpha; - result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage; RefPtr surface = mData->GetAsSourceSurface(); result->mSurface = surface->GetDataSurface(); MOZ_ASSERT(result->mSurface); @@ -720,9 +701,6 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal, RefPtr ret = new ImageBitmap(aGlobal, data, aData->mWriteOnly, aData->mIsPremultipliedAlpha); - ret->mIsCroppingAreaOutSideOfSourceImage = - aData->mIsCroppingAreaOutSideOfSourceImage; - ErrorResult rv; ret->SetPictureRect(aData->mPictureRect, rv); return ret.forget(); @@ -796,9 +774,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl ret->SetPictureRect(aCropRect.ref(), aRv); } - // Set mIsCroppingAreaOutSideOfSourceImage. - ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect); - return ret.forget(); } @@ -850,9 +825,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl ret->SetPictureRect(aCropRect.ref(), aRv); } - // Set mIsCroppingAreaOutSideOfSourceImage. - ret->SetIsCroppingAreaOutSideOfSourceImage(data->GetSize(), aCropRect); - return ret.forget(); } @@ -918,9 +890,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas ret->SetPictureRect(cropRect, aRv); } - // Set mIsCroppingAreaOutSideOfSourceImage. - ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect); - return ret.forget(); } @@ -986,9 +955,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData, // The cropping information has been handled in the CreateImageFromRawData() // function. - // Set mIsCroppingAreaOutSideOfSourceImage. - ret->SetIsCroppingAreaOutSideOfSourceImage(imageSize, aCropRect); - return ret.forget(); } @@ -1026,9 +992,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D& ret->SetPictureRect(aCropRect.ref(), aRv); } - // Set mIsCroppingAreaOutSideOfSourceImage. - ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect); - return ret.forget(); } @@ -1052,14 +1015,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap, ret->SetPictureRect(aCropRect.ref(), aRv); } - // Set mIsCroppingAreaOutSideOfSourceImage. - if (aImageBitmap.mIsCroppingAreaOutSideOfSourceImage == true) { - ret->mIsCroppingAreaOutSideOfSourceImage = true; - } else { - ret->SetIsCroppingAreaOutSideOfSourceImage(aImageBitmap.mPictureRect.Size(), - aCropRect); - } - return ret.forget(); } @@ -1318,9 +1273,6 @@ private: // Create ImageBitmap object. RefPtr imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */); - // Set mIsCroppingAreaOutSideOfSourceImage. - imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect); - return imageBitmap.forget(); } }; @@ -1414,9 +1366,6 @@ private: // Create ImageBitmap object. RefPtr imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */); - // Set mIsCroppingAreaOutSideOfSourceImage. - imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect); - return imageBitmap.forget(); } @@ -1506,20 +1455,17 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx, uint32_t picRectWidth_; uint32_t picRectHeight_; uint32_t isPremultipliedAlpha_; - uint32_t isCroppingAreaOutSideOfSourceImage_; uint32_t writeOnly; uint32_t dummy; if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) || !JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) || !JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_, - &isCroppingAreaOutSideOfSourceImage_) || + &dummy) || !JS_ReadUint32Pair(aReader, &writeOnly, &dummy)) { return nullptr; } - MOZ_ASSERT(dummy == 0); - int32_t picRectX = BitwiseCast(picRectX_); int32_t picRectY = BitwiseCast(picRectY_); int32_t picRectWidth = BitwiseCast(picRectWidth_); @@ -1540,9 +1486,6 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx, RefPtr imageBitmap = new ImageBitmap(aParent, img, !!writeOnly, isPremultipliedAlpha_); - imageBitmap->mIsCroppingAreaOutSideOfSourceImage = - isCroppingAreaOutSideOfSourceImage_; - ErrorResult error; imageBitmap->SetPictureRect(IntRect(picRectX, picRectY, picRectWidth, picRectHeight), error); @@ -1572,7 +1515,6 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter, const uint32_t picRectWidth = BitwiseCast(aImageBitmap->mPictureRect.width); const uint32_t picRectHeight = BitwiseCast(aImageBitmap->mPictureRect.height); const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0; - const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0; const uint32_t isWriteOnly = aImageBitmap->mWriteOnly ? 1 : 0; // Indexing the cloned surfaces and send the index to the receiver. @@ -1581,8 +1523,7 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter, 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, isPremultipliedAlpha, - isCroppingAreaOutSideOfSourceImage)) || + NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha, 0)) || NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isWriteOnly, 0))) { return false; } @@ -1658,214 +1599,5 @@ ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv) } } -template -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; - - // 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.Throw(NS_ERROR_NOT_IMPLEMENTED); - mPromise->MaybeReject(error); - return; - } - - if (NS_WARN_IF(!bufferData) || NS_WARN_IF(!bufferLength)) { - error.Throw(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.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); - mPromise->MaybeReject(error); - return; - } - - // Call ImageBitmapFormatUtils. - UniquePtr layout = - mImageBitmap->mDataWrapper->MapDataInto(bufferData, - mOffset, - bufferLength, - mFormat, - error); - - if (NS_WARN_IF(!layout)) { - mPromise->MaybeReject(error); - return; - } - - mPromise->MaybeResolve(*layout); - } - - RefPtr mPromise; - RefPtr mImageBitmap; - JS::PersistentRooted mBuffer; - int32_t mOffset; - ImageBitmapFormat mFormat; -}; - -template -class MapDataIntoBufferSourceTask final : public Runnable, - public MapDataIntoBufferSource -{ -public: - MapDataIntoBufferSourceTask(JSContext* aCx, - Promise *aPromise, - ImageBitmap *aImageBitmap, - const T& aBuffer, - int32_t aOffset, - ImageBitmapFormat aFormat) - : MapDataIntoBufferSource(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat) - { - } - - virtual ~MapDataIntoBufferSourceTask() = default; - - NS_IMETHOD Run() override - { - MapDataIntoBufferSource::DoMapDataIntoBufferSource(); - return NS_OK; - } -}; - -template -class MapDataIntoBufferSourceWorkerTask final : public WorkerSameThreadRunnable, - public MapDataIntoBufferSource -{ -public: - MapDataIntoBufferSourceWorkerTask(JSContext* aCx, - Promise *aPromise, - ImageBitmap *aImageBitmap, - const T& aBuffer, - int32_t aOffset, - ImageBitmapFormat aFormat) - : WorkerSameThreadRunnable(GetCurrentThreadWorkerPrivate()), - MapDataIntoBufferSource(aCx, aPromise, aImageBitmap, aBuffer, aOffset, aFormat) - { - } - - virtual ~MapDataIntoBufferSourceWorkerTask() = default; - - bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override - { - MapDataIntoBufferSource::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 task; - - if (aBuffer.IsArrayBuffer()) { - const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer(); - task = new MapDataIntoBufferSourceTask(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat); - } else if (aBuffer.IsArrayBufferView()) { - const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView(); - task = new MapDataIntoBufferSourceTask(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat); - } - - NS_DispatchToCurrentThread(task); // Actually, to the main-thread. - } else { - RefPtr task; - - if (aBuffer.IsArrayBuffer()) { - const ArrayBuffer& buffer = aBuffer.GetAsArrayBuffer(); - task = new MapDataIntoBufferSourceWorkerTask(aCx, aPromise, aImageBitmap, buffer, aOffset, aFormat); - } else if (aBuffer.IsArrayBufferView()) { - const ArrayBufferView& bufferView = aBuffer.GetAsArrayBufferView(); - task = new MapDataIntoBufferSourceWorkerTask(aCx, aPromise, aImageBitmap, bufferView, aOffset, aFormat); - } - - task->Dispatch(); // Actually, to the current worker-thread. - } -} - -already_AddRefed -ImageBitmap::MapDataInto(JSContext* aCx, - ImageBitmapFormat aFormat, - const ArrayBufferViewOrArrayBuffer& aBuffer, - int32_t aOffset, ErrorResult& aRv) -{ - MOZ_ASSERT(mDataWrapper, "No ImageBitmapFormatUtils functionalities."); - MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto()."); - - RefPtr promise = Promise::Create(mParent, aRv); - - if (NS_WARN_IF(aRv.Failed())) { - return nullptr; - } - - // 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(); -} - } // namespace dom } // namespace mozilla diff --git a/dom/canvas/ImageBitmap.h b/dom/canvas/ImageBitmap.h index 20422d969c..efd339f112 100644 --- a/dom/canvas/ImageBitmap.h +++ b/dom/canvas/ImageBitmap.h @@ -55,7 +55,6 @@ class HTMLVideoElement; enum class ImageBitmapFormat : uint32_t; class ImageData; class ImageUtils; -template class MapDataIntoBufferSource; class Promise; class PostMessageEvent; // For StructuredClone between windows. @@ -64,7 +63,6 @@ struct ImageBitmapCloneData final RefPtr mSurface; gfx::IntRect mPictureRect; bool mIsPremultipliedAlpha; - bool mIsCroppingAreaOutSideOfSourceImage; bool mWriteOnly; }; @@ -151,9 +149,6 @@ public: friend CreateImageBitmapFromBlobTask; friend CreateImageBitmapFromBlobWorkerTask; - template - friend class MapDataIntoBufferSource; - bool IsWriteOnly() const { return mWriteOnly; } @@ -166,12 +161,6 @@ public: int32_t MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv); - already_AddRefed - MapDataInto(JSContext* aCx, - ImageBitmapFormat aFormat, - const ArrayBufferViewOrArrayBuffer& aBuffer, - int32_t aOffset, ErrorResult& aRv); - protected: /* @@ -201,9 +190,6 @@ protected: void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv); - void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize, - const Maybe& aCroppingRect); - static already_AddRefed CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl, const Maybe& aCropRect, ErrorResult& aRv); @@ -269,15 +255,6 @@ protected: const bool mIsPremultipliedAlpha; - /* - * 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; - /* * Write-Only flag is set to true if this image has been generated from a * cross-origin source. This is the opposite of what is called 'origin-clean' diff --git a/dom/canvas/ImageUtils.cpp b/dom/canvas/ImageUtils.cpp index 30616c8471..295fa0c58d 100644 --- a/dom/canvas/ImageUtils.cpp +++ b/dom/canvas/ImageUtils.cpp @@ -118,38 +118,6 @@ public: return (uint32_t)(size.height * stride); } - virtual UniquePtr - 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 srcLayout = - CreateDefaultPixelLayout(GetFormat(), Surface()->GetSize().width, - Surface()->GetSize().height, map.GetStride()); - - // Prepare destination buffer. - uint8_t* dstBuffer = aBuffer + aOffset; - UniquePtr dstLayout = - CopyAndConvertImageData(GetFormat(), map.GetData(), srcLayout.get(), - aFormat, dstBuffer); - - if (!dstLayout) { - aRv.Throw(NS_ERROR_NOT_AVAILABLE); - return nullptr; - } - - return dstLayout; - } - protected: Impl() {} @@ -197,32 +165,6 @@ public: } } - UniquePtr - 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 srcLayout = - CreatePixelLayoutFromPlanarYCbCrData(data); - - // Do conversion. - UniquePtr 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 { @@ -274,17 +216,5 @@ ImageUtils::GetBufferLength() const return mImpl->GetBufferLength(); } -UniquePtr -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 index 66ed0431c4..4998570517 100644 --- a/dom/canvas/ImageUtils.h +++ b/dom/canvas/ImageUtils.h @@ -31,10 +31,6 @@ typedef nsTArray ImagePixelLayout; * (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 @@ -58,10 +54,6 @@ public: uint32_t GetBufferLength() const; - UniquePtr - MapDataInto(uint8_t* aBuffer, uint32_t aOffset, uint32_t aBufferLength, - ImageBitmapFormat aFormat, ErrorResult& aRv) const; - protected: Impl* mImpl; }; diff --git a/dom/webidl/ImageBitmap.webidl b/dom/webidl/ImageBitmap.webidl index d1471ed72d..14e0c1165b 100644 --- a/dom/webidl/ImageBitmap.webidl +++ b/dom/webidl/ImageBitmap.webidl @@ -399,6 +399,4 @@ partial interface ImageBitmap { ImageBitmapFormat findOptimalFormat (optional sequence aPossibleFormats); [Throws, Func="mozilla::dom::ImageBitmap::ExtensionsEnabled"] long mappedDataLength (ImageBitmapFormat aFormat); - [Throws, Func="mozilla::dom::ImageBitmap::ExtensionsEnabled"] - Promise mapDataInto (ImageBitmapFormat aFormat, BufferSource aBuffer, long aOffset); };