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

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

Issue 2849643002: Implement ImageData::CropRect() (Closed)
Patch Set: Adding MakeCopy() 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 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 360
361 // This function is called from unit tests, and all the parameters are supposed 361 // This function is called from unit tests, and all the parameters are supposed
362 // to be validated on the call site. 362 // to be validated on the call site.
363 ImageData* ImageData::CreateForTest( 363 ImageData* ImageData::CreateForTest(
364 const IntSize& size, 364 const IntSize& size,
365 DOMArrayBufferView* buffer_view, 365 DOMArrayBufferView* buffer_view,
366 const ImageDataColorSettings* color_settings) { 366 const ImageDataColorSettings* color_settings) {
367 return new ImageData(size, buffer_view, color_settings); 367 return new ImageData(size, buffer_view, color_settings);
368 } 368 }
369 369
370 bool ImageData::CompareImageDataColorSettingsForTest(ImageData* image_data_1,
371 ImageData* image_data_2) {
372 ImageDataColorSettings color_settings_1, color_settings_2;
373 image_data_1->getColorSettings(color_settings_1);
374 image_data_2->getColorSettings(color_settings_2);
375 return color_settings_1.colorSpace() == color_settings_2.colorSpace() &&
376 color_settings_1.storageFormat() == color_settings_2.storageFormat();
377 }
378
379 ImageData* ImageData::MakeCopy() {
380 unsigned data_length = size_.Width() * size_.Height() * 4;
381 DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
382 data_length,
383 ImageData::GetImageDataStorageFormat(color_settings_.storageFormat()));
384 if (!buffer_view)
385 return nullptr;
386 std::memcpy(buffer_view->View()->Buffer()->Data(), BufferBase()->Data(),
387 data_length * buffer_view->TypeSize());
388 return new ImageData(size_, buffer_view, &color_settings_);
389 }
390
391 // Crops ImageData to the intersect of its size and the given rectangle. If the
392 // intersection is empty or it cannot create the cropped ImageData it returns
393 // nullptr. This function leaves the source ImageData intact. When crop_rect
394 // covers all the ImageData and the copy parameter is false, "this" is returned.
395 // Otherwise, a copy of the ImageData is returned.
396 ImageData* ImageData::MakeSubset(const IntRect& crop_rect, bool enforce_copy) {
397 IntRect src_rect(IntPoint(), size_);
398 const IntRect dst_rect = Intersection(src_rect, crop_rect);
399 if (dst_rect.IsEmpty())
400 return nullptr;
401 if (src_rect == dst_rect) {
402 if (enforce_copy)
403 return MakeCopy();
404 return this;
405 }
406
407 unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height();
408 DOMUint8ClampedArray* data_u8 = nullptr;
409 DOMUint16Array* data_u16 = nullptr;
410 DOMFloat32Array* data_f32 = nullptr;
411 if (data_)
412 data_u8 = AllocateAndValidateUint8ClampedArray(data_size);
413 else if (data_u16_)
414 data_u16 = AllocateAndValidateUint16Array(data_size);
415 else if (data_f32_)
416 data_f32 = AllocateAndValidateFloat32Array(data_size);
417
418 int src_index = 0, dst_index = 0;
419 for (int i = 0; i < dst_rect.Height(); i++) {
420 src_index = ((i + dst_rect.X()) * src_rect.Width() + dst_rect.Y()) * 4;
421 dst_index = i * dst_rect.Width() * 4;
422 if (data_) {
423 std::memcpy(data_u8->Data() + dst_index, data_->Data() + src_index,
424 dst_rect.Width() * 4);
425 } else if (data_u16_) {
426 std::memcpy(data_u16->Data() + dst_index, data_u16_->Data() + src_index,
427 dst_rect.Width() * 8);
428 } else if (data_f32_) {
429 std::memcpy(data_f32->Data() + dst_index, data_f32_->Data() + src_index,
430 dst_rect.Width() * 16);
431 }
432 }
433
434 if (data_)
435 return new ImageData(dst_rect.Size(), data_u8, &color_settings_);
436 if (data_u16_)
437 return new ImageData(dst_rect.Size(), data_u16, &color_settings_);
438 return new ImageData(dst_rect.Size(), data_f32, &color_settings_);
439 }
440
370 ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state, 441 ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state,
371 EventTarget& event_target, 442 EventTarget& event_target,
372 Optional<IntRect> crop_rect, 443 Optional<IntRect> crop_rect,
373 const ImageBitmapOptions& options, 444 const ImageBitmapOptions& options,
374 ExceptionState& exception_state) { 445 ExceptionState& exception_state) {
375 if ((crop_rect && 446 if ((crop_rect &&
376 !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(), 447 !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(),
377 exception_state)) || 448 exception_state)) ||
378 !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(), 449 !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(),
379 BitmapSourceSize().Height(), 450 BitmapSourceSize().Height(),
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 // For ImageData, the color space is only specified by color settings. 667 // For ImageData, the color space is only specified by color settings.
597 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this. 668 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
598 sk_sp<SkColorSpace> ImageData::GetSkColorSpace() { 669 sk_sp<SkColorSpace> ImageData::GetSkColorSpace() {
599 if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() || 670 if (!RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled() ||
600 !RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) 671 !RuntimeEnabledFeatures::colorCorrectRenderingEnabled())
601 return nullptr; 672 return nullptr;
602 673
603 return SkColorSpace::MakeSRGB(); 674 return SkColorSpace::MakeSRGB();
604 } 675 }
605 676
606 // This function returns the proper SkColorSpace to color correct the pixels
607 // stored in ImageData before copying to the canvas. For now, it assumes that
608 // both ImageData and canvas use a linear gamma curve.
609 sk_sp<SkColorSpace> ImageData::GetSkColorSpace(
610 const CanvasColorSpace& color_space,
611 const CanvasPixelFormat& pixel_format) {
612 switch (color_space) {
613 case kLegacyCanvasColorSpace:
614 return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace();
615 case kSRGBCanvasColorSpace:
616 if (pixel_format == kF16CanvasPixelFormat)
617 return (gfx::ColorSpace::CreateSCRGBLinear()).ToSkColorSpace();
618 return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace();
619 case kRec2020CanvasColorSpace:
620 return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
621 gfx::ColorSpace::TransferID::LINEAR))
622 .ToSkColorSpace();
623 case kP3CanvasColorSpace:
624 return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTEST432_1,
625 gfx::ColorSpace::TransferID::LINEAR))
626 .ToSkColorSpace();
627 }
628 NOTREACHED();
629 return nullptr;
630 }
631
632 sk_sp<SkColorSpace> ImageData::GetSkColorSpaceForTest(
633 const CanvasColorSpace& color_space,
634 const CanvasPixelFormat& pixel_format) {
635 return GetSkColorSpace(color_space, pixel_format);
636 }
637
638 bool ImageData::ImageDataInCanvasColorSettings( 677 bool ImageData::ImageDataInCanvasColorSettings(
639 const CanvasColorSpace& canvas_color_space, 678 const CanvasColorSpace& canvas_color_space,
640 const CanvasPixelFormat& canvas_pixel_format, 679 const CanvasPixelFormat& canvas_pixel_format,
641 std::unique_ptr<uint8_t[]>& converted_pixels) { 680 std::unique_ptr<uint8_t[]>& converted_pixels) {
642 if (!data_ && !data_u16_ && !data_f32_) 681 if (!data_ && !data_u16_ && !data_f32_)
643 return false; 682 return false;
644 683
645 // If canvas and image data are both in the same color space and pixel format 684 // If canvas and image data are both in the same color space and pixel format
646 // is 8-8-8-8, just return the embedded data. 685 // is 8-8-8-8, just return the embedded data.
647 CanvasColorSpace image_data_color_space = 686 CanvasColorSpace image_data_color_space =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 } else if (data_f32_) { 725 } else if (data_f32_) {
687 src_data = static_cast<void*>(data_f32_->Data()); 726 src_data = static_cast<void*>(data_f32_->Data());
688 DCHECK(src_data); 727 DCHECK(src_data);
689 src_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat; 728 src_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat;
690 } else { 729 } else {
691 NOTREACHED(); 730 NOTREACHED();
692 } 731 }
693 732
694 sk_sp<SkColorSpace> src_color_space = nullptr; 733 sk_sp<SkColorSpace> src_color_space = nullptr;
695 if (data_) { 734 if (data_) {
696 src_color_space = ImageData::GetSkColorSpace(image_data_color_space, 735 src_color_space =
697 kRGBA8CanvasPixelFormat); 736 CanvasColorParams(image_data_color_space, kRGBA8CanvasPixelFormat)
737 .GetSkColorSpaceForSkSurfaces();
698 } else { 738 } else {
699 src_color_space = ImageData::GetSkColorSpace(image_data_color_space, 739 src_color_space =
700 kF16CanvasPixelFormat); 740 CanvasColorParams(image_data_color_space, kF16CanvasPixelFormat)
741 .GetSkColorSpaceForSkSurfaces();
701 } 742 }
702 743
703 sk_sp<SkColorSpace> dst_color_space = 744 sk_sp<SkColorSpace> dst_color_space =
704 ImageData::GetSkColorSpace(canvas_color_space, canvas_pixel_format); 745 CanvasColorParams(canvas_color_space, canvas_pixel_format)
705 746 .GetSkColorSpaceForSkSurfaces();
706 SkColorSpaceXform::ColorFormat dst_color_format = 747 SkColorSpaceXform::ColorFormat dst_color_format =
707 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; 748 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
708 if (canvas_pixel_format == kF16CanvasPixelFormat) 749 if (canvas_pixel_format == kF16CanvasPixelFormat)
709 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat; 750 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
710 751
711 if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get()) && 752 if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get()) &&
712 src_color_format == dst_color_format) 753 src_color_format == dst_color_format)
713 return static_cast<unsigned char*>(src_data); 754 return static_cast<unsigned char*>(src_data);
714 755
715 std::unique_ptr<SkColorSpaceXform> xform = 756 std::unique_ptr<SkColorSpaceXform> xform =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 SECURITY_CHECK(static_cast<unsigned>(size.Width() * size.Height() * 4) <= 820 SECURITY_CHECK(static_cast<unsigned>(size.Width() * size.Height() * 4) <=
780 data_f32_->length()); 821 data_f32_->length());
781 break; 822 break;
782 823
783 default: 824 default:
784 NOTREACHED(); 825 NOTREACHED();
785 } 826 }
786 } 827 }
787 828
788 } // namespace blink 829 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698