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

Side by Side Diff: third_party/WebKit/Source/core/html/ImageDataTest.cpp

Issue 2849643002: Implement ImageData::CropRect() (Closed)
Patch Set: Adding flipping to ImageData::CopyRect() Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/html/ImageData.h" 5 #include "core/html/ImageData.h"
6 6
7 #include "core/dom/ExceptionCode.h" 7 #include "core/dom/ExceptionCode.h"
8 #include "platform/geometry/IntSize.h" 8 #include "platform/geometry/IntSize.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/skia/include/core/SkColorSpaceXform.h" 10 #include "third_party/skia/include/core/SkColorSpaceXform.h"
(...skipping 20 matching lines...) Expand all
31 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( 31 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(
32 color_correct_rendering); 32 color_correct_rendering);
33 } 33 }
34 34
35 bool experimental_canvas_features; 35 bool experimental_canvas_features;
36 bool color_correct_rendering; 36 bool color_correct_rendering;
37 }; 37 };
38 38
39 TEST_F(ImageDataTest, NegativeAndZeroIntSizeTest) { 39 TEST_F(ImageDataTest, NegativeAndZeroIntSizeTest) {
40 ImageData* image_data; 40 ImageData* image_data;
41 41 // Test scenarios
42 image_data = ImageData::Create(IntSize(0, 10)); 42 const int num_test_cases = 6;
43 EXPECT_EQ(image_data, nullptr); 43 const IntSize image_data_sizes[6] = {IntSize(0, 10), IntSize(10, 0),
44 44 IntSize(0, 0), IntSize(-1, 10),
45 image_data = ImageData::Create(IntSize(10, 0)); 45 IntSize(10, -1), IntSize(-1, -1)};
46 EXPECT_EQ(image_data, nullptr); 46 for (int i = 1; i < num_test_cases; i++) {
47 47 image_data = ImageData::Create(image_data_sizes[i]);
48 image_data = ImageData::Create(IntSize(0, 0)); 48 EXPECT_EQ(image_data, nullptr);
49 EXPECT_EQ(image_data, nullptr); 49 }
50
51 image_data = ImageData::Create(IntSize(-1, 10));
52 EXPECT_EQ(image_data, nullptr);
53
54 image_data = ImageData::Create(IntSize(10, -1));
55 EXPECT_EQ(image_data, nullptr);
56
57 image_data = ImageData::Create(IntSize(-1, -1));
58 EXPECT_EQ(image_data, nullptr);
59 } 50 }
60 51
61 // Under asan_clang_phone, the test crashes after the memory allocation 52 // Under asan_clang_phone, the test crashes after the memory allocation
62 // is not successful. It is probably related to the value of 53 // is not successful. It is probably related to the value of
63 // allocator_may_return_null on trybots, which in this case causes ASAN 54 // allocator_may_return_null on trybots, which in this case causes ASAN
64 // to terminate the process instead of returning null. 55 // to terminate the process instead of returning null.
65 // crbug.com/704948 56 // crbug.com/704948
66 #if defined(ADDRESS_SANITIZER) 57 #if defined(ADDRESS_SANITIZER)
67 #define MAYBE_CreateImageDataTooBig DISABLED_CreateImageDataTooBig 58 #define MAYBE_CreateImageDataTooBig DISABLED_CreateImageDataTooBig
68 #else 59 #else
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 return false; 234 return false;
244 } 235 }
245 236
246 SkColorSpaceXform::ColorFormat dst_color_format = 237 SkColorSpaceXform::ColorFormat dst_color_format =
247 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; 238 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
248 if (dst_pixel_format == kF16CanvasPixelFormat) 239 if (dst_pixel_format == kF16CanvasPixelFormat)
249 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat; 240 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
250 241
251 sk_sp<SkColorSpace> src_sk_color_space = nullptr; 242 sk_sp<SkColorSpace> src_sk_color_space = nullptr;
252 if (u8_array) { 243 if (u8_array) {
253 src_sk_color_space = ImageData::GetSkColorSpaceForTest( 244 src_sk_color_space =
254 src_color_space, kRGBA8CanvasPixelFormat); 245 CanvasColorParams(src_color_space, kRGBA8CanvasPixelFormat)
246 .GetSkColorSpaceForSkSurfaces();
255 } else { 247 } else {
256 src_sk_color_space = ImageData::GetSkColorSpaceForTest( 248 src_sk_color_space =
257 src_color_space, kF16CanvasPixelFormat); 249 CanvasColorParams(src_color_space, kF16CanvasPixelFormat)
250 .GetSkColorSpaceForSkSurfaces();
258 } 251 }
259 252
260 sk_sp<SkColorSpace> dst_sk_color_space = 253 sk_sp<SkColorSpace> dst_sk_color_space =
261 ImageData::GetSkColorSpaceForTest(dst_color_space, dst_pixel_format); 254 CanvasColorParams(dst_color_space, dst_pixel_format)
255 .GetSkColorSpaceForSkSurfaces();
262 256
263 // When the input dataArray is in Uint16, we normally should convert the 257 // When the input dataArray is in Uint16, we normally should convert the
264 // values from Little Endian to Big Endian before passing the buffer to 258 // values from Little Endian to Big Endian before passing the buffer to
265 // SkColorSpaceXform::apply. However, in this test scenario we are creating 259 // SkColorSpaceXform::apply. However, in this test scenario we are creating
266 // the Uin16 dataArray by multiplying a Uint8Clamped array members by 257, 260 // the Uin16 dataArray by multiplying a Uint8Clamped array members by 257,
267 // hence the Big Endian and Little Endian representations are the same. 261 // hence the Big Endian and Little Endian representations are the same.
268 262
269 std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New( 263 std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(
270 src_sk_color_space.get(), dst_sk_color_space.get()); 264 src_sk_color_space.get(), dst_sk_color_space.get());
271 265
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 EXPECT_EQ(0, 387 EXPECT_EQ(0,
394 memcmp(pixels_converted_manually.get(), 388 memcmp(pixels_converted_manually.get(),
395 pixels_converted_in_image_data.get(), output_length)); 389 pixels_converted_in_image_data.get(), output_length));
396 } 390 }
397 } 391 }
398 } 392 }
399 delete[] u16_pixels; 393 delete[] u16_pixels;
400 delete[] f32_pixels; 394 delete[] f32_pixels;
401 } 395 }
402 396
397 // This test examines ImageData::CropRect()
398 TEST_F(ImageDataTest, TestCropRect) {
399 const int num_image_data_storage_formats = 3;
400 ImageDataStorageFormat image_data_storage_formats[] = {
401 kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat,
402 kFloat32ArrayStorageFormat,
403 };
404 String image_data_storage_format_names[] = {
405 kUint8ClampedArrayStorageFormatName, kUint16ArrayStorageFormatName,
406 kFloat32ArrayStorageFormatName,
407 };
408
409 // Source pixels
410 unsigned width = 20;
411 unsigned height = 20;
412 unsigned data_length = width * height * 4;
413 uint8_t* u8_pixels = new uint8_t[data_length];
414 uint16_t* u16_pixels = new uint16_t[data_length];
415 float* f32_pixels = new float[data_length];
416
417 // Test scenarios
418 const int num_test_cases = 12;
419 const IntRect crop_rects[12] = {
420 IntRect(3, 4, 5, 6), IntRect(3, 4, 5, 6), IntRect(10, 10, 20, 20),
421 IntRect(10, 10, 20, 20), IntRect(0, 0, 20, 20), IntRect(0, 0, 20, 20),
422 IntRect(0, 0, 10, 10), IntRect(0, 0, 10, 10), IntRect(0, 0, 10, 0),
423 IntRect(0, 0, 0, 10), IntRect(10, 0, 10, 10), IntRect(0, 10, 10, 10),
424 };
425 const bool crop_flips[12] = {true, false, true, false, true, false,
426 true, false, false, false, false, false};
427
428 // Fill the pixels with numbers related to their positions
429 unsigned set_value = 0;
430 unsigned expected_value = 0;
431 float fexpected_value = 0;
432 unsigned index = 0, row_index = 0;
433 for (unsigned i = 0; i < height; i++)
434 for (unsigned j = 0; j < width; j++)
435 for (unsigned k = 0; k < 4; k++) {
436 index = i * width * 4 + j * 4 + k;
437 set_value = (i + 1) * (j + 1) * (k + 1);
438 u8_pixels[index] = set_value % 255;
439 u16_pixels[index] = (set_value * 257) % 65535;
440 f32_pixels[index] = (set_value % 255) / 255.0f;
441 }
442
443 // Create ImageData objects
444 DOMArrayBufferView* data_array = nullptr;
445
446 DOMUint8ClampedArray* data_u8 =
447 DOMUint8ClampedArray::Create(u8_pixels, data_length);
448 DCHECK(data_u8);
449 EXPECT_EQ(data_length, data_u8->length());
450 DOMUint16Array* data_u16 = DOMUint16Array::Create(u16_pixels, data_length);
451 DCHECK(data_u16);
452 EXPECT_EQ(data_length, data_u16->length());
453 DOMFloat32Array* data_f32 = DOMFloat32Array::Create(f32_pixels, data_length);
454 DCHECK(data_f32);
455 EXPECT_EQ(data_length, data_f32->length());
456
457 ImageData* image_data = nullptr;
458 ImageData* cropped_image_data = nullptr;
459
460 bool test_passed = true;
461 for (int i = 0; i < num_image_data_storage_formats; i++) {
462 if (image_data_storage_formats[i] == kUint8ClampedArrayStorageFormat)
463 data_array = static_cast<DOMArrayBufferView*>(data_u8);
464 else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat)
465 data_array = static_cast<DOMArrayBufferView*>(data_u16);
466 else
467 data_array = static_cast<DOMArrayBufferView*>(data_f32);
468
469 ImageDataColorSettings color_settings;
470 color_settings.setStorageFormat(image_data_storage_format_names[i]);
471 image_data = ImageData::CreateForTest(IntSize(width, height), data_array,
472 &color_settings);
473 for (int j = 0; j < num_test_cases; j++) {
474 // Test the size of the cropped image data
475 IntRect src_rect(IntPoint(), image_data->Size());
476 IntRect crop_rect = Intersection(src_rect, crop_rects[j]);
477
478 cropped_image_data = image_data->CropRect(crop_rects[j], crop_flips[j]);
479 if (crop_rect.IsEmpty()) {
480 EXPECT_FALSE(cropped_image_data);
481 continue;
482 }
483 EXPECT_TRUE(cropped_image_data->Size() == crop_rect.Size());
484
485 // Test the content
486 for (int k = 0; k < crop_rect.Height(); k++)
487 for (int m = 0; m < crop_rect.Width(); m++)
488 for (int n = 0; n < 4; n++) {
489 row_index = crop_flips[j] ? (crop_rect.Height() - k - 1) : k;
490 index =
491 row_index * cropped_image_data->Size().Width() * 4 + m * 4 + n;
492 expected_value =
493 (k + crop_rect.X() + 1) * (m + crop_rect.Y() + 1) * (n + 1);
494 if (image_data_storage_formats[i] ==
495 kUint8ClampedArrayStorageFormat)
496 expected_value %= 255;
497 else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat)
498 expected_value = (expected_value * 257) % 65535;
499 else
500 fexpected_value = (expected_value % 255) / 255.0f;
501
502 if (image_data_storage_formats[i] ==
503 kUint8ClampedArrayStorageFormat) {
504 if (cropped_image_data->data()->Data()[index] != expected_value) {
505 test_passed = false;
506 break;
507 }
508 } else if (image_data_storage_formats[i] ==
509 kUint16ArrayStorageFormat) {
510 if (cropped_image_data->dataUnion()
511 .getAsUint16Array()
512 .View()
513 ->Data()[index] != expected_value) {
514 test_passed = false;
515 break;
516 }
517 } else {
518 if (cropped_image_data->dataUnion()
519 .getAsFloat32Array()
520 .View()
521 ->Data()[index] != fexpected_value) {
522 test_passed = false;
523 break;
524 }
525 }
526 }
527 EXPECT_TRUE(test_passed);
528 }
529 }
530
531 delete[] u8_pixels;
532 delete[] u16_pixels;
533 delete[] f32_pixels;
534 }
535
403 } // namspace 536 } // namspace
404 } // namespace blink 537 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698