pdfviewer: add indexed rbg image support, enhanche caching(setData) for SkPdfObject
Review URL: https://codereview.chromium.org/21738005
git-svn-id: http://skia.googlecode.com/svn/trunk@10534 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
index 306bf07..6386f98 100644
--- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp
@@ -306,7 +306,7 @@
}
if (storeCatalog) {
- const SkPdfObject* ref = trailer->Root(NULL);
+ SkPdfObject* ref = trailer->Root(NULL);
if (ref == NULL || !ref->isReference()) {
// TODO(edisonn): oops, we have to fix the corrup pdf file
return current;
@@ -384,7 +384,7 @@
}
void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) {
- const SkPdfArray* kids = tree->Kids(this);
+ SkPdfArray* kids = tree->Kids(this);
if (kids == NULL) {
*fPages.append() = (SkPdfPageObjectDictionary*)tree;
return;
@@ -392,7 +392,7 @@
int cnt = kids->size();
for (int i = 0; i < cnt; i++) {
- const SkPdfObject* obj = resolveReference(kids->objAtAIndex(i));
+ SkPdfObject* obj = resolveReference(kids->objAtAIndex(i));
if (fMapper->mapPageObjectDictionary(obj) != kPageObjectDictionary_SkPdfObjectType) {
*fPages.append() = (SkPdfPageObjectDictionary*)obj;
} else {
@@ -506,7 +506,7 @@
// TODO(edisonn): fix infinite loop if ref to itself!
// TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolvedReference?
-SkPdfObject* SkNativeParsedPDF::resolveReference(const SkPdfObject* ref) {
+SkPdfObject* SkNativeParsedPDF::resolveReference(SkPdfObject* ref) {
if (ref && ref->isReference()) {
int id = ref->referenceId();
// TODO(edisonn): generation/updates not supported now
diff --git a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
index d073f00..de71bf6 100644
--- a/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
+++ b/experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.h
@@ -64,7 +64,7 @@
// the string does not own the char*
SkPdfString* createString(const unsigned char* sz, size_t len) const;
- SkPdfObject* resolveReference(const SkPdfObject* ref);
+ SkPdfObject* resolveReference(SkPdfObject* ref);
// Reports an approximation of all the memory usage.
size_t bytesUsed() const;
@@ -95,7 +95,7 @@
SkPdfMapper* fMapper;
const unsigned char* fFileContent;
size_t fContentLength;
- const SkPdfObject* fRootCatalogRef;
+ SkPdfObject* fRootCatalogRef;
SkPdfCatalogDictionary* fRootCatalog;
mutable SkTDArray<PublicObjectEntry> fObjects;
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
index 8dd5d30..637eb4d 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfNativeTokenizer.cpp
@@ -32,9 +32,11 @@
static void TRACE_INDENT(int level, const char* type) {
static int id = 0;
id++;
+#if 0
if (478613 == id) {
printf("break;\n");
}
+#endif
// all types should have 2 letters, so the text is alligned nicely
printf("\n%10i %15s: ", id, type);
for (int i = 0 ; i < level; i++) {
@@ -158,7 +160,6 @@
}
array->appendInArray(newObj);
}
- printf("break;\n"); // DO NOT SUBMIT!
// TODO(edisonn): report not reached, we should never get here
// TODO(edisonn): there might be a bug here, enable an assert and run it on files
// or it might be that the files were actually corrupted
@@ -954,9 +955,11 @@
#ifdef PDF_TRACE_READ_TOKEN
static int read_op = 0;
read_op++;
+#if 0
if (548 == read_op) {
printf("break;\n");
}
+#endif
printf("%i READ %s %s\n", read_op, token->fType == kKeyword_TokenType ? "Keyword" : "Object", token->fKeyword ? std::string(token->fKeyword, token->fKeywordLength).c_str() : token->fObject->toString().c_str());
#endif
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfObject.cpp b/experimental/PdfViewer/pdfparser/native/SkPdfObject.cpp
index eb342af..a02d789 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfObject.cpp
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfObject.cpp
@@ -6,6 +6,9 @@
#include "SkStream.h"
#include "SkPdfNativeTokenizer.h"
+#include "SkBitmap.h"
+#include "SkPdfFont.h"
+
SkPdfObject SkPdfObject::kNull = SkPdfObject::makeNull();
bool SkPdfObject::applyFlateDecodeFilter() {
@@ -86,3 +89,21 @@
return true;
}
+
+void SkPdfObject::releaseData() {
+ if (fData) {
+ switch (fDataType) {
+ case kFont_Data:
+ delete (SkPdfFont*)fData;
+ break;
+ case kBitmap_Data:
+ delete (SkBitmap*)fData;
+ break;
+ default:
+ SkASSERT(false);
+ break;
+ }
+ }
+ fData = NULL;
+ fDataType = kEmpty_Data;
+}
diff --git a/experimental/PdfViewer/pdfparser/native/SkPdfObject.h b/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
index 29780d0..1fb4e1f 100644
--- a/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
+++ b/experimental/PdfViewer/pdfparser/native/SkPdfObject.h
@@ -49,6 +49,12 @@
kUndefined_PdfObjectType, // per 1.4 spec, if the same key appear twice in the dictionary, the value is undefined
};
+ enum DataType {
+ kEmpty_Data,
+ kFont_Data,
+ kBitmap_Data,
+ };
+
private:
struct Reference {
unsigned int fId;
@@ -76,21 +82,33 @@
Reference fRef;
};
SkTDict<SkPdfObject*>* fMap;
+
+ // TODO(edisonn): rename data with cache
void* fData;
+ DataType fDataType;
public:
- SkPdfObject() : fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL) {}
+ SkPdfObject() : fObjectType(kInvalid_PdfObjectType), fMap(NULL), fData(NULL), fDataType(kEmpty_Data) {}
- inline void* data() {
- return fData;
+
+ inline bool hasData(DataType type) {
+ return type == fDataType;
}
- inline void setData(void* data) {
+ inline void* data(DataType type) {
+ return type == fDataType ? fData : NULL;
+ }
+
+ inline void setData(void* data, DataType type) {
+ releaseData();
+ fDataType = type;
fData = data;
}
+ void releaseData();
+
// ~SkPdfObject() {
// //reset(); must be called manually!
// }
@@ -114,6 +132,7 @@
break;
}
fObjectType = kInvalid_PdfObjectType;
+ releaseData();
}
ObjectType type() { return fObjectType; }
@@ -604,6 +623,10 @@
return fObjectType == kString_PdfObjectType || fObjectType == kHexString_PdfObjectType;
}
+ bool isHexString() const {
+ return fObjectType == kHexString_PdfObjectType;
+ }
+
bool isMatrix() const {
return fObjectType == kArray_PdfObjectType && fArray->count() == 6; // NYI + and elems are numbers
}
@@ -867,7 +890,9 @@
case kHexString_PdfObjectType:
str.append("<");
- str.append((const char*)fStr.fBuffer, fStr.fBytes);
+ for (unsigned int i = 0 ; i < fStr.fBytes; i++) {
+ str.appendf("%02x", (unsigned int)fStr.fBuffer[i]);
+ }
str.append(">");
break;
@@ -908,9 +933,9 @@
const unsigned char* stream = NULL;
size_t length = 0;
if (GetFilteredStreamRef(&stream, &length)) {
- str.append("stream");
+ str.append("stream\n");
str.append((const char*)stream, length > 256 ? 256 : length);
- str.append("endstream");
+ str.append("\nendstream");
} else {
str.append("stream STREAM_ERROR endstream");
}