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

Unified Diff: third_party/WebKit/Source/core/html/ImageDataTest.cpp

Issue 2771813003: Prepare ImageData for color managed BaseRenderingContext2D::create/put/get-ImageData (Closed)
Patch Set: Unit test added 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/ImageDataTest.cpp
diff --git a/third_party/WebKit/Source/core/html/ImageDataTest.cpp b/third_party/WebKit/Source/core/html/ImageDataTest.cpp
index daa0d9af1063391c41fb3d93ed69c4188ff8f252..716b0a67ceebdd083dac2e34c0ed651174f6189b 100644
--- a/third_party/WebKit/Source/core/html/ImageDataTest.cpp
+++ b/third_party/WebKit/Source/core/html/ImageDataTest.cpp
@@ -7,14 +7,31 @@
#include "core/dom/ExceptionCode.h"
#include "platform/geometry/IntSize.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkColorSpaceXform.h"
namespace blink {
namespace {
class ImageDataTest : public ::testing::Test {
protected:
- ImageDataTest(){};
- void TearDown(){};
+ virtual void SetUp() {
+ // Save the state of experimental canvas features and color correct
+ // rendering flags to restore them on teardown.
+ experimentalCanvasFeatures =
+ RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled();
+ colorCorrectRendering =
+ RuntimeEnabledFeatures::colorCorrectRenderingEnabled();
+ }
+
+ virtual void TearDown() {
+ RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(
+ experimentalCanvasFeatures);
+ RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(
+ colorCorrectRendering);
+ }
+
+ bool experimentalCanvasFeatures;
+ bool colorCorrectRendering;
};
TEST_F(ImageDataTest, NegativeAndZeroIntSizeTest) {
@@ -50,5 +67,117 @@ TEST_F(ImageDataTest, CreateImageDataTooBig) {
}
}
+// Skia conversion does not guarantee to be exact, se we need to do
+// approximate comparisons.
+static inline bool IsNearlyTheSame(float f, float g) {
+ static const float epsilonScale = 0.01f;
+ return std::abs(f - g) < epsilonScale *
+ std::max(std::max(std::abs(f), std::abs(g)), epsilonScale);
+}
+
+// This test verifies the correct behavior of ImageData member function used
+// to convert pixels data from canvas pixel format image data storage format.
+// This function is used in BaseRenderingContext2D::getImageData.
+TEST_F(ImageDataTest, TestConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat) {
+ // Source pixels in RGBA32
+ unsigned char rgba32Pixels[] = {255, 0, 0, 255, // Red
+ 0, 0, 0, 0, // Transparent
+ 255, 192, 128, 64, // Decreasing values
+ 93, 117, 205, 11}; // Random values
+ const unsigned numColorComponents = 16;
+ // Source pixels in F16
+ unsigned char* f16Pixels = new unsigned char [numColorComponents * 2];
+
+ // Filling F16 source pixels
+ std::unique_ptr<SkColorSpaceXform> xform =
+ SkColorSpaceXform::New(SkColorSpace::MakeSRGBLinear().get(),
+ SkColorSpace::MakeSRGBLinear().get());
+ xform->apply(SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat, f16Pixels,
+ SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat, rgba32Pixels,
+ 4, SkAlphaType::kUnpremul_SkAlphaType);
+
+ // Creating ArrayBufferContents objects. We need two buffers for RGBA32 data
+ // because kRGBA8CanvasPixelFormat->kUint8ClampedArrayStorageFormat consumes
+ // the input data parameter.
+ WTF::ArrayBufferContents contentsRGBA32(numColorComponents, 1, WTF::ArrayBufferContents::NotShared,
+ WTF::ArrayBufferContents::DontInitialize);
+ std::memcpy(contentsRGBA32.data(), rgba32Pixels, numColorComponents);
+
+ WTF::ArrayBufferContents contents2RGBA32(numColorComponents, 1, WTF::ArrayBufferContents::NotShared,
+ WTF::ArrayBufferContents::DontInitialize);
+ std::memcpy(contents2RGBA32.data(), rgba32Pixels, numColorComponents);
+
+ WTF::ArrayBufferContents contentsF16(numColorComponents * 2, 1, WTF::ArrayBufferContents::NotShared,
+ WTF::ArrayBufferContents::DontInitialize);
+ std::memcpy(contentsF16.data(), f16Pixels, numColorComponents * 2);
+
+ // Uint16 is not supported as the storage format for ImageData created from a
+ // canvas, so this conversion is neither implemented nor tested here.
+ bool testPassed = true;
+ DOMArrayBufferView* data = nullptr;
+ DOMUint8ClampedArray* dataU8 = nullptr;
+ DOMFloat32Array* dataF32 = nullptr;
+
+ // Testing kRGBA8CanvasPixelFormat -> kUint8ClampedArrayStorageFormat
+ data = ImageData::convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contentsRGBA32, kRGBA8CanvasPixelFormat, kUint8ClampedArrayStorageFormat);
+ DCHECK(data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped);
+ dataU8 = const_cast<DOMUint8ClampedArray*>(
+ static_cast<const DOMUint8ClampedArray*>(data));
+ DCHECK(dataU8);
+ for (unsigned i = 0; i < numColorComponents; i++) {
+ if (dataU8->data()[i] != rgba32Pixels[i]){
+ testPassed = false;
+ break;
+ }
+ }
+ EXPECT_TRUE(testPassed);
+
+ // Testing kRGBA8CanvasPixelFormat -> kFloat32ArrayStorageFormat
+ data = ImageData::convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contents2RGBA32, kRGBA8CanvasPixelFormat, kFloat32ArrayStorageFormat);
+ DCHECK(data->type() == DOMArrayBufferView::ViewType::TypeFloat32);
+ dataF32 = const_cast<DOMFloat32Array*>(
+ static_cast<const DOMFloat32Array*>(data));
+ DCHECK(dataF32);
+ for (unsigned i = 0; i < numColorComponents; i++) {
+ if (!IsNearlyTheSame(dataF32->data()[i], rgba32Pixels[i] / 255.0)){
+ testPassed = false;
+ break;
+ }
+ }
+ EXPECT_TRUE(testPassed);
+
+ // Testing kF16CanvasPixelFormat -> kUint8ClampedArrayStorageFormat
+ data = ImageData::convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contentsF16, kF16CanvasPixelFormat, kUint8ClampedArrayStorageFormat);
+ DCHECK(data->type() == DOMArrayBufferView::ViewType::TypeUint8Clamped);
+ dataU8 = const_cast<DOMUint8ClampedArray*>(
+ static_cast<const DOMUint8ClampedArray*>(data));
+ DCHECK(dataU8);
+ for (unsigned i = 0; i < numColorComponents; i++) {
+ if (!IsNearlyTheSame(dataU8->data()[i], rgba32Pixels[i])){
+ testPassed = false;
+ break;
+ }
+ }
+ EXPECT_TRUE(testPassed);
+
+ // Testing kF16CanvasPixelFormat -> kFloat32ArrayStorageFormat
+ data = ImageData::convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(
+ contentsF16, kF16CanvasPixelFormat, kFloat32ArrayStorageFormat);
+ DCHECK(data->type() == DOMArrayBufferView::ViewType::TypeFloat32);
+ dataF32 = const_cast<DOMFloat32Array*>(
+ static_cast<const DOMFloat32Array*>(data));
+ DCHECK(dataF32);
+ for (unsigned i = 0; i < numColorComponents; i++) {
+ if (!IsNearlyTheSame(dataF32->data()[i], rgba32Pixels[i] / 255.0)){
+ testPassed = false;
+ break;
+ }
+ }
+ EXPECT_TRUE(testPassed);
+}
+
} // namspace
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698