OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2013 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkPdfNativeObject.h" | |
9 | |
10 #include "SkBitmap.h" | |
11 #include "SkFlate.h" | |
12 #include "SkPdfFont.h" | |
13 #include "SkPdfNativeTokenizer.h" | |
14 #include "SkPdfReporter.h" | |
15 #include "SkStream.h" | |
16 | |
17 // TODO(edisonn): mac builder does not find the header ... but from headers is o
k | |
18 //#include "SkPdfStreamCommonDictionary_autogen.h" | |
19 #include "SkPdfHeaders_autogen.h" | |
20 | |
21 | |
22 SkPdfNativeObject SkPdfNativeObject::kNull = SkPdfNativeObject::makeNull(); | |
23 | |
24 bool SkPdfNativeObject::applyFlateDecodeFilter() { | |
25 const unsigned char* old = fStr.fBuffer; | |
26 bool deleteOld = isStreamOwned(); | |
27 | |
28 SkMemoryStream skstream(fStr.fBuffer, fStr.fBytes >> 2, false); | |
29 SkDynamicMemoryWStream uncompressedData; | |
30 | |
31 if (SkFlate::Inflate(&skstream, &uncompressedData)) { | |
32 fStr.fBytes = (uncompressedData.bytesWritten() << 2) + kOwnedStreamBit + | |
33 kUnfilteredStreamBit; | |
34 fStr.fBuffer = (const unsigned char*)new unsigned char[uncompressedData.
bytesWritten()]; | |
35 uncompressedData.copyTo((void*)fStr.fBuffer); | |
36 | |
37 if (deleteOld) { | |
38 delete[] old; | |
39 } | |
40 | |
41 return true; | |
42 } else { | |
43 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "inf
late failed", this, NULL); | |
44 return false; | |
45 } | |
46 } | |
47 | |
48 bool SkPdfNativeObject::applyDCTDecodeFilter() { | |
49 // applyDCTDecodeFilter will fail, and it won't allow any more filters. | |
50 // technically, it would be possible, but not a real world scenario. | |
51 // in this way we create the image from the DCT stream directly. | |
52 return false; | |
53 } | |
54 | |
55 bool SkPdfNativeObject::applyFilter(const char* name) { | |
56 if (strcmp(name, "FlateDecode") == 0) { | |
57 return applyFlateDecodeFilter(); | |
58 } else if (strcmp(name, "DCTDecode") == 0) { | |
59 return applyDCTDecodeFilter(); | |
60 } | |
61 SkPdfReport(kCodeWarning_SkPdfIssueSeverity, kNYI_SkPdfIssue, "filter not su
pported", this, | |
62 NULL); | |
63 return false; | |
64 } | |
65 | |
66 bool SkPdfNativeObject::filterStream() { | |
67 SkPdfMarkObjectUsed(); | |
68 | |
69 if (!hasStream()) { | |
70 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kBadStream_SkPdfIssue, "No
Stream", this, | |
71 NULL); | |
72 return false; | |
73 } | |
74 | |
75 if (isStreamFiltered()) { | |
76 return true; | |
77 } | |
78 | |
79 SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*)this; | |
80 | |
81 if (!stream->has_Filter()) { | |
82 fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit; | |
83 } else if (stream->isFilterAName(NULL)) { | |
84 SkString filterName = stream->getFilterAsName(NULL); | |
85 applyFilter(filterName.c_str()); | |
86 } else if (stream->isFilterAArray(NULL)) { | |
87 const SkPdfArray* filters = stream->getFilterAsArray(NULL); | |
88 int cnt = (int) filters->size(); | |
89 for (int i = cnt - 1; i >= 0; i--) { | |
90 const SkPdfNativeObject* filterName = filters->objAtAIndex(i); | |
91 if (filterName != NULL && filterName->isName()) { | |
92 if (!applyFilter(filterName->nameValue())) { | |
93 break; | |
94 } | |
95 } else { | |
96 SkPdfReport(kIgnoreError_SkPdfIssueSeverity, kIncositentSyntax_S
kPdfIssue, | |
97 "filter name should be a Name", this, NULL); | |
98 } | |
99 } | |
100 } | |
101 | |
102 return true; | |
103 } | |
104 | |
105 void SkPdfNativeObject::releaseData() { | |
106 #ifdef PDF_TRACK_OBJECT_USAGE | |
107 SkPdfReportIf(!fUsed, kInfo_SkPdfIssueSeverity, kUnusedObject_SkPdfIssue, | |
108 "Unused object in rendering", this, NULL); | |
109 #endif // PDF_TRACK_OBJECT_USAGE | |
110 | |
111 SkPdfMarkObjectUnused(); | |
112 | |
113 if (fData) { | |
114 switch (fDataType) { | |
115 case kFont_Data: | |
116 delete (SkPdfFont*)fData; | |
117 break; | |
118 case kBitmap_Data: | |
119 delete (SkBitmap*)fData; | |
120 break; | |
121 default: | |
122 SkASSERT(false); | |
123 break; | |
124 } | |
125 } | |
126 fData = NULL; | |
127 fDataType = kEmpty_Data; | |
128 } | |
OLD | NEW |