Make SkStream *not* ref counted.

SkStream is a stateful object, so it does not make sense for it to have
multiple owners. Make SkStream inherit directly from SkNoncopyable.

Update methods which previously called SkStream::ref() (e.g.
SkImageDecoder::buildTileIndex() and SkFrontBufferedStream::Create(),
which required the existing owners to call SkStream::unref()) to take
ownership of their SkStream parameters and delete when done (including
on failure).

Switch all SkAutoTUnref<SkStream>s to SkAutoTDelete<SkStream>s. In some
cases this means heap allocating streams that were previously stack
allocated.

Respect ownership rules of SkTypeface::CreateFromStream() and
SkImageDecoder::buildTileIndex().

Update the comments for exceptional methods which do not affect the
ownership of their SkStream parameters (e.g.
SkPicture::CreateFromStream() and SkTypeface::Deserialize()) to be
explicit about ownership.

Remove test_stream_life, which tested that buildTileIndex() behaved
correctly when SkStream was a ref counted object. The test does not
make sense now that it is not.

In SkPDFStream, remove the SkMemoryStream member. Instead of using it,
create a new SkMemoryStream to pass to fDataStream (which is now an
SkAutoTDelete).

Make other pdf rasterizers behave like SkPDFDocumentToBitmap.

SkPDFDocumentToBitmap delete the SkStream, so do the same in the
following pdf rasterizers:

SkPopplerRasterizePDF
SkNativeRasterizePDF
SkNoRasterizePDF

Requires a change to Android, which currently treats SkStreams as ref
counted objects.

Review URL: https://codereview.chromium.org/849103004
diff --git a/src/animator/SkAnimateMaker.cpp b/src/animator/SkAnimateMaker.cpp
index a3ebb64..2565762 100644
--- a/src/animator/SkAnimateMaker.cpp
+++ b/src/animator/SkAnimateMaker.cpp
@@ -99,7 +99,7 @@
 //  SkDebugf("animator decode %s\n", uri);
 
 //    SkStream* stream = SkStream::GetURIStream(fPrefix.c_str(), uri);
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
+    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(uri));
     if (stream.get()) {
         bool success = decodeStream(stream);
         if (hasError() && fError.hasNoun() == false)
diff --git a/src/animator/SkAnimator.cpp b/src/animator/SkAnimator.cpp
index 1c53e30..f2b7780 100644
--- a/src/animator/SkAnimator.cpp
+++ b/src/animator/SkAnimator.cpp
@@ -84,7 +84,7 @@
 //  SkDebugf("animator decode %s\n", uri);
 
 //    SkStream* stream = SkStream::GetURIStream(fMaker->fPrefix.c_str(), uri);
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(uri));
+    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(uri));
     if (stream.get()) {
         this->setURIBase(uri);
         return decodeStream(stream);
diff --git a/src/animator/SkDrawBitmap.cpp b/src/animator/SkDrawBitmap.cpp
index 5349774..f41c152 100644
--- a/src/animator/SkDrawBitmap.cpp
+++ b/src/animator/SkDrawBitmap.cpp
@@ -189,7 +189,7 @@
         fBitmap.reset();
 
         //SkStream* stream = SkStream::GetURIStream(fUriBase, src.c_str());
-        SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(src.c_str()));
+        SkAutoTDelete<SkStreamAsset> stream(SkStream::NewFromFile(src.c_str()));
         if (stream.get()) {
             SkImageDecoder::DecodeStream(stream, &fBitmap);
         }
diff --git a/src/core/SkFontDescriptor.h b/src/core/SkFontDescriptor.h
index 5a6ddd5..aafbe84 100644
--- a/src/core/SkFontDescriptor.h
+++ b/src/core/SkFontDescriptor.h
@@ -12,11 +12,10 @@
 #include "SkString.h"
 #include "SkTypeface.h"
 
