Expand header in serialized pictures
Make chunk/tag reading allow for optional and (somewhat) out-of-order chunks.
Return empty picture instead of throwing on error
Review URL: https://codereview.appspot.com/6329049
git-svn-id: http://skia.googlecode.com/svn/trunk/src@4308 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/core/SkPicture.cpp b/core/SkPicture.cpp
index 3af7a19..bcc2236 100644
--- a/core/SkPicture.cpp
+++ b/core/SkPicture.cpp
@@ -201,24 +201,36 @@
// V2 : adds SkPixelRef's generation ID.
// V3 : PictInfo tag at beginning, and EOF tag at the end
-#define PICTURE_VERSION 3
+// V4 : move SkPictInfo to be the header
+#define PICTURE_VERSION 4
SkPicture::SkPicture(SkStream* stream) : SkRefCnt() {
- uint32_t version = stream->readU32();
-
- if (PICTURE_VERSION != version) {
- sk_throw();
- }
-
- fWidth = stream->readU32();
- fHeight = stream->readU32();
-
fRecord = NULL;
fPlayback = NULL;
+ fWidth = fHeight = 0;
+
+ SkPictInfo info;
+
+ if (!stream->read(&info, sizeof(info))) {
+ return;
+ }
+ if (PICTURE_VERSION != info.fVersion) {
+ return;
+ }
if (stream->readBool()) {
- fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream, version));
+ bool isValid = false;
+ fPlayback = SkNEW_ARGS(SkPicturePlayback, (stream, info, &isValid));
+ if (!isValid) {
+ SkDELETE(fPlayback);
+ fPlayback = NULL;
+ return;
+ }
}
+
+ // do this at the end, so that they will be zero if we hit an error.
+ fWidth = info.fWidth;
+ fHeight = info.fHeight;
}
void SkPicture::serialize(SkWStream* stream) const {
@@ -228,9 +240,20 @@
playback = SkNEW_ARGS(SkPicturePlayback, (*fRecord));
}
- stream->write32(PICTURE_VERSION);
- stream->write32(fWidth);
- stream->write32(fHeight);
+ SkPictInfo info;
+
+ info.fVersion = PICTURE_VERSION;
+ info.fWidth = fWidth;
+ info.fHeight = fHeight;
+ info.fFlags = SkPictInfo::kCrossProcess_Flag;
+#ifdef SK_SCALAR_IS_FLOAT
+ info.fFlags |= SkPictInfo::kScalarIsFloat_Flag;
+#endif
+ if (8 == sizeof(void*)) {
+ info.fFlags |= SkPictInfo::kPtrIs64Bit_Flag;
+ }
+
+ stream->write(&info, sizeof(info));
if (playback) {
stream->writeBool(true);
playback->serialize(stream);