Enable flattening and unflattening of SkColorSpace

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2085653003

Review-Url: https://codereview.chromium.org/2085653003
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h
index 4b55c47..57f74e9 100644
--- a/include/core/SkColorSpace.h
+++ b/include/core/SkColorSpace.h
@@ -11,6 +11,8 @@
 #include "SkMatrix44.h"
 #include "SkRefCnt.h"
 
+class SkData;
+
 class SK_API SkColorSpace : public SkRefCnt {
 public:
 
@@ -75,11 +77,17 @@
         return kSRGB_GammaNamed == fGammaNamed || k2Dot2Curve_GammaNamed == fGammaNamed;
     }
 
+    /**
+     *  Returns nullptr on failure.  Fails when we fallback to serializing ICC data and
+     *  the data is too large to serialize.
+     */
+    sk_sp<SkData> serialize() const;
+
+    static sk_sp<SkColorSpace> Deserialize(const void* data, size_t length);
+
 protected:
     SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Named named);
 
-    friend Named sk_deduce_named_from_colorspace(SkColorSpace*);
-
     const GammaNamed fGammaNamed;
     const SkMatrix44 fToXYZD50;
     const Named      fNamed;
diff --git a/include/core/SkMatrix44.h b/include/core/SkMatrix44.h
index d64d4b7..715ee78 100644
--- a/include/core/SkMatrix44.h
+++ b/include/core/SkMatrix44.h
@@ -439,6 +439,15 @@
         kAllPublic_Masks = 0xF
     };
 
+    /** Efficiently reads 12 matrix entries, ignoring the last col.
+     *  This is typically useful when we know the last col is (0, 0, 0, 1).
+     */
+    void as4x3ColMajorf(float[]) const;
+
+    /* This sets the top-left of the matrix and clears the
+     * perspective components (with [3][3] set to 1). */
+    void set4x3ColMajorf(const float[]);
+
     SkMScalar transX() const { return fMat[3][0]; }
     SkMScalar transY() const { return fMat[3][1]; }
     SkMScalar transZ() const { return fMat[3][2]; }
@@ -469,6 +478,8 @@
     inline bool isTriviallyIdentity() const {
         return 0 == fTypeMask;
     }
+
+    friend class SkColorSpace;
 };
 
 #endif
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 5df45ff..95c38f2 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -9,6 +9,8 @@
 #include "SkColorSpace_Base.h"
 #include "SkEndian.h"
 #include "SkOnce.h"
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
 
 #define SkColorSpacePrintf(...)
 
@@ -24,11 +26,10 @@
     , fNamed(named)
 {}
 
-SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Named named,
-                                     sk_sp<SkData> profileData)
+SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Named named)
     : INHERITED(gammaNamed, toXYZD50, named)
     , fGammas(nullptr)
-    , fProfileData(std::move(profileData))
+    , fProfileData(nullptr)
 {}
 
 SkColorSpace_Base::SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas,
@@ -102,11 +103,10 @@
         return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, gammas, toXYZD50, nullptr));
     }
 
-    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50, nullptr);
+    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50);
 }
 
-sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50,
-                                              sk_sp<SkData> profileData) {
+sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50) {
     switch (gammaNamed) {
         case kSRGB_GammaNamed:
             if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) {
@@ -125,12 +125,11 @@
             break;
     }
 
-    return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnknown_Named,
-                                                     profileData));
+    return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnknown_Named));
 }
 
 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50) {
-    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50, nullptr);
+    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50);
 }
 
 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) {
@@ -144,7 +143,7 @@
             sRGBOnce([] {
                 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor);
                 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50);
-                sRGB = new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50, kSRGB_Named, nullptr);
+                sRGB = new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50, kSRGB_Named);
             });
             return sk_ref_sp(sRGB);
         }
@@ -153,7 +152,7 @@
                 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Constructor);
                 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50);
                 adobeRGB = new SkColorSpace_Base(k2Dot2Curve_GammaNamed, adobergbToxyzD50,
-                                                 kAdobeRGB_Named, nullptr);
+                                                 kAdobeRGB_Named);
             });
             return sk_ref_sp(adobeRGB);
         }
@@ -930,7 +929,7 @@
                     return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, std::move(gammas),
                                                                      mat, std::move(data)));
                 } else {
-                    return SkColorSpace_Base::NewRGB(gammaNamed, mat, std::move(data));
+                    return SkColorSpace_Base::NewRGB(gammaNamed, mat);
                 }
             }
 
@@ -955,7 +954,7 @@
                                                                      std::move(gammas), toXYZ,
                                                                      std::move(data)));
                 } else {
-                    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ, std::move(data));
+                    return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ);
                 }
             }
         }
@@ -1208,3 +1207,153 @@
     //                 the client calls again?
     return SkData::MakeFromMalloc(profile.release(), kICCProfileSize);
 }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+enum Version {
+    k0_Version, // Initial version, header + flags for matrix and profile
+};
+
+struct ColorSpaceHeader {
+    /**
+     *  If kMatrix_Flag is set, we will write 12 floats after the header.
+     *  Should not be set at the same time as the kICC_Flag.
+     */
+    static constexpr uint8_t kMatrix_Flag = 1 << 0;
+
+    /**
+     *  If kICC_Flag is set, we will write an ICC profile after the header.
+     *  The ICC profile will be written as a uint32 size, followed immediately
+     *  by the data (padded to 4 bytes).
+     *  Should not be set at the same time as the kMatrix_Flag.
+     */
+    static constexpr uint8_t kICC_Flag    = 1 << 1;
+
+    static ColorSpaceHeader Pack(Version version, SkColorSpace::Named named,
+                                 SkColorSpace::GammaNamed gammaNamed, uint8_t flags) {
+        ColorSpaceHeader header;
+
+        SkASSERT(k0_Version == version);
+        header.fVersion = (uint8_t) version;
+
+        SkASSERT(named <= SkColorSpace::kAdobeRGB_Named);
+        header.fNamed = (uint8_t) named;
+
+        SkASSERT(gammaNamed <= SkColorSpace::kNonStandard_GammaNamed);
+        header.fGammaNamed = (uint8_t) gammaNamed;
+
+        SkASSERT(flags <= kICC_Flag);
+        header.fFlags = flags;
+        return header;
+    }
+
+    uint8_t fVersion;    // Always zero
+    uint8_t fNamed;      // Must be a SkColorSpace::Named
+    uint8_t fGammaNamed; // Must be a SkColorSpace::GammaNamed
+    uint8_t fFlags;      // Some combination of the flags listed above
+};
+
+sk_sp<SkData> SkColorSpace::serialize() const {
+    // If we have a named profile, only write the enum.
+    switch (fNamed) {
+        case kSRGB_Named:
+        case kAdobeRGB_Named: {
+            sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader));
+            *((ColorSpaceHeader*) data->writable_data()) =
+                    ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, 0);
+            return data;
+        }
+        default:
+            break;
+    }
+
+    // If we have a named gamma, write the enum and the matrix.
+    switch (fGammaNamed) {
+        case kSRGB_GammaNamed:
+        case k2Dot2Curve_GammaNamed:
+        case kLinear_GammaNamed: {
+            sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader) +
+                                                           12 * sizeof(float));
+            void* dataPtr = data->writable_data();
+
+            *((ColorSpaceHeader*) dataPtr) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed,
+                                                                    ColorSpaceHeader::kMatrix_Flag);
+            dataPtr = SkTAddOffset<void>(dataPtr, sizeof(ColorSpaceHeader));
+
+            fToXYZD50.as4x3ColMajorf((float*) dataPtr);
+            return data;
+        }
+        default:
+            break;
+    }
+
+    // If we do not have a named gamma, this must have been created from an ICC profile.
+    // Since we were unable to recognize the gamma, we will have saved the ICC data.
+    SkASSERT(as_CSB(this)->fProfileData);
+
+    size_t profileSize = as_CSB(this)->fProfileData->size();
+    if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) {
+        return nullptr;
+    }
+
+    sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader) + sizeof(uint32_t) +
+                                                   SkAlign4(profileSize));
+    void* dataPtr = data->writable_data();
+
+    *((ColorSpaceHeader*) dataPtr) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed,
+                                                            ColorSpaceHeader::kICC_Flag);
+    dataPtr = SkTAddOffset<void>(dataPtr, sizeof(ColorSpaceHeader));
+
+    *((uint32_t*) dataPtr) = (uint32_t) SkAlign4(profileSize);
+    dataPtr = SkTAddOffset<void>(dataPtr, sizeof(uint32_t));
+
+    memcpy(dataPtr, as_CSB(this)->fProfileData->data(), profileSize);
+    memset(SkTAddOffset<void>(dataPtr, profileSize), 0, SkAlign4(profileSize) - profileSize);
+    return data;
+}
+
+sk_sp<SkColorSpace> SkColorSpace::Deserialize(const void* data, size_t length) {
+    if (length < sizeof(ColorSpaceHeader)) {
+        return nullptr;
+    }
+
+    ColorSpaceHeader header = *((const ColorSpaceHeader*) data);
+    data = SkTAddOffset<const void>(data, sizeof(ColorSpaceHeader));
+    length -= sizeof(ColorSpaceHeader);
+    switch ((Named) header.fNamed) {
+        case kSRGB_Named:
+        case kAdobeRGB_Named:
+            return NewNamed((Named) header.fNamed);
+        default:
+            break;
+    }
+
+    switch ((GammaNamed) header.fGammaNamed) {
+        case kSRGB_GammaNamed:
+        case k2Dot2Curve_GammaNamed:
+        case kLinear_GammaNamed: {
+            if (ColorSpaceHeader::kMatrix_Flag != header.fFlags || length < 12 * sizeof(float)) {
+                return nullptr;
+            }
+
+            SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
+            toXYZ.set4x3ColMajorf((const float*) data);
+            return NewRGB((GammaNamed) header.fGammaNamed, toXYZ);
+        }
+        default:
+            break;
+    }
+
+    if (ColorSpaceHeader::kICC_Flag != header.fFlags || length < sizeof(uint32_t)) {
+        return nullptr;
+    }
+
+    uint32_t profileSize = *((uint32_t*) data);
+    data = SkTAddOffset<const void>(data, sizeof(uint32_t));
+    length -= sizeof(uint32_t);
+    if (length < profileSize) {
+        return nullptr;
+    }
+
+    return NewICC(data, profileSize);
+}
diff --git a/src/core/SkColorSpace_Base.h b/src/core/SkColorSpace_Base.h
index fc4f665..9f63915 100644
--- a/src/core/SkColorSpace_Base.h
+++ b/src/core/SkColorSpace_Base.h
@@ -159,11 +159,9 @@
 
 private:
 