-class SkWStream;
-
 class SkFontDescriptor {
 public:
     SkFontDescriptor(SkTypeface::Style = SkTypeface::kNormal);
+    // Does not affect ownership of SkStream.
     SkFontDescriptor(SkStream*);
 
     void serialize(SkWStream*);
@@ -28,7 +27,9 @@
     const char* getFullName() const { return fFullName.c_str(); }
     const char* getPostscriptName() const { return fPostscriptName.c_str(); }
     const char* getFontFileName() const { return fFontFileName.c_str(); }
-    SkStream* getFontData() const { return fFontData; }
+    bool hasFontData() const { return fFontData.get() != NULL; }
+    // Transfers ownership to the caller.
+    SkStream* transferFontData() { return fFontData.detach(); }
     int getFontIndex() const { return fFontIndex; }
 
     void setFamilyName(const char* name) { fFamilyName.set(name); }
@@ -46,7 +47,7 @@
     SkString fFullName;
     SkString fPostscriptName;
     SkString fFontFileName;
-    SkAutoTUnref<SkStream> fFontData;
+    SkAutoTDelete<SkStream> fFontData;
     int fFontIndex;
 
     SkTypeface::Style fStyle;
diff --git a/src/core/SkFontMgr.cpp b/src/core/SkFontMgr.cpp
index ca29e29..71289a6 100644
--- a/src/core/SkFontMgr.cpp
+++ b/src/core/SkFontMgr.cpp
@@ -7,10 +7,10 @@
 
 #include "SkFontMgr.h"
 #include "SkLazyPtr.h"
+#include "SkStream.h"
 #include "SkTypes.h"
 
 class SkFontStyle;
-class SkStream;
 class SkTypeface;
 
 class SkEmptyFontStyleSet : public SkFontStyleSet {
@@ -68,7 +68,8 @@
     SkTypeface* onCreateFromData(SkData*, int) const SK_OVERRIDE {
         return NULL;
     }
-    SkTypeface* onCreateFromStream(SkStream*, int) const SK_OVERRIDE {
+    SkTypeface* onCreateFromStream(SkStream* stream, int) const SK_OVERRIDE {
+        SkDELETE(stream);
         return NULL;
     }
     SkTypeface* onCreateFromFile(const char[], int) const SK_OVERRIDE {
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index f1d5ab6..0bd641f 100644
--- a/src/core/SkPaint.cpp
+++ b/src/core/SkPaint.cpp
@@ -2084,7 +2084,7 @@
     if (typeface) {
         SkDynamicMemoryWStream ostream;
         typeface->serialize(&ostream);
-        SkAutoTUnref<SkStreamAsset> istream(ostream.detachAsStream());
+        SkAutoTDelete<SkStreamAsset> istream(ostream.detachAsStream());
         SkFontDescriptor descriptor(istream);
 
         str->append("<dt>Font Family Name:</dt><dd>");
diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h
index ab78f8a..cada8d1 100644
--- a/src/core/SkPictureData.h
+++ b/src/core/SkPictureData.h
@@ -58,6 +58,7 @@
 class SkPictureData {
 public:
     SkPictureData(const SkPictureRecord& record, const SkPictInfo&, bool deepCopyOps);
+    // Does not affect ownership of SkStream.
     static SkPictureData* CreateFromStream(SkStream*,
                                            const SkPictInfo&,
                                            SkPicture::InstallPixelRefProc);
@@ -79,6 +80,7 @@
 protected:
     explicit SkPictureData(const SkPictInfo& info);
 
+    // Does not affect ownership of SkStream.
     bool parseStream(SkStream*, SkPicture::InstallPixelRefProc);
     bool parseBuffer(SkReadBuffer& buffer);
 
@@ -135,6 +137,7 @@
     void init();
 
     // these help us with reading/writing
+    // Does not affect ownership of SkStream.
     bool parseStreamTag(SkStream*, uint32_t tag, uint32_t size, SkPicture::InstallPixelRefProc);
     bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
     void flattenToBuffer(SkWriteBuffer&) const;
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index 2b190b0..38432c4 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -239,7 +239,7 @@
     }
 
     if (!fName.isEmpty()) {
-        SkAutoTUnref<SkFILEStream> that(new SkFILEStream(fName.c_str()));
+        SkAutoTDelete<SkFILEStream> that(new SkFILEStream(fName.c_str()));
         if (sk_fidentical(that->fFILE, this->fFILE)) {
             return that.detach();
         }
@@ -265,7 +265,7 @@
 }
 
 SkStreamAsset* SkFILEStream::fork() const {
-    SkAutoTUnref<SkStreamAsset> that(this->duplicate());
+    SkAutoTDelete<SkStreamAsset> that(this->duplicate());
     that->seek(this->getPosition());
     return that.detach();
 }
@@ -396,7 +396,7 @@
 }
 
 SkMemoryStream* SkMemoryStream::fork() const {
-    SkAutoTUnref<SkMemoryStream> that(this->duplicate());
+    SkAutoTDelete<SkMemoryStream> that(this->duplicate());
     that->seek(fOffset);
     return that.detach();
 }
@@ -741,7 +741,7 @@
     }
 
     SkBlockMemoryStream* fork() const SK_OVERRIDE {
-        SkAutoTUnref<SkBlockMemoryStream> that(this->duplicate());
+        SkAutoTDelete<SkBlockMemoryStream> that(this->duplicate());
         that->fCurrent = this->fCurrent;
         that->fOffset = this->fOffset;
         that->fCurrentOffset = this->fCurrentOffset;
@@ -827,7 +827,7 @@
     // file access.
     SkFILEStream* stream = SkNEW_ARGS(SkFILEStream, (path));
     if (!stream->isValid()) {
-        stream->unref();
+        SkDELETE(stream);
         stream = NULL;
     }
     return stream;
@@ -886,7 +886,7 @@
     if (!stream) {
         return NULL;
     }
-    SkAutoTUnref<SkStreamRewindable> dupStream(stream->duplicate());
+    SkAutoTDelete<SkStreamRewindable> dupStream(stream->duplicate());
     if (dupStream) {
         return dupStream.detach();
     }
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index 75ff58e..b86cfa7 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -156,7 +156,7 @@
     this->onGetFontDescriptor(&desc, &isLocal);
 
     // Embed font data if it's a local font.
-    if (isLocal && NULL == desc.getFontData()) {
+    if (isLocal && !desc.hasFontData()) {
         int ttcIndex;
         desc.setFontData(this->onOpenStream(&ttcIndex));
         desc.setFontIndex(ttcIndex);
@@ -170,7 +170,7 @@
     this->onGetFontDescriptor(&desc, &ignoredIsLocal);
 
     // Always embed font data.
-    if (NULL == desc.getFontData()) {
+    if (!desc.hasFontData()) {
         int ttcIndex;
         desc.setFontData(this->onOpenStream(&ttcIndex));
         desc.setFontIndex(ttcIndex);
@@ -180,7 +180,7 @@
 
 SkTypeface* SkTypeface::Deserialize(SkStream* stream) {
     SkFontDescriptor desc(stream);
-    SkStream* data = desc.getFontData();
+    SkStream* data = desc.transferFontData();
     if (data) {
         SkTypeface* typeface = SkTypeface::CreateFromStream(data, desc.getFontIndex());
         if (typeface) {
diff --git a/src/device/xps/SkXPSDevice.cpp b/src/device/xps/SkXPSDevice.cpp
index df2cdd9..c1105a2 100644
--- a/src/device/xps/SkXPSDevice.cpp
+++ b/src/device/xps/SkXPSDevice.cpp
@@ -401,7 +401,7 @@
         fontPackageBuffer.realloc(bytesWritten);
     }
 
-    SkAutoTUnref<SkMemoryStream> newStream(new SkMemoryStream());
+    SkAutoTDelete<SkMemoryStream> newStream(new SkMemoryStream());
     newStream->setMemoryOwned(fontPackageBuffer.detach(), bytesWritten + extra);
 
     SkTScopedComPtr<IStream> newIStream;
diff --git a/src/fonts/SkFontMgr_fontconfig.cpp b/src/fonts/SkFontMgr_fontconfig.cpp
index a3989fc..c1d531d 100644
--- a/src/fonts/SkFontMgr_fontconfig.cpp
+++ b/src/fonts/SkFontMgr_fontconfig.cpp
@@ -296,6 +296,7 @@
     SkTypeface* onCreateFromData(SkData*, int ttcIndex) const SK_OVERRIDE { return NULL; }
 
     SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTDelete<SkStream> streamDeleter(stream);
         const size_t length = stream->getLength();
         if (!length) {
             return NULL;
@@ -311,13 +312,13 @@
             return NULL;
         }
 
-        SkTypeface* face = FontConfigTypeface::Create(style, isFixedWidth, stream);
+        SkTypeface* face = FontConfigTypeface::Create(style, isFixedWidth, streamDeleter.detach());
         return face;
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-        return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
+        SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
+        return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL;
     }
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
diff --git a/src/fonts/SkFontMgr_indirect.cpp b/src/fonts/SkFontMgr_indirect.cpp
index c438623..6f94dfd 100644
--- a/src/fonts/SkFontMgr_indirect.cpp
+++ b/src/fonts/SkFontMgr_indirect.cpp
@@ -213,19 +213,19 @@
 
     // No exact match, but did find a data match.
     if (dataTypeface.get() != NULL) {
-        SkAutoTUnref<SkStream> stream(dataTypeface->openStream(NULL));
+        SkAutoTDelete<SkStream> stream(dataTypeface->openStream(NULL));
         if (stream.get() != NULL) {
-            return fImpl->createFromStream(stream.get(), dataTypefaceIndex);
+            return fImpl->createFromStream(stream.detach(), dataTypefaceIndex);
         }
     }
 
     // No data match, request data and add entry.
-    SkAutoTUnref<SkStreamAsset> stream(fProxy->getData(id.fDataId));
+    SkAutoTDelete<SkStreamAsset> stream(fProxy->getData(id.fDataId));
     if (stream.get() == NULL) {
         return NULL;
     }
 
-    SkAutoTUnref<SkTypeface> typeface(fImpl->createFromStream(stream, id.fTtcIndex));
+    SkAutoTUnref<SkTypeface> typeface(fImpl->createFromStream(stream.detach(), id.fTtcIndex));
     if (typeface.get() == NULL) {
         return NULL;
     }
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index e46f336..a915214 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -125,7 +125,7 @@
     }
 
     int faceIndex;
-    SkAutoTUnref<SkStream> fontStream(typeface->openStream(&faceIndex));
+    SkAutoTDelete<SkStream> fontStream(typeface->openStream(&faceIndex));
 
     const size_t fontDataLength = fontStream->getLength();
     if (0 == fontDataLength) {
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index baa112c..e7a775e 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -24,11 +24,11 @@
 public:
     virtual ~DecodingImageGenerator();
 
-    SkData*                fData;
-    SkStreamRewindable*    fStream;
-    const SkImageInfo      fInfo;
-    const int              fSampleSize;
-    const bool             fDitherImage;
+    SkData*                             fData;
+    SkAutoTDelete<SkStreamRewindable>   fStream;
+    const SkImageInfo                   fInfo;
+    const int                           fSampleSize;
+    const bool                          fDitherImage;
 
     DecodingImageGenerator(SkData* data,
                            SkStreamRewindable* stream,
@@ -128,7 +128,6 @@
 
 DecodingImageGenerator::~DecodingImageGenerator() {
     SkSafeUnref(fData);
-    fStream->unref();
 }
 
 SkData* DecodingImageGenerator::onRefEncodedData() {
@@ -227,7 +226,7 @@
         SkStreamRewindable* stream,
         const SkDecodingImageGenerator::Options& opts) {
     SkASSERT(stream);
-    SkAutoTUnref<SkStreamRewindable> autoStream(stream);  // always unref this.
+    SkAutoTDelete<SkStreamRewindable> autoStream(stream);  // always delete this
     SkAssertResult(autoStream->rewind());
     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(autoStream));
     if (NULL == decoder.get()) {
@@ -280,7 +279,6 @@
     }
     SkStreamRewindable* stream = SkNEW_ARGS(SkMemoryStream, (data));
     SkASSERT(stream != NULL);
-    SkASSERT(stream->unique());
     return CreateDecodingImageGenerator(data, stream, opts);
 }
 
@@ -288,9 +286,7 @@
         SkStreamRewindable* stream,
         const SkDecodingImageGenerator::Options& opts) {
     SkASSERT(stream != NULL);
-    SkASSERT(stream->unique());
-    if ((stream == NULL) || !stream->unique()) {
-        SkSafeUnref(stream);
+    if (stream == NULL) {
         return NULL;
     }
     return CreateDecodingImageGenerator(NULL, stream, opts);
diff --git a/src/images/SkImageDecoder.cpp b/src/images/SkImageDecoder.cpp
index 596d05e..89a4705 100644
--- a/src/images/SkImageDecoder.cpp
+++ b/src/images/SkImageDecoder.cpp
@@ -158,6 +158,13 @@
     return this->onBuildTileIndex(stream, width, height);
 }
 
+bool SkImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, int* /*width*/,
+                                      int* /*height*/) {
+    SkDELETE(stream);
+    return false;
+}
+
+
 bool SkImageDecoder::cropBitmap(SkBitmap *dst, SkBitmap *src, int sampleSize,
                                 int dstX, int dstY, int width, int height,
                                 int srcX, int srcY) {
@@ -212,7 +219,7 @@
     SkASSERT(file);
     SkASSERT(bm);
 
-    SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(file));
+    SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(file));
     if (stream.get()) {
         if (SkImageDecoder::DecodeStream(stream, bm, pref, mode, format)) {
             bm->pixelRef()->setURI(file);
diff --git a/src/images/SkImageDecoder_libjpeg.cpp b/src/images/SkImageDecoder_libjpeg.cpp
index 8c9d267..e0722e1 100644
--- a/src/images/SkImageDecoder_libjpeg.cpp
+++ b/src/images/SkImageDecoder_libjpeg.cpp
@@ -105,8 +105,10 @@
 #ifdef SK_BUILD_FOR_ANDROID
 class SkJPEGImageIndex {
 public:
+    // Takes ownership of stream.
     SkJPEGImageIndex(SkStreamRewindable* stream, SkImageDecoder* decoder)
         : fSrcMgr(stream, decoder)
+        , fStream(stream)
         , fInfoInitialized(false)
         , fHuffmanCreated(false)
         , fDecompressStarted(false)
@@ -206,6 +208,7 @@
 
 private:
     skjpeg_source_mgr  fSrcMgr;
+    SkAutoTDelete<SkStream> fStream;
     jpeg_decompress_struct fCInfo;
     huffman_index fHuffmanIndex;
     bool fInfoInitialized;
diff --git a/src/images/SkImageDecoder_libpng.cpp b/src/images/SkImageDecoder_libpng.cpp
index c3bba6e..f9ef6b7 100644
--- a/src/images/SkImageDecoder_libpng.cpp
+++ b/src/images/SkImageDecoder_libpng.cpp
@@ -53,13 +53,13 @@
 
 class SkPNGImageIndex {
 public:
+    // Takes ownership of stream.
     SkPNGImageIndex(SkStreamRewindable* stream, png_structp png_ptr, png_infop info_ptr)
         : fStream(stream)
         , fPng_ptr(png_ptr)
         , fInfo_ptr(info_ptr)
         , fColorType(kUnknown_SkColorType) {
         SkASSERT(stream != NULL);
-        stream->ref();
     }
     ~SkPNGImageIndex() {
         if (fPng_ptr) {
@@ -67,7 +67,7 @@
         }
     }
 
-    SkAutoTUnref<SkStreamRewindable>    fStream;
+    SkAutoTDelete<SkStreamRewindable>   fStream;
     png_structp                         fPng_ptr;
     png_infop                           fInfo_ptr;
     SkColorType                         fColorType;
@@ -718,6 +718,7 @@
 #ifdef SK_BUILD_FOR_ANDROID
 
 bool SkPNGImageDecoder::onBuildTileIndex(SkStreamRewindable* sk_stream, int *width, int *height) {
+    SkAutoTDelete<SkStreamRewindable> streamDeleter(sk_stream);
     png_structp png_ptr;
     png_infop   info_ptr;
 
@@ -743,7 +744,7 @@
     if (fImageIndex) {
         SkDELETE(fImageIndex);
     }
-    fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (sk_stream, png_ptr, info_ptr));
+    fImageIndex = SkNEW_ARGS(SkPNGImageIndex, (streamDeleter.detach(), png_ptr, info_ptr));
 
     return true;
 }
diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp
index c56933d..5ac647a 100644
--- a/src/images/SkImageDecoder_libwebp.cpp
+++ b/src/images/SkImageDecoder_libwebp.cpp
@@ -95,14 +95,10 @@
 class SkWEBPImageDecoder: public SkImageDecoder {
 public:
     SkWEBPImageDecoder() {
-        fInputStream = NULL;
         fOrigWidth = 0;
         fOrigHeight = 0;
         fHasAlpha = 0;
     }
-    virtual ~SkWEBPImageDecoder() {
-        SkSafeUnref(fInputStream);
-    }
 
     Format getFormat() const SK_OVERRIDE {
         return kWEBP_Format;
@@ -125,7 +121,7 @@
 
     bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height);
 
-    SkStream* fInputStream;
+    SkAutoTDelete<SkStream> fInputStream;
     int fOrigWidth;
     int fOrigHeight;
     int fHasAlpha;
@@ -316,6 +312,7 @@
 
 bool SkWEBPImageDecoder::onBuildTileIndex(SkStreamRewindable* stream,
                                           int *width, int *height) {
+    SkAutoTDelete<SkStreamRewindable> streamDeleter(stream);
     int origWidth, origHeight, hasAlpha;
     if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) {
         return false;
@@ -329,7 +326,7 @@
     *width = origWidth;
     *height = origHeight;
 
-    SkRefCnt_SafeAssign(this->fInputStream, stream);
+    this->fInputStream.reset(streamDeleter.detach());
     this->fOrigWidth = origWidth;
     this->fOrigHeight = origHeight;
     this->fHasAlpha = hasAlpha;
diff --git a/src/images/SkJpegUtility.cpp b/src/images/SkJpegUtility.cpp
index e17b55b..937c5ec 100644
--- a/src/images/SkJpegUtility.cpp
+++ b/src/images/SkJpegUtility.cpp
@@ -96,7 +96,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder)
-    : fStream(SkRef(stream))
+    : fStream(stream)
     , fDecoder(decoder) {
 
     init_source = sk_init_source;
@@ -110,10 +110,6 @@
 //    SkDebugf("**************** use memorybase %p %d\n", fMemoryBase, fMemoryBaseSize);
 }
 
-skjpeg_source_mgr::~skjpeg_source_mgr() {
-    SkSafeUnref(fStream);
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 
 static void sk_init_destination(j_compress_ptr cinfo) {
diff --git a/src/images/SkJpegUtility.h b/src/images/SkJpegUtility.h
index 69092ef..1a763f8 100644
--- a/src/images/SkJpegUtility.h
+++ b/src/images/SkJpegUtility.h
@@ -35,9 +35,8 @@
 */
 struct skjpeg_source_mgr : jpeg_source_mgr {
     skjpeg_source_mgr(SkStream* stream, SkImageDecoder* decoder);
-    ~skjpeg_source_mgr();
 
-    // fStream is ref'ed and unref'ed
+    // Unowned.
     SkStream*       fStream;
     // Unowned pointer to the decoder, used to check if the decoding process
     // has been cancelled.
diff --git a/src/images/SkMovie.cpp b/src/images/SkMovie.cpp
index 9a2a71c..2a1339f 100644
--- a/src/images/SkMovie.cpp
+++ b/src/images/SkMovie.cpp
@@ -90,6 +90,6 @@
 }
 
 SkMovie* SkMovie::DecodeFile(const char path[]) {
-    SkAutoTUnref<SkStreamRewindable> stream(SkStream::NewFromFile(path));
+    SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(path));
     return stream.get() ? SkMovie::DecodeStream(stream) : NULL;
 }
diff --git a/src/pdf/SkPDFFont.cpp b/src/pdf/SkPDFFont.cpp
index a093f62..de61326 100644
--- a/src/pdf/SkPDFFont.cpp
+++ b/src/pdf/SkPDFFont.cpp
@@ -158,7 +158,7 @@
     // if the data was NUL terminated so that we can use strstr() to search it.
     // Make as few copies as possible given these constraints.
     SkDynamicMemoryWStream dynamicStream;
-    SkAutoTUnref<SkMemoryStream> staticStream;
+    SkAutoTDelete<SkMemoryStream> staticStream;
     SkData* data = NULL;
     const uint8_t* src;
     size_t srcLen;
@@ -586,7 +586,7 @@
                                      const SkTDArray<uint32_t>& subset,
                                      SkPDFStream** fontStream) {
     int ttcIndex;
-    SkAutoTUnref<SkStream> fontData(typeface->openStream(&ttcIndex));
+    SkAutoTDelete<SkStream> fontData(typeface->openStream(&ttcIndex));
     SkASSERT(fontData.get());
 
     size_t fontSize = fontData->getLength();
@@ -1091,7 +1091,7 @@
                 fontStream.reset(rawStream);
             } else {
                 int ttcIndex;
-                SkAutoTUnref<SkStream> fontData(
+                SkAutoTDelete<SkStream> fontData(
                         typeface()->openStream(&ttcIndex));
                 fontStream.reset(new SkPDFStream(fontData.get()));
                 fontSize = fontData->getLength();
@@ -1108,7 +1108,7 @@
         case SkAdvancedTypefaceMetrics::kCFF_Font:
         case SkAdvancedTypefaceMetrics::kType1CID_Font: {
             int ttcIndex;
-            SkAutoTUnref<SkStream> fontData(typeface()->openStream(&ttcIndex));
+            SkAutoTDelete<SkStream> fontData(typeface()->openStream(&ttcIndex));
             SkAutoTUnref<SkPDFStream> fontStream(
                 new SkPDFStream(fontData.get()));
             addResource(fontStream.get());
@@ -1238,7 +1238,7 @@
     size_t header SK_INIT_TO_AVOID_WARNING;
     size_t data SK_INIT_TO_AVOID_WARNING;
     size_t trailer SK_INIT_TO_AVOID_WARNING;
-    SkAutoTUnref<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
+    SkAutoTDelete<SkStream> rawFontData(typeface()->openStream(&ttcIndex));
     SkAutoTUnref<SkData> fontData(handle_type1_stream(rawFontData.get(), &header,
                                                       &data, &trailer));
     if (fontData.get() == NULL) {
@@ -1405,7 +1405,7 @@
             SkPDFUtils::PaintPath(paint.getStyle(), path->getFillType(),
                                   &content);
         }
-        SkAutoTUnref<SkMemoryStream> glyphStream(new SkMemoryStream());
+        SkAutoTDelete<SkMemoryStream> glyphStream(new SkMemoryStream());
         glyphStream->setData(content.copyToData())->unref();
 
         SkAutoTUnref<SkPDFStream> glyphDescription(
diff --git a/src/pdf/SkPDFFormXObject.cpp b/src/pdf/SkPDFFormXObject.cpp
index 1635b0f..2a0f530 100644
--- a/src/pdf/SkPDFFormXObject.cpp
+++ b/src/pdf/SkPDFFormXObject.cpp
@@ -25,7 +25,7 @@
     SkPDFResourceDict* resourceDict = device->getResourceDict();
     resourceDict->getReferencedResources(emptySet, &fResources, false);
 
-    SkAutoTUnref<SkStream> content(device->content());
+    SkAutoTDelete<SkStream> content(device->content());
     setData(content.get());
 
     SkAutoTUnref<SkPDFArray> bboxArray(device->copyMediaBox());
diff --git a/src/pdf/SkPDFImage.cpp b/src/pdf/SkPDFImage.cpp
index 65454fa..5dc6bab 100644
--- a/src/pdf/SkPDFImage.cpp
+++ b/src/pdf/SkPDFImage.cpp
@@ -239,40 +239,41 @@
         }
         return NULL;
     }
-    bool isOpaque = true;
-    bool transparent = extractAlpha;
-    SkStream* stream = NULL;
 
     SkAutoLockPixels lock(bitmap);
     if (NULL == bitmap.getPixels()) {
         return NULL;
     }
 
+    bool isOpaque = true;
+    bool transparent = extractAlpha;
+    SkAutoTDelete<SkStream> stream;
+
     switch (colorType) {
         case kIndex_8_SkColorType:
             if (!extractAlpha) {
-                stream = extract_index8_image(bitmap, srcRect);
+                stream.reset(extract_index8_image(bitmap, srcRect));
             }
             break;
         case kARGB_4444_SkColorType:
-            stream = extract_argb4444_data(bitmap, srcRect, extractAlpha,
-                                           &isOpaque, &transparent);
+            stream.reset(extract_argb4444_data(bitmap, srcRect, extractAlpha,
+                                               &isOpaque, &transparent));
             break;
         case kRGB_565_SkColorType:
             if (!extractAlpha) {
-                stream = extract_rgb565_image(bitmap, srcRect);
+                stream.reset(extract_rgb565_image(bitmap, srcRect));
             }
             break;
         case kN32_SkColorType:
-            stream = extract_argb8888_data(bitmap, srcRect, extractAlpha,
-                                           &isOpaque, &transparent);
+            stream.reset(extract_argb8888_data(bitmap, srcRect, extractAlpha,
+                                               &isOpaque, &transparent));
             break;
         case kAlpha_8_SkColorType:
             if (!extractAlpha) {
-                stream = create_black_image();
+                stream.reset(create_black_image());
             } else {
-                stream = extract_a8_alpha(bitmap, srcRect,
-                                          &isOpaque, &transparent);
+                stream.reset(extract_a8_alpha(bitmap, srcRect,
+                                              &isOpaque, &transparent));
             }
             break;
         default:
@@ -283,10 +284,9 @@
         *isTransparent = transparent;
     }
     if (extractAlpha && (transparent || isOpaque)) {
-        SkSafeUnref(stream);
         return NULL;
     }
-    return stream;
+    return stream.detach();
 }
 
 static SkPDFArray* make_indexed_color_space(SkColorTable* table) {
@@ -468,7 +468,7 @@
     }
 
     bool isTransparent = false;
-    SkAutoTUnref<SkStream> alphaData;
+    SkAutoTDelete<SkStream> alphaData;
     if (!bitmap.isOpaque()) {
         // Note that isOpaque is not guaranteed to return false for bitmaps
         // with alpha support but a completely opaque alpha channel,
@@ -639,7 +639,7 @@
         }
         // Fallback method
         if (!fStreamValid) {
-            SkAutoTUnref<SkStream> stream(
+            SkAutoTDelete<SkStream> stream(
                     extract_image_data(fBitmap, fSrcRect, fIsAlpha, NULL));
             this->setData(stream);
             fStreamValid = true;
diff --git a/src/pdf/SkPDFImage.h b/src/pdf/SkPDFImage.h
index 5c026da..a4bc548 100644
--- a/src/pdf/SkPDFImage.h
+++ b/src/pdf/SkPDFImage.h
@@ -82,6 +82,7 @@
      *  @param stream     The image stream. May be NULL. Otherwise, this
      *                    (instead of the input bitmap) will be used as the
      *                    PDF's content stream, possibly with lossless encoding.
+     *                    Will be duplicated, and left in indeterminate state.
      *  @param bitmap     The image. If a stream is not given, its color data
      *                    will be used as the image. If a stream is given, this
      *                    is used for configuration only.
diff --git a/src/pdf/SkPDFShader.cpp b/src/pdf/SkPDFShader.cpp
index 2a144a6..1b9d9eb 100644
--- a/src/pdf/SkPDFShader.cpp
+++ b/src/pdf/SkPDFShader.cpp
@@ -737,7 +737,7 @@
     SkAutoTUnref<SkPDFObject> luminosityShader(SkPDFShader::GetPDFShaderByState(
             fShaderState->CreateAlphaToLuminosityState()));
 
-    SkAutoTUnref<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
+    SkAutoTDelete<SkStream> alphaStream(create_pattern_fill_content(-1, bbox));
 
     SkAutoTUnref<SkPDFResourceDict>
         resources(get_gradient_resource_dict(luminosityShader, NULL));
@@ -764,7 +764,7 @@
     fResourceDict.reset(
             get_gradient_resource_dict(fColorShader.get(), alphaGs.get()));
 
-    SkAutoTUnref<SkStream> colorStream(
+    SkAutoTDelete<SkStream> colorStream(
             create_pattern_fill_content(0, bbox));
     setData(colorStream.get());
 
@@ -1131,7 +1131,7 @@
     }
 
     // Put the canvas into the pattern stream (fContent).
-    SkAutoTUnref<SkStream> content(pattern.content());
+    SkAutoTDelete<SkStream> content(pattern.content());
     setData(content.get());
     SkPDFResourceDict* resourceDict = pattern.getResourceDict();
     resourceDict->getReferencedResources(fResources, &fResources, false);
diff --git a/src/pdf/SkPDFStream.cpp b/src/pdf/SkPDFStream.cpp
index 837de7a..5eaa6c2 100644
--- a/src/pdf/SkPDFStream.cpp
+++ b/src/pdf/SkPDFStream.cpp
@@ -61,25 +61,19 @@
 SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
 
 void SkPDFStream::setData(SkData* data) {
-    fMemoryStream.setData(data);
-    if (&fMemoryStream != fDataStream.get()) {
-        fDataStream.reset(SkRef(&fMemoryStream));
-    }
+    // FIXME: Don't swap if the data is the same.
+    fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data)));
 }
 
 void SkPDFStream::setData(SkStream* stream) {
     // Code assumes that the stream starts at the beginning and is rewindable.
-    if (&fMemoryStream == fDataStream.get()) {
-        SkASSERT(&fMemoryStream != stream);
-        fMemoryStream.setData(NULL);
-    }
-    SkASSERT(0 == fMemoryStream.getLength());
     if (stream) {
         // SkStreamRewindableFromSkStream will try stream->duplicate().
         fDataStream.reset(SkStreamRewindableFromSkStream(stream));
         SkASSERT(fDataStream.get());
     } else {
-        fDataStream.reset(SkRef(&fMemoryStream));
+        // Use an empty memory stream.
+        fDataStream.reset(SkNEW(SkMemoryStream));
     }
 }
 
@@ -97,7 +91,7 @@
                     SkFlate::Deflate(fDataStream.get(), &compressedData));
             SkAssertResult(fDataStream->rewind());
             if (compressedData.getOffset() < this->dataSize()) {
-                SkAutoTUnref<SkStream> compressed(
+                SkAutoTDelete<SkStream> compressed(
                         compressedData.detachAsStream());
                 this->setData(compressed.get());
                 insertName("Filter", "FlateDecode");
diff --git a/src/pdf/SkPDFStream.h b/src/pdf/SkPDFStream.h
index 586b2e8..cf9316f 100644
--- a/src/pdf/SkPDFStream.h
+++ b/src/pdf/SkPDFStream.h
@@ -93,10 +93,7 @@
     // Mutex guards fState, fDataStream, and fSubstitute in public interface.
     SkMutex fMutex;
 
-    SkMemoryStream fMemoryStream;  // Used by fDataStream when
-                                   // fDataStream needs to be backed
-                                   // by SkData.
-    SkAutoTUnref<SkStreamRewindable> fDataStream;
+    SkAutoTDelete<SkStreamRewindable> fDataStream;
     SkAutoTUnref<SkPDFStream> fSubstitute;
 
     typedef SkPDFDict INHERITED;
diff --git a/src/ports/SkFontConfigTypeface.h b/src/ports/SkFontConfigTypeface.h
index fcbc16f..821f490 100644
--- a/src/ports/SkFontConfigTypeface.h
+++ b/src/ports/SkFontConfigTypeface.h
@@ -15,7 +15,7 @@
 class FontConfigTypeface : public SkTypeface_FreeType {
     SkFontConfigInterface::FontIdentity fIdentity;
     SkString fFamilyName;
-    SkStream* fLocalStream;
+    SkAutoTDelete<SkStream> fLocalStream;
 
 public:
     static FontConfigTypeface* Create(const SkFontStyle& style,
@@ -29,16 +29,12 @@
         return SkNEW_ARGS(FontConfigTypeface, (style, fixedWidth, localStream));
     }
 
-    virtual ~FontConfigTypeface() {
-        SkSafeUnref(fLocalStream);
-    }
-
     const SkFontConfigInterface::FontIdentity& getIdentity() const {
         return fIdentity;
     }
 
     const char* getFamilyName() const { return fFamilyName.c_str(); }
-    SkStream*   getLocalStream() const { return fLocalStream; }
+    SkStream*   getLocalStream() const { return fLocalStream.get(); }
 
     bool isFamilyName(const char* name) const {
         return fFamilyName.equals(name);
@@ -60,10 +56,9 @@
             , fLocalStream(NULL) {}
 
     FontConfigTypeface(const SkFontStyle& style, bool fixedWidth, SkStream* localStream)
-            : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth) {
+            : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
+            , fLocalStream(localStream) {
         // we default to empty fFamilyName and fIdentity
-        fLocalStream = localStream;
-        SkSafeRef(localStream);
     }
 
     void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index ce762d8..72fe8f6 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -233,18 +233,15 @@
 ///////////////////////////////////////////////////////////////////////////
 
 struct SkFaceRec {
-    SkFaceRec*      fNext;
-    FT_Face         fFace;
-    FT_StreamRec    fFTStream;
-    SkStream*       fSkStream;
-    uint32_t        fRefCnt;
-    uint32_t        fFontID;
+    SkFaceRec*              fNext;
+    FT_Face                 fFace;
+    FT_StreamRec            fFTStream;
+    SkAutoTDelete<SkStream> fSkStream;
+    uint32_t                fRefCnt;
+    uint32_t                fFontID;
 
-    // assumes ownership of the stream, will call unref() when its done
+    // assumes ownership of the stream, will delete when its done
     SkFaceRec(SkStream* strm, uint32_t fontID);
-    ~SkFaceRec() {
-        fSkStream->unref();
-    }
 };
 
 extern "C" {
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index 32e9f80..4c577d8 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -132,7 +132,7 @@
         // should have been provided by CreateFromStream()
         *ttcIndex = 0;
 
-        SkAutoTUnref<SkStream> dupStream(stream->duplicate());
+        SkAutoTDelete<SkStream> dupStream(stream->duplicate());
         if (dupStream) {
             return dupStream.detach();
         }
@@ -148,13 +148,10 @@
         SkAutoTMalloc<uint8_t> allocMemory(length);
         stream->rewind();
         if (length == stream->read(allocMemory.get(), length)) {
-            SkAutoTUnref<SkMemoryStream> copyStream(new SkMemoryStream());
+            SkAutoTDelete<SkMemoryStream> copyStream(new SkMemoryStream());
             copyStream->setMemoryOwned(allocMemory.detach(), length);
             return copyStream.detach();
         }
-
-        stream->rewind();
-        stream->ref();
     } else {
         SkAutoTUnref<SkFontConfigInterface> fci(RefFCI());
         if (NULL == fci.get()) {
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index ec8e338..b6fab62 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -139,7 +139,7 @@
 
 private:
     SkString fPath;
-    const SkAutoTUnref<SkStreamAsset> fStream;
+    const SkAutoTDelete<SkStreamAsset> fStream;
 
     typedef SkTypeface_Custom INHERITED;
 };
@@ -283,13 +283,12 @@
     }
 
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(new SkMemoryStream(data));
-        return this->createFromStream(stream, ttcIndex);
+        return this->createFromStream(new SkMemoryStream(data), ttcIndex);
     }
 
     SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTDelete<SkStream> streamDeleter(stream);
         if (NULL == stream || stream->getLength() <= 0) {
-            SkDELETE(stream);
             return NULL;
         }
 
@@ -298,15 +297,15 @@
         SkString name;
         if (fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
             return SkNEW_ARGS(SkTypeface_Stream, (style, isFixedPitch, false, name,
-                                                  stream, ttcIndex));
+                                                  streamDeleter.detach(), ttcIndex));
         } else {
             return NULL;
         }
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-        return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
+        SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
+        return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL;
     }
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
@@ -341,7 +340,7 @@
 
         while (iter.next(&name, false)) {
             SkString filename(SkOSPath::Join(directory.c_str(), name.c_str()));
-            SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(filename.c_str()));
+            SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(filename.c_str()));
             if (!stream.get()) {
                 SkDebugf("---- failed to open <%s>\n", filename.c_str());
                 continue;
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index 1ec2bb5..70f3ddf 100755
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -1924,6 +1924,7 @@
     return fontHandle;
 }
 
+// Does not affect ownership of stream.
 static SkTypeface* create_from_stream(SkStream* stream) {
     // Create a unique and unpredictable font name.
     // Avoids collisions and access from CSS.
@@ -2481,19 +2482,18 @@
     }
 
     SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTDelete<SkStream> streamDeleter(stream);
         return create_from_stream(stream);
     }
 
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
         // could be in base impl
-        SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
-        return this->createFromStream(stream);
+        return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data)));
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
         // could be in base impl
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-        return this->createFromStream(stream);
+        return this->createFromStream(SkStream::NewFromFile(path));
     }
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
diff --git a/src/ports/SkFontMgr_android.cpp b/src/ports/SkFontMgr_android.cpp
index 794790b..ce93194 100644
--- a/src/ports/SkFontMgr_android.cpp
+++ b/src/ports/SkFontMgr_android.cpp
@@ -104,7 +104,7 @@
                              bool isFixedPitch,
                              const SkString& familyName)
         : INHERITED(index, style, isFixedPitch, familyName)
-        , fStream(SkRef(stream)) { }
+        , fStream(stream) { }
 
     virtual void onGetFontDescriptor(SkFontDescriptor* desc,
                                      bool* serialize) const SK_OVERRIDE {
@@ -121,7 +121,7 @@
     }
 
 private:
-    SkAutoTUnref<SkStream> fStream;
+    SkAutoTDelete<SkStream> fStream;
 
     typedef SkTypeface_Android INHERITED;
 };
@@ -152,7 +152,7 @@
             SkString pathName;
             get_path_for_sys_fonts(basePath, fontFile.fFileName, &pathName);
 
-            SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(pathName.c_str()));
+            SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str()));
             if (!stream.get()) {
                 DEBUG_FONT(("---- SystemFonts[%d] file=%s (NOT EXIST)", i, pathName.c_str()));
                 continue;
@@ -409,23 +409,23 @@
     }
 
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(new SkMemoryStream(data));
-        return this->createFromStream(stream, ttcIndex);
+        return this->createFromStream(new SkMemoryStream(data), ttcIndex);
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-        return stream.get() ? this->createFromStream(stream, ttcIndex) : NULL;
+        SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
+        return stream.get() ? this->createFromStream(stream.detach(), ttcIndex) : NULL;
     }
 
     SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTDelete<SkStream> streamDeleter(stream);
         bool isFixedPitch;
         SkFontStyle style;
         SkString name;
         if (!fScanner.scanFont(stream, ttcIndex, &name, &style, &isFixedPitch)) {
             return NULL;
         }
