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

Unified Diff: third_party/WebKit/Source/core/html/ImageData.h

Issue 2555213002: Implement color management for ImageData (Closed)
Patch Set: Addressing issues Created 4 years 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 side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698