diff --git a/include/core/SkSerialProcs.h b/include/core/SkSerialProcs.h index d55d1a8405..e1f4c61455 100644 --- a/include/core/SkSerialProcs.h +++ b/include/core/SkSerialProcs.h @@ -13,16 +13,14 @@ #include "SkTypeface.h" /** - * A serial-proc is asked to serialize the specified object (e.g. picture or image), by writing - * its serialized form into the specified stream. If the proc does this, it returns true. - * - * If the proc chooses to have Skia perform its default action, it ignores the stream parameter - * and just returns false. + * A serial-proc is asked to serialize the specified object (e.g. picture or image). + * If a data object is returned, it will be used (even if it is zero-length). + * If null is returned, then Skia will take its default action. */ -typedef bool (*SkSerialPictureProc)(SkPicture*, SkWStream*, void* ctx); -typedef bool (*SkSerialImageProc)(SkImage*, SkWStream*, void* ctx); -typedef bool (*SkSerialTypefaceProc)(SkTypeface*, SkWStream*, void* ctx); +typedef sk_sp (*SkSerialPictureProc)(SkPicture*, void* ctx); +typedef sk_sp (*SkSerialImageProc)(SkImage*, void* ctx); +typedef sk_sp (*SkSerialTypefaceProc)(SkTypeface*, void* ctx); /** * A deserial-proc is given the serialized form previously returned by the corresponding diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index e87439aad9..5442738368 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -273,14 +273,9 @@ bool SkPicture::PictureIOSecurityPrecautionsEnabled() { ////////////////////////////////////////////////////////////////////////////////////////////////// -bool PixelSerializer_SkSerialImageProc(SkImage* img, SkWStream* stream, void* ctx) { +sk_sp PixelSerializer_SkSerialImageProc(SkImage* img, void* ctx) { SkASSERT(ctx); - sk_sp enc = img->encodeToData(static_cast(ctx)); - if (enc) { - stream->write(enc->data(), enc->size()); - return true; - } - return false; + return img->encodeToData(static_cast(ctx)); } sk_sp ImageDeserializer_SkDeserialImageProc(const void* data, size_t length, void* ctx) { diff --git a/src/core/SkPictureCommon.h b/src/core/SkPictureCommon.h index 74d693f56b..c282f01fec 100644 --- a/src/core/SkPictureCommon.h +++ b/src/core/SkPictureCommon.h @@ -142,7 +142,7 @@ struct SkPathCounter { int fNumSlowPathsAndDashEffects; }; -bool PixelSerializer_SkSerialImageProc(SkImage*, SkWStream*, void* sk_pixelserializer); +sk_sp PixelSerializer_SkSerialImageProc(SkImage*, void* pixelserializer); sk_sp ImageDeserializer_SkDeserialImageProc(const void*, size_t, void* imagedeserializer); #endif // SkPictureCommon_DEFINED diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp index 49cccd6783..bd1d64b76a 100644 --- a/src/core/SkWriteBuffer.cpp +++ b/src/core/SkWriteBuffer.cpp @@ -140,17 +140,18 @@ void SkBinaryWriteBuffer::writeImage(const SkImage* image) { this->writeInt(image->height()); auto write_data = [this](sk_sp data, int sign) { - if (data) { - size_t size = data->size(); - if (size && sk_64_isS32(size)) { - this->write32(SkToS32(size) * sign); - this->writePad32(data->data(), size); // does nothing if size == 0 - this->write32(0); // origin-x - this->write32(0); // origin-y - return; - } + size_t size = data ? data->size() : 0; + if (!sk_64_isS32(size)) { + size = 0; // too big to store + } + if (size) { + this->write32(SkToS32(size) * sign); + this->writePad32(data->data(), size); // does nothing if size == 0 + this->write32(0); // origin-x + this->write32(0); // origin-y + } else { + this->write32(0); // signal no image } - this->write32(0); // no data or size too big }; /* @@ -159,14 +160,19 @@ void SkBinaryWriteBuffer::writeImage(const SkImage* image) { * <0 : negative (int32_t) of a custom encoded blob using SerialProcs * >0 : standard encoded blob size (use MakeFromEncoded) */ + sk_sp data; + int sign = 1; // +1 signals standard encoder if (fProcs.fImageProc) { - SkDynamicMemoryWStream stream; - if (fProcs.fImageProc(const_cast(image), &stream, fProcs.fImageCtx)) { - write_data(stream.detachAsData(), -1); // -1 signals custom encoder - return; - } + data = fProcs.fImageProc(const_cast(image), fProcs.fImageCtx); + sign = -1; // +1 signals custom encoder } - write_data(image->encodeToData(), 1); // +1 signals standard encoder + // We check data, since a custom proc can return nullptr, in which case we behave as if + // there was no custom proc. + if (!data) { + data = image->encodeToData(); + sign = 1; + } + write_data(std::move(data), sign); } void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) { diff --git a/tests/SerialProcsTest.cpp b/tests/SerialProcsTest.cpp index 7368a20c98..6361309b98 100644 --- a/tests/SerialProcsTest.cpp +++ b/tests/SerialProcsTest.cpp @@ -31,31 +31,21 @@ DEF_TEST(serial_procs_image, reporter) { const char magic_str[] = "magic signature"; const SkSerialImageProc sprocs[] = { - [](SkImage* img, SkWStream* stream, void* ctx) { - return false; - }, - [](SkImage* img, SkWStream* stream, void* ctx) { - auto d = img->encodeToData(); - stream->write(d->data(), d->size()); - return true; - }, - [](SkImage* img, SkWStream* stream, void* ctx) { - State* state = (State*)ctx; - stream->write(state->fStr, strlen(state->fStr)); - return true; - }, + [](SkImage* img, void* ctx) -> sk_sp { return nullptr; }, + [](SkImage* img, void* ctx) { return img->encodeToData(); }, + [](SkImage* img, void* ctx) { return SkData::MakeWithCString(((State*)ctx)->fStr); }, }; const SkDeserialImageProc dprocs[] = { [](const void* data, size_t length, void*) -> sk_sp { SK_ABORT("should not get called"); return nullptr; }, - [](const void* data, size_t length, void*) -> sk_sp { + [](const void* data, size_t length, void*) { return SkImage::MakeFromEncoded(SkData::MakeWithCopy(data, length)); }, [](const void* data, size_t length, void* ctx) -> sk_sp { State* state = (State*)ctx; - if (length != strlen(state->fStr) || memcmp(data, state->fStr, length)) { + if (length != strlen(state->fStr)+1 || memcmp(data, state->fStr, length)) { return nullptr; } return sk_ref_sp(state->fImg);