diff options
author | 2017-05-02 16:19:51 -0400 | |
---|---|---|
committer | 2017-05-02 21:05:51 +0000 | |
commit | 733340a6997762dc2fe5048cfe5af33bf8293d93 (patch) | |
tree | 5ded5a1cfdfedac13a6de0156f459cde82ba0d92 | |
parent | 26b44df2333d5e8cec8aef11ab598d63b4ee05c7 (diff) |
Support numerical transfer functions in readPixels()
Let's do this because:
(1) We can.
(2) Android and Chrome have asked for it.
(3) It will simplify the implementation of SkImage::makeColorSpace().
Bug: skia:
Change-Id: Ia3c322b8a58c79ad67cdebe744e0623bd59dcffd
Reviewed-on: https://skia-review.googlesource.com/15148
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>
-rw-r--r-- | gm/readpixels.cpp | 10 | ||||
-rw-r--r-- | src/core/SkConvertPixels.cpp | 13 | ||||
-rw-r--r-- | src/core/SkImageInfoPriv.h | 2 |
3 files changed, 20 insertions, 5 deletions
diff --git a/gm/readpixels.cpp b/gm/readpixels.cpp index f757a497b8..69d22bb7f2 100644 --- a/gm/readpixels.cpp +++ b/gm/readpixels.cpp @@ -91,10 +91,12 @@ static sk_sp<SkImage> make_picture_image() { SkColorSpace::MakeSRGB()); } -static sk_sp<SkColorSpace> make_srgb_transfer_fn(const SkColorSpacePrimaries& primaries) { +static sk_sp<SkColorSpace> make_parametric_transfer_fn(const SkColorSpacePrimaries& primaries) { SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor); SkAssertResult(primaries.toXYZD50(&toXYZD50)); - return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, toXYZD50); + SkColorSpaceTransferFn fn; + fn.fA = 1.f; fn.fB = 0.f; fn.fC = 0.f; fn.fD = 0.f; fn.fE = 0.f; fn.fF = 0.f; fn.fG = 1.8f; + return SkColorSpace::MakeRGB(fn, toXYZD50); } static sk_sp<SkColorSpace> make_wide_gamut() { @@ -108,7 +110,7 @@ static sk_sp<SkColorSpace> make_wide_gamut() { primaries.fBY = 0.0001f; primaries.fWX = 0.34567f; primaries.fWY = 0.35850f; - return make_srgb_transfer_fn(primaries); + return make_parametric_transfer_fn(primaries); } static sk_sp<SkColorSpace> make_small_gamut() { @@ -121,7 +123,7 @@ static sk_sp<SkColorSpace> make_small_gamut() { primaries.fBY = 0.16f; primaries.fWX = 0.3127f; primaries.fWY = 0.3290f; - return make_srgb_transfer_fn(primaries); + return make_parametric_transfer_fn(primaries); } static void draw_image(SkCanvas* canvas, SkImage* image, SkColorType dstColorType, diff --git a/src/core/SkConvertPixels.cpp b/src/core/SkConvertPixels.cpp index b919f5dbe8..67e8a28cbf 100644 --- a/src/core/SkConvertPixels.cpp +++ b/src/core/SkConvertPixels.cpp @@ -310,6 +310,12 @@ static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, size if (isColorAware && srcInfo.gammaCloseToSRGB()) { pipeline.append_from_srgb(srcInfo.alphaType()); + } else if (isColorAware && !srcInfo.colorSpace()->gammaIsLinear()) { + SkColorSpaceTransferFn fn; + SkAssertResult(srcInfo.colorSpace()->isNumericalTransferFn(&fn)); + pipeline.append(SkRasterPipeline::parametric_r, &fn); + pipeline.append(SkRasterPipeline::parametric_g, &fn); + pipeline.append(SkRasterPipeline::parametric_b, &fn); } float matrix[12]; @@ -331,6 +337,13 @@ static void convert_with_pipeline(const SkImageInfo& dstInfo, void* dstRow, size if (isColorAware && dstInfo.gammaCloseToSRGB()) { pipeline.append(SkRasterPipeline::to_srgb); + } else if (isColorAware && !dstInfo.colorSpace()->gammaIsLinear()) { + SkColorSpaceTransferFn fn; + SkAssertResult(dstInfo.colorSpace()->isNumericalTransferFn(&fn)); + fn = fn.invert(); + pipeline.append(SkRasterPipeline::parametric_r, &fn); + pipeline.append(SkRasterPipeline::parametric_g, &fn); + pipeline.append(SkRasterPipeline::parametric_b, &fn); } if (kUnpremul_SkAlphaType == premulState && kPremul_SkAlphaType == dat && diff --git a/src/core/SkImageInfoPriv.h b/src/core/SkImageInfoPriv.h index a0c1b3403a..42e80cab2b 100644 --- a/src/core/SkImageInfoPriv.h +++ b/src/core/SkImageInfoPriv.h @@ -94,7 +94,7 @@ static inline bool SkImageInfoIsValidRenderingCS(const SkImageInfo& info) { * conversion is not well-defined. */ static inline bool SkImageInfoValidConversion(const SkImageInfo& dst, const SkImageInfo& src) { - if (!SkImageInfoIsValidRenderingCS(dst) || !SkImageInfoIsValidRenderingCS(src)) { + if (!SkImageInfoIsValidAllowNumericalCS(dst) || !SkImageInfoIsValidAllowNumericalCS(src)) { return false; } |