| 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 |