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

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

Issue 26613006: code cleanup (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 2 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
« no previous file with comments | « experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkPdfConfig.h"
9 #include "SkPdfNativeObject.h"
8 #include "SkPdfNativeTokenizer.h" 10 #include "SkPdfNativeTokenizer.h"
9 #include "SkPdfNativeObject.h" 11 #include "SkPdfUtils.h"
10 #include "SkPdfConfig.h"
11 12
12 // TODO(edisonn): mac builder does not find the header ... but from headers is o k 13 // TODO(edisonn): mac builder does not find the header ... but from headers is o k
13 //#include "SkPdfStreamCommonDictionary_autogen.h" 14 //#include "SkPdfStreamCommonDictionary_autogen.h"
14 //#include "SkPdfImageDictionary_autogen.h" 15 //#include "SkPdfImageDictionary_autogen.h"
15 #include "SkPdfHeaders_autogen.h" 16 #include "SkPdfHeaders_autogen.h"
16 17
17 18
18 // TODO(edisonn): perf!!! 19 // TODO(edisonn): Perf, Make this function run faster.
19 // there could be 0s between start and end! but not in the needle. 20 // There could be 0s between start and end.
21 // needle will not contain 0s.
20 static char* strrstrk(char* hayStart, char* hayEnd, const char* needle) { 22 static char* strrstrk(char* hayStart, char* hayEnd, const char* needle) {
21 int needleLen = strlen(needle); 23 int needleLen = strlen(needle);
22 if ((isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (hayStart+needl eLen == hayEnd)) && 24 if ((isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (hayStart+needl eLen == hayEnd)) &&
23 strncmp(hayStart, needle, needleLen) == 0) { 25 strncmp(hayStart, needle, needleLen) == 0) {
24 return hayStart; 26 return hayStart;
25 } 27 }
26 28
27 hayStart++; 29 hayStart++;
28 30
29 while (hayStart < hayEnd) { 31 while (hayStart < hayEnd) {
30 if (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart-1)) && 32 if (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart-1)) &&
31 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (haySta rt+needleLen == hayEnd)) && 33 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) ||
34 (hayStart+needleLen == hayEnd)) &&
32 strncmp(hayStart, needle, needleLen) == 0) { 35 strncmp(hayStart, needle, needleLen) == 0) {
33 return hayStart; 36 return hayStart;
34 } 37 }
35 hayStart++; 38 hayStart++;
36 } 39 }
37 return NULL; 40 return NULL;
38 } 41 }
39 42
40 #ifdef PDF_TRACE_TOKENIZER
41
42 static void TRACE_COMMENT(char ch) {
43 printf("%c", ch);
44 }
45
46 static void TRACE_TK(char ch) {
47 printf("%c", ch);
48 }
49
50 static void TRACE_NAME(const unsigned char* start, const unsigned char* end) {
51 while (start < end) {
52 printf("%c", *start);
53 start++;
54 }
55 printf("\n");
56 }
57
58 static void TRACE_STRING(const unsigned char* start, const unsigned char* end) {
59 while (start < end) {
60 printf("%c", *start);
61 start++;
62 }
63 printf("\n");
64 }
65
66 static void TRACE_HEXSTRING(const unsigned char* start, const unsigned char* end ) {
67 while (start < end) {
68 printf("%c", *start);
69 start++;
70 }
71 printf("\n");
72 }
73
74 #else
75 #define TRACE_COMMENT(ch)
76 #define TRACE_TK(ch)
77 #define TRACE_NAME(start,end)
78 #define TRACE_STRING(start,end)
79 #define TRACE_HEXSTRING(start,end)
80 #endif
81
82 const unsigned char* skipPdfWhiteSpaces(const unsigned char* start, const unsign ed char* end) { 43 const unsigned char* skipPdfWhiteSpaces(const unsigned char* start, const unsign ed char* end) {
83 while (start < end && (isPdfWhiteSpace(*start) || *start == kComment_PdfDeli miter)) { 44 while (start < end && (isPdfWhiteSpace(*start) || *start == kComment_PdfDeli miter)) {
84 TRACE_COMMENT(*start); 45 TRACE_COMMENT(*start);
85 if (*start == kComment_PdfDelimiter) { 46 if (*start == kComment_PdfDelimiter) {
86 // skip the comment until end of line 47 // skip the comment until end of line
87 while (start < end && !isPdfEOL(*start)) { 48 while (start < end && !isPdfEOL(*start)) {
88 //*start = '\0';
89 start++; 49 start++;
90 TRACE_COMMENT(*start); 50 TRACE_COMMENT(*start);
91 } 51 }
92 } else { 52 } else {
93 //*start = '\0';
94 start++; 53 start++;
95 } 54 }
96 } 55 }
97 return start; 56 return start;
98 } 57 }
99 58
100 // TODO(edisonn) '(' can be used, will it break the string a delimiter or space inside () ?
101 const unsigned char* endOfPdfToken(const unsigned char* start, const unsigned ch ar* end) { 59 const unsigned char* endOfPdfToken(const unsigned char* start, const unsigned ch ar* end) {
102 SkASSERT(!isPdfWhiteSpace(*start)); 60 SkASSERT(!isPdfWhiteSpace(*start));
103 61
104 if (start < end && isPdfDelimiter(*start)) { 62 if (start < end && isPdfDelimiter(*start)) {
105 TRACE_TK(*start); 63 TRACE_TK(*start);
106 start++; 64 start++;
107 return start; 65 return start;
108 } 66 }
109 67
110 while (start < end && !isPdfWhiteSpaceOrPdfDelimiter(*start)) { 68 while (start < end && !isPdfWhiteSpaceOrPdfDelimiter(*start)) {
111 TRACE_TK(*start); 69 TRACE_TK(*start);
112 start++; 70 start++;
113 } 71 }
114 return start; 72 return start;
115 } 73 }
116 74
117 // last elem has to be ] 75 // The parsing should end with a ].
118 static const unsigned char* readArray(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* array, SkPdfAllocator* allocator, SkPdfNativeDoc* doc) { 76 static const unsigned char* readArray(const unsigned char* start, const unsigned char* end,
77 SkPdfNativeObject* array,
78 SkPdfAllocator* allocator, SkPdfNativeDoc* doc) {
119 SkPdfNativeObject::makeEmptyArray(array); 79 SkPdfNativeObject::makeEmptyArray(array);
120 // PUT_TRACK_STREAM(array, start, start) 80 // PUT_TRACK_STREAM(array, start, start)
121 81
122 if (allocator == NULL) { 82 if (allocator == NULL) {
123 // TODO(edisonn): report/warning error 83 // TODO(edisonn): report/warning error/assert
124 return end; 84 return end;
125 } 85 }
126 86
127 while (start < end) { 87 while (start < end) {
128 // skip white spaces 88 // skip white spaces
129 start = skipPdfWhiteSpaces(start, end); 89 start = skipPdfWhiteSpaces(start, end);
130 90
131 const unsigned char* endOfToken = endOfPdfToken(start, end); 91 const unsigned char* endOfToken = endOfPdfToken(start, end);
132 92
133 if (endOfToken == start) { 93 if (endOfToken == start) {
134 // TODO(edisonn): report error in pdf file (end of stream with ] for end of aray 94 // TODO(edisonn): report error in pdf file (end of stream with ] for end of aray
135 return start; 95 return start;
136 } 96 }
137 97
138 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit er) { 98 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit er) {
139 return endOfToken; 99 return endOfToken;
140 } 100 }
141 101
142 SkPdfNativeObject* newObj = allocator->allocObject(); 102 SkPdfNativeObject* newObj = allocator->allocObject();
143 start = nextObject(start, end, newObj, allocator, doc); 103 start = nextObject(start, end, newObj, allocator, doc);
144 // TODO(edisonn): perf/memory: put the variables on the stack, and flush them on the array only when 104 // TODO(edisonn): perf/memory: put the variables on the stack, and flush them on the array
145 // we are sure they are not references! 105 // only when we are sure they are not references!
146 if (newObj->isKeywordReference() && array->size() >= 2 && array->objAtAI ndex(array->size() - 1)->isInteger() && array->objAtAIndex(array->size() - 2)->i sInteger()) { 106 if (newObj->isKeywordReference() && array->size() >= 2 &&
107 array->objAtAIndex(array->size() - 1)->isInteger() &&
108 array->objAtAIndex(array->size() - 2)->isInteger()) {
147 SkPdfNativeObject* gen = array->removeLastInArray(); 109 SkPdfNativeObject* gen = array->removeLastInArray();
148 SkPdfNativeObject* id = array->removeLastInArray(); 110 SkPdfNativeObject* id = array->removeLastInArray();
149 111
150 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue( ), (unsigned int)gen->intValue(), newObj); 112 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue( ),
113 (unsigned int)gen->intValue (), newObj);
151 // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now 114 // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now
152
153 } 115 }
154 array->appendInArray(newObj); 116 array->appendInArray(newObj);
155 } 117 }
156 // TODO(edisonn): report not reached, we should never get here 118 // TODO(edisonn): report not reached, we should never get here
157 // TODO(edisonn): there might be a bug here, enable an assert and run it on files 119 // TODO(edisonn): there might be a bug here, enable an assert and run it on files
158 // or it might be that the files were actually corrupted 120 // or it might be that the files were actually corrupted
159 return start; 121 return start;
160 } 122 }
161 123
162 // When we read strings we will rewrite the string so we will reuse the memory 124 static const unsigned char* readString(const unsigned char* start, const unsigne d char* end,
163 // when we start to read the string, we already consumed the opened bracket 125 unsigned char* out) {
164
165 // TODO(edisonn): space: add paramater, taht would report if we need to allocate new buffer, or we can reuse the one we have
166
167 static const unsigned char* readString(const unsigned char* start, const unsigne d char* end, unsigned char* out) {
168 const unsigned char* in = start; 126 const unsigned char* in = start;
169 bool hasOut = (out != NULL); 127 bool hasOut = (out != NULL);
170 128
171 int openRoundBrackets = 1; 129 int openRoundBrackets = 1;
172 while (in < end) { 130 while (in < end) {
173 openRoundBrackets += ((*in) == kOpenedRoundBracket_PdfDelimiter); 131 openRoundBrackets += ((*in) == kOpenedRoundBracket_PdfDelimiter);
174 openRoundBrackets -= ((*in) == kClosedRoundBracket_PdfDelimiter); 132 openRoundBrackets -= ((*in) == kClosedRoundBracket_PdfDelimiter);
175 if (openRoundBrackets == 0) { 133 if (openRoundBrackets == 0) {
176 in++; // consumed ) 134 in++; // consumed )
177 break; 135 break;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 211 }
254 } 212 }
255 if (i > 0) { 213 if (i > 0) {
256 if (hasOut) { *out = code & 0xff; } 214 if (hasOut) { *out = code & 0xff; }
257 out++; 215 out++;
258 } 216 }
259 } 217 }
260 break; 218 break;
261 219
262 default: 220 default:
263 // Per spec, backslash is ignored is escaped ch is unkno wn 221 // Per spec, backslash is ignored if escaped ch is unkno wn
264 in++; 222 in++;
265 break; 223 break;
266 } 224 }
267 } else { 225 } else {
268 in++; 226 in++;
269 } 227 }
270 } else { 228 } else {
271 // TODO(edisonn): perf, avoid copy into itself, maybe first do a sim ple scan until found backslash ?
272 // we could have one look that first just inc current, and when we f ind the backslash
273 // we go to this loop
274 if (hasOut) { *out = *in; } 229 if (hasOut) { *out = *in; }
275 in++; 230 in++;
276 out++; 231 out++;
277 } 232 }
278 } 233 }
279 234
280 if (hasOut) { 235 if (hasOut) {
281 return in; // consumed already ) at the end of the string 236 return in; // consumed already ) at the end of the string
282 } else { 237 } else {
283 return start + (out - (const unsigned char*)NULL); // return where the s tring would end if we reuse the string 238 // return where the string would end if we reuse the string
239 return start + (out - (const unsigned char*)NULL);
284 } 240 }
285 } 241 }
286 242
287 static int readStringLength(const unsigned char* start, const unsigned char* end ) { 243 static int readStringLength(const unsigned char* start, const unsigned char* end ) {
288 return readString(start, end, NULL) - start; 244 return readString(start, end, NULL) - start;
289 } 245 }
290 246
291 static const unsigned char* readString(const unsigned char* start, const unsigne d char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { 247 static const unsigned char* readString(const unsigned char* start, const unsigne d char* end,
248 SkPdfNativeObject* str, SkPdfAllocator* a llocator) {
292 if (!allocator) { 249 if (!allocator) {
250 // TODO(edisonn): report error/warn/assert
293 return end; 251 return end;
294 } 252 }
253
295 int outLength = readStringLength(start, end); 254 int outLength = readStringLength(start, end);
296 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu t it in a preallocated buffer
297 unsigned char* out = (unsigned char*)allocator->alloc(outLength); 255 unsigned char* out = (unsigned char*)allocator->alloc(outLength);
298 const unsigned char* now = readString(start, end, out); 256 const unsigned char* now = readString(start, end, out);
299 SkPdfNativeObject::makeString(out, out + outLength, str); 257 SkPdfNativeObject::makeString(out, out + outLength, str);
300 // PUT_TRACK_STREAM(str, start, now) 258 // PUT_TRACK_STREAM(str, start, now)
301 TRACE_STRING(out, out + outLength); 259 TRACE_STRING(out, out + outLength);
302 return now; // consumed already ) at the end of the string 260 return now; // consumed already ) at the end of the string
303 } 261 }
304 262
305 static const unsigned char* readHexString(const unsigned char* start, const unsi gned char* end, unsigned char* out) { 263 static const unsigned char* readHexString(const unsigned char* start, const unsi gned char* end,
264 unsigned char* out) {
306 bool hasOut = (out != NULL); 265 bool hasOut = (out != NULL);
307 const unsigned char* in = start; 266 const unsigned char* in = start;
308 267
309 unsigned char code = 0; 268 unsigned char code = 0;
310 269
311 while (in < end) { 270 while (in < end) {
312 while (in < end && isPdfWhiteSpace(*in)) { 271 while (in < end && isPdfWhiteSpace(*in)) {
313 in++; 272 in++;
314 } 273 }
315 274
316 if (*in == kClosedInequityBracket_PdfDelimiter) { 275 if (*in == kClosedInequityBracket_PdfDelimiter) {
317 //*in = '\0';
318 in++; // consume > 276 in++; // consume >
319 // normal exit 277 // normal exit
320 break; 278 break;
321 } 279 }
322 280
323 if (in >= end) { 281 if (in >= end) {
324 // end too soon 282 // end too soon
325 break; 283 break;
326 } 284 }
327 285
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 default: 376 default:
419 break; 377 break;
420 } 378 }
421 379
422 if (hasOut) { *out = code; } 380 if (hasOut) { *out = code; }
423 out++; 381 out++;
424 in++; 382 in++;
425 } 383 }
426 384
427 if (hasOut) { 385 if (hasOut) {
428 return in; // consumed already > at the end of the string 386 return in; // consumed already ) at the end of the string
429 } else { 387 } else {
430 return start + (out - (const unsigned char*)NULL); // return where the s tring would end if we reuse the string 388 // return where the string would end if we reuse the string
389 return start + (out - (const unsigned char*)NULL);
431 } 390 }
432 } 391 }
433 392
434 static int readHexStringLength(const unsigned char* start, const unsigned char* end) { 393 static int readHexStringLength(const unsigned char* start, const unsigned char* end) {
435 return readHexString(start, end, NULL) - start; 394 return readHexString(start, end, NULL) - start;
436 } 395 }
437 396
438 static const unsigned char* readHexString(const unsigned char* start, const unsi gned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { 397 static const unsigned char* readHexString(const unsigned char* start, const unsi gned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) {
439 if (!allocator) { 398 if (!allocator) {
399 // TODO(edisonn): report error/warn/assert
440 return end; 400 return end;
441 } 401 }
442 int outLength = readHexStringLength(start, end); 402 int outLength = readHexStringLength(start, end);
443 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu t it in a preallocated buffer
444 unsigned char* out = (unsigned char*)allocator->alloc(outLength); 403 unsigned char* out = (unsigned char*)allocator->alloc(outLength);
445 const unsigned char* now = readHexString(start, end, out); 404 const unsigned char* now = readHexString(start, end, out);
446 SkPdfNativeObject::makeHexString(out, out + outLength, str); 405 SkPdfNativeObject::makeHexString(out, out + outLength, str);
447 // str PUT_TRACK_STREAM(start, now) 406 // str PUT_TRACK_STREAM(start, now)
448 TRACE_HEXSTRING(out, out + outLength); 407 TRACE_HEXSTRING(out, out + outLength);
449 return now; // consumed already > at the end of the string 408 return now; // consumed already > at the end of the string
450 } 409 }
451 410
452 // TODO(edisonn): before PDF 1.2 name could not have special characters, add ver sion parameter 411 // TODO(edisonn): add version parameter, before PDF 1.2 name could not have spec ial characters.
453 static const unsigned char* readName(const unsigned char* start, const unsigned char* end, unsigned char* out) { 412 static const unsigned char* readName(const unsigned char* start, const unsigned char* end,
413 unsigned char* out) {
454 bool hasOut = (out != NULL); 414 bool hasOut = (out != NULL);
455 const unsigned char* in = start; 415 const unsigned char* in = start;
456 416
457 unsigned char code = 0; 417 unsigned char code = 0;
458 418
459 while (in < end) { 419 while (in < end) {
460 if (isPdfWhiteSpaceOrPdfDelimiter(*in)) { 420 if (isPdfWhiteSpaceOrPdfDelimiter(*in)) {
461 break; 421 break;
462 } 422 }
463 423
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 out++; 503 out++;
544 in++; 504 in++;
545 } else { 505 } else {
546 if (hasOut) { *out = *in; } 506 if (hasOut) { *out = *in; }
547 out++; 507 out++;
548 in++; 508 in++;
549 } 509 }
550 } 510 }
551 511
552 if (hasOut) { 512 if (hasOut) {
553 return in; 513 return in; // consumed already ) at the end of the string
554 } else { 514 } else {
555 return start + (out - (const unsigned char*)NULL); // return where the s tring would end if we reuse the string 515 // return where the string would end if we reuse the string
516 return start + (out - (const unsigned char*)NULL);
556 } 517 }
557 } 518 }
558 519
559 static int readNameLength(const unsigned char* start, const unsigned char* end) { 520 static int readNameLength(const unsigned char* start, const unsigned char* end) {
560 return readName(start, end, NULL) - start; 521 return readName(start, end, NULL) - start;
561 } 522 }
562 523
563 static const unsigned char* readName(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* name, SkPdfAllocator* allocator) { 524 static const unsigned char* readName(const unsigned char* start, const unsigned char* end,
525 SkPdfNativeObject* name, SkPdfAllocator* al locator) {
564 if (!allocator) { 526 if (!allocator) {
527 // TODO(edisonn): report error/warn/assert
565 return end; 528 return end;
566 } 529 }
567 int outLength = readNameLength(start, end); 530 int outLength = readNameLength(start, end);
568 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu t it in a preallocated buffer
569 unsigned char* out = (unsigned char*)allocator->alloc(outLength); 531 unsigned char* out = (unsigned char*)allocator->alloc(outLength);
570 const unsigned char* now = readName(start, end, out); 532 const unsigned char* now = readName(start, end, out);
571 SkPdfNativeObject::makeName(out, out + outLength, name); 533 SkPdfNativeObject::makeName(out, out + outLength, name);
572 //PUT_TRACK_STREAM(start, now) 534 //PUT_TRACK_STREAM(start, now)
573 TRACE_NAME(out, out + outLength); 535 TRACE_NAME(out, out + outLength);
574 return now; 536 return now;
575 } 537 }
576 538
577 // TODO(edisonn): pdf spec let Length to be an indirect object define after the stream 539 // TODO(edisonn): pdf spec let Length to be an indirect object define after the stream
578 // that makes for an interesting scenario, where the stream itself contains ends tream, together 540 // that makes for an interesting scenario, where the stream itself contains ends tream, together
(...skipping 11 matching lines...) Expand all
590 endobj 552 endobj
591 endstream 553 endstream
592 8 0 obj #real obj 554 8 0 obj #real obj
593 << 100 >> #real obj 555 << 100 >> #real obj
594 endobj 556 endobj
595 and it could get worse, with multiple object like this 557 and it could get worse, with multiple object like this
596 */ 558 */
597 559
598 // right now implement the silly algorithm that assumes endstream is finishing t he stream 560 // right now implement the silly algorithm that assumes endstream is finishing t he stream
599 561
600 562 static const unsigned char* readStream(const unsigned char* start, const unsigne d char* end,
601 static const unsigned char* readStream(const unsigned char* start, const unsigne d char* end, SkPdfNativeObject* dict, SkPdfNativeDoc* doc) { 563 SkPdfNativeObject* dict, SkPdfNativeDoc* doc) {
602 start = skipPdfWhiteSpaces(start, end); 564 start = skipPdfWhiteSpaces(start, end);
603 if (!(start[0] == 's' && start[1] == 't' && start[2] == 'r' && start[3] == ' e' && start[4] == 'a' && start[5] == 'm')) { 565 if (!( start[0] == 's' &&
566 start[1] == 't' &&
567 start[2] == 'r' &&
568 start[3] == 'e' &&
569 start[4] == 'a' &&
570 start[5] == 'm')) {
604 // no stream. return. 571 // no stream. return.
605 return start; 572 return start;
606 } 573 }
607 574
608 start += 6; // strlen("stream") 575 start += 6; // strlen("stream")
609 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { 576 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) {
610 start += 2; 577 start += 2;
611 } else if (start[0] == kLF_PdfWhiteSpace) { 578 } else if (start[0] == kLF_PdfWhiteSpace) {
612 start += 1; 579 start += 1;
613 } else if (isPdfWhiteSpace(start[0])) { 580 } else if (isPdfWhiteSpace(start[0])) {
614 start += 1; 581 start += 1;
615 } else { 582 } else {
616 // TODO(edisonn): warn it should be isPdfDelimiter(start[0])) ? 583 // TODO(edisonn): warn it should be isPdfDelimiter(start[0])) ?
617 // TODO(edisonn): warning?
618 } 584 }
619 585
620 SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*) dict; 586 SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*) dict;
621 // TODO(edisonn): load Length 587 // TODO(edisonn): load Length
622 int64_t length = -1; 588 int64_t length = -1;
623 589
624 // TODO(edisonn): very basic implementation 590 // TODO(edisonn): very basic implementation
625 if (stream->has_Length() && stream->Length(doc) > 0) { 591 if (stream->has_Length() && stream->Length(doc) > 0) {
626 length = stream->Length(doc); 592 length = stream->Length(doc);
627 } 593 }
628 594
629 // TODO(edisonn): laod external streams 595 // TODO(edisonn): load external streams
630 // TODO(edisonn): look at the last filter, to determione how to deal with po ssible issue 596 // TODO(edisonn): look at the last filter, to determine how to deal with pos sible parsing
631 597 // issues. The last filter can have special rules to terminate a stream, whi ch we could
598 // use to determine end of stream.
632 599
633 if (length >= 0) { 600 if (length >= 0) {
634 const unsigned char* endstream = start + length; 601 const unsigned char* endstream = start + length;
635 602
636 if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpa ce) { 603 if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpa ce) {
637 endstream += 2; 604 endstream += 2;
638 } else if (endstream[0] == kLF_PdfWhiteSpace) { 605 } else if (endstream[0] == kLF_PdfWhiteSpace) {
639 endstream += 1; 606 endstream += 1;
640 } 607 }
641 608
642 if (strncmp((const char*)endstream, "endstream", strlen("endstream")) != 0) { 609 if (strncmp((const char*)endstream, "endstream", strlen("endstream")) != 0) {
643 length = -1; 610 length = -1;
644 } 611 }
645 } 612 }
646 613
647 if (length < 0) { 614 if (length < 0) {
648 // scan the buffer, until we find first endstream 615 // scan the buffer, until we find first endstream
649 // TODO(edisonn): all buffers must have a 0 at the end now, 616 // TODO(edisonn): all buffers must have a 0 at the end now,
650 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)s tart, (char*)end, "endstream"); 617 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)s tart, (char*)end,
618 "endstre am");
651 619
652 if (endstream) { 620 if (endstream) {
653 length = endstream - start; 621 length = endstream - start;
654 if (*(endstream-1) == kLF_PdfWhiteSpace) length--; 622 if (*(endstream-1) == kLF_PdfWhiteSpace) length--;
655 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; 623 if (*(endstream-2) == kCR_PdfWhiteSpace) length--;
656 } 624 }
657 } 625 }
658 if (length >= 0) { 626 if (length >= 0) {
659 const unsigned char* endstream = start + length; 627 const unsigned char* endstream = start + length;
660 628
661 if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpa ce) { 629 if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpa ce) {
662 endstream += 2; 630 endstream += 2;
663 } else if (endstream[0] == kLF_PdfWhiteSpace) { 631 } else if (endstream[0] == kLF_PdfWhiteSpace) {
664 endstream += 1; 632 endstream += 1;
665 } 633 }
666 634
667 // TODO(edisonn): verify the next bytes are "endstream" 635 // TODO(edisonn): verify the next bytes are "endstream"
668 636
669 endstream += strlen("endstream"); 637 endstream += strlen("endstream");
670 // TODO(edisonn): Assert? report error/warning? 638 // TODO(edisonn): Assert? report error/warning?
671 dict->addStream(start, (size_t)length); 639 dict->addStream(start, (size_t)length);
672 return endstream; 640 return endstream;
673 } 641 }
674 return start; 642 return start;
675 } 643 }
676 644
677 static const unsigned char* readInlineImageStream(const unsigned char* start, co nst unsigned char* end, SkPdfImageDictionary* inlineImage, SkPdfNativeDoc* doc) { 645 static const unsigned char* readInlineImageStream(const unsigned char* start,
646 const unsigned char* end,
647 SkPdfImageDictionary* inlineIm age,
648 SkPdfNativeDoc* doc) {
678 // We already processed ID keyword, and we should be positioned immediately after it 649 // We already processed ID keyword, and we should be positioned immediately after it
679 650
680 // TODO(edisonn): security: read after end check, or make buffers with extra 2 bytes 651 // TODO(edisonn): security: either make all streams to have extra 2 bytes at the end,
652 // instead of this if.
653 //if (end - start <= 2) {
654 // // TODO(edisonn): warning?
655 // return end; // but can we have a pixel image encoded in 1-2 bytes?
656 //}
657
681 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { 658 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) {
682 start += 2; 659 start += 2;
683 } else if (start[0] == kLF_PdfWhiteSpace) { 660 } else if (start[0] == kLF_PdfWhiteSpace) {
684 start += 1; 661 start += 1;
685 } else if (isPdfWhiteSpace(start[0])) { 662 } else if (isPdfWhiteSpace(start[0])) {
686 start += 1; 663 start += 1;
687 } else { 664 } else {
688 SkASSERT(isPdfDelimiter(start[0])); 665 SkASSERT(isPdfDelimiter(start[0]));
689 // TODO(edisonn): warning? 666 // TODO(edisonn): warning?
690 } 667 }
691 668
692 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start , (char*)end, "EI"); 669 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start , (char*)end, "EI");
693 const unsigned char* endEI = endstream ? endstream + 2 : NULL; // 2 == strl en("EI") 670 const unsigned char* endEI = endstream ? endstream + 2 : NULL; // 2 == strl en("EI")
694 671
695 if (endstream) { 672 if (endstream) {
696 int length = endstream - start; 673 int length = endstream - start;
697 if (*(endstream-1) == kLF_PdfWhiteSpace) length--; 674 if (*(endstream-1) == kLF_PdfWhiteSpace) length--;
698 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; 675 if (*(endstream-2) == kCR_PdfWhiteSpace) length--;
699 inlineImage->addStream(start, (size_t)length); 676 inlineImage->addStream(start, (size_t)length);
700 } else { 677 } else {
701 // TODO(edisonn): report error in inline image stream (ID-EI) section 678 // TODO(edisonn): report error in inline image stream (ID-EI) section
702 // TODO(edisonn): based on filter, try to ignore a missing EI, and read data properly 679 // TODO(edisonn): based on filter, try to ignore a missing EI, and read data properly
703 return end; 680 return end;
704 } 681 }
705 return endEI; 682 return endEI;
706 } 683 }
707 684
708 static const unsigned char* readDictionary(const unsigned char* start, const uns igned char* end, SkPdfNativeObject* dict, SkPdfAllocator* allocator, SkPdfNative Doc* doc) { 685 static const unsigned char* readDictionary(const unsigned char* start, const uns igned char* end,
686 SkPdfNativeObject* dict,
687 SkPdfAllocator* allocator, SkPdfNativ eDoc* doc) {
709 if (allocator == NULL) { 688 if (allocator == NULL) {
710 // TODO(edisonn): report/warning error 689 // TODO(edisonn): report/warning error
711 return end; 690 return end;
712 } 691 }
713 SkPdfNativeObject::makeEmptyDictionary(dict); 692 SkPdfNativeObject::makeEmptyDictionary(dict);
714 // PUT_TRACK_STREAM(dict, start, start) 693 // PUT_TRACK_STREAM(dict, start, start)
715 694
716 start = skipPdfWhiteSpaces(start, end); 695 start = skipPdfWhiteSpaces(start, end);
717 SkPdfAllocator tmpStorage; // keys will be stored in dict, we can free them immediately after set. 696 SkPdfAllocator tmpStorage; // keys will be stored in dict, we can free them after set.
718 697
719 while (start < end && *start == kNamed_PdfDelimiter) { 698 while (start < end && *start == kNamed_PdfDelimiter) {
720 SkPdfNativeObject key; 699 SkPdfNativeObject key;
721 //*start = '\0'; 700 //*start = '\0';
722 start++; 701 start++;
723 start = readName(start, end, &key, &tmpStorage); 702 start = readName(start, end, &key, &tmpStorage);
724 start = skipPdfWhiteSpaces(start, end); 703 start = skipPdfWhiteSpaces(start, end);
725 704
726 if (start < end) { 705 if (start < end) {
727 SkPdfNativeObject* value = allocator->allocObject(); 706 SkPdfNativeObject* value = allocator->allocObject();
728 start = nextObject(start, end, value, allocator, doc); 707 start = nextObject(start, end, value, allocator, doc);
729 708
730 start = skipPdfWhiteSpaces(start, end); 709 start = skipPdfWhiteSpaces(start, end);
731 710
732 if (start < end) { 711 if (start < end) {
733 // seems we have an indirect reference 712 // We should have an indirect reference
734 if (isPdfDigit(*start)) { 713 if (isPdfDigit(*start)) {
735 SkPdfNativeObject generation; 714 SkPdfNativeObject generation;
736 start = nextObject(start, end, &generation, allocator, doc); 715 start = nextObject(start, end, &generation, allocator, doc);
737 716
738 SkPdfNativeObject keywordR; 717 SkPdfNativeObject keywordR;
739 start = nextObject(start, end, &keywordR, allocator, doc); 718 start = nextObject(start, end, &keywordR, allocator, doc);
740 719
741 if (value->isInteger() && generation.isInteger() && keywordR .isKeywordReference()) { 720 if (value->isInteger() && generation.isInteger() &&
721 keywordR.isKeywordReference()) {
742 int64_t id = value->intValue(); 722 int64_t id = value->intValue();
743 SkPdfNativeObject::resetAndMakeReference((unsigned int)i d, (unsigned int)generation.intValue(), value); 723 SkPdfNativeObject::resetAndMakeReference(
724 (unsigned int)id,
725 (unsigned int)generation.intValue(),
726 value);
744 // PUT_TRACK_PARAMETERS_OBJ2(value, &generation) 727 // PUT_TRACK_PARAMETERS_OBJ2(value, &generation)
745 dict->set(&key, value); 728 dict->set(&key, value);
746 } else { 729 } else {
747 // error, ignore 730 // TODO(edisonn) error?, ignore it for now.
748 dict->set(&key, value); 731 dict->set(&key, value);
749 } 732 }
750 } else { 733 } else {
751 // next elem is not a digit, but it might not be / either! 734 // next elem is not a digit, but it might not be / either!
752 dict->set(&key, value); 735 dict->set(&key, value);
753 } 736 }
754 } else { 737 } else {
755 // /key >> 738 // /key >>
756 dict->set(&key, value); 739 dict->set(&key, value);
757 return end; 740 return end;
758 } 741 }
759 start = skipPdfWhiteSpaces(start, end); 742 start = skipPdfWhiteSpaces(start, end);
760 } else { 743 } else {
761 dict->set(&key, &SkPdfNativeObject::kNull); 744 dict->set(&key, &SkPdfNativeObject::kNull);
762 return end; 745 return end;
763 } 746 }
764 } 747 }
765 748
766 // TODO(edisonn): options to ignore these errors
767
768 // now we should expect >> 749 // now we should expect >>
769 start = skipPdfWhiteSpaces(start, end); 750 start = skipPdfWhiteSpaces(start, end);
770 if (*start != kClosedInequityBracket_PdfDelimiter) { 751 if (*start != kClosedInequityBracket_PdfDelimiter) {
771 // TODO(edisonn): report/warning 752 // TODO(edisonn): report/warning
772 } 753 }
773 //*start = '\0'; 754
774 start++; // skip > 755 start++; // skip >
775 if (*start != kClosedInequityBracket_PdfDelimiter) { 756 if (*start != kClosedInequityBracket_PdfDelimiter) {
776 // TODO(edisonn): report/warning 757 // TODO(edisonn): report/warning
777 } 758 }
778 //*start = '\0'; 759
779 start++; // skip > 760 start++; // skip >
780 761
781 //STORE_TRACK_PARAMETER_OFFSET_END(dict,start); 762 //STORE_TRACK_PARAMETER_OFFSET_END(dict,start);
782 763
783 start = readStream(start, end, dict, doc); 764 start = readStream(start, end, dict, doc);
784 765
785 return start; 766 return start;
786 } 767 }
787 768
788 const unsigned char* nextObject(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* token, SkPdfAllocator* allocator, SkPdfNativeDoc* doc) { 769 const unsigned char* nextObject(const unsigned char* start, const unsigned char* end,
770 SkPdfNativeObject* token,
771 SkPdfAllocator* allocator, SkPdfNativeDoc* doc) {
789 const unsigned char* current; 772 const unsigned char* current;
790 773
791 // skip white spaces 774 // skip white spaces
792 start = skipPdfWhiteSpaces(start, end); 775 start = skipPdfWhiteSpaces(start, end);
793 776
794 if (start >= end) { 777 if (start >= end) {
795 return end; 778 return end;
796 } 779 }
797 780
798 current = endOfPdfToken(start, end); 781 current = endOfPdfToken(start, end);
799 782
800 // no token, len would be 0 783 // no token, len would be 0
801 if (current == start || current == end) { 784 if (current == start || current == end) {
802 return end; 785 return end;
803 } 786 }
804 787
805 int tokenLen = current - start; 788 int tokenLen = current - start;
806 789
807 if (tokenLen == 1) { 790 if (tokenLen == 1) {
808 // start array 791 // start array
809 switch (*start) { 792 switch (*start) {
810 case kOpenedSquareBracket_PdfDelimiter: 793 case kOpenedSquareBracket_PdfDelimiter:
811 //*start = '\0';
812 return readArray(current, end, token, allocator, doc); 794 return readArray(current, end, token, allocator, doc);
813 795
814 case kOpenedRoundBracket_PdfDelimiter: 796 case kOpenedRoundBracket_PdfDelimiter:
815 //*start = '\0';
816 return readString(start + 1, end, token, allocator); 797 return readString(start + 1, end, token, allocator);
817 798
818 case kOpenedInequityBracket_PdfDelimiter: 799 case kOpenedInequityBracket_PdfDelimiter:
819 //*start = '\0';
820 if (end > start + 1 && start[1] == kOpenedInequityBracket_PdfDel imiter) { 800 if (end > start + 1 && start[1] == kOpenedInequityBracket_PdfDel imiter) {
821 //start[1] = '\0'; // optional
822 // TODO(edisonn): pass here the length somehow? 801 // TODO(edisonn): pass here the length somehow?
823 return readDictionary(start + 2, end, token, allocator, doc) ; // skip << 802 return readDictionary(start + 2, end, token, allocator, doc) ; // skip <<
824 } else { 803 } else {
825 return readHexString(start + 1, end, token, allocator); // skip < 804 return readHexString(start + 1, end, token, allocator); // skip <
826 } 805 }
827 806
828 case kNamed_PdfDelimiter: 807 case kNamed_PdfDelimiter:
829 //*start = '\0';
830 return readName(start + 1, end, token, allocator); 808 return readName(start + 1, end, token, allocator);
831 809
832 // TODO(edisonn): what to do curly brackets? read spec! 810 // TODO(edisonn): what to do curly brackets?
833 case kOpenedCurlyBracket_PdfDelimiter: 811 case kOpenedCurlyBracket_PdfDelimiter:
834 default: 812 default:
835 break; 813 break;
836 } 814 }
837 815
838 SkASSERT(!isPdfWhiteSpace(*start)); 816 SkASSERT(!isPdfWhiteSpace(*start));
839 if (isPdfDelimiter(*start)) { 817 if (isPdfDelimiter(*start)) {
840 // TODO(edisonn): how stream ] } > ) will be handled? 818 // TODO(edisonn): how unexpected stream ] } > ) will be handled?
841 // for now ignore, and it will become a keyword to be ignored 819 // for now ignore, and it will become a keyword to be ignored
842 } 820 }
843 } 821 }
844 822
845 if (tokenLen == 4 && start[0] == 'n' && start[1] == 'u' && start[2] == 'l' & & start[3] == 'l') { 823 if (tokenLen == 4 && start[0] == 'n' && start[1] == 'u' && start[2] == 'l' & & start[3] == 'l') {
846 SkPdfNativeObject::makeNull(token); 824 SkPdfNativeObject::makeNull(token);
847 // PUT_TRACK_STREAM(start, start + 4) 825 // PUT_TRACK_STREAM(start, start + 4)
848 return current; 826 return current;
849 } 827 }
850 828
851 if (tokenLen == 4 && start[0] == 't' && start[1] == 'r' && start[2] == 'u' & & start[3] == 'e') { 829 if (tokenLen == 4 && start[0] == 't' && start[1] == 'r' && start[2] == 'u' & & start[3] == 'e') {
852 SkPdfNativeObject::makeBoolean(true, token); 830 SkPdfNativeObject::makeBoolean(true, token);
853 // PUT_TRACK_STREAM(start, start + 4) 831 // PUT_TRACK_STREAM(start, start + 4)
854 return current; 832 return current;
855 } 833 }
856 834
857 if (tokenLen == 5 && start[0] == 'f' && start[1] == 'a' && start[2] == 'l' & & start[3] == 's' && start[4] == 'e') { 835 // TODO(edisonn): again, make all buffers have 5 extra bytes
836 if (tokenLen == 5 && start[0] == 'f' &&
837 start[1] == 'a' &&
838 start[2] == 'l' &&
839 start[3] == 's' &&
840 start[4] == 'e') {
858 SkPdfNativeObject::makeBoolean(false, token); 841 SkPdfNativeObject::makeBoolean(false, token);
859 // PUT_TRACK_STREAM(start, start + 5) 842 // PUT_TRACK_STREAM(start, start + 5)
860 return current; 843 return current;
861 } 844 }
862 845
863 if (isPdfNumeric(*start)) { 846 if (isPdfNumeric(*start)) {
864 SkPdfNativeObject::makeNumeric(start, current, token); 847 SkPdfNativeObject::makeNumeric(start, current, token);
865 // PUT_TRACK_STREAM(start, current) 848 // PUT_TRACK_STREAM(start, current)
866 } else { 849 } else {
867 SkPdfNativeObject::makeKeyword(start, current, token); 850 SkPdfNativeObject::makeKeyword(start, current, token);
(...skipping 27 matching lines...) Expand all
895 if (fCurrentUsed >= BUFFER_SIZE) { 878 if (fCurrentUsed >= BUFFER_SIZE) {
896 fHistory.push(fCurrent); 879 fHistory.push(fCurrent);
897 fCurrent = allocBlock(); 880 fCurrent = allocBlock();
898 fCurrentUsed = 0; 881 fCurrentUsed = 0;
899 fSizeInBytes += sizeof(SkPdfNativeObject*); 882 fSizeInBytes += sizeof(SkPdfNativeObject*);
900 } 883 }
901 fCurrentUsed++; 884 fCurrentUsed++;
902 return &fCurrent[fCurrentUsed - 1]; 885 return &fCurrent[fCurrentUsed - 1];
903 } 886 }
904 887
905 // TODO(edisonn): perf: do no copy the buffers, but use them, and mark cache the result, so there is no need of a second pass 888 // TODO(edisonn): perf: do no copy the buffers, but reuse them, and mark cache t he result,
906 SkPdfNativeTokenizer::SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream, SkP dfAllocator* allocator, SkPdfNativeDoc* doc) : fDoc(doc), fAllocator(allocator), fUncompressedStream(NULL), fUncompressedStreamEnd(NULL), fEmpty(false), fHasPut Back(false) { 889 // so there is no need of a second pass
890 SkPdfNativeTokenizer::SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream,
891 SkPdfAllocator* allocator,
892 SkPdfNativeDoc* doc)
893 : fDoc(doc)
894 , fAllocator(allocator)
895 , fUncompressedStream(NULL)
896 , fUncompressedStreamEnd(NULL)
897 , fEmpty(false)
898 , fHasPutBack(false) {
907 const unsigned char* buffer = NULL; 899 const unsigned char* buffer = NULL;
908 size_t len = 0; 900 size_t len = 0;
909 objWithStream->GetFilteredStreamRef(&buffer, &len); 901 objWithStream->GetFilteredStreamRef(&buffer, &len);
910 // TODO(edisonn): hack, find end of object 902 // TODO(edisonn): really bad hack, find end of object (endobj might be in a comment!)
903 // we need to do now for perf, and our generated pdfs do not have comments,
904 // but we need to remove this hack for pdfs in the wild
911 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); 905 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj");
912 if (endobj) { 906 if (endobj) {
913 len = endobj - (char*)buffer + strlen("endobj"); 907 len = endobj - (char*)buffer + strlen("endobj");
914 } 908 }
915 fUncompressedStreamStart = fUncompressedStream = buffer; 909 fUncompressedStreamStart = fUncompressedStream = buffer;
916 fUncompressedStreamEnd = fUncompressedStream + len; 910 fUncompressedStreamEnd = fUncompressedStream + len;
917 } 911 }
918 912
919 SkPdfNativeTokenizer::SkPdfNativeTokenizer(const unsigned char* buffer, int len, SkPdfAllocator* allocator, SkPdfNativeDoc* doc) : fDoc(doc), fAllocator(allocat or), fEmpty(false), fHasPutBack(false) { 913 SkPdfNativeTokenizer::SkPdfNativeTokenizer(const unsigned char* buffer, int len,
920 // TODO(edisonn): hack, find end of object 914 SkPdfAllocator* allocator,
915 SkPdfNativeDoc* doc) : fDoc(doc)
916 , fAllocator(all ocator)
917 , fEmpty(false)
918 , fHasPutBack(fa lse) {
919 // TODO(edisonn): really bad hack, find end of object (endobj might be in a comment!)
920 // we need to do now for perf, and our generated pdfs do not have comments,
921 // but we need to remove this hack for pdfs in the wild
921 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); 922 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj");
922 if (endobj) { 923 if (endobj) {
923 len = endobj - (char*)buffer + strlen("endobj"); 924 len = endobj - (char*)buffer + strlen("endobj");
924 } 925 }
925 fUncompressedStreamStart = fUncompressedStream = buffer; 926 fUncompressedStreamStart = fUncompressedStream = buffer;
926 fUncompressedStreamEnd = fUncompressedStream + len; 927 fUncompressedStreamEnd = fUncompressedStream + len;
927 } 928 }
928 929
929 SkPdfNativeTokenizer::~SkPdfNativeTokenizer() { 930 SkPdfNativeTokenizer::~SkPdfNativeTokenizer() {
930 } 931 }
931 932
932 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { 933 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) {
933 SkPdfNativeObject obj;
934 #ifdef PDF_TRACE_READ_TOKEN 934 #ifdef PDF_TRACE_READ_TOKEN
935 static int read_op = 0; 935 static int read_op = 0;
936 #endif 936 #endif
937
937 token->fKeyword = NULL; 938 token->fKeyword = NULL;
938 token->fObject = NULL; 939 token->fObject = NULL;
939 940
940 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS treamEnd); 941 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS treamEnd);
941 if (fUncompressedStream >= fUncompressedStreamEnd) { 942 if (fUncompressedStream >= fUncompressedStreamEnd) {
942 return false; 943 return false;
943 } 944 }
944 945
946 SkPdfNativeObject obj;
945 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd , &obj, fAllocator, fDoc); 947 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd , &obj, fAllocator, fDoc);
946 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart) 948 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)
947 949
948 // If it is a keyword, we will only get the pointer of the string 950 // If it is a keyword, we will only get the pointer of the string.
949 if (obj.type() == SkPdfNativeObject::kKeyword_PdfObjectType) { 951 if (obj.type() == SkPdfNativeObject::kKeyword_PdfObjectType) {
950 token->fKeyword = obj.c_str(); 952 token->fKeyword = obj.c_str();
951 token->fKeywordLength = obj.lenstr(); 953 token->fKeywordLength = obj.lenstr();
952 token->fType = kKeyword_TokenType; 954 token->fType = kKeyword_TokenType;
953 } else { 955 } else {
954 SkPdfNativeObject* pobj = fAllocator->allocObject(); 956 SkPdfNativeObject* pobj = fAllocator->allocObject();
955 *pobj = obj; 957 *pobj = obj;
956 token->fObject = pobj; 958 token->fObject = pobj;
957 token->fType = kObject_TokenType; 959 token->fType = kObject_TokenType;
958 } 960 }
959 961
960 #ifdef PDF_TRACE_READ_TOKEN 962 #ifdef PDF_TRACE_READ_TOKEN
961 read_op++; 963 read_op++;
962 #if 0 964 #if 0
963 if (548 == read_op) { 965 if (548 == read_op) {
964 printf("break;\n"); 966 printf("break;\n");
965 } 967 }
966 #endif 968 #endif
967 printf("%i READ %s %s\n", read_op, token->fType == kKeyword_TokenType ? "Key word" : "Object", token->fKeyword ? SkString(token->fKeyword, token->fKeywordLen gth).c_str() : token->fObject->toString().c_str()); 969 printf("%i READ %s %s\n", read_op, token->fType == kKeyword_TokenType ? "Key word" : "Object",
970 token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_ str() :
971 token->fObject->toString().c_str());
968 #endif 972 #endif
969 973
970 return true; 974 return true;
971 } 975 }
972 976
973 void SkPdfNativeTokenizer::PutBack(PdfToken token) { 977 void SkPdfNativeTokenizer::PutBack(PdfToken token) {
974 SkASSERT(!fHasPutBack); 978 SkASSERT(!fHasPutBack);
975 fHasPutBack = true; 979 fHasPutBack = true;
976 fPutBack = token; 980 fPutBack = token;
977 #ifdef PDF_TRACE_READ_TOKEN 981 #ifdef PDF_TRACE_READ_TOKEN
978 printf("PUT_BACK %s %s\n", token.fType == kKeyword_TokenType ? "Keyword" : " Object", token.fKeyword ? SkString(token.fKeyword, token.fKeywordLength).c_str() : token.fObject->toString().c_str()); 982 printf("PUT_BACK %s %s\n", token.fType == kKeyword_TokenType ? "Keyword" : " Object",
983 token.fKeyword ? SkString(token.fKeyword, token.fKeywordLength).c_str () :
984 token.fObject->toString().c_str());
979 #endif 985 #endif
980 } 986 }
981 987
982 bool SkPdfNativeTokenizer::readToken(PdfToken* token) { 988 bool SkPdfNativeTokenizer::readToken(PdfToken* token) {
983 if (fHasPutBack) { 989 if (fHasPutBack) {
984 *token = fPutBack; 990 *token = fPutBack;
985 fHasPutBack = false; 991 fHasPutBack = false;
986 #ifdef PDF_TRACE_READ_TOKEN 992 #ifdef PDF_TRACE_READ_TOKEN
987 printf("READ_BACK %s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : "Object", token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_ str() : token->fObject->toString().c_str()); 993 printf("READ_BACK %s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : "Object",
994 token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_ str() :
995 token->fObject->toString().c_str());
988 #endif 996 #endif
989 return true; 997 return true;
990 } 998 }
991 999
992 if (fEmpty) { 1000 if (fEmpty) {
993 #ifdef PDF_TRACE_READ_TOKEN 1001 #ifdef PDF_TRACE_READ_TOKEN
994 printf("EMPTY TOKENIZER\n"); 1002 printf("EMPTY TOKENIZER\n");
995 #endif 1003 #endif
996 return false; 1004 return false;
997 } 1005 }
998 1006
999 return readTokenCore(token); 1007 return readTokenCore(token);
1000 } 1008 }
1001 1009
1002 #define DECLARE_PDF_NAME(longName) SkPdfName longName((char*)#longName) 1010 #define DECLARE_PDF_NAME(longName) SkPdfName longName((char*)#longName)
1003 1011
1004 // keys 1012 // keys
1005 DECLARE_PDF_NAME(BitsPerComponent); 1013 DECLARE_PDF_NAME(BitsPerComponent);
1006 DECLARE_PDF_NAME(ColorSpace); 1014 DECLARE_PDF_NAME(ColorSpace);
1007 DECLARE_PDF_NAME(Decode); 1015 DECLARE_PDF_NAME(Decode);
1008 DECLARE_PDF_NAME(DecodeParms); 1016 DECLARE_PDF_NAME(DecodeParms);
1009 DECLARE_PDF_NAME(Filter); 1017 DECLARE_PDF_NAME(Filter);
1010 DECLARE_PDF_NAME(Height); 1018 DECLARE_PDF_NAME(Height);
1011 DECLARE_PDF_NAME(ImageMask); 1019 DECLARE_PDF_NAME(ImageMask);
1012 DECLARE_PDF_NAME(Intent); // PDF 1.1 - the key, or the abreviations? 1020 DECLARE_PDF_NAME(Intent); // PDF 1.1 - the key, or the abBreviations?
1013 DECLARE_PDF_NAME(Interpolate); 1021 DECLARE_PDF_NAME(Interpolate);
1014 DECLARE_PDF_NAME(Width); 1022 DECLARE_PDF_NAME(Width);
1015 1023
1016 // values 1024 // values
1017 DECLARE_PDF_NAME(DeviceGray); 1025 DECLARE_PDF_NAME(DeviceGray);
1018 DECLARE_PDF_NAME(DeviceRGB); 1026 DECLARE_PDF_NAME(DeviceRGB);
1019 DECLARE_PDF_NAME(DeviceCMYK); 1027 DECLARE_PDF_NAME(DeviceCMYK);
1020 DECLARE_PDF_NAME(Indexed); 1028 DECLARE_PDF_NAME(Indexed);
1021 DECLARE_PDF_NAME(ASCIIHexDecode); 1029 DECLARE_PDF_NAME(ASCIIHexDecode);
1022 DECLARE_PDF_NAME(ASCII85Decode); 1030 DECLARE_PDF_NAME(ASCII85Decode);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1072 1080
1073 SkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() { 1081 SkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() {
1074 // BI already processed 1082 // BI already processed
1075 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS treamEnd); 1083 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS treamEnd);
1076 if (fUncompressedStream >= fUncompressedStreamEnd) { 1084 if (fUncompressedStream >= fUncompressedStreamEnd) {
1077 return NULL; 1085 return NULL;
1078 } 1086 }
1079 1087
1080 SkPdfImageDictionary* inlineImage = (SkPdfImageDictionary*)fAllocator->alloc Object(); 1088 SkPdfImageDictionary* inlineImage = (SkPdfImageDictionary*)fAllocator->alloc Object();
1081 SkPdfNativeObject::makeEmptyDictionary(inlineImage); 1089 SkPdfNativeObject::makeEmptyDictionary(inlineImage);
1082 // PUT_TRACK_STREAM_ARGS_EXPL(fStreamId, fUncompressedStream - fUncompresse dStreamStart, fUncompressedStream - fUncompressedStreamStart) 1090 // PUT_TRACK_STREAM_ARGS_EXPL(fStreamId, fUncompressedStream - fUncompresse dStreamStart,
1091 // fUncompressedStream - fUncompressedStreamStar t)
1083 1092
1084 while (fUncompressedStream < fUncompressedStreamEnd) { 1093 while (fUncompressedStream < fUncompressedStreamEnd) {
1085 SkPdfNativeObject* key = fAllocator->allocObject(); 1094 SkPdfNativeObject* key = fAllocator->allocObject();
1086 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStrea mEnd, key, fAllocator, fDoc); 1095 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStrea mEnd, key,
1096 fAllocator, fDoc);
1087 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)s 1097 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)s
1088 1098
1089 if (key->isKeyword() && key->lenstr() == 2 && key->c_str()[0] == 'I' && key->c_str()[1] == 'D') { // ID 1099 if (key->isKeyword() && key->lenstr() == 2 &&
1090 fUncompressedStream = readInlineImageStream(fUncompressedStream, fUn compressedStreamEnd, inlineImage, fDoc); 1100 key->c_str()[0] == 'I' && key->c_str()[1] == 'D') { // ID
1101 fUncompressedStream = readInlineImageStream(fUncompressedStream, fUn compressedStreamEnd,
1102 inlineImage, fDoc);
1091 return inlineImage; 1103 return inlineImage;
1092 } else { 1104 } else {
1093 SkPdfNativeObject* obj = fAllocator->allocObject(); 1105 SkPdfNativeObject* obj = fAllocator->allocObject();
1094 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedS treamEnd, obj, fAllocator, fDoc); 1106 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedS treamEnd, obj,
1107 fAllocator, fDoc);
1095 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart) s 1108 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart) s
1096 // TODO(edisonn): perf maybe we should not expand abreviation like t his 1109 // TODO(edisonn): perf maybe we should not expand abBreviation like this
1097 inlineImage->set(inlineImageKeyAbbreviationExpand(key), 1110 inlineImage->set(inlineImageKeyAbbreviationExpand(key),
1098 inlineImageValueAbbreviationExpand(obj)); 1111 inlineImageValueAbbreviationExpand(obj));
1099 } 1112 }
1100 } 1113 }
1101 // TODO(edisonn): report end of data with inline image without an EI 1114 // TODO(edisonn): report end of data with inline image without an EI
1102 return inlineImage; 1115 return inlineImage;
1103 } 1116 }
OLDNEW
« no previous file with comments | « experimental/PdfViewer/pdfparser/native/SkPdfNativeObject.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698