aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/skcms
diff options
context:
space:
mode:
authorGravatar skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>2018-05-09 18:44:08 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-09 19:40:51 +0000
commitb5d1f244b2d7a73217a03742d4fffd25ad1427f4 (patch)
tree0c619b94f4f8eb10c05bdc00d3b24f028ef8dbfe /third_party/skcms
parente61b969a07ba3ebe9e47e61381ad16c5d2c549a2 (diff)
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 <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com> Reviewed-by: skcms-skia-autoroll <skcms-skia-autoroll@skia-buildbots.google.com.iam.gserviceaccount.com>
Diffstat (limited to 'third_party/skcms')
-rw-r--r--third_party/skcms/skcms.h6
-rw-r--r--third_party/skcms/src/ICCProfile.c72
-rw-r--r--third_party/skcms/src/LinearAlgebra.c11
-rw-r--r--third_party/skcms/src/LinearAlgebra.h1
-rw-r--r--third_party/skcms/src/Transform.c13
-rwxr-xr-xthird_party/skcms/version.sha12
6 files changed, 92 insertions, 13 deletions
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