Flutter Impeller
decompressed_image.cc
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 
6 
7 #include <limits>
8 
9 #include "flutter/fml/mapping.h"
11 
12 namespace impeller {
13 
15 
17  ISize size,
18  Format format,
19  std::shared_ptr<const fml::Mapping> allocation)
20  : size_(size), format_(format), allocation_(std::move(allocation)) {
21  if (!allocation_ || size.IsEmpty() || format_ == Format::kInvalid) {
22  return;
23  }
24  is_valid_ = true;
25 }
26 
28 
30  return is_valid_;
31 }
32 
34  return size_;
35 }
36 
38  return format_;
39 }
40 
41 const std::shared_ptr<const fml::Mapping>& DecompressedImage::GetAllocation()
42  const {
43  return allocation_;
44 }
45 
47  switch (format) {
49  return 0u;
51  return 1u;
53  return 1u;
55  return 3u;
57  return 4;
58  }
59  return 0u;
60 }
61 
63  if (!is_valid_) {
64  return {};
65  }
66 
67  if (format_ == Format::kRGBA) {
68  return DecompressedImage{size_, format_, allocation_};
69  }
70 
71  const auto bpp = GetBytesPerPixel(format_);
72  const auto source_byte_size = size_.Area() * bpp;
73  if (allocation_->GetSize() < source_byte_size) {
74  return {};
75  }
76 
77  auto rgba_allocation = std::make_shared<Allocation>();
78  if (!rgba_allocation->Truncate(Bytes{size_.Area() * 4u}, false)) {
79  return {};
80  }
81 
82  const uint8_t* source = allocation_->GetMapping();
83  uint8_t* dest = rgba_allocation->GetBuffer();
84 
85  for (size_t i = 0, j = 0; i < source_byte_size; i += bpp, j += 4u) {
86  switch (format_) {
88  dest[j + 0] = source[i];
89  dest[j + 1] = source[i];
90  dest[j + 2] = source[i];
91  dest[j + 3] = std::numeric_limits<uint8_t>::max();
92  break;
94  dest[j + 0] = std::numeric_limits<uint8_t>::max();
95  dest[j + 1] = std::numeric_limits<uint8_t>::max();
96  dest[j + 2] = std::numeric_limits<uint8_t>::max();
97  dest[j + 3] = source[i];
98  break;
100  dest[j + 0] = source[i + 0];
101  dest[j + 1] = source[i + 1];
102  dest[j + 2] = source[i + 2];
103  dest[j + 3] = std::numeric_limits<uint8_t>::max();
104  break;
107  // Should never happen. The necessary checks have already been
108  // performed.
109  FML_CHECK(false);
110  break;
111  }
112  }
113 
114  return DecompressedImage{
115  size_, Format::kRGBA,
116  std::make_shared<fml::NonOwnedMapping>(
117  rgba_allocation->GetBuffer(), //
118  rgba_allocation->GetLength().GetByteSize(), //
119  [rgba_allocation](auto, auto) {}) //
120  };
121 }
122 
123 } // namespace impeller
DecompressedImage ConvertToRGBA() const
const std::shared_ptr< const fml::Mapping > & GetAllocation() const
const ISize & GetSize() const
static size_t GetBytesPerPixel(DecompressedImage::Format format)
Definition: comparable.h:95
constexpr Type Area() const
Definition: size.h:120
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:123