-        return SkNEW_ARGS(SkTypeface_AndroidStream, (stream, ttcIndex,
+        return SkNEW_ARGS(SkTypeface_AndroidStream, (streamDeleter.detach(), ttcIndex,
                                                      style, isFixedPitch, name));
     }
 
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index b5e4eae..28df5d4 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -378,7 +378,7 @@
     /** @param stream does not take ownership of the reference, does take ownership of the stream.*/
     SkTypeface_stream(const SkFontStyle& style, bool fixedWidth, int index, SkStreamAsset* stream)
         : INHERITED(style, SkTypefaceCache::NewFontID(), fixedWidth)
-        , fStream(SkRef(stream))
+        , fStream(stream)
         , fIndex(index)
     { };
 
@@ -397,7 +397,7 @@
     }
 
 private:
-    SkAutoTUnref<SkStreamAsset> fStream;
+    SkAutoTDelete<SkStreamAsset> fStream;
     int fIndex;
 
     typedef SkTypeface_FreeType INHERITED;
@@ -809,8 +809,8 @@
         return this->matchFamilyStyle(get_string(fcTypeface->fPattern, FC_FAMILY), style);
     }
 
-    /** @param stream does not take ownership of the reference. */
-    SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE {
+    SkTypeface* onCreateFromStream(SkStream* inputStream, int ttcIndex) const SK_OVERRIDE {
+        SkAutoTDelete<SkStream> stream(inputStream);
         const size_t length = stream->getLength();
         if (length <= 0 || (1u << 30) < length) {
             return NULL;
@@ -823,17 +823,15 @@
         }
 
         return SkNEW_ARGS(SkTypeface_stream, (style, isFixedWidth, ttcIndex,
-                                              static_cast<SkStreamAsset*>(stream)));
+                                              static_cast<SkStreamAsset*>(stream.detach())));
     }
 
     SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStreamAsset> stream(SkNEW_ARGS(SkMemoryStream, (data)));
