Encode F16 with correct color space tag
Test: CTS and Skia unit tests.
Bug: b/62538716
NOTREECHECKS=true
NOTRY=true
NOPRESUBMIT=true
Change-Id: I1467b012771442404f7401f2c3bf949ee5c59fa6
Reviewed-on: https://skia-review.googlesource.com/19543
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index 5120570..cfac46e 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 "SkPreConfig.h"
#include "SkRasterPipeline.h"
@@ -276,10 +277,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/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp
index 764e9c4..1524de3 100644
--- a/src/images/SkJPEGImageEncoder.cpp
+++ b/src/images/SkJPEGImageEncoder.cpp
@@ -136,21 +136,19 @@
jpeg_start_compress(&cinfo, TRUE);
- if (pixmap.colorSpace()) {
- sk_sp<SkData> icc = icc_from_color_space(*pixmap.colorSpace());
- 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(pixmap.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());
- jpeg_write_marker(&cinfo, kICCMarker, markerData->bytes(), markerData->size());
- }
+ jpeg_write_marker(&cinfo, kICCMarker, markerData->bytes(), markerData->size());
}
if (proc) {
diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp
index b57c32a..eb08fa4 100644
--- a/src/images/SkPNGImageEncoder.cpp
+++ b/src/images/SkPNGImageEncoder.cpp
@@ -347,14 +347,12 @@
}
}
- if (pixmap.colorSpace()) {
- if (pixmap.colorSpace()->isSRGB()) {
- png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
- } else {
- sk_sp<SkData> icc = icc_from_color_space(*pixmap.colorSpace());
- if (icc) {
- set_icc(png_ptr, info_ptr, std::move(icc));
- }
+ if (pixmap.colorSpace() && pixmap.colorSpace()->isSRGB()) {
+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
+ } else {
+ sk_sp<SkData> icc = icc_from_color_space(pixmap.info());
+ if (icc) {
+ set_icc(png_ptr, info_ptr, std::move(icc));
}
}
diff --git a/src/images/SkWEBPImageEncoder.cpp b/src/images/SkWEBPImageEncoder.cpp
index c0cd4a6..f77e17f 100644
--- a/src/images/SkWEBPImageEncoder.cpp
+++ b/src/images/SkWEBPImageEncoder.cpp
@@ -180,7 +180,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 = pixmap.colorSpace() ? icc_from_color_space(*pixmap.colorSpace()) : nullptr;
+ sk_sp<SkData> icc = icc_from_color_space(pixmap.info());
SkDynamicMemoryWStream tmp;
pic.custom_ptr = icc ? (void*)&tmp : (void*)stream;