| 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 "SkPdfConfig.h" | 8 #include "SkPdfConfig.h" |
| 9 #include "SkPdfDiffEncoder.h" | 9 #include "SkPdfDiffEncoder.h" |
| 10 #include "SkPdfNativeObject.h" | 10 #include "SkPdfNativeObject.h" |
| 11 #include "SkPdfNativeTokenizer.h" | 11 #include "SkPdfNativeTokenizer.h" |
| 12 #include "SkPdfUtils.h" | 12 #include "SkPdfUtils.h" |
| 13 | 13 |
| 14 // TODO(edisonn): mac builder does not find the header ... but from headers is o
k | 14 // TODO(edisonn): mac builder does not find the header ... but from headers is o
k |
| 15 //#include "SkPdfStreamCommonDictionary_autogen.h" | 15 //#include "SkPdfStreamCommonDictionary_autogen.h" |
| 16 //#include "SkPdfImageDictionary_autogen.h" | 16 //#include "SkPdfImageDictionary_autogen.h" |
| 17 #include "SkPdfHeaders_autogen.h" | 17 #include "SkPdfHeaders_autogen.h" |
| 18 | 18 |
| 19 | 19 |
| 20 // TODO(edisonn): Perf, Make this function run faster. | 20 // TODO(edisonn): Perf, Make this function run faster. |
| 21 // There could be 0s between start and end. | 21 // There could be 0s between start and end. |
| 22 // needle will not contain 0s. | 22 // needle will not contain 0s. |
| 23 static char* strrstrk(char* hayStart, char* hayEnd, const char* needle) { | 23 static char* strrstrk(char* hayStart, char* hayEnd, const char* needle) { |
| 24 int needleLen = strlen(needle); | 24 size_t needleLen = strlen(needle); |
| 25 if ((isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (hayStart+needl
eLen == hayEnd)) && | 25 if ((isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (hayStart+needl
eLen == hayEnd)) && |
| 26 strncmp(hayStart, needle, needleLen) == 0) { | 26 strncmp(hayStart, needle, needleLen) == 0) { |
| 27 return hayStart; | 27 return hayStart; |
| 28 } | 28 } |
| 29 | 29 |
| 30 hayStart++; | 30 hayStart++; |
| 31 | 31 |
| 32 while (hayStart < hayEnd) { | 32 while (hayStart < hayEnd) { |
| 33 if (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart-1)) && | 33 if (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart-1)) && |
| 34 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || | 34 (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 | 98 |
| 99 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit
er) { | 99 if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimit
er) { |
| 100 return endOfToken; | 100 return endOfToken; |
| 101 } | 101 } |
| 102 | 102 |
| 103 SkPdfNativeObject* newObj = allocator->allocObject(); | 103 SkPdfNativeObject* newObj = allocator->allocObject(); |
| 104 start = nextObject(start, end, newObj, allocator, doc); | 104 start = nextObject(start, end, newObj, allocator, doc); |
| 105 // TODO(edisonn): perf/memory: put the variables on the stack, and flush
them on the array | 105 // TODO(edisonn): perf/memory: put the variables on the stack, and flush
them on the array |
| 106 // only when we are sure they are not references! | 106 // only when we are sure they are not references! |
| 107 if (newObj->isKeywordReference() && array->size() >= 2 && | 107 if (newObj->isKeywordReference() && array->size() >= 2 && |
| 108 array->objAtAIndex(array->size() - 1)->isInteger() && | 108 array->objAtAIndex(SkToInt(array->size() - 1))->isInteger() && |
| 109 array->objAtAIndex(array->size() - 2)->isInteger()) { | 109 array->objAtAIndex(SkToInt(array->size() - 2))->isInteger()) { |
| 110 SkPdfNativeObject* gen = array->removeLastInArray(); | 110 SkPdfNativeObject* gen = array->removeLastInArray(); |
| 111 SkPdfNativeObject* id = array->removeLastInArray(); | 111 SkPdfNativeObject* id = array->removeLastInArray(); |
| 112 | 112 |
| 113 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue(
), | 113 SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue(
), |
| 114 (unsigned int)gen->intValue
(), newObj); | 114 (unsigned int)gen->intValue
(), newObj); |
| 115 // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now | 115 // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now |
| 116 } | 116 } |
| 117 array->appendInArray(newObj); | 117 array->appendInArray(newObj); |
| 118 } | 118 } |
| 119 // TODO(edisonn): report not reached, we should never get here | 119 // TODO(edisonn): report not reached, we should never get here |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 } | 234 } |
| 235 | 235 |
| 236 if (hasOut) { | 236 if (hasOut) { |
| 237 return in; // consumed already ) at the end of the string | 237 return in; // consumed already ) at the end of the string |
| 238 } else { | 238 } else { |
| 239 // return where the string would end if we reuse the string | 239 // return where the string would end if we reuse the string |
| 240 return start + (out - (const unsigned char*)NULL); | 240 return start + (out - (const unsigned char*)NULL); |
| 241 } | 241 } |
| 242 } | 242 } |
| 243 | 243 |
| 244 static int readStringLength(const unsigned char* start, const unsigned char* end
) { | 244 static size_t readStringLength(const unsigned char* start, const unsigned char*
end) { |
| 245 return readString(start, end, NULL) - start; | 245 return readString(start, end, NULL) - start; |
| 246 } | 246 } |
| 247 | 247 |
| 248 static const unsigned char* readString(const unsigned char* start, const unsigne
d char* end, | 248 static const unsigned char* readString(const unsigned char* start, const unsigne
d char* end, |
| 249 SkPdfNativeObject* str, SkPdfAllocator* a
llocator) { | 249 SkPdfNativeObject* str, SkPdfAllocator* a
llocator) { |
| 250 if (!allocator) { | 250 if (!allocator) { |
| 251 // TODO(edisonn): report error/warn/assert | 251 // TODO(edisonn): report error/warn/assert |
| 252 return end; | 252 return end; |
| 253 } | 253 } |
| 254 | 254 |
| 255 int outLength = readStringLength(start, end); | 255 size_t outLength = readStringLength(start, end); |
| 256 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 256 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 257 const unsigned char* now = readString(start, end, out); | 257 const unsigned char* now = readString(start, end, out); |
| 258 SkPdfNativeObject::makeString(out, out + outLength, str); | 258 SkPdfNativeObject::makeString(out, out + outLength, str); |
| 259 // PUT_TRACK_STREAM(str, start, now) | 259 // PUT_TRACK_STREAM(str, start, now) |
| 260 TRACE_STRING(out, out + outLength); | 260 TRACE_STRING(out, out + outLength); |
| 261 return now; // consumed already ) at the end of the string | 261 return now; // consumed already ) at the end of the string |
| 262 } | 262 } |
| 263 | 263 |
| 264 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, | 264 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, |
| 265 unsigned char* out) { | 265 unsigned char* out) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 } | 384 } |
| 385 | 385 |
| 386 if (hasOut) { | 386 if (hasOut) { |
| 387 return in; // consumed already ) at the end of the string | 387 return in; // consumed already ) at the end of the string |
| 388 } else { | 388 } else { |
| 389 // return where the string would end if we reuse the string | 389 // return where the string would end if we reuse the string |
| 390 return start + (out - (const unsigned char*)NULL); | 390 return start + (out - (const unsigned char*)NULL); |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 static int readHexStringLength(const unsigned char* start, const unsigned char*
end) { | 394 static size_t readHexStringLength(const unsigned char* start, const unsigned cha
r* end) { |
| 395 return readHexString(start, end, NULL) - start; | 395 return readHexString(start, end, NULL) - start; |
| 396 } | 396 } |
| 397 | 397 |
| 398 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { | 398 static const unsigned char* readHexString(const unsigned char* start, const unsi
gned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { |
| 399 if (!allocator) { | 399 if (!allocator) { |
| 400 // TODO(edisonn): report error/warn/assert | 400 // TODO(edisonn): report error/warn/assert |
| 401 return end; | 401 return end; |
| 402 } | 402 } |
| 403 int outLength = readHexStringLength(start, end); | 403 size_t outLength = readHexStringLength(start, end); |
| 404 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 404 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 405 const unsigned char* now = readHexString(start, end, out); | 405 const unsigned char* now = readHexString(start, end, out); |
| 406 SkPdfNativeObject::makeHexString(out, out + outLength, str); | 406 SkPdfNativeObject::makeHexString(out, out + outLength, str); |
| 407 // str PUT_TRACK_STREAM(start, now) | 407 // str PUT_TRACK_STREAM(start, now) |
| 408 TRACE_HEXSTRING(out, out + outLength); | 408 TRACE_HEXSTRING(out, out + outLength); |
| 409 return now; // consumed already > at the end of the string | 409 return now; // consumed already > at the end of the string |
| 410 } | 410 } |
| 411 | 411 |
| 412 // TODO(edisonn): add version parameter, before PDF 1.2 name could not have spec
ial characters. | 412 // TODO(edisonn): add version parameter, before PDF 1.2 name could not have spec
ial characters. |
| 413 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, | 413 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 } | 511 } |
| 512 | 512 |
| 513 if (hasOut) { | 513 if (hasOut) { |
| 514 return in; // consumed already ) at the end of the string | 514 return in; // consumed already ) at the end of the string |
| 515 } else { | 515 } else { |
| 516 // return where the string would end if we reuse the string | 516 // return where the string would end if we reuse the string |
| 517 return start + (out - (const unsigned char*)NULL); | 517 return start + (out - (const unsigned char*)NULL); |
| 518 } | 518 } |
| 519 } | 519 } |
| 520 | 520 |
| 521 static int readNameLength(const unsigned char* start, const unsigned char* end)
{ | 521 static size_t readNameLength(const unsigned char* start, const unsigned char* en
d) { |
| 522 return readName(start, end, NULL) - start; | 522 return readName(start, end, NULL) - start; |
| 523 } | 523 } |
| 524 | 524 |
| 525 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, | 525 static const unsigned char* readName(const unsigned char* start, const unsigned
char* end, |
| 526 SkPdfNativeObject* name, SkPdfAllocator* al
locator) { | 526 SkPdfNativeObject* name, SkPdfAllocator* al
locator) { |
| 527 if (!allocator) { | 527 if (!allocator) { |
| 528 // TODO(edisonn): report error/warn/assert | 528 // TODO(edisonn): report error/warn/assert |
| 529 return end; | 529 return end; |
| 530 } | 530 } |
| 531 int outLength = readNameLength(start, end); | 531 size_t outLength = readNameLength(start, end); |
| 532 unsigned char* out = (unsigned char*)allocator->alloc(outLength); | 532 unsigned char* out = (unsigned char*)allocator->alloc(outLength); |
| 533 const unsigned char* now = readName(start, end, out); | 533 const unsigned char* now = readName(start, end, out); |
| 534 SkPdfNativeObject::makeName(out, out + outLength, name); | 534 SkPdfNativeObject::makeName(out, out + outLength, name); |
| 535 //PUT_TRACK_STREAM(start, now) | 535 //PUT_TRACK_STREAM(start, now) |
| 536 TRACE_NAME(out, out + outLength); | 536 TRACE_NAME(out, out + outLength); |
| 537 return now; | 537 return now; |
| 538 } | 538 } |
| 539 | 539 |
| 540 // TODO(edisonn): pdf spec let Length to be an indirect object define after the
stream | 540 // TODO(edisonn): pdf spec let Length to be an indirect object define after the
stream |
| 541 // that makes for an interesting scenario, where the stream itself contains ends
tream, together | 541 // that makes for an interesting scenario, where the stream itself contains ends
tream, together |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 start += 1; | 664 start += 1; |
| 665 } else { | 665 } else { |
| 666 SkASSERT(isPdfDelimiter(start[0])); | 666 SkASSERT(isPdfDelimiter(start[0])); |
| 667 // TODO(edisonn): warning? | 667 // TODO(edisonn): warning? |
| 668 } | 668 } |
| 669 | 669 |
| 670 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start
, (char*)end, "EI"); | 670 const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start
, (char*)end, "EI"); |
| 671 const unsigned char* endEI = endstream ? endstream + 2 : NULL; // 2 == strl
en("EI") | 671 const unsigned char* endEI = endstream ? endstream + 2 : NULL; // 2 == strl
en("EI") |
| 672 | 672 |
| 673 if (endstream) { | 673 if (endstream) { |
| 674 int length = endstream - start; | 674 size_t length = endstream - start; |
| 675 if (*(endstream-1) == kLF_PdfWhiteSpace) length--; | 675 if (*(endstream-1) == kLF_PdfWhiteSpace) length--; |
| 676 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; | 676 if (*(endstream-2) == kCR_PdfWhiteSpace) length--; |
| 677 inlineImage->addStream(start, (size_t)length); | 677 inlineImage->addStream(start, (size_t)length); |
| 678 } else { | 678 } else { |
| 679 // TODO(edisonn): report error in inline image stream (ID-EI) section | 679 // TODO(edisonn): report error in inline image stream (ID-EI) section |
| 680 // TODO(edisonn): based on filter, try to ignore a missing EI, and read
data properly | 680 // TODO(edisonn): based on filter, try to ignore a missing EI, and read
data properly |
| 681 return end; | 681 return end; |
| 682 } | 682 } |
| 683 return endEI; | 683 return endEI; |
| 684 } | 684 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 return end; | 779 return end; |
| 780 } | 780 } |
| 781 | 781 |
| 782 current = endOfPdfToken(start, end); | 782 current = endOfPdfToken(start, end); |
| 783 | 783 |
| 784 // no token, len would be 0 | 784 // no token, len would be 0 |
| 785 if (current == start || current == end) { | 785 if (current == start || current == end) { |
| 786 return end; | 786 return end; |
| 787 } | 787 } |
| 788 | 788 |
| 789 int tokenLen = current - start; | 789 size_t tokenLen = current - start; |
| 790 | 790 |
| 791 if (tokenLen == 1) { | 791 if (tokenLen == 1) { |
| 792 // start array | 792 // start array |
| 793 switch (*start) { | 793 switch (*start) { |
| 794 case kOpenedSquareBracket_PdfDelimiter: | 794 case kOpenedSquareBracket_PdfDelimiter: |
| 795 return readArray(current, end, token, allocator, doc); | 795 return readArray(current, end, token, allocator, doc); |
| 796 | 796 |
| 797 case kOpenedRoundBracket_PdfDelimiter: | 797 case kOpenedRoundBracket_PdfDelimiter: |
| 798 return readString(start + 1, end, token, allocator); | 798 return readString(start + 1, end, token, allocator); |
| 799 | 799 |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 SkPdfAllocator* allocator, | 915 SkPdfAllocator* allocator, |
| 916 SkPdfNativeDoc* doc) : fDoc(doc) | 916 SkPdfNativeDoc* doc) : fDoc(doc) |
| 917 , fAllocator(all
ocator) | 917 , fAllocator(all
ocator) |
| 918 , fEmpty(false) | 918 , fEmpty(false) |
| 919 , fHasPutBack(fa
lse) { | 919 , fHasPutBack(fa
lse) { |
| 920 // TODO(edisonn): really bad hack, find end of object (endobj might be in a
comment!) | 920 // TODO(edisonn): really bad hack, find end of object (endobj might be in a
comment!) |
| 921 // we need to do now for perf, and our generated pdfs do not have comments, | 921 // we need to do now for perf, and our generated pdfs do not have comments, |
| 922 // but we need to remove this hack for pdfs in the wild | 922 // but we need to remove this hack for pdfs in the wild |
| 923 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); | 923 char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); |
| 924 if (endobj) { | 924 if (endobj) { |
| 925 len = endobj - (char*)buffer + strlen("endobj"); | 925 len = SkToInt(endobj - (char*)buffer + strlen("endobj")); |
| 926 } | 926 } |
| 927 fUncompressedStreamStart = fUncompressedStream = buffer; | 927 fUncompressedStreamStart = fUncompressedStream = buffer; |
| 928 fUncompressedStreamEnd = fUncompressedStream + len; | 928 fUncompressedStreamEnd = fUncompressedStream + len; |
| 929 } | 929 } |
| 930 | 930 |
| 931 SkPdfNativeTokenizer::~SkPdfNativeTokenizer() { | 931 SkPdfNativeTokenizer::~SkPdfNativeTokenizer() { |
| 932 } | 932 } |
| 933 | 933 |
| 934 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { | 934 bool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { |
| 935 #ifdef PDF_TRACE_READ_TOKEN | 935 #ifdef PDF_TRACE_READ_TOKEN |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 fAllocator, fDoc); | 1116 fAllocator, fDoc); |
| 1117 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)
s | 1117 // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)
s |
| 1118 // TODO(edisonn): perf maybe we should not expand abBreviation like
this | 1118 // TODO(edisonn): perf maybe we should not expand abBreviation like
this |
| 1119 inlineImage->set(inlineImageKeyAbbreviationExpand(key), | 1119 inlineImage->set(inlineImageKeyAbbreviationExpand(key), |
| 1120 inlineImageValueAbbreviationExpand(obj)); | 1120 inlineImageValueAbbreviationExpand(obj)); |
| 1121 } | 1121 } |
| 1122 } | 1122 } |
| 1123 // TODO(edisonn): report end of data with inline image without an EI | 1123 // TODO(edisonn): report end of data with inline image without an EI |
| 1124 return inlineImage; | 1124 return inlineImage; |
| 1125 } | 1125 } |
| OLD | NEW |