Skip to content

Commit 555faba

Browse files
chinmaygardednfield
authored andcommitted
Avoid depending on STB in //flutter/impeller/image. (flutter#47)
1 parent a781e2f commit 555faba

File tree

365 files changed

+133
-78302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

365 files changed

+133
-78302
lines changed

impeller/image/BUILD.gn

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@
55
import("//flutter/impeller/tools/impeller.gni")
66

77
impeller_component("image") {
8+
public = [
9+
"compressed_image.h",
10+
"decompressed_image.h",
11+
]
12+
813
sources = [
14+
"backends/skia/compressed_image_skia.cc",
15+
"backends/skia/compressed_image_skia.h",
916
"compressed_image.cc",
10-
"compressed_image.h",
1117
"decompressed_image.cc",
12-
"decompressed_image.h",
1318
]
1419

15-
deps = [ "../third_party/stb" ]
20+
deps = [ "//third_party/skia" ]
1621

1722
public_deps = [
1823
"../base",
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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/backends/skia/compressed_image_skia.h"
6+
7+
#include <memory>
8+
9+
#include "impeller/base/validation.h"
10+
#include "third_party/skia/include/core/SkData.h"
11+
#include "third_party/skia/include/core/SkImageGenerator.h"
12+
#include "third_party/skia/include/core/SkPixmap.h"
13+
14+
namespace impeller {
15+
16+
CompressedImageSkia::CompressedImageSkia(
17+
std::shared_ptr<const fml::Mapping> allocation)
18+
: CompressedImage(std::move(allocation)) {}
19+
20+
CompressedImageSkia::~CompressedImageSkia() = default;
21+
22+
// |CompressedImage|
23+
DecompressedImage CompressedImageSkia::Decode() const {
24+
if (!IsValid()) {
25+
return {};
26+
}
27+
if (source_->GetSize() == 0u) {
28+
return {};
29+
}
30+
31+
auto src = new std::shared_ptr<const fml::Mapping>(source_);
32+
auto sk_data = SkData::MakeWithProc(
33+
source_->GetMapping(), source_->GetSize(),
34+
[](const void* ptr, void* context) {
35+
delete reinterpret_cast<decltype(src)>(context);
36+
},
37+
src);
38+
39+
auto generator = SkImageGenerator::MakeFromEncoded(sk_data);
40+
if (!generator) {
41+
return {};
42+
}
43+
44+
auto info = SkImageInfo::MakeN32Premul(generator->getInfo().dimensions());
45+
46+
auto bitmap = std::make_shared<SkBitmap>();
47+
if (!bitmap->tryAllocPixels(info)) {
48+
VALIDATION_LOG << "Could not allocate arena for decompressing image.";
49+
return {};
50+
}
51+
52+
if (!generator->getPixels(bitmap->pixmap())) {
53+
VALIDATION_LOG << "Could not decompress image into arena.";
54+
return {};
55+
}
56+
57+
auto mapping = std::make_shared<fml::NonOwnedMapping>(
58+
reinterpret_cast<const uint8_t*>(bitmap->pixmap().addr()), // data
59+
bitmap->pixmap().rowBytes() * bitmap->pixmap().height(), // size
60+
[bitmap](const uint8_t* data, size_t size) mutable {
61+
bitmap.reset();
62+
} // proc
63+
);
64+
65+
return {
66+
{bitmap->pixmap().dimensions().fWidth,
67+
bitmap->pixmap().dimensions().fHeight}, // size
68+
DecompressedImage::Format::kRGBA, // format
69+
mapping // allocation
70+
};
71+
}
72+
73+
} // namespace impeller
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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+
#pragma once
6+
7+
#include "flutter/fml/macros.h"
8+
#include "impeller/image/compressed_image.h"
9+
10+
namespace impeller {
11+
12+
class CompressedImageSkia final : public CompressedImage {
13+
public:
14+
CompressedImageSkia(std::shared_ptr<const fml::Mapping> allocation);
15+
16+
~CompressedImageSkia() override;
17+
18+
// |CompressedImage|
19+
DecompressedImage Decode() const override;
20+
21+
private:
22+
FML_DISALLOW_COPY_AND_ASSIGN(CompressedImageSkia);
23+
};
24+
25+
} // namespace impeller

impeller/image/compressed_image.cc

Lines changed: 11 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,82 +4,23 @@
44

55
#include "impeller/image/compressed_image.h"
66

7-
#include <stb_image.h>
8-
9-
#include "impeller/base/validation.h"
7+
#include "impeller/image/backends/skia/compressed_image_skia.h"
108

119
namespace impeller {
1210

13-
CompressedImage::CompressedImage(
14-
std::shared_ptr<const fml::Mapping> sourceAllocation)
15-
: source_(std::move(sourceAllocation)) {}
16-
17-
CompressedImage::~CompressedImage() = default;
18-
19-
DecompressedImage CompressedImage::Decode() const {
20-
if (!source_) {
21-
return {};
22-
}
23-
24-
int width = 0;
25-
int height = 0;
26-
int comps = 0;
27-
28-
stbi_uc* decoded =
29-
::stbi_load_from_memory(source_->GetMapping(), // Source Data
30-
source_->GetSize(), // Source Data Size
31-
&width, // Out: Width
32-
&height, // Out: Height
33-
&comps, // Out: Components
34-
STBI_default);
35-
36-
if (decoded == nullptr) {
37-
VALIDATION_LOG << "Could not decode image from host memory.";
38-
return {};
39-
}
40-
41-
auto dest_allocation = std::make_shared<const fml::NonOwnedMapping>(
42-
decoded, // bytes
43-
width * height * comps * sizeof(stbi_uc), // byte size
44-
[](const uint8_t* data, size_t size) {
45-
::stbi_image_free(const_cast<uint8_t*>(data));
46-
} // release proc
47-
);
48-
49-
/*
50-
* Make sure we got a valid component set.
51-
*/
52-
auto components = DecompressedImage::Format::kInvalid;
53-
54-
switch (comps) {
55-
case STBI_grey:
56-
components = DecompressedImage::Format::kGrey;
57-
break;
58-
case STBI_grey_alpha:
59-
components = DecompressedImage::Format::kGreyAlpha;
60-
break;
61-
case STBI_rgb:
62-
components = DecompressedImage::Format::kRGB;
63-
break;
64-
case STBI_rgb_alpha:
65-
components = DecompressedImage::Format::kRGBA;
66-
break;
67-
default:
68-
components = DecompressedImage::Format::kInvalid;
69-
break;
11+
std::shared_ptr<CompressedImage> CompressedImage::Create(
12+
std::shared_ptr<const fml::Mapping> allocation) {
13+
// There is only one backend today.
14+
if (!allocation) {
15+
return nullptr;
7016
}
17+
return std::make_shared<CompressedImageSkia>(std::move(allocation));
18+
}
7119

72-
if (components == DecompressedImage::Format::kInvalid) {
73-
VALIDATION_LOG << "Could not detect image components when decoding.";
74-
return {};
75-
}
20+
CompressedImage::CompressedImage(std::shared_ptr<const fml::Mapping> allocation)
21+
: source_(std::move(allocation)) {}
7622

77-
return DecompressedImage{
78-
ISize{width, height}, // size
79-
components, // components
80-
std::move(dest_allocation) // allocation
81-
};
82-
}
23+
CompressedImage::~CompressedImage() = default;
8324

8425
bool CompressedImage::IsValid() const {
8526
return static_cast<bool>(source_);

impeller/image/compressed_image.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#pragma once
66

7+
#include <memory>
8+
79
#include "flutter/fml/macros.h"
810
#include "flutter/fml/mapping.h"
911
#include "impeller/geometry/size.h"
@@ -15,16 +17,19 @@ class ImageSource;
1517

1618
class CompressedImage {
1719
public:
18-
CompressedImage(std::shared_ptr<const fml::Mapping> sourceAllocation);
20+
static std::shared_ptr<CompressedImage> Create(
21+
std::shared_ptr<const fml::Mapping> allocation);
1922

20-
~CompressedImage();
23+
virtual ~CompressedImage();
2124

22-
[[nodiscard]] DecompressedImage Decode() const;
25+
[[nodiscard]] virtual DecompressedImage Decode() const = 0;
2326

2427
bool IsValid() const;
2528

26-
private:
27-
std::shared_ptr<const fml::Mapping> source_;
29+
protected:
30+
const std::shared_ptr<const fml::Mapping> source_;
31+
32+
CompressedImage(std::shared_ptr<const fml::Mapping> allocation);
2833
};
2934

3035
} // namespace impeller

impeller/playground/playground.mm

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,18 @@ static void PlaygroundKeyCallback(GLFWwindow* window,
195195

196196
std::shared_ptr<Texture> Playground::CreateTextureForFixture(
197197
const char* fixture_name) const {
198-
CompressedImage compressed_image(
198+
auto compressed_image = CompressedImage::Create(
199199
flutter::testing::OpenFixtureAsMapping(fixture_name));
200+
if (!compressed_image) {
201+
VALIDATION_LOG << "Could not create compressed image.";
202+
return nullptr;
203+
}
200204
// The decoded image is immediately converted into RGBA as that format is
201205
// known to be supported everywhere. For image sources that don't need 32
202206
// bit pixel strides, this is overkill. Since this is a test fixture we
203207
// aren't necessarily trying to eke out memory savings here and instead
204208
// favor simplicity.
205-
auto image = compressed_image.Decode().ConvertToRGBA();
209+
auto image = compressed_image->Decode().ConvertToRGBA();
206210
if (!image.IsValid()) {
207211
VALIDATION_LOG << "Could not find fixture named " << fixture_name;
208212
return nullptr;

impeller/third_party/stb/BUILD.gn

Lines changed: 0 additions & 12 deletions
This file was deleted.

impeller/third_party/stb/STBImplementation.c

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)