From b5d1f244b2d7a73217a03742d4fffd25ad1427f4 Mon Sep 17 00:00:00 2001 From: "skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com" Date: Wed, 9 May 2018 18:44:08 +0000 Subject: Roll skia/third_party/skcms f771d23..78ee9e8 (1 commits) https://skia.googlesource.com/skcms.git/+log/f771d23..78ee9e8 2018-05-09 brianosman@google.com Add skcms_PrimariesToXYZD50 The AutoRoll server is located here: https://skcms-skia-roll.skia.org Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff, who should be CC'd on the roll, and stop the roller if necessary. CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel TBR=egdaniel@google.com Change-Id: Id29aa5abf53d1f4a79eff393f88f33ff6ff807bc Reviewed-on: https://skia-review.googlesource.com/127102 Commit-Queue: skcms-skia-autoroll Reviewed-by: skcms-skia-autoroll --- third_party/skcms/skcms.h | 6 +++ third_party/skcms/src/ICCProfile.c | 72 +++++++++++++++++++++++++++++++++++ third_party/skcms/src/LinearAlgebra.c | 11 ++++++ third_party/skcms/src/LinearAlgebra.h | 1 + third_party/skcms/src/Transform.c | 13 +------ third_party/skcms/version.sha1 | 2 +- 6 files changed, 92 insertions(+), 13 deletions(-) (limited to 'third_party/skcms') diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h index bb94ad57cc..79d0abf5cd 100644 --- a/third_party/skcms/skcms.h +++ b/third_party/skcms/skcms.h @@ -232,6 +232,12 @@ SKCMS_API bool skcms_MakeUsableAsDestination(skcms_ICCProfile* profile); // profile unchanged and return false. SKCMS_API bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile); +SKCMS_API bool skcms_PrimariesToXYZD50(float rx, float ry, + float gx, float gy, + float bx, float by, + float wx, float wy, + skcms_Matrix3x3* toXYZD50); + #ifdef __cplusplus } #endif diff --git a/third_party/skcms/src/ICCProfile.c b/third_party/skcms/src/ICCProfile.c index a242e24e2d..6b8c25df06 100644 --- a/third_party/skcms/src/ICCProfile.c +++ b/third_party/skcms/src/ICCProfile.c @@ -6,6 +6,7 @@ */ #include "../skcms.h" +#include "LinearAlgebra.h" #include "Macros.h" #include "PortableMath.h" #include "RandomBytes.h" @@ -933,3 +934,74 @@ bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A, const skcms_ICC } return true; } + +static bool is_zero_to_one(float x) { + return 0 <= x && x <= 1; +} + +bool skcms_PrimariesToXYZD50(float rx, float ry, + float gx, float gy, + float bx, float by, + float wx, float wy, + skcms_Matrix3x3* toXYZD50) { + if (!is_zero_to_one(rx) || !is_zero_to_one(ry) || + !is_zero_to_one(gx) || !is_zero_to_one(gy) || + !is_zero_to_one(bx) || !is_zero_to_one(by) || + !is_zero_to_one(wx) || !is_zero_to_one(wy) || + !toXYZD50) { + return false; + } + + // First, we need to convert xy values (primaries) to XYZ. + skcms_Matrix3x3 primaries = {{ + { rx, gx, bx }, + { ry, gy, by }, + { 1 - rx - ry, 1 - gx - gy, 1 - bx - by }, + }}; + skcms_Matrix3x3 primaries_inv; + if (!skcms_Matrix3x3_invert(&primaries, &primaries_inv)) { + return false; + } + + // Assumes that Y is 1.0f. + skcms_Vector3 wXYZ = { { wx / wy, 1, (1 - wx - wy) / wy } }; + skcms_Vector3 XYZ = skcms_MV_mul(&primaries_inv, &wXYZ); + + skcms_Matrix3x3 toXYZ = {{ + { XYZ.vals[0], 0, 0 }, + { 0, XYZ.vals[1], 0 }, + { 0, 0, XYZ.vals[2] }, + }}; + toXYZ = skcms_Matrix3x3_concat(&primaries, &toXYZ); + + // Now convert toXYZ matrix to toXYZD50. + skcms_Vector3 wXYZD50 = { { 0.96422f, 1.0f, 0.82521f } }; + + // Calculate the chromatic adaptation matrix. We will use the Bradford method, thus + // the matrices below. The Bradford method is used by Adobe and is widely considered + // to be the best. + skcms_Matrix3x3 xyz_to_lms = {{ + { 0.8951f, 0.2664f, -0.1614f }, + { -0.7502f, 1.7135f, 0.0367f }, + { 0.0389f, -0.0685f, 1.0296f }, + }}; + skcms_Matrix3x3 lms_to_xyz = {{ + { 0.9869929f, -0.1470543f, 0.1599627f }, + { 0.4323053f, 0.5183603f, 0.0492912f }, + { -0.0085287f, 0.0400428f, 0.9684867f }, + }}; + + skcms_Vector3 srcCone = skcms_MV_mul(&xyz_to_lms, &wXYZ); + skcms_Vector3 dstCone = skcms_MV_mul(&xyz_to_lms, &wXYZD50); + + skcms_Matrix3x3 DXtoD50 = {{ + { dstCone.vals[0] / srcCone.vals[0], 0, 0 }, + { 0, dstCone.vals[1] / srcCone.vals[1], 0 }, + { 0, 0, dstCone.vals[2] / srcCone.vals[2] }, + }}; + DXtoD50 = skcms_Matrix3x3_concat(&DXtoD50, &xyz_to_lms); + DXtoD50 = skcms_Matrix3x3_concat(&lms_to_xyz, &DXtoD50); + + *toXYZD50 = skcms_Matrix3x3_concat(&DXtoD50, &toXYZ); + return true; +} diff --git a/third_party/skcms/src/LinearAlgebra.c b/third_party/skcms/src/LinearAlgebra.c index 51127e6d1d..fb35e5c65c 100644 --- a/third_party/skcms/src/LinearAlgebra.c +++ b/third_party/skcms/src/LinearAlgebra.c @@ -67,6 +67,17 @@ bool skcms_Matrix3x3_invert(const skcms_Matrix3x3* src, skcms_Matrix3x3* dst) { return true; } +skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3* A, const skcms_Matrix3x3* B) { + skcms_Matrix3x3 m = { { { 0,0,0 },{ 0,0,0 },{ 0,0,0 } } }; + for (int r = 0; r < 3; r++) + for (int c = 0; c < 3; c++) { + m.vals[r][c] = A->vals[r][0] * B->vals[0][c] + + A->vals[r][1] * B->vals[1][c] + + A->vals[r][2] * B->vals[2][c]; + } + return m; +} + skcms_Vector3 skcms_MV_mul(const skcms_Matrix3x3* m, const skcms_Vector3* v) { skcms_Vector3 dst = {{0,0,0}}; for (int row = 0; row < 3; ++row) { diff --git a/third_party/skcms/src/LinearAlgebra.h b/third_party/skcms/src/LinearAlgebra.h index 47f53d9230..10b122645a 100644 --- a/third_party/skcms/src/LinearAlgebra.h +++ b/third_party/skcms/src/LinearAlgebra.h @@ -13,5 +13,6 @@ typedef struct { float vals[3]; } skcms_Vector3; // It is _not_ safe to alias the pointers to invert in-place. bool skcms_Matrix3x3_invert(const skcms_Matrix3x3*, skcms_Matrix3x3*); +skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3* A, const skcms_Matrix3x3* B); skcms_Vector3 skcms_MV_mul(const skcms_Matrix3x3*, const skcms_Vector3*); diff --git a/third_party/skcms/src/Transform.c b/third_party/skcms/src/Transform.c index 59851e8c00..9d359d2623 100644 --- a/third_party/skcms/src/Transform.c +++ b/third_party/skcms/src/Transform.c @@ -365,17 +365,6 @@ static size_t bytes_per_pixel(skcms_PixelFormat fmt) { return 0; } -static skcms_Matrix3x3 concat_3x3(const skcms_Matrix3x3* A, const skcms_Matrix3x3* B) { - skcms_Matrix3x3 m = {{ {0,0,0}, {0,0,0}, {0,0,0} }}; - for (int r = 0; r < 3; r++) - for (int c = 0; c < 3; c++) { - m.vals[r][c] = A->vals[r][0] * B->vals[0][c] - + A->vals[r][1] * B->vals[1][c] - + A->vals[r][2] * B->vals[2][c]; - } - return m; -} - static bool prep_for_destination(const skcms_ICCProfile* profile, skcms_Matrix3x3* fromXYZD50, skcms_TransferFunction* invR, @@ -562,7 +551,7 @@ bool skcms_Transform(const void* src, if (0 != memcmp(&dstProfile->toXYZD50, to_xyz, sizeof(skcms_Matrix3x3))) { // Concat the entire gamut transform into from_xyz, // now slightly misnamed but it's a handy spot to stash the result. - from_xyz = concat_3x3(&from_xyz, to_xyz); + from_xyz = skcms_Matrix3x3_concat(&from_xyz, to_xyz); *ops++ = Op_matrix_3x3; *args++ = &from_xyz; } diff --git a/third_party/skcms/version.sha1 b/third_party/skcms/version.sha1 index c85bd27354..c733dd87f7 100755 --- a/third_party/skcms/version.sha1 +++ b/third_party/skcms/version.sha1 @@ -1 +1 @@ -f771d234ebdc7a1297ad6afd7574987d2ed2c7ad \ No newline at end of file +78ee9e8913e0ab2ddb5208b7844b24f1301ce37e \ No newline at end of file -- cgit v1.2.3