OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); | 92 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); |
93 if (!byteArray) { | 93 if (!byteArray) { |
94 exceptionState.throwDOMException(V8Error, | 94 exceptionState.throwDOMException(V8Error, |
95 "Out of memory at ImageData creation"); | 95 "Out of memory at ImageData creation"); |
96 return nullptr; | 96 return nullptr; |
97 } | 97 } |
98 | 98 |
99 return new ImageData(IntSize(width, height), byteArray); | 99 return new ImageData(IntSize(width, height), byteArray); |
100 } | 100 } |
101 | 101 |
| 102 ImageData* ImageData::create(unsigned width, |
| 103 unsigned height, |
| 104 String colorSpace, |
| 105 ExceptionState& exceptionState) { |
| 106 if (!width || !height) { |
| 107 exceptionState.throwDOMException( |
| 108 IndexSizeError, String::format("The source %s is zero or not a number.", |
| 109 width ? "height" : "width")); |
| 110 return nullptr; |
| 111 } |
| 112 |
| 113 CheckedNumeric<unsigned> dataSize = 4; |
| 114 dataSize *= width; |
| 115 dataSize *= height; |
| 116 if (!dataSize.IsValid() || static_cast<int>(width) < 0 || |
| 117 static_cast<int>(height) < 0) { |
| 118 exceptionState.throwDOMException( |
| 119 IndexSizeError, |
| 120 "The requested image size exceeds the supported range."); |
| 121 return nullptr; |
| 122 } |
| 123 |
| 124 DOMUint8ClampedArray* byteArray = |
| 125 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); |
| 126 if (!byteArray) { |
| 127 exceptionState.throwDOMException(V8Error, |
| 128 "Out of memory at ImageData creation"); |
| 129 return nullptr; |
| 130 } |
| 131 |
| 132 return new ImageData(IntSize(width, height), byteArray, colorSpace); |
| 133 } |
| 134 |
102 bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data, | 135 bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data, |
103 unsigned width, | 136 unsigned width, |
104 unsigned& lengthInPixels, | 137 unsigned& lengthInPixels, |
105 ExceptionState& exceptionState) { | 138 ExceptionState& exceptionState) { |
106 if (!width) { | 139 if (!width) { |
107 exceptionState.throwDOMException( | 140 exceptionState.throwDOMException( |
108 IndexSizeError, "The source width is zero or not a number."); | 141 IndexSizeError, "The source width is zero or not a number."); |
109 return false; | 142 return false; |
110 } | 143 } |
111 DCHECK(data); | 144 DCHECK(data); |
(...skipping 12 matching lines...) Expand all Loading... |
124 if (length % width) { | 157 if (length % width) { |
125 exceptionState.throwDOMException( | 158 exceptionState.throwDOMException( |
126 IndexSizeError, | 159 IndexSizeError, |
127 "The input data byte length is not a multiple of (4 * width)."); | 160 "The input data byte length is not a multiple of (4 * width)."); |
128 return false; | 161 return false; |
129 } | 162 } |
130 lengthInPixels = length; | 163 lengthInPixels = length; |
131 return true; | 164 return true; |
132 } | 165 } |
133 | 166 |
| 167 bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data, |
| 168 unsigned width, |
| 169 unsigned& lengthInPixels, |
| 170 String colorSpace, |
| 171 ExceptionState& exceptionState) { |
| 172 if (colorSpace != kLegacyImageDataColorSpaceName && |
| 173 colorSpace != kSRGBImageDataColorSpaceName) { |
| 174 exceptionState.throwDOMException(NotSupportedError, |
| 175 "The input color space is not supported " |
| 176 "in Uint8ClampedArraye-backed image " |
| 177 "data."); |
| 178 return false; |
| 179 } |
| 180 return validateConstructorArguments(data, width, lengthInPixels, |
| 181 exceptionState); |
| 182 } |
| 183 |
134 ImageData* ImageData::create(DOMUint8ClampedArray* data, | 184 ImageData* ImageData::create(DOMUint8ClampedArray* data, |
135 unsigned width, | 185 unsigned width, |
136 ExceptionState& exceptionState) { | 186 ExceptionState& exceptionState) { |
137 unsigned lengthInPixels = 0; | 187 unsigned lengthInPixels = 0; |
138 if (!validateConstructorArguments(data, width, lengthInPixels, | 188 if (!validateConstructorArguments(data, width, lengthInPixels, |
139 exceptionState)) { | 189 exceptionState)) { |
140 DCHECK(exceptionState.hadException()); | 190 DCHECK(exceptionState.hadException()); |
141 return nullptr; | 191 return nullptr; |
142 } | 192 } |
143 DCHECK_GT(lengthInPixels, 0u); | 193 DCHECK_GT(lengthInPixels, 0u); |
(...skipping 16 matching lines...) Expand all Loading... |
160 DCHECK_GT(width, 0u); | 210 DCHECK_GT(width, 0u); |
161 if (height != lengthInPixels / width) { | 211 if (height != lengthInPixels / width) { |
162 exceptionState.throwDOMException( | 212 exceptionState.throwDOMException( |
163 IndexSizeError, | 213 IndexSizeError, |
164 "The input data byte length is not equal to (4 * width * height)."); | 214 "The input data byte length is not equal to (4 * width * height)."); |
165 return nullptr; | 215 return nullptr; |
166 } | 216 } |
167 return new ImageData(IntSize(width, height), data); | 217 return new ImageData(IntSize(width, height), data); |
168 } | 218 } |
169 | 219 |
| 220 ImageData* ImageData::create(DOMUint8ClampedArray* data, |
| 221 unsigned width, |
| 222 unsigned height, |
| 223 String colorSpace, |
| 224 ExceptionState& exceptionState) { |
| 225 unsigned lengthInPixels = 0; |
| 226 if (!validateConstructorArguments(data, width, lengthInPixels, colorSpace, |
| 227 exceptionState)) { |
| 228 DCHECK(exceptionState.hadException()); |
| 229 return nullptr; |
| 230 } |
| 231 DCHECK_GT(lengthInPixels, 0u); |
| 232 DCHECK_GT(width, 0u); |
| 233 if (height != lengthInPixels / width) { |
| 234 exceptionState.throwDOMException( |
| 235 IndexSizeError, |
| 236 "The input data byte length is not equal to (4 * width * height)."); |
| 237 return nullptr; |
| 238 } |
| 239 return new ImageData(IntSize(width, height), data, colorSpace); |
| 240 } |
| 241 |
| 242 // TODO(zakerinasab): Fix this when ImageBitmap color correction code is landed. |
| 243 // Tip: If the source Image Data has a color space, createImageBitmap must |
| 244 // respect this color space even when no color space tag is passed to it. |
170 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, | 245 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, |
171 EventTarget& eventTarget, | 246 EventTarget& eventTarget, |
172 Optional<IntRect> cropRect, | 247 Optional<IntRect> cropRect, |
173 const ImageBitmapOptions& options, | 248 const ImageBitmapOptions& options, |
174 ExceptionState& exceptionState) { | 249 ExceptionState& exceptionState) { |
175 if ((cropRect && | 250 if ((cropRect && |
176 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(), | 251 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(), |
177 exceptionState)) || | 252 exceptionState)) || |
178 !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(), | 253 !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(), |
179 bitmapSourceSize().height(), | 254 bitmapSourceSize().height(), |
(...skipping 24 matching lines...) Expand all Loading... |
204 v8::Local<v8::Value> pixelArray = toV8(m_data.get(), wrapper, isolate); | 279 v8::Local<v8::Value> pixelArray = toV8(m_data.get(), wrapper, isolate); |
205 if (pixelArray.IsEmpty() || | 280 if (pixelArray.IsEmpty() || |
206 !v8CallBoolean(wrapper->DefineOwnProperty( | 281 !v8CallBoolean(wrapper->DefineOwnProperty( |
207 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"), | 282 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"), |
208 pixelArray, v8::ReadOnly))) | 283 pixelArray, v8::ReadOnly))) |
209 return v8::Local<v8::Object>(); | 284 return v8::Local<v8::Object>(); |
210 } | 285 } |
211 return wrapper; | 286 return wrapper; |
212 } | 287 } |
213 | 288 |
214 ImageData::ImageData(const IntSize& size, DOMUint8ClampedArray* byteArray) | 289 ImageData::ImageData(const IntSize& size, |
215 : m_size(size), m_data(byteArray) { | 290 DOMUint8ClampedArray* byteArray, |
| 291 String colorSpace) |
| 292 : m_size(size), m_colorSpace(colorSpace), m_data(byteArray) { |
216 DCHECK_GE(size.width(), 0); | 293 DCHECK_GE(size.width(), 0); |
217 DCHECK_GE(size.height(), 0); | 294 DCHECK_GE(size.height(), 0); |
218 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <= | 295 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <= |
219 m_data->length()); | 296 m_data->length()); |
220 } | 297 } |
221 | 298 |
222 } // namespace blink | 299 } // namespace blink |
OLD | NEW |