summaryrefslogtreecommitdiff
path: root/pdf/SkPDFStream.cpp
diff options
context:
space:
mode:
authorBaligh Uddin <baligh@google.com>2013-11-01 16:01:55 -0700
committerBaligh Uddin <baligh@google.com>2013-11-01 16:01:55 -0700
commitec502fb532582da0f3141560bc451df3902ce463 (patch)
treebfd8e692b73dee4749734ca317b4707988dfae3a /pdf/SkPDFStream.cpp
parent5588ded0ae11d6fa36e1771747b82b7831db906b (diff)
parent53a521c76400a3e6d64dc96396390b746ec1e48e (diff)
downloadsrc-ec502fb532582da0f3141560bc451df3902ce463.tar.gz
Merge remote-tracking branch 'origin/kitkat-dev'chromium_org-pre-replicationidea133
Diffstat (limited to 'pdf/SkPDFStream.cpp')
-rw-r--r--pdf/SkPDFStream.cpp125
1 files changed, 125 insertions, 0 deletions
diff --git a/pdf/SkPDFStream.cpp b/pdf/SkPDFStream.cpp
new file mode 100644
index 00000000..e5709764
--- /dev/null
+++ b/pdf/SkPDFStream.cpp
@@ -0,0 +1,125 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkData.h"
+#include "SkFlate.h"
+#include "SkPDFCatalog.h"
+#include "SkPDFStream.h"
+#include "SkStream.h"
+
+static bool skip_compression(SkPDFCatalog* catalog) {
+ return SkToBool(catalog->getDocumentFlags() &
+ SkPDFDocument::kFavorSpeedOverSize_Flags);
+}
+
+SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
+ setData(stream);
+}
+
+SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
+ setData(data);
+}
+
+SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
+ : SkPDFDict(),
+ fState(kUnused_State) {
+ setData(pdfStream.fData.get());
+ bool removeLength = true;
+ // Don't uncompress an already compressed stream, but we could.
+ if (pdfStream.fState == kCompressed_State) {
+ fState = kCompressed_State;
+ removeLength = false;
+ }
+ SkPDFDict::Iter dict(pdfStream);
+ SkPDFName* key;
+ SkPDFObject* value;
+ SkPDFName lengthName("Length");
+ for (key = dict.next(&value); key != NULL; key = dict.next(&value)) {
+ if (removeLength && *key == lengthName) {
+ continue;
+ }
+ this->insert(key, value);
+ }
+}
+
+SkPDFStream::~SkPDFStream() {}
+
+void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
+ bool indirect) {
+ if (indirect) {
+ return emitIndirectObject(stream, catalog);
+ }
+ if (!this->populate(catalog)) {
+ return fSubstitute->emitObject(stream, catalog, indirect);
+ }
+
+ this->INHERITED::emitObject(stream, catalog, false);
+ stream->writeText(" stream\n");
+ stream->writeStream(fData.get(), fData->getLength());
+ fData->rewind();
+ stream->writeText("\nendstream");
+}
+
+size_t SkPDFStream::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
+ if (indirect) {
+ return getIndirectOutputSize(catalog);
+ }
+ if (!this->populate(catalog)) {
+ return fSubstitute->getOutputSize(catalog, indirect);
+ }
+
+ return this->INHERITED::getOutputSize(catalog, false) +
+ strlen(" stream\n\nendstream") + fData->getLength();
+}
+
+SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
+
+void SkPDFStream::setData(SkData* data) {
+ SkMemoryStream* stream = new SkMemoryStream;
+ stream->setData(data);
+ fData.reset(stream); // Transfer ownership.
+}
+
+void SkPDFStream::setData(SkStream* stream) {
+ // Code assumes that the stream starts at the beginning and is rewindable.
+ if (stream) {
+ SkASSERT(stream->getPosition() == 0);
+ SkASSERT(stream->rewind());
+ }
+ fData.reset(stream);
+ SkSafeRef(stream);
+}
+
+bool SkPDFStream::populate(SkPDFCatalog* catalog) {
+ if (fState == kUnused_State) {
+ if (!skip_compression(catalog) && SkFlate::HaveFlate()) {
+ SkDynamicMemoryWStream compressedData;
+
+ SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
+ if (compressedData.getOffset() < fData->getLength()) {
+ SkMemoryStream* stream = new SkMemoryStream;
+ stream->setData(compressedData.copyToData())->unref();
+ fData.reset(stream); // Transfer ownership.
+ insertName("Filter", "FlateDecode");
+ }
+ fState = kCompressed_State;
+ } else {
+ fState = kNoCompression_State;
+ }
+ insertInt("Length", fData->getLength());
+ } else if (fState == kNoCompression_State && !skip_compression(catalog) &&
+ SkFlate::HaveFlate()) {
+ if (!fSubstitute.get()) {
+ fSubstitute.reset(new SkPDFStream(*this));
+ catalog->setSubstitute(this, fSubstitute.get());
+ }
+ return false;
+ }
+ return true;
+}