Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/Float32ImageData.cpp |
| diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/Float32ImageData.cpp |
| similarity index 51% |
| copy from third_party/WebKit/Source/core/html/ImageData.cpp |
| copy to third_party/WebKit/Source/core/html/Float32ImageData.cpp |
| index 32726d5aef74e76fa1f9a1d4a83ba2c63ad13014..f676c105c4f1a2e87c41934aa521455db0856844 100644 |
| --- a/third_party/WebKit/Source/core/html/ImageData.cpp |
| +++ b/third_party/WebKit/Source/core/html/Float32ImageData.cpp |
| @@ -26,10 +26,10 @@ |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| -#include "core/html/ImageData.h" |
| +#include "core/html/Float32ImageData.h" |
| #include "bindings/core/v8/ExceptionState.h" |
| -#include "bindings/core/v8/V8Uint8ClampedArray.h" |
| +#include "bindings/core/v8/V8Float32Array.h" |
| #include "core/dom/ExceptionCode.h" |
| #include "core/frame/ImageBitmap.h" |
| #include "core/imagebitmap/ImageBitmapOptions.h" |
| @@ -38,24 +38,24 @@ |
| namespace blink { |
| -ImageData* ImageData::create(const IntSize& size) { |
| - CheckedNumeric<unsigned> dataSize = 4; |
| +Float32ImageData* Float32ImageData::create(const IntSize& size) { |
| + CheckedNumeric<unsigned> dataSize = 8; |
|
Justin Novosad
2016/12/08 18:16:34
This should be 16. Even better, write it as 4*siz
zakerinasab
2016/12/08 20:40:51
No, it should be 4 as RGBA has four elements. Fixe
|
| dataSize *= size.width(); |
| dataSize *= size.height(); |
| if (!dataSize.IsValid()) |
| return nullptr; |
| - DOMUint8ClampedArray* byteArray = |
| - DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); |
| + DOMFloat32Array* byteArray = |
| + DOMFloat32Array::createOrNull(dataSize.ValueOrDie()); |
| if (!byteArray) |
| return nullptr; |
| - return new ImageData(size, byteArray); |
| + return new Float32ImageData(size, byteArray); |
| } |
| -ImageData* ImageData::create(const IntSize& size, |
| - DOMUint8ClampedArray* byteArray) { |
| - CheckedNumeric<unsigned> dataSize = 4; |
| +Float32ImageData* Float32ImageData::create(const IntSize& size, |
| + DOMFloat32Array* byteArray) { |
| + CheckedNumeric<unsigned> dataSize = 8; |
| dataSize *= size.width(); |
| dataSize *= size.height(); |
| if (!dataSize.IsValid()) |
| @@ -64,12 +64,12 @@ ImageData* ImageData::create(const IntSize& size, |
| if (!dataSize.IsValid() || dataSize.ValueOrDie() > byteArray->length()) |
| return nullptr; |
| - return new ImageData(size, byteArray); |
| + return new Float32ImageData(size, byteArray); |
| } |
| -ImageData* ImageData::create(unsigned width, |
| - unsigned height, |
| - ExceptionState& exceptionState) { |
| +Float32ImageData* Float32ImageData::create(unsigned width, |
| + unsigned height, |
| + ExceptionState& exceptionState) { |
| if (!width || !height) { |
| exceptionState.throwDOMException( |
| IndexSizeError, String::format("The source %s is zero or not a number.", |
| @@ -77,7 +77,7 @@ ImageData* ImageData::create(unsigned width, |
| return nullptr; |
| } |
| - CheckedNumeric<unsigned> dataSize = 4; |
| + CheckedNumeric<unsigned> dataSize = 8; |
|
Justin Novosad
2016/12/08 18:16:34
oops
zakerinasab
2016/12/08 20:40:51
No, it should be 4 as RGBA has four elements. Fixe
|
| dataSize *= width; |
| dataSize *= height; |
| if (!dataSize.IsValid() || static_cast<int>(width) < 0 || |
| @@ -88,21 +88,55 @@ ImageData* ImageData::create(unsigned width, |
| return nullptr; |
| } |
| - DOMUint8ClampedArray* byteArray = |
| - DOMUint8ClampedArray::createOrNull(dataSize.ValueOrDie()); |
| + DOMFloat32Array* byteArray = |
| + DOMFloat32Array::createOrNull(dataSize.ValueOrDie()); |
| if (!byteArray) { |
| - exceptionState.throwDOMException(V8Error, |
| - "Out of memory at ImageData creation"); |
| + exceptionState.throwDOMException( |
| + V8Error, "Out of memory at Float32ImageData creation"); |
| return nullptr; |
| } |
| - return new ImageData(IntSize(width, height), byteArray); |
| + return new Float32ImageData(IntSize(width, height), byteArray); |
| } |
| -bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data, |
| - unsigned width, |
| - unsigned& lengthInPixels, |
| - ExceptionState& exceptionState) { |
| +Float32ImageData* Float32ImageData::create(unsigned width, |
| + unsigned height, |
| + String colorSpace, |
| + ExceptionState& exceptionState) { |
| + if (!width || !height) { |
| + exceptionState.throwDOMException( |
| + IndexSizeError, String::format("The source %s is zero or not a number.", |
| + width ? "height" : "width")); |
| + return nullptr; |
| + } |
| + |
| + CheckedNumeric<unsigned> dataSize = 8; |
|
Justin Novosad
2016/12/08 18:16:34
oops
zakerinasab
2016/12/08 20:40:51
No, it should be 4 as RGBA has four elements. Fixe
|
| + dataSize *= width; |
| + dataSize *= height; |
| + if (!dataSize.IsValid() || static_cast<int>(width) < 0 || |
| + static_cast<int>(height) < 0) { |
| + exceptionState.throwDOMException( |
| + IndexSizeError, |
| + "The requested image size exceeds the supported range."); |
| + return nullptr; |
| + } |
| + |
| + DOMFloat32Array* byteArray = |
| + DOMFloat32Array::createOrNull(dataSize.ValueOrDie()); |
| + if (!byteArray) { |
| + exceptionState.throwDOMException( |
| + V8Error, "Out of memory at Float32ImageData creation"); |
| + return nullptr; |
| + } |
| + |
| + return new Float32ImageData(IntSize(width, height), byteArray, colorSpace); |
| +} |
| + |
| +bool Float32ImageData::validateConstructorArguments( |
| + DOMFloat32Array* data, |
| + unsigned width, |
| + unsigned& lengthInPixels, |
| + ExceptionState& exceptionState) { |
| if (!width) { |
| exceptionState.throwDOMException( |
| IndexSizeError, "The source width is zero or not a number."); |
| @@ -115,25 +149,41 @@ bool ImageData::validateConstructorArguments(DOMUint8ClampedArray* data, |
| "The input data has a zero byte length."); |
| return false; |
| } |
| - if (length % 4) { |
| + if (length % 8) { |
| exceptionState.throwDOMException( |
| - IndexSizeError, "The input data byte length is not a multiple of 4."); |
| + IndexSizeError, "The input data byte length is not a multiple of 8."); |
| return false; |
| } |
| - length /= 4; |
| + length /= 8; |
| if (length % width) { |
| exceptionState.throwDOMException( |
| IndexSizeError, |
| - "The input data byte length is not a multiple of (4 * width)."); |
| + "The input data byte length is not a multiple of (8 * width)."); |
| return false; |
| } |
| lengthInPixels = length; |
| return true; |
| } |
| -ImageData* ImageData::create(DOMUint8ClampedArray* data, |
| - unsigned width, |
| - ExceptionState& exceptionState) { |
| +bool Float32ImageData::validateConstructorArguments( |
| + DOMFloat32Array* data, |
| + unsigned width, |
| + unsigned& lengthInPixels, |
| + String colorSpace, |
| + ExceptionState& exceptionState) { |
| + if (colorSpace != kLinearRGBImageDataColorSpaceName) { |
| + exceptionState.throwDOMException(NotSupportedError, |
| + "The input color space is not supported " |
| + "in Float32Array-backed image data."); |
| + return false; |
| + } |
| + return validateConstructorArguments(data, width, lengthInPixels, |
| + exceptionState); |
| +} |
| + |
| +Float32ImageData* Float32ImageData::create(DOMFloat32Array* data, |
| + unsigned width, |
| + ExceptionState& exceptionState) { |
| unsigned lengthInPixels = 0; |
| if (!validateConstructorArguments(data, width, lengthInPixels, |
| exceptionState)) { |
| @@ -143,13 +193,13 @@ ImageData* ImageData::create(DOMUint8ClampedArray* data, |
| DCHECK_GT(lengthInPixels, 0u); |
| DCHECK_GT(width, 0u); |
| unsigned height = lengthInPixels / width; |
| - return new ImageData(IntSize(width, height), data); |
| + return new Float32ImageData(IntSize(width, height), data); |
| } |
| -ImageData* ImageData::create(DOMUint8ClampedArray* data, |
| - unsigned width, |
| - unsigned height, |
| - ExceptionState& exceptionState) { |
| +Float32ImageData* Float32ImageData::create(DOMFloat32Array* data, |
| + unsigned width, |
| + unsigned height, |
| + ExceptionState& exceptionState) { |
| unsigned lengthInPixels = 0; |
| if (!validateConstructorArguments(data, width, lengthInPixels, |
| exceptionState)) { |
| @@ -161,17 +211,43 @@ ImageData* ImageData::create(DOMUint8ClampedArray* data, |
| if (height != lengthInPixels / width) { |
| exceptionState.throwDOMException( |
| IndexSizeError, |
| - "The input data byte length is not equal to (4 * width * height)."); |
| + "The input data byte length is not equal to (8 * width * height)."); |
|
Justin Novosad
2016/12/08 18:16:34
16
zakerinasab
2016/12/08 20:40:51
No, it should be 4 as RGBA has four elements. Fixe
|
| return nullptr; |
| } |
| - return new ImageData(IntSize(width, height), data); |
| + return new Float32ImageData(IntSize(width, height), data); |
| } |
| -ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, |
| - EventTarget& eventTarget, |
| - Optional<IntRect> cropRect, |
| - const ImageBitmapOptions& options, |
| +Float32ImageData* Float32ImageData::create(DOMFloat32Array* data, |
| + unsigned width, |
| + unsigned height, |
| + String colorSpace, |
| ExceptionState& exceptionState) { |
| + unsigned lengthInPixels = 0; |
| + if (!validateConstructorArguments(data, width, lengthInPixels, colorSpace, |
| + exceptionState)) { |
| + DCHECK(exceptionState.hadException()); |
| + return nullptr; |
| + } |
| + DCHECK_GT(lengthInPixels, 0u); |
| + DCHECK_GT(width, 0u); |
| + if (height != lengthInPixels / width) { |
| + exceptionState.throwDOMException( |
| + IndexSizeError, |
| + "The input data byte length is not equal to (8 * width * height)."); |
|
Justin Novosad
2016/12/08 18:16:34
16
zakerinasab
2016/12/08 20:40:51
No, it should be 4 as RGBA has four elements. Fixe
|
| + return nullptr; |
| + } |
| + return new Float32ImageData(IntSize(width, height), data, colorSpace); |
| +} |
| + |
| +// TODO(zakerinasab): Fix this when ImageBitmap color correction code is landed. |
| +// Tip: If the source Image Data has a color space, createImageBitmap must |
| +// respect this color space even when no color space tag is passed to it. |
| +ScriptPromise Float32ImageData::createImageBitmap( |
| + ScriptState* scriptState, |
| + EventTarget& eventTarget, |
| + Optional<IntRect> cropRect, |
| + const ImageBitmapOptions& options, |
| + ExceptionState& exceptionState) { |
| if ((cropRect && |
| !ImageBitmap::isSourceSizeValid(cropRect->width(), cropRect->height(), |
| exceptionState)) || |
| @@ -190,7 +266,7 @@ ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState, |
| scriptState, ImageBitmap::create(this, cropRect, options)); |
| } |
| -v8::Local<v8::Object> ImageData::associateWithWrapper( |
| +v8::Local<v8::Object> Float32ImageData::associateWithWrapper( |
| v8::Isolate* isolate, |
| const WrapperTypeInfo* wrapperType, |
| v8::Local<v8::Object> wrapper) { |
| @@ -198,8 +274,8 @@ v8::Local<v8::Object> ImageData::associateWithWrapper( |
| ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper); |
| if (!wrapper.IsEmpty() && m_data.get()) { |
| - // Create a V8 Uint8ClampedArray object and set the "data" property |
| - // of the ImageData object to the created v8 object, eliminating the |
| + // Create a V8 Float32Array object and set the "data" property |
| + // of the Float32ImageData object to the created v8 object, eliminating the |
| // C++ callback when accessing the "data" property. |
| v8::Local<v8::Value> pixelArray = toV8(m_data.get(), wrapper, isolate); |
| if (pixelArray.IsEmpty() || |
| @@ -211,11 +287,13 @@ v8::Local<v8::Object> ImageData::associateWithWrapper( |
| return wrapper; |
| } |
| -ImageData::ImageData(const IntSize& size, DOMUint8ClampedArray* byteArray) |
| - : m_size(size), m_data(byteArray) { |
| +Float32ImageData::Float32ImageData(const IntSize& size, |
| + DOMFloat32Array* byteArray, |
| + String colorSpace) |
| + : m_size(size), m_colorSpace(colorSpace), m_data(byteArray) { |
| DCHECK_GE(size.width(), 0); |
| DCHECK_GE(size.height(), 0); |
| - SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <= |
| + SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 8) <= |
| m_data->length()); |
| } |