| OLD | NEW |
| 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 "SkPdfNativeTokenizer.h" | 8 #include "SkPdfNativeTokenizer.h" |
| 9 #include "SkPdfNativeObject.h" | 9 #include "SkPdfNativeObject.h" |
| 10 #include "SkPdfConfig.h" | 10 #include "SkPdfConfig.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (haySta
rt+needleLen == hayEnd)) && | 31 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (haySta
rt+needleLen == hayEnd)) && |
| 32 strncmp(hayStart, needle, needleLen) == 0) { | 32 strncmp(hayStart, needle, needleLen) == 0) { |
| 33 return hayStart; | 33 return hayStart; |
| 34 } | 34 } |
| 35 hayStart++; | 35 hayStart++; |
| 36 } | 36 } |
| 37 return NULL; | 37 return NULL; |
| 38 } | 38 } |
| 39 | 39 |
| 40 #ifdef PDF_TRACE_TOKENIZER | 40 #ifdef PDF_TRACE_TOKENIZER |
| 41 static void TRACE_INDENT(int level, const char* type) { | |
| 42 static int id = 0; | |
| 43 id++; | |
| 44 #if 0 | |
| 45 if (478613 == id) { | |
| 46 printf("break;\n"); | |
| 47 } | |
| 48 #endif | |
| 49 // all types should have 2 letters, so the text is alligned nicely | |
| 50 printf("\n%10i %15s: ", id, type); | |
| 51 for (int i = 0 ; i < level; i++) { | |
| 52 printf(" "); | |
| 53 } | |
| 54 } | |
| 55 | 41 |
| 56 static void TRACE_COMMENT(char ch) { | 42 static void TRACE_COMMENT(char ch) { |
| 57 printf("%c", ch); | 43 printf("%c", ch); |
| 58 } | 44 } |
| 59 | 45 |
| 60 static void TRACE_TK(char ch) { | 46 static void TRACE_TK(char ch) { |
| 61 printf("%c", ch); | 47 printf("%c", ch); |
| 62 } | 48 } |
| 63 | 49 |
| 64 static void TRACE_NAME(const unsigned char* start, const unsigned char* end) { | 50 static void TRACE_NAME(const unsigned char* start, const unsigned char* end) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 79 | 65 |
| 80 static void TRACE_HEXSTRING(const unsigned char* start, const unsigned char* end
) { | 66 static void TRACE_HEXSTRING(const unsigned char* start, const unsigned char* end
) { |
| 81 while (start < end) { | 67 while (start < end) { |
| 82 printf("%c", *start); | 68 printf("%c", *start); |
| 83 start++; | 69 start++; |
| 84 } | 70 } |
| 85 printf("\n"); | 71 printf("\n"); |
| 86 } | 72 } |
| 87 | 73 |
| 88 #else | 74 #else |
| 89 #define TRACE_INDENT(level,type) | |
| 90 #define TRACE_COMMENT(ch) | 75 #define TRACE_COMMENT(ch) |
| 91 #define TRACE_TK(ch) | 76 #define TRACE_TK(ch) |
| 92 #define TRACE_NAME(start,end) | 77 #define TRACE_NAME(start,end) |
| 93 #define TRACE_STRING(start,end) | 78 #define TRACE_STRING(start,end) |
| 94 #define TRACE_HEXSTRING(start,end) | 79 #define TRACE_HEXSTRING(start,end) |
| 95 #endif | 80 #endif |
| 96 | 81 |
| 97 const unsigned char* skipPdfWhiteSpaces(int level, const unsigned char* start, c
onst unsigned char* end) { | 82 const unsigned char* skipPdfWhiteSpaces(const unsigned char* start, const unsign
ed char* end) { |
| 98 TRACE_INDENT(level, "White Space"); | |
| 99 while (start < end && (isPdfWhiteSpace(*start) || *start == kComment_PdfDeli
miter)) { | 83 while (start < end && (isPdfWhiteSpace(*start) || *start == kComment_PdfDeli
miter)) { |
| 100 TRACE_COMMENT(*start); | 84 TRACE_COMMENT(*start); |
| 101 if (*start == kComment_PdfDelimiter) { | 85 if (*start == kComment_PdfDelimiter) { |
| 102 // skip the comment until end of line | 86 // skip the comment until end of line |
| 103 while (start < end && !isPdfEOL(*start)) { | 87 while (start < end && !isPdfEOL(*start)) { |
| 104 //*start = '\0'; | 88 //*start = '\0'; |
| 105 start++; | 89 start++; |
| 106 TRACE_COMMENT(*start); | 90 TRACE_COMMENT(*start); |
| 107 } | 91 } |
| 108 } else { | 92 } else { |
| 109 //*start = '\0'; | 93 //*start = '\0'; |
| 110 start++; | 94 start++; |
| 111 } | 95 } |
| 112 } | 96 } |
| 113 return start; | 97 return start; |
| 114 } | 98 } |
| 115 | 99 |
| 116 // TODO(edisonn) '(' can be used, will it break the string a delimiter or space
inside () ? | 100 // TODO(edisonn) '(' can be used, will it break the string a delimiter or space
inside () ? |
| 117 const unsigned char* endOfPdfToken(int level, const unsigned char* start, const
unsigned char* end) { | 101 const unsigned char* endOfPdfToken(const unsigned char* start, const unsigned ch
ar* end) { |
| 118 //int opened brackets | |
| 119 //TODO(edisonn): what out for special chars, like \n, \032 | |
| 120 TRACE_INDENT(level, "Token"); | |
| 121 | |
| 122 SkASSERT(!isPdfWhiteSpace(*start)); | 102 SkASSERT(!isPdfWhiteSpace(*start)); |
| 123 | 103 |
| 124 if (start < end && isPdfDelimiter(*start)) { | 104 if (start < end && isPdfDelimiter(*start)) { |
| 125 TRACE_TK(*start); | 105 TRACE_TK(*start); |
| 126 start++; | 106 start++; |
| 127 return start; | 107 return start; |
| 128 } | 108 } |
| 129 | 109 |
| 130 while (start < end && !isPdfWhiteSpaceOrPdfDelimiter(*start)) { | 110 while (start < end && !isPdfWhiteSpaceOrPdfDelimiter(*start)) { |
| 131 TRACE_TK(*start); | 111 TRACE_TK(*start); |
| 132 start++; | 112 start++; |
| 133 } | 113 } |
| 134 return start; | 114 return start; |
| 135 } | 115 } |
| 136 | 116 |
| 137 // last elem has to be ] | 117 // last elem has to be ] |
| 138 static const unsigned char* readArray(int level, const unsigned char* start, con
st unsigned char* end, SkPdfNativeObject* array, SkPdfAllocator* allocator, SkPd
fNativeDoc* doc GET_TRACK_STREAM) { | 118 static const unsigned char* readArray(const unsigned char* start, const unsigned
char* end, SkPdfNativeObject* array, SkPdfAllocator* allocator, SkPdfNativeDoc*
doc) { |
| 139 SkPdfNativeObject::makeEmptyArray(array PUT_TRACK_STREAM(start, start)); | 119 SkPdfNativeObject::makeEmptyArray(array); |
| 120 // PUT_TRACK_STREAM(array, start, start) |
| 140 | 121 |
| 141 if (allocator == NULL) { | 122 if (allocator == NULL) { |
| 142 // TODO(edisonn): report/warning error | 123 // TODO(edisonn): report/warning error |
| 143 return end; | 124 return end; |
| 144 } | 125 } |
| 145 | 126 |
| 146 TRACE_INDENT(level, "Array"); | |
| 147 while (start < end) { | 127 while (start < end) { |
| 148 // skip white spaces | 128 // skip white spaces |
| 149 start = skipPdfWhiteSpaces(level + 1, start, end); | 129 start = skipPdfWhiteSpaces(start, end); |
| 150 | 130 |
| 151 const unsigned char* endOfToken = endOfPdfToken(level + 1, start, end); | 131 const unsigned char* endOfToken = endOfPdfToken(start, end); |
| 152 | 132 |
| 153 if (endOfToken == start) { | 133 if (endOfToken == start) { |
| 154 // TODO(edisonn): report error in pdf file (end of stream with ] for
end of aray | 134 // TODO(edisonn): report error in pdf file (end of stream with ] for
end of aray |
| 155 return start; | 135 return start; |
| 156 } | 136 } |
| 157 | 137 |
| 158 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit
er) { | 138 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit
er) { |
| 159 return endOfToken; | 139 return endOfToken; |
| 160 } | 140 } |
| 161 | 141 |
| 162 SkPdfNativeObject* newObj = allocator->allocObject(); | 142 SkPdfNativeObject* newObj = allocator->allocObject(); |
| 163 start = nextObject(level + 1, start, end, newObj, allocator, doc PUT_TRA
CK_STREAM_ARGS); | 143 start = nextObject(start, end, newObj, allocator, doc); |
| 164 // TODO(edisonn): perf/memory: put the variables on the stack, and flush
them on the array only when | 144 // TODO(edisonn): perf/memory: put the variables on the stack, and flush
them on the array only when |
| 165 // we are sure they are not references! | 145 // we are sure they are not references! |
| 166 if (newObj->isKeywordReference() && array->size() >= 2 && array->objAtAI
ndex(array->size() - 1)->isInteger() && array->objAtAIndex(array->size() - 2)->i
sInteger()) { | 146 if (newObj->isKeywordReference() && array->size() >= 2 && array->objAtAI
ndex(array->size() - 1)->isInteger() && array->objAtAIndex(array->size() - 2)->i
sInteger()) { |
| 167 SkPdfNativeObject* gen = array->removeLastInArray(); | 147 SkPdfNativeObject* gen = array->removeLastInArray(); |
| 168 SkPdfNativeObject* id = array->removeLastInArray(); | 148 SkPdfNativeObject* id = array->removeLastInArray(); |
| 169 | 149 |
| 170 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue(
), (unsigned int)gen->intValue(), newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj)); | 150 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue(
), (unsigned int)gen->intValue(), newObj); |
| 151 // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now |
| 171 | 152 |
| 172 } | 153 } |
| 173 array->appendInArray(newObj); | 154 array->appendInArray(newObj); |
| 174 } | 155 } |
| 175 // TODO(edisonn): report not reached, we should never get here | 156 // TODO(edisonn): report not reached, we should never get here |
| 176 // TODO(edisonn): there might be a bug here, enable an assert and run it on
files | 157 // TODO(edisonn): there might be a bug here, enable an assert and run it on
files |
| 177 // or it might be that the files were actually corrupted | 158 // or it might be that the files were actually corrupted |
| 178 return start; | 159 return start; |
| 179 } | 160 } |
| 180 | 161 |
| 181 // When we read strings we will rewrite the string so we will reuse the memory | 162 // When we read strings we will rewrite the string so we will reuse the memory |
| 182 // when we start to read the string, we already consumed the opened bracket | 163 // when we start to read the string, we already consumed the opened bracket |
| 183 | 164 |
| 184 // TODO(edisonn): space: add paramater, taht would report if we need to allocate
new buffer, or we can reuse the one we have | 165 // TODO(edisonn): space: add paramater, taht would report if we need to allocate
new buffer, or we can reuse the one we have |
| 185 | 166 |
| 186 static const unsigned char* readString(int level, const unsigned char* start, co
nst unsigned char* end, unsigned char* out) { | 167 static const unsigned char* readString(const unsigned char* start, const unsigne
d char* end, unsigned char* out) { |
| 187 TRACE_INDENT(level, "String"); | |
| 188 const unsigned char* in = start; | 168 const unsigned char* in = start; |
| 189 bool hasOut = (out != NULL); | 169 bool hasOut = (out != NULL); |
| 190 | 170 |
| 191 int openRoundBrackets = 1; | 171 int openRoundBrackets = 1; |
| 192 while (in < end) { | 172 while (in < end) { |
| 193 openRoundBrackets += ((*in) == kOpenedRoundBracket_PdfDelimiter); | 173 openRoundBrackets += ((*in) == kOpenedRoundBracket_PdfDelimiter); |
| 194 openRoundBrackets -= ((*in) == kClosedRoundBracket_PdfDelimiter); | 174 openRoundBrackets -= ((*in) == kClosedRoundBracket_PdfDelimiter); |
| 195 if (openRoundBrackets == 0) { | 175 if (openRoundBrackets == 0) { |
| 196 in++; // consumed ) | 176 in++; // consumed ) |
| 197 break; | 177 break; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 } | 277 } |
| 298 } | 278 } |
| 299 | 279 |
| 300 if (hasOut) { | 280 if (hasOut) { |
| 301 return in; // consumed already ) at the end of the string | 281 return in; // consumed already ) at the end of the string |
| 302 } else { | 282 } else { |
| 303 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string | 283 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string |
| 304 } | 284 } |
| 305 } | 285 } |
| 306 | 286 |
| 307 static int readStringLength(int level, const unsigned char* start, const unsigne
d char* end) { | 287 static int readStringLength(const unsigned char* start, const unsigned char* end
) { |
| 308 return readString(level, start, end, NULL) - start; | 288 return readString(start, end, NULL) - start; |
| 309 } | 289 } |
| 310 | 290 |
| 311 static const unsigned char* readString(int level, const unsigned char* start, co
nst unsigned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator GET_TR
ACK_STREAM) { | 291 static const unsigned char* readString(const unsigned char* start, const unsigne
d char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { |
| 312 if (!allocator) { | 292 if (!allocator) { |
| 313 return end; | 293 return end; |
| 314 } | 294 } |
| 315 int outLength = readStringLength(level, start, end); | 295 int outLength = readStringLength(start, end); |
| 316 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer | 296 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer |
| 317 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 297 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 318 const unsigned char* now = readString(level, start, end, out); | 298 const unsigned char* now = readString(start, end, out); |
| 319 SkPdfNativeObject::makeString(out, out + outLength, str PUT_TRACK_STREAM(sta
rt, now)); | 299 SkPdfNativeObject::makeString(out, out + outLength, str); |
| 300 // PUT_TRACK_STREAM(str, start, now) |
| 320 TRACE_STRING(out, out + outLength); | 301 TRACE_STRING(out, out + outLength); |
| 321 return now; // consumed already ) at the end of the string | 302 return now; // consumed already ) at the end of the string |
| 322 } | 303 } |
| 323 | 304 |
| 324 static const unsigned char* readHexString(int level, const unsigned char* start,
const unsigned char* end, unsigned char* out) { | 305 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, unsigned char* out) { |
| 325 TRACE_INDENT(level, "HexString"); | |
| 326 bool hasOut = (out != NULL); | 306 bool hasOut = (out != NULL); |
| 327 const unsigned char* in = start; | 307 const unsigned char* in = start; |
| 328 | 308 |
| 329 unsigned char code = 0; | 309 unsigned char code = 0; |
| 330 | 310 |
| 331 while (in < end) { | 311 while (in < end) { |
| 332 while (in < end && isPdfWhiteSpace(*in)) { | 312 while (in < end && isPdfWhiteSpace(*in)) { |
| 333 in++; | 313 in++; |
| 334 } | 314 } |
| 335 | 315 |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 in++; | 424 in++; |
| 445 } | 425 } |
| 446 | 426 |
| 447 if (hasOut) { | 427 if (hasOut) { |
| 448 return in; // consumed already > at the end of the string | 428 return in; // consumed already > at the end of the string |
| 449 } else { | 429 } else { |
| 450 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string | 430 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string |
| 451 } | 431 } |
| 452 } | 432 } |
| 453 | 433 |
| 454 static int readHexStringLength(int level, const unsigned char* start, const unsi
gned char* end) { | 434 static int readHexStringLength(const unsigned char* start, const unsigned char*
end) { |
| 455 return readHexString(level, start, end, NULL) - start; | 435 return readHexString(start, end, NULL) - start; |
| 456 } | 436 } |
| 457 | 437 |
| 458 static const unsigned char* readHexString(int level, const unsigned char* start,
const unsigned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator GET
_TRACK_STREAM) { | 438 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { |
| 459 if (!allocator) { | 439 if (!allocator) { |
| 460 return end; | 440 return end; |
| 461 } | 441 } |
| 462 int outLength = readHexStringLength(level, start, end); | 442 int outLength = readHexStringLength(start, end); |
| 463 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer | 443 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer |
| 464 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 444 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 465 const unsigned char* now = readHexString(level, start, end, out); | 445 const unsigned char* now = readHexString(start, end, out); |
| 466 SkPdfNativeObject::makeHexString(out, out + outLength, str PUT_TRACK_STREAM(
start, now)); | 446 SkPdfNativeObject::makeHexString(out, out + outLength, str); |
| 447 // str PUT_TRACK_STREAM(start, now) |
| 467 TRACE_HEXSTRING(out, out + outLength); | 448 TRACE_HEXSTRING(out, out + outLength); |
| 468 return now; // consumed already > at the end of the string | 449 return now; // consumed already > at the end of the string |
| 469 } | 450 } |
| 470 | 451 |
| 471 // TODO(edisonn): before PDF 1.2 name could not have special characters, add ver
sion parameter | 452 // TODO(edisonn): before PDF 1.2 name could not have special characters, add ver
sion parameter |
| 472 static const unsigned char* readName(int level, const unsigned char* start, cons
t unsigned char* end, unsigned char* out) { | 453 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, unsigned char* out) { |
| 473 TRACE_INDENT(level, "Name"); | |
| 474 bool hasOut = (out != NULL); | 454 bool hasOut = (out != NULL); |
| 475 const unsigned char* in = start; | 455 const unsigned char* in = start; |
| 476 | 456 |
| 477 unsigned char code = 0; | 457 unsigned char code = 0; |
| 478 | 458 |
| 479 while (in < end) { | 459 while (in < end) { |
| 480 if (isPdfWhiteSpaceOrPdfDelimiter(*in)) { | 460 if (isPdfWhiteSpaceOrPdfDelimiter(*in)) { |
| 481 break; | 461 break; |
| 482 } | 462 } |
| 483 | 463 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 } | 549 } |
| 570 } | 550 } |
| 571 | 551 |
| 572 if (hasOut) { | 552 if (hasOut) { |
| 573 return in; | 553 return in; |
| 574 } else { | 554 } else { |
| 575 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string | 555 return start + (out - (const unsigned char*)NULL); // return where the s
tring would end if we reuse the string |
| 576 } | 556 } |
| 577 } | 557 } |
| 578 | 558 |
| 579 static int readNameLength(int level, const unsigned char* start, const unsigned
char* end) { | 559 static int readNameLength(const unsigned char* start, const unsigned char* end)
{ |
| 580 return readName(level, start, end, NULL) - start; | 560 return readName(start, end, NULL) - start; |
| 581 } | 561 } |
| 582 | 562 |
| 583 static const unsigned char* readName(int level, const unsigned char* start, cons
t unsigned char* end, SkPdfNativeObject* name, SkPdfAllocator* allocator GET_TRA
CK_STREAM) { | 563 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, SkPdfNativeObject* name, SkPdfAllocator* allocator) { |
| 584 if (!allocator) { | 564 if (!allocator) { |
| 585 return end; | 565 return end; |
| 586 } | 566 } |
| 587 int outLength = readNameLength(level, start, end); | 567 int outLength = readNameLength(start, end); |
| 588 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer | 568 // TODO(edisonn): optimize the allocation, don't allocate new string, but pu
t it in a preallocated buffer |
| 589 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 569 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 590 const unsigned char* now = readName(level, start, end, out); | 570 const unsigned char* now = readName(start, end, out); |
| 591 SkPdfNativeObject::makeName(out, out + outLength, name PUT_TRACK_STREAM(star
t, now)); | 571 SkPdfNativeObject::makeName(out, out + outLength, name); |
| 572 //PUT_TRACK_STREAM(start, now) |
| 592 TRACE_NAME(out, out + outLength); | 573 TRACE_NAME(out, out + outLength); |
| 593 return now; | 574 return now; |
| 594 } | 575 } |
| 595 | 576 |
| 596 // TODO(edisonn): pdf spec let Length to be an indirect object define after the
stream | 577 // TODO(edisonn): pdf spec let Length to be an indirect object define after the
stream |
| 597 // that makes for an interesting scenario, where the stream itself contains ends
tream, together | 578 // that makes for an interesting scenario, where the stream itself contains ends
tream, together |
| 598 // with a reference object with the length, but the real length object would be
somewhere else | 579 // with a reference object with the length, but the real length object would be
somewhere else |
| 599 // it could confuse the parser | 580 // it could confuse the parser |
| 600 /*example: | 581 /*example: |
| 601 | 582 |
| 602 7 0 obj | 583 7 0 obj |
| 603 << /length 8 0 R>> | 584 << /length 8 0 R>> |
| 604 stream | 585 stream |
| 605 ............... | 586 ............... |
| 606 endstream | 587 endstream |
| 607 8 0 obj #we are in stream actually, not a real object | 588 8 0 obj #we are in stream actually, not a real object |
| 608 << 10 >> #we are in stream actually, not a real object | 589 << 10 >> #we are in stream actually, not a real object |
| 609 endobj | 590 endobj |
| 610 endstream | 591 endstream |
| 611 8 0 obj #real obj | 592 8 0 obj #real obj |
| 612 << 100 >> #real obj | 593 << 100 >> #real obj |
| 613 endobj | 594 endobj |
| 614 and it could get worse, with multiple object like this | 595 and it could get worse, with multiple object like this |
| 615 */ | 596 */ |
| 616 | 597 |
| 617 // right now implement the silly algorithm that assumes endstream is finishing t
he stream | 598 // right now implement the silly algorithm that assumes endstream is finishing t
he stream |
| 618 | 599 |
| 619 | 600 |
| 620 static const unsigned char* readStream(int level, const unsigned char* start, co
nst unsigned char* end, SkPdfNativeObject* dict, SkPdfNativeDoc* doc) { | 601 static const unsigned char* readStream(const unsigned char* start, const unsigne
d char* end, SkPdfNativeObject* dict, SkPdfNativeDoc* doc) { |
| 621 TRACE_INDENT(level, "Stream"); | 602 start = skipPdfWhiteSpaces(start, end); |
| 622 start = skipPdfWhiteSpaces(level, start, end); | |
| 623 if (!(start[0] == 's' && start[1] == 't' && start[2] == 'r' && start[3] == '
e' && start[4] == 'a' && start[5] == 'm')) { | 603 if (!(start[0] == 's' && start[1] == 't' && start[2] == 'r' && start[3] == '
e' && start[4] == 'a' && start[5] == 'm')) { |
| 624 // no stream. return. | 604 // no stream. return. |
| 625 return start; | 605 return start; |
| 626 } | 606 } |
| 627 | 607 |
| 628 start += 6; // strlen("stream") | 608 start += 6; // strlen("stream") |
| 629 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { | 609 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { |
| 630 start += 2; | 610 start += 2; |
| 631 } else if (start[0] == kLF_PdfWhiteSpace) { | 611 } else if (start[0] == kLF_PdfWhiteSpace) { |
| 632 start += 1; | 612 start += 1; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 // TODO(edisonn): verify the next bytes are "endstream" | 667 // TODO(edisonn): verify the next bytes are "endstream" |
| 688 | 668 |
| 689 endstream += strlen("endstream"); | 669 endstream += strlen("endstream"); |
| 690 // TODO(edisonn): Assert? report error/warning? | 670 // TODO(edisonn): Assert? report error/warning? |
| 691 dict->addStream(start, (size_t)length); | 671 dict->addStream(start, (size_t)length); |
| 692 return endstream; | 672 return endstream; |
| 693 } | 673 } |
| 694 return start; | 674 return start; |
| 695 } | 675 } |
| 696 | 676 |
| 697 static const unsigned char* readInlineImageStream(int level, const unsigned char
* start, const unsigned char* end, SkPdfImageDictionary* inlineImage, SkPdfNativ
eDoc* doc) { | 677 static const unsigned char* readInlineImageStream(const unsigned char* start, co
nst unsigned char* end, SkPdfImageDictionary* inlineImage, SkPdfNativeDoc* doc)
{ |
| 698 TRACE_INDENT(level, "Inline Image"); | |
| 699 // We already processed ID keyword, and we should be positioned immediately
after it | 678 // We already processed ID keyword, and we should be positioned immediately
after it |
| 700 | 679 |
| 701 // TODO(edisonn): security: read after end check, or make buffers with extra
2 bytes | 680 // TODO(edisonn): security: read after end check, or make buffers with extra
2 bytes |
| 702 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { | 681 if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { |
| 703 start += 2; | 682 start += 2; |
| 704 } else if (start[0] == kLF_PdfWhiteSpace) { | 683 } else if (start[0] == kLF_PdfWhiteSpace) { |
| 705 start += 1; | 684 start += 1; |
| 706 } else if (isPdfWhiteSpace(start[0])) { | 685 } else if (isPdfWhiteSpace(start[0])) { |
| 707 start += 1; | 686 start += 1; |
| 708 } else { | 687 } else { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 719 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; | 698 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; |
| 720 inlineImage->addStream(start, (size_t)length); | 699 inlineImage->addStream(start, (size_t)length); |
| 721 } else { | 700 } else { |
| 722 // TODO(edisonn): report error in inline image stream (ID-EI) section | 701 // TODO(edisonn): report error in inline image stream (ID-EI) section |
| 723 // TODO(edisonn): based on filter, try to ignore a missing EI, and read
data properly | 702 // TODO(edisonn): based on filter, try to ignore a missing EI, and read
data properly |
| 724 return end; | 703 return end; |
| 725 } | 704 } |
| 726 return endEI; | 705 return endEI; |
| 727 } | 706 } |
| 728 | 707 |
| 729 static const unsigned char* readDictionary(int level, const unsigned char* start
, const unsigned char* end, SkPdfNativeObject* dict, SkPdfAllocator* allocator,
SkPdfNativeDoc* doc GET_TRACK_STREAM) { | 708 static const unsigned char* readDictionary(const unsigned char* start, const uns
igned char* end, SkPdfNativeObject* dict, SkPdfAllocator* allocator, SkPdfNative
Doc* doc) { |
| 730 if (allocator == NULL) { | 709 if (allocator == NULL) { |
| 731 // TODO(edisonn): report/warning error | 710 // TODO(edisonn): report/warning error |
| 732 return end; | 711 return end; |
| 733 } | 712 } |
| 734 TRACE_INDENT(level, "Dictionary"); | 713 SkPdfNativeObject::makeEmptyDictionary(dict); |
| 735 SkPdfNativeObject::makeEmptyDictionary(dict PUT_TRACK_STREAM(start, start)); | 714 // PUT_TRACK_STREAM(dict, start, start) |
| 736 | 715 |
| 737 start = skipPdfWhiteSpaces(level, start, end); | 716 start = skipPdfWhiteSpaces(start, end); |
| 738 SkPdfAllocator tmpStorage; // keys will be stored in dict, we can free them
immediately after set. | 717 SkPdfAllocator tmpStorage; // keys will be stored in dict, we can free them
immediately after set. |
| 739 | 718 |
| 740 while (start < end && *start == kNamed_PdfDelimiter) { | 719 while (start < end && *start == kNamed_PdfDelimiter) { |
| 741 SkPdfNativeObject key; | 720 SkPdfNativeObject key; |
| 742 //*start = '\0'; | 721 //*start = '\0'; |
| 743 start++; | 722 start++; |
| 744 start = readName(level + 1, start, end, &key, &tmpStorage PUT_TRACK_STRE
AM_ARGS); | 723 start = readName(start, end, &key, &tmpStorage); |
| 745 start = skipPdfWhiteSpaces(level + 1, start, end); | 724 start = skipPdfWhiteSpaces(start, end); |
| 746 | 725 |
| 747 if (start < end) { | 726 if (start < end) { |
| 748 SkPdfNativeObject* value = allocator->allocObject(); | 727 SkPdfNativeObject* value = allocator->allocObject(); |
| 749 start = nextObject(level + 1, start, end, value, allocator, doc PUT_
TRACK_STREAM_ARGS); | 728 start = nextObject(start, end, value, allocator, doc); |
| 750 | 729 |
| 751 start = skipPdfWhiteSpaces(level + 1, start, end); | 730 start = skipPdfWhiteSpaces(start, end); |
| 752 | 731 |
| 753 if (start < end) { | 732 if (start < end) { |
| 754 // seems we have an indirect reference | 733 // seems we have an indirect reference |
| 755 if (isPdfDigit(*start)) { | 734 if (isPdfDigit(*start)) { |
| 756 SkPdfNativeObject generation; | 735 SkPdfNativeObject generation; |
| 757 start = nextObject(level + 1, start, end, &generation, alloc
ator, doc PUT_TRACK_STREAM_ARGS); | 736 start = nextObject(start, end, &generation, allocator, doc); |
| 758 | 737 |
| 759 SkPdfNativeObject keywordR; | 738 SkPdfNativeObject keywordR; |
| 760 start = nextObject(level + 1, start, end, &keywordR, allocat
or, doc PUT_TRACK_STREAM_ARGS); | 739 start = nextObject(start, end, &keywordR, allocator, doc); |
| 761 | 740 |
| 762 if (value->isInteger() && generation.isInteger() && keywordR
.isKeywordReference()) { | 741 if (value->isInteger() && generation.isInteger() && keywordR
.isKeywordReference()) { |
| 763 int64_t id = value->intValue(); | 742 int64_t id = value->intValue(); |
| 764 SkPdfNativeObject::resetAndMakeReference((unsigned int)i
d, (unsigned int)generation.intValue(), value PUT_TRACK_PARAMETERS_OBJ2(value, &
generation)); | 743 SkPdfNativeObject::resetAndMakeReference((unsigned int)i
d, (unsigned int)generation.intValue(), value); |
| 744 // PUT_TRACK_PARAMETERS_OBJ2(value, &generation) |
| 765 dict->set(&key, value); | 745 dict->set(&key, value); |
| 766 } else { | 746 } else { |
| 767 // error, ignore | 747 // error, ignore |
| 768 dict->set(&key, value); | 748 dict->set(&key, value); |
| 769 } | 749 } |
| 770 } else { | 750 } else { |
| 771 // next elem is not a digit, but it might not be / either! | 751 // next elem is not a digit, but it might not be / either! |
| 772 dict->set(&key, value); | 752 dict->set(&key, value); |
| 773 } | 753 } |
| 774 } else { | 754 } else { |
| 775 // /key >> | 755 // /key >> |
| 776 dict->set(&key, value); | 756 dict->set(&key, value); |
| 777 return end; | 757 return end; |
| 778 } | 758 } |
| 779 start = skipPdfWhiteSpaces(level + 1, start, end); | 759 start = skipPdfWhiteSpaces(start, end); |
| 780 } else { | 760 } else { |
| 781 dict->set(&key, &SkPdfNativeObject::kNull); | 761 dict->set(&key, &SkPdfNativeObject::kNull); |
| 782 return end; | 762 return end; |
| 783 } | 763 } |
| 784 } | 764 } |
| 785 | 765 |
| 786 // TODO(edisonn): options to ignore these errors | 766 // TODO(edisonn): options to ignore these errors |
| 787 | 767 |
| 788 // now we should expect >> | 768 // now we should expect >> |
| 789 start = skipPdfWhiteSpaces(level, start, end); | 769 start = skipPdfWhiteSpaces(start, end); |
| 790 if (*start != kClosedInequityBracket_PdfDelimiter) { | 770 if (*start != kClosedInequityBracket_PdfDelimiter) { |
| 791 // TODO(edisonn): report/warning | 771 // TODO(edisonn): report/warning |
| 792 } | 772 } |
| 793 //*start = '\0'; | 773 //*start = '\0'; |
| 794 start++; // skip > | 774 start++; // skip > |
| 795 if (*start != kClosedInequityBracket_PdfDelimiter) { | 775 if (*start != kClosedInequityBracket_PdfDelimiter) { |
| 796 // TODO(edisonn): report/warning | 776 // TODO(edisonn): report/warning |
| 797 } | 777 } |
| 798 //*start = '\0'; | 778 //*start = '\0'; |
| 799 start++; // skip > | 779 start++; // skip > |
| 800 | 780 |
| 801 STORE_TRACK_PARAMETER_OFFSET_END(dict,start); | 781 //STORE_TRACK_PARAMETER_OFFSET_END(dict,start); |
| 802 | 782 |
| 803 start = readStream(level, start, end, dict, doc); | 783 start = readStream(start, end, dict, doc); |
| 804 | 784 |
| 805 return start; | 785 return start; |
| 806 } | 786 } |
| 807 | 787 |
| 808 const unsigned char* nextObject(int level, const unsigned char* start, const uns
igned char* end, SkPdfNativeObject* token, SkPdfAllocator* allocator, SkPdfNativ
eDoc* doc GET_TRACK_STREAM) { | 788 const unsigned char* nextObject(const unsigned char* start, const unsigned char*
end, SkPdfNativeObject* token, SkPdfAllocator* allocator, SkPdfNativeDoc* doc)
{ |
| 809 const unsigned char* current; | 789 const unsigned char* current; |
| 810 | 790 |
| 811 // skip white spaces | 791 // skip white spaces |
| 812 start = skipPdfWhiteSpaces(level, start, end); | 792 start = skipPdfWhiteSpaces(start, end); |
| 813 | 793 |
| 814 if (start >= end) { | 794 if (start >= end) { |
| 815 return end; | 795 return end; |
| 816 } | 796 } |
| 817 | 797 |
| 818 current = endOfPdfToken(level, start, end); | 798 current = endOfPdfToken(start, end); |
| 819 | 799 |
| 820 // no token, len would be 0 | 800 // no token, len would be 0 |
| 821 if (current == start || current == end) { | 801 if (current == start || current == end) { |
| 822 return end; | 802 return end; |
| 823 } | 803 } |
| 824 | 804 |
| 825 int tokenLen = current - start; | 805 int tokenLen = current - start; |
| 826 | 806 |
| 827 if (tokenLen == 1) { | 807 if (tokenLen == 1) { |
| 828 // start array | 808 // start array |
| 829 switch (*start) { | 809 switch (*start) { |
| 830 case kOpenedSquareBracket_PdfDelimiter: | 810 case kOpenedSquareBracket_PdfDelimiter: |
| 831 //*start = '\0'; | 811 //*start = '\0'; |
| 832 return readArray(level + 1, current, end, token, allocator, doc
PUT_TRACK_STREAM_ARGS); | 812 return readArray(current, end, token, allocator, doc); |
| 833 | 813 |
| 834 case kOpenedRoundBracket_PdfDelimiter: | 814 case kOpenedRoundBracket_PdfDelimiter: |
| 835 //*start = '\0'; | 815 //*start = '\0'; |
| 836 return readString(level, start + 1, end, token, allocator PUT_TR
ACK_STREAM_ARGS); | 816 return readString(start + 1, end, token, allocator); |
| 837 | 817 |
| 838 case kOpenedInequityBracket_PdfDelimiter: | 818 case kOpenedInequityBracket_PdfDelimiter: |
| 839 //*start = '\0'; | 819 //*start = '\0'; |
| 840 if (end > start + 1 && start[1] == kOpenedInequityBracket_PdfDel
imiter) { | 820 if (end > start + 1 && start[1] == kOpenedInequityBracket_PdfDel
imiter) { |
| 841 //start[1] = '\0'; // optional | 821 //start[1] = '\0'; // optional |
| 842 // TODO(edisonn): pass here the length somehow? | 822 // TODO(edisonn): pass here the length somehow? |
| 843 return readDictionary(level + 1, start + 2, end, token, allo
cator, doc PUT_TRACK_STREAM_ARGS); // skip << | 823 return readDictionary(start + 2, end, token, allocator, doc)
; // skip << |
| 844 } else { | 824 } else { |
| 845 return readHexString(level, start + 1, end, token, allocator
PUT_TRACK_STREAM_ARGS); // skip < | 825 return readHexString(start + 1, end, token, allocator); //
skip < |
| 846 } | 826 } |
| 847 | 827 |
| 848 case kNamed_PdfDelimiter: | 828 case kNamed_PdfDelimiter: |
| 849 //*start = '\0'; | 829 //*start = '\0'; |
| 850 return readName(level, start + 1, end, token, allocator PUT_TRAC
K_STREAM_ARGS); | 830 return readName(start + 1, end, token, allocator); |
| 851 | 831 |
| 852 // TODO(edisonn): what to do curly brackets? read spec! | 832 // TODO(edisonn): what to do curly brackets? read spec! |
| 853 case kOpenedCurlyBracket_PdfDelimiter: | 833 case kOpenedCurlyBracket_PdfDelimiter: |
| 854 default: | 834 default: |
| 855 break; | 835 break; |
| 856 } | 836 } |
| 857 | 837 |
| 858 SkASSERT(!isPdfWhiteSpace(*start)); | 838 SkASSERT(!isPdfWhiteSpace(*start)); |
| 859 if (isPdfDelimiter(*start)) { | 839 if (isPdfDelimiter(*start)) { |
| 860 // TODO(edisonn): how stream ] } > ) will be handled? | 840 // TODO(edisonn): how stream ] } > ) will be handled? |
| 861 // for now ignore, and it will become a keyword to be ignored | 841 // for now ignore, and it will become a keyword to be ignored |
| 862 } | 842 } |
| 863 } | 843 } |
| 864 | 844 |
| 865 if (tokenLen == 4 && start[0] == 'n' && start[1] == 'u' && start[2] == 'l' &
& start[3] == 'l') { | 845 if (tokenLen == 4 && start[0] == 'n' && start[1] == 'u' && start[2] == 'l' &
& start[3] == 'l') { |
| 866 SkPdfNativeObject::makeNull(token PUT_TRACK_STREAM(start, start + 4)); | 846 SkPdfNativeObject::makeNull(token); |
| 847 // PUT_TRACK_STREAM(start, start + 4) |
| 867 return current; | 848 return current; |
| 868 } | 849 } |
| 869 | 850 |
| 870 if (tokenLen == 4 && start[0] == 't' && start[1] == 'r' && start[2] == 'u' &
& start[3] == 'e') { | 851 if (tokenLen == 4 && start[0] == 't' && start[1] == 'r' && start[2] == 'u' &
& start[3] == 'e') { |
| 871 SkPdfNativeObject::makeBoolean(true, token PUT_TRACK_STREAM(start, start
+ 4)); | 852 SkPdfNativeObject::makeBoolean(true, token); |
| 853 // PUT_TRACK_STREAM(start, start + 4) |
| 872 return current; | 854 return current; |
| 873 } | 855 } |
| 874 | 856 |
| 875 if (tokenLen == 5 && start[0] == 'f' && start[1] == 'a' && start[2] == 'l' &
& start[3] == 's' && start[4] == 'e') { | 857 if (tokenLen == 5 && start[0] == 'f' && start[1] == 'a' && start[2] == 'l' &
& start[3] == 's' && start[4] == 'e') { |
| 876 SkPdfNativeObject::makeBoolean(false, token PUT_TRACK_STREAM(start, star
t + 5)); | 858 SkPdfNativeObject::makeBoolean(false, token); |
| 859 // PUT_TRACK_STREAM(start, start + 5) |
| 877 return current; | 860 return current; |
| 878 } | 861 } |
| 879 | 862 |
| 880 if (isPdfNumeric(*start)) { | 863 if (isPdfNumeric(*start)) { |
| 881 SkPdfNativeObject::makeNumeric(start, current, token PUT_TRACK_STREAM(st
art, current)); | 864 SkPdfNativeObject::makeNumeric(start, current, token); |
| 865 // PUT_TRACK_STREAM(start, current) |
| 882 } else { | 866 } else { |
| 883 SkPdfNativeObject::makeKeyword(start, current, token PUT_TRACK_STREAM(st
art, current)); | 867 SkPdfNativeObject::makeKeyword(start, current, token); |
| 868 // PUT_TRACK_STREAM(start, current) |
| 884 } | 869 } |
| 885 return current; | 870 return current; |
| 886 } | 871 } |
| 887 | 872 |
| 888 SkPdfNativeObject* SkPdfAllocator::allocBlock() { | 873 SkPdfNativeObject* SkPdfAllocator::allocBlock() { |
| 889 fSizeInBytes += BUFFER_SIZE * sizeof(SkPdfNativeObject); | 874 fSizeInBytes += BUFFER_SIZE * sizeof(SkPdfNativeObject); |
| 890 return new SkPdfNativeObject[BUFFER_SIZE]; | 875 return new SkPdfNativeObject[BUFFER_SIZE]; |
| 891 } | 876 } |
| 892 | 877 |
| 893 SkPdfAllocator::~SkPdfAllocator() { | 878 SkPdfAllocator::~SkPdfAllocator() { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 } | 930 } |
| 946 | 931 |
| 947 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { | 932 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { |
| 948 SkPdfNativeObject obj; | 933 SkPdfNativeObject obj; |
| 949 #ifdef PDF_TRACE_READ_TOKEN | 934 #ifdef PDF_TRACE_READ_TOKEN |
| 950 static int read_op = 0; | 935 static int read_op = 0; |
| 951 #endif | 936 #endif |
| 952 token->fKeyword = NULL; | 937 token->fKeyword = NULL; |
| 953 token->fObject = NULL; | 938 token->fObject = NULL; |
| 954 | 939 |
| 955 fUncompressedStream = skipPdfWhiteSpaces(0, fUncompressedStream, fUncompress
edStreamEnd); | 940 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS
treamEnd); |
| 956 if (fUncompressedStream >= fUncompressedStreamEnd) { | 941 if (fUncompressedStream >= fUncompressedStreamEnd) { |
| 957 return false; | 942 return false; |
| 958 } | 943 } |
| 959 | 944 |
| 960 fUncompressedStream = nextObject(0, fUncompressedStream, fUncompressedStream
End, &obj, fAllocator, fDoc PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressed
StreamStart)); | 945 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd
, &obj, fAllocator, fDoc); |
| 946 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart) |
| 961 | 947 |
| 962 // If it is a keyword, we will only get the pointer of the string | 948 // If it is a keyword, we will only get the pointer of the string |
| 963 if (obj.type() == SkPdfNativeObject::kKeyword_PdfObjectType) { | 949 if (obj.type() == SkPdfNativeObject::kKeyword_PdfObjectType) { |
| 964 token->fKeyword = obj.c_str(); | 950 token->fKeyword = obj.c_str(); |
| 965 token->fKeywordLength = obj.lenstr(); | 951 token->fKeywordLength = obj.lenstr(); |
| 966 token->fType = kKeyword_TokenType; | 952 token->fType = kKeyword_TokenType; |
| 967 } else { | 953 } else { |
| 968 SkPdfNativeObject* pobj = fAllocator->allocObject(); | 954 SkPdfNativeObject* pobj = fAllocator->allocObject(); |
| 969 *pobj = obj; | 955 *pobj = obj; |
| 970 token->fObject = pobj; | 956 token->fObject = pobj; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1079 HANDLE_NAME_ABBR(value, FlateDecode, Fl); // (PDF 1.2) | 1065 HANDLE_NAME_ABBR(value, FlateDecode, Fl); // (PDF 1.2) |
| 1080 HANDLE_NAME_ABBR(value, RunLengthDecode, RL); | 1066 HANDLE_NAME_ABBR(value, RunLengthDecode, RL); |
| 1081 HANDLE_NAME_ABBR(value, CCITTFaxDecode, CCF); | 1067 HANDLE_NAME_ABBR(value, CCITTFaxDecode, CCF); |
| 1082 HANDLE_NAME_ABBR(value, DCTDecode, DCT); | 1068 HANDLE_NAME_ABBR(value, DCTDecode, DCT); |
| 1083 | 1069 |
| 1084 return value; | 1070 return value; |
| 1085 } | 1071 } |
| 1086 | 1072 |
| 1087 SkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() { | 1073 SkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() { |
| 1088 // BI already processed | 1074 // BI already processed |
| 1089 fUncompressedStream = skipPdfWhiteSpaces(0, fUncompressedStream, fUncompress
edStreamEnd); | 1075 fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedS
treamEnd); |
| 1090 if (fUncompressedStream >= fUncompressedStreamEnd) { | 1076 if (fUncompressedStream >= fUncompressedStreamEnd) { |
| 1091 return NULL; | 1077 return NULL; |
| 1092 } | 1078 } |
| 1093 | 1079 |
| 1094 SkPdfImageDictionary* inlineImage = (SkPdfImageDictionary*)fAllocator->alloc
Object(); | 1080 SkPdfImageDictionary* inlineImage = (SkPdfImageDictionary*)fAllocator->alloc
Object(); |
| 1095 SkPdfNativeObject::makeEmptyDictionary(inlineImage PUT_TRACK_STREAM_ARGS_EXP
L(fStreamId, fUncompressedStream - fUncompressedStreamStart, fUncompressedStream
- fUncompressedStreamStart)); | 1081 SkPdfNativeObject::makeEmptyDictionary(inlineImage); |
| 1082 // PUT_TRACK_STREAM_ARGS_EXPL(fStreamId, fUncompressedStream - fUncompresse
dStreamStart, fUncompressedStream - fUncompressedStreamStart) |
| 1096 | 1083 |
| 1097 while (fUncompressedStream < fUncompressedStreamEnd) { | 1084 while (fUncompressedStream < fUncompressedStreamEnd) { |
| 1098 SkPdfNativeObject* key = fAllocator->allocObject(); | 1085 SkPdfNativeObject* key = fAllocator->allocObject(); |
| 1099 fUncompressedStream = nextObject(0, fUncompressedStream, fUncompressedSt
reamEnd, key, fAllocator, fDoc PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompres
sedStreamStart)); | 1086 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStrea
mEnd, key, fAllocator, fDoc); |
| 1087 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)s |
| 1100 | 1088 |
| 1101 if (key->isKeyword() && key->lenstr() == 2 && key->c_str()[0] == 'I' &&
key->c_str()[1] == 'D') { // ID | 1089 if (key->isKeyword() && key->lenstr() == 2 && key->c_str()[0] == 'I' &&
key->c_str()[1] == 'D') { // ID |
| 1102 fUncompressedStream = readInlineImageStream(0, fUncompressedStream,
fUncompressedStreamEnd, inlineImage, fDoc); | 1090 fUncompressedStream = readInlineImageStream(fUncompressedStream, fUn
compressedStreamEnd, inlineImage, fDoc); |
| 1103 return inlineImage; | 1091 return inlineImage; |
| 1104 } else { | 1092 } else { |
| 1105 SkPdfNativeObject* obj = fAllocator->allocObject(); | 1093 SkPdfNativeObject* obj = fAllocator->allocObject(); |
| 1106 fUncompressedStream = nextObject(0, fUncompressedStream, fUncompress
edStreamEnd, obj, fAllocator, fDoc PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncom
pressedStreamStart)); | 1094 fUncompressedStream = nextObject(fUncompressedStream, fUncompressedS
treamEnd, obj, fAllocator, fDoc); |
| 1095 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)
s |
| 1107 // TODO(edisonn): perf maybe we should not expand abreviation like t
his | 1096 // TODO(edisonn): perf maybe we should not expand abreviation like t
his |
| 1108 inlineImage->set(inlineImageKeyAbbreviationExpand(key), | 1097 inlineImage->set(inlineImageKeyAbbreviationExpand(key), |
| 1109 inlineImageValueAbbreviationExpand(obj)); | 1098 inlineImageValueAbbreviationExpand(obj)); |
| 1110 } | 1099 } |
| 1111 } | 1100 } |
| 1112 // TODO(edisonn): report end of data with inline image without an EI | 1101 // TODO(edisonn): report end of data with inline image without an EI |
| 1113 return inlineImage; | 1102 return inlineImage; |
| 1114 } | 1103 } |
| OLD | NEW |