-        return this->createFromStream(stream, ttcIndex);
+        return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data)), ttcIndex);
     }
 
     SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE {
-        SkAutoTUnref<SkStreamAsset> stream(SkStream::NewFromFile(path));
-        return this->createFromStream(stream, ttcIndex);
+        return this->createFromStream(SkStream::NewFromFile(path), ttcIndex);
     }
 
     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
index e7ea980..31c1d3f 100644
--- a/src/ports/SkFontMgr_win_dw.cpp
+++ b/src/ports/SkFontMgr_win_dw.cpp
@@ -34,6 +34,7 @@
         UINT32 fontFileReferenceKeySize,
         IDWriteFontFileStream** fontFileStream);
 
+    // Takes ownership of stream.
     static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFileLoader) {
         *streamFontFileLoader = new StreamFontFileLoader(stream);
         if (NULL == streamFontFileLoader) {
@@ -42,10 +43,10 @@
         return S_OK;
     }
 
-    SkAutoTUnref<SkStream> fStream;
+    SkAutoTDelete<SkStream> fStream;
 
 private:
-    StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream)) { }
+    StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(stream) { }
     virtual ~StreamFontFileLoader() { }
 
     ULONG fRefCount;
@@ -80,7 +81,7 @@
     IDWriteFontFileStream** fontFileStream)
 {
     SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
-    HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream));
+    HR(SkDWriteFontFileStreamWrapper::Create(fStream->duplicate(), &stream));
     *fontFileStream = stream.release();
     return S_OK;
 }
