| Index: src/core/SkReadBuffer.cpp
|
| diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp
|
| index 54f684acaa7379633f7cefb9193c1d3f010f2e38..5356d4a6b1f47ab27db1ba9d7eb9743403e77da4 100644
|
| --- a/src/core/SkReadBuffer.cpp
|
| +++ b/src/core/SkReadBuffer.cpp
|
| @@ -8,11 +8,32 @@
|
| #include "SkBitmap.h"
|
| #include "SkErrorInternals.h"
|
| #include "SkImage.h"
|
| +#include "SkImageDeserializer.h"
|
| #include "SkImageGenerator.h"
|
| #include "SkReadBuffer.h"
|
| #include "SkStream.h"
|
| #include "SkTypeface.h"
|
|
|
| +namespace {
|
| +
|
| + // This generator intentionally should always fail on all attempts to get its pixels,
|
| + // simulating a bad or empty codec stream.
|
| + class EmptyImageGenerator final : public SkImageGenerator {
|
| + public:
|
| + EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
|
| +
|
| + private:
|
| + typedef SkImageGenerator INHERITED;
|
| + };
|
| +
|
| + static sk_sp<SkImage> MakeEmptyImage(int width, int height) {
|
| + return SkImage::MakeFromGenerator(
|
| + new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height)));
|
| + }
|
| +
|
| +} // anonymous namespace
|
| +
|
| +
|
| static uint32_t default_flags() {
|
| uint32_t flags = 0;
|
| flags |= SkReadBuffer::kScalarIsFloat_Flag;
|
| @@ -22,6 +43,9 @@ 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;
|
| @@ -32,7 +56,7 @@ SkReadBuffer::SkReadBuffer() {
|
|
|
| fFactoryArray = nullptr;
|
| fFactoryCount = 0;
|
| - fBitmapDecoder = nullptr;
|
| + fImageDeserializer = &gDefaultImageDeserializer;
|
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
|
| fDecodedBitmapIndex = -1;
|
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT
|
| @@ -49,7 +73,7 @@ SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
|
|
|
| fFactoryArray = nullptr;
|
| fFactoryCount = 0;
|
| - fBitmapDecoder = nullptr;
|
| + fImageDeserializer = &gDefaultImageDeserializer;
|
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
|
| fDecodedBitmapIndex = -1;
|
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT
|
| @@ -68,7 +92,7 @@ SkReadBuffer::SkReadBuffer(SkStream* stream) {
|
|
|
| fFactoryArray = nullptr;
|
| fFactoryCount = 0;
|
| - fBitmapDecoder = nullptr;
|
| + fImageDeserializer = &gDefaultImageDeserializer;
|
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT
|
| fDecodedBitmapIndex = -1;
|
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT
|
| @@ -78,6 +102,10 @@ SkReadBuffer::~SkReadBuffer() {
|
| sk_free(fMemoryPtr);
|
| }
|
|
|
| +void SkReadBuffer::setImageDeserializer(SkImageDeserializer* deserializer) {
|
| + fImageDeserializer = deserializer ? deserializer : &gDefaultImageDeserializer;
|
| +}
|
| +
|
| bool SkReadBuffer::readBool() {
|
| return fReader.readBool();
|
| }
|
| @@ -179,7 +207,7 @@ uint32_t SkReadBuffer::getArrayCount() {
|
| return *(uint32_t*)fReader.peek();
|
| }
|
|
|
| -bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
|
| +sk_sp<SkImage> SkReadBuffer::readBitmapAsImage() {
|
| const int width = this->readInt();
|
| const int height = this->readInt();
|
|
|
| @@ -203,39 +231,12 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
|
| const void* data = this->skip(length);
|
| const int32_t xOffset = this->readInt();
|
| const int32_t yOffset = this->readInt();
|
| - if (fBitmapDecoder != nullptr && fBitmapDecoder(data, length, bitmap)) {
|
| - if (bitmap->width() == width && bitmap->height() == height) {
|
| -#ifdef DEBUG_NON_DETERMINISTIC_ASSERT
|
| - if (0 != xOffset || 0 != yOffset) {
|
| - SkDebugf("SkReadBuffer::readBitmap: heights match,"
|
| - " but offset is not zero. \nInfo about the bitmap:"
|
| - "\n\tIndex: %d\n\tDimensions: [%d %d]\n\tEncoded"
|
| - " data size: %d\n\tOffset: (%d, %d)\n",
|
| - fDecodedBitmapIndex, width, height, length, xOffset,
|
| - yOffset);
|
| - }
|
| -#endif // DEBUG_NON_DETERMINISTIC_ASSERT
|
| - // If the width and height match, there should be no offset.
|
| - SkASSERT(0 == xOffset && 0 == yOffset);
|
| - return true;
|
| - }
|
| -
|
| - // This case can only be reached if extractSubset was called, so
|
| - // the recorded width and height must be smaller than or equal to
|
| - // the encoded width and height.
|
| - // FIXME (scroggo): This assert assumes that our decoder and the
|
| - // sources encoder agree on the width and height which may not
|
| - // always be the case. Removing until it can be investigated
|
| - // further.
|
| - //SkASSERT(width <= bitmap->width() && height <= bitmap->height());
|
| -
|
| - SkBitmap subsetBm;
|
| - SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
|
| - if (bitmap->extractSubset(&subsetBm, subset)) {
|
| - bitmap->swap(subsetBm);
|
| - return true;
|
| - }
|
| + SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height);
|
| + sk_sp<SkImage> image = fImageDeserializer->makeFromMemory(data, length, &subset);
|
| + if (image) {
|
| + return image;
|
| }
|
| +
|
| // This bitmap was encoded when written, but we are unable to decode, possibly due to
|
| // not having a decoder.
|
| SkErrorInternals::SetError(kParseError_SkError,
|
| @@ -243,32 +244,20 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
|
| // Even though we weren't able to decode the pixels, the readbuffer should still be
|
| // intact, so we return true with an empty bitmap, so we don't force an abort of the
|
| // larger deserialize.
|
| - bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
|
| - return true;
|
| - } else if (SkBitmap::ReadRawPixels(this, bitmap)) {
|
| - return true;
|
| + return MakeEmptyImage(width, height);
|
| + } else {
|
| + SkBitmap bitmap;
|
| + if (SkBitmap::ReadRawPixels(this, &bitmap)) {
|
| + bitmap.setImmutable();
|
| + return SkImage::MakeFromBitmap(bitmap);
|
| + }
|
| }
|
| }
|
| // Could not read the SkBitmap. Use a placeholder bitmap.
|
| - bitmap->setInfo(SkImageInfo::MakeUnknown(width, height));
|
| - return false;
|
| + return nullptr;
|
| }
|
|
|
| -namespace {
|
| -
|
| -// This generator intentionally should always fail on all attempts to get its pixels,
|
| -// simulating a bad or empty codec stream.
|
| -class EmptyImageGenerator final : public SkImageGenerator {
|
| -public:
|
| - EmptyImageGenerator(const SkImageInfo& info) : INHERITED(info) { }
|
| -
|
| -private:
|
| - typedef SkImageGenerator INHERITED;
|
| -};
|
| -
|
| -} // anonymous namespace
|
| -
|
| -SkImage* SkReadBuffer::readImage() {
|
| +sk_sp<SkImage> SkReadBuffer::readImage() {
|
| int width = this->read32();
|
| int height = this->read32();
|
| if (width <= 0 || height <= 0) { // SkImage never has a zero dimension
|
| @@ -276,25 +265,20 @@ SkImage* SkReadBuffer::readImage() {
|
| return nullptr;
|
| }
|
|
|
| - auto placeholder = [=] {
|
| - return SkImage::MakeFromGenerator(
|
| - new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))).release();
|
| - };
|
| -
|
| uint32_t encoded_size = this->getArrayCount();
|
| 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 placeholder();
|
| + return MakeEmptyImage(width, height);
|
| }
|
| if (encoded_size == 1) {
|
| // We had to encode the image as raw pixels via SkBitmap.
|
| (void)this->readUInt(); // Swallow that encoded_size == 1 sentinel.
|
| SkBitmap bm;
|
| if (SkBitmap::ReadRawPixels(this, &bm)) {
|
| - return SkImage::MakeFromBitmap(bm).release();
|
| + return SkImage::MakeFromBitmap(bm);
|
| }
|
| - return placeholder();
|
| + return MakeEmptyImage(width, height);
|
| }
|
|
|
| // The SkImage encoded itself.
|
| @@ -308,13 +292,9 @@ SkImage* SkReadBuffer::readImage() {
|
| }
|
|
|
| const SkIRect subset = SkIRect::MakeXYWH(originX, originY, width, height);
|
| - SkImage* image = SkImage::MakeFromEncoded(std::move(encoded), &subset).release();
|
| - if (image) {
|
| - return image;
|
| - }
|
|
|
| - return SkImage::MakeFromGenerator(
|
| - new EmptyImageGenerator(SkImageInfo::MakeN32Premul(width, height))).release();
|
| + sk_sp<SkImage> image = fImageDeserializer->makeFromData(encoded.get(), &subset);
|
| + return image ? image : MakeEmptyImage(width, height);
|
| }
|
|
|
| SkTypeface* SkReadBuffer::readTypeface() {
|
|
|