From 0cb7df97185d5fc8780e225c912e2bc99a26aa8d Mon Sep 17 00:00:00 2001 From: "scroggo@google.com" Date: Tue, 30 Apr 2013 02:37:56 +0000 Subject: [PATCH] Allow supporting 1 older PICTURE_VERSION. Allows https://codereview.chromium.org/14230022/ to be submitted without breaking bench_pictures and render_pictures. After DEPS roll and SKP capture, this will be reverted. Review URL: https://codereview.chromium.org/14158015 git-svn-id: http://skia.googlecode.com/svn/trunk@8918 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkPicture.h | 2 +- src/core/SkOrderedReadBuffer.cpp | 109 ++++++++++++++++++++++++++------------- src/core/SkOrderedReadBuffer.h | 3 ++ src/core/SkPicture.cpp | 8 ++- src/core/SkPicturePlayback.cpp | 1 + 5 files changed, 85 insertions(+), 38 deletions(-) diff --git a/include/core/SkPicture.h b/include/core/SkPicture.h index b2c2b62..157c4ca 100644 --- a/include/core/SkPicture.h +++ b/include/core/SkPicture.h @@ -192,7 +192,6 @@ public: void abortPlayback(); #endif -protected: // V2 : adds SkPixelRef's generation ID. // V3 : PictInfo tag at beginning, and EOF tag at the end // V4 : move SkPictInfo to be the header @@ -206,6 +205,7 @@ protected: // V11: modify how readBitmap and writeBitmap store their info. static const uint32_t PICTURE_VERSION = 11; +protected: // fPlayback, fRecord, fWidth & fHeight are protected to allow derived classes to // install their own SkPicturePlayback-derived players,SkPictureRecord-derived // recorders and set the picture size diff --git a/src/core/SkOrderedReadBuffer.cpp b/src/core/SkOrderedReadBuffer.cpp index 85491c5..a5be45e 100644 --- a/src/core/SkOrderedReadBuffer.cpp +++ b/src/core/SkOrderedReadBuffer.cpp @@ -23,6 +23,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer() : INHERITED() { fFactoryArray = NULL; fFactoryCount = 0; fBitmapDecoder = NULL; + fPictureVersion = SkPicture::PICTURE_VERSION; } SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERITED() { @@ -37,6 +38,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer(const void* data, size_t size) : INHERI fFactoryArray = NULL; fFactoryCount = 0; fBitmapDecoder = NULL; + fPictureVersion = SkPicture::PICTURE_VERSION; } SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) { @@ -53,6 +55,7 @@ SkOrderedReadBuffer::SkOrderedReadBuffer(SkStream* stream) { fFactoryArray = NULL; fFactoryCount = 0; fBitmapDecoder = NULL; + fPictureVersion = SkPicture::PICTURE_VERSION; } SkOrderedReadBuffer::~SkOrderedReadBuffer() { @@ -168,52 +171,88 @@ uint32_t SkOrderedReadBuffer::getArrayCount() { return *(uint32_t*)fReader.peek(); } +void SkOrderedReadBuffer::setPictureVersion(uint32_t version) { + SkASSERT(version <= SkPicture::PICTURE_VERSION); + fPictureVersion = version; +} + void SkOrderedReadBuffer::readBitmap(SkBitmap* bitmap) { - const int width = this->readInt(); - const int height = this->readInt(); - // The writer stored a boolean value to determine whether an SkBitmapHeap was used during - // writing. - if (this->readBool()) { - // An SkBitmapHeap was used for writing. Read the index from the stream and find the - // corresponding SkBitmap in fBitmapStorage. - const uint32_t index = fReader.readU32(); - fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap) - if (fBitmapStorage) { - *bitmap = *fBitmapStorage->getBitmap(index); - fBitmapStorage->releaseRef(index); - return; - } else { - // The bitmap was stored in a heap, but there is no way to access it. Set an error and - // fall through to use a place holder bitmap. - SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap " - "stored the SkBitmap in an SkBitmapHeap, but " - "SkOrderedReadBuffer has no SkBitmapHeapReader to " - "retrieve the SkBitmap."); - } - } else { - // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap. + if (10 == fPictureVersion) { + // Old code to read a bitmap in PICTURE_VERSION 10 const size_t length = this->readUInt(); if (length > 0) { - // A non-zero size means the SkBitmap was encoded. + // Bitmap was encoded. const void* data = this->skip(length); + const int width = this->readInt(); + const int height = this->readInt(); if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) { SkASSERT(bitmap->width() == width && bitmap->height() == height); + } else { + // This bitmap was encoded when written, but we are unable to decode, possibly due to + // not having a decoder. Use a placeholder bitmap. + SkErrorInternals::SetError(kParseError_SkError, + "Could not decode bitmap. Resulting bitmap will be red."); + bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); + bitmap->allocPixels(); + bitmap->eraseColor(SK_ColorRED); + } + } else { + if (fBitmapStorage) { + const uint32_t index = fReader.readU32(); + fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap) + *bitmap = *fBitmapStorage->getBitmap(index); + fBitmapStorage->releaseRef(index); + } else { + bitmap->unflatten(*this); + } + } + } else { + const int width = this->readInt(); + const int height = this->readInt(); + // The writer stored a boolean value to determine whether an SkBitmapHeap was used during + // writing. + if (this->readBool()) { + // An SkBitmapHeap was used for writing. Read the index from the stream and find the + // corresponding SkBitmap in fBitmapStorage. + const uint32_t index = fReader.readU32(); + fReader.readU32(); // bitmap generation ID (see SkOrderedWriteBuffer::writeBitmap) + if (fBitmapStorage) { + *bitmap = *fBitmapStorage->getBitmap(index); + fBitmapStorage->releaseRef(index); return; + } else { + // The bitmap was stored in a heap, but there is no way to access it. Set an error and + // fall through to use a place holder bitmap. + SkErrorInternals::SetError(kParseError_SkError, "SkOrderedWriteBuffer::writeBitmap " + "stored the SkBitmap in an SkBitmapHeap, but " + "SkOrderedReadBuffer has no SkBitmapHeapReader to " + "retrieve the SkBitmap."); } - // This bitmap was encoded when written, but we are unable to decode, possibly due to - // not having a decoder. - SkErrorInternals::SetError(kParseError_SkError, - "Could not decode bitmap. Resulting bitmap will be red."); } else { - // A size of zero means the SkBitmap was simply flattened. - bitmap->unflatten(*this); - return; + // The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap. + const size_t length = this->readUInt(); + if (length > 0) { + // A non-zero size means the SkBitmap was encoded. + const void* data = this->skip(length); + if (fBitmapDecoder != NULL && fBitmapDecoder(data, length, bitmap)) { + SkASSERT(bitmap->width() == width && bitmap->height() == height); + return; + } + // This bitmap was encoded when written, but we are unable to decode, possibly due to + // not having a decoder. + SkErrorInternals::SetError(kParseError_SkError, + "Could not decode bitmap. Resulting bitmap will be red."); + } else { + // A size of zero means the SkBitmap was simply flattened. + bitmap->unflatten(*this); + return; + } } + // Could not read the SkBitmap. Use a placeholder bitmap. + bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); + bitmap->allocPixels(); + bitmap->eraseColor(SK_ColorRED); } - // Could not read the SkBitmap. Use a placeholder bitmap. - bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap->allocPixels(); - bitmap->eraseColor(SK_ColorRED); } SkTypeface* SkOrderedReadBuffer::readTypeface() { diff --git a/src/core/SkOrderedReadBuffer.h b/src/core/SkOrderedReadBuffer.h index c609ec8..f59b9bb 100644 --- a/src/core/SkOrderedReadBuffer.h +++ b/src/core/SkOrderedReadBuffer.h @@ -27,6 +27,8 @@ public: virtual SkOrderedReadBuffer* getOrderedBinaryBuffer() SK_OVERRIDE { return this; } + void setPictureVersion(uint32_t version); + SkReader32* getReader32() { return &fReader; } uint32_t size() { return fReader.size(); } @@ -121,6 +123,7 @@ private: int fFactoryCount; SkPicture::InstallPixelRefProc fBitmapDecoder; + uint32_t fPictureVersion; typedef SkFlattenableReadBuffer INHERITED; }; diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp index 1ff5865..39d0653 100644 --- a/src/core/SkPicture.cpp +++ b/src/core/SkPicture.cpp @@ -6,7 +6,7 @@ * found in the LICENSE file. */ - +#include "SkErrorInternals.h" #include "SkPictureFlat.h" #include "SkPicturePlayback.h" #include "SkPictureRecord.h" @@ -283,9 +283,13 @@ void SkPicture::initFromStream(SkStream* stream, bool* success, InstallPixelRefP SkPictInfo info; if (!stream->read(&info, sizeof(info))) { + SkErrorInternals::SetError(kParseError_SkError, "Failed to parse skp info."); return; } - if (PICTURE_VERSION != info.fVersion) { + + if (info.fVersion < 10 || info.fVersion > PICTURE_VERSION) { + SkErrorInternals::SetError(kParseError_SkError, "skp version %d not supported.", + info.fVersion); return; } diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index d54a6c5..e534aba 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -537,6 +537,7 @@ void SkPicturePlayback::parseStreamTag(SkStream* stream, const SkPictInfo& info, SkOrderedReadBuffer buffer(storage.get(), size); buffer.setFlags(pictInfoFlagsToReadBufferFlags(info.fFlags)); + buffer.setPictureVersion(info.fVersion); fFactoryPlayback->setupBuffer(buffer); fTFPlayback.setupBuffer(buffer); -- 2.7.4