@@ -535,6 +536,7 @@
 
 SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcIndex) const {
     SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
+    // This transfers ownership of stream to the new object.
     HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
     HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get()));
     SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
@@ -580,13 +582,11 @@
 }
 
 SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) const {
-    SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
-    return this->createFromStream(stream, ttcIndex);
+    return this->createFromStream(SkNEW_ARGS(SkMemoryStream, (data)), ttcIndex);
 }
 
 SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) const {
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
-    return this->createFromStream(stream, ttcIndex);
+    return this->createFromStream(SkStream::NewFromFile(path), ttcIndex);
 }
 
 HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[],
diff --git a/src/ports/SkImageDecoder_empty.cpp b/src/ports/SkImageDecoder_empty.cpp
index 069cf7f..e5ad6da 100644
--- a/src/ports/SkImageDecoder_empty.cpp
+++ b/src/ports/SkImageDecoder_empty.cpp
@@ -11,10 +11,9 @@
 #include "SkImageDecoder.h"
 #include "SkImageEncoder.h"
 #include "SkMovie.h"
+#include "SkStream.h"
 
 class SkColorTable;
-class SkStream;
-class SkStreamRewindable;
 
 // Empty implementations for SkImageDecoder.
 
@@ -48,6 +47,13 @@
     return false;
 }
 
