Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(20)

Side by Side Diff: third_party/WebKit/Source/core/html/ImageData.cpp

Issue 2636533002: Revert of Implement color management for ImageData
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 16 matching lines...) Expand all
27 */ 27 */
28 28
29 #include "core/html/ImageData.h" 29 #include "core/html/ImageData.h"
30 30
31 #include "bindings/core/v8/ExceptionState.h" 31 #include "bindings/core/v8/ExceptionState.h"
32 #include "bindings/core/v8/V8Uint8ClampedArray.h" 32 #include "bindings/core/v8/V8Uint8ClampedArray.h"
33 #include "core/dom/ExceptionCode.h" 33 #include "core/dom/ExceptionCode.h"
34 #include "core/frame/ImageBitmap.h" 34 #include "core/frame/ImageBitmap.h"
35 #include "core/imagebitmap/ImageBitmapOptions.h" 35 #include "core/imagebitmap/ImageBitmapOptions.h"
36 #include "platform/RuntimeEnabledFeatures.h" 36 #include "platform/RuntimeEnabledFeatures.h"
37 #include "wtf/CheckedNumeric.h"
37 38
38 namespace blink { 39 namespace blink {
39 40
40 bool ImageData::validateConstructorArguments(const unsigned& paramFlags,
41 const IntSize* size,
42 const unsigned& width,
43 const unsigned& height,
44 const DOMArrayBufferView* data,
45 const String* colorSpace,
46 ExceptionState* exceptionState,
47 ImageDataType imageDataType) {
48 if (paramFlags & kParamData) {
49 if (data->type() != DOMArrayBufferView::ViewType::TypeUint8Clamped &&
50 data->type() != DOMArrayBufferView::ViewType::TypeFloat32)
51 return false;
52 if (data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped &&
53 imageDataType != kUint8ClampedImageData)
54 imageDataType = kFloat32ImageData;
55 }
56
57 // ImageData::create parameters without ExceptionState
58 if (paramFlags & kParamSize) {
59 if (!size->width() || !size->height())
60 return false;
61 if (paramFlags & kParamData) {
62 DCHECK(data);
63 CheckedNumeric<unsigned> dataSize = 4;
64 dataSize *= size->width();
65 dataSize *= size->height();
66 unsigned length =
67 data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
68 ? (const_cast<DOMUint8ClampedArray*>(
69 static_cast<const DOMUint8ClampedArray*>(data)))
70 ->length()
71 : (const_cast<DOMFloat32Array*>(
72 static_cast<const DOMFloat32Array*>(data)))
73 ->length();
74 if (!dataSize.IsValid() || dataSize.ValueOrDie() > length)
75 return false;
76 }
77 return true;
78 }
79
80 // ImageData::create parameters with ExceptionState
81 if ((paramFlags & kParamWidth) && !width) {
82 exceptionState->throwDOMException(
83 IndexSizeError, "The source width is zero or not a number.");
84 return false;
85 }
86 if ((paramFlags & kParamHeight) && !height) {
87 exceptionState->throwDOMException(
88 IndexSizeError, "The source height is zero or not a number.");
89 return false;
90 }
91 if (paramFlags & (kParamWidth | kParamHeight)) {
92 CheckedNumeric<unsigned> dataSize = 4;
93 dataSize *= width;
94 dataSize *= height;
95 if (!dataSize.IsValid()) {
96 exceptionState->throwDOMException(
97 IndexSizeError,
98 "The requested image size exceeds the supported range.");
99 return false;
100 }
101 }
102 if (paramFlags & kParamData) {
103 DCHECK(data);
104 unsigned length =
105 data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
106 ? (const_cast<DOMUint8ClampedArray*>(
107 static_cast<const DOMUint8ClampedArray*>(data)))
108 ->length()
109 : (const_cast<DOMFloat32Array*>(
110 static_cast<const DOMFloat32Array*>(data)))
111 ->length();
112 if (!length) {
113 exceptionState->throwDOMException(IndexSizeError,
114 "The input data has zero elements.");
115 return false;
116 }
117 if (length % 4) {
118 exceptionState->throwDOMException(
119 IndexSizeError, "The input data length is not a multiple of 4.");
120 return false;
121 }
122 length /= 4;
123 if (length % width) {
124 exceptionState->throwDOMException(
125 IndexSizeError,
126 "The input data length is not a multiple of (4 * width).");
127 return false;
128 }
129 if ((paramFlags & kParamHeight) && height != length / width) {
130 exceptionState->throwDOMException(
131 IndexSizeError,
132 "The input data length is not equal to (4 * width * height).");
133 return false;
134 }
135 }
136 if (paramFlags & kParamColorSpace) {
137 if (!colorSpace || colorSpace->length() == 0) {
138 exceptionState->throwDOMException(
139 NotSupportedError, "The source color space is not defined.");
140 return false;
141 }
142 if (imageDataType == kUint8ClampedImageData &&
143 *colorSpace != kLegacyImageDataColorSpaceName &&
144 *colorSpace != kSRGBImageDataColorSpaceName) {
145 exceptionState->throwDOMException(NotSupportedError,
146 "The input color space is not "
147 "supported in "
148 "Uint8ClampedArray-backed ImageData.");
149 return false;
150 }
151 if (imageDataType == kFloat32ImageData &&
152 *colorSpace != kLinearRGBImageDataColorSpaceName) {
153 exceptionState->throwDOMException(NotSupportedError,
154 "The input color space is not "
155 "supported in "
156 "Float32Array-backed ImageData.");
157 return false;
158 }
159 }
160 return true;
161 }
162
163 DOMUint8ClampedArray* ImageData::allocateAndValidateUint8ClampedArray(
164 const unsigned& length,
165 ExceptionState* exceptionState) {
166 if (!length)
167 return nullptr;
168 DOMUint8ClampedArray* dataArray = DOMUint8ClampedArray::createOrNull(length);
169 if (!dataArray || length != dataArray->length()) {
170 if (exceptionState) {
171 exceptionState->throwDOMException(V8RangeError,
172 "Out of memory at ImageData creation");
173 }
174 return nullptr;
175 }
176 return dataArray;
177 }
178
179 ImageData* ImageData::create(const IntSize& size) { 41 ImageData* ImageData::create(const IntSize& size) {
180 if (!ImageData::validateConstructorArguments(kParamSize, &size))
181 return nullptr;
182 DOMUint8ClampedArray* byteArray =
183 ImageData::allocateAndValidateUint8ClampedArray(4 * size.width() *
184 size.height());
185 if (!byteArray)
186 return nullptr;
187 return new ImageData(size, byteArray);
188 }
189
190 // This function accepts size (0, 0).
191 ImageData* ImageData::createForTest(const IntSize& size) {
192 CheckedNumeric<unsigned> dataSize = 4; 42 CheckedNumeric<unsigned> dataSize = 4;
193 dataSize *= size.width(); 43 dataSize *= size.width();
194 dataSize *= size.height(); 44 dataSize *= size.height();
195 if (!dataSize.IsValid()) 45 if (!dataSize.IsValid())
196 return nullptr; 46 return nullptr;
197 47
198 DOMUint8ClampedArray* byteArray = 48 DOMUint8ClampedArray* byteArray =
199 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); 49 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie());
200 if (!byteArray) 50 if (!byteArray)
201 return nullptr; 51 return nullptr;
202 52
203 return new ImageData(size, byteArray); 53 return new ImageData(size, byteArray);
204 } 54 }
205 55
206 ImageData* ImageData::create(const IntSize& size, 56 ImageData* ImageData::create(const IntSize& size,
207 DOMUint8ClampedArray* byteArray) { 57 DOMUint8ClampedArray* byteArray) {
208 if (!ImageData::validateConstructorArguments(kParamSize | kParamData, &size, 58 CheckedNumeric<unsigned> dataSize = 4;
209 0, 0, byteArray)) 59 dataSize *= size.width();
60 dataSize *= size.height();
61 if (!dataSize.IsValid())
210 return nullptr; 62 return nullptr;
63
64 if (!dataSize.IsValid() || dataSize.ValueOrDie() > byteArray->length())
65 return nullptr;
66
211 return new ImageData(size, byteArray); 67 return new ImageData(size, byteArray);
212 } 68 }
213 69
214 ImageData* ImageData::create(unsigned width, 70 ImageData* ImageData::create(unsigned width,
215 unsigned height, 71 unsigned height,
216 ExceptionState& exceptionState) { 72 ExceptionState& exceptionState) {
217 if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight, 73 if (!width || !height) {
218 nullptr, width, height, nullptr, 74 exceptionState.throwDOMException(
219 nullptr, &exceptionState)) 75 IndexSizeError, String::format("The source %s is zero or not a number.",
76 width ? "height" : "width"));
220 return nullptr; 77 return nullptr;
78 }
79
80 CheckedNumeric<unsigned> dataSize = 4;
81 dataSize *= width;
82 dataSize *= height;
83 if (!dataSize.IsValid() || static_cast<int>(width) < 0 ||
84 static_cast<int>(height) < 0) {
85 exceptionState.throwDOMException(
86 IndexSizeError,
87 "The requested image size exceeds the supported range.");
88 return nullptr;
89 }
90
221 DOMUint8ClampedArray* byteArray = 91 DOMUint8ClampedArray* byteArray =
222 ImageData::allocateAndValidateUint8ClampedArray(4 * width * height, 92 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie());
223 &exceptionState); 93 if (!byteArray) {
224 return byteArray ? new ImageData(IntSize(width, height), byteArray) : nullptr; 94 exceptionState.throwDOMException(V8Error,
95 "Out of memory at ImageData creation");
96 return nullptr;
97 }
98
99 return new ImageData(IntSize(width, height), byteArray);
100 }
101
102 bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data,
103 unsigned width,
104 unsigned& lengthInPixels,
105 ExceptionState& exceptionState) {
106 if (!width) {
107 exceptionState.throwDOMException(
108 IndexSizeError, "The source width is zero or not a number.");
109 return false;
110 }
111 DCHECK(data);
112 unsigned length = data->length();
113 if (!length) {
114 exceptionState.throwDOMException(IndexSizeError,
115 "The input data has a zero byte length.");
116 return false;
117 }
118 if (length % 4) {
119 exceptionState.throwDOMException(
120 IndexSizeError, "The input data byte length is not a multiple of 4.");
121 return false;
122 }
123 length /= 4;
124 if (length % width) {
125 exceptionState.throwDOMException(
126 IndexSizeError,
127 "The input data byte length is not a multiple of (4 * width).");
128 return false;
129 }
130 lengthInPixels = length;
131 return true;
225 } 132 }
226 133
227 ImageData* ImageData::create(DOMUint8ClampedArray* data, 134 ImageData* ImageData::create(DOMUint8ClampedArray* data,
228 unsigned width, 135 unsigned width,
229 ExceptionState& exceptionState) { 136 ExceptionState& exceptionState) {
230 if (!ImageData::validateConstructorArguments(kParamData | kParamWidth, 137 unsigned lengthInPixels = 0;
231 nullptr, width, 0, data, nullptr, 138 if (!validateConstructorArguments(data, width, lengthInPixels,
232 &exceptionState)) 139 exceptionState)) {
140 DCHECK(exceptionState.hadException());
233 return nullptr; 141 return nullptr;
234 unsigned height = data->length() / (width * 4); 142 }
143 DCHECK_GT(lengthInPixels, 0u);
144 DCHECK_GT(width, 0u);
145 unsigned height = lengthInPixels / width;
235 return new ImageData(IntSize(width, height), data); 146 return new ImageData(IntSize(width, height), data);
236 } 147 }
237 148
238 ImageData* ImageData::create(DOMUint8ClampedArray* data, 149 ImageData* ImageData::create(DOMUint8ClampedArray* data,
239 unsigned width, 150 unsigned width,
240 unsigned height, 151 unsigned height,
241 ExceptionState& exceptionState) { 152 ExceptionState& exceptionState) {
242 if (!ImageData::validateConstructorArguments( 153 unsigned lengthInPixels = 0;
243 kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, 154 if (!validateConstructorArguments(data, width, lengthInPixels,
244 nullptr, &exceptionState)) 155 exceptionState)) {
156 DCHECK(exceptionState.hadException());
245 return nullptr; 157 return nullptr;
158 }
159 DCHECK_GT(lengthInPixels, 0u);
160 DCHECK_GT(width, 0u);
161 if (height != lengthInPixels / width) {
162 exceptionState.throwDOMException(
163 IndexSizeError,
164 "The input data byte length is not equal to (4 * width * height).");
165 return nullptr;
166 }
246 return new ImageData(IntSize(width, height), data); 167 return new ImageData(IntSize(width, height), data);
247 } 168 }
248 169
249 ImageDataColorSpace ImageData::getImageDataColorSpace(String colorSpaceName) {
250 if (colorSpaceName == kLegacyImageDataColorSpaceName)
251 return kLegacyImageDataColorSpace;
252 if (colorSpaceName == kSRGBImageDataColorSpaceName)
253 return kSRGBImageDataColorSpace;
254 if (colorSpaceName == kLinearRGBImageDataColorSpaceName)
255 return kLinearRGBImageDataColorSpace;
256 NOTREACHED();
257 return kLegacyImageDataColorSpace;
258 }
259
260 String ImageData::getImageDataColorSpaceName(ImageDataColorSpace colorSpace) {
261 switch (colorSpace) {
262 case kLegacyImageDataColorSpace:
263 return kLegacyImageDataColorSpaceName;
264 case kSRGBImageDataColorSpace:
265 return kSRGBImageDataColorSpaceName;
266 case kLinearRGBImageDataColorSpace:
267 return kLinearRGBImageDataColorSpaceName;
268 }
269 NOTREACHED();
270 return String();
271 }
272
273 ImageData* ImageData::createImageData(unsigned width,
274 unsigned height,
275 String colorSpace,
276 ExceptionState& exceptionState) {
277 if (!ImageData::validateConstructorArguments(
278 kParamWidth | kParamHeight | kParamColorSpace, nullptr, width, height,
279 nullptr, &colorSpace, &exceptionState))
280 return nullptr;
281
282 DOMUint8ClampedArray* byteArray =
283 ImageData::allocateAndValidateUint8ClampedArray(4 * width * height,
284 &exceptionState);
285 return byteArray
286 ? new ImageData(IntSize(width, height), byteArray, colorSpace)
287 : nullptr;
288 }
289
290 ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
291 unsigned width,
292 String colorSpace,
293 ExceptionState& exceptionState) {
294 if (!ImageData::validateConstructorArguments(
295 kParamData | kParamWidth | kParamColorSpace, nullptr, width, 0, data,
296 &colorSpace, &exceptionState))
297 return nullptr;
298 unsigned height = data->length() / (width * 4);
299 return new ImageData(IntSize(width, height), data, colorSpace);
300 }
301
302 ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
303 unsigned width,
304 unsigned height,
305 String colorSpace,
306 ExceptionState& exceptionState) {
307 if (!ImageData::validateConstructorArguments(
308 kParamData | kParamWidth | kParamHeight | kParamColorSpace, nullptr,
309 width, height, data, &colorSpace, &exceptionState))
310 return nullptr;
311 return new ImageData(IntSize(width, height), data, colorSpace);
312 }
313
314 // TODO(zakerinasab): Fix this when ImageBitmap color correction code is landed.
315 // Tip: If the source Image Data has a color space, createImageBitmap must
316 // respect this color space even when no color space tag is passed to it.
317 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, 170 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState,
318 EventTarget& eventTarget, 171 EventTarget& eventTarget,
319 Optional<IntRect> cropRect, 172 Optional<IntRect> cropRect,
320 const ImageBitmapOptions& options, 173 const ImageBitmapOptions& options,
321 ExceptionState& exceptionState) { 174 ExceptionState& exceptionState) {
322 if ((cropRect && 175 if ((cropRect &&
323 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(), 176 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(),
324 exceptionState)) || 177 exceptionState)) ||
325 !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(), 178 !ImageBitmap::isSourceSizeValid(bitmapSourceSize().width(),
326 bitmapSourceSize().height(), 179 bitmapSourceSize().height(),
(...skipping 24 matching lines...) Expand all
351 v8::Local<v8::Value> pixelArray = ToV8(m_data.get(), wrapper, isolate); 204 v8::Local<v8::Value> pixelArray = ToV8(m_data.get(), wrapper, isolate);
352 if (pixelArray.IsEmpty() || 205 if (pixelArray.IsEmpty() ||
353 !v8CallBoolean(wrapper->DefineOwnProperty( 206 !v8CallBoolean(wrapper->DefineOwnProperty(
354 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"), 207 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"),
355 pixelArray, v8::ReadOnly))) 208 pixelArray, v8::ReadOnly)))
356 return v8::Local<v8::Object>(); 209 return v8::Local<v8::Object>();
357 } 210 }
358 return wrapper; 211 return wrapper;
359 } 212 }
360 213
361 ImageData::ImageData(const IntSize& size, 214 ImageData::ImageData(const IntSize& size, DOMUint8ClampedArray* byteArray)
362 DOMUint8ClampedArray* byteArray, 215 : m_size(size), m_data(byteArray) {
363 String colorSpaceName)
364 : m_size(size),
365 m_colorSpace(getImageDataColorSpace(colorSpaceName)),
366 m_data(byteArray) {
367 DCHECK_GE(size.width(), 0); 216 DCHECK_GE(size.width(), 0);
368 DCHECK_GE(size.height(), 0); 217 DCHECK_GE(size.height(), 0);
369 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <= 218 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
370 m_data->length()); 219 m_data->length());
371 } 220 }
372 221
373 } // namespace blink 222 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageData.h ('k') | third_party/WebKit/Source/core/html/ImageData.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698