blob: 4aeb2dbe1ec5694c49d7605d9ca7a1459cac0345 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2010 Google Inc.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00004 *
epoger@google.comec3ed6a2011-07-28 14:26:00 +00005 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +00007 */
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@google.com8a85d0c2011-06-24 19:12:12 +000010#include "SkData.h"
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000011#include "SkFlate.h"
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000012#include "SkPDFCatalog.h"
13#include "SkPDFStream.h"
14#include "SkStream.h"
halcanary67ec1f82014-06-27 11:36:20 -070015#include "SkStreamPriv.h"
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000016
vandebo@chromium.org26e14492013-08-26 22:52:09 +000017SkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
halcanary67ec1f82014-06-27 11:36:20 -070018 this->setData(stream);
vandebo@chromium.org421d6442011-07-20 17:39:01 +000019}
20
21SkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
halcanary67ec1f82014-06-27 11:36:20 -070022 this->setData(data);
vandebo@chromium.org421d6442011-07-20 17:39:01 +000023}
24
25SkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
26 : SkPDFDict(),
vandebo@chromium.org26e14492013-08-26 22:52:09 +000027 fState(kUnused_State) {
halcanarye3224822014-07-14 09:12:12 -070028 this->setData(pdfStream.fDataStream.get());
vandebo@chromium.org421d6442011-07-20 17:39:01 +000029 bool removeLength = true;
30 // Don't uncompress an already compressed stream, but we could.
31 if (pdfStream.fState == kCompressed_State) {
32 fState = kCompressed_State;
33 removeLength = false;
vandebo@chromium.orga09ef972010-12-01 22:17:20 +000034 }
halcanary1f8ed022014-06-27 10:37:27 -070035 this->mergeFrom(pdfStream);
36 if (removeLength) {
37 this->remove("Length");
vandebo@chromium.org421d6442011-07-20 17:39:01 +000038 }
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000039}
40
vandebo@chromium.org421d6442011-07-20 17:39:01 +000041SkPDFStream::~SkPDFStream() {}
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000042
halcanary4fc48af2015-01-12 10:07:50 -080043void SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog) {
halcanary67ec1f82014-06-27 11:36:20 -070044 SkAutoMutexAcquire lock(fMutex); // multiple threads could be calling emit
vandebo@chromium.org421d6442011-07-20 17:39:01 +000045 if (!this->populate(catalog)) {
halcanary4fc48af2015-01-12 10:07:50 -080046 return fSubstitute->emitObject(stream, catalog);
vandebo@chromium.org421d6442011-07-20 17:39:01 +000047 }
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000048
halcanary4fc48af2015-01-12 10:07:50 -080049 this->INHERITED::emitObject(stream, catalog);
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000050 stream->writeText(" stream\n");
halcanarye3224822014-07-14 09:12:12 -070051 stream->writeStream(fDataStream.get(), fDataStream->getLength());
52 SkAssertResult(fDataStream->rewind());
vandebo@chromium.org9b49dc02010-10-20 22:23:29 +000053 stream->writeText("\nendstream");
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +000054}
55
vandebo@chromium.org421d6442011-07-20 17:39:01 +000056SkPDFStream::SkPDFStream() : fState(kUnused_State) {}
57
commit-bot@chromium.orgd8d976e2013-07-08 23:17:57 +000058void SkPDFStream::setData(SkData* data) {
scroggoa1193e42015-01-21 12:09:53 -080059 // FIXME: Don't swap if the data is the same.
60 fDataStream.reset(SkNEW_ARGS(SkMemoryStream, (data)));
commit-bot@chromium.orgd8d976e2013-07-08 23:17:57 +000061}
62
vandebo@chromium.org421d6442011-07-20 17:39:01 +000063void SkPDFStream::setData(SkStream* stream) {
vandebo@chromium.org26e14492013-08-26 22:52:09 +000064 // Code assumes that the stream starts at the beginning and is rewindable.
65 if (stream) {
halcanarye3224822014-07-14 09:12:12 -070066 // SkStreamRewindableFromSkStream will try stream->duplicate().
67 fDataStream.reset(SkStreamRewindableFromSkStream(stream));
68 SkASSERT(fDataStream.get());
halcanary67ec1f82014-06-27 11:36:20 -070069 } else {
scroggoa1193e42015-01-21 12:09:53 -080070 // Use an empty memory stream.
71 fDataStream.reset(SkNEW(SkMemoryStream));
vandebo@chromium.org26e14492013-08-26 22:52:09 +000072 }
halcanary67ec1f82014-06-27 11:36:20 -070073}
74
75size_t SkPDFStream::dataSize() const {
halcanarye3224822014-07-14 09:12:12 -070076 SkASSERT(fDataStream->hasLength());
77 return fDataStream->getLength();
vandebo@chromium.org421d6442011-07-20 17:39:01 +000078}
79
80bool SkPDFStream::populate(SkPDFCatalog* catalog) {
halcanary91d1d622015-02-17 14:43:06 -080081#ifdef SK_NO_FLATE
vandebo@chromium.org421d6442011-07-20 17:39:01 +000082 if (fState == kUnused_State) {
halcanary91d1d622015-02-17 14:43:06 -080083 fState = kNoCompression_State;
84 insertInt("Length", this->dataSize());
85 }
86 return true;
87
88#else // !SK_NO_FLATE
89
90 if (fState == kUnused_State) {
91 fState = kNoCompression_State;
mtkleincabc08c2015-02-19 08:29:24 -080092 SkDynamicMemoryWStream compressedData;
vandebo@chromium.org421d6442011-07-20 17:39:01 +000093
mtkleincabc08c2015-02-19 08:29:24 -080094 SkAssertResult(
95 SkFlate::Deflate(fDataStream.get(), &compressedData));
96 SkAssertResult(fDataStream->rewind());
97 if (compressedData.getOffset() < this->dataSize()) {
98 SkAutoTDelete<SkStream> compressed(
99 compressedData.detachAsStream());
100 this->setData(compressed.get());
101 insertName("Filter", "FlateDecode");
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000102 }
mtkleincabc08c2015-02-19 08:29:24 -0800103 fState = kCompressed_State;
halcanary67ec1f82014-06-27 11:36:20 -0700104 insertInt("Length", this->dataSize());
halcanary91d1d622015-02-17 14:43:06 -0800105 }
mtkleincabc08c2015-02-19 08:29:24 -0800106 else if (fState == kNoCompression_State) {
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000107 if (!fSubstitute.get()) {
vandebo@chromium.orgd96d17b2013-01-04 19:31:24 +0000108 fSubstitute.reset(new SkPDFStream(*this));
vandebo@chromium.org421d6442011-07-20 17:39:01 +0000109 catalog->setSubstitute(this, fSubstitute.get());
110 }
111 return false;
112 }
113 return true;
halcanary91d1d622015-02-17 14:43:06 -0800114#endif // SK_NO_FLATE
vandebo@chromium.org8459d4e2010-09-24 22:25:30 +0000115}