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