diff --git a/content/canvas/src/ImageData.cpp b/content/canvas/src/ImageData.cpp index b211d416a4b5..ed4595648e9d 100644 --- a/content/canvas/src/ImageData.cpp +++ b/content/canvas/src/ImageData.cpp @@ -6,6 +6,7 @@ #include "mozilla/dom/ImageData.h" +#include "mozilla/CheckedInt.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/dom/ImageDataBinding.h" @@ -35,6 +36,59 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ImageData) tmp->DropData(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END +//static +ImageData* +ImageData::Constructor(const GlobalObject& aGlobal, + const uint32_t aWidth, + const uint32_t aHeight, + ErrorResult& aRv) +{ + if (aWidth == 0 || aHeight == 0) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + CheckedInt length = CheckedInt(aWidth) * aHeight * 4; + if (!length.isValid()) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + JS::Rooted obj(aGlobal.GetContext(), aGlobal.Get()); + JSObject* data = Uint8ClampedArray::Create(aGlobal.GetContext(), obj, + length.value()); + if (!data) { + aRv.Throw(NS_ERROR_OUT_OF_MEMORY); + return nullptr; + } + return new ImageData(aWidth, aHeight, *data); +} + +//static +ImageData* +ImageData::Constructor(const GlobalObject& aGlobal, + const Uint8ClampedArray& aData, + const uint32_t aWidth, + const Optional& aHeight, + ErrorResult& aRv) +{ + uint32_t length = aData.Length(); + if (length == 0 || length % 4) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return nullptr; + } + length /= 4; + if (aWidth == 0) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + uint32_t height = length / aWidth; + if (length != aWidth * height || + (aHeight.WasPassed() && aHeight.Value() != height)) { + aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); + return nullptr; + } + return new ImageData(aWidth, height, *aData.Obj()); +} + void ImageData::HoldData() { diff --git a/content/canvas/src/ImageData.h b/content/canvas/src/ImageData.h index 40e6fb913f07..2e6eeb6bf287 100644 --- a/content/canvas/src/ImageData.h +++ b/content/canvas/src/ImageData.h @@ -10,6 +10,8 @@ #include "nsIDOMCanvasRenderingContext2D.h" #include "mozilla/Attributes.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/TypedArray.h" #include #include "nsCycleCollectionParticipant.h" @@ -40,6 +42,17 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ImageData) + static ImageData* Constructor(const GlobalObject& aGlobal, + const uint32_t aWidth, + const uint32_t aHeight, + ErrorResult& aRv); + + static ImageData* Constructor(const GlobalObject& aGlobal, + const Uint8ClampedArray& aData, + const uint32_t aWidth, + const Optional& aHeight, + ErrorResult& aRv); + uint32_t Width() const { return mWidth; diff --git a/content/canvas/test/mochitest.ini b/content/canvas/test/mochitest.ini index 0543fd7b6410..03dc3b88033d 100644 --- a/content/canvas/test/mochitest.ini +++ b/content/canvas/test/mochitest.ini @@ -97,6 +97,7 @@ support-files = [test_drawImageIncomplete.html] [test_drawImage_document_domain.html] [test_drawImage_edge_cases.html] +[test_ImageData_ctor.html] [test_isPointInStroke.html] [test_mozDashOffset.html] [test_mozGetAsFile.html] diff --git a/content/canvas/test/test_ImageData_ctor.html b/content/canvas/test/test_ImageData_ctor.html new file mode 100644 index 000000000000..cb4329454375 --- /dev/null +++ b/content/canvas/test/test_ImageData_ctor.html @@ -0,0 +1,80 @@ + +Canvas test: ImageData + + + +
+ + diff --git a/content/canvas/test/test_canvas.html b/content/canvas/test/test_canvas.html index 9a6bfefcd34d..c73a4ac20032 100644 --- a/content/canvas/test/test_canvas.html +++ b/content/canvas/test/test_canvas.html @@ -8363,9 +8363,16 @@ var canvas = document.getElementById('c280'); var ctx = canvas.getContext('2d'); ok(window.ImageData !== undefined, "window.ImageData !== undefined"); -try { var _thrown = false; - new window.ImageData(1,1); -} catch (e) { _thrown = true; } finally { ok(_thrown, "should throw exception"); } + +var _thrown_outer = false; +try { + +new window.ImageData(1,1); + +} catch (e) { + _thrown_outer = true; +} +ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception'); } diff --git a/dom/webidl/ImageData.webidl b/dom/webidl/ImageData.webidl index 869aff7b02ff..dae457594d84 100644 --- a/dom/webidl/ImageData.webidl +++ b/dom/webidl/ImageData.webidl @@ -10,6 +10,8 @@ * You are granted a license to use, reproduce and create derivative works of this document. */ +[Constructor(unsigned long sw, unsigned long sh), + Constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh)] interface ImageData { [Constant] readonly attribute unsigned long width;