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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/html/ImageData.cpp
diff --git a/third_party/WebKit/Source/core/html/ImageData.cpp b/third_party/WebKit/Source/core/html/ImageData.cpp
index ae78044c5c4ead4935c61c3c81b26756d63e7c1d..ffa7a11b3321b374ba458975db719add28c0ff2a 100644
--- a/third_party/WebKit/Source/core/html/ImageData.cpp
+++ b/third_party/WebKit/Source/core/html/ImageData.cpp
@@ -38,159 +38,152 @@
namespace blink {
+bool RaiseDOMExceptionAndReturnFalse(ExceptionState* exceptionState,
+ ExceptionCode exceptionCode,
+ const char* message) {
+ if (exceptionState)
+ exceptionState->throwDOMException(exceptionCode, message);
+ return false;
+}
+
bool ImageData::validateConstructorArguments(const unsigned& paramFlags,
const IntSize* size,
const unsigned& width,
const unsigned& height,
const DOMArrayBufferView* data,
- const String* colorSpace,
- ExceptionState* exceptionState,
- ImageDataType imageDataType) {
- if (paramFlags & kParamData) {
- if (data->type() != DOMArrayBufferView::ViewType::TypeUint8Clamped &&
- data->type() != DOMArrayBufferView::ViewType::TypeFloat32)
- return false;
- if (data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped &&
- imageDataType != kUint8ClampedImageData)
- imageDataType = kFloat32ImageData;
- }
+ ExceptionState* exceptionState) {
+ // We accept all the combinations of colorSpace and storageFormat in an
+ // ImageDataColorSettings to be stored in an ImageData. Therefore, we don't
+ // check the color settings in this function.
- // ImageData::create parameters without ExceptionState
- if (paramFlags & kParamSize) {
- if (!size->width() || !size->height())
- return false;
- CheckedNumeric<unsigned> dataSize = 4;
- dataSize *= size->width();
- dataSize *= size->height();
- if (!dataSize.IsValid())
- return false;
- if (paramFlags & kParamData) {
- DCHECK(data);
- unsigned length =
- data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
- ? (const_cast<DOMUint8ClampedArray*>(
- static_cast<const DOMUint8ClampedArray*>(data)))
- ->length()
- : (const_cast<DOMFloat32Array*>(
- static_cast<const DOMFloat32Array*>(data)))
- ->length();
- if (dataSize.ValueOrDie() > 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;
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError,
+ "The source width is zero or not a number.");
}
+
if ((paramFlags & kParamHeight) && !height) {
- exceptionState->throwDOMException(
- IndexSizeError, "The source height is zero or not a number.");
- return false;
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError,
+ "The source height is zero or not a number.");
}
+
if (paramFlags & (kParamWidth | kParamHeight)) {
CheckedNumeric<unsigned> dataSize = 4;
dataSize *= width;
dataSize *= height;
- if (!dataSize.IsValid()) {
- exceptionState->throwDOMException(
- IndexSizeError,
+ if (!dataSize.IsValid())
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError,
"The requested image size exceeds the supported range.");
- return false;
- }
}
+
+ unsigned dataLength = 0;
if (paramFlags & kParamData) {
DCHECK(data);
- unsigned length =
- data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped
- ? (const_cast<DOMUint8ClampedArray*>(
- static_cast<const DOMUint8ClampedArray*>(data)))
- ->length()
- : (const_cast<DOMFloat32Array*>(
- static_cast<const DOMFloat32Array*>(data)))
- ->length();
- if (!length) {
- exceptionState->throwDOMException(IndexSizeError,
- "The input data has zero elements.");
- return false;
+ switch (data->type()) {
+ case DOMArrayBufferView::ViewType::TypeUint8Clamped:
+ dataLength = data->view()->byteLength();
+ break;
+ case DOMArrayBufferView::ViewType::TypeUint16:
+ dataLength = data->view()->byteLength() / 2;
+ break;
+ case DOMArrayBufferView::ViewType::TypeFloat32:
+ dataLength = data->view()->byteLength() / 4;
+ break;
+ default:
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, NotSupportedError,
+ "The input data type is not supported.");
}
- if (length % 4) {
- exceptionState->throwDOMException(
- IndexSizeError, "The input data length is not a multiple of 4.");
- return false;
+
+ if (!dataLength) {
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError, "The input data has zero elements.");
+ }
+
+ if (dataLength % 4) {
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError,
+ "The input data length is not a multiple of 4.");
}
- length /= 4;
- if (length % width) {
- exceptionState->throwDOMException(
- IndexSizeError,
+
+ if ((paramFlags & kParamWidth) && (dataLength / 4) % width) {
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, IndexSizeError,
"The input data length is not a multiple of (4 * width).");
- return false;
}
- if ((paramFlags & kParamHeight) && height != length / width) {
- exceptionState->throwDOMException(
- IndexSizeError,
+
+ if ((paramFlags & kParamHeight & kParamWidth) &&
+ height != dataLength / (4 * width))
+ return RaiseDOMExceptionAndReturnFalse(
+ exceptionState, 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.");
+
+ if (paramFlags & kParamSize) {
+ if (!size->width() || !size->height())
return false;
- }
- if (imageDataType == kFloat32ImageData &&
- *colorSpace != kLinearRGBImageDataColorSpaceName) {
- exceptionState->throwDOMException(NotSupportedError,
- "The input color space is not "
- "supported in "
- "Float32Array-backed ImageData.");
+ CheckedNumeric<unsigned> dataSize = 4;
+ dataSize *= size->width();
+ dataSize *= size->height();
+ if (!dataSize.IsValid())
return false;
+ if (paramFlags & kParamData) {
+ if (dataSize.ValueOrDie() > dataLength)
+ return false;
}
}
+
return true;
}
-DOMUint8ClampedArray* ImageData::allocateAndValidateUint8ClampedArray(
+DOMArrayBufferView* ImageData::allocateAndValidateDataArray(
const unsigned& length,
+ ImageDataStorageFormat storageFormat,
ExceptionState* exceptionState) {
if (!length)
return nullptr;
- DOMUint8ClampedArray* dataArray = DOMUint8ClampedArray::createOrNull(length);
- if (!dataArray || length != dataArray->length()) {
- if (exceptionState) {
+
+ DOMArrayBufferView* dataArray = nullptr;
+ unsigned dataLength = 0;
+ switch (storageFormat) {
+ case kUint8ClampedArrayStorageFormat:
+ dataArray = DOMUint8ClampedArray::createOrNull(length);
+ dataLength = dataArray->view()->byteLength();
+ break;
+ case kUint16ArrayStorageFormat:
+ dataArray = DOMUint16Array::createOrNull(length);
+ dataLength = dataArray->view()->byteLength() / 2;
+ break;
+ case kFloat32ArrayStorageFormat:
+ dataArray = DOMFloat32Array::createOrNull(length);
+ dataLength = dataArray->view()->byteLength() / 4;
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ if (!dataArray || length != dataLength) {
+ if (exceptionState)
exceptionState->throwDOMException(V8RangeError,
"Out of memory at ImageData creation");
- }
return nullptr;
}
+
return dataArray;
}
ImageData* ImageData::create(const IntSize& size) {
if (!ImageData::validateConstructorArguments(kParamSize, &size))
return nullptr;
- DOMUint8ClampedArray* byteArray =
- ImageData::allocateAndValidateUint8ClampedArray(4 * size.width() *
- size.height());
- if (!byteArray)
- return nullptr;
+ DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
+ 4 * size.width() * size.height(), kUint8ClampedArrayStorageFormat);
return new ImageData(size, byteArray);
}
-// This function accepts size (0, 0).
+// This function accepts size (0, 0) and always returns the ImageData in
+// "srgb" color space and "uint8" storage format.
ImageData* ImageData::createForTest(const IntSize& size) {
CheckedNumeric<unsigned> dataSize = 4;
dataSize *= size.width();
@@ -211,17 +204,8 @@ ImageData* ImageData::create(const IntSize& size,
if (!ImageData::validateConstructorArguments(kParamSize | kParamData, &size,
0, 0, byteArray))
return nullptr;
- return new ImageData(size, byteArray);
-}
-ImageData* ImageData::create(const IntSize& size,
- DOMUint8ClampedArray* byteArray,
- const String& colorSpace) {
- if (!ImageData::validateConstructorArguments(
- kParamSize | kParamData | kParamColorSpace, &size, 0, 0, byteArray,
- &colorSpace))
- return nullptr;
- return new ImageData(size, byteArray, colorSpace);
+ return new ImageData(size, byteArray);
}
ImageData* ImageData::create(unsigned width,
@@ -229,21 +213,21 @@ ImageData* ImageData::create(unsigned width,
ExceptionState& exceptionState) {
if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
nullptr, width, height, nullptr,
- nullptr, &exceptionState))
+ &exceptionState))
return nullptr;
- DOMUint8ClampedArray* byteArray =
- ImageData::allocateAndValidateUint8ClampedArray(4 * width * height,
- &exceptionState);
+
+ DOMArrayBufferView* byteArray = allocateAndValidateDataArray(
+ 4 * width * height, kUint8ClampedArrayStorageFormat, &exceptionState);
return byteArray ? new ImageData(IntSize(width, height), byteArray) : nullptr;
}
ImageData* ImageData::create(DOMUint8ClampedArray* data,
unsigned width,
ExceptionState& exceptionState) {
- if (!ImageData::validateConstructorArguments(kParamData | kParamWidth,
- nullptr, width, 0, data, nullptr,
- &exceptionState))
+ if (!ImageData::validateConstructorArguments(
+ kParamData | kParamWidth, nullptr, width, 0, data, &exceptionState))
return nullptr;
+
unsigned height = data->length() / (width * 4);
return new ImageData(IntSize(width, height), data);
}
@@ -254,50 +238,55 @@ ImageData* ImageData::create(DOMUint8ClampedArray* data,
ExceptionState& exceptionState) {
if (!ImageData::validateConstructorArguments(
kParamData | kParamWidth | kParamHeight, nullptr, width, height, data,
- nullptr, &exceptionState))
+ &exceptionState))
return nullptr;
+
return new ImageData(IntSize(width, height), data);
}
-ImageData* ImageData::createImageData(unsigned width,
- unsigned height,
- String colorSpace,
- ExceptionState& exceptionState) {
- if (!ImageData::validateConstructorArguments(
- kParamWidth | kParamHeight | kParamColorSpace, nullptr, width, height,
- nullptr, &colorSpace, &exceptionState))
+ImageData* ImageData::createImageData(
+ unsigned width,
+ unsigned height,
+ const ImageDataColorSettings& colorSettings,
+ ExceptionState& exceptionState) {
+ if (!ImageData::validateConstructorArguments(kParamWidth | kParamHeight,
+ nullptr, width, height, nullptr,
+ &exceptionState))
return nullptr;
- DOMUint8ClampedArray* byteArray =
- ImageData::allocateAndValidateUint8ClampedArray(4 * width * height,
- &exceptionState);
- return byteArray
- ? new ImageData(IntSize(width, height), byteArray, colorSpace)
- : nullptr;
-}
+ ImageDataStorageFormat storageFormat =
+ ImageData::getImageDataStorageFormat(colorSettings.storageFormat());
+ DOMArrayBufferView* bufferView = allocateAndValidateDataArray(
+ 4 * width * height, storageFormat, &exceptionState);
-ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
- unsigned width,
- String colorSpace,
- ExceptionState& exceptionState) {
- if (!ImageData::validateConstructorArguments(
- kParamData | kParamWidth | kParamColorSpace, nullptr, width, 0, data,
- &colorSpace, &exceptionState))
+ if (!bufferView)
return nullptr;
- unsigned height = data->length() / (width * 4);
- return new ImageData(IntSize(width, height), data, colorSpace);
+
+ return new ImageData(IntSize(width, height), bufferView, &colorSettings);
}
-ImageData* ImageData::createImageData(DOMUint8ClampedArray* data,
- unsigned width,
- unsigned height,
- String colorSpace,
- ExceptionState& exceptionState) {
+ImageData* ImageData::createImageData(
+ ImageDataArray& data,
+ unsigned width,
+ unsigned height,
+ const ImageDataColorSettings& colorSettings,
+ ExceptionState& exceptionState) {
+ DOMArrayBufferView* bufferView = nullptr;
+ if (data.isUint8ClampedArray())
+ bufferView = data.getAsUint8ClampedArray();
+ else if (data.isUint16Array())
+ bufferView = data.getAsUint16Array();
+ else if (data.isFloat32Array())
+ bufferView = data.getAsFloat32Array();
+ else
+ NOTREACHED();
+
if (!ImageData::validateConstructorArguments(
- kParamData | kParamWidth | kParamHeight | kParamColorSpace, nullptr,
- width, height, data, &colorSpace, &exceptionState))
+ kParamData | kParamWidth | kParamHeight, nullptr, width, height,
+ bufferView, &exceptionState))
return nullptr;
- return new ImageData(IntSize(width, height), data, colorSpace);
+
+ return new ImageData(IntSize(width, height), bufferView, &colorSettings);
}
ScriptPromise ImageData::createImageBitmap(ScriptState* scriptState,
@@ -330,7 +319,7 @@ v8::Local<v8::Object> ImageData::associateWithWrapper(
wrapper =
ScriptWrappable::associateWithWrapper(isolate, wrapperType, wrapper);
- if (!wrapper.IsEmpty() && m_data.get()) {
+ if (!wrapper.IsEmpty() && m_data) {
// Create a V8 Uint8ClampedArray object and set the "data" property
// of the ImageData object to the created v8 object, eliminating the
// C++ callback when accessing the "data" property.
@@ -344,61 +333,95 @@ v8::Local<v8::Object> ImageData::associateWithWrapper(
return wrapper;
}
-ImageDataColorSpace ImageData::getImageDataColorSpace(String colorSpaceName) {
- if (colorSpaceName == kLegacyImageDataColorSpaceName)
- return kLegacyImageDataColorSpace;
- if (colorSpaceName == kSRGBImageDataColorSpaceName)
- return kSRGBImageDataColorSpace;
- if (colorSpaceName == kLinearRGBImageDataColorSpaceName)
- return kLinearRGBImageDataColorSpace;
- NOTREACHED();
- return kLegacyImageDataColorSpace;
+const DOMUint8ClampedArray* ImageData::data() const {
+ if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
+ return m_data.get();
+ return nullptr;
}
-String ImageData::getImageDataColorSpaceName(ImageDataColorSpace colorSpace) {
- switch (colorSpace) {
- case kLegacyImageDataColorSpace:
- return kLegacyImageDataColorSpaceName;
- case kSRGBImageDataColorSpace:
- return kSRGBImageDataColorSpaceName;
- case kLinearRGBImageDataColorSpace:
- return kLinearRGBImageDataColorSpaceName;
- }
- NOTREACHED();
- return String();
+DOMUint8ClampedArray* ImageData::data() {
+ if (m_colorSettings.storageFormat() == kUint8ClampedArrayStorageFormatName)
+ return m_data.get();
+ return nullptr;
}
-sk_sp<SkColorSpace> ImageData::imageDataColorSpaceToSkColorSpace(
- ImageDataColorSpace colorSpace) {
- switch (colorSpace) {
- case kLegacyImageDataColorSpace:
- return ColorBehavior::globalTargetColorSpace().ToSkColorSpace();
- case kSRGBImageDataColorSpace:
- return SkColorSpace::MakeSRGB();
- case kLinearRGBImageDataColorSpace:
- return SkColorSpace::MakeSRGBLinear();
- }
+ImageDataStorageFormat ImageData::getImageDataStorageFormat(
+ const String& storageFormatName) {
+ if (storageFormatName == kUint8ClampedArrayStorageFormatName)
+ return kUint8ClampedArrayStorageFormat;
+ if (storageFormatName == kUint16ArrayStorageFormatName)
+ return kUint16ArrayStorageFormat;
+ if (storageFormatName == kFloat32ArrayStorageFormatName)
+ return kFloat32ArrayStorageFormat;
NOTREACHED();
- return nullptr;
+ return kUint8ClampedArrayStorageFormat;
}
+// For ImageData, the color space is only specified by color settings.
+// It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
sk_sp<SkColorSpace> ImageData::getSkColorSpace() {
if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
!RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
return nullptr;
- return ImageData::imageDataColorSpaceToSkColorSpace(m_colorSpace);
+
+ return SkColorSpace::MakeSRGB();
+}
+
+void ImageData::trace(Visitor* visitor) {
+ visitor->trace(m_data);
+ visitor->trace(m_dataU16);
+ visitor->trace(m_dataF32);
+ visitor->trace(m_dataUnion);
}
ImageData::ImageData(const IntSize& size,
- DOMUint8ClampedArray* byteArray,
- String colorSpaceName)
- : m_size(size),
- m_colorSpace(getImageDataColorSpace(colorSpaceName)),
- m_data(byteArray) {
+ DOMArrayBufferView* data,
+ const ImageDataColorSettings* colorSettings)
+ : m_size(size) {
DCHECK_GE(size.width(), 0);
DCHECK_GE(size.height(), 0);
- SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
- m_data->length());
+ DCHECK(data);
+
+ m_data = nullptr;
+ m_dataU16 = nullptr;
+ m_dataF32 = nullptr;
+
+ if (colorSettings) {
+ m_colorSettings.setColorSpace(colorSettings->colorSpace());
+ m_colorSettings.setStorageFormat(colorSettings->storageFormat());
+ }
+
+ ImageDataStorageFormat storageFormat =
+ getImageDataStorageFormat(m_colorSettings.storageFormat());
+
+ switch (storageFormat) {
+ case kUint8ClampedArrayStorageFormat:
+ m_data = const_cast<DOMUint8ClampedArray*>(
+ static_cast<const DOMUint8ClampedArray*>(data));
+ m_dataUnion.setUint8ClampedArray(m_data);
+ SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+ m_data->length());
+ break;
+
+ case kUint16ArrayStorageFormat:
+ m_dataU16 =
+ const_cast<DOMUint16Array*>(static_cast<const DOMUint16Array*>(data));
+ m_dataUnion.setUint16Array(m_dataU16);
+ SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+ m_dataU16->length());
+ break;
+
+ case kFloat32ArrayStorageFormat:
+ m_dataF32 = const_cast<DOMFloat32Array*>(
+ static_cast<const DOMFloat32Array*>(data));
+ m_dataUnion.setFloat32Array(m_dataF32);
+ SECURITY_CHECK(static_cast<unsigned>(size.width() * size.height() * 4) <=
+ m_dataF32->length());
+ break;
+
+ default:
+ NOTREACHED();
+ }
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698