1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/* 2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright 2013 Google Inc. 3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * 4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Use of this source code is governed by a BSD-style license that can be 5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * found in the LICENSE file. 6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com */ 73aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 8571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#include "SkPdfConfig.h" 95092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com#include "SkPdfDiffEncoder.h" 10c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfNativeObject.h" 11c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfNativeTokenizer.h" 12c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com#include "SkPdfUtils.h" 133aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 1433f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com// TODO(edisonn): mac builder does not find the header ... but from headers is ok 1533f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com//#include "SkPdfStreamCommonDictionary_autogen.h" 1633f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com//#include "SkPdfImageDictionary_autogen.h" 1733f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com#include "SkPdfHeaders_autogen.h" 1833f11b6fcdb7dfce27f953803be40fbacedc7450edisonn@google.com 1978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 20c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// TODO(edisonn): Perf, Make this function run faster. 21c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// There could be 0s between start and end. 22c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// needle will not contain 0s. 2378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comstatic char* strrstrk(char* hayStart, char* hayEnd, const char* needle) { 2478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com int needleLen = strlen(needle); 2578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if ((isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || (hayStart+needleLen == hayEnd)) && 2678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com strncmp(hayStart, needle, needleLen) == 0) { 2778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return hayStart; 2878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 2978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 3078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com hayStart++; 3178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 3278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com while (hayStart < hayEnd) { 3378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart-1)) && 34c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com (isPdfWhiteSpaceOrPdfDelimiter(*(hayStart+needleLen)) || 35c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com (hayStart+needleLen == hayEnd)) && 3678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com strncmp(hayStart, needle, needleLen) == 0) { 3778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return hayStart; 3878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 3978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com hayStart++; 4078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 4178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return NULL; 4278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com} 4378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 44598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comconst unsigned char* skipPdfWhiteSpaces(const unsigned char* start, const unsigned char* end) { 454ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com while (start < end && (isPdfWhiteSpace(*start) || *start == kComment_PdfDelimiter)) { 462ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_COMMENT(*start); 47571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*start == kComment_PdfDelimiter) { 48571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // skip the comment until end of line 49571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (start < end && !isPdfEOL(*start)) { 50571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start++; 512ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_COMMENT(*start); 52571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 53571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 54571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start++; 55571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 56571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 57571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 58571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 59571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 60598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comconst unsigned char* endOfPdfToken(const unsigned char* start, const unsigned char* end) { 61571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkASSERT(!isPdfWhiteSpace(*start)); 62571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 63571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (start < end && isPdfDelimiter(*start)) { 642ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_TK(*start); 65571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start++; 66571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 67571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 68571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 69571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (start < end && !isPdfWhiteSpaceOrPdfDelimiter(*start)) { 702ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_TK(*start); 71571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start++; 72571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 73571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 74571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 75571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 76c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// The parsing should end with a ]. 77c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readArray(const unsigned char* start, const unsigned char* end, 78c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* array, 79c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator* allocator, SkPdfNativeDoc* doc) { 80598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeEmptyArray(array); 81598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(array, start, start) 82bca421b468f53a591333918248f54bbd958389d2edisonn@google.com 831f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com if (allocator == NULL) { 84c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): report/warning error/assert 851f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com return end; 861f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com } 871f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com 88571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (start < end) { 89571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // skip white spaces 90598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 91571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 92598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com const unsigned char* endOfToken = endOfPdfToken(start, end); 93571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 94571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (endOfToken == start) { 95571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): report error in pdf file (end of stream with ] for end of aray 96571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 97571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 98571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 99571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (endOfToken == start + 1 && *start == kClosedSquareBracket_PdfDelimiter) { 100571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return endOfToken; 101571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 102571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 1033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* newObj = allocator->allocObject(); 104598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = nextObject(start, end, newObj, allocator, doc); 105c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): perf/memory: put the variables on the stack, and flush them on the array 106c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // only when we are sure they are not references! 107c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com if (newObj->isKeywordReference() && array->size() >= 2 && 108c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com array->objAtAIndex(array->size() - 1)->isInteger() && 109c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com array->objAtAIndex(array->size() - 2)->isInteger()) { 1103aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* gen = array->removeLastInArray(); 1113aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* id = array->removeLastInArray(); 112bca421b468f53a591333918248f54bbd958389d2edisonn@google.com 113c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject::resetAndMakeReference((unsigned int)id->intValue(), 114c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com (unsigned int)gen->intValue(), newObj); 115598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // newObj PUT_TRACK_PARAMETERS_OBJ2(id, newObj) - store end, as now 116571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 117571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com array->appendInArray(newObj); 118571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 119571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): report not reached, we should never get here 1208bad7375d7e0ebe28af4d905665f34227843bd16edisonn@google.com // TODO(edisonn): there might be a bug here, enable an assert and run it on files 1218bad7375d7e0ebe28af4d905665f34227843bd16edisonn@google.com // or it might be that the files were actually corrupted 122571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 123571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 124571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 125c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readString(const unsigned char* start, const unsigned char* end, 126c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com unsigned char* out) { 1272ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* in = start; 1282ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com bool hasOut = (out != NULL); 1292ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 1302ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com int openRoundBrackets = 1; 1312ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com while (in < end) { 132571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com openRoundBrackets += ((*in) == kOpenedRoundBracket_PdfDelimiter); 133571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com openRoundBrackets -= ((*in) == kClosedRoundBracket_PdfDelimiter); 1342ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (openRoundBrackets == 0) { 1352ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com in++; // consumed ) 1362ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com break; 1372ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } 1382ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 139571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*in == kEscape_PdfSpecial) { 140571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (in + 1 < end) { 141571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (in[1]) { 142571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'n': 1432ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kLF_PdfWhiteSpace; } 144571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 145571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 146571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 147571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 148571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'r': 1492ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kCR_PdfWhiteSpace; } 150571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 151571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 152571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 153571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 154571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 't': 1552ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kHT_PdfWhiteSpace; } 156571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 157571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 158571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 159571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 160571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'b': 161571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): any special meaning to backspace? 1622ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kBackspace_PdfSpecial; } 163571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 164571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 165571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 166571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 167571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'f': 1681f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com if (hasOut) { *out = kFF_PdfWhiteSpace; } 169571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 170571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 171571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 172571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 173571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kOpenedRoundBracket_PdfDelimiter: 1742ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kOpenedRoundBracket_PdfDelimiter; } 175571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 176571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 177571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 178571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 179571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kClosedRoundBracket_PdfDelimiter: 1802ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kClosedRoundBracket_PdfDelimiter; } 181571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 182571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 183571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 184571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 185571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kEscape_PdfSpecial: 1862ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = kEscape_PdfSpecial; } 187571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 188571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in += 2; 189571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 190571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 191571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '0': 192571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '1': 193571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '2': 194571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '3': 195571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '4': 196571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '5': 197571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '6': 198571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '7': { 199571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com //read octals 200571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; // consume backslash 201571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 202571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com int code = 0; 203571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com int i = 0; 204571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (in < end && *in >= '0' && *in < '8') { 205571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (code << 3) + ((*in) - '0'); // code * 8 + d 206571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com i++; 207571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 208571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (i == 3) { 2092ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code & 0xff; } 210571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 211571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com i = 0; 212571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 213571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 214571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (i > 0) { 2152ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code & 0xff; } 216571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 217571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 218571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 219571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 220571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 221571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 222c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // Per spec, backslash is ignored if escaped ch is unknown 223571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 224571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 225571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 2268bad7375d7e0ebe28af4d905665f34227843bd16edisonn@google.com } else { 2278bad7375d7e0ebe28af4d905665f34227843bd16edisonn@google.com in++; 228571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 229571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 2302ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = *in; } 231571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 232571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 233571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 234571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 235571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 2362ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { 2372ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com return in; // consumed already ) at the end of the string 2382ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else { 239c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // return where the string would end if we reuse the string 240c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com return start + (out - (const unsigned char*)NULL); 2412ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } 2422ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 2432ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 244598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comstatic int readStringLength(const unsigned char* start, const unsigned char* end) { 245598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readString(start, end, NULL) - start; 2462ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 247571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 248c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readString(const unsigned char* start, const unsigned char* end, 249c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* str, SkPdfAllocator* allocator) { 250b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com if (!allocator) { 251c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): report error/warn/assert 252b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com return end; 253b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com } 254c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com 255598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com int outLength = readStringLength(start, end); 2562ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com unsigned char* out = (unsigned char*)allocator->alloc(outLength); 257598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com const unsigned char* now = readString(start, end, out); 258598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeString(out, out + outLength, str); 259598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(str, start, now) 2602ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_STRING(out, out + outLength); 261bca421b468f53a591333918248f54bbd958389d2edisonn@google.com return now; // consumed already ) at the end of the string 262571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 263571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 264c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readHexString(const unsigned char* start, const unsigned char* end, 265c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com unsigned char* out) { 2662ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com bool hasOut = (out != NULL); 2672ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* in = start; 268571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 269571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com unsigned char code = 0; 270571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 271571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (in < end) { 272571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (in < end && isPdfWhiteSpace(*in)) { 273571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 274571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 275571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 276571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*in == kClosedInequityBracket_PdfDelimiter) { 2772ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com in++; // consume > 278571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // normal exit 279571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 280571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 281571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 282571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (in >= end) { 283571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // end too soon 284571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 285571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 286571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 287571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (*in) { 288571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '0': 289571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '1': 290571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '2': 291571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '3': 292571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '4': 293571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '5': 294571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '6': 295571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '7': 296571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '8': 297571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '9': 298571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - '0') << 4; 299571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 300571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 301571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'a': 302571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'b': 303571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'c': 304571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'd': 305571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'e': 306571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'f': 307571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - 'a' + 10) << 4; 308571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 309571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 310571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'A': 311571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'B': 312571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'C': 313571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'D': 314571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'E': 315571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'F': 316571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - 'A' + 10) << 4; 317571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 318571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 319571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): spec does not say how to handle this error 320571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 321571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 322571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 323571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 324571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; // advance 325571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 326571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (in < end && isPdfWhiteSpace(*in)) { 327571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 328571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 329571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 330571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): report error 331571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (in >= end) { 3322ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code; } 333571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 334571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 335571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 336571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 337571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*in == kClosedInequityBracket_PdfDelimiter) { 3382ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code; } 339571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 3401acab362fdde40948e47438edcc4326e04b9b52bedisonn@google.com in++; 341571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 342571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 343571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 344571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (*in) { 345571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '0': 346571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '1': 347571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '2': 348571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '3': 349571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '4': 350571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '5': 351571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '6': 352571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '7': 353571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '8': 354571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '9': 355571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - '0'); 356571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 357571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 358571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'a': 359571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'b': 360571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'c': 361571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'd': 362571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'e': 363571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'f': 364571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - 'a' + 10); 365571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 366571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 367571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'A': 368571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'B': 369571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'C': 370571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'D': 371571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'E': 372571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'F': 373571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - 'A' + 10); 374571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 375571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 376571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): spec does not say how to handle this error 377571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 378571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 379571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 380571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 3812ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code; } 382571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 383571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 384571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 385571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 3862ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { 387c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com return in; // consumed already ) at the end of the string 3882ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else { 389c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // return where the string would end if we reuse the string 390c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com return start + (out - (const unsigned char*)NULL); 391571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 3922ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 393571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 394598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comstatic int readHexStringLength(const unsigned char* start, const unsigned char* end) { 395598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readHexString(start, end, NULL) - start; 3962ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 3972ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 398598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comstatic const unsigned char* readHexString(const unsigned char* start, const unsigned char* end, SkPdfNativeObject* str, SkPdfAllocator* allocator) { 399b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com if (!allocator) { 400c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): report error/warn/assert 401b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com return end; 402b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com } 403598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com int outLength = readHexStringLength(start, end); 4042ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com unsigned char* out = (unsigned char*)allocator->alloc(outLength); 405598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com const unsigned char* now = readHexString(start, end, out); 406598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeHexString(out, out + outLength, str); 407598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // str PUT_TRACK_STREAM(start, now) 4082ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_HEXSTRING(out, out + outLength); 409bca421b468f53a591333918248f54bbd958389d2edisonn@google.com return now; // consumed already > at the end of the string 410571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 411571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 412c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// TODO(edisonn): add version parameter, before PDF 1.2 name could not have special characters. 413c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readName(const unsigned char* start, const unsigned char* end, 414c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com unsigned char* out) { 4152ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com bool hasOut = (out != NULL); 4162ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* in = start; 417571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 418571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com unsigned char code = 0; 419571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 420571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (in < end) { 421571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (isPdfWhiteSpaceOrPdfDelimiter(*in)) { 422571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 423571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 424571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 425571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*in == '#' && in + 2 < end) { 426571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 427571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (*in) { 428571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '0': 429571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '1': 430571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '2': 431571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '3': 432571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '4': 433571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '5': 434571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '6': 435571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '7': 436571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '8': 437571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '9': 438571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - '0') << 4; 439571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 440571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 441571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'a': 442571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'b': 443571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'c': 444571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'd': 445571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'e': 446571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'f': 447571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - 'a' + 10) << 4; 448571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 449571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 450571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'A': 451571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'B': 452571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'C': 453571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'D': 454571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'E': 455571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'F': 456571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code = (*in - 'A' + 10) << 4; 457571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 458571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 459571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): spec does not say how to handle this error 460571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 461571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 462571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 463571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 464571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; // advance 465571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 466571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (*in) { 467571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '0': 468571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '1': 469571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '2': 470571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '3': 471571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '4': 472571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '5': 473571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '6': 474571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '7': 475571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '8': 476571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case '9': 477571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - '0'); 478571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 479571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 480571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'a': 481571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'b': 482571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'c': 483571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'd': 484571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'e': 485571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'f': 486571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - 'a' + 10); 487571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 488571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 489571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'A': 490571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'B': 491571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'C': 492571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'D': 493571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'E': 494571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case 'F': 495571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com code += (*in - 'A' + 10); 496571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 497571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 498571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): spec does not say how to handle this error 499571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 500571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 501571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 502571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 5032ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = code; } 504571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 505571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 506571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 5072ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { *out = *in; } 508571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com out++; 509571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com in++; 510571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 511571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 512571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 5132ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com if (hasOut) { 514c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com return in; // consumed already ) at the end of the string 5152ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } else { 516c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // return where the string would end if we reuse the string 517c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com return start + (out - (const unsigned char*)NULL); 5182ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com } 5192ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 5202ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 521598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.comstatic int readNameLength(const unsigned char* start, const unsigned char* end) { 522598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readName(start, end, NULL) - start; 5232ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com} 5242ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com 525c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readName(const unsigned char* start, const unsigned char* end, 526c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* name, SkPdfAllocator* allocator) { 527b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com if (!allocator) { 528c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): report error/warn/assert 529b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com return end; 530b44334c1c07f307f3e2dbb9ee4ace4c14860a345edisonn@google.com } 531598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com int outLength = readNameLength(start, end); 5322ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com unsigned char* out = (unsigned char*)allocator->alloc(outLength); 533598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com const unsigned char* now = readName(start, end, out); 534598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeName(out, out + outLength, name); 535598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com //PUT_TRACK_STREAM(start, now) 5362ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com TRACE_NAME(out, out + outLength); 537bca421b468f53a591333918248f54bbd958389d2edisonn@google.com return now; 538571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 539571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 540571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// TODO(edisonn): pdf spec let Length to be an indirect object define after the stream 541571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// that makes for an interesting scenario, where the stream itself contains endstream, together 542571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// with a reference object with the length, but the real length object would be somewhere else 543571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// it could confuse the parser 544571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com/*example: 545571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 546571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com7 0 obj 547571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com<< /length 8 0 R>> 548571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comstream 549571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com............... 550571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comendstream 551571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com8 0 obj #we are in stream actually, not a real object 552571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com<< 10 >> #we are in stream actually, not a real object 553571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comendobj 554571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comendstream 555571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com8 0 obj #real obj 556571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com<< 100 >> #real obj 557571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comendobj 558571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comand it could get worse, with multiple object like this 559571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com*/ 560571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 561571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com// right now implement the silly algorithm that assumes endstream is finishing the stream 562571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 563c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readStream(const unsigned char* start, const unsigned char* end, 564c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* dict, SkPdfNativeDoc* doc) { 565598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 566c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com if (!( start[0] == 's' && 567c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[1] == 't' && 568c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[2] == 'r' && 569c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[3] == 'e' && 570c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[4] == 'a' && 571c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[5] == 'm')) { 572571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // no stream. return. 573571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 574571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 575571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 576571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start += 6; // strlen("stream") 577571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { 578571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start += 2; 579571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else if (start[0] == kLF_PdfWhiteSpace) { 580571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start += 1; 58178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else if (isPdfWhiteSpace(start[0])) { 58278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start += 1; 58378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else { 58478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): warn it should be isPdfDelimiter(start[0])) ? 585571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 586571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 587571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkPdfStreamCommonDictionary* stream = (SkPdfStreamCommonDictionary*) dict; 588571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): load Length 589a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com int64_t length = -1; 590571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 591571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): very basic implementation 592951d6532de49003cd5a43f57caf91dd6d3efc33eedisonn@google.com if (stream->has_Length() && stream->Length(doc) > 0) { 593951d6532de49003cd5a43f57caf91dd6d3efc33eedisonn@google.com length = stream->Length(doc); 594571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 595571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 596c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): load external streams 597c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): look at the last filter, to determine how to deal with possible parsing 598c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // issues. The last filter can have special rules to terminate a stream, which we could 599c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // use to determine end of stream. 6004ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 6014ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com if (length >= 0) { 6024ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com const unsigned char* endstream = start + length; 6034ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 6044ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpace) { 6054ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com endstream += 2; 6064ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com } else if (endstream[0] == kLF_PdfWhiteSpace) { 6074ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com endstream += 1; 6084ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com } 6094ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 6104ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com if (strncmp((const char*)endstream, "endstream", strlen("endstream")) != 0) { 6114ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com length = -1; 6124ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com } 6134ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com } 6144ef4bed00efd247a0ea005b95b7239a9d4c14c68edisonn@google.com 615571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (length < 0) { 616571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // scan the buffer, until we find first endstream 617571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): all buffers must have a 0 at the end now, 618c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start, (char*)end, 619c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com "endstream"); 620571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 621571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (endstream) { 622571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com length = endstream - start; 623571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (*(endstream-1) == kLF_PdfWhiteSpace) length--; 62478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (*(endstream-2) == kCR_PdfWhiteSpace) length--; 625571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 626571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 627571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (length >= 0) { 6282ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* endstream = start + length; 629571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 630571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (endstream[0] == kCR_PdfWhiteSpace && endstream[1] == kLF_PdfWhiteSpace) { 631571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com endstream += 2; 632571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else if (endstream[0] == kLF_PdfWhiteSpace) { 633571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com endstream += 1; 634571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 635571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 636571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): verify the next bytes are "endstream" 637571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 638571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com endstream += strlen("endstream"); 639571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): Assert? report error/warning? 640a3356fce903ff75dc332b53dd3a860ba810b9519edisonn@google.com dict->addStream(start, (size_t)length); 641571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return endstream; 642571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 643571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 644571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 645571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 646c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readInlineImageStream(const unsigned char* start, 647c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com const unsigned char* end, 648c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfImageDictionary* inlineImage, 649c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeDoc* doc) { 65078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // We already processed ID keyword, and we should be positioned immediately after it 65178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 652c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): security: either make all streams to have extra 2 bytes at the end, 653c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // instead of this if. 654c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com //if (end - start <= 2) { 655c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // // TODO(edisonn): warning? 656c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // return end; // but can we have a pixel image encoded in 1-2 bytes? 657c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com //} 658c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com 65978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (start[0] == kCR_PdfWhiteSpace && start[1] == kLF_PdfWhiteSpace) { 66078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start += 2; 66178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else if (start[0] == kLF_PdfWhiteSpace) { 66278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start += 1; 66378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else if (isPdfWhiteSpace(start[0])) { 66478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start += 1; 66578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else { 66678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com SkASSERT(isPdfDelimiter(start[0])); 66778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): warning? 66878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 66978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 6702ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* endstream = (const unsigned char*)strrstrk((char*)start, (char*)end, "EI"); 6712ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* endEI = endstream ? endstream + 2 : NULL; // 2 == strlen("EI") 67278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 67378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (endstream) { 67478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com int length = endstream - start; 67578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (*(endstream-1) == kLF_PdfWhiteSpace) length--; 67678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (*(endstream-2) == kCR_PdfWhiteSpace) length--; 67778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com inlineImage->addStream(start, (size_t)length); 67878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else { 67978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): report error in inline image stream (ID-EI) section 68078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): based on filter, try to ignore a missing EI, and read data properly 68178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return end; 68278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 68378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return endEI; 68478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com} 68578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 686c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comstatic const unsigned char* readDictionary(const unsigned char* start, const unsigned char* end, 687c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* dict, 688c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator* allocator, SkPdfNativeDoc* doc) { 6891f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com if (allocator == NULL) { 6901f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com // TODO(edisonn): report/warning error 6911f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com return end; 6921f080163ac58e0a5a621a720de5fc63e7b736765edisonn@google.com } 693598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeEmptyDictionary(dict); 694598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(dict, start, start) 695571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 696598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 697c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator tmpStorage; // keys will be stored in dict, we can free them after set. 698571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 699571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com while (start < end && *start == kNamed_PdfDelimiter) { 7003aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject key; 7012ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com //*start = '\0'; 702571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com start++; 703598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = readName(start, end, &key, &tmpStorage); 704598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 705571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 706571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (start < end) { 7073aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* value = allocator->allocObject(); 708598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = nextObject(start, end, value, allocator, doc); 709571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 710598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 711571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 712571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (start < end) { 713c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // We should have an indirect reference 714571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (isPdfDigit(*start)) { 7153aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject generation; 716598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = nextObject(start, end, &generation, allocator, doc); 717571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 7183aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject keywordR; 719598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = nextObject(start, end, &keywordR, allocator, doc); 720571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 721c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com if (value->isInteger() && generation.isInteger() && 722c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com keywordR.isKeywordReference()) { 723571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com int64_t id = value->intValue(); 724c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject::resetAndMakeReference( 725c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com (unsigned int)id, 726c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com (unsigned int)generation.intValue(), 727c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com value); 728598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_PARAMETERS_OBJ2(value, &generation) 729571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com dict->set(&key, value); 730571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 731c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn) error?, ignore it for now. 732571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com dict->set(&key, value); 733571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 734571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 735571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // next elem is not a digit, but it might not be / either! 736571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com dict->set(&key, value); 737571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 738571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 739571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // /key >> 740571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com dict->set(&key, value); 741571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return end; 742571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 743598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 744571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 7453aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com dict->set(&key, &SkPdfNativeObject::kNull); 746571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return end; 747571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 748571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 749571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 750571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // now we should expect >> 751598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 75278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (*start != kClosedInequityBracket_PdfDelimiter) { 75378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): report/warning 75478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 755c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com 75678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start++; // skip > 75778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (*start != kClosedInequityBracket_PdfDelimiter) { 75878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): report/warning 75978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 760c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com 76178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com start++; // skip > 762571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 763598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com //STORE_TRACK_PARAMETER_OFFSET_END(dict,start); 764bca421b468f53a591333918248f54bbd958389d2edisonn@google.com 765598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = readStream(start, end, dict, doc); 766571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 767571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return start; 768571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 769571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 770c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comconst unsigned char* nextObject(const unsigned char* start, const unsigned char* end, 771c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject* token, 772c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator* allocator, SkPdfNativeDoc* doc) { 7732ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* current; 774571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 775571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // skip white spaces 776598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com start = skipPdfWhiteSpaces(start, end); 777571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 778af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (start >= end) { 779af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return end; 780af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com } 781af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com 782598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com current = endOfPdfToken(start, end); 783571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 784571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // no token, len would be 0 785af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com if (current == start || current == end) { 786af54a513a5b7723b53f61730afe0ad6256881749edisonn@google.com return end; 787571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 788571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 789571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com int tokenLen = current - start; 790571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 791571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (tokenLen == 1) { 792571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // start array 793571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com switch (*start) { 794571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kOpenedSquareBracket_PdfDelimiter: 795598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readArray(current, end, token, allocator, doc); 796571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 797571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kOpenedRoundBracket_PdfDelimiter: 798598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readString(start + 1, end, token, allocator); 799571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 800571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kOpenedInequityBracket_PdfDelimiter: 801571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (end > start + 1 && start[1] == kOpenedInequityBracket_PdfDelimiter) { 802571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // TODO(edisonn): pass here the length somehow? 803598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readDictionary(start + 2, end, token, allocator, doc); // skip << 804571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 805598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readHexString(start + 1, end, token, allocator); // skip < 806571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 807571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 808571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kNamed_PdfDelimiter: 809598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com return readName(start + 1, end, token, allocator); 810571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 811c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): what to do curly brackets? 812571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com case kOpenedCurlyBracket_PdfDelimiter: 813571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com default: 814571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com break; 815571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 816571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 817571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkASSERT(!isPdfWhiteSpace(*start)); 818571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (isPdfDelimiter(*start)) { 819c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): how unexpected stream ] } > ) will be handled? 820571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com // for now ignore, and it will become a keyword to be ignored 821571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 822571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 823571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 824571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (tokenLen == 4 && start[0] == 'n' && start[1] == 'u' && start[2] == 'l' && start[3] == 'l') { 825598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeNull(token); 826598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(start, start + 4) 827571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return current; 828571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 829571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 830571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (tokenLen == 4 && start[0] == 't' && start[1] == 'r' && start[2] == 'u' && start[3] == 'e') { 831598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeBoolean(true, token); 832598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(start, start + 4) 833571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return current; 834571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 835571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 836c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): again, make all buffers have 5 extra bytes 837c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com if (tokenLen == 5 && start[0] == 'f' && 838c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[1] == 'a' && 839c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[2] == 'l' && 840c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[3] == 's' && 841c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com start[4] == 'e') { 842598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeBoolean(false, token); 843598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(start, start + 5) 844571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return current; 845571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 846571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 847571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (isPdfNumeric(*start)) { 848598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeNumeric(start, current, token); 849598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(start, current) 850571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 851598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeKeyword(start, current, token); 852598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM(start, current) 853571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 854571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return current; 855571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 856571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 8573aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfNativeObject* SkPdfAllocator::allocBlock() { 8583aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com fSizeInBytes += BUFFER_SIZE * sizeof(SkPdfNativeObject); 8593aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com return new SkPdfNativeObject[BUFFER_SIZE]; 860571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 861571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 862571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comSkPdfAllocator::~SkPdfAllocator() { 863571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com for (int i = 0 ; i < fHandles.count(); i++) { 864571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com free(fHandles[i]); 865571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 866571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com for (int i = 0 ; i < fHistory.count(); i++) { 867222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com for (int j = 0 ; j < BUFFER_SIZE; j++) { 868222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com fHistory[i][j].reset(); 869222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 870571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com delete[] fHistory[i]; 871571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 872222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com for (int j = 0 ; j < BUFFER_SIZE; j++) { 873222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com fCurrent[j].reset(); 874222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 875571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com delete[] fCurrent; 876571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 877571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 8783aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comSkPdfNativeObject* SkPdfAllocator::allocObject() { 879571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (fCurrentUsed >= BUFFER_SIZE) { 880571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fHistory.push(fCurrent); 881571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fCurrent = allocBlock(); 882571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fCurrentUsed = 0; 8833aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com fSizeInBytes += sizeof(SkPdfNativeObject*); 884571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 885571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fCurrentUsed++; 886571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return &fCurrent[fCurrentUsed - 1]; 887571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 888571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 889c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// TODO(edisonn): perf: do no copy the buffers, but reuse them, and mark cache the result, 890c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com// so there is no need of a second pass 891c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comSkPdfNativeTokenizer::SkPdfNativeTokenizer(SkPdfNativeObject* objWithStream, 892c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator* allocator, 893c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeDoc* doc) 894c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com : fDoc(doc) 895c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fAllocator(allocator) 896c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fUncompressedStream(NULL) 897c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fUncompressedStreamEnd(NULL) 898c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fEmpty(false) 899c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fHasPutBack(false) { 9002ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com const unsigned char* buffer = NULL; 901571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com size_t len = 0; 9022ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com objWithStream->GetFilteredStreamRef(&buffer, &len); 903c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): really bad hack, find end of object (endobj might be in a comment!) 904c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // we need to do now for perf, and our generated pdfs do not have comments, 905c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // but we need to remove this hack for pdfs in the wild 90678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); 907222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com if (endobj) { 908222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com len = endobj - (char*)buffer + strlen("endobj"); 909222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 9102ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com fUncompressedStreamStart = fUncompressedStream = buffer; 911571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fUncompressedStreamEnd = fUncompressedStream + len; 912222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com} 913571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 914c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comSkPdfNativeTokenizer::SkPdfNativeTokenizer(const unsigned char* buffer, int len, 915c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfAllocator* allocator, 916c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeDoc* doc) : fDoc(doc) 917c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fAllocator(allocator) 918c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fEmpty(false) 919c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com , fHasPutBack(false) { 920c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): really bad hack, find end of object (endobj might be in a comment!) 921c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // we need to do now for perf, and our generated pdfs do not have comments, 922c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // but we need to remove this hack for pdfs in the wild 92378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com char* endobj = strrstrk((char*)buffer, (char*)buffer + len, "endobj"); 924222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com if (endobj) { 925222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com len = endobj - (char*)buffer + strlen("endobj"); 926222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com } 9272ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com fUncompressedStreamStart = fUncompressedStream = buffer; 928571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fUncompressedStreamEnd = fUncompressedStream + len; 9293aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com} 9303aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com 9313aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.comSkPdfNativeTokenizer::~SkPdfNativeTokenizer() { 932571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 933571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 934571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.combool SkPdfNativeTokenizer::readTokenCore(PdfToken* token) { 93591ce698cf24c0a86fbdd5e09d29e7f4507a77fecedisonn@google.com#ifdef PDF_TRACE_READ_TOKEN 93691ce698cf24c0a86fbdd5e09d29e7f4507a77fecedisonn@google.com static int read_op = 0; 93791ce698cf24c0a86fbdd5e09d29e7f4507a77fecedisonn@google.com#endif 938c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com 939571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fKeyword = NULL; 940571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fObject = NULL; 941571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 942598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedStreamEnd); 943571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (fUncompressedStream >= fUncompressedStreamEnd) { 9445092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com fEmpty = true; 945571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 946571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 947571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 948c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com SkPdfNativeObject obj; 949598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd, &obj, fAllocator, fDoc); 950598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart) 951571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 952c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // If it is a keyword, we will only get the pointer of the string. 9533aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com if (obj.type() == SkPdfNativeObject::kKeyword_PdfObjectType) { 954571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fKeyword = obj.c_str(); 955e878e726bd1c16a0d177543471e071c7338193f4edisonn@google.com token->fKeywordLength = obj.lenstr(); 956571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fType = kKeyword_TokenType; 957571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } else { 9583aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* pobj = fAllocator->allocObject(); 959571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com *pobj = obj; 960571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fObject = pobj; 961571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com token->fType = kObject_TokenType; 962571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 963571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 9642ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#ifdef PDF_TRACE_READ_TOKEN 965571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com read_op++; 966b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com#if 0 967222382b30a176db9d9044d9df1ae14e0fbe27181edisonn@google.com if (548 == read_op) { 968571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com printf("break;\n"); 969571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 970b0145ce60ea1a3bacc786ec1285218c6fe70c8a3edisonn@google.com#endif 971c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com printf("%i READ %s %s\n", read_op, token->fType == kKeyword_TokenType ? "Keyword" : "Object", 972c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_str() : 973c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com token->fObject->toString().c_str()); 974571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#endif 975571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 976571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return true; 977571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 978571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 979571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.comvoid SkPdfNativeTokenizer::PutBack(PdfToken token) { 980571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com SkASSERT(!fHasPutBack); 981571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fHasPutBack = true; 982571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fPutBack = token; 9832ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#ifdef PDF_TRACE_READ_TOKEN 984c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com printf("PUT_BACK %s %s\n", token.fType == kKeyword_TokenType ? "Keyword" : "Object", 985c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com token.fKeyword ? SkString(token.fKeyword, token.fKeywordLength).c_str() : 986c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com token.fObject->toString().c_str()); 987571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#endif 988571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com} 989571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 9905092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.combool SkPdfNativeTokenizer::readToken(PdfToken* token, bool writeDiff) { 991571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (fHasPutBack) { 992571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com *token = fPutBack; 993571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com fHasPutBack = false; 9942ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#ifdef PDF_TRACE_READ_TOKEN 9955092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com printf("READ_BACK %s %s\n", token->fType == kKeyword_TokenType ? "Keyword" : "Object", 9965092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com token->fKeyword ? SkString(token->fKeyword, token->fKeywordLength).c_str() : 9975092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com token->fObject->toString().c_str()); 998571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#endif 9995092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com if (writeDiff) { 10005092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com SkPdfDiffEncoder::WriteToFile(token); 10015092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com } 1002571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return true; 1003571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 1004571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 1005571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com if (fEmpty) { 10062ccc3afa474f9485c39c2e863252ddaa3f35724bedisonn@google.com#ifdef PDF_TRACE_READ_TOKEN 10075092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com printf("EMPTY TOKENIZER\n"); 1008571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com#endif 1009571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com return false; 1010571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com } 1011571c70b95f56e22b5a7d6f4f288aa6c9a925a64fedisonn@google.com 10125092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com const bool result = readTokenCore(token); 10135092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com if (result && writeDiff) { 10145092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com SkPdfDiffEncoder::WriteToFile(token); 10155092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com } 10165092adc5461a7c5cb3e1fad01be2174c3f4a0c46scroggo@google.com return result; 10173aac1f9f308192f3787265830fe86ce8874e7382edisonn@google.com} 101878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 101978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com#define DECLARE_PDF_NAME(longName) SkPdfName longName((char*)#longName) 102078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 102178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com// keys 102278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(BitsPerComponent); 102378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(ColorSpace); 102478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Decode); 102578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(DecodeParms); 102678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Filter); 102778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Height); 102878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(ImageMask); 1029c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.comDECLARE_PDF_NAME(Intent); // PDF 1.1 - the key, or the abBreviations? 103078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Interpolate); 103178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Width); 103278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 103378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com// values 103478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(DeviceGray); 103578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(DeviceRGB); 103678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(DeviceCMYK); 103778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(Indexed); 103878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(ASCIIHexDecode); 103978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(ASCII85Decode); 104078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(LZWDecode); 104178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(FlateDecode); // PDF 1.2 104278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(RunLengthDecode); 104378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(CCITTFaxDecode); 104478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comDECLARE_PDF_NAME(DCTDecode); 104578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 104678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com#define HANDLE_NAME_ABBR(obj,longName,shortName) if (obj->isName(#shortName)) return &longName; 104778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 104878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 10493aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comstatic SkPdfNativeObject* inlineImageKeyAbbreviationExpand(SkPdfNativeObject* key) { 105078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (!key || !key->isName()) { 105178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return key; 105278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 105378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 105478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): use autogenerated code! 105578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, BitsPerComponent, BPC); 105678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, ColorSpace, CS); 105778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, Decode, D); 105878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, DecodeParms, DP); 105978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, Filter, F); 106078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, Height, H); 106178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, ImageMask, IM); 106278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com// HANDLE_NAME_ABBR(key, Intent, ); 106378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, Interpolate, I); 106478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(key, Width, W); 106578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 106678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return key; 106778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com} 106878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 10693aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.comstatic SkPdfNativeObject* inlineImageValueAbbreviationExpand(SkPdfNativeObject* value) { 107078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (!value || !value->isName()) { 107178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return value; 107278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 107378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 107478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): use autogenerated code! 107578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, DeviceGray, G); 107678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, DeviceRGB, RGB); 107778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, DeviceCMYK, CMYK); 107878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, Indexed, I); 107978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, ASCIIHexDecode, AHx); 108078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, ASCII85Decode, A85); 108178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, LZWDecode, LZW); 108278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, FlateDecode, Fl); // (PDF 1.2) 108378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, RunLengthDecode, RL); 108478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, CCITTFaxDecode, CCF); 108578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com HANDLE_NAME_ABBR(value, DCTDecode, DCT); 108678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 108778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return value; 108878b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com} 108978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 109078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.comSkPdfImageDictionary* SkPdfNativeTokenizer::readInlineImage() { 109178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // BI already processed 1092598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com fUncompressedStream = skipPdfWhiteSpaces(fUncompressedStream, fUncompressedStreamEnd); 109378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com if (fUncompressedStream >= fUncompressedStreamEnd) { 109478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return NULL; 109578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 109678b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 109778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com SkPdfImageDictionary* inlineImage = (SkPdfImageDictionary*)fAllocator->allocObject(); 1098598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com SkPdfNativeObject::makeEmptyDictionary(inlineImage); 1099c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // PUT_TRACK_STREAM_ARGS_EXPL(fStreamId, fUncompressedStream - fUncompressedStreamStart, 1100c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // fUncompressedStream - fUncompressedStreamStart) 110178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 110278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com while (fUncompressedStream < fUncompressedStreamEnd) { 11033aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* key = fAllocator->allocObject(); 1104c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd, key, 1105c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fAllocator, fDoc); 1106598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)s 110778b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com 1108c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com if (key->isKeyword() && key->lenstr() == 2 && 1109c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com key->c_str()[0] == 'I' && key->c_str()[1] == 'D') { // ID 1110c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fUncompressedStream = readInlineImageStream(fUncompressedStream, fUncompressedStreamEnd, 1111c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com inlineImage, fDoc); 111278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return inlineImage; 111378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } else { 11143aa355527a3b91d3e12b8bee49e5637d00a736caedisonn@google.com SkPdfNativeObject* obj = fAllocator->allocObject(); 1115c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fUncompressedStream = nextObject(fUncompressedStream, fUncompressedStreamEnd, obj, 1116c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com fAllocator, fDoc); 1117598cf5d3cfc428108cf21ab45d73a995d7e5c2a8edisonn@google.com // PUT_TRACK_STREAM_ARGS_EXPL2(fStreamId, fUncompressedStreamStart)s 1118c8fda9d96be0bd944d37a6e23f7adad5f247c51dedisonn@google.com // TODO(edisonn): perf maybe we should not expand abBreviation like this 111978b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com inlineImage->set(inlineImageKeyAbbreviationExpand(key), 112078b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com inlineImageValueAbbreviationExpand(obj)); 112178b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 112278b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com } 112378b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com // TODO(edisonn): report end of data with inline image without an EI 112478b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com return inlineImage; 112578b38b130deb8bcfa41611039875ce0162542ac1edisonn@google.com} 1126