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

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

Issue 2728373004: Remove Float32ImageData and update ImageData for color management (Closed)
Patch Set: Addressing comments Created 3 years, 9 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 20 matching lines...) Expand all
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 "platform/graphics/ColorBehavior.h" 37 #include "platform/graphics/ColorBehavior.h"
38 38
39 namespace blink { 39 namespace blink {
40 40
41 bool RaiseDOMExceptionAndReturnFalse(ExceptionState* exceptionState,
42 ExceptionCode exceptionCode,
43 const char* message) {
44 if (exceptionState)
45 exceptionState->throwDOMException(exceptionCode, message);
46 return false;
47 }
48
41 bool ImageData::validateConstructorArguments(const unsigned& paramFlags, 49 bool ImageData::validateConstructorArguments(const unsigned& paramFlags,
42 const IntSize* size, 50 const IntSize* size,
43 const unsigned& width, 51 const unsigned& width,
44 const unsigned& height, 52 const unsigned& height,
45 const DOMArrayBufferView* data, 53 const DOMArrayBufferView* data,
46 const String* colorSpace, 54 ExceptionState* exceptionState) {
47 ExceptionState* exceptionState, 55 // We accept all the combinations of colorSpace and storageFormat in an
48 ImageDataType imageDataType) { 56 // ImageDataColorSettings to be stored in an ImageData. Therefore, we don't
49 if (paramFlags & kParamData) { 57 // check the color settings in this function.
50 if (data->type() != DOMArrayBufferView::ViewType::TypeUint8Clamped && 58
51 data->type() != DOMArrayBufferView::ViewType::TypeFloat32) 59 if ((paramFlags & kParamWidth) && !width) {
52 return false; 60 return RaiseDOMExceptionAndReturnFalse(
53 if (data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped && 61 exceptionState, IndexSizeError,
54 imageDataType != kUint8ClampedImageData) 62 "The source width is zero or not a number.");
55 imageDataType = kFloat32ImageData;
56 } 63 }
57 64
58 // ImageData::create parameters without ExceptionState 65 if ((paramFlags & kParamHeight) && !height) {
66 return RaiseDOMExceptionAndReturnFalse(
67 exceptionState, IndexSizeError,
68 "The source height is zero or not a number.");
69 }
70
71 if (paramFlags & (kParamWidth | kParamHeight)) {
72 CheckedNumeric<unsigned> dataSize = 4;
73 dataSize *= width;
74 dataSize *= height;
75 if (!dataSize.IsValid())
76 return RaiseDOMExceptionAndReturnFalse(
77 exceptionState, IndexSizeError,
78 "The requested image size exceeds the supported range.");
79 }
80
81 unsigned dataLength = 0;
82 if (paramFlags & kParamData) {
83 DCHECK(data);
84 switch (data->type()) {
85 case DOMArrayBufferView::ViewType::TypeUint8Clamped:
86 dataLength = data->view()->byteLength();
87 break;
88 case DOMArrayBufferView::ViewType::TypeUint16:
89 dataLength = data->view()->byteLength() / 2;
90 break;
91 case DOMArrayBufferView::ViewType::TypeFloat32:
92 dataLength = data->view()->byteLength() / 4;
93 break;
94 default:
95 return RaiseDOMExceptionAndReturnFalse(
96 exceptionState, NotSupportedError,
97 "The input data type is not supported.");
98 }
99
100 if (!dataLength) {
101 return RaiseDOMExceptionAndReturnFalse(
102 exceptionState, IndexSizeError, "The input data has zero elements.");
103 }
104
105 if (dataLength % 4) {
106 return RaiseDOMExceptionAndReturnFalse(
107 exceptionState, IndexSizeError,
108 "The input data length is not a multiple of 4.");
109 }
110
111 if ((paramFlags & kParamWidth) && (dataLength / 4) % width) {
112 return RaiseDOMExceptionAndReturnFalse(
113 exceptionState, IndexSizeError,
114 "The input data length is not a multiple of (4 * width).");
115 }
116
117 if ((paramFlags & kParamHeight & kParamWidth) &&
118 height != dataLength / (4 * width))
119 return RaiseDOMExceptionAndReturnFalse(
120 exceptionState, IndexSizeError,
121 "The input data length is not equal to (4 * width * height).");
122 }
123
59 if (paramFlags & kParamSize) { 124 if (paramFlags & kParamSize) {
60 if (!size->width() || !size->height()) 125 if (!size->width() || !size->height())
61 return false; 126 return false;
62 CheckedNumeric<unsigned> dataSize = 4; 127 CheckedNumeric<unsigned> dataSize = 4;
63 dataSize *= size->width(); 128 dataSize *= size->width();
64 dataSize *= size->height(); 129 dataSize *= size->height();
65 if (!dataSize.IsValid()) 130 if (!dataSize.IsValid())
66 return false; 131 return false;
67 if (paramFlags & kParamData) { 132 if (paramFlags & kParamData) {
68 DCHECK(data); 133 if (dataSize.ValueOrDie() > dataLength)
69 unsigned length =
70 data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
71 ? (const_cast<DOMUint8ClampedArray*>(
72 static_cast<const DOMUint8ClampedArray*>(data)))
73 ->length()
74 : (const_cast<DOMFloat32Array*>(
75 static_cast<const DOMFloat32Array*>(data)))
76 ->length();
77 if (dataSize.ValueOrDie() > length)
78 return false; 134 return false;
79 } 135 }
80 return true;
81 } 136 }
82 137
83 // ImageData::create parameters with ExceptionState
84 if ((paramFlags & kParamWidth) && !width) {
85 exceptionState->throwDOMException(
86 IndexSizeError, "The source width is zero or not a number.");
87 return false;
88 }
89 if ((paramFlags & kParamHeight) && !height) {
90 exceptionState->throwDOMException(
91 IndexSizeError, "The source height is zero or not a number.");
92 return false;
93 }
94 if (paramFlags & (kParamWidth | kParamHeight)) {
95 CheckedNumeric<unsigned> dataSize = 4;
96 dataSize *= width;
97 dataSize *= height;
98 if (!dataSize.IsValid()) {
99 exceptionState->throwDOMException(
100 IndexSizeError,
101 "The requested image size exceeds the supported range.");
102 return false;
103 }
104 }
105 if (paramFlags & kParamData) {
106 DCHECK(data);
107 unsigned length =
108 data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
109 ? (const_cast<DOMUint8ClampedArray*>(
110 static_cast<const DOMUint8ClampedArray*>(data)))
111 ->length()
112 : (const_cast<DOMFloat32Array*>(
113 static_cast<const DOMFloat32Array*>(data)))
114 ->length();
115 if (!length) {
116 exceptionState->throwDOMException(IndexSizeError,
117 "The input data has zero elements.");
118 return false;
119 }
120 if (length % 4) {
121 exceptionState->throwDOMException(
122 IndexSizeError, "The input data length is not a multiple of 4.");
123 return false;
124 }
125 length /= 4;
126 if (length % width) {
127 exceptionState->throwDOMException(
128 IndexSizeError,
129 "The input data length is not a multiple of (4 * width).");
130 return false;
131 }
132 if ((paramFlags & kParamHeight) && height != length / width) {
133 exceptionState->throwDOMException(
134 IndexSizeError,
135 "The input data length is not equal to (4 * width * height).");
136 return false;
137 }
138 }
139 if (paramFlags & kParamColorSpace) {
140 if (!colorSpace || colorSpace->length() == 0) {
141 exceptionState->throwDOMException(
142 NotSupportedError, "The source color space is not defined.");
143 return false;
144 }
145 if (imageDataType == kUint8ClampedImageData &&
146 *colorSpace != kLegacyImageDataColorSpaceName &&
147 *colorSpace != kSRGBImageDataColorSpaceName) {
148 exceptionState->throwDOMException(NotSupportedError,
149 "The input color space is not "
150 "supported in "
151 "Uint8ClampedArray-backed ImageData.");
152 return false;
153 }
154 if (imageDataType == kFloat32ImageData &&
155 *colorSpace != kLinearRGBImageDataColorSpaceName) {
156 exceptionState->throwDOMException(NotSupportedError,
157 "The input color space is not "
158 "supported in "
159 "Float32Array-backed ImageData.");
160 return false;
161 }
162 }
163 return true; 138 return true;
164 } 139 }
165 140
166 DOMUint8ClampedArray* ImageData::allocateAndValidateUint8ClampedArray( 141 DOMArrayBufferView* ImageData::allocateAndValidateDataArray(
167 const unsigned& length, 142 const unsigned& length,
143 ImageDataStorageFormat storageFormat,
168 ExceptionState* exceptionState) { 144 ExceptionState* exceptionState) {
169 if (!length) 145 if (!length)
170 return nullptr; 146 return nullptr;
171 DOMUint8ClampedArray* dataArray = DOMUint8ClampedArray::createOrNull(length); 147
172 if (!dataArray || length != dataArray->length()) { 148 DOMArrayBufferView* dataArray = nullptr;
173 if (exceptionState) { 149 unsigned dataLength = 0;
150 switch (storageFormat) {
151 case kUint8ClampedArrayStorageFormat:
152 dataArray = DOMUint8ClampedArray::createOrNull(length);
153 dataLength = dataArray->view()->byteLength();
154 break;
155 case kUint16ArrayStorageFormat:
156 dataArray = DOMUint16Array::createOrNull(length);
157 dataLength = dataArray->view()->byteLength() / 2;
158 break;
159 case kFloat32ArrayStorageFormat:
160 dataArray = DOMFloat32Array::createOrNull(length);
161 dataLength = dataArray->view()->byteLength() / 4;
162 break;
163 default:
164 NOTREACHED();
165 }
166
167 if (!dataArray || length != dataLength) {
168 if (exceptionState)
174 exceptionState->throwDOMException(V8RangeError, 169 exceptionState->throwDOMException(V8RangeError,
175 "Out of memory at ImageData creation"); 170 "Out of memory at ImageData creation");
176 }
177 return nullptr; 171 return nullptr;
178 } 172 }
173
179 return dataArray; 174 return dataArray;
180 } 175 }
181 176
182 ImageData* ImageData::create(const IntSize& size) { 177 ImageData* ImageData::create(const IntSize& size) {
183 if (!ImageData::validateConstructorArguments(kParamSize, &size)) 178 if (!ImageData::validateConstructorArguments(kParamSize, &size))
184 return nullptr; 179 return nullptr;
185 DOMUint8ClampedArray* byteArray = 180 DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
186 ImageData::allocateAndValidateUint8ClampedArray(4 * size.width() * 181 4 * size.width() * size.height(), kUint8ClampedArrayStorageFormat);
187 size.height());
188 if (!byteArray)
189 return nullptr;
190 return new ImageData(size, byteArray); 182 return new ImageData(size, byteArray);
191 } 183 }
192 184
193 // This function accepts size (0, 0). 185 // This function accepts size (0, 0) and always returns the ImageData in
186 // "srgb" color space and "uint8" storage format.
194 ImageData* ImageData::createForTest(const IntSize& size) { 187 ImageData* ImageData::createForTest(const IntSize& size) {
195 CheckedNumeric<unsigned> dataSize = 4; 188 CheckedNumeric<unsigned> dataSize = 4;
196 dataSize *= size.width(); 189 dataSize *= size.width();
197 dataSize *= size.height(); 190 dataSize *= size.height();
198 if (!dataSize.IsValid()) 191 if (!dataSize.IsValid())
199 return nullptr; 192 return nullptr;
200 193
201 DOMUint8ClampedArray* byteArray = 194 DOMUint8ClampedArray* byteArray =
202 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); 195 DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie());
203 if (!byteArray) 196 if (!byteArray)
204 return nullptr; 197 return nullptr;
205 198
206 return new ImageData(size, byteArray); 199 return new ImageData(size, byteArray);
207 } 200 }
208 201
209 ImageData* ImageData::create(const IntSize& size, 202 ImageData* ImageData::create(const IntSize& size,
210 DOMUint8ClampedArray* byteArray) { 203 DOMUint8ClampedArray* byteArray) {
211 if (!ImageData::validateConstructorArguments(kParamSize | kParamData, &size, 204 if (!ImageData::validateConstructorArguments(kParamSize | kParamData, &size,
212 0, 0, byteArray)) 205 0, 0, byteArray))
213 return nullptr; 206 return nullptr;
207
214 return new ImageData(size, byteArray); 208 return new ImageData(size, byteArray);
215 } 209 }
216 210
217 ImageData* ImageData::create(const IntSize& size,
218 DOMUint8ClampedArray* byteArray,
219 const String& colorSpace) {
220 if (!ImageData::validateConstructorArguments(
221 kParamSize | kParamData | kParamColorSpace, &size, 0, 0, byteArray,
222 &colorSpace))
223 return nullptr;
224 return new ImageData(size, byteArray, colorSpace);
225 }
226
227 ImageData* ImageData::create(unsigned width, 211 ImageData* ImageData::create(unsigned width,
228 unsigned height, 212 unsigned height,
229 ExceptionState& exceptionState) { 213 ExceptionState& exceptionState) {
230 if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight, 214 if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
231 nullptr, width, height, nullptr, 215 nullptr, width, height, nullptr,
232 nullptr, &exceptionState)) 216 &exceptionState))
233 return nullptr; 217 return nullptr;
234 DOMUint8ClampedArray* byteArray = 218
235 ImageData::allocateAndValidateUint8ClampedArray(4 * width * height, 219 DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
236 &exceptionState); 220 4 * width * height, kUint8ClampedArrayStorageFormat, &exceptionState);
237 return byteArray ? new ImageData(IntSize(width, height), byteArray) : nullptr; 221 return byteArray ? new ImageData(IntSize(width, height), byteArray) : nullptr;
238 } 222 }
239 223
240 ImageData* ImageData::create(DOMUint8ClampedArray* data, 224 ImageData* ImageData::create(DOMUint8ClampedArray* data,
241 unsigned width, 225 unsigned width,
242 ExceptionState& exceptionState) { 226 ExceptionState& exceptionState) {
243 if (!ImageData::validateConstructorArguments(kParamData | kParamWidth, 227 if (!ImageData::validateConstructorArguments(
244 nullptr, width, 0, data, nullptr, 228 kParamData | kParamWidth, nullptr, width, 0, data, &exceptionState))
245 &exceptionState))
246 return nullptr; 229 return nullptr;
230
247 unsigned height = data->length() / (width * 4); 231 unsigned height = data->length() / (width * 4);
248 return new ImageData(IntSize(width, height), data); 232 return new ImageData(IntSize(width, height), data);
249 } 233 }
250 234
251 ImageData* ImageData::create(DOMUint8ClampedArray* data, 235 ImageData* ImageData::create(DOMUint8ClampedArray* data,
252 unsigned width, 236 unsigned width,
253 unsigned height, 237 unsigned height,
254 ExceptionState& exceptionState) { 238 ExceptionState& exceptionState) {
255 if (!ImageData::validateConstructorArguments( 239 if (!ImageData::validateConstructorArguments(
256 kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, 240 kParamData | kParamWidth | kParamHeight, nullptr, width, height, data,
257 nullptr, &exceptionState)) 241 &exceptionState))
258 return nullptr; 242 return nullptr;
243
259 return new ImageData(IntSize(width, height), data); 244 return new ImageData(IntSize(width, height), data);
260 } 245 }
261 246
262 ImageData* ImageData::createImageData(unsigned width, 247 ImageData* ImageData::createImageData(
263 unsigned height, 248 unsigned width,
264 String colorSpace, 249 unsigned height,
265 ExceptionState& exceptionState) { 250 const ImageDataColorSettings& colorSettings,
266 if (!ImageData::validateConstructorArguments( 251 ExceptionState& exceptionState) {
267 kParamWidth | kParamHeight | kParamColorSpace, nullptr, width, height, 252 if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
268 nullptr, &colorSpace, &exceptionState)) 253 nullptr, width, height, nullptr,
254 &exceptionState))
269 return nullptr; 255 return nullptr;
270 256
271 DOMUint8ClampedArray* byteArray = 257 ImageDataStorageFormat storageFormat =
272 ImageData::allocateAndValidateUint8ClampedArray(4 * width * height, 258 ImageData::getImageDataStorageFormat(colorSettings.storageFormat());
273 &exceptionState); 259 DOMArrayBufferView* bufferView = allocateAndValidateDataArray(
274 return byteArray 260 4 * width * height, storageFormat, &exceptionState);
275 ? new ImageData(IntSize(width, height), byteArray, colorSpace) 261
276 : nullptr; 262 if (!bufferView)
263 return nullptr;
264
265 return new ImageData(IntSize(width, height), bufferView, &colorSettings);
277 } 266 }
278 267
279 ImageData* ImageData::createImageData(DOMUint8ClampedArray* data, 268 ImageData* ImageData::createImageData(
280 unsigned width, 269 ImageDataArray& data,
281 String colorSpace, 270 unsigned width,
282 ExceptionState& exceptionState) { 271 unsigned height,
272 const ImageDataColorSettings& colorSettings,
273 ExceptionState& exceptionState) {
274 DOMArrayBufferView* bufferView = nullptr;
275 if (data.isUint8ClampedArray())
276 bufferView = data.getAsUint8ClampedArray();
277 else if (data.isUint16Array())
278 bufferView = data.getAsUint16Array();
279 else if (data.isFloat32Array())
280 bufferView = data.getAsFloat32Array();
281 else
282 NOTREACHED();
283
283 if (!ImageData::validateConstructorArguments( 284 if (!ImageData::validateConstructorArguments(
284 kParamData | kParamWidth | kParamColorSpace, nullptr, width, 0, data, 285 kParamData | kParamWidth | kParamHeight, nullptr, width, height,
285 &colorSpace, &exceptionState)) 286 bufferView, &exceptionState))
286 return nullptr; 287 return nullptr;
287 unsigned height = data->length() / (width * 4);
288 return new ImageData(IntSize(width, height), data, colorSpace);
289 }
290 288
291 ImageData* ImageData::createImageData(DOMUint8ClampedArray* data, 289 return new ImageData(IntSize(width, height), bufferView, &colorSettings);
292 unsigned width,
293 unsigned height,
294 String colorSpace,
295 ExceptionState& exceptionState) {
296 if (!ImageData::validateConstructorArguments(
297 kParamData | kParamWidth | kParamHeight | kParamColorSpace, nullptr,
298 width, height, data, &colorSpace, &exceptionState))
299 return nullptr;
300 return new ImageData(IntSize(width, height), data, colorSpace);
301 } 290 }
302 291
303 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, 292 ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState,
304 EventTarget& eventTarget, 293 EventTarget& eventTarget,
305 Optional<IntRect> cropRect, 294 Optional<IntRect> cropRect,
306 const ImageBitmapOptions& options, 295 const ImageBitmapOptions& options,
307 ExceptionState& exceptionState) { 296 ExceptionState& exceptionState) {
308 if ((cropRect && 297 if ((cropRect &&
309 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(), 298 !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(),
310 exceptionState)) || 299 exceptionState)) ||
(...skipping 12 matching lines...) Expand all
323 scriptState, ImageBitmap::create(this, cropRect, options)); 312 scriptState, ImageBitmap::create(this, cropRect, options));
324 } 313 }
325 314
326 v8::Local<v8::Object> ImageData::associateWithWrapper( 315 v8::Local<v8::Object> ImageData::associateWithWrapper(
327 v8::Isolate* isolate, 316 v8::Isolate* isolate,
328 const WrapperTypeInfo* wrapperType, 317 const WrapperTypeInfo* wrapperType,
329 v8::Local<v8::Object> wrapper) { 318 v8::Local<v8::Object> wrapper) {
330 wrapper = 319 wrapper =
331 ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper); 320 ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper);
332 321
333 if (!wrapper.IsEmpty() && m_data.get()) { 322 if (!wrapper.IsEmpty() && m_data) {
334 // Create a V8 Uint8ClampedArray object and set the "data" property 323 // Create a V8 Uint8ClampedArray object and set the "data" property
335 // of the ImageData object to the created v8 object, eliminating the 324 // of the ImageData object to the created v8 object, eliminating the
336 // C++ callback when accessing the "data" property. 325 // C++ callback when accessing the "data" property.
337 v8::Local<v8::Value> pixelArray = ToV8(m_data.get(), wrapper, isolate); 326 v8::Local<v8::Value> pixelArray = ToV8(m_data.get(), wrapper, isolate);
338 if (pixelArray.IsEmpty() || 327 if (pixelArray.IsEmpty() ||
339 !v8CallBoolean(wrapper->DefineOwnProperty( 328 !v8CallBoolean(wrapper->DefineOwnProperty(
340 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"), 329 isolate->GetCurrentContext(), v8AtomicString(isolate, "data"),
341 pixelArray, v8::ReadOnly))) 330 pixelArray, v8::ReadOnly)))
342 return v8::Local<v8::Object>(); 331 return v8::Local<v8::Object>();
343 } 332 }
344 return wrapper; 333 return wrapper;
345 } 334 }
346 335
347 ImageDataColorSpace ImageData::getImageDataColorSpace(String colorSpaceName) { 336 const DOMUint8ClampedArray* ImageData::data() const {
348 if (colorSpaceName == kLegacyImageDataColorSpaceName) 337 if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
349 return kLegacyImageDataColorSpace; 338 return m_data.get();
350 if (colorSpaceName == kSRGBImageDataColorSpaceName)
351 return kSRGBImageDataColorSpace;
352 if (colorSpaceName == kLinearRGBImageDataColorSpaceName)
353 return kLinearRGBImageDataColorSpace;
354 NOTREACHED();
355 return kLegacyImageDataColorSpace;
356 }
357
358 String ImageData::getImageDataColorSpaceName(ImageDataColorSpace colorSpace) {
359 switch (colorSpace) {
360 case kLegacyImageDataColorSpace:
361 return kLegacyImageDataColorSpaceName;
362 case kSRGBImageDataColorSpace:
363 return kSRGBImageDataColorSpaceName;
364 case kLinearRGBImageDataColorSpace:
365 return kLinearRGBImageDataColorSpaceName;
366 }
367 NOTREACHED();
368 return String();
369 }
370
371 sk_sp<SkColorSpace> ImageData::imageDataColorSpaceToSkColorSpace(
372 ImageDataColorSpace colorSpace) {
373 switch (colorSpace) {
374 case kLegacyImageDataColorSpace:
375 return ColorBehavior::globalTargetColorSpace().ToSkColorSpace();
376 case kSRGBImageDataColorSpace:
377 return SkColorSpace::MakeSRGB();
378 case kLinearRGBImageDataColorSpace:
379 return SkColorSpace::MakeSRGBLinear();
380 }
381 NOTREACHED();
382 return nullptr; 339 return nullptr;
383 } 340 }
384 341
342 DOMUint8ClampedArray* ImageData::data() {
343 if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
344 return m_data.get();
345 return nullptr;
346 }
347
348 ImageDataStorageFormat ImageData::getImageDataStorageFormat(
349 const String& storageFormatName) {
350 if (storageFormatName == kUint8ClampedArrayStorageFormatName)
351 return kUint8ClampedArrayStorageFormat;
352 if (storageFormatName == kUint16ArrayStorageFormatName)
353 return kUint16ArrayStorageFormat;
354 if (storageFormatName == kFloat32ArrayStorageFormatName)
355 return kFloat32ArrayStorageFormat;
356 NOTREACHED();
357 return kUint8ClampedArrayStorageFormat;
358 }
359
360 // For ImageData, the color space is only specified by color settings.
361 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
385 sk_sp<SkColorSpace> ImageData::getSkColorSpace() { 362 sk_sp<SkColorSpace> ImageData::getSkColorSpace() {
386 if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() || 363 if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
387 !RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) 364 !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
388 return nullptr; 365 return nullptr;
389 return ImageData::imageDataColorSpaceToSkColorSpace(m_colorSpace); 366
367 return SkColorSpace::MakeSRGB();
368 }
369
370 void ImageData::trace(Visitor* visitor) {
371 visitor->trace(m_data);
372 visitor->trace(m_dataU16);
373 visitor->trace(m_dataF32);
374 visitor->trace(m_dataUnion);
390 } 375 }
391 376
392 ImageData::ImageData(const IntSize& size, 377 ImageData::ImageData(const IntSize& size,
393 DOMUint8ClampedArray* byteArray, 378 DOMArrayBufferView* data,
394 String colorSpaceName) 379 const ImageDataColorSettings* colorSettings)
395 : m_size(size), 380 : m_size(size) {
396 m_colorSpace(getImageDataColorSpace(colorSpaceName)),
397 m_data(byteArray) {
398 DCHECK_GE(size.width(), 0); 381 DCHECK_GE(size.width(), 0);
399 DCHECK_GE(size.height(), 0); 382 DCHECK_GE(size.height(), 0);
400 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <= 383 DCHECK(data);
401 m_data->length()); 384
385 m_data = nullptr;
386 m_dataU16 = nullptr;
387 m_dataF32 = nullptr;
388
389 if (colorSettings) {
390 m_colorSettings.setColorSpace(colorSettings->colorSpace());
391 m_colorSettings.setStorageFormat(colorSettings->storageFormat());
392 }
393
394 ImageDataStorageFormat storageFormat =
395 getImageDataStorageFormat(m_colorSettings.storageFormat());
396
397 switch (storageFormat) {
398 case kUint8ClampedArrayStorageFormat:
399 m_data = const_cast<DOMUint8ClampedArray*>(
400 static_cast<const DOMUint8ClampedArray*>(data));
401 m_dataUnion.setUint8ClampedArray(m_data);
402 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
403 m_data->length());
404 break;
405
406 case kUint16ArrayStorageFormat:
407 m_dataU16 =
408 const_cast<DOMUint16Array*>(static_cast<const DOMUint16Array*>(data));
409 m_dataUnion.setUint16Array(m_dataU16);
410 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
411 m_dataU16->length());
412 break;
413
414 case kFloat32ArrayStorageFormat:
415 m_dataF32 = const_cast<DOMFloat32Array*>(
416 static_cast<const DOMFloat32Array*>(data));
417 m_dataUnion.setFloat32Array(m_dataF32);
418 SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
419 m_dataF32->length());
420 break;
421
422 default:
423 NOTREACHED();
424 }
402 } 425 }
403 426
404 } // namespace blink 427 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698