Flutter Engine
The Flutter Engine
Functions
SkRescaleAndReadPixels.h File Reference
#include "include/core/SkImage.h"

Go to the source code of this file.

Functions

void SkRescaleAndReadPixels (SkBitmap src, const SkImageInfo &resultInfo, const SkIRect &srcRect, SkImage::RescaleGamma, SkImage::RescaleMode, SkImage::ReadPixelsCallback, SkImage::ReadPixelsContext)
 

Function Documentation

◆ SkRescaleAndReadPixels()

void SkRescaleAndReadPixels ( SkBitmap  src,
const SkImageInfo resultInfo,
const SkIRect srcRect,
SkImage::RescaleGamma  rescaleGamma,
SkImage::RescaleMode  rescaleMode,
SkImage::ReadPixelsCallback  callback,
SkImage::ReadPixelsContext  context 
)

Generic/synchronous implementation for SkImage:: and SkSurface::asyncRescaleAndReadPixels.

Definition at line 28 of file SkRescaleAndReadPixels.cpp.

34 {
35 int srcW = srcRect.width();
36 int srcH = srcRect.height();
37
38 float sx = (float)resultInfo.width() / srcW;
39 float sy = (float)resultInfo.height() / srcH;
40 // How many bilerp/bicubic steps to do in X and Y. + means upscaling, - means downscaling.
41 int stepsX;
42 int stepsY;
43 if (rescaleMode != SkImage::RescaleMode::kNearest) {
44 stepsX = static_cast<int>((sx > 1.f) ? std::ceil(std::log2f(sx))
45 : std::floor(std::log2f(sx)));
46 stepsY = static_cast<int>((sy > 1.f) ? std::ceil(std::log2f(sy))
47 : std::floor(std::log2f(sy)));
48 } else {
49 stepsX = sx != 1.f;
50 stepsY = sy != 1.f;
51 }
52
54 paint.setBlendMode(SkBlendMode::kSrc);
55 if (stepsX < 0 || stepsY < 0) {
56 // Don't trigger MIP generation. We don't currently have a way to trigger bicubic for
57 // downscaling draws.
58
59 // TODO: should we trigger cubic now that we can?
60 if (rescaleMode != SkImage::RescaleMode::kNearest) {
62 }
63 }
64
65 auto rescaling_to_sampling = [](SkImage::RescaleMode rescaleMode) {
67 if (rescaleMode == SkImage::RescaleMode::kRepeatedLinear) {
69 } else if (rescaleMode == SkImage::RescaleMode::kRepeatedCubic) {
70 sampling = SkSamplingOptions({1.0f/3, 1.0f/3});
71 }
72 return sampling;
73 };
74 SkSamplingOptions sampling = rescaling_to_sampling(rescaleMode);
75
76 sk_sp<SkSurface> tempSurf;
77 sk_sp<SkImage> srcImage;
78 int srcX = srcRect.fLeft;
79 int srcY = srcRect.fTop;
81 // Assume we should ignore the rescale linear request if the surface has no color space since
82 // it's unclear how we'd linearize from an unknown color space.
83 if (rescaleGamma == SkSurface::RescaleGamma::kLinear && bmp.info().colorSpace() &&
84 !bmp.info().colorSpace()->gammaIsLinear()) {
85 auto cs = bmp.info().colorSpace()->makeLinearGamma();
86 // Promote to F16 color type to preserve precision.
87 auto ii = SkImageInfo::Make(srcW, srcH, kRGBA_F16_SkColorType, bmp.info().alphaType(),
88 std::move(cs));
89 auto linearSurf = SkSurfaces::Raster(ii);
90 if (!linearSurf) {
91 callback(context, nullptr);
92 return;
93 }
94 linearSurf->getCanvas()->drawImage(bmp.asImage().get(), -srcX, -srcY, sampling, &paint);
95 tempSurf = std::move(linearSurf);
96 srcImage = tempSurf->makeImageSnapshot();
97 srcX = 0;
98 srcY = 0;
100 } else {
101 // MakeFromBitmap would trigger a copy if bmp is mutable.
102 srcImage = SkImages::RasterFromPixmap(bmp.pixmap(), nullptr, nullptr);
103 }
104 while (stepsX || stepsY) {
105 int nextW = resultInfo.width();
106 int nextH = resultInfo.height();
107 if (stepsX < 0) {
108 nextW = resultInfo.width() << (-stepsX - 1);
109 stepsX++;
110 } else if (stepsX != 0) {
111 if (stepsX > 1) {
112 nextW = srcW * 2;
113 }
114 --stepsX;
115 }
116 if (stepsY < 0) {
117 nextH = resultInfo.height() << (-stepsY - 1);
118 stepsY++;
119 } else if (stepsY != 0) {
120 if (stepsY > 1) {
121 nextH = srcH * 2;
122 }
123 --stepsY;
124 }
125 auto ii = srcImage->imageInfo().makeWH(nextW, nextH);
126 if (!stepsX && !stepsY) {
127 // Might as well fold conversion to final info in the last step.
128 ii = resultInfo;
129 }
130 auto next = SkSurfaces::Raster(ii);
131 if (!next) {
132 callback(context, nullptr);
133 return;
134 }
135 next->getCanvas()->drawImageRect(
136 srcImage.get(), SkRect::Make(SkIRect::MakeXYWH(srcX, srcY, srcW, srcH)),
137 SkRect::MakeIWH(nextW, nextH), sampling, &paint, constraint);
138 tempSurf = std::move(next);
139 srcImage = tempSurf->makeImageSnapshot();
140 srcX = srcY = 0;
141 srcW = nextW;
142 srcH = nextH;
144 }
145
146 size_t rowBytes = resultInfo.minRowBytes();
147 std::unique_ptr<char[]> data(new char[resultInfo.height() * rowBytes]);
148 SkPixmap pm(resultInfo, data.get(), rowBytes);
149 if (srcImage->readPixels(nullptr, pm, srcX, srcY)) {
150 class Result : public SkImage::AsyncReadResult {
151 public:
152 Result(std::unique_ptr<const char[]> data, size_t rowBytes)
153 : fData(std::move(data)), fRowBytes(rowBytes) {}
154 int count() const override { return 1; }
155 const void* data(int i) const override { return fData.get(); }
156 size_t rowBytes(int i) const override { return fRowBytes; }
157
158 private:
159 std::unique_ptr<const char[]> fData;
160 size_t fRowBytes;
161 };
162 callback(context, std::make_unique<Result>(std::move(data), rowBytes));
163 } else {
164 callback(context, nullptr);
165 }
166}
static float next(float f)
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
SrcRectConstraint
Definition: SkCanvas.h:1541
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
Definition: SkCanvas.h:1542
@ kFast_SrcRectConstraint
sample outside bounds; faster
Definition: SkCanvas.h:1543
virtual size_t rowBytes(int i) const =0
virtual int count() const =0
virtual const void * data(int i) const =0
const SkImageInfo & imageInfo() const
Definition: SkImage.h:279
bool readPixels(GrDirectContext *context, const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY, CachingHint cachingHint=kAllow_CachingHint) const
Definition: SkImage.cpp:42
RescaleMode
Definition: SkImage.h:587
sk_sp< SkImage > makeImageSnapshot()
Definition: SkSurface.cpp:90
T * get() const
Definition: SkRefCnt.h:303
const Paint & paint
Definition: color_source.cc:38
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SkSamplingOptions sampling
Definition: SkRecords.h:337
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
SkSamplingOptions(SkFilterMode::kLinear))
SIN Vec< N, float > floor(const Vec< N, float > &x)
Definition: SkVx.h:703
SIN Vec< N, float > ceil(const Vec< N, float > &x)
Definition: SkVx.h:702
Definition: ref_ptr.h:256
constexpr int32_t height() const
Definition: SkRect.h:165
int32_t fTop
smaller y-axis bounds
Definition: SkRect.h:34
constexpr int32_t width() const
Definition: SkRect.h:158
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
Definition: SkRect.h:104
int32_t fLeft
smaller x-axis bounds
Definition: SkRect.h:33
SkImageInfo makeWH(int newWidth, int newHeight) const
Definition: SkImageInfo.h:444
size_t minRowBytes() const
Definition: SkImageInfo.h:517
int width() const
Definition: SkImageInfo.h:365
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
int height() const
Definition: SkImageInfo.h:371
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static SkRect MakeIWH(int w, int h)
Definition: SkRect.h:623
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63