1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/* 2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright 2013 Google Inc. 3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * 4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Use of this source code is governed by a BSD-style license that can be 5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * found in the LICENSE file. 6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com */ 7571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 83aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com#include "SkPdfNativeObject.h" 933f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com 10c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkBitmap.h" 11571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include "SkFlate.h" 12c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfFont.h" 13571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include "SkPdfNativeTokenizer.h" 14c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfReporter.h" 15c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkStream.h" 16571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 17c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// TODO(edisonn): mac builder does not find the header ... but from headers is ok 18c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com//#include "SkPdfStreamCommonDictionary_autogen.h" 19c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfHeaders_autogen.h" 20b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 21af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 22598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comSkPdfNativeObject SkPdfNativeObject::kNull = SkPdfNativeObject::makeNull(); 23571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 243aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.combool SkPdfNativeObject::applyFlateDecodeFilter() { 25571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!SkFlate::HaveFlate()) { 26c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kNoFlateLibrary_SkPdfIssue, 27c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com "forgot to link with flate library?", NULL, NULL); 28571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 29571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 30571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 312ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* old = fStr.fBuffer; 322ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com bool deleteOld = isStreamOwned(); 332ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 342ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com SkMemoryStream skstream(fStr.fBuffer, fStr.fBytes >> 2, false); 35571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkDynamicMemoryWStream uncompressedData; 36571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 37571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (SkFlate::Inflate(&skstream, &uncompressedData)) { 38c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fStr.fBytes = (uncompressedData.bytesWritten() << 2) + kOwnedStreamBit + 39c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com kUnfilteredStreamBit; 402ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com fStr.fBuffer = (const unsigned char*)new unsigned char[uncompressedData.bytesWritten()]; 412ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com uncompressedData.copyTo((void*)fStr.fBuffer); 422ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 432ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (deleteOld) { 442ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com delete[] old; 452ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } 462ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 47571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return true; 48571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 49af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "inflate failed", this, NULL); 50571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 51571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 52571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 53571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 543aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.combool SkPdfNativeObject::applyDCTDecodeFilter() { 55c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // applyDCTDecodeFilter will fail, and it won't allow any more filters. 56c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // technically, it would be possible, but not a real world scenario. 57c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // in this way we create the image from the DCT stream directly. 58571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 59571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 60571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 613aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.combool SkPdfNativeObject::applyFilter(const char* name) { 62571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (strcmp(name, "FlateDecode") == 0) { 632ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com return applyFlateDecodeFilter(); 64571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else if (strcmp(name, "DCTDecode") == 0) { 652ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com return applyDCTDecodeFilter(); 66571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 67c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "filter not supported", this, 68c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com NULL); 69571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 70571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 71571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 723aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.combool SkPdfNativeObject::filterStream() { 730fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com SkPdfMarkObjectUsed(); 740fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com 75571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!hasStream()) { 76c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "No Stream", this, 77c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com NULL); 78571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 79571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 80571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 81571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (isStreamFiltered()) { 82571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return true; 83571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 84571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 85571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*)this; 86571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 87571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (!stream->has_Filter()) { 88571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit; 892ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else if (stream->isFilterAName(NULL)) { 90063d7072ef45971c17045721626b3f0cd052b3b9edisonn@google.com SkString filterName = stream->getFilterAsName(NULL); 912ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com applyFilter(filterName.c_str()); 92571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else if (stream->isFilterAArray(NULL)) { 93571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com const SkPdfArray* filters = stream->getFilterAsArray(NULL); 945f008652f69ce7809b920b9fa573bc72216acd51scroggo@google.com int cnt = (int) filters->size(); 95571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com for (int i = cnt - 1; i >= 0; i--) { 963aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com const SkPdfNativeObject* filterName = filters->objAtAIndex(i); 97571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (filterName != NULL && filterName->isName()) { 982ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (!applyFilter(filterName->nameValue())) { 99571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 100571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 101571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 102c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncositentSyntax_SkPdfIssue, 103c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com "filter name should be a Name", this, NULL); 104571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 105571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 106571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 107571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 108571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return true; 109571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 110b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com 1113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comvoid SkPdfNativeObject::releaseData() { 112af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com#ifdef PDF_TRACK_OBJECT_USAGE 1137d8013f3064cd202f5a2344a1ab1860fd7511bb3scroggo@google.com SkPdfReportIf(!fUsed, kInfo_SkPdfIssueSeverity, kUnusedObject_SkPdfIssue, 114c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com "Unused object in rendering", this, NULL); 115af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com#endif // PDF_TRACK_OBJECT_USAGE 1160fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com 1170fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com SkPdfMarkObjectUnused(); 1180fd25d8b22ae092183f3dc67dec4c0c1bbde06bfedisonn@google.com 119b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com if (fData) { 120b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com switch (fDataType) { 121b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com case kFont_Data: 122b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com delete (SkPdfFont*)fData; 123b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com break; 124b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com case kBitmap_Data: 125b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com delete (SkBitmap*)fData; 126b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com break; 127b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com default: 128b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com SkASSERT(false); 129b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com break; 130b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 131b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com } 132b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com fData = NULL; 133b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com fDataType = kEmpty_Data; 134b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com} 135