diff options
-rw-r--r-- | include/core/SkImage.h | 8 | ||||
-rw-r--r-- | src/image/SkImage.cpp | 22 |
2 files changed, 30 insertions, 0 deletions
diff --git a/include/core/SkImage.h b/include/core/SkImage.h index 1d725c237d..75d7083805 100644 --- a/include/core/SkImage.h +++ b/include/core/SkImage.h @@ -384,6 +384,14 @@ public: * the pixels fails). Otherwise, it returns the original image. */ sk_sp<SkImage> makeNonTextureImage() const; + + /** + * If this image is already backed by raster (i.e. peekPixels would succeed), then this just + * returns itself. If not, this attempts to create a raster version of this image and returns + * that, or nullptr if that fails. + */ + sk_sp<SkImage> makeRasterImage() const; + /** * Apply a given image filter to this image, and return the filtered result. * diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index b60224038e..c157e48640 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -325,6 +325,28 @@ sk_sp<SkImage> SkImage::makeColorSpace(sk_sp<SkColorSpace> target, return as_IB(this)->onMakeColorSpace(std::move(target), targetColorType, premulBehavior); } +sk_sp<SkImage> SkImage::makeRasterImage() const { + SkPixmap pm; + if (this->peekPixels(&pm)) { + return sk_ref_sp(const_cast<SkImage*>(this)); + } + + const SkImageInfo info = as_IB(this)->onImageInfo(); + const size_t rowBytes = info.minRowBytes(); + size_t size = info.computeByteSize(rowBytes); + if (SkImageInfo::ByteSizeOverflowed(size)) { + return nullptr; + } + + sk_sp<SkData> data = SkData::MakeUninitialized(size); + pm = { info, data->writable_data(), info.minRowBytes() }; + if (!this->readPixels(pm, 0, 0)) { + return nullptr; + } + + return SkImage::MakeRasterData(info, std::move(data), rowBytes); +} + ////////////////////////////////////////////////////////////////////////////////////// #if !SK_SUPPORT_GPU |