aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkStream.h5
-rw-r--r--src/core/SkStream.cpp24
-rw-r--r--src/pdf/SkPDFBitmap.cpp7
-rw-r--r--src/pdf/SkPDFTypes.cpp2
4 files changed, 30 insertions, 8 deletions
diff --git a/include/core/SkStream.h b/include/core/SkStream.h
index b4875adda6..01fd82a530 100644
--- a/include/core/SkStream.h
+++ b/include/core/SkStream.h
@@ -384,11 +384,14 @@ public:
/** More efficient version of read(dst, 0, bytesWritten()). */
void copyTo(void* dst) const;
- void writeToStream(SkWStream* dst) const;
+ bool writeToStream(SkWStream* dst) const;
/** Equivalent to copyTo() followed by reset(), but may save memory use. */
void copyToAndReset(void* dst);
+ /** Equivalent to writeToStream() followed by reset(), but may save memory use. */
+ bool writeToAndReset(SkWStream* dst);
+
/** Return the contents as SkData, and then reset the stream. */
sk_sp<SkData> detachAsData();
diff --git a/src/core/SkStream.cpp b/src/core/SkStream.cpp
index ef86bc963e..7bb2079f7f 100644
--- a/src/core/SkStream.cpp
+++ b/src/core/SkStream.cpp
@@ -545,10 +545,13 @@ void SkDynamicMemoryWStream::copyTo(void* dst) const {
}
}
-void SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
+bool SkDynamicMemoryWStream::writeToStream(SkWStream* dst) const {
for (Block* block = fHead; block != nullptr; block = block->fNext) {
- dst->write(block->start(), block->written());
+ if (!dst->write(block->start(), block->written())) {
+ return false;
+ }
}
+ return true;
}
void SkDynamicMemoryWStream::padToAlign4() {
@@ -584,6 +587,23 @@ void SkDynamicMemoryWStream::copyToAndReset(void* ptr) {
fBytesWrittenBeforeTail = 0;
}
+bool SkDynamicMemoryWStream::writeToAndReset(SkWStream* dst) {
+ // By looping through the source and freeing as we copy, we
+ // can reduce real memory use with large streams.
+ bool dstStreamGood = true;
+ for (Block* block = fHead; block != nullptr; ) {
+ if (dstStreamGood && !dst->write(block->start(), block->written())) {
+ dstStreamGood = false;
+ }
+ Block* next = block->fNext;
+ sk_free(block);
+ block = next;
+ }
+ fHead = fTail = nullptr;
+ fBytesWrittenBeforeTail = 0;
+ return dstStreamGood;
+}
+
sk_sp<SkData> SkDynamicMemoryWStream::detachAsData() {
const size_t size = this->bytesWritten();
if (0 == size) {
diff --git a/src/pdf/SkPDFBitmap.cpp b/src/pdf/SkPDFBitmap.cpp
index b58aaf48a5..d5eb19e552 100644
--- a/src/pdf/SkPDFBitmap.cpp
+++ b/src/pdf/SkPDFBitmap.cpp
@@ -356,8 +356,7 @@ static void emit_image_xobject(SkWStream* stream,
} else {
bitmap_to_pdf_pixels(bitmap, &deflateWStream);
}
- deflateWStream.finalize(); // call before detachAsStream().
- std::unique_ptr<SkStreamAsset> asset(buffer.detachAsStream());
+ deflateWStream.finalize(); // call before buffer.bytesWritten().
SkPDFDict pdfDict("XObject");
pdfDict.insertName("Subtype", "Image");
@@ -380,11 +379,11 @@ static void emit_image_xobject(SkWStream* stream,
}
pdfDict.insertInt("BitsPerComponent", 8);
pdfDict.insertName("Filter", "FlateDecode");
- pdfDict.insertInt("Length", asset->getLength());
+ pdfDict.insertInt("Length", buffer.bytesWritten());
pdfDict.emitObject(stream, objNumMap);
pdf_stream_begin(stream);
- stream->writeStream(asset.get(), asset->getLength());
+ buffer.writeToAndReset(stream);
pdf_stream_end(stream);
}
diff --git a/src/pdf/SkPDFTypes.cpp b/src/pdf/SkPDFTypes.cpp
index c66c80a6bc..2559f93106 100644
--- a/src/pdf/SkPDFTypes.cpp
+++ b/src/pdf/SkPDFTypes.cpp
@@ -489,7 +489,7 @@ void SkPDFSharedStream::emitObject(
SkPDFUnion::Name("FlateDecode").emitObject(stream, objNumMap);
stream->writeText(">>");
stream->writeText(" stream\n");
- buffer.writeToStream(stream);
+ buffer.writeToAndReset(stream);
stream->writeText("\nendstream");
}
#endif