Handle SkStream::rewind properly.

include/core/SkStream.h:
Update documentation to state that rewinding a stream at the beginning
should return true. This is important because our decoders fail if
rewind returns false, assuming that the stream is not at the beginning.

src/images/SkImageDecoder_libpng.cpp:
If rewind fails, call png_error.

src/images/SkImageDecoder_libwebp.cpp:
If rewind fails, report an error and return false.

src/images/SkImageRef.cpp:
If rewind fails report an error and return false.
FIXME: Need to handle flattening properly. Should I perhaps move
writeStream into SkOrderedWriteBuffer?

src/images/SkJpegUtility.cpp:
Report a jpeg error on failure to rewind.

BUG=https://b.corp.google.com/issue?id=8432093
R=bungeman@google.com, djsollen@google.com, reed@google.com

Review URL: https://codereview.chromium.org/22861028

git-svn-id: http://skia.googlecode.com/svn/trunk@10977 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index d7a105d..27f8ead 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -96,7 +96,9 @@
     SkData* readData();
 
 //SkStreamRewindable
-    /** Rewinds to the beginning of the stream. If this cannot be done, return false. */
+    /** Rewinds to the beginning of the stream. Returns true if the stream is known
+     *  to be at the beginning after this call returns.
+     */
     virtual bool rewind() { return false; }
 
     /** Duplicates this stream. If this cannot be done, returns NULL.
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index 85e803b..c188a2f 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -124,7 +124,9 @@
 #ifdef SK_BUILD_FOR_ANDROID
 static void sk_seek_fn(png_structp png_ptr, png_uint_32 offset) {
     SkStream* sk_stream = (SkStream*) png_get_io_ptr(png_ptr);
-    sk_stream->rewind();
+    if (!sk_stream->rewind()) {
+        png_error(png_ptr, "Failed to rewind stream!");
+    }
     (void)sk_stream->skip(offset);
 }
 #endif
diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp
index 9f1116e..7fb1cf0 100644
--- a/src/images/SkImageDecoder_libwebp.cpp
+++ b/src/images/SkImageDecoder_libwebp.cpp
@@ -199,7 +199,10 @@
         return false;
     }
 
-    stream->rewind();
+    if (!stream->rewind()) {
+        SkDebugf("Failed to rewind webp stream!");
+        return false;
+    }
     const size_t readBufferSize = stream->hasLength() ?
             SkTMin(stream->getLength(), WEBP_IDECODE_BUFFER_SZ) : WEBP_IDECODE_BUFFER_SZ;
     SkAutoMalloc srcStorage(readBufferSize);
@@ -311,7 +314,11 @@
         return false;
     }
 
-    stream->rewind();
+    if (!stream->rewind()) {
+        SkDebugf("Failed to rewind webp stream!");
+        return false;
+    }
+
     *width = origWidth;
     *height = origHeight;
 
diff --git a/src/images/SkImageRef.cpp b/src/images/SkImageRef.cpp
index 299166c..bd4a739 100644
--- a/src/images/SkImageRef.cpp
+++ b/src/images/SkImageRef.cpp
@@ -107,7 +107,10 @@
 
     SkASSERT(fBitmap.getPixels() == NULL);
 
-    fStream->rewind();
+    if (!fStream->rewind()) {
+        SkDEBUGF(("Failed to rewind SkImageRef stream!"));
+        return false;
+    }
 
     SkImageDecoder* codec;
     if (fFactory) {
@@ -184,6 +187,15 @@
     buffer.writeUInt(fConfig);
     buffer.writeInt(fSampleSize);
     buffer.writeBool(fDoDither);
-    fStream->rewind();
-    buffer.writeStream(fStream, fStream->getLength());
+    // FIXME: Consider moving this logic should go into writeStream itself.
+    // writeStream currently has no other callers, so this may be fine for
+    // now.
+    if (!fStream->rewind()) {
+        SkDEBUGF(("Failed to rewind SkImageRef stream!"));
+        buffer.write32(0);
+    } else {
+        // FIXME: Handle getLength properly here. Perhaps this class should
+        // take an SkStreamAsset.
+        buffer.writeStream(fStream, fStream->getLength());
+    }
 }
diff --git a/src/images/SkJpegUtility.cpp b/src/images/SkJpegUtility.cpp
index 8d8f62f..1ec9f00 100644
--- a/src/images/SkJpegUtility.cpp
+++ b/src/images/SkJpegUtility.cpp
@@ -16,7 +16,10 @@
 #ifdef SK_BUILD_FOR_ANDROID
     src->current_offset = 0;
 #endif
-    src->fStream->rewind();
+    if (!src->fStream->rewind()) {
+        SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
+        cinfo->err->error_exit((j_common_ptr)cinfo);
+    }
 }
 
 #ifdef SK_BUILD_FOR_ANDROID
@@ -27,7 +30,11 @@
     if (bo > src->current_offset) {
         (void)src->fStream->skip(bo - src->current_offset);
     } else {
-        src->fStream->rewind();
+        if (!src->fStream->rewind()) {
+            SkDebugf("xxxxxxxxxxxxxx failure to rewind\n");
+            cinfo->err->error_exit((j_common_ptr)cinfo);
+            return false;
+        }
         (void)src->fStream->skip(bo);
     }