Chromium Code Reviews| Index: src/core/SkReadBuffer.cpp |
| diff --git a/src/core/SkReadBuffer.cpp b/src/core/SkReadBuffer.cpp |
| index 54f684acaa7379633f7cefb9193c1d3f010f2e38..47405e96114dda297361aa53ad7d77d842909842 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; |
| @@ -32,7 +53,8 @@ SkReadBuffer::SkReadBuffer() { |
| fFactoryArray = nullptr; |
| fFactoryCount = 0; |
| - fBitmapDecoder = nullptr; |
| +// fBitmapDecoder = nullptr; |
| + fImageDeserializer = nullptr; |
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
| fDecodedBitmapIndex = -1; |
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
| @@ -49,7 +71,8 @@ SkReadBuffer::SkReadBuffer(const void* data, size_t size) { |
| fFactoryArray = nullptr; |
| fFactoryCount = 0; |
| - fBitmapDecoder = nullptr; |
| +// fBitmapDecoder = nullptr; |
| + fImageDeserializer = nullptr; |
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
| fDecodedBitmapIndex = -1; |
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
| @@ -68,7 +91,8 @@ SkReadBuffer::SkReadBuffer(SkStream* stream) { |
| fFactoryArray = nullptr; |
| fFactoryCount = 0; |
| - fBitmapDecoder = nullptr; |
| +// fBitmapDecoder = nullptr; |
| + fImageDeserializer = nullptr; |
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
| fDecodedBitmapIndex = -1; |
| #endif // DEBUG_NON_DETERMINISTIC_ASSERT |
| @@ -179,7 +203,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,6 +227,8 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) { |
| const void* data = this->skip(length); |
| const int32_t xOffset = this->readInt(); |
| const int32_t yOffset = this->readInt(); |
| + SkIRect subset = SkIRect::MakeXYWH(xOffset, yOffset, width, height); |
| +#if 0 |
| if (fBitmapDecoder != nullptr && fBitmapDecoder(data, length, bitmap)) { |
| if (bitmap->width() == width && bitmap->height() == height) { |
| #ifdef DEBUG_NON_DETERMINISTIC_ASSERT |
| @@ -230,12 +256,20 @@ bool SkReadBuffer::readBitmap(SkBitmap* bitmap) { |
| //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; |
| } |
| } |
| +#else |
| + if (fImageDeserializer) { |
|
mtklein
2016/08/10 21:48:31
Might be nice to default this to a singleton defau
reed1
2016/08/10 23:43:19
Agreed. I had meant to mark that as a TODO. WIll i
|
| + sk_sp<SkImage> image = |
| + fImageDeserializer->deserialize(SkData::MakeWithCopy(data, length), &subset); |
| + if (image) { |
| + return image; |
| + } |
| + } |
| +#endif |
| // 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 +277,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 +298,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 +325,14 @@ 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; |
| + if (fImageDeserializer) { |
| + image = fImageDeserializer->deserialize(std::move(encoded), &subset); |
| + } else { |
| + image = SkImage::MakeFromEncoded(std::move(encoded), &subset); |
| + } |
| + return image ? image : MakeEmptyImage(width, height); |
| } |
| SkTypeface* SkReadBuffer::readTypeface() { |