+bool SkImageDecoder::onBuildTileIndex(SkStreamRewindable* stream,
+                                      int* /*width*/, int* /*height*/) {
+    SkDELETE(stream);
+    return false;
+}
+
+
 bool SkImageDecoder::decodeSubset(SkBitmap*, const SkIRect&, SkColorType) {
     return false;
 }
diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp
index 563a515..b777806 100644
--- a/src/ports/SkTypeface_win_dw.cpp
+++ b/src/ports/SkTypeface_win_dw.cpp
@@ -186,7 +186,7 @@
     }
 
     int ttcIndex;
-    SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
+    SkAutoTDelete<SkStream> stream(this->openStream(&ttcIndex));
     return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0;
 }
 
diff --git a/src/sfnt/SkOTUtils.h b/src/sfnt/SkOTUtils.h
index 51781b4..691bd76 100644
--- a/src/sfnt/SkOTUtils.h
+++ b/src/sfnt/SkOTUtils.h
@@ -33,6 +33,8 @@
       *  UnicodeBMPUCS2, and English_UnitedStates settings.
       *
       *  fontName and fontNameLen must be specified in terms of ASCII chars.
+      *
+      *  Does not affect fontData's ownership.
       */
     static SkData* RenameFont(SkStream* fontData, const char* fontName, int fontNameLen);
 
