180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2010 Google Inc.
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkData.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlate.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFCatalog.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPDFStream.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkStream.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool skip_compression(SkPDFCatalog* catalog) {
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkToBool(catalog->getDocumentFlags() &
18096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                    SkPDFDocument::kFavorSpeedOverSize_Flags);
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21e6457fed254b8df289f225625f262c7e0cc75cddDerek SollenbergerSkPDFStream::SkPDFStream(SkStream* stream) : fState(kUnused_State) {
22e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    setData(stream);
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPDFStream::SkPDFStream(SkData* data) : fState(kUnused_State) {
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    setData(data);
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPDFStream::SkPDFStream(const SkPDFStream& pdfStream)
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        : SkPDFDict(),
31e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger          fState(kUnused_State) {
32e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    setData(pdfStream.fData.get());
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool removeLength = true;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Don't uncompress an already compressed stream, but we could.
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (pdfStream.fState == kCompressed_State) {
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fState = kCompressed_State;
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        removeLength = false;
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPDFDict::Iter dict(pdfStream);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPDFName* key;
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPDFObject* value;
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPDFName lengthName("Length");
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (key = dict.next(&value); key != NULL; key = dict.next(&value)) {
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (removeLength && *key == lengthName) {
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            continue;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->insert(key, value);
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPDFStream::~SkPDFStream() {}
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFStream::emitObject(SkWStream* stream, SkPDFCatalog* catalog,
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             bool indirect) {
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (indirect) {
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return emitIndirectObject(stream, catalog);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!this->populate(catalog)) {
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fSubstitute->emitObject(stream, catalog, indirect);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::emitObject(stream, catalog, false);
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->writeText(" stream\n");
6419dc01fba9641c01a710b5e2aea844f313cbc5e1Derek Sollenberger    stream->writeStream(fData.get(), fData->getLength());
65e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    fData->rewind();
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    stream->writeText("\nendstream");
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t SkPDFStream::getOutputSize(SkPDFCatalog* catalog, bool indirect) {
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (indirect) {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return getIndirectOutputSize(catalog);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!this->populate(catalog)) {
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return fSubstitute->getOutputSize(catalog, indirect);
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return this->INHERITED::getOutputSize(catalog, false) +
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        strlen(" stream\n\nendstream") + fData->getLength();
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPDFStream::SkPDFStream() : fState(kUnused_State) {}
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid SkPDFStream::setData(SkData* data) {
8458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkMemoryStream* stream = new SkMemoryStream;
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    stream->setData(data);
8658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    fData.reset(stream);  // Transfer ownership.
8758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
8858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPDFStream::setData(SkStream* stream) {
90e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    // Code assumes that the stream starts at the beginning and is rewindable.
91e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    if (stream) {
92e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger        SkASSERT(stream->getPosition() == 0);
93e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger        SkASSERT(stream->rewind());
94e6457fed254b8df289f225625f262c7e0cc75cddDerek Sollenberger    }
95d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    fData.reset(stream);
96d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    SkSafeRef(stream);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkPDFStream::populate(SkPDFCatalog* catalog) {
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fState == kUnused_State) {
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!skip_compression(catalog) && SkFlate::HaveFlate()) {
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkDynamicMemoryWStream compressedData;
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            SkAssertResult(SkFlate::Deflate(fData.get(), &compressedData));
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            if (compressedData.getOffset() < fData->getLength()) {
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                SkMemoryStream* stream = new SkMemoryStream;
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                stream->setData(compressedData.copyToData())->unref();
108d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                fData.reset(stream);  // Transfer ownership.
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                insertName("Filter", "FlateDecode");
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fState = kCompressed_State;
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fState = kNoCompression_State;
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        insertInt("Length", fData->getLength());
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else if (fState == kNoCompression_State && !skip_compression(catalog) &&
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru               SkFlate::HaveFlate()) {
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!fSubstitute.get()) {
119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            fSubstitute.reset(new SkPDFStream(*this));
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            catalog->setSubstitute(this, fSubstitute.get());
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
126