1
2/*
3 * Copyright 2010 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#include "SkData.h"
11#include "SkDeflate.h"
12#include "SkPDFStream.h"
13#include "SkStream.h"
14#include "SkStreamPriv.h"
15
16SkPDFStream::~SkPDFStream() {}
17
18void SkPDFStream::emitObject(SkWStream* stream,
19                             const SkPDFObjNumMap& objNumMap,
20                             const SkPDFSubstituteMap& substitutes) const {
21    SkASSERT(fCompressedData);
22    this->INHERITED::emitObject(stream, objNumMap, substitutes);
23    // duplicate (a cheap operation) preserves const on fCompressedData.
24    SkAutoTDelete<SkStreamRewindable> dup(fCompressedData->duplicate());
25    SkASSERT(dup);
26    SkASSERT(dup->hasLength());
27    stream->writeText(" stream\n");
28    stream->writeStream(dup.get(), dup->getLength());
29    stream->writeText("\nendstream");
30}
31
32void SkPDFStream::setData(SkStream* stream) {
33    SkASSERT(!fCompressedData);  // Only call this function once.
34    SkASSERT(stream);
35    // Code assumes that the stream starts at the beginning.
36
37    SkDynamicMemoryWStream compressedData;
38    SkDeflateWStream deflateWStream(&compressedData);
39    SkStreamCopy(&deflateWStream, stream);
40    deflateWStream.finalize();
41    size_t length = compressedData.bytesWritten();
42
43    if (stream->hasLength()) {
44        SkAutoTDelete<SkStreamRewindable> dup(stream->duplicate());
45        if (dup && dup->hasLength() &&
46            dup->getLength() <= length + strlen("/Filter_/FlateDecode_")) {
47            this->insertInt("Length", dup->getLength());
48            fCompressedData.reset(dup.detach());
49            return;
50        }
51    }
52    fCompressedData.reset(compressedData.detachAsStream());
53    this->insertName("Filter", "FlateDecode");
54    this->insertInt("Length", length);
55}
56