OLD | NEW |
| (Empty) |
1 | |
2 #include "SkPdfObject.h" | |
3 #include "SkPdfStreamCommonDictionary_autogen.h" | |
4 | |
5 #include "SkFlate.h" | |
6 #include "SkStream.h" | |
7 #include "SkPdfNativeTokenizer.h" | |
8 | |
9 #include "SkBitmap.h" | |
10 #include "SkPdfFont.h" | |
11 | |
12 SkPdfObject SkPdfObject::kNull = SkPdfObject::makeNull(); | |
13 | |
14 bool SkPdfObject::applyFlateDecodeFilter() { | |
15 if (!SkFlate::HaveFlate()) { | |
16 // TODO(edisonn): warn, make callers handle it | |
17 return false; | |
18 } | |
19 | |
20 const unsigned char* old = fStr.fBuffer; | |
21 bool deleteOld = isStreamOwned(); | |
22 | |
23 SkMemoryStream skstream(fStr.fBuffer, fStr.fBytes >> 2, false); | |
24 SkDynamicMemoryWStream uncompressedData; | |
25 | |
26 if (SkFlate::Inflate(&skstream, &uncompressedData)) { | |
27 fStr.fBytes = (uncompressedData.bytesWritten() << 2) + kOwnedStreamBit +
kUnfilteredStreamBit; | |
28 fStr.fBuffer = (const unsigned char*)new unsigned char[uncompressedData.
bytesWritten()]; | |
29 uncompressedData.copyTo((void*)fStr.fBuffer); | |
30 | |
31 if (deleteOld) { | |
32 delete[] old; | |
33 } | |
34 | |
35 return true; | |
36 } else { | |
37 // TODO(edisonn): warn, make callers handle it | |
38 return false; | |
39 } | |
40 } | |
41 | |
42 bool SkPdfObject::applyDCTDecodeFilter() { | |
43 // this would fail, and it won't allow any more filters. | |
44 // technically, it would be possible, but not a real world scenario | |
45 // TODO(edisonn): or get the image here and store it for fast retrieval? | |
46 return false; | |
47 } | |
48 | |
49 bool SkPdfObject::applyFilter(const char* name) { | |
50 if (strcmp(name, "FlateDecode") == 0) { | |
51 return applyFlateDecodeFilter(); | |
52 } else if (strcmp(name, "DCTDecode") == 0) { | |
53 return applyDCTDecodeFilter(); | |
54 } | |
55 // TODO(edisonn): allert, not supported, but should be implemented asap | |
56 return false; | |
57 } | |
58 | |
59 bool SkPdfObject::filterStream() { | |
60 if (!hasStream()) { | |
61 return false; | |
62 } | |
63 | |
64 if (isStreamFiltered()) { | |
65 return true; | |
66 } | |
67 | |
68 SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*)this; | |
69 | |
70 if (!stream->has_Filter()) { | |
71 fStr.fBytes = ((fStr.fBytes >> 1) << 1) + kFilteredStreamBit; | |
72 } else if (stream->isFilterAName(NULL)) { | |
73 std::string filterName = stream->getFilterAsName(NULL); | |
74 applyFilter(filterName.c_str()); | |
75 } else if (stream->isFilterAArray(NULL)) { | |
76 const SkPdfArray* filters = stream->getFilterAsArray(NULL); | |
77 int cnt = filters->size(); | |
78 for (int i = cnt - 1; i >= 0; i--) { | |
79 const SkPdfObject* filterName = filters->objAtAIndex(i); | |
80 if (filterName != NULL && filterName->isName()) { | |
81 if (!applyFilter(filterName->nameValue())) { | |
82 break; | |
83 } | |
84 } else { | |
85 // TODO(edisonn): report warning | |
86 } | |
87 } | |
88 } | |
89 | |
90 return true; | |
91 } | |
92 | |
93 void SkPdfObject::releaseData() { | |
94 if (fData) { | |
95 switch (fDataType) { | |
96 case kFont_Data: | |
97 delete (SkPdfFont*)fData; | |
98 break; | |
99 case kBitmap_Data: | |
100 delete (SkBitmap*)fData; | |
101 break; | |
102 default: | |
103 SkASSERT(false); | |
104 break; | |
105 } | |
106 } | |
107 fData = NULL; | |
108 fDataType = kEmpty_Data; | |
109 } | |
OLD | NEW |