diff --git a/src/utils/SkFrontBufferedStream.cpp b/src/utils/SkFrontBufferedStream.cpp
index ad5ae6e..562d376 100644
--- a/src/utils/SkFrontBufferedStream.cpp
+++ b/src/utils/SkFrontBufferedStream.cpp
@@ -31,7 +31,7 @@
     SkStreamRewindable* duplicate() const SK_OVERRIDE { return NULL; }
 
 private:
-    SkAutoTUnref<SkStream>  fStream;
+    SkAutoTDelete<SkStream> fStream;
     const bool              fHasLength;
     const size_t            fLength;
     // Current offset into the stream. Always >= 0.
@@ -71,7 +71,7 @@
 }
 
 FrontBufferedStream::FrontBufferedStream(SkStream* stream, size_t bufferSize)
-    : fStream(SkRef(stream))
+    : fStream(stream)
     , fHasLength(stream->hasPosition() && stream->hasLength())
     , fLength(stream->getLength() - stream->getPosition())
     , fOffset(0)
diff --git a/src/utils/SkPDFRasterizer.cpp b/src/utils/SkPDFRasterizer.cpp
index 1cb792f..d44dfa3 100644
--- a/src/utils/SkPDFRasterizer.cpp
+++ b/src/utils/SkPDFRasterizer.cpp
@@ -27,6 +27,7 @@
 
 #ifdef SK_BUILD_POPPLER
 bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output) {
+  SkAutoTDelete<SkStream> streamDeleter(pdf);
   size_t size = pdf->getLength();
   SkAutoFree buffer(sk_malloc_throw(size));
   pdf->read(buffer.get(), size);
@@ -81,6 +82,7 @@
 
 #ifdef SK_BUILD_NATIVE_PDF_RENDERER
 bool SkNativeRasterizePDF(SkStream* pdf, SkBitmap* output) {
+    SkAutoTDelete<SkStream> streamDeleter(pdf);
     return SkPDFNativeRenderToBitmap(pdf, output);
 }
 #endif  // SK_BUILD_NATIVE_PDF_RENDERER
diff --git a/src/utils/SkPDFRasterizer.h b/src/utils/SkPDFRasterizer.h
index 82ec092..36bd086 100644
--- a/src/utils/SkPDFRasterizer.h
+++ b/src/utils/SkPDFRasterizer.h
@@ -11,10 +11,12 @@
 #include "SkStream.h"
 
 #ifdef SK_BUILD_POPPLER
+// Deletes pdf when finished.
 bool SkPopplerRasterizePDF(SkStream* pdf, SkBitmap* output);
 #endif  // SK_BUILD_POPPLER
 
 #ifdef SK_BUILD_NATIVE_PDF_RENDERER
+// Deletes pdf when finished.
 bool SkNativeRasterizePDF(SkStream* pdf, SkBitmap* output);
 #endif  // SK_BUILD_NATIVE_PDF_RENDERER
 
diff --git a/src/utils/mac/SkStream_mac.cpp b/src/utils/mac/SkStream_mac.cpp
index 64d2dbb..2688471 100644
--- a/src/utils/mac/SkStream_mac.cpp
+++ b/src/utils/mac/SkStream_mac.cpp
@@ -8,13 +8,21 @@
 #include "SkCGUtils.h"
 #include "SkStream.h"
 
-// This is used by CGDataProviderCreateWithData
+// These are used by CGDataProviderCreateWithData
 
 static void unref_proc(void* info, const void* addr, size_t size) {
     SkASSERT(info);
     ((SkRefCnt*)info)->unref();
 }
 
+static void delete_stream_proc(void* info, const void* addr, size_t size) {
+    SkASSERT(info);
+    SkStream* stream = (SkStream*)info;
+    SkASSERT(stream->getMemoryBase() == addr);
+    SkASSERT(stream->getLength() == size);
+    SkDELETE(stream);
+}
+
 // These are used by CGDataProviderSequentialCallbacks
 
 static size_t get_bytes_proc(void* info, void* buffer, size_t bytes) {
@@ -31,19 +39,20 @@
     ((SkStream*)info)->rewind();
 }
 
+// Used when info is an SkStream.
 static void release_info_proc(void* info) {
     SkASSERT(info);
-    ((SkStream*)info)->unref();
+    SkDELETE((SkStream*)info);
 }
 
 CGDataProviderRef SkCreateDataProviderFromStream(SkStream* stream) {
-    stream->ref();  // unref will be called when the provider is deleted
-
+    // TODO: Replace with SkStream::getData() when that is added. Then we only
+    // have one version of CGDataProviderCreateWithData (i.e. same release proc)
     const void* addr = stream->getMemoryBase();
     if (addr) {
         // special-case when the stream is just a block of ram
         return CGDataProviderCreateWithData(stream, addr, stream->getLength(),
-                                            unref_proc);
+                                            delete_stream_proc);
     }
 
     CGDataProviderSequentialCallbacks rec;
diff --git a/src/utils/win/SkDWriteFontFileStream.cpp b/src/utils/win/SkDWriteFontFileStream.cpp
index 0f0c628..5569db5 100644
--- a/src/utils/win/SkDWriteFontFileStream.cpp
+++ b/src/utils/win/SkDWriteFontFileStream.cpp
@@ -142,7 +142,7 @@
 }
 
 SkDWriteFontFileStreamWrapper::SkDWriteFontFileStreamWrapper(SkStream* stream)
