Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 et tw=78: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "mozilla/dom/ImageData.h"
8 :
9 : #include "mozilla/CheckedInt.h"
10 : #include "mozilla/HoldDropJSObjects.h"
11 : #include "mozilla/dom/ImageDataBinding.h"
12 :
13 : #include "jsapi.h"
14 :
15 : namespace mozilla {
16 : namespace dom {
17 :
18 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageData)
19 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageData)
20 :
21 : NS_IMPL_CYCLE_COLLECTION_CLASS(ImageData)
22 :
23 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageData)
24 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
25 0 : NS_INTERFACE_MAP_END
26 :
27 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ImageData)
28 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData)
29 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
30 :
31 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ImageData)
32 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
33 :
34 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ImageData)
35 0 : tmp->DropData();
36 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
37 :
38 : //static
39 : already_AddRefed<ImageData>
40 0 : ImageData::Constructor(const GlobalObject& aGlobal,
41 : const uint32_t aWidth,
42 : const uint32_t aHeight,
43 : ErrorResult& aRv)
44 : {
45 0 : if (aWidth == 0 || aHeight == 0) {
46 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
47 0 : return nullptr;
48 : }
49 0 : CheckedInt<uint32_t> length = CheckedInt<uint32_t>(aWidth) * aHeight * 4;
50 0 : if (!length.isValid()) {
51 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
52 0 : return nullptr;
53 : }
54 0 : js::AssertSameCompartment(aGlobal.Context(), aGlobal.Get());
55 0 : JSObject* data = Uint8ClampedArray::Create(aGlobal.Context(),
56 0 : length.value());
57 0 : if (!data) {
58 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
59 0 : return nullptr;
60 : }
61 0 : RefPtr<ImageData> imageData = new ImageData(aWidth, aHeight, *data);
62 0 : return imageData.forget();
63 : }
64 :
65 : //static
66 : already_AddRefed<ImageData>
67 0 : ImageData::Constructor(const GlobalObject& aGlobal,
68 : const Uint8ClampedArray& aData,
69 : const uint32_t aWidth,
70 : const Optional<uint32_t>& aHeight,
71 : ErrorResult& aRv)
72 : {
73 0 : aData.ComputeLengthAndData();
74 :
75 0 : uint32_t length = aData.Length();
76 0 : if (length == 0 || length % 4) {
77 0 : aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
78 0 : return nullptr;
79 : }
80 0 : length /= 4;
81 0 : if (aWidth == 0) {
82 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
83 0 : return nullptr;
84 : }
85 0 : uint32_t height = length / aWidth;
86 0 : if (length != aWidth * height ||
87 0 : (aHeight.WasPassed() && aHeight.Value() != height)) {
88 0 : aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
89 0 : return nullptr;
90 : }
91 0 : if (JS_GetTypedArraySharedness(aData.Obj())) {
92 : // Throw if the object is mapping shared memory (must opt in).
93 0 : aRv.ThrowTypeError<MSG_TYPEDARRAY_IS_SHARED>(NS_LITERAL_STRING("Argument of ImageData constructor"));
94 0 : return nullptr;
95 : }
96 0 : RefPtr<ImageData> imageData = new ImageData(aWidth, height, *aData.Obj());
97 0 : return imageData.forget();
98 : }
99 :
100 : void
101 0 : ImageData::HoldData()
102 : {
103 0 : mozilla::HoldJSObjects(this);
104 0 : }
105 :
106 : void
107 0 : ImageData::DropData()
108 : {
109 0 : if (mData) {
110 0 : mData = nullptr;
111 0 : mozilla::DropJSObjects(this);
112 : }
113 0 : }
114 :
115 : bool
116 0 : ImageData::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
117 : {
118 0 : return ImageDataBinding::Wrap(aCx, this, aGivenProto, aReflector);
119 : }
120 :
121 : } // namespace dom
122 : } // namespace mozilla
|