OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |