diff options
-rw-r--r-- | include/core/SkColorSpace.h | 6 | ||||
-rw-r--r-- | src/core/SkColorSpace.cpp | 60 | ||||
-rw-r--r-- | tests/ColorSpaceTest.cpp | 54 |
3 files changed, 73 insertions, 47 deletions
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h index 2bf2ed0de6..9fc5ccde71 100644 --- a/include/core/SkColorSpace.h +++ b/include/core/SkColorSpace.h @@ -96,6 +96,12 @@ public: */ sk_sp<SkData> serialize() const; + /** + * If |memory| is nullptr, returns the size required to serialize. + * Otherwise, serializes into |memory| and returns the size. + */ + size_t writeToMemory(void* memory) const; + static sk_sp<SkColorSpace> Deserialize(const void* data, size_t length); protected: diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp index 67100d2cc0..6c34277b31 100644 --- a/src/core/SkColorSpace.cpp +++ b/src/core/SkColorSpace.cpp @@ -200,15 +200,16 @@ struct ColorSpaceHeader { uint8_t fFlags; // Some combination of the flags listed above }; -sk_sp<SkData> SkColorSpace::serialize() const { +size_t SkColorSpace::writeToMemory(void* memory) 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; + if (memory) { + *((ColorSpaceHeader*) memory) = + ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, 0); + } + return sizeof(ColorSpaceHeader); } default: break; @@ -219,16 +220,14 @@ sk_sp<SkData> SkColorSpace::serialize() const { 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; + if (memory) { + *((ColorSpaceHeader*) memory) = + ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, + ColorSpaceHeader::kMatrix_Flag); + memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)); + fToXYZD50.as4x3ColMajorf((float*) memory); + } + return sizeof(ColorSpaceHeader) + 12 * sizeof(float); } default: break; @@ -240,22 +239,31 @@ sk_sp<SkData> SkColorSpace::serialize() const { size_t profileSize = as_CSB(this)->fProfileData->size(); if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { - return nullptr; + return 0; } - sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(ColorSpaceHeader) + sizeof(uint32_t) + - SkAlign4(profileSize)); - void* dataPtr = data->writable_data(); + if (memory) { + *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, + ColorSpaceHeader::kICC_Flag); + memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)); - *((ColorSpaceHeader*) dataPtr) = ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNamed, - ColorSpaceHeader::kICC_Flag); - dataPtr = SkTAddOffset<void>(dataPtr, sizeof(ColorSpaceHeader)); + *((uint32_t*) memory) = (uint32_t) SkAlign4(profileSize); + memory = SkTAddOffset<void>(memory, sizeof(uint32_t)); - *((uint32_t*) dataPtr) = (uint32_t) SkAlign4(profileSize); - dataPtr = SkTAddOffset<void>(dataPtr, sizeof(uint32_t)); + memcpy(memory, as_CSB(this)->fProfileData->data(), profileSize); + memset(SkTAddOffset<void>(memory, profileSize), 0, SkAlign4(profileSize) - profileSize); + } + return sizeof(ColorSpaceHeader) + sizeof(uint32_t) + SkAlign4(profileSize); +} + +sk_sp<SkData> SkColorSpace::serialize() const { + size_t size = this->writeToMemory(nullptr); + if (0 == size) { + return nullptr; + } - memcpy(dataPtr, as_CSB(this)->fProfileData->data(), profileSize); - memset(SkTAddOffset<void>(dataPtr, profileSize), 0, SkAlign4(profileSize) - profileSize); + sk_sp<SkData> data = SkData::MakeUninitialized(size); + this->writeToMemory(data->writable_data()); return data; } diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp index df03ea40c2..f9593d91f9 100644 --- a/tests/ColorSpaceTest.cpp +++ b/tests/ColorSpaceTest.cpp @@ -166,31 +166,43 @@ DEF_TEST(ColorSpace_Named, r) { REPORTER_ASSERT(r, info.gammaCloseToSRGB()); } +static void matrix_equals(skiatest::Reporter* r, SkColorSpace* space1, SkColorSpace* space2) { + REPORTER_ASSERT(r, space1->xyz().getFloat(0, 0) == space2->xyz().getFloat(0, 0)); + REPORTER_ASSERT(r, space1->xyz().getFloat(0, 1) == space2->xyz().getFloat(0, 1)); + REPORTER_ASSERT(r, space1->xyz().getFloat(0, 2) == space2->xyz().getFloat(0, 2)); + REPORTER_ASSERT(r, space1->xyz().getFloat(0, 3) == space2->xyz().getFloat(0, 3)); + REPORTER_ASSERT(r, space1->xyz().getFloat(1, 0) == space2->xyz().getFloat(1, 0)); + REPORTER_ASSERT(r, space1->xyz().getFloat(1, 1) == space2->xyz().getFloat(1, 1)); + REPORTER_ASSERT(r, space1->xyz().getFloat(1, 2) == space2->xyz().getFloat(1, 2)); + REPORTER_ASSERT(r, space1->xyz().getFloat(1, 3) == space2->xyz().getFloat(1, 3)); + REPORTER_ASSERT(r, space1->xyz().getFloat(2, 0) == space2->xyz().getFloat(2, 0)); + REPORTER_ASSERT(r, space1->xyz().getFloat(2, 1) == space2->xyz().getFloat(2, 1)); + REPORTER_ASSERT(r, space1->xyz().getFloat(2, 2) == space2->xyz().getFloat(2, 2)); + REPORTER_ASSERT(r, space1->xyz().getFloat(2, 3) == space2->xyz().getFloat(2, 3)); + REPORTER_ASSERT(r, space1->xyz().getFloat(3, 0) == space2->xyz().getFloat(3, 0)); + REPORTER_ASSERT(r, space1->xyz().getFloat(3, 1) == space2->xyz().getFloat(3, 1)); + REPORTER_ASSERT(r, space1->xyz().getFloat(3, 2) == space2->xyz().getFloat(3, 2)); + REPORTER_ASSERT(r, space1->xyz().getFloat(3, 3) == space2->xyz().getFloat(3, 3)); +} + 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()); + sk_sp<SkData> data1 = space->serialize(); + + size_t bytes = space->writeToMemory(nullptr); + sk_sp<SkData> data2 = SkData::MakeUninitialized(bytes); + space->writeToMemory(data2->writable_data()); + + sk_sp<SkColorSpace> newSpace1 = SkColorSpace::Deserialize(data1->data(), data1->size()); + sk_sp<SkColorSpace> newSpace2 = SkColorSpace::Deserialize(data2->data(), data2->size()); if (isNamed) { - REPORTER_ASSERT(r, space == newSpace.get()); + REPORTER_ASSERT(r, space == newSpace1.get()); + REPORTER_ASSERT(r, space == newSpace2.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)); + REPORTER_ASSERT(r, space->gammaNamed() == newSpace1->gammaNamed()); + REPORTER_ASSERT(r, space->gammaNamed() == newSpace2->gammaNamed()); + matrix_equals(r, space, newSpace1.get()); + matrix_equals(r, space, newSpace2.get()); } } |