diff options
author | Mike Reed <reed@google.com> | 2017-12-05 15:11:24 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-12-05 20:33:18 +0000 |
commit | 60691a5127852631b03250f15fa6cda9a504befc (patch) | |
tree | 3ee27fd4857e58c890c5f0a2292749885b2a14de /src/core/SkReadBuffer.cpp | |
parent | c8037dc5edda42cacd839df4e1c7d8cfd0953309 (diff) |
add serial procs to pictures
Bug: skia:7380
Change-Id: Ic1b7e437316c7913711cf5cb119e3fe904cd2c05
Reviewed-on: https://skia-review.googlesource.com/76980
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/core/SkReadBuffer.cpp')
-rw-r--r-- | src/core/SkReadBuffer.cpp | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp index 628e3af062..b1d7808dcb 100644 --- a/src/core/SkReadBuffer.cpp +++ b/src/core/SkReadBuffer.cpp @@ -44,9 +44,6 @@ static uint32_t default_flags() { return flags; } -// This has an empty constructor and destructor, and is thread-safe, so we can use a singleton. -static SkImageDeserializer gDefaultImageDeserializer; - SkReadBuffer::SkReadBuffer() { fFlags = default_flags(); fVersion = 0; @@ -57,7 +54,6 @@ SkReadBuffer::SkReadBuffer() { fFactoryArray = nullptr; fFactoryCount = 0; - fImageDeserializer = &gDefaultImageDeserializer; #ifdef DEBUG_NON_DETERMINISTIC_ASSERT fDecodedBitmapIndex = -1; #endif // DEBUG_NON_DETERMINISTIC_ASSERT @@ -74,7 +70,6 @@ SkReadBuffer::SkReadBuffer(const void* data, size_t size) { fFactoryArray = nullptr; fFactoryCount = 0; - fImageDeserializer = &gDefaultImageDeserializer; #ifdef DEBUG_NON_DETERMINISTIC_ASSERT fDecodedBitmapIndex = -1; #endif // DEBUG_NON_DETERMINISTIC_ASSERT @@ -93,7 +88,6 @@ SkReadBuffer::SkReadBuffer(SkStream* stream) { fFactoryArray = nullptr; fFactoryCount = 0; - fImageDeserializer = &gDefaultImageDeserializer; #ifdef DEBUG_NON_DETERMINISTIC_ASSERT fDecodedBitmapIndex = -1; #endif // DEBUG_NON_DETERMINISTIC_ASSERT @@ -103,8 +97,8 @@ SkReadBuffer::~SkReadBuffer() { sk_free(fMemoryPtr); } -void SkReadBuffer::setImageDeserializer(SkImageDeserializer* deserializer) { - fImageDeserializer = deserializer ? deserializer : &gDefaultImageDeserializer; +void SkReadBuffer::setDeserialProcs(const SkDeserialProcs& procs) { + fProcs = procs; } bool SkReadBuffer::readBool() { @@ -131,6 +125,14 @@ int32_t SkReadBuffer::read32() { return fReader.readInt(); } +bool SkReadBuffer::readPad32(void* buffer, size_t bytes) { + if (!fReader.isAvailable(bytes)) { + return false; + } + fReader.read(buffer, bytes); + return true; +} + uint8_t SkReadBuffer::peekByte() { SkASSERT(fReader.available() > 0); return *((uint8_t*) fReader.peek()); @@ -235,10 +237,16 @@ sk_sp<SkImage> SkReadBuffer::readImage() { return nullptr; } - uint32_t encoded_size = this->getArrayCount(); + /* + * What follows is a 32bit encoded size. + * 0 : failure, nothing else to do + * <0 : negative (int32_t) of a custom encoded blob using SerialProcs + * >0 : standard encoded blob size (use MakeFromEncoded) + */ + + int32_t encoded_size = this->read32(); if (encoded_size == 0) { // The image could not be encoded at serialization time - return an empty placeholder. - (void)this->readUInt(); // Swallow that encoded_size == 0 sentinel. return MakeEmptyImage(width, height); } if (encoded_size == 1) { @@ -247,19 +255,33 @@ sk_sp<SkImage> SkReadBuffer::readImage() { return nullptr; } - // The SkImage encoded itself. - sk_sp<SkData> encoded(this->readByteArrayAsData()); - - int originX = this->read32(); - int originY = this->read32(); + size_t size = SkAbs32(encoded_size); + sk_sp<SkData> data = SkData::MakeUninitialized(size); + if (!this->readPad32(data->writable_data(), size)) { + this->validate(false); + return nullptr; + } + int32_t originX = this->read32(); + int32_t originY = this->read32(); if (originX < 0 || originY < 0) { this->validate(false); return nullptr; } - const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); - - sk_sp<SkImage> image = fImageDeserializer->makeFromData(encoded.get(), &subset); + sk_sp<SkImage> image; + if (encoded_size < 0) { // custom encoded, need serial proc + if (fProcs.fImageProc) { + image = fProcs.fImageProc(data->data(), data->size(), fProcs.fImageCtx); + } else { + // Nothing to do (no client proc), but since we've already "read" the custom data, + // wee just leave image as nullptr. + } + } else { + SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height); + image = SkImage::MakeFromEncoded(std::move(data), &subset); + } + // Question: are we correct to return an "empty" image instead of nullptr, if the decoder + // failed for some reason? return image ? image : MakeEmptyImage(width, height); } |