aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@google.com>2018-05-22 13:47:52 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-22 14:17:15 +0000
commit5b58b7c14c4405163e2af68dd3951a83fa1dabf2 (patch)
treef6d940bd35e271e139613a23e295b47dd4da631b /src
parent89735a0f47d2a06542d966a383dcba9f7a00d675 (diff)
Reland "strip down SkICC.cpp"
This reverts commit 27fe397bc0cc1b091f9f85863c62b88156239cf0. Reason for revert: time to fly. Original change's description: > Revert "strip down SkICC.cpp" > > This reverts commit eab50eb9c6117c2a9d0e5648f89cebbb4dbd9d30 > and this tiny bit of e61b969a07ba3ebe9e47e61381ad16c5d2c549a2: > > https://skia-review.googlesource.com/c/skia/+/127122/3/tests/ICCTest.cpp > > Change-Id: I4306e5118a4e5eb88c05078186a28bd443fd76f7 > Reviewed-on: https://skia-review.googlesource.com/127305 > Reviewed-by: Mike Klein <mtklein@chromium.org> > Commit-Queue: Mike Klein <mtklein@chromium.org> TBR=mtklein@chromium.org,brianosman@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Change-Id: I93a6cfb66f0da0e098fdcb77ac1cd619e41614b1 Reviewed-on: https://skia-review.googlesource.com/129446 Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkICC.cpp213
-rw-r--r--src/core/SkICCPriv.h7
-rw-r--r--src/images/SkImageEncoderFns.h2
3 files changed, 30 insertions, 192 deletions
diff --git a/src/core/SkICC.cpp b/src/core/SkICC.cpp
index 3a77dfc200..aa9c45e50b 100644
--- a/src/core/SkICC.cpp
+++ b/src/core/SkICC.cpp
@@ -7,134 +7,13 @@
#include "SkAutoMalloc.h"
#include "SkColorSpacePriv.h"
-#include "SkColorSpaceXformPriv.h"
-#include "SkColorSpace_XYZ.h"
#include "SkEndian.h"
#include "SkFixed.h"
#include "SkICC.h"
#include "SkICCPriv.h"
#include "SkMD5.h"
-#include "SkString.h"
#include "SkUtils.h"
-SkICC::SkICC(sk_sp<SkColorSpace> colorSpace)
- : fColorSpace(std::move(colorSpace))
-{}
-
-sk_sp<SkICC> SkICC::Make(const void* ptr, size_t len) {
- sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeICC(ptr, len);
- if (!colorSpace) {
- return nullptr;
- }
-
- return sk_sp<SkICC>(new SkICC(std::move(colorSpace)));
-}
-
-bool SkICC::toXYZD50(SkMatrix44* toXYZD50) const {
- return fColorSpace->toXYZD50(toXYZD50);
-}
-
-bool SkICC::isNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const {
- return fColorSpace->isNumericalTransferFn(coeffs);
-}
-
-static const int kDefaultTableSize = 512; // Arbitrary
-
-void fn_to_table(float* tablePtr, const SkColorSpaceTransferFn& fn) {
- // Y = (aX + b)^g + e for X >= d
- // Y = cX + f otherwise
- for (int i = 0; i < kDefaultTableSize; i++) {
- float x = ((float) i) / ((float) (kDefaultTableSize - 1));
- if (x >= fn.fD) {
- tablePtr[i] = clamp_0_1(powf(fn.fA * x + fn.fB, fn.fG) + fn.fE);
- } else {
- tablePtr[i] = clamp_0_1(fn.fC * x + fn.fF);
- }
- }
-}
-
-void copy_to_table(float* tablePtr, const SkGammas* gammas, int index) {
- SkASSERT(gammas->isTable(index));
- const float* ptr = gammas->table(index);
- const size_t bytes = gammas->tableSize(index) * sizeof(float);
- memcpy(tablePtr, ptr, bytes);
-}
-
-bool SkICC::rawTransferFnData(Tables* tables) const {
- if (!fColorSpace->toXYZD50()) {
- return false; // Can't even dream of handling A2B here...
- }
- SkColorSpace_XYZ* colorSpace = (SkColorSpace_XYZ*) fColorSpace.get();
-
- SkColorSpaceTransferFn fn;
- if (this->isNumericalTransferFn(&fn)) {
- tables->fStorage = SkData::MakeUninitialized(kDefaultTableSize * sizeof(float));
- fn_to_table((float*) tables->fStorage->writable_data(), fn);
- tables->fRed.fOffset = tables->fGreen.fOffset = tables->fBlue.fOffset = 0;
- tables->fRed.fCount = tables->fGreen.fCount = tables->fBlue.fCount = kDefaultTableSize;
- return true;
- }
-
- const SkGammas* gammas = colorSpace->gammas();
- SkASSERT(gammas);
- if (gammas->allChannelsSame()) {
- SkASSERT(gammas->isTable(0));
- tables->fStorage = SkData::MakeUninitialized(gammas->tableSize(0) * sizeof(float));
- copy_to_table((float*) tables->fStorage->writable_data(), gammas, 0);
- tables->fRed.fOffset = tables->fGreen.fOffset = tables->fBlue.fOffset = 0;
- tables->fRed.fCount = tables->fGreen.fCount = tables->fBlue.fCount = gammas->tableSize(0);
- return true;
- }
-
- // Determine the storage size.
- size_t storageSize = 0;
- for (int i = 0; i < 3; i++) {
- if (gammas->isTable(i)) {
- storageSize += gammas->tableSize(i) * sizeof(float);
- } else {
- storageSize += kDefaultTableSize * sizeof(float);
- }
- }
-
- // Fill in the tables.
- tables->fStorage = SkData::MakeUninitialized(storageSize);
- float* ptr = (float*) tables->fStorage->writable_data();
- size_t offset = 0;
- Channel rgb[3];
- for (int i = 0; i < 3; i++) {
- if (gammas->isTable(i)) {
- copy_to_table(ptr, gammas, i);
- rgb[i].fOffset = offset;
- rgb[i].fCount = gammas->tableSize(i);
- offset += rgb[i].fCount * sizeof(float);
- ptr += rgb[i].fCount;
- continue;
- }
-
- if (gammas->isNamed(i)) {
- SkAssertResult(named_to_parametric(&fn, gammas->data(i).fNamed));
- } else if (gammas->isValue(i)) {
- value_to_parametric(&fn, gammas->data(i).fValue);
- } else {
- SkASSERT(gammas->isParametric(i));
- fn = gammas->params(i);
- }
-
- fn_to_table(ptr, fn);
- rgb[i].fOffset = offset;
- rgb[i].fCount = kDefaultTableSize;
- offset += kDefaultTableSize * sizeof(float);
- ptr += kDefaultTableSize;
- }
-
- tables->fRed = rgb[0];
- tables->fGreen = rgb[1];
- tables->fBlue = rgb[2];
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
static constexpr char kDescriptionTagBodyPrefix[12] =
{ 'G', 'o', 'o', 'g', 'l', 'e', '/', 'S', 'k', 'i', 'a' , '/'};
@@ -165,9 +44,14 @@ static constexpr uint32_t kWhitePointTag[5] {
// Google Inc. 2016 (UTF-16)
static constexpr uint8_t kCopyrightTagBody[] = {
- 0x00, 0x47, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x67, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00,
- 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x31,
- 0x00, 0x36,
+ 0x00, 0x47, 0x00, 0x6f,
+ 0x00, 0x6f, 0x00, 0x67,
+ 0x00, 0x6c, 0x00, 0x65,
+ 0x00, 0x20, 0x00, 0x49,
+ 0x00, 0x6e, 0x00, 0x63,
+ 0x00, 0x2e, 0x00, 0x20,
+ 0x00, 0x32, 0x00, 0x30,
+ 0x00, 0x31, 0x00, 0x36,
};
static_assert(SkIsAlign4(sizeof(kCopyrightTagBody)), "Copyright must be aligned to 4-bytes.");
static constexpr uint32_t kCopyrightTagHeader[7] {
@@ -288,12 +172,12 @@ static SkFixed float_round_to_fixed(float x) {
return sk_float_saturate2int((float)floor((double)x * SK_Fixed1 + 0.5));
}
-static void write_xyz_tag(uint32_t* ptr, const SkMatrix44& toXYZ, int col) {
+static void write_xyz_tag(uint32_t* ptr, const float toXYZD50[9], int col) {
ptr[0] = SkEndian_SwapBE32(kXYZ_PCSSpace);
ptr[1] = 0;
- ptr[2] = SkEndian_SwapBE32(float_round_to_fixed(toXYZ.getFloat(0, col)));
- ptr[3] = SkEndian_SwapBE32(float_round_to_fixed(toXYZ.getFloat(1, col)));
- ptr[4] = SkEndian_SwapBE32(float_round_to_fixed(toXYZ.getFloat(2, col)));
+ ptr[2] = SkEndian_SwapBE32(float_round_to_fixed(toXYZD50[0*3 + col]));
+ ptr[3] = SkEndian_SwapBE32(float_round_to_fixed(toXYZD50[1*3 + col]));
+ ptr[4] = SkEndian_SwapBE32(float_round_to_fixed(toXYZD50[2*3 + col]));
}
static void write_trc_tag(uint32_t* ptr, const SkColorSpaceTransferFn& fn) {
@@ -309,12 +193,6 @@ static void write_trc_tag(uint32_t* ptr, const SkColorSpaceTransferFn& fn) {
ptr[9] = SkEndian_SwapBE32(float_round_to_fixed(fn.fF));
}
-static bool is_3x3(const SkMatrix44& toXYZD50) {
- return 0.0f == toXYZD50.get(3, 0) && 0.0f == toXYZD50.get(3, 1) && 0.0f == toXYZD50.get(3, 2) &&
- 0.0f == toXYZD50.get(0, 3) && 0.0f == toXYZD50.get(1, 3) && 0.0f == toXYZD50.get(2, 3) &&
- 1.0f == toXYZD50.get(3, 3);
-}
-
static bool nearly_equal(float x, float y) {
// A note on why I chose this tolerance: transfer_fn_almost_equal() uses a
// tolerance of 0.001f, which doesn't seem to be enough to distinguish
@@ -338,28 +216,18 @@ static bool nearly_equal(const SkColorSpaceTransferFn& u,
&& nearly_equal(u.fF, v.fF);
}
-static bool nearly_equal(const SkMatrix44& toXYZD50, const float standard[9]) {
- return nearly_equal(toXYZD50.getFloat(0, 0), standard[0])
- && nearly_equal(toXYZD50.getFloat(0, 1), standard[1])
- && nearly_equal(toXYZD50.getFloat(0, 2), standard[2])
- && nearly_equal(toXYZD50.getFloat(1, 0), standard[3])
- && nearly_equal(toXYZD50.getFloat(1, 1), standard[4])
- && nearly_equal(toXYZD50.getFloat(1, 2), standard[5])
- && nearly_equal(toXYZD50.getFloat(2, 0), standard[6])
- && nearly_equal(toXYZD50.getFloat(2, 1), standard[7])
- && nearly_equal(toXYZD50.getFloat(2, 2), standard[8])
- && nearly_equal(toXYZD50.getFloat(0, 3), 0.0f)
- && nearly_equal(toXYZD50.getFloat(1, 3), 0.0f)
- && nearly_equal(toXYZD50.getFloat(2, 3), 0.0f)
- && nearly_equal(toXYZD50.getFloat(3, 0), 0.0f)
- && nearly_equal(toXYZD50.getFloat(3, 1), 0.0f)
- && nearly_equal(toXYZD50.getFloat(3, 2), 0.0f)
- && nearly_equal(toXYZD50.getFloat(3, 3), 1.0f);
+static bool nearly_equal(const float u[9], const float v[9]) {
+ for (int i = 0; i < 9; i++) {
+ if (!nearly_equal(u[i], v[i])) {
+ return false;
+ }
+ }
+ return true;
}
// Return nullptr if the color profile doen't have a special name.
const char* get_color_profile_description(const SkColorSpaceTransferFn& fn,
- const SkMatrix44& toXYZD50) {
+ const float toXYZD50[9]) {
bool srgb_xfer = nearly_equal(fn, gSRGB_TransferFn);
bool srgb_gamut = nearly_equal(toXYZD50, gSRGB_toXYZD50);
if (srgb_xfer && srgb_gamut) {
@@ -400,7 +268,7 @@ const char* get_color_profile_description(const SkColorSpaceTransferFn& fn,
static void get_color_profile_tag(char dst[kICCDescriptionTagSize],
const SkColorSpaceTransferFn& fn,
- const SkMatrix44& toXYZD50) {
+ const float toXYZD50[9]) {
SkASSERT(dst);
if (const char* description = get_color_profile_description(fn, toXYZD50)) {
SkASSERT(strlen(description) < kICCDescriptionTagSize);
@@ -410,12 +278,7 @@ static void get_color_profile_tag(char dst[kICCDescriptionTagSize],
} else {
strncpy(dst, kDescriptionTagBodyPrefix, sizeof(kDescriptionTagBodyPrefix));
SkMD5 md5;
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 3; ++j) {
- float value = toXYZD50.getFloat(i,j);
- md5.write(&value, sizeof(value));
- }
- }
+ md5.write(toXYZD50, 9*sizeof(float));
static_assert(sizeof(fn) == sizeof(float) * 7, "packed");
md5.write(&fn, sizeof(fn));
SkMD5::Digest digest;
@@ -430,29 +293,8 @@ static void get_color_profile_tag(char dst[kICCDescriptionTagSize],
}
}
-SkString SkICCGetColorProfileTag(const SkColorSpaceTransferFn& fn,
- const SkMatrix44& toXYZD50) {
- char tag[kICCDescriptionTagSize];
- get_color_profile_tag(tag, fn, toXYZD50);
- size_t len = kICCDescriptionTagSize;
- while (len > 0 && tag[len - 1] == '\0') {
- --len; // tag is padded out with zeros
- }
- SkASSERT(len != 0);
- return SkString(tag, len);
-}
-
-// returns pointer just beyond where we just wrote.
-static uint8_t* string_copy_ascii_to_utf16be(uint8_t* dst, const char* src, size_t count) {
- while (count-- > 0) {
- *dst++ = 0;
- *dst++ = (uint8_t)(*src++);
- }
- return dst;
-}
-
-sk_sp<SkData> SkICC::WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix44& toXYZD50) {
- if (!is_3x3(toXYZD50) || !is_valid_transfer_fn(fn)) {
+sk_sp<SkData> SkWriteICCProfile(const SkColorSpaceTransferFn& fn, const float toXYZD50[9]) {
+ if (!is_valid_transfer_fn(fn)) {
return nullptr;
}
@@ -473,7 +315,12 @@ sk_sp<SkData> SkICC::WriteToICC(const SkColorSpaceTransferFn& fn, const SkMatrix
{
char colorProfileTag[kICCDescriptionTagSize];
get_color_profile_tag(colorProfileTag, fn, toXYZD50);
- ptr = string_copy_ascii_to_utf16be(ptr, colorProfileTag, kICCDescriptionTagSize);
+
+ // ASCII --> big-endian UTF-16.
+ for (size_t i = 0; i < kICCDescriptionTagSize; i++) {
+ *ptr++ = 0;
+ *ptr++ = colorProfileTag[i];
+ }
}
// Write XYZ tags
diff --git a/src/core/SkICCPriv.h b/src/core/SkICCPriv.h
index a50d362a55..3d2b8965a9 100644
--- a/src/core/SkICCPriv.h
+++ b/src/core/SkICCPriv.h
@@ -51,11 +51,4 @@ enum ParaCurveType {
kGABCDEF_ParaCurveType = 4,
};
-/*
- * Given fn and toXYZD50, generate a decription tag that either includes a hash
- * of the function and gamut or is a special name.
- * Exposed for unit testing and tools.
- */
-SkString SkICCGetColorProfileTag(const SkColorSpaceTransferFn& fn,
- const SkMatrix44& toXYZD50);
#endif // SkICCPriv_DEFINED
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index 8637541720..d8d1c64bb8 100644
--- a/src/images/SkImageEncoderFns.h
+++ b/src/images/SkImageEncoderFns.h
@@ -427,8 +427,6 @@ static inline sk_sp<SkData> icc_from_color_space(const SkImageInfo& info) {
if (cs->isNumericalTransferFn(&fn) && cs->toXYZD50(&toXYZD50)) {
return SkICC::WriteToICC(fn, toXYZD50);
}
-
- // TODO: Should we support writing ICC profiles for additional color spaces?
return nullptr;
}