Chromium Code Reviews| Index: third_party/WebKit/Source/core/html/ImageData.h |
| diff --git a/third_party/WebKit/Source/core/html/ImageData.h b/third_party/WebKit/Source/core/html/ImageData.h |
| index 206671a1b48fba1f7b1937dc4cb78414fcb93f8b..985bd42f670969a4368edfd5c19fc40a9596bed3 100644 |
| --- a/third_party/WebKit/Source/core/html/ImageData.h |
| +++ b/third_party/WebKit/Source/core/html/ImageData.h |
| @@ -36,13 +36,38 @@ |
| #include "platform/geometry/IntRect.h" |
| #include "platform/geometry/IntSize.h" |
| #include "platform/heap/Handle.h" |
| +#include "wtf/CheckedNumeric.h" |
| #include "wtf/Compiler.h" |
| +#include "wtf/text/WTFString.h" |
| namespace blink { |
| class ExceptionState; |
| class ImageBitmapOptions; |
| +enum ConstructorParams { |
| + kParamSize = 1, |
| + kParamWidth = 1 << 1, |
| + kParamHeight = 1 << 2, |
| + kParamData = 1 << 3, |
| + kParamColorSpace = 1 << 4, |
| +}; |
| + |
| +enum ImageDataType { |
| + kUint8ClampedImageData, |
| + kFloat32ImageData, |
| +}; |
| + |
| +enum ImageDataColorSpace { |
| + kLegacyImageDataColorSpace, |
| + kSRGBImageDataColorSpace, |
| + kLinearRGBImageDataColorSpace, |
| +}; |
| + |
| +const char* const kLinearRGBImageDataColorSpaceName = "linear-rgb"; |
| +const char* const kSRGBImageDataColorSpaceName = "srgb"; |
| +const char* const kLegacyImageDataColorSpaceName = "legacy-srgb"; |
| + |
| class CORE_EXPORT ImageData final : public GarbageCollectedFinalized<ImageData>, |
| public ScriptWrappable, |
| public ImageBitmapSource { |
| @@ -60,9 +85,30 @@ class CORE_EXPORT ImageData final : public GarbageCollectedFinalized<ImageData>, |
| unsigned height, |
| ExceptionState&); |
| + static ImageData* createForTest(const IntSize&); |
| + |
| + ImageData* createImageData(unsigned width, |
| + unsigned height, |
| + String colorSpace, |
| + ExceptionState&); |
| + ImageData* createImageData(DOMUint8ClampedArray*, |
| + unsigned width, |
| + String colorSpace, |
| + ExceptionState&); |
| + ImageData* createImageData(DOMUint8ClampedArray*, |
| + unsigned width, |
| + unsigned height, |
| + String colorSpace, |
| + ExceptionState&); |
| + |
| + static ImageDataColorSpace getImageDataColorSpace(String); |
| + static String getImageDataColorSpaceName(ImageDataColorSpace); |
| + |
| IntSize size() const { return m_size; } |
| int width() const { return m_size.width(); } |
| int height() const { return m_size.height(); } |
| + String colorSpace() const { return getImageDataColorSpaceName(m_colorSpace); } |
| + ImageDataColorSpace imageDataColorSpace() { return m_colorSpace; } |
| const DOMUint8ClampedArray* data() const { return m_data.get(); } |
| DOMUint8ClampedArray* data() { return m_data.get(); } |
| @@ -81,18 +127,166 @@ class CORE_EXPORT ImageData final : public GarbageCollectedFinalized<ImageData>, |
| const WrapperTypeInfo*, |
| v8::Local<v8::Object> wrapper) override; |
| - private: |
| - ImageData(const IntSize&, DOMUint8ClampedArray*); |
| + template <typename DataArrayType> |
| + static bool validateConstructorArguments( |
| + const unsigned&, |
| + const IntSize* = nullptr, |
| + const unsigned& = 0, |
| + const unsigned& = 0, |
| + const DataArrayType* = nullptr, |
| + const String* = nullptr, |
| + ExceptionState* = nullptr, |
| + ImageDataType = kUint8ClampedImageData); |
| - static bool validateConstructorArguments(DOMUint8ClampedArray*, |
| - unsigned width, |
| - unsigned&, |
| - ExceptionState&); |
| + template <typename DataArrayType> |
| + static DataArrayType* allocateAndValidateDataArray( |
| + const unsigned&, |
| + ExceptionState* = nullptr, |
| + ImageDataType = kUint8ClampedImageData); |
| + |
| + private: |
| + ImageData(const IntSize&, |
| + DOMUint8ClampedArray*, |
| + String = kLegacyImageDataColorSpaceName); |
| IntSize m_size; |
| + ImageDataColorSpace m_colorSpace; |
| Member<DOMUint8ClampedArray> m_data; |
| + |
| + static bool validateConstructorArguments( |
| + const unsigned&, |
| + const IntSize* = nullptr, |
| + const unsigned& = 0, |
| + const unsigned& = 0, |
| + const DOMUint8ClampedArray* = nullptr, |
| + const String* = nullptr, |
| + ExceptionState* = nullptr); |
| + |
| + static DOMUint8ClampedArray* allocateAndValidateUint8ClampedArray( |
| + const unsigned&, |
| + ExceptionState* = nullptr); |
| }; |
| +template <typename DataArrayType> |
| +bool ImageData::validateConstructorArguments(const unsigned& paramFlags, |
|
Justin Novosad
2016/12/16 18:38:11
Would be more efficient not to write this method a
zakerinasab1
2016/12/19 19:57:39
Done.
|
| + const IntSize* size, |
| + const unsigned& width, |
| + const unsigned& height, |
| + const DataArrayType* data, |
| + const String* colorSpace, |
| + ExceptionState* exceptionState, |
| + ImageDataType imageDataType) { |
| + // ImageData::create parameters without ExceptionState |
| + if (paramFlags & kParamSize) { |
| + if (!size->width() || !size->height()) |
| + return false; |
| + if (paramFlags & kParamData) { |
| + DCHECK(data); |
| + CheckedNumeric<unsigned> dataSize = 4; |
| + dataSize *= size->width(); |
| + dataSize *= size->height(); |
| + if (!dataSize.IsValid() || dataSize.ValueOrDie() > data->length()) |
| + return false; |
| + } |
| + return true; |
| + } |
| + |
| + // ImageData::create parameters with ExceptionState |
| + if ((paramFlags & kParamWidth) && !width) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, "The source width is zero or not a number."); |
| + return false; |
| + } |
| + if ((paramFlags & kParamHeight) && !height) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, "The source height is zero or not a number."); |
| + return false; |
| + } |
| + if (paramFlags & (kParamWidth | kParamHeight)) { |
| + CheckedNumeric<unsigned> dataSize = 4; |
| + dataSize *= width; |
| + dataSize *= height; |
| + if (!dataSize.IsValid()) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, |
| + "The requested image size exceeds the supported range."); |
| + return false; |
| + } |
| + } |
| + if (paramFlags & kParamData) { |
| + DCHECK(data); |
| + unsigned length = data->length(); |
| + if (!length) { |
| + exceptionState->throwDOMException(IndexSizeError, |
| + "The input data has zero elements."); |
| + return false; |
| + } |
| + if (length % 4) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, "The input data length is not a multiple of 4."); |
| + return false; |
| + } |
| + length /= 4; |
| + if (length % width) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, |
| + "The input data length is not a multiple of (4 * width)."); |
| + return false; |
| + } |
| + if ((paramFlags & kParamHeight) && height != length / width) { |
| + exceptionState->throwDOMException( |
| + IndexSizeError, |
| + "The input data length is not equal to (4 * width * height)."); |
| + return false; |
| + } |
| + } |
| + if (paramFlags & kParamColorSpace) { |
| + if (!colorSpace || colorSpace->length() == 0) { |
| + exceptionState->throwDOMException( |
| + NotSupportedError, "The source color space is not defined."); |
| + return false; |
| + } |
| + if (imageDataType == kUint8ClampedImageData && |
| + *colorSpace != kLegacyImageDataColorSpaceName && |
| + *colorSpace != kSRGBImageDataColorSpaceName) { |
| + exceptionState->throwDOMException(NotSupportedError, |
| + "The input color space is not " |
| + "supported in " |
| + "Uint8ClampedArray-backed ImageData."); |
| + return false; |
| + } |
| + if (imageDataType == kFloat32ImageData && |
| + *colorSpace != kLinearRGBImageDataColorSpaceName) { |
| + exceptionState->throwDOMException(NotSupportedError, |
| + "The input color space is not " |
| + "supported in " |
| + "Float32Array-backed ImageData."); |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +template <typename DataArrayType> |
| +DataArrayType* ImageData::allocateAndValidateDataArray( |
| + const unsigned& length, |
| + ExceptionState* exceptionState, |
| + ImageDataType imageDataType) { |
| + if (!length) |
| + return nullptr; |
| + DataArrayType* dataArray = DataArrayType::createOrNull(length); |
| + if (!dataArray || length != dataArray->length()) { |
| + if (exceptionState) { |
| + exceptionState->throwDOMException( |
| + V8RangeError, imageDataType == kUint8ClampedImageData |
| + ? "Out of memory at ImageData creation" |
| + : "Out of memory at Float32ImageData creation"); |
| + } |
| + return nullptr; |
| + } |
| + return dataArray; |
| +} |
| + |
| } // namespace blink |
| #endif // ImageData_h |