Begin implementation of SkImage_Base::makeColorSpace
Originally: https://skia-review.googlesource.com/9622 CQ_INCLUDE_TRYBOTS=skia.primary:Test-Mac-Clang-MacMini6.2-CPU-AVX-x86_64-Release,Test-Android-Clang-PixelC-CPU-TegraX1-arm64-Debug-Android BUG=skia: Change-Id: I7ef1daaab32892399e3333e4b2fc75d70a1900e4 Reviewed-on: https://skia-review.googlesource.com/9651 Commit-Queue: Matt Sarett <msarett@google.com> Reviewed-by: Matt Sarett <msarett@google.com>
This commit is contained in:
parent
bdce9c2d73
commit
6de1310981
@ -8,6 +8,7 @@
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkColorSpaceXform.h"
|
||||
#include "SkColorSpaceXformCanvas.h"
|
||||
#include "SkImage_Base.h"
|
||||
#include "SkMakeUnique.h"
|
||||
#include "SkNoDrawCanvas.h"
|
||||
#include "SkSurface.h"
|
||||
@ -72,8 +73,7 @@ public:
|
||||
}
|
||||
|
||||
sk_sp<const SkImage> xform(const SkImage* img) const {
|
||||
// TODO: for real
|
||||
return sk_ref_sp(img);
|
||||
return as_IB(img)->makeColorSpace(fTargetCS);
|
||||
}
|
||||
|
||||
void onDrawPaint(const SkPaint& paint) override {
|
||||
|
@ -312,6 +312,19 @@ bool SkImage::isAlphaOnly() const {
|
||||
return as_IB(this)->onImageInfo().colorType() == kAlpha_8_SkColorType;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Base::makeColorSpace(sk_sp<SkColorSpace> target) const {
|
||||
SkColorSpaceTransferFn fn;
|
||||
if (!target || !target->isNumericalTransferFn(&fn)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (SkColorSpace::Equals(this->colorSpace(), target.get())) {
|
||||
return sk_ref_sp(const_cast<SkImage_Base*>(this));
|
||||
}
|
||||
|
||||
return this->onMakeColorSpace(std::move(target));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !SK_SUPPORT_GPU
|
||||
|
@ -81,14 +81,18 @@ public:
|
||||
fAddedToCache.store(true);
|
||||
}
|
||||
|
||||
virtual sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) {
|
||||
// TODO: Implement this.
|
||||
return sk_ref_sp(this);
|
||||
}
|
||||
// Transforms image into the input color space.
|
||||
sk_sp<SkImage> makeColorSpace(sk_sp<SkColorSpace> target) const;
|
||||
|
||||
virtual bool onPinAsTexture(GrContext*) const { return false; }
|
||||
virtual void onUnpinAsTexture(GrContext*) const {}
|
||||
|
||||
protected:
|
||||
virtual sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const {
|
||||
// TODO: Make this pure virtual.
|
||||
return sk_ref_sp(const_cast<SkImage_Base*>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
// Set true by caches when they cache content that's derived from the current pixels.
|
||||
mutable SkAtomic<bool> fAddedToCache;
|
||||
|
@ -40,6 +40,7 @@ public:
|
||||
GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
|
||||
sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
|
||||
bool onIsLazyGenerated() const override { return true; }
|
||||
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override;
|
||||
|
||||
private:
|
||||
mutable SkImageCacherator fCache;
|
||||
@ -115,6 +116,23 @@ sk_sp<SkImage> SkImage_Generator::onMakeSubset(const SkIRect& subset) const {
|
||||
return validator ? sk_sp<SkImage>(new SkImage_Generator(&validator)) : nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Generator::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
|
||||
SkBitmap dst;
|
||||
SkImageInfo dstInfo = fCache.info().makeColorSpace(target);
|
||||
if (kIndex_8_SkColorType == dstInfo.colorType() ||
|
||||
kGray_8_SkColorType == dstInfo.colorType()) {
|
||||
dstInfo = dstInfo.makeColorType(kN32_SkColorType);
|
||||
}
|
||||
dst.allocPixels(dstInfo);
|
||||
|
||||
if (!fCache.directGeneratePixels(dstInfo, dst.getPixels(), dst.rowBytes(), 0, 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
dst.setImmutable();
|
||||
return SkImage::MakeFromBitmap(dst);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> generator,
|
||||
const SkIRect* subset) {
|
||||
SkImageCacherator::Validator validator(
|
||||
|
@ -120,6 +120,8 @@ public:
|
||||
return fBitmap.pixelRef() && fBitmap.pixelRef()->isLazyGenerated();
|
||||
}
|
||||
|
||||
sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override;
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const override;
|
||||
bool onPinAsTexture(GrContext*) const override;
|
||||
@ -365,3 +367,21 @@ bool SkImage_Raster::onAsLegacyBitmap(SkBitmap* bitmap, LegacyBitmapMode mode) c
|
||||
}
|
||||
return this->INHERITED::onAsLegacyBitmap(bitmap, mode);
|
||||
}
|
||||
|
||||
sk_sp<SkImage> SkImage_Raster::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
|
||||
SkBitmap dst;
|
||||
SkImageInfo dstInfo = fBitmap.info().makeColorSpace(target);
|
||||
if (kIndex_8_SkColorType == dstInfo.colorType() ||
|
||||
kGray_8_SkColorType == dstInfo.colorType())
|
||||
{
|
||||
dstInfo = dstInfo.makeColorType(kN32_SkColorType);
|
||||
}
|
||||
dst.allocPixels(dstInfo);
|
||||
|
||||
SkPixmap src;
|
||||
SkAssertResult(this->onPeekPixels(&src));
|
||||
|
||||
SkAssertResult(dst.writePixels(src));
|
||||
dst.setImmutable();
|
||||
return SkImage::MakeFromBitmap(dst);
|
||||
}
|
||||
|
@ -1050,6 +1050,10 @@ static sk_sp<SkImage> create_picture_image(sk_sp<SkColorSpace> space) {
|
||||
nullptr, nullptr, SkImage::BitDepth::kU8, std::move(space));
|
||||
};
|
||||
|
||||
static inline bool almost_equal(int a, int b) {
|
||||
return SkTAbs(a - b) <= 1;
|
||||
}
|
||||
|
||||
DEF_TEST(Image_ColorSpace, r) {
|
||||
sk_sp<SkColorSpace> srgb = SkColorSpace::MakeSRGB();
|
||||
sk_sp<SkImage> image = GetResourceAsImage("mandrill_512_q075.jpg");
|
||||
@ -1082,6 +1086,34 @@ DEF_TEST(Image_ColorSpace, r) {
|
||||
REPORTER_ASSERT(r, SkColorSpace::Equals(rec2020.get(), image->colorSpace()));
|
||||
}
|
||||
|
||||
DEF_TEST(Image_makeColorSpace, r) {
|
||||
sk_sp<SkColorSpace> p3 = SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma,
|
||||
SkColorSpace::kDCIP3_D65_Gamut);
|
||||
|
||||
SkBitmap srgbBitmap;
|
||||
srgbBitmap.allocPixels(SkImageInfo::MakeS32(1, 1, kOpaque_SkAlphaType));
|
||||
*srgbBitmap.getAddr32(0, 0) = SkSwizzle_RGBA_to_PMColor(0xFF604020);
|
||||
srgbBitmap.setImmutable();
|
||||
sk_sp<SkImage> srgbImage = SkImage::MakeFromBitmap(srgbBitmap);
|
||||
sk_sp<SkImage> p3Image = as_IB(srgbImage)->makeColorSpace(p3);
|
||||
SkBitmap p3Bitmap;
|
||||
bool success = p3Image->asLegacyBitmap(&p3Bitmap, SkImage::kRO_LegacyBitmapMode);
|
||||
REPORTER_ASSERT(r, success);
|
||||
p3Bitmap.lockPixels();
|
||||
REPORTER_ASSERT(r, almost_equal(0x28, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
|
||||
REPORTER_ASSERT(r, almost_equal(0x40, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
|
||||
REPORTER_ASSERT(r, almost_equal(0x5E, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
|
||||
|
||||
srgbImage = GetResourceAsImage("1x1.png");
|
||||
p3Image = as_IB(srgbImage)->makeColorSpace(p3);
|
||||
success = p3Image->asLegacyBitmap(&p3Bitmap, SkImage::kRO_LegacyBitmapMode);
|
||||
REPORTER_ASSERT(r, success);
|
||||
p3Bitmap.lockPixels();
|
||||
REPORTER_ASSERT(r, almost_equal(0x8B, SkGetPackedR32(*p3Bitmap.getAddr32(0, 0))));
|
||||
REPORTER_ASSERT(r, almost_equal(0x82, SkGetPackedG32(*p3Bitmap.getAddr32(0, 0))));
|
||||
REPORTER_ASSERT(r, almost_equal(0x77, SkGetPackedB32(*p3Bitmap.getAddr32(0, 0))));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void make_all_premul(SkBitmap* bm) {
|
||||
|
Loading…
Reference in New Issue
Block a user