mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-25 00:27:29 +09:00
Issue #2546 - Part 3: Remove mapDataInto
This commit is contained in:
parent
2b8d75e136
commit
1bc0eda791
6 changed files with 2 additions and 377 deletions
|
|
@ -562,10 +562,6 @@ DOMInterfaces = {
|
||||||
'headerFile': 'xpcjsid.h',
|
'headerFile': 'xpcjsid.h',
|
||||||
},
|
},
|
||||||
|
|
||||||
'ImageBitmap': {
|
|
||||||
'implicitJSContext': [ 'mapDataInto' ],
|
|
||||||
},
|
|
||||||
|
|
||||||
'ImageCapture': {
|
'ImageCapture': {
|
||||||
'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
|
'binaryNames': { 'videoStreamTrack': 'GetVideoStreamTrack' }
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -412,7 +412,6 @@ ImageBitmap::ImageBitmap(nsIGlobalObject* aGlobal, layers::Image* aData,
|
||||||
, mDataWrapper(new ImageUtils(mData))
|
, mDataWrapper(new ImageUtils(mData))
|
||||||
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
|
, mPictureRect(0, 0, aData->GetSize().width, aData->GetSize().height)
|
||||||
, mIsPremultipliedAlpha(aIsPremultipliedAlpha)
|
, mIsPremultipliedAlpha(aIsPremultipliedAlpha)
|
||||||
, mIsCroppingAreaOutSideOfSourceImage(false)
|
|
||||||
, mWriteOnly(aWriteOnly)
|
, mWriteOnly(aWriteOnly)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
|
MOZ_ASSERT(aData, "aData is null in ImageBitmap constructor.");
|
||||||
|
|
@ -442,23 +441,6 @@ ImageBitmap::SetPictureRect(const IntRect& aRect, ErrorResult& aRv)
|
||||||
mPictureRect = FixUpNegativeDimension(aRect, 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>
|
static already_AddRefed<SourceSurface>
|
||||||
ConvertColorFormatIfNeeded(RefPtr<SourceSurface> aSurface)
|
ConvertColorFormatIfNeeded(RefPtr<SourceSurface> aSurface)
|
||||||
{
|
{
|
||||||
|
|
@ -702,7 +684,6 @@ ImageBitmap::ToCloneData() const
|
||||||
UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
|
UniquePtr<ImageBitmapCloneData> result(new ImageBitmapCloneData());
|
||||||
result->mPictureRect = mPictureRect;
|
result->mPictureRect = mPictureRect;
|
||||||
result->mIsPremultipliedAlpha = mIsPremultipliedAlpha;
|
result->mIsPremultipliedAlpha = mIsPremultipliedAlpha;
|
||||||
result->mIsCroppingAreaOutSideOfSourceImage = mIsCroppingAreaOutSideOfSourceImage;
|
|
||||||
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
|
RefPtr<SourceSurface> surface = mData->GetAsSourceSurface();
|
||||||
result->mSurface = surface->GetDataSurface();
|
result->mSurface = surface->GetDataSurface();
|
||||||
MOZ_ASSERT(result->mSurface);
|
MOZ_ASSERT(result->mSurface);
|
||||||
|
|
@ -720,9 +701,6 @@ ImageBitmap::CreateFromCloneData(nsIGlobalObject* aGlobal,
|
||||||
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mWriteOnly,
|
RefPtr<ImageBitmap> ret = new ImageBitmap(aGlobal, data, aData->mWriteOnly,
|
||||||
aData->mIsPremultipliedAlpha);
|
aData->mIsPremultipliedAlpha);
|
||||||
|
|
||||||
ret->mIsCroppingAreaOutSideOfSourceImage =
|
|
||||||
aData->mIsCroppingAreaOutSideOfSourceImage;
|
|
||||||
|
|
||||||
ErrorResult rv;
|
ErrorResult rv;
|
||||||
ret->SetPictureRect(aData->mPictureRect, rv);
|
ret->SetPictureRect(aData->mPictureRect, rv);
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
|
|
@ -796,9 +774,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl
|
||||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -850,9 +825,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLVideoElement& aVideoEl
|
||||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(data->GetSize(), aCropRect);
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -918,9 +890,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, HTMLCanvasElement& aCanvas
|
||||||
ret->SetPictureRect(cropRect, aRv);
|
ret->SetPictureRect(cropRect, aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -986,9 +955,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageData& aImageData,
|
||||||
// The cropping information has been handled in the CreateImageFromRawData()
|
// The cropping information has been handled in the CreateImageFromRawData()
|
||||||
// function.
|
// function.
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(imageSize, aCropRect);
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1026,9 +992,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, CanvasRenderingContext2D&
|
||||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(surface->GetSize(), aCropRect);
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1052,14 +1015,6 @@ ImageBitmap::CreateInternal(nsIGlobalObject* aGlobal, ImageBitmap& aImageBitmap,
|
||||||
ret->SetPictureRect(aCropRect.ref(), aRv);
|
ret->SetPictureRect(aCropRect.ref(), aRv);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
if (aImageBitmap.mIsCroppingAreaOutSideOfSourceImage == true) {
|
|
||||||
ret->mIsCroppingAreaOutSideOfSourceImage = true;
|
|
||||||
} else {
|
|
||||||
ret->SetIsCroppingAreaOutSideOfSourceImage(aImageBitmap.mPictureRect.Size(),
|
|
||||||
aCropRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret.forget();
|
return ret.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1318,9 +1273,6 @@ private:
|
||||||
// Create ImageBitmap object.
|
// Create ImageBitmap object.
|
||||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
|
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
|
|
||||||
|
|
||||||
return imageBitmap.forget();
|
return imageBitmap.forget();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1414,9 +1366,6 @@ private:
|
||||||
// Create ImageBitmap object.
|
// Create ImageBitmap object.
|
||||||
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
|
RefPtr<ImageBitmap> imageBitmap = new ImageBitmap(mGlobalObject, data, false /* write-only */);
|
||||||
|
|
||||||
// Set mIsCroppingAreaOutSideOfSourceImage.
|
|
||||||
imageBitmap->SetIsCroppingAreaOutSideOfSourceImage(sourceSize, originalCropRect);
|
|
||||||
|
|
||||||
return imageBitmap.forget();
|
return imageBitmap.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1506,20 +1455,17 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
||||||
uint32_t picRectWidth_;
|
uint32_t picRectWidth_;
|
||||||
uint32_t picRectHeight_;
|
uint32_t picRectHeight_;
|
||||||
uint32_t isPremultipliedAlpha_;
|
uint32_t isPremultipliedAlpha_;
|
||||||
uint32_t isCroppingAreaOutSideOfSourceImage_;
|
|
||||||
uint32_t writeOnly;
|
uint32_t writeOnly;
|
||||||
uint32_t dummy;
|
uint32_t dummy;
|
||||||
|
|
||||||
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
|
if (!JS_ReadUint32Pair(aReader, &picRectX_, &picRectY_) ||
|
||||||
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
|
!JS_ReadUint32Pair(aReader, &picRectWidth_, &picRectHeight_) ||
|
||||||
!JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_,
|
!JS_ReadUint32Pair(aReader, &isPremultipliedAlpha_,
|
||||||
&isCroppingAreaOutSideOfSourceImage_) ||
|
&dummy) ||
|
||||||
!JS_ReadUint32Pair(aReader, &writeOnly, &dummy)) {
|
!JS_ReadUint32Pair(aReader, &writeOnly, &dummy)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(dummy == 0);
|
|
||||||
|
|
||||||
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
|
int32_t picRectX = BitwiseCast<int32_t>(picRectX_);
|
||||||
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
|
int32_t picRectY = BitwiseCast<int32_t>(picRectY_);
|
||||||
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
|
int32_t picRectWidth = BitwiseCast<int32_t>(picRectWidth_);
|
||||||
|
|
@ -1540,9 +1486,6 @@ ImageBitmap::ReadStructuredClone(JSContext* aCx,
|
||||||
RefPtr<ImageBitmap> imageBitmap =
|
RefPtr<ImageBitmap> imageBitmap =
|
||||||
new ImageBitmap(aParent, img, !!writeOnly, isPremultipliedAlpha_);
|
new ImageBitmap(aParent, img, !!writeOnly, isPremultipliedAlpha_);
|
||||||
|
|
||||||
imageBitmap->mIsCroppingAreaOutSideOfSourceImage =
|
|
||||||
isCroppingAreaOutSideOfSourceImage_;
|
|
||||||
|
|
||||||
ErrorResult error;
|
ErrorResult error;
|
||||||
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
|
imageBitmap->SetPictureRect(IntRect(picRectX, picRectY,
|
||||||
picRectWidth, picRectHeight), error);
|
picRectWidth, picRectHeight), error);
|
||||||
|
|
@ -1572,7 +1515,6 @@ ImageBitmap::WriteStructuredClone(JSStructuredCloneWriter* aWriter,
|
||||||
const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
|
const uint32_t picRectWidth = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.width);
|
||||||
const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
|
const uint32_t picRectHeight = BitwiseCast<uint32_t>(aImageBitmap->mPictureRect.height);
|
||||||
const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0;
|
const uint32_t isPremultipliedAlpha = aImageBitmap->mIsPremultipliedAlpha ? 1 : 0;
|
||||||
const uint32_t isCroppingAreaOutSideOfSourceImage = aImageBitmap->mIsCroppingAreaOutSideOfSourceImage ? 1 : 0;
|
|
||||||
const uint32_t isWriteOnly = aImageBitmap->mWriteOnly ? 1 : 0;
|
const uint32_t isWriteOnly = aImageBitmap->mWriteOnly ? 1 : 0;
|
||||||
|
|
||||||
// Indexing the cloned surfaces and send the index to the receiver.
|
// 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)) ||
|
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, picRectX, picRectY)) ||
|
||||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
|
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, picRectWidth, picRectHeight)) ||
|
||||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha,
|
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isPremultipliedAlpha, 0)) ||
|
||||||
isCroppingAreaOutSideOfSourceImage)) ||
|
|
||||||
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isWriteOnly, 0))) {
|
NS_WARN_IF(!JS_WriteUint32Pair(aWriter, isWriteOnly, 0))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1658,214 +1599,5 @@ ImageBitmap::MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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<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)
|
|
||||||
: 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(mDataWrapper, "No ImageBitmapFormatUtils functionalities.");
|
|
||||||
MOZ_ASSERT(aCx, "No JSContext while calling ImageBitmap::MapDataInto().");
|
|
||||||
|
|
||||||
RefPtr<Promise> 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 dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ class HTMLVideoElement;
|
||||||
enum class ImageBitmapFormat : uint32_t;
|
enum class ImageBitmapFormat : uint32_t;
|
||||||
class ImageData;
|
class ImageData;
|
||||||
class ImageUtils;
|
class ImageUtils;
|
||||||
template<typename T> class MapDataIntoBufferSource;
|
|
||||||
class Promise;
|
class Promise;
|
||||||
class PostMessageEvent; // For StructuredClone between windows.
|
class PostMessageEvent; // For StructuredClone between windows.
|
||||||
|
|
||||||
|
|
@ -64,7 +63,6 @@ struct ImageBitmapCloneData final
|
||||||
RefPtr<gfx::DataSourceSurface> mSurface;
|
RefPtr<gfx::DataSourceSurface> mSurface;
|
||||||
gfx::IntRect mPictureRect;
|
gfx::IntRect mPictureRect;
|
||||||
bool mIsPremultipliedAlpha;
|
bool mIsPremultipliedAlpha;
|
||||||
bool mIsCroppingAreaOutSideOfSourceImage;
|
|
||||||
bool mWriteOnly;
|
bool mWriteOnly;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -151,9 +149,6 @@ public:
|
||||||
friend CreateImageBitmapFromBlobTask;
|
friend CreateImageBitmapFromBlobTask;
|
||||||
friend CreateImageBitmapFromBlobWorkerTask;
|
friend CreateImageBitmapFromBlobWorkerTask;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
friend class MapDataIntoBufferSource;
|
|
||||||
|
|
||||||
bool IsWriteOnly() const {
|
bool IsWriteOnly() const {
|
||||||
return mWriteOnly;
|
return mWriteOnly;
|
||||||
}
|
}
|
||||||
|
|
@ -166,12 +161,6 @@ public:
|
||||||
int32_t
|
int32_t
|
||||||
MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
|
MappedDataLength(ImageBitmapFormat aFormat, ErrorResult& aRv);
|
||||||
|
|
||||||
already_AddRefed<Promise>
|
|
||||||
MapDataInto(JSContext* aCx,
|
|
||||||
ImageBitmapFormat aFormat,
|
|
||||||
const ArrayBufferViewOrArrayBuffer& aBuffer,
|
|
||||||
int32_t aOffset, ErrorResult& aRv);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -201,9 +190,6 @@ protected:
|
||||||
|
|
||||||
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
|
void SetPictureRect(const gfx::IntRect& aRect, ErrorResult& aRv);
|
||||||
|
|
||||||
void SetIsCroppingAreaOutSideOfSourceImage(const gfx::IntSize& aSourceSize,
|
|
||||||
const Maybe<gfx::IntRect>& aCroppingRect);
|
|
||||||
|
|
||||||
static already_AddRefed<ImageBitmap>
|
static already_AddRefed<ImageBitmap>
|
||||||
CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
|
CreateInternal(nsIGlobalObject* aGlobal, HTMLImageElement& aImageEl,
|
||||||
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
const Maybe<gfx::IntRect>& aCropRect, ErrorResult& aRv);
|
||||||
|
|
@ -269,15 +255,6 @@ protected:
|
||||||
|
|
||||||
const bool mIsPremultipliedAlpha;
|
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
|
* 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'
|
* cross-origin source. This is the opposite of what is called 'origin-clean'
|
||||||
|
|
|
||||||
|
|
@ -118,38 +118,6 @@ public:
|
||||||
return (uint32_t)(size.height * stride);
|
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:
|
protected:
|
||||||
Impl() {}
|
Impl() {}
|
||||||
|
|
||||||
|
|
@ -197,32 +165,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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:
|
private:
|
||||||
const PlanarYCbCrData* GetPlanarYCbCrData() const
|
const PlanarYCbCrData* GetPlanarYCbCrData() const
|
||||||
{
|
{
|
||||||
|
|
@ -274,17 +216,5 @@ ImageUtils::GetBufferLength() const
|
||||||
return mImpl->GetBufferLength();
|
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 dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,6 @@ typedef nsTArray<ChannelPixelLayout> ImagePixelLayout;
|
||||||
* (1) GetFormat() converts the image's format into ImageBitmapFormat enum.
|
* (1) GetFormat() converts the image's format into ImageBitmapFormat enum.
|
||||||
* (2) GetBufferLength() returns the number of bytes that are used to store
|
* (2) GetBufferLength() returns the number of bytes that are used to store
|
||||||
* the image's underlying raw data.
|
* 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
|
* In theory, the functionalities of this class could be merged into the
|
||||||
* interface of layers::Image. However, this is designed as a isolated wrapper
|
* interface of layers::Image. However, this is designed as a isolated wrapper
|
||||||
|
|
@ -58,10 +54,6 @@ public:
|
||||||
|
|
||||||
uint32_t GetBufferLength() const;
|
uint32_t GetBufferLength() const;
|
||||||
|
|
||||||
UniquePtr<ImagePixelLayout>
|
|
||||||
MapDataInto(uint8_t* aBuffer, uint32_t aOffset, uint32_t aBufferLength,
|
|
||||||
ImageBitmapFormat aFormat, ErrorResult& aRv) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Impl* mImpl;
|
Impl* mImpl;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -399,6 +399,4 @@ partial interface ImageBitmap {
|
||||||
ImageBitmapFormat findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
|
ImageBitmapFormat findOptimalFormat (optional sequence<ImageBitmapFormat> aPossibleFormats);
|
||||||
[Throws, Func="mozilla::dom::ImageBitmap::ExtensionsEnabled"]
|
[Throws, Func="mozilla::dom::ImageBitmap::ExtensionsEnabled"]
|
||||||
long mappedDataLength (ImageBitmapFormat aFormat);
|
long mappedDataLength (ImageBitmapFormat aFormat);
|
||||||
[Throws, Func="mozilla::dom::ImageBitmap::ExtensionsEnabled"]
|
|
||||||
Promise<ImagePixelLayout> mapDataInto (ImageBitmapFormat aFormat, BufferSource aBuffer, long aOffset);
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue