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 |