| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_IMAGEBITMAP_IMAGE_BITMAP_H_ |
| #define THIRD_PARTY_BLINK_RENDERER_CORE_IMAGEBITMAP_IMAGE_BITMAP_H_ |
| |
| #include <memory> |
| |
| #include "base/memory/scoped_refptr.h" |
| #include "base/task/sequenced_task_runner.h" |
| #include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom-blink.h" |
| #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" |
| #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" |
| #include "third_party/blink/renderer/bindings/core/v8/v8_image_bitmap_options.h" |
| #include "third_party/blink/renderer/core/core_export.h" |
| #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h" |
| #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" |
| #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" |
| #include "third_party/blink/renderer/platform/bindings/v8_external_memory_accounter.h" |
| #include "third_party/blink/renderer/platform/graphics/image.h" |
| #include "third_party/blink/renderer/platform/graphics/image_orientation.h" |
| #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" |
| #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" |
| #include "third_party/blink/renderer/platform/wtf/functional.h" |
| #include "third_party/skia/include/core/SkRefCnt.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| namespace blink { |
| class HTMLCanvasElement; |
| class HTMLVideoElement; |
| class ImageData; |
| class ImageElementBase; |
| class ImageDecoder; |
| class OffscreenCanvas; |
| |
| class CORE_EXPORT ImageBitmap final : public ScriptWrappable, |
| public CanvasImageSource, |
| public ImageBitmapSource { |
| DEFINE_WRAPPERTYPEINFO(); |
| |
| public: |
| // Expects the ImageElementBase to return/have an SVGImage. |
| static ScriptPromise<ImageBitmap> CreateAsync( |
| ImageElementBase*, |
| std::optional<gfx::Rect>, |
| ScriptState*, |
| scoped_refptr<base::SequencedTaskRunner> task_runner, |
| mojom::blink::PreferredColorScheme, |
| ExceptionState&, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| static sk_sp<SkImage> GetSkImageFromDecoder(std::unique_ptr<ImageDecoder>); |
| |
| ImageBitmap(ImageElementBase*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(HTMLVideoElement*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(HTMLCanvasElement*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(OffscreenCanvas*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(ImageData*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(ImageBitmap*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| ImageBitmap(scoped_refptr<StaticBitmapImage>); |
| ImageBitmap(scoped_refptr<StaticBitmapImage>, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions* = ImageBitmapOptions::Create()); |
| // This constructor may called by structured-cloning an ImageBitmap. |
| // isImageBitmapOriginClean indicates whether the original ImageBitmap is |
| // origin clean or not. |
| ImageBitmap(const SkPixmap& pixmap, |
| bool is_image_bitmap_origin_clean, |
| ImageOrientationEnum); |
| |
| scoped_refptr<StaticBitmapImage> BitmapImage() const { return image_; } |
| |
| // Retrieve the SkImageInfo that best represents BitmapImage(). |
| SkImageInfo GetBitmapSkImageInfo() const; |
| |
| // When apply_orientation is true this method will orient the data according |
| // to the source's EXIF information. |
| Vector<uint8_t> CopyBitmapData(const SkImageInfo& info, |
| bool apply_orientation); |
| unsigned width() const; |
| unsigned height() const; |
| gfx::Size Size() const; |
| |
| bool IsNeutered() const override { return is_neutered_; } |
| bool OriginClean() const { return image_->OriginClean(); } |
| bool IsPremultiplied() const { return image_->IsPremultiplied(); } |
| ImageOrientationEnum ImageOrientation() const { |
| return image_->Orientation().Orientation(); |
| } |
| scoped_refptr<StaticBitmapImage> Transfer(); |
| void close(); |
| |
| ~ImageBitmap() override; |
| |
| // CanvasImageSource implementation |
| scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, |
| const gfx::SizeF&) override; |
| bool WouldTaintOrigin() const override { |
| return image_ && !image_->OriginClean(); |
| } |
| gfx::SizeF ElementSize(const gfx::SizeF&, |
| const RespectImageOrientationEnum) const override; |
| bool IsImageBitmap() const override { return true; } |
| bool IsAccelerated() const override; |
| |
| // ImageBitmapSource implementation |
| ImageBitmapSourceStatus CheckUsability() const override; |
| ScriptPromise<ImageBitmap> CreateImageBitmap(ScriptState*, |
| std::optional<gfx::Rect>, |
| const ImageBitmapOptions*, |
| ExceptionState&) override; |
| |
| struct ParsedOptions { |
| // If true, then the final result should be flipped vertically. This happens |
| // in the space after `source_orientation` has been applied. |
| bool flip_y = false; |
| bool premultiply_alpha = true; |
| // TODO(crbug.com/40773069): This is based on the incorrect values and needs |
| // to be removed. |
| bool should_scale_input = false; |
| bool has_color_space_conversion = false; |
| bool orientation_from_image = true; |
| // TODO(crbug.com/40773069): The value of `resize_width`, `resize_height`, |
| // and `crop_rect` are computed incorrectly. Remove this when all code that |
| // uses it is removed. |
| unsigned resize_width = 0; |
| unsigned resize_height = 0; |
| gfx::Rect crop_rect; |
| cc::PaintFlags::FilterQuality resize_quality = |
| cc::PaintFlags::FilterQuality::kLow; |
| |
| // The sampling options to use. This will be set to nearest-neighbor if no |
| // resampling is performed. |
| SkSamplingOptions sampling; |
| |
| // The orientation of the source. |
| class ImageOrientation source_orientation; |
| |
| // The `source_size`, `source_rect`, and `dest_size` parameters are all in |
| // the space after the `source_orientation` has been applied. |
| gfx::Size source_size; |
| gfx::Rect source_rect; |
| gfx::Size dest_size; |
| |
| // Compute the parameters for creating and then resizing a subset of the |
| // source image. In the underlying PaintImage, `source_skrect` corresponds |
| // to `source_rect`, `source_skrect_valid` corresponds to the intersection |
| // of that with the PaintImage size, and `dest_sksize` corresponds to the |
| // output size. |
| void ComputeSubsetParameters(SkIRect& source_skrect, |
| SkIRect& source_skrect_valid, |
| SkISize& dest_sksize) const; |
| }; |
| |
| private: |
| void UpdateImageBitmapMemoryUsage(); |
| static void ResolvePromiseOnOriginalThread( |
| ScriptPromiseResolver<ImageBitmap>*, |
| bool origin_clean, |
| std::unique_ptr<ParsedOptions>, |
| sk_sp<SkImage>, |
| const ImageOrientationEnum); |
| static void RasterizeImageOnBackgroundThread( |
| PaintRecord, |
| const gfx::Rect&, |
| scoped_refptr<base::SequencedTaskRunner>, |
| CrossThreadOnceFunction<void(sk_sp<SkImage>, const ImageOrientationEnum)> |
| callback); |
| scoped_refptr<StaticBitmapImage> image_; |
| bool is_neutered_ = false; |
| int32_t memory_usage_ = 0; |
| NO_UNIQUE_ADDRESS V8ExternalMemoryAccounterBase external_memory_accounter_; |
| }; |
| |
| } // namespace blink |
| |
| #endif // THIRD_PARTY_BLINK_RENDERER_CORE_IMAGEBITMAP_IMAGE_BITMAP_H_ |