concat gamut transform matrices together

Change-Id: Iafeac82d12efa190daf1d972384656cc9347a23e
Reviewed-on: https://skia-review.googlesource.com/120663
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/Transform.c b/src/Transform.c
index 1f46e35..7428ea6 100644
--- a/src/Transform.c
+++ b/src/Transform.c
@@ -301,6 +301,17 @@
     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;
+}
+
 bool skcms_Transform(const void*             src,
                      skcms_PixelFormat       srcFmt,
                      skcms_AlphaFormat       srcAlpha,
@@ -467,9 +478,11 @@
             if (!skcms_Matrix3x3_invert(&dstProfile->toXYZD50, &from_xyz)) {
                 return false;
             }
-            // TODO: concat these here and only append one matrix_3x3 op.
-            *ops++ = Op_matrix_3x3; *args++ =    to_xyz;
-            *ops++ = Op_matrix_3x3; *args++ = &from_xyz;
+            // 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);
+            *ops++  = Op_matrix_3x3;
+            *args++ = &from_xyz;
         }
 
         // Encode back to dst RGB using its parametric transfer functions.