| 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
5 #include "impeller/image/decompressed_image.h"
6
7 #include <limits>
8
9 #include "flutter/fml/mapping.h"
10 #include "impeller/base/allocation.h"
11
12 namespace impeller {
13
14 DecompressedImage::DecompressedImage() = default;
15
16 DecompressedImage::DecompressedImage(
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
27 DecompressedImage::~DecompressedImage() = default;
28
29 bool DecompressedImage::IsValid() const {
30 return is_valid_;
31 }
32
33 const ISize& DecompressedImage::GetSize() const {
34 return size_;
35 }
36
37 DecompressedImage::Format DecompressedImage::GetFormat() const {
38 return format_;
39 }
40
41 const std::shared_ptr<const fml::Mapping>& DecompressedImage::GetAllocation()
42 const {
43 return allocation_;
44 }
45
46 static size_t GetBytesPerPixel(DecompressedImage::Format format) {
47 switch (format) {
48 case DecompressedImage::Format::kInvalid:
49 return 0u;
50 case DecompressedImage::Format::kGrey:
51 return 1u;
52 case DecompressedImage::Format::kGreyAlpha:
53 return 1u;
54 case DecompressedImage::Format::kRGB:
55 return 3u;
56 case DecompressedImage::Format::kRGBA:
57 return 4;
58 }
59 return 0u;
60 }
61
62 DecompressedImage DecompressedImage::ConvertToRGBA() const {
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(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_) {
87 case DecompressedImage::Format::kGrey:
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;
93 case DecompressedImage::Format::kGreyAlpha:
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;
99 case DecompressedImage::Format::kRGB:
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;
105 case DecompressedImage::Format::kInvalid:
106 case DecompressedImage::Format::kRGBA:
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(), //
119 [rgba_allocation](auto, auto) {}) //
120 };
121 }
122
123 } // namespace impeller
impeller::DecompressedImage
Definition: decompressed_image.h:17
impeller::DecompressedImage::Format::kRGBA
@ kRGBA
allocation.h
impeller::DecompressedImage::Format::kGrey
@ kGrey
impeller::GetBytesPerPixel
static size_t GetBytesPerPixel(DecompressedImage::Format format)
Definition: decompressed_image.cc:46
impeller::TSize< int64_t >
impeller::DecompressedImage::ConvertToRGBA
DecompressedImage ConvertToRGBA() const
Definition: decompressed_image.cc:62
impeller::DecompressedImage::Format::kRGB
@ kRGB
impeller::DecompressedImage::GetFormat
Format GetFormat() const
Definition: decompressed_image.cc:37
impeller::DecompressedImage::IsValid
bool IsValid() const
Definition: decompressed_image.cc:29
decompressed_image.h
impeller::TSize::Area
constexpr Type Area() const
Definition: size.h:102
std
Definition: comparable.h:95
impeller::DecompressedImage::DecompressedImage
DecompressedImage()
impeller::DecompressedImage::GetAllocation
const std::shared_ptr< const fml::Mapping > & GetAllocation() const
Definition: decompressed_image.cc:41
impeller::DecompressedImage::~DecompressedImage
~DecompressedImage()
impeller::DecompressedImage::Format
Format
Definition: decompressed_image.h:19
impeller::TSize::IsEmpty
constexpr bool IsEmpty() const
Returns true if either of the width or height are 0, negative, or NaN.
Definition: size.h:105
impeller::DecompressedImage::Format::kGreyAlpha
@ kGreyAlpha
impeller
Definition: aiks_context.cc:10
impeller::DecompressedImage::GetSize
const ISize & GetSize() const
Definition: decompressed_image.cc:33
impeller::DecompressedImage::Format::kInvalid
@ kInvalid