aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
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
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')
-rw-r--r--src/core/SkPicture.cpp99
-rw-r--r--src/core/SkPictureCommon.h4
-rw-r--r--src/core/SkPictureData.cpp23
-rw-r--r--src/core/SkPictureData.h10
-rw-r--r--src/core/SkReadBuffer.cpp58
-rw-r--r--src/core/SkReadBuffer.h17
-rw-r--r--src/core/SkWriteBuffer.cpp43
-rw-r--r--src/pipe/SkPipeCanvas.cpp1
8 files changed, 189 insertions, 66 deletions
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 972b81f997..e87439aad9 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -9,10 +9,12 @@
#include "SkImageDeserializer.h"
#include "SkImageGenerator.h"
#include "SkPicture.h"
+#include "SkPictureCommon.h"
#include "SkPictureData.h"
#include "SkPicturePlayback.h"
#include "SkPictureRecord.h"
#include "SkPictureRecorder.h"
+#include "SkSerialProcs.h"
#if defined(SK_DISALLOW_CROSSPROCESS_PICTUREIMAGEFILTERS) || \
defined(SK_ENABLE_PICTURE_IO_SECURITY_PRECAUTIONS)
@@ -129,7 +131,10 @@ sk_sp<SkPicture> SkPicture::Forwardport(const SkPictInfo& info,
}
sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, SkImageDeserializer* factory) {
- return MakeFromStream(stream, factory, nullptr);
+ SkDeserialProcs procs;
+ procs.fImageProc = ImageDeserializer_SkDeserialImageProc;
+ procs.fImageCtx = factory;
+ return MakeFromStream(stream, procs, nullptr);
}
sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream) {
@@ -140,7 +145,7 @@ sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream) {
sk_sp<SkPicture> SkPicture::MakeFromData(const void* data, size_t size,
SkImageDeserializer* factory) {
SkMemoryStream stream(data, size);
- return MakeFromStream(&stream, factory, nullptr);
+ return MakeFromStream(&stream, factory);
}
sk_sp<SkPicture> SkPicture::MakeFromData(const SkData* data, SkImageDeserializer* factory) {
@@ -148,17 +153,33 @@ sk_sp<SkPicture> SkPicture::MakeFromData(const SkData* data, SkImageDeserializer
return nullptr;
}
SkMemoryStream stream(data->data(), data->size());
- return MakeFromStream(&stream, factory, nullptr);
+ return MakeFromStream(&stream, factory);
}
-sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, SkImageDeserializer* factory,
+sk_sp<SkPicture> SkPicture::MakeFromData(const SkData* data, const SkDeserialProcs& procs) {
+ if (!data) {
+ return nullptr;
+ }
+ SkMemoryStream stream(data->data(), data->size());
+ return MakeFromStream(&stream, procs, nullptr);
+}
+
+sk_sp<SkPicture> SkPicture::MakeFromData(sk_sp<SkData> data, const SkDeserialProcs& procs) {
+ return MakeFromData(data.get(), procs);
+}
+
+sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, const SkDeserialProcs& procs) {
+ return MakeFromStream(stream, procs, nullptr);
+}
+
+sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, const SkDeserialProcs& procs,
SkTypefacePlayback* typefaces) {
SkPictInfo info;
if (!InternalOnly_StreamIsSKP(stream, &info) || !stream->readBool()) {
return nullptr;
}
std::unique_ptr<SkPictureData> data(
- SkPictureData::CreateFromStream(stream, info, factory, typefaces));
+ SkPictureData::CreateFromStream(stream, info, procs, typefaces));
return Forwardport(info, data.get(), nullptr);
}
@@ -181,17 +202,27 @@ SkPictureData* SkPicture::backport() const {
}
void SkPicture::serialize(SkWStream* stream, SkPixelSerializer* pixelSerializer) const {
- this->serialize(stream, pixelSerializer, nullptr);
+ SkSerialProcs procs;
+ if (pixelSerializer) {
+ procs.fImageProc = PixelSerializer_SkSerialImageProc;
+ procs.fImageCtx = pixelSerializer;
+ }
+ this->serialize(stream, procs, nullptr);
}
sk_sp<SkData> SkPicture::serialize(SkPixelSerializer* pixelSerializer) const {
SkDynamicMemoryWStream stream;
- this->serialize(&stream, pixelSerializer, nullptr);
+ this->serialize(&stream, pixelSerializer);
return stream.detachAsData();
}
-void SkPicture::serialize(SkWStream* stream,
- SkPixelSerializer* pixelSerializer,
+sk_sp<SkData> SkPicture::serialize(const SkSerialProcs& procs) const {
+ SkDynamicMemoryWStream stream;
+ this->serialize(&stream, procs, nullptr);
+ return stream.detachAsData();
+}
+
+void SkPicture::serialize(SkWStream* stream, const SkSerialProcs& procs,
SkRefCntSet* typefaceSet) const {
SkPictInfo info = this->createHeader();
std::unique_ptr<SkPictureData> data(this->backport());
@@ -199,7 +230,7 @@ void SkPicture::serialize(SkWStream* stream,
stream->write(&info, sizeof(info));
if (data) {
stream->writeBool(true);
- data->serialize(stream, pixelSerializer, typefaceSet);
+ data->serialize(stream, procs, typefaceSet);
} else {
stream->writeBool(false);
}
@@ -239,3 +270,51 @@ void SkPicture::SetPictureIOSecurityPrecautionsEnabled_Dangerous(bool set) {
bool SkPicture::PictureIOSecurityPrecautionsEnabled() {
return g_AllPictureIOSecurityPrecautionsEnabled;
}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool PixelSerializer_SkSerialImageProc(SkImage* img, SkWStream* stream, void* ctx) {
+ SkASSERT(ctx);
+ sk_sp<SkData> enc = img->encodeToData(static_cast<SkPixelSerializer*>(ctx));
+ if (enc) {
+ stream->write(enc->data(), enc->size());
+ return true;
+ }
+ return false;
+}
+
+sk_sp<SkImage> ImageDeserializer_SkDeserialImageProc(const void* data, size_t length, void* ctx) {
+ SkASSERT(ctx);
+ SkImageDeserializer* imd = static_cast<SkImageDeserializer*>(ctx);
+ const SkIRect* subset = nullptr;
+ return imd->makeFromMemory(data, length, subset);
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifdef SK_SUPPORT_LEGACY_SERIAL_BUFFER_OBJECTS
+#include "SkReadBuffer.h"
+#include "SkWriteBuffer.h"
+
+void SkBinaryWriteBuffer::setPixelSerializer(sk_sp<SkPixelSerializer> ps) {
+ fPS = ps;
+ if (ps) {
+ fProcs.fImageProc = PixelSerializer_SkSerialImageProc;
+ fProcs.fImageCtx = ps.get();
+ } else {
+ fProcs.fImageProc = nullptr;
+ fProcs.fImageCtx = nullptr;
+ }
+}
+
+void SkReadBuffer::setImageDeserializer(SkImageDeserializer* factory) {
+ if (factory) {
+ fProcs.fImageProc = ImageDeserializer_SkDeserialImageProc;
+ fProcs.fImageCtx = factory;
+ } else {
+ fProcs.fImageProc = nullptr;
+ fProcs.fImageCtx = nullptr;
+ }
+}
+#endif
+
diff --git a/src/core/SkPictureCommon.h b/src/core/SkPictureCommon.h
index 43805fd49f..74d693f56b 100644
--- a/src/core/SkPictureCommon.h
+++ b/src/core/SkPictureCommon.h
@@ -141,4 +141,8 @@ struct SkPathCounter {
int fNumSlowPathsAndDashEffects;
};
+
+bool PixelSerializer_SkSerialImageProc(SkImage*, SkWStream*, void* sk_pixelserializer);
+sk_sp<SkImage> ImageDeserializer_SkDeserialImageProc(const void*, size_t, void* imagedeserializer);
+
#endif // SkPictureCommon_DEFINED
diff --git a/src/core/SkPictureData.cpp b/src/core/SkPictureData.cpp
index a5a644fe69..24e161f191 100644
--- a/src/core/SkPictureData.cpp
+++ b/src/core/SkPictureData.cpp
@@ -278,8 +278,7 @@ void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
}
}
-void SkPictureData::serialize(SkWStream* stream,
- SkPixelSerializer* pixelSerializer,
+void SkPictureData::serialize(SkWStream* stream, const SkSerialProcs& procs,
SkRefCntSet* topLevelTypeFaceSet) const {
// This can happen at pretty much any time, so might as well do it first.
write_tag_size(stream, SK_PICT_READER_TAG, fOpData->size());
@@ -294,7 +293,7 @@ void SkPictureData::serialize(SkWStream* stream,
SkFactorySet factSet; // buffer refs factSet, so factSet must come first.
SkBinaryWriteBuffer buffer(SkBinaryWriteBuffer::kCrossProcess_Flag);
buffer.setFactoryRecorder(&factSet);
- buffer.setPixelSerializer(sk_ref_sp(pixelSerializer));
+ buffer.setSerialProcs(procs);
buffer.setTypefaceRecorder(typefaceSet);
this->flattenToBuffer(buffer);
@@ -307,7 +306,7 @@ void SkPictureData::serialize(SkWStream* stream,
size_t bytesWritten() const override { return fBytesWritten; }
} devnull;
for (int i = 0; i < fPictureCount; i++) {
- fPictureRefs[i]->serialize(&devnull, pixelSerializer, typefaceSet);
+ fPictureRefs[i]->serialize(&devnull, procs, typefaceSet);
}
// We need to write factories before we write the buffer.
@@ -325,7 +324,7 @@ void SkPictureData::serialize(SkWStream* stream,
if (fPictureCount > 0) {
write_tag_size(stream, SK_PICT_PICTURE_TAG, fPictureCount);
for (int i = 0; i < fPictureCount; i++) {
- fPictureRefs[i]->serialize(stream, pixelSerializer, typefaceSet);
+ fPictureRefs[i]->serialize(stream, procs, typefaceSet);
}
}
@@ -383,7 +382,7 @@ static uint32_t pictInfoFlagsToReadBufferFlags(uint32_t pictInfoFlags) {
bool SkPictureData::parseStreamTag(SkStream* stream,
uint32_t tag,
uint32_t size,
- SkImageDeserializer* factory,
+ const SkDeserialProcs& procs,
SkTypefacePlayback* topLevelTFPlayback) {
/*
* By the time we encounter BUFFER_SIZE_TAG, we need to have already seen
@@ -436,7 +435,7 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
fPictureCount = 0;
fPictureRefs = new const SkPicture* [size];
for (uint32_t i = 0; i < size; i++) {
- fPictureRefs[i] = SkPicture::MakeFromStream(stream, factory, topLevelTFPlayback).release();
+ fPictureRefs[i] = SkPicture::MakeFromStream(stream, procs, topLevelTFPlayback).release();
if (!fPictureRefs[i]) {
return false;
}
@@ -458,7 +457,7 @@ bool SkPictureData::parseStreamTag(SkStream* stream,
return false;
}
fFactoryPlayback->setupBuffer(buffer);
- buffer.setImageDeserializer(factory);
+ buffer.setDeserialProcs(procs);
if (fTFPlayback.count() > 0) {
// .skp files <= v43 have typefaces serialized with each sub picture.
@@ -602,14 +601,14 @@ bool SkPictureData::parseBufferTag(SkReadBuffer& buffer, uint32_t tag, uint32_t
SkPictureData* SkPictureData::CreateFromStream(SkStream* stream,
const SkPictInfo& info,
- SkImageDeserializer* factory,
+ const SkDeserialProcs& procs,
SkTypefacePlayback* topLevelTFPlayback) {
std::unique_ptr<SkPictureData> data(new SkPictureData(info));
if (!topLevelTFPlayback) {
topLevelTFPlayback = &data->fTFPlayback;
}
- if (!data->parseStream(stream, factory, topLevelTFPlayback)) {
+ if (!data->parseStream(stream, procs, topLevelTFPlayback)) {
return nullptr;
}
return data.release();
@@ -627,7 +626,7 @@ SkPictureData* SkPictureData::CreateFromBuffer(SkReadBuffer& buffer,
}
bool SkPictureData::parseStream(SkStream* stream,
- SkImageDeserializer* factory,
+ const SkDeserialProcs& procs,
SkTypefacePlayback* topLevelTFPlayback) {
for (;;) {
uint32_t tag = stream->readU32();
@@ -636,7 +635,7 @@ bool SkPictureData::parseStream(SkStream* stream,
}
uint32_t size = stream->readU32();
- if (!this->parseStreamTag(stream, tag, size, factory, topLevelTFPlayback)) {
+ if (!this->parseStreamTag(stream, tag, size, procs, topLevelTFPlayback)) {
return false; // we're invalid
}
}
diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h
index b95f428807..551af70312 100644
--- a/src/core/SkPictureData.h
+++ b/src/core/SkPictureData.h
@@ -16,8 +16,8 @@
class SkData;
class SkPictureRecord;
-class SkPixelSerializer;
class SkReader32;
+struct SkSerialProcs;
class SkStream;
class SkWStream;
class SkBBoxHierarchy;
@@ -79,13 +79,13 @@ public:
// Does not affect ownership of SkStream.
static SkPictureData* CreateFromStream(SkStream*,
const SkPictInfo&,
- SkImageDeserializer*,
+ const SkDeserialProcs&,
SkTypefacePlayback*);
static SkPictureData* CreateFromBuffer(SkReadBuffer&, const SkPictInfo&);
virtual ~SkPictureData();
- void serialize(SkWStream*, SkPixelSerializer*, SkRefCntSet*) const;
+ void serialize(SkWStream*, const SkSerialProcs&, SkRefCntSet*) const;
void flatten(SkWriteBuffer&) const;
bool containsBitmaps() const;
@@ -100,7 +100,7 @@ protected:
explicit SkPictureData(const SkPictInfo& info);
// Does not affect ownership of SkStream.
- bool parseStream(SkStream*, SkImageDeserializer*, SkTypefacePlayback*);
+ bool parseStream(SkStream*, const SkDeserialProcs&, SkTypefacePlayback*);
bool parseBuffer(SkReadBuffer& buffer);
public:
@@ -172,7 +172,7 @@ private:
// these help us with reading/writing
// Does not affect ownership of SkStream.
bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size,
- SkImageDeserializer*, SkTypefacePlayback*);
+ const SkDeserialProcs&, SkTypefacePlayback*);
bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
void flattenToBuffer(SkWriteBuffer&) const;
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);
}
diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h
index b7c54c4c72..ae3fde6818 100644
--- a/src/core/SkReadBuffer.h
+++ b/src/core/SkReadBuffer.h
@@ -10,6 +10,7 @@
#include "SkColorFilter.h"
#include "SkData.h"
+#include "SkSerialProcs.h"
#include "SkDrawLooper.h"
#include "SkImageFilter.h"
#include "SkMaskFilter.h"
@@ -24,7 +25,6 @@
#include "SkTHash.h"
#include "SkWriteBuffer.h"
-class SkBitmap;
class SkImage;
class SkInflator;
@@ -157,6 +157,9 @@ public:
sk_sp<SkRasterizer> readRasterizer() { return this->readFlattenable<SkRasterizer>(); }
sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }
+ // Reads SkAlign4(bytes), but will only copy bytes into the buffer.
+ virtual bool readPad32(void* buffer, size_t bytes);
+
// binary data and arrays
virtual bool readByteArray(void* value, size_t size);
virtual bool readColorArray(SkColor* colors, size_t size);
@@ -178,6 +181,9 @@ public:
// helpers to get info about arrays and binary data
virtual uint32_t getArrayCount();
+ // If there is a real error (e.g. data is corrupted) this returns null. If the image cannot
+ // be created (e.g. it was not originally encoded) then this returns an image that doesn't
+ // draw.
sk_sp<SkImage> readImage();
virtual sk_sp<SkTypeface> readTypeface();
@@ -209,9 +215,11 @@ public:
fCustomFactory.set(name, factory);
}
- // If nullptr is passed, then the default deserializer will be used
- // which calls SkImage::MakeFromEncoded()
+ void setDeserialProcs(const SkDeserialProcs& procs);
+
+#ifdef SK_SUPPORT_LEGACY_SERIAL_BUFFER_OBJECTS
void setImageDeserializer(SkImageDeserializer* factory);
+#endif
// Default impelementations don't check anything.
virtual bool validate(bool isValid) { return isValid; }
@@ -274,8 +282,7 @@ private:
// Only used if we do not have an fFactoryArray.
SkTHashMap<SkString, SkFlattenable::Factory> fCustomFactory;
- // We do not own this ptr, we just use it (guaranteed to never be null)
- SkImageDeserializer* fImageDeserializer;
+ SkDeserialProcs fProcs;
#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
// Debugging counter to keep track of how many bitmaps we
diff --git a/src/core/SkWriteBuffer.cpp b/src/core/SkWriteBuffer.cpp
index e6620f9e83..49cccd6783 100644
--- a/src/core/SkWriteBuffer.cpp
+++ b/src/core/SkWriteBuffer.cpp
@@ -130,13 +130,6 @@ bool SkBinaryWriteBuffer::writeToStream(SkWStream* stream) {
return fWriter.writeToStream(stream);
}
-static void write_encoded_bitmap(SkBinaryWriteBuffer* buffer, SkData* data,
- const SkIPoint& origin) {
- buffer->writeDataAsByteArray(data);
- buffer->write32(origin.fX);
- buffer->write32(origin.fY);
-}
-
void SkBinaryWriteBuffer::writeImage(const SkImage* image) {
if (fDeduper) {
this->write32(fDeduper->findOrDefineImage(const_cast<SkImage*>(image)));
@@ -146,12 +139,34 @@ void SkBinaryWriteBuffer::writeImage(const SkImage* image) {
this->writeInt(image->width());
this->writeInt(image->height());
- sk_sp<SkData> encoded = image->encodeToData(this->getPixelSerializer());
- if (encoded && encoded->size() > 0) {
- write_encoded_bitmap(this, encoded.get(), SkIPoint::Make(0, 0));
- return;
+ auto write_data = [this](sk_sp<SkData> 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;
+ }
+ }
+ this->write32(0); // no data or size too big
+ };
+
+ /*
+ * 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)
+ */
+ if (fProcs.fImageProc) {
+ SkDynamicMemoryWStream stream;
+ if (fProcs.fImageProc(const_cast<SkImage*>(image), &stream, fProcs.fImageCtx)) {
+ write_data(stream.detachAsData(), -1); // -1 signals custom encoder
+ return;
+ }
}
- this->writeUInt(0); // signal no pixels (in place of the size of the encoded data)
+ write_data(image->encodeToData(), 1); // +1 signals standard encoder
}
void SkBinaryWriteBuffer::writeTypeface(SkTypeface* obj) {
@@ -181,10 +196,6 @@ SkRefCntSet* SkBinaryWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
return rec;
}
-void SkBinaryWriteBuffer::setPixelSerializer(sk_sp<SkPixelSerializer> serializer) {
- fPixelSerializer = std::move(serializer);
-}
-
void SkBinaryWriteBuffer::writeFlattenable(const SkFlattenable* flattenable) {
if (nullptr == flattenable) {
this->write32(0);
diff --git a/src/pipe/SkPipeCanvas.cpp b/src/pipe/SkPipeCanvas.cpp
index 226a95725c..b9fcd2d4b5 100644
--- a/src/pipe/SkPipeCanvas.cpp
+++ b/src/pipe/SkPipeCanvas.cpp
@@ -13,6 +13,7 @@
#include "SkPathEffect.h"
#include "SkPipeCanvas.h"
#include "SkPipeFormat.h"
+#include "SkPixelSerializer.h"
#include "SkRSXform.h"
#include "SkRasterizer.h"
#include "SkShader.h"