| 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
|
|
|