Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: experimental/PdfViewer/pdfparser/native/SkNativeParsedPDF.cpp

Issue 18536014: pdfviewer: more load references dinamically plumming (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #include "SkNativeParsedPDF.h" 1 #include "SkNativeParsedPDF.h"
2 #include "SkPdfNativeTokenizer.h" 2 #include "SkPdfNativeTokenizer.h"
3 #include "SkPdfBasics.h" 3 #include "SkPdfBasics.h"
4 #include "SkPdfObject.h" 4 #include "SkPdfObject.h"
5 5
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <string.h> 7 #include <string.h>
8 #include <sys/types.h> 8 #include <sys/types.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 10
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 delete fAllocator; 121 delete fAllocator;
122 } 122 }
123 123
124 unsigned char* SkNativeParsedPDF::readCrossReferenceSection(unsigned char* xrefS tart, unsigned char* trailerEnd) { 124 unsigned char* SkNativeParsedPDF::readCrossReferenceSection(unsigned char* xrefS tart, unsigned char* trailerEnd) {
125 unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(edisonn ): verify next keyord is "xref", use nextObject here 125 unsigned char* current = ignoreLine(xrefStart, trailerEnd); // TODO(edisonn ): verify next keyord is "xref", use nextObject here
126 126
127 SkPdfObject token; 127 SkPdfObject token;
128 while (current < trailerEnd) { 128 while (current < trailerEnd) {
129 token.reset(); 129 token.reset();
130 unsigned char* previous = current; 130 unsigned char* previous = current;
131 current = nextObject(current, trailerEnd, &token, NULL); 131 current = nextObject(current, trailerEnd, &token, NULL, NULL);
132 if (!token.isInteger()) { 132 if (!token.isInteger()) {
133 return previous; 133 return previous;
134 } 134 }
135 135
136 int startId = (int)token.intValue(); 136 int startId = (int)token.intValue();
137 token.reset(); 137 token.reset();
138 current = nextObject(current, trailerEnd, &token, NULL); 138 current = nextObject(current, trailerEnd, &token, NULL, NULL);
139 139
140 if (!token.isInteger()) { 140 if (!token.isInteger()) {
141 // TODO(edisonn): report/warning 141 // TODO(edisonn): report/warning
142 return current; 142 return current;
143 } 143 }
144 144
145 int entries = (int)token.intValue(); 145 int entries = (int)token.intValue();
146 146
147 for (int i = 0; i < entries; i++) { 147 for (int i = 0; i < entries; i++) {
148 token.reset(); 148 token.reset();
149 current = nextObject(current, trailerEnd, &token, NULL); 149 current = nextObject(current, trailerEnd, &token, NULL, NULL);
150 if (!token.isInteger()) { 150 if (!token.isInteger()) {
151 // TODO(edisonn): report/warning 151 // TODO(edisonn): report/warning
152 return current; 152 return current;
153 } 153 }
154 int offset = (int)token.intValue(); 154 int offset = (int)token.intValue();
155 155
156 token.reset(); 156 token.reset();
157 current = nextObject(current, trailerEnd, &token, NULL); 157 current = nextObject(current, trailerEnd, &token, NULL, NULL);
158 if (!token.isInteger()) { 158 if (!token.isInteger()) {
159 // TODO(edisonn): report/warning 159 // TODO(edisonn): report/warning
160 return current; 160 return current;
161 } 161 }
162 int generation = (int)token.intValue(); 162 int generation = (int)token.intValue();
163 163
164 token.reset(); 164 token.reset();
165 current = nextObject(current, trailerEnd, &token, NULL); 165 current = nextObject(current, trailerEnd, &token, NULL, NULL);
166 if (!token.isKeyword() || token.len() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) { 166 if (!token.isKeyword() || token.len() != 1 || (*token.c_str() != 'f' && *token.c_str() != 'n')) {
167 // TODO(edisonn): report/warning 167 // TODO(edisonn): report/warning
168 return current; 168 return current;
169 } 169 }
170 170
171 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f'); 171 addCrossSectionInfo(startId + i, generation, offset, *token.c_str() == 'f');
172 } 172 }
173 } 173 }
174 // TODO(edisonn): it should never get here? there is no trailer? 174 // TODO(edisonn): it should never get here? there is no trailer?
175 return current; 175 return current;
176 } 176 }
177 177
178 long SkNativeParsedPDF::readTrailer(unsigned char* trailerStart, unsigned char* trailerEnd, bool storeCatalog) { 178 long SkNativeParsedPDF::readTrailer(unsigned char* trailerStart, unsigned char* trailerEnd, bool storeCatalog) {
179 unsigned char* current = ignoreLine(trailerStart, trailerEnd); // TODO(edis onn): verify next keyord is "trailer" use nextObject here 179 unsigned char* current = ignoreLine(trailerStart, trailerEnd); // TODO(edis onn): verify next keyord is "trailer" use nextObject here
180 180
181 SkPdfObject token; 181 SkPdfObject token;
182 current = nextObject(current, trailerEnd, &token, fAllocator); 182 current = nextObject(current, trailerEnd, &token, fAllocator, NULL);
183 if (!token.isDictionary()) { 183 if (!token.isDictionary()) {
184 return -1; 184 return -1;
185 } 185 }
186 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token; 186 SkPdfFileTrailerDictionary* trailer = (SkPdfFileTrailerDictionary*)&token;
187 if (!trailer->valid()) { 187 if (!trailer->valid()) {
188 return -1; 188 return -1;
189 } 189 }
190 190
191 if (storeCatalog) { 191 if (storeCatalog) {
192 const SkPdfObject* ref = trailer->Root(NULL); 192 const SkPdfObject* ref = trailer->Root(NULL);
(...skipping 14 matching lines...) Expand all
207 void SkNativeParsedPDF::addCrossSectionInfo(int id, int generation, int offset, bool isFreed) { 207 void SkNativeParsedPDF::addCrossSectionInfo(int id, int generation, int offset, bool isFreed) {
208 // TODO(edisonn): security here 208 // TODO(edisonn): security here
209 while (fObjects.count() < id + 1) { 209 while (fObjects.count() < id + 1) {
210 reset(fObjects.append()); 210 reset(fObjects.append());
211 } 211 }
212 212
213 fObjects[id].fOffset = offset; 213 fObjects[id].fOffset = offset;
214 fObjects[id].fObj = NULL; 214 fObjects[id].fObj = NULL;
215 } 215 }
216 216
217 SkPdfObject* SkNativeParsedPDF::readObject(int id/*, int expectedGeneration*/) c onst { 217 SkPdfObject* SkNativeParsedPDF::readObject(int id/*, int expectedGeneration*/) {
218 long startOffset = fObjects[id].fOffset; 218 long startOffset = fObjects[id].fOffset;
219 //long endOffset = fObjects[id].fOffsetEnd; 219 //long endOffset = fObjects[id].fOffsetEnd;
220 // TODO(edisonn): use hinted endOffset 220 // TODO(edisonn): use hinted endOffset
221 // TODO(edisonn): current implementation will result in a lot of memory usag e 221 // TODO(edisonn): current implementation will result in a lot of memory usag e
222 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will 222 // to decrease memory usage, we wither need to be smart and know where objec ts end, and we will
223 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to 223 // alocate only the chancks needed, or the tokenizer will not make copies, b ut then it needs to
224 // cache the results so it does not go twice on the same buffer 224 // cache the results so it does not go twice on the same buffer
225 unsigned char* current = fFileContent + startOffset; 225 unsigned char* current = fFileContent + startOffset;
226 unsigned char* end = fFileContent + fContentLength; 226 unsigned char* end = fFileContent + fContentLength;
227 227
228 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator); 228 SkPdfNativeTokenizer tokenizer(current, end - current, fMapper, fAllocator, this);
229 229
230 SkPdfObject idObj; 230 SkPdfObject idObj;
231 SkPdfObject generationObj; 231 SkPdfObject generationObj;
232 SkPdfObject objKeyword; 232 SkPdfObject objKeyword;
233 SkPdfObject* dict = fAllocator->allocObject(); 233 SkPdfObject* dict = fAllocator->allocObject();
234 234
235 current = nextObject(current, end, &idObj, NULL); 235 current = nextObject(current, end, &idObj, NULL, NULL);
236 if (current >= end) { 236 if (current >= end) {
237 // TODO(edisonn): report warning/error 237 // TODO(edisonn): report warning/error
238 return NULL; 238 return NULL;
239 } 239 }
240 240
241 current = nextObject(current, end, &generationObj, NULL); 241 current = nextObject(current, end, &generationObj, NULL, NULL);
242 if (current >= end) { 242 if (current >= end) {
243 // TODO(edisonn): report warning/error 243 // TODO(edisonn): report warning/error
244 return NULL; 244 return NULL;
245 } 245 }
246 246
247 current = nextObject(current, end, &objKeyword, NULL); 247 current = nextObject(current, end, &objKeyword, NULL, NULL);
248 if (current >= end) { 248 if (current >= end) {
249 // TODO(edisonn): report warning/error 249 // TODO(edisonn): report warning/error
250 return NULL; 250 return NULL;
251 } 251 }
252 252
253 if (!idObj.isInteger() || !generationObj.isInteger() || id != idObj.intValue ()/* || generation != generationObj.intValue()*/) { 253 if (!idObj.isInteger() || !generationObj.isInteger() || id != idObj.intValue ()/* || generation != generationObj.intValue()*/) {
254 // TODO(edisonn): report warning/error 254 // TODO(edisonn): report warning/error
255 } 255 }
256 256
257 if (!objKeyword.isKeyword() || strcmp(objKeyword.c_str(), "obj") != 0) { 257 if (!objKeyword.isKeyword() || strcmp(objKeyword.c_str(), "obj") != 0) {
258 // TODO(edisonn): report warning/error 258 // TODO(edisonn): report warning/error
259 } 259 }
260 260
261 current = nextObject(current, end, dict, fAllocator); 261 current = nextObject(current, end, dict, fAllocator, this);
262 262
263 // TODO(edisonn): report warning/error - verify last token is endobj 263 // TODO(edisonn): report warning/error - verify last token is endobj
264 264
265 return dict; 265 return dict;
266 } 266 }
267 267
268 void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) { 268 void SkNativeParsedPDF::fillPages(SkPdfPageTreeNodeDictionary* tree) {
269 const SkPdfArray* kids = tree->Kids(this); 269 const SkPdfArray* kids = tree->Kids(this);
270 if (kids == NULL) { 270 if (kids == NULL) {
271 *fPages.append() = (SkPdfPageObjectDictionary*)tree; 271 *fPages.append() = (SkPdfPageObjectDictionary*)tree;
(...skipping 14 matching lines...) Expand all
286 286
287 int SkNativeParsedPDF::pages() const { 287 int SkNativeParsedPDF::pages() const {
288 return fPages.count(); 288 return fPages.count();
289 } 289 }
290 290
291 SkPdfResourceDictionary* SkNativeParsedPDF::pageResources(int page) { 291 SkPdfResourceDictionary* SkNativeParsedPDF::pageResources(int page) {
292 return fPages[page]->Resources(this); 292 return fPages[page]->Resources(this);
293 } 293 }
294 294
295 // TODO(edisonn): Partial implemented. Move the logics directly in the code gene rator for inheritable and default value? 295 // TODO(edisonn): Partial implemented. Move the logics directly in the code gene rator for inheritable and default value?
296 SkRect SkNativeParsedPDF::MediaBox(int page) const { 296 SkRect SkNativeParsedPDF::MediaBox(int page) {
297 SkPdfPageObjectDictionary* current = fPages[page]; 297 SkPdfPageObjectDictionary* current = fPages[page];
298 while (!current->has_MediaBox() && current->has_Parent()) { 298 while (!current->has_MediaBox() && current->has_Parent()) {
299 current = (SkPdfPageObjectDictionary*)current->Parent(this); 299 current = (SkPdfPageObjectDictionary*)current->Parent(this);
300 } 300 }
301 if (current) { 301 if (current) {
302 return current->MediaBox(this); 302 return current->MediaBox(this);
303 } 303 }
304 return SkRect::MakeEmpty(); 304 return SkRect::MakeEmpty();
305 } 305 }
306 306
307 // TODO(edisonn): stream or array ... ? for now only array 307 // TODO(edisonn): stream or array ... ? for now only array
308 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfPage(int page) const { 308 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfPage(int page) {
309 if (fPages[page]->isContentsAStream(this)) { 309 if (fPages[page]->isContentsAStream(this)) {
310 return tokenizerOfStream(fPages[page]->getContentsAsStream(this)); 310 return tokenizerOfStream(fPages[page]->getContentsAsStream(this));
311 } else { 311 } else {
312 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart 312 // TODO(edisonn): NYI, we need to concatenate all streams in the array o r make the tokenizer smart
313 // so we don't allocate new memory 313 // so we don't allocate new memory
314 return NULL; 314 return NULL;
315 } 315 }
316 } 316 }
317 317
318 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfStream(SkPdfObject* stream) const { 318 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfStream(SkPdfObject* stream) {
319 if (stream == NULL) { 319 if (stream == NULL) {
320 return NULL; 320 return NULL;
321 } 321 }
322 322
323 return new SkPdfNativeTokenizer(stream, fMapper, fAllocator); 323 return new SkPdfNativeTokenizer(stream, fMapper, fAllocator, this);
324 } 324 }
325 325
326 // TODO(edisonn): NYI 326 // TODO(edisonn): NYI
327 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfBuffer(unsigned char* buffer , size_t len) const { 327 SkPdfNativeTokenizer* SkNativeParsedPDF::tokenizerOfBuffer(unsigned char* buffer , size_t len) {
328 // warning does not track two calls in the same buffer! the buffer is update d! 328 // warning does not track two calls in the same buffer! the buffer is update d!
329 // make a clean copy if needed! 329 // make a clean copy if needed!
330 return new SkPdfNativeTokenizer(buffer, len, fMapper, fAllocator); 330 return new SkPdfNativeTokenizer(buffer, len, fMapper, fAllocator, this);
331 } 331 }
332 332
333 size_t SkNativeParsedPDF::objects() const { 333 size_t SkNativeParsedPDF::objects() const {
334 return fObjects.count(); 334 return fObjects.count();
335 } 335 }
336 336
337 SkPdfObject* SkNativeParsedPDF::object(int i) { 337 SkPdfObject* SkNativeParsedPDF::object(int i) {
338 SkASSERT(!(i < 0 || i > fObjects.count())); 338 SkASSERT(!(i < 0 || i > fObjects.count()));
339 339
340 if (i < 0 || i > fObjects.count()) { 340 if (i < 0 || i > fObjects.count()) {
(...skipping 28 matching lines...) Expand all
369 SkPdfString* SkNativeParsedPDF::createString(unsigned char* sz, size_t len) cons t { 369 SkPdfString* SkNativeParsedPDF::createString(unsigned char* sz, size_t len) cons t {
370 SkPdfObject* obj = fAllocator->allocObject(); 370 SkPdfObject* obj = fAllocator->allocObject();
371 SkPdfObject::makeString(sz, len, obj); 371 SkPdfObject::makeString(sz, len, obj);
372 return (SkPdfString*)obj; 372 return (SkPdfString*)obj;
373 } 373 }
374 374
375 SkPdfAllocator* SkNativeParsedPDF::allocator() const { 375 SkPdfAllocator* SkNativeParsedPDF::allocator() const {
376 return fAllocator; 376 return fAllocator;
377 } 377 }
378 378
379 SkPdfObject* SkNativeParsedPDF::resolveReference(SkPdfObject* ref) const {
380 return (SkPdfObject*)resolveReference((const SkPdfObject*)ref);
381 }
382
383 // TODO(edisonn): fix infinite loop if ref to itself! 379 // TODO(edisonn): fix infinite loop if ref to itself!
384 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv edReference? 380 // TODO(edisonn): perf, fix refs at load, and resolve will simply return fResolv edReference?
385 SkPdfObject* SkNativeParsedPDF::resolveReference(const SkPdfObject* ref) const { 381 SkPdfObject* SkNativeParsedPDF::resolveReference(const SkPdfObject* ref) {
386 if (ref && ref->isReference()) { 382 if (ref && ref->isReference()) {
387 int id = ref->referenceId(); 383 int id = ref->referenceId();
388 // TODO(edisonn): generation/updates not supported now 384 // TODO(edisonn): generation/updates not supported now
389 //int gen = ref->referenceGeneration(); 385 //int gen = ref->referenceGeneration();
390 386
391 SkASSERT(!(id < 0 || id > fObjects.count())); 387 SkASSERT(!(id < 0 || id > fObjects.count()));
392 388
393 if (id < 0 || id > fObjects.count()) { 389 if (id < 0 || id > fObjects.count()) {
394 return NULL; 390 return NULL;
395 } 391 }
(...skipping 14 matching lines...) Expand all
410 } else { 406 } else {
411 fObjects[id].fResolvedReference = resolveReference(fObjects[id]. fObj); 407 fObjects[id].fResolvedReference = resolveReference(fObjects[id]. fObj);
412 } 408 }
413 } 409 }
414 410
415 return fObjects[id].fResolvedReference; 411 return fObjects[id].fResolvedReference;
416 } 412 }
417 // TODO(edisonn): fix the mess with const, probably we need to remove it pre tty much everywhere 413 // TODO(edisonn): fix the mess with const, probably we need to remove it pre tty much everywhere
418 return (SkPdfObject*)ref; 414 return (SkPdfObject*)ref;
419 } 415 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698