Always encode images with sRGB encoded pixels
Bug: skia:
Change-Id: Icb25bc21a30e88f21df5b0e267d5a3a05535e44a
Reviewed-on: https://skia-review.googlesource.com/19544
Commit-Queue: Matt Sarett <msarett@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
(cherry picked from commit 1950e0a868774330330555a9a368992218f42240)
Reviewed-on: https://skia-review.googlesource.com/19814
Reviewed-by: Matt Sarett <msarett@google.com>
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index b01f1cd..6b49b2d 100644
--- a/src/images/SkImageEncoderFns.h
+++ b/src/images/SkImageEncoderFns.h
@@ -15,6 +15,7 @@
#include "SkBitmap.h"
#include "SkColor.h"
#include "SkColorPriv.h"
+#include "SkColorSpace_Base.h"
#include "SkICC.h"
#include "SkOpts.h"
#include "SkPreConfig.h"
@@ -256,6 +257,7 @@
int width, int, const SkPMColor*) {
SkRasterPipeline_<256> p;
p.append(SkRasterPipeline::load_f16, (const void**) &src);
+ p.append(SkRasterPipeline::to_srgb);
p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
p.run(0, width);
}
@@ -268,6 +270,7 @@
SkRasterPipeline_<256> p;
p.append(SkRasterPipeline::load_f16, (const void**) &src);
p.append(SkRasterPipeline::unpremul);
+ p.append(SkRasterPipeline::to_srgb);
p.append(SkRasterPipeline::store_u16_be, (void**) &dst);
p.run(0, width);
}
@@ -312,10 +315,21 @@
p.run(0, width);
}
-static inline sk_sp<SkData> icc_from_color_space(const SkColorSpace& cs) {
+static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
+ SkColorSpace* cs = info.colorSpace();
+ if (!cs) {
+ return nullptr;
+ }
+
+ sk_sp<SkColorSpace> owned;
+ if (kRGBA_F16_SkColorType == info.colorType()) {
+ owned = as_CSB(cs)->makeSRGBGamma();
+ cs = owned.get();
+ }
+
SkColorSpaceTransferFn fn;
SkMatrix44 toXYZD50(SkMatrix44::kUninitialized_Constructor);
- if (cs.isNumericalTransferFn(&fn) && cs.toXYZD50(&toXYZD50)) {
+ if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
return SkICC::WriteToICC(fn, toXYZD50);
}
diff --git a/src/images/SkJpegEncoder.cpp b/src/images/SkJpegEncoder.cpp
index eaea77e..a0ee398 100644
--- a/src/images/SkJpegEncoder.cpp
+++ b/src/images/SkJpegEncoder.cpp
@@ -207,29 +207,19 @@
jpeg_set_quality(encoderMgr->cinfo(), options.fQuality, TRUE);
jpeg_start_compress(encoderMgr->cinfo(), TRUE);
- if (SkColorSpace* cs = src.colorSpace()) {
- sk_sp<SkColorSpace> owned;
- if (src.colorType() == kRGBA_F16_SkColorType) {
- // We'll be converting to 8-bit sRGB, so we'd better tag it that way.
- owned = as_CSB(src.colorSpace())->makeSRGBGamma();
- cs = owned.get();
- }
+ sk_sp<SkData> icc = icc_from_color_space(src.info());
+ if (icc) {
+ // Create a contiguous block of memory with the icc signature followed by the profile.
+ sk_sp<SkData> markerData =
+ SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size());
+ uint8_t* ptr = (uint8_t*) markerData->writable_data();
+ memcpy(ptr, kICCSig, sizeof(kICCSig));
+ ptr += sizeof(kICCSig);
+ *ptr++ = 1; // This is the first marker.
+ *ptr++ = 1; // Out of one total markers.
+ memcpy(ptr, icc->data(), icc->size());
- sk_sp<SkData> icc = icc_from_color_space(*cs);
- if (icc) {
- // Create a contiguous block of memory with the icc signature followed by the profile.
- sk_sp<SkData> markerData =
- SkData::MakeUninitialized(kICCMarkerHeaderSize + icc->size());
- uint8_t* ptr = (uint8_t*) markerData->writable_data();
- memcpy(ptr, kICCSig, sizeof(kICCSig));
- ptr += sizeof(kICCSig);
- *ptr++ = 1; // This is the first marker.
- *ptr++ = 1; // Out of one total markers.
- memcpy(ptr, icc->data(), icc->size());
-
- jpeg_write_marker(encoderMgr->cinfo(), kICCMarker, markerData->bytes(),
- markerData->size());
- }
+ jpeg_write_marker(encoderMgr->cinfo(), kICCMarker, markerData->bytes(), markerData->size());
}
return std::unique_ptr<SkJpegEncoder>(new SkJpegEncoder(std::move(encoderMgr), src));
diff --git a/src/images/SkPngEncoder.cpp b/src/images/SkPngEncoder.cpp
index d28657f..7a1bfcf 100644
--- a/src/images/SkPngEncoder.cpp
+++ b/src/images/SkPngEncoder.cpp
@@ -53,7 +53,7 @@
bool setHeader(const SkImageInfo& srcInfo, const SkPngEncoder::Options& options);
bool setPalette(const SkImageInfo& srcInfo, SkColorTable* colorTable,
SkTransferFunctionBehavior);
- bool setColorSpace(SkColorSpace* colorSpace);
+ bool setColorSpace(const SkImageInfo& info);
bool writeInfo(const SkImageInfo& srcInfo);
void chooseProc(const SkImageInfo& srcInfo, SkTransferFunctionBehavior unpremulBehavior);
@@ -327,8 +327,8 @@
return true;
}
-static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkColorSpace& colorSpace) {
- sk_sp<SkData> icc = icc_from_color_space(colorSpace);
+static void set_icc(png_structp png_ptr, png_infop info_ptr, const SkImageInfo& info) {
+ sk_sp<SkData> icc = icc_from_color_space(info);
if (!icc) {
return;
}
@@ -344,17 +344,15 @@
png_set_iCCP(png_ptr, info_ptr, name, 0, iccPtr, icc->size());
}
-bool SkPngEncoderMgr::setColorSpace(SkColorSpace* colorSpace) {
+bool SkPngEncoderMgr::setColorSpace(const SkImageInfo& info) {
if (setjmp(png_jmpbuf(fPngPtr))) {
return false;
}
- if (colorSpace) {
- if (colorSpace->isSRGB()) {
- png_set_sRGB(fPngPtr, fInfoPtr, PNG_sRGB_INTENT_PERCEPTUAL);
- } else {
- set_icc(fPngPtr, fInfoPtr, *colorSpace);
- }
+ if (info.colorSpace() && info.colorSpace()->isSRGB()) {
+ png_set_sRGB(fPngPtr, fInfoPtr, PNG_sRGB_INTENT_PERCEPTUAL);
+ } else {
+ set_icc(fPngPtr, fInfoPtr, info);
}
return true;
@@ -401,7 +399,7 @@
return nullptr;
}
- if (!encoderMgr->setColorSpace(src.colorSpace())) {
+ if (!encoderMgr->setColorSpace(src.info())) {
return nullptr;
}
diff --git a/src/images/SkWebpEncoder.cpp b/src/images/SkWebpEncoder.cpp
index 81ed7e1..296d4f4 100644
--- a/src/images/SkWebpEncoder.cpp
+++ b/src/images/SkWebpEncoder.cpp
@@ -194,16 +194,7 @@
// If there is no need to embed an ICC profile, we write directly to the input stream.
// Otherwise, we will first encode to |tmp| and use a mux to add the ICC chunk. libwebp
// forces us to have an encoded image before we can add a profile.
- sk_sp<SkData> icc;
- if (SkColorSpace* cs = pixmap.colorSpace()) {
- sk_sp<SkColorSpace> owned;
- if (pixmap.colorType() == kRGBA_F16_SkColorType) {
- // We'll be converting to 8-bit sRGB, so we'd better tag it that way.
- owned = as_CSB(pixmap.colorSpace())->makeSRGBGamma();
- cs = owned.get();
- }
- icc = icc_from_color_space(*cs);
- }
+ sk_sp<SkData> icc = icc_from_color_space(pixmap.info());
SkDynamicMemoryWStream tmp;
pic.custom_ptr = icc ? (void*)&tmp : (void*)stream;