aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkReadBuffer.cpp
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-12-05 15:11:24 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-12-05 20:33:18 +0000
commit60691a5127852631b03250f15fa6cda9a504befc (patch)
tree3ee27fd4857e58c890c5f0a2292749885b2a14de /src/core/SkReadBuffer.cpp
parentc8037dc5edda42cacd839df4e1c7d8cfd0953309 (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.cpp58
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);
}