-    : fRefCount(1), fStream(SkRef(stream)) {
+    : fRefCount(1), fStream(stream) {
 }
 
 HRESULT STDMETHODCALLTYPE SkDWriteFontFileStreamWrapper::QueryInterface(REFIID iid, void** ppvObject) {
diff --git a/src/utils/win/SkDWriteFontFileStream.h b/src/utils/win/SkDWriteFontFileStream.h
index 1800e2f..a7e4125 100644
--- a/src/utils/win/SkDWriteFontFileStream.h
+++ b/src/utils/win/SkDWriteFontFileStream.h
@@ -71,7 +71,7 @@
     virtual ~SkDWriteFontFileStreamWrapper() { }
 
     ULONG fRefCount;
-    SkAutoTUnref<SkStream> fStream;
+    SkAutoTDelete<SkStream> fStream;
     SkMutex fStreamMutex;
 };
 #endif
diff --git a/src/views/animated/SkWidgetViews.cpp b/src/views/animated/SkWidgetViews.cpp
index 8e7f517..cd22678 100644
--- a/src/views/animated/SkWidgetViews.cpp
+++ b/src/views/animated/SkWidgetViews.cpp
@@ -42,7 +42,7 @@
 void init_skin_anim(const char path[], SkAnimator* anim) {
     SkASSERT(path && anim);
 
-    SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
+    SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
     if (!stream.get()) {
         SkDEBUGF(("init_skin_anim: loading skin failed <%s>\n", path));
         sk_throw();