[go: nahoru, domu]

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);