Flutter Engine
image_descriptor.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_LIB_UI_PAINTING_IMAGE_DESCRIPTOR_H_
6 #define FLUTTER_LIB_UI_PAINTING_IMAGE_DESCRIPTOR_H_
7 
8 #include <cstdint>
9 #include <memory>
10 #include <optional>
11 
12 #include "flutter/fml/macros.h"
13 #include "flutter/lib/ui/dart_wrapper.h"
14 #include "flutter/lib/ui/painting/image_generator_registry.h"
15 #include "flutter/lib/ui/painting/immutable_buffer.h"
16 #include "third_party/skia/include/codec/SkCodec.h"
17 #include "third_party/skia/include/core/SkImageGenerator.h"
18 #include "third_party/skia/include/core/SkImageInfo.h"
19 #include "third_party/skia/src/codec/SkCodecImageGenerator.h"
21 
22 namespace flutter {
23 
24 /// @brief Creates an image descriptor for encoded or decoded image data,
25 /// describing the width, height, and bytes per pixel for that image.
26 /// This class will hold a reference on the underlying image data, and
27 /// in the case of compressed data, an `ImageGenerator` for the data.
28 /// The Codec initialization actually happens in initEncoded, making
29 /// `initstantiateCodec` a lightweight operation.
30 /// @see `ImageGenerator`
31 class ImageDescriptor : public RefCountedDartWrappable<ImageDescriptor> {
32  public:
33  ~ImageDescriptor() override = default;
34 
35  // This must be kept in sync with the enum in painting.dart
36  enum PixelFormat {
39  };
40 
41  /// @brief Asynchronously initlializes an ImageDescriptor for an encoded
42  /// image, as long as the format is recognized by an encoder installed
43  /// in the `ImageGeneratorRegistry`. Calling this method will create
44  /// an `ImageGenerator` and read EXIF corrected dimensions from the
45  /// image data.
46  /// @see `ImageGeneratorRegistry`
47  static void initEncoded(Dart_NativeArguments args);
48 
49  /// @brief Synchronously initializes an `ImageDescriptor` for decompressed
50  /// image data as specified by the `PixelFormat`.
51  static void initRaw(Dart_Handle descriptor_handle,
53  int width,
54  int height,
55  int row_bytes,
56  PixelFormat pixel_format);
57 
58  /// @brief Associates a flutter::Codec object with the dart.ui Codec handle.
59  void instantiateCodec(Dart_Handle codec, int target_width, int target_height);
60 
61  /// @brief The width of this image, EXIF oriented if applicable.
62  int width() const { return image_info_.width(); }
63 
64  /// @brief The height of this image. EXIF oriented if applicable.
65  int height() const { return image_info_.height(); }
66 
67  /// @brief The bytes per pixel of the image.
68  int bytesPerPixel() const { return image_info_.bytesPerPixel(); }
69 
70  /// @brief The byte length of the first row of the image.
71  /// Defaults to width() * 4.
72  int row_bytes() const {
73  return row_bytes_.value_or(
74  static_cast<size_t>(image_info_.width() * image_info_.bytesPerPixel()));
75  }
76 
77  /// @brief Whether the given `target_width` or `target_height` differ from
78  /// `width()` and `height()` respectively.
79  bool should_resize(int target_width, int target_height) const {
80  return target_width != width() || target_height != height();
81  }
82 
83  /// @brief The underlying buffer for this image.
84  sk_sp<SkData> data() const { return buffer_; }
85 
86  sk_sp<SkImage> image() const;
87 
88  /// @brief Whether this descriptor represents compressed (encoded) data or
89  /// not.
90  bool is_compressed() const { return !!generator_; }
91 
92  /// @brief The orientation corrected image info for this image.
93  const SkImageInfo& image_info() const { return image_info_; }
94 
95  /// @brief Gets the scaled dimensions of this image, if backed by an
96  /// `ImageGenerator` that can perform efficient subpixel scaling.
97  /// @see `ImageGenerator::GetScaledDimensions`
98  SkISize get_scaled_dimensions(float scale) {
99  if (generator_) {
100  return generator_->GetScaledDimensions(scale);
101  }
102  return image_info_.dimensions();
103  }
104 
105  /// @brief Gets pixels for this image transformed based on the EXIF
106  /// orientation tag, if applicable.
107  bool get_pixels(const SkPixmap& pixmap) const;
108 
109  void dispose() {
110  buffer_.reset();
111  generator_.reset();
113  }
114 
115  size_t GetAllocationSize() const override {
116  return sizeof(ImageDescriptor) + sizeof(SkImageInfo) + buffer_->size();
117  }
118 
119  static void RegisterNatives(tonic::DartLibraryNatives* natives);
120 
121  private:
122  ImageDescriptor(sk_sp<SkData> buffer,
123  const SkImageInfo& image_info,
124  std::optional<size_t> row_bytes);
125  ImageDescriptor(sk_sp<SkData> buffer,
126  std::shared_ptr<ImageGenerator> generator);
127 
128  sk_sp<SkData> buffer_;
129  std::shared_ptr<ImageGenerator> generator_;
130  const SkImageInfo image_info_;
131  std::optional<size_t> row_bytes_;
132 
133  const SkImageInfo CreateImageInfo() const;
134 
135  DEFINE_WRAPPERTYPEINFO();
136  FML_FRIEND_MAKE_REF_COUNTED(ImageDescriptor);
137  FML_DISALLOW_COPY_AND_ASSIGN(ImageDescriptor);
138 
140 };
141 
142 } // namespace flutter
143 
144 #endif // FLUTTER_LIB_UI_PAINTING_IMAGE_DESCRIPTOR_H_
G_BEGIN_DECLS FlValue * args
bool should_resize(int target_width, int target_height) const
Whether the given target_width or target_height differ from width() and height() respectively.
sk_sp< SkImage > image() const
friend class ImageDecoderFixtureTest
SkISize get_scaled_dimensions(float scale)
Gets the scaled dimensions of this image, if backed by an ImageGenerator that can perform efficient s...
static void initEncoded(Dart_NativeArguments args)
Asynchronously initlializes an ImageDescriptor for an encoded image, as long as the format is recogni...
Creates an image descriptor for encoded or decoded image data, describing the width, height, and bytes per pixel for that image. This class will hold a reference on the underlying image data, and in the case of compressed data, an ImageGenerator for the data. The Codec initialization actually happens in initEncoded, making initstantiateCodec a lightweight operation.
static void initRaw(Dart_Handle descriptor_handle, fml::RefPtr< ImmutableBuffer > data, int width, int height, int row_bytes, PixelFormat pixel_format)
Synchronously initializes an ImageDescriptor for decompressed image data as specified by the PixelFor...
static void RegisterNatives(tonic::DartLibraryNatives *natives)
int row_bytes() const
The byte length of the first row of the image. Defaults to width() * 4.
int bytesPerPixel() const
The bytes per pixel of the image.
size_t GetAllocationSize() const override
sk_sp< SkData > data() const
The underlying buffer for this image.
~ImageDescriptor() override=default
const SkImageInfo & image_info() const
The orientation corrected image info for this image.
int height() const
The height of this image. EXIF oriented if applicable.
static const uint8_t buffer[]
void instantiateCodec(Dart_Handle codec, int target_width, int target_height)
Associates a flutter::Codec object with the dart.ui Codec handle.
int width() const
The width of this image, EXIF oriented if applicable.
bool is_compressed() const
Whether this descriptor represents compressed (encoded) data or not.
bool get_pixels(const SkPixmap &pixmap) const
Gets pixels for this image transformed based on the EXIF orientation tag, if applicable.