Avoid getLength in ico decoder.

Only call getLength() if hasLength() returned true. Otherwise, copy the
stream into an SkDynamicMemoryWStream and copy it into alloc'ed space.

Share common code between bmp and ico.

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

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

git-svn-id: http://skia.googlecode.com/svn/trunk@10850 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/images/SkStreamHelpers.cpp b/src/images/SkStreamHelpers.cpp
new file mode 100644
index 0000000..3e9ee45
--- /dev/null
+++ b/src/images/SkStreamHelpers.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkStream.h"
+#include "SkStreamHelpers.h"
+#include "SkTypes.h"
+
+size_t CopyStreamToStorage(SkAutoMalloc* storage, SkStream* stream) {
+    SkASSERT(storage != NULL);
+    SkASSERT(stream != NULL);
+
+    if (stream->hasLength()) {
+        const size_t length = stream->getLength();
+        void* dst = storage->reset(length);
+        if (stream->read(dst, length) != length) {
+            return 0;
+        }
+        return length;
+    }
+
+    SkDynamicMemoryWStream tempStream;
+    // Arbitrary buffer size.
+    const size_t bufferSize = 256 * 1024; // 256KB
+    char buffer[bufferSize];
+    SkDEBUGCODE(size_t debugLength = 0;)
+    do {
+        size_t bytesRead = stream->read(buffer, bufferSize);
+        tempStream.write(buffer, bytesRead);
+        SkDEBUGCODE(debugLength += bytesRead);
+        SkASSERT(tempStream.bytesWritten() == debugLength);
+    } while (!stream->isAtEnd());
+    const size_t length = tempStream.bytesWritten();
+    void* dst = storage->reset(length);
+    tempStream.copyTo(dst);
+    return length;
+}