Add support for writing ICC profiles in png encodes
BUG=skia:
Change-Id: I99eb2f157f249ed09d724461ec4a1e31db70816a
Reviewed-on: https://skia-review.googlesource.com/9782
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/src/images/SkImageEncoderPriv.h b/src/images/SkImageEncoderPriv.h
index 5f7560d..69d45fb 100644
--- a/src/images/SkImageEncoderPriv.h
+++ b/src/images/SkImageEncoderPriv.h
@@ -11,15 +11,15 @@
#include "SkImageEncoder.h"
struct SkEncodeOptions {
- enum class PremulBehavior {
+ enum class ColorBehavior {
// Convert to a linear space before premultiplying or unpremultiplying.
- kGammaCorrect,
+ kCorrect,
// Ignore the transfer function when premultiplying or unpremultiplying.
kLegacy,
};
- PremulBehavior fPremulBehavior = PremulBehavior::kLegacy;
+ ColorBehavior fColorBehavior = ColorBehavior::kLegacy;
};
#ifdef SK_HAS_JPEG_LIBRARY
diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp
index c37aa46..1f8f0d63 100644
--- a/src/images/SkJPEGImageEncoder.cpp
+++ b/src/images/SkJPEGImageEncoder.cpp
@@ -86,10 +86,10 @@
pixmap.colorSpace()->gammaIsLinear());
SkPixmap src = pixmap;
- if (SkEncodeOptions::PremulBehavior::kLegacy == opts.fPremulBehavior) {
+ if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
src.setColorSpace(nullptr);
} else {
- // kGammaCorrect behavior requires a color space. It's not actually critical in the
+ // kCorrect behavior requires a color space. It's not actually critical in the
// jpeg case (since jpegs are opaque), but Skia color correct behavior generally
// requires pixels to be tagged with color spaces.
if (!src.colorSpace()) {
diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp
index e4a60f9..69a7b07 100644
--- a/src/images/SkPNGImageEncoder.cpp
+++ b/src/images/SkPNGImageEncoder.cpp
@@ -12,6 +12,7 @@
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkDither.h"
+#include "SkICC.h"
#include "SkMath.h"
#include "SkStream.h"
#include "SkTemplates.h"
@@ -168,7 +169,7 @@
src.colorSpace()->gammaIsLinear());
SkPixmap pixmap = src;
- if (SkEncodeOptions::PremulBehavior::kLegacy == opts.fPremulBehavior) {
+ if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
pixmap.setColorSpace(nullptr);
} else {
if (!pixmap.colorSpace()) {
@@ -334,6 +335,21 @@
}
}
+ if (pixmap.colorSpace()) {
+ SkColorSpaceTransferFn fn;
+ SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor);
+ if (pixmap.colorSpace()->isSRGB()) {
+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
+ } else if (pixmap.colorSpace()->isNumericalTransferFn(&fn) &&
+ pixmap.colorSpace()->toXYZD50(&toXYZD50))
+ {
+ sk_sp<SkData> icc = SkICC::WriteToICC(fn, toXYZD50);
+ png_set_iCCP(png_ptr, info_ptr, "Skia", 0, icc->bytes(), icc->size());
+ }
+
+ // TODO: Should we support writing ICC profiles for additional color spaces?
+ }
+
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
png_write_info(png_ptr, info_ptr);
int pngBytesPerPixel = num_components(pngColorType) * (bitDepth / 8);
diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp
index 5928f97..8797ff5 100644
--- a/src/images/SkWEBPImageEncoder.cpp
+++ b/src/images/SkWEBPImageEncoder.cpp
@@ -126,7 +126,7 @@
srcPixmap.colorSpace()->gammaIsLinear());
SkPixmap pixmap = srcPixmap;
- if (SkEncodeOptions::PremulBehavior::kLegacy == opts.fPremulBehavior) {
+ if (SkEncodeOptions::ColorBehavior::kLegacy == opts.fColorBehavior) {
pixmap.setColorSpace(nullptr);
} else {
if (!pixmap.colorSpace()) {