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

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

Issue 2849643002: Implement ImageData::CropRect() (Closed)
Patch Set: Addressing comments Created 3 years, 6 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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 358
359 // This function is called from unit tests, and all the parameters are supposed 359 // This function is called from unit tests, and all the parameters are supposed
360 // to be validated on the call site. 360 // to be validated on the call site.
361 ImageData* ImageData::CreateForTest( 361 ImageData* ImageData::CreateForTest(
362 const IntSize& size, 362 const IntSize& size,
363 DOMArrayBufferView* buffer_view, 363 DOMArrayBufferView* buffer_view,
364 const ImageDataColorSettings* color_settings) { 364 const ImageDataColorSettings* color_settings) {
365 return new ImageData(size, buffer_view, color_settings); 365 return new ImageData(size, buffer_view, color_settings);
366 } 366 }
367 367
368 // Crops ImageData to the intersect of its size and the given rectangle. If the
369 // intersection is empty or it cannot create the cropped ImageData it returns
370 // nullptr. This function leaves the source ImageData intact. When crop_rect
371 // covers all the ImageData, a copy of the ImageData is returned.
372 ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) {
373 IntRect src_rect(IntPoint(), size_);
374 const IntRect dst_rect = Intersection(src_rect, crop_rect);
375 if (dst_rect.IsEmpty())
376 return nullptr;
377
378 unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height();
379 DOMArrayBufferView* buffer_view = AllocateAndValidateDataArray(
380 data_size,
381 ImageData::GetImageDataStorageFormat(color_settings_.storageFormat()));
382 if (!buffer_view)
383 return nullptr;
384
385 if (src_rect == dst_rect && !flip_y) {
386 std::memcpy(buffer_view->BufferBase()->Data(), BufferBase()->Data(),
387 data_size * buffer_view->TypeSize());
388 } else {
389 unsigned data_type_size =
390 ImageData::StorageFormatDataSize(color_settings_.storageFormat());
391 int src_index = (dst_rect.X() * src_rect.Width() + dst_rect.Y()) * 4;
392 int dst_index = 0;
393 if (flip_y)
394 dst_index = (dst_rect.Height() - 1) * dst_rect.Width() * 4;
395 int src_row_stride = src_rect.Width() * 4;
396 int dst_row_stride = flip_y ? -dst_rect.Width() * 4 : dst_rect.Width() * 4;
397 for (int i = 0; i < dst_rect.Height(); i++) {
398 std::memcpy(
399 static_cast<char*>(buffer_view->BufferBase()->Data()) +
400 dst_index * data_type_size,
401 static_cast<char*>(BufferBase()->Data()) + src_index * data_type_size,
402 dst_rect.Width() * 4 * data_type_size);
403 src_index += src_row_stride;
404 dst_index += dst_row_stride;
405 }
406 }
407 return new ImageData(dst_rect.Size(), buffer_view, &color_settings_);
408 }
409
368 ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state, 410 ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state,
369 EventTarget& event_target, 411 EventTarget& event_target,
370 Optional<IntRect> crop_rect, 412 Optional<IntRect> crop_rect,
371 const ImageBitmapOptions& options, 413 const ImageBitmapOptions& options,
372 ExceptionState& exception_state) { 414 ExceptionState& exception_state) {
373 if ((crop_rect && 415 if ((crop_rect &&
374 !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(), 416 !ImageBitmap::IsSourceSizeValid(crop_rect->Width(), crop_rect->Height(),
375 exception_state)) || 417 exception_state)) ||
376 !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(), 418 !ImageBitmap::IsSourceSizeValid(BitmapSourceSize().Width(),
377 BitmapSourceSize().Height(), 419 BitmapSourceSize().Height(),
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 635
594 // For ImageData, the color space is only specified by color settings. 636 // For ImageData, the color space is only specified by color settings.
595 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this. 637 // It cannot have a SkColorSpace. This doesn't mean anything. Fix this.
596 sk_sp<SkColorSpace> ImageData::GetSkColorSpace() { 638 sk_sp<SkColorSpace> ImageData::GetSkColorSpace() {
597 if (!RuntimeEnabledFeatures::colorCanvasExtensionsEnabled()) 639 if (!RuntimeEnabledFeatures::colorCanvasExtensionsEnabled())
598 return nullptr; 640 return nullptr;
599 641
600 return SkColorSpace::MakeSRGB(); 642 return SkColorSpace::MakeSRGB();
601 } 643 }
602 644
603 // This function returns the proper SkColorSpace to color correct the pixels
604 // stored in ImageData before copying to the canvas. For now, it assumes that
605 // both ImageData and canvas use a linear gamma curve.
606 sk_sp<SkColorSpace> ImageData::GetSkColorSpace(
607 const CanvasColorSpace& color_space,
608 const CanvasPixelFormat& pixel_format) {
609 switch (color_space) {
610 case kLegacyCanvasColorSpace:
611 return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace();
612 case kSRGBCanvasColorSpace:
613 if (pixel_format == kF16CanvasPixelFormat)
614 return (gfx::ColorSpace::CreateSCRGBLinear()).ToSkColorSpace();
615 return (gfx::ColorSpace::CreateSRGB()).ToSkColorSpace();
616 case kRec2020CanvasColorSpace:
617 return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::BT2020,
618 gfx::ColorSpace::TransferID::LINEAR))
619 .ToSkColorSpace();
620 case kP3CanvasColorSpace:
621 return (gfx::ColorSpace(gfx::ColorSpace::PrimaryID::SMPTEST432_1,
622 gfx::ColorSpace::TransferID::LINEAR))
623 .ToSkColorSpace();
624 }
625 NOTREACHED();
626 return nullptr;
627 }
628
629 sk_sp<SkColorSpace> ImageData::GetSkColorSpaceForTest(
630 const CanvasColorSpace& color_space,
631 const CanvasPixelFormat& pixel_format) {
632 return GetSkColorSpace(color_space, pixel_format);
633 }
634
635 bool ImageData::ImageDataInCanvasColorSettings( 645 bool ImageData::ImageDataInCanvasColorSettings(
636 const CanvasColorSpace& canvas_color_space, 646 const CanvasColorSpace& canvas_color_space,
637 const CanvasPixelFormat& canvas_pixel_format, 647 const CanvasPixelFormat& canvas_pixel_format,
638 std::unique_ptr<uint8_t[]>& converted_pixels) { 648 std::unique_ptr<uint8_t[]>& converted_pixels) {
639 if (!data_ && !data_u16_ && !data_f32_) 649 if (!data_ && !data_u16_ && !data_f32_)
640 return false; 650 return false;
641 651
642 // If canvas and image data are both in the same color space and pixel format 652 // If canvas and image data are both in the same color space and pixel format
643 // is 8-8-8-8, just return the embedded data. 653 // is 8-8-8-8, just return the embedded data.
644 CanvasColorSpace image_data_color_space = 654 CanvasColorSpace image_data_color_space =
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 } else if (data_f32_) { 693 } else if (data_f32_) {
684 src_data = static_cast<void*>(data_f32_->Data()); 694 src_data = static_cast<void*>(data_f32_->Data());
685 DCHECK(src_data); 695 DCHECK(src_data);
686 src_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat; 696 src_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F32_ColorFormat;
687 } else { 697 } else {
688 NOTREACHED(); 698 NOTREACHED();
689 } 699 }
690 700
691 sk_sp<SkColorSpace> src_color_space = nullptr; 701 sk_sp<SkColorSpace> src_color_space = nullptr;
692 if (data_) { 702 if (data_) {
693 src_color_space = ImageData::GetSkColorSpace(image_data_color_space, 703 src_color_space =
694 kRGBA8CanvasPixelFormat); 704 CanvasColorParams(image_data_color_space, kRGBA8CanvasPixelFormat)
705 .GetSkColorSpaceForSkSurfaces();
695 } else { 706 } else {
696 src_color_space = ImageData::GetSkColorSpace(image_data_color_space, 707 src_color_space =
697 kF16CanvasPixelFormat); 708 CanvasColorParams(image_data_color_space, kF16CanvasPixelFormat)
709 .GetSkColorSpaceForSkSurfaces();
698 } 710 }
699 711
700 sk_sp<SkColorSpace> dst_color_space = 712 sk_sp<SkColorSpace> dst_color_space =
701 ImageData::GetSkColorSpace(canvas_color_space, canvas_pixel_format); 713 CanvasColorParams(canvas_color_space, canvas_pixel_format)
702 714 .GetSkColorSpaceForSkSurfaces();
703 SkColorSpaceXform::ColorFormat dst_color_format = 715 SkColorSpaceXform::ColorFormat dst_color_format =
704 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; 716 SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
705 if (canvas_pixel_format == kF16CanvasPixelFormat) 717 if (canvas_pixel_format == kF16CanvasPixelFormat)
706 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat; 718 dst_color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
707 719
708 if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get()) && 720 if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get()) &&
709 src_color_format == dst_color_format) 721 src_color_format == dst_color_format)
710 return static_cast<unsigned char*>(src_data); 722 return static_cast<unsigned char*>(src_data);
711 723
712 std::unique_ptr<SkColorSpaceXform> xform = 724 std::unique_ptr<SkColorSpaceXform> xform =
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
776 SECURITY_CHECK(static_cast<unsigned>(size.Width() * size.Height() * 4) <= 788 SECURITY_CHECK(static_cast<unsigned>(size.Width() * size.Height() * 4) <=
777 data_f32_->length()); 789 data_f32_->length());
778 break; 790 break;
779 791
780 default: 792 default:
781 NOTREACHED(); 793 NOTREACHED();
782 } 794 }
783 } 795 }
784 796
785 } // namespace blink 797 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/html/ImageData.h ('k') | third_party/WebKit/Source/core/html/ImageDataTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698