-    static sk_sp<SkColorSpace> NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50,
-                                      sk_sp<SkData> profileData);
+    static sk_sp<SkColorSpace> NewRGB(GammaNamed gammaNamed, const SkMatrix44& toXYZD50);
 
-    SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZ, Named named,
-                      sk_sp<SkData> profileData);
+    SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& toXYZ, Named named);
 
     SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGammas> gammas, const SkMatrix44& toXYZ,
                       sk_sp<SkData> profileData);
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index ee16923..ba418d5 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -9,50 +9,6 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 
-/*
- *  We store this as a byte in the ImageInfo flatten buffer.
- */
-enum class SkFlattenColorSpaceEnum {
-    kUnspecified,
-    kSRGB,
-    kAdobe1998,
-    // ... add more here
-    kLastEnum = kAdobe1998,
-    // final value means the actual profile data follows the info
-    kICCProfile = 0xFF,
-};
-
-static sk_sp<SkColorSpace> make_from_enum(SkFlattenColorSpaceEnum value) {
-    switch (value) {
-        case SkFlattenColorSpaceEnum::kSRGB:
-            return SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
-        case SkFlattenColorSpaceEnum::kAdobe1998:
-            return SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named);
-        default:
-            return nullptr;
-    }
-}
-
-SkColorSpace::Named sk_deduce_named_from_colorspace(SkColorSpace* cs) {
-    return cs->fNamed;
-}
-
-static SkFlattenColorSpaceEnum deduce_from_colorspace(SkColorSpace* cs) {
-    if (!cs) {
-        return SkFlattenColorSpaceEnum::kUnspecified;
-    }
-    switch (sk_deduce_named_from_colorspace(cs)) {
-        case SkColorSpace::kSRGB_Named:
-            return SkFlattenColorSpaceEnum::kSRGB;
-        case SkColorSpace::kAdobeRGB_Named:
-            return SkFlattenColorSpaceEnum::kAdobe1998;
-        default:
-            return SkFlattenColorSpaceEnum::kICCProfile;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
 #ifdef SK_SUPPORT_LEGACY_COLORPROFILETYPE
 SkColorProfileType SkImageInfo::profileType() const {
     return fColorSpace && fColorSpace->gammaCloseToSRGB()
@@ -81,40 +37,31 @@
     SkASSERT(0 == (packed >> 24));
     fColorType = (SkColorType)((packed >> 0) & 0xFF);
     fAlphaType = (SkAlphaType)((packed >> 8) & 0xFF);
-    SkFlattenColorSpaceEnum csenum = (SkFlattenColorSpaceEnum)((packed >> 16) & 0xFF);
     buffer.validate(alpha_type_is_valid(fAlphaType) && color_type_is_valid(fColorType));
 
-    if (SkFlattenColorSpaceEnum::kICCProfile == csenum) {
-        SkASSERT(false);    // we shouldn't hit this yet, as we don't write these yet
-        fColorSpace.reset();
-    } else {
-        if (csenum > SkFlattenColorSpaceEnum::kLastEnum) {
-            csenum = SkFlattenColorSpaceEnum::kUnspecified;
-        }
-        fColorSpace = make_from_enum(csenum);
-    }
+    sk_sp<SkData> data = buffer.readByteArrayAsData();
+    fColorSpace = SkColorSpace::Deserialize(data->data(), data->size());
 }
 
 void SkImageInfo::flatten(SkWriteBuffer& buffer) const {
     buffer.write32(fWidth);
     buffer.write32(fHeight);
 
-    SkFlattenColorSpaceEnum csenum = deduce_from_colorspace(fColorSpace.get());
-
-    // TODO: when we actually support flattening the colorspace to a profile blob, remove this
-    //       hack (and write the blob after we write packed.
-    if (SkFlattenColorSpaceEnum::kICCProfile == csenum) {
-        csenum = SkFlattenColorSpaceEnum::kUnspecified;
-    }
-
-    SkASSERT(0 == ((int)csenum & ~0xFF));
     SkASSERT(0 == (fAlphaType & ~0xFF));
     SkASSERT(0 == (fColorType & ~0xFF));
-    uint32_t packed = ((int)csenum << 16) | (fAlphaType << 8) | fColorType;
+    uint32_t packed = (fAlphaType << 8) | fColorType;
     buffer.write32(packed);
 
-    if (SkFlattenColorSpaceEnum::kICCProfile == csenum) {
-        // TODO: write the ICCProfile blob
+    if (fColorSpace) {
+        sk_sp<SkData> data = fColorSpace->serialize();
+        if (data) {
+            buffer.writeDataAsByteArray(data.get());
+        } else {
+            buffer.writeByteArray(nullptr, 0);
+        }
+    } else {
+        sk_sp<SkData> data = SkData::MakeEmpty();
+        buffer.writeDataAsByteArray(data.get());
     }
 }
 
diff --git a/src/core/SkMatrix44.cpp b/src/core/SkMatrix44.cpp
index 34b5327..56c2e8a 100644
--- a/src/core/SkMatrix44.cpp
+++ b/src/core/SkMatrix44.cpp
@@ -85,6 +85,17 @@
 #endif
 }
 
+void SkMatrix44::as4x3ColMajorf(float dst[]) const {
+    const SkMScalar* src = &fMat[0][0];
+#ifdef SK_MSCALAR_IS_DOUBLE
+    for (int i = 0; i < 12; ++i) {
+        dst[i] = SkMScalarToFloat(src[i]);
+    }
+#elif defined SK_MSCALAR_IS_FLOAT
+    memcpy(dst, src, 12 * sizeof(float));
+#endif
+}
+
 void SkMatrix44::asColMajord(double dst[]) const {
     const SkMScalar* src = &fMat[0][0];
 #ifdef SK_MSCALAR_IS_DOUBLE
@@ -217,6 +228,14 @@
     this->dirtyTypeMask();
 }
 
+void SkMatrix44::set4x3ColMajorf(const float src[]) {
+    fMat[0][0] = src[0]; fMat[0][1] = src[1]; fMat[0][2] = src[2];  fMat[0][3] = src[3];
+    fMat[1][0] = src[4]; fMat[1][1] = src[5]; fMat[1][2] = src[6];  fMat[1][3] = src[7];
+    fMat[2][0] = src[8]; fMat[2][1] = src[9]; fMat[2][2] = src[10]; fMat[2][3] = src[11];
+    fMat[3][0] = 0;      fMat[3][1] = 0;      fMat[3][2] = 0;       fMat[3][3] = 1;
+    this->dirtyTypeMask();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkMatrix44::setTranslate(SkMScalar dx, SkMScalar dy, SkMScalar dz) {
diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp
index 4b39ab0..853bdce 100644
--- a/tests/ColorSpaceTest.cpp
+++ b/tests/ColorSpaceTest.cpp
@@ -165,3 +165,41 @@
     SkImageInfo info = SkImageInfo::MakeS32(10, 10, kPremul_SkAlphaType);
     REPORTER_ASSERT(r, info.gammaCloseToSRGB());
 }
+
+static void test_serialize(skiatest::Reporter* r, SkColorSpace* space, bool isNamed) {
+    sk_sp<SkData> data = space->serialize();
+    sk_sp<SkColorSpace> newSpace = SkColorSpace::Deserialize(data->data(), data->size());
+
+    if (isNamed) {
+        REPORTER_ASSERT(r, space == newSpace.get());
+    } else {
+        REPORTER_ASSERT(r, space->gammaNamed() == newSpace->gammaNamed());
+
+        REPORTER_ASSERT(r, space->xyz().getFloat(0, 0) == newSpace->xyz().getFloat(0, 0));
+        REPORTER_ASSERT(r, space->xyz().getFloat(0, 1) == newSpace->xyz().getFloat(0, 1));
+        REPORTER_ASSERT(r, space->xyz().getFloat(0, 2) == newSpace->xyz().getFloat(0, 2));
+        REPORTER_ASSERT(r, space->xyz().getFloat(0, 3) == newSpace->xyz().getFloat(0, 3));
+        REPORTER_ASSERT(r, space->xyz().getFloat(1, 0) == newSpace->xyz().getFloat(1, 0));
+        REPORTER_ASSERT(r, space->xyz().getFloat(1, 1) == newSpace->xyz().getFloat(1, 1));
+        REPORTER_ASSERT(r, space->xyz().getFloat(1, 2) == newSpace->xyz().getFloat(1, 2));
+        REPORTER_ASSERT(r, space->xyz().getFloat(1, 3) == newSpace->xyz().getFloat(1, 3));
+        REPORTER_ASSERT(r, space->xyz().getFloat(2, 0) == newSpace->xyz().getFloat(2, 0));
+        REPORTER_ASSERT(r, space->xyz().getFloat(2, 1) == newSpace->xyz().getFloat(2, 1));
+        REPORTER_ASSERT(r, space->xyz().getFloat(2, 2) == newSpace->xyz().getFloat(2, 2));
+        REPORTER_ASSERT(r, space->xyz().getFloat(2, 3) == newSpace->xyz().getFloat(2, 3));
+        REPORTER_ASSERT(r, space->xyz().getFloat(3, 0) == newSpace->xyz().getFloat(3, 0));
+        REPORTER_ASSERT(r, space->xyz().getFloat(3, 1) == newSpace->xyz().getFloat(3, 1));
+        REPORTER_ASSERT(r, space->xyz().getFloat(3, 2) == newSpace->xyz().getFloat(3, 2));
+        REPORTER_ASSERT(r, space->xyz().getFloat(3, 3) == newSpace->xyz().getFloat(3, 3));
+    }
+}
+
+DEF_TEST(ColorSpace_Serialize, r) {
+    test_serialize(r, SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named).get(), true);
+    test_serialize(r, SkColorSpace::NewNamed(SkColorSpace::kAdobeRGB_Named).get(), true);
+
+    sk_sp<SkData> monitorData = SkData::MakeFromFileName(
+            GetResourcePath("monitor_profiles/HP_ZR30w.icc").c_str());
+    test_serialize(r, SkColorSpace::NewICC(monitorData->data(), monitorData->size()).get(), false);
+}
+
diff --git a/tests/ImageIsOpaqueTest.cpp b/tests/ImageIsOpaqueTest.cpp
index 42c9f99..843c1d1 100644
--- a/tests/ImageIsOpaqueTest.cpp
+++ b/tests/ImageIsOpaqueTest.cpp
@@ -31,9 +31,7 @@
     info2.unflatten(rb);
     REPORTER_ASSERT(reporter, rb.offset() == wb.bytesWritten());
 
-    // FIXME (msarett):
-    // Support flatten/unflatten of SkColorSpace objects.
-    REPORTER_ASSERT(reporter, info.makeColorSpace(nullptr) == info2.makeColorSpace(nullptr));
+    REPORTER_ASSERT(reporter, info == info2);
 }
 
 DEF_TEST(ImageInfo_flattening, reporter) {