diff options
author | tcit <tcit@tcit.fr> | 2014-07-24 15:49:36 +0200 |
---|---|---|
committer | tcit <tcit@tcit.fr> | 2014-07-24 15:49:36 +0200 |
commit | 4188f38ad56d7ba2ea46e94403f305243514f80c (patch) | |
tree | f357ddbd0d846ebae0ecf5d2ab00d6b7dd6eb8d5 /inc/3rdparty/libraries/mpdf/mpdfi | |
parent | 2b58426b2d4a7f1585d5d7667c0a4fbea4cd29dd (diff) | |
download | wallabag-4188f38ad56d7ba2ea46e94403f305243514f80c.tar.gz wallabag-4188f38ad56d7ba2ea46e94403f305243514f80c.tar.zst wallabag-4188f38ad56d7ba2ea46e94403f305243514f80c.zip |
add pdf and mobi libraries
Diffstat (limited to 'inc/3rdparty/libraries/mpdf/mpdfi')
-rw-r--r-- | inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterASCII85.php | 98 | ||||
-rw-r--r-- | inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterLZW.php | 154 | ||||
-rw-r--r-- | inc/3rdparty/libraries/mpdf/mpdfi/fpdi_pdf_parser.php | 363 | ||||
-rw-r--r-- | inc/3rdparty/libraries/mpdf/mpdfi/pdf_context.php | 78 | ||||
-rw-r--r-- | inc/3rdparty/libraries/mpdf/mpdfi/pdf_parser.php | 690 |
5 files changed, 1383 insertions, 0 deletions
diff --git a/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterASCII85.php b/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterASCII85.php new file mode 100644 index 00000000..fc42d574 --- /dev/null +++ b/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterASCII85.php | |||
@@ -0,0 +1,98 @@ | |||
1 | <?php | ||
2 | // | ||
3 | // FPDI - Version 1.3.1 | ||
4 | // | ||
5 | // Copyright 2004-2009 Setasign - Jan Slabon | ||
6 | // | ||
7 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | // you may not use this file except in compliance with the License. | ||
9 | // You may obtain a copy of the License at | ||
10 | // | ||
11 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | // | ||
13 | // Unless required by applicable law or agreed to in writing, software | ||
14 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | // See the License for the specific language governing permissions and | ||
17 | // limitations under the License. | ||
18 | // | ||
19 | |||
20 | if (!defined('ORD_z')) | ||
21 | define('ORD_z',ord('z')); | ||
22 | if (!defined('ORD_exclmark')) | ||
23 | define('ORD_exclmark', ord('!')); | ||
24 | if (!defined('ORD_u')) | ||
25 | define('ORD_u', ord('u')); | ||
26 | if (!defined('ORD_tilde')) | ||
27 | define('ORD_tilde', ord('~')); | ||
28 | |||
29 | class FilterASCII85 { | ||
30 | |||
31 | function error($msg) { | ||
32 | die($msg); | ||
33 | } | ||
34 | |||
35 | function decode($in) { | ||
36 | $out = ''; | ||
37 | $state = 0; | ||
38 | $chn = null; | ||
39 | |||
40 | $l = strlen($in); | ||
41 | |||
42 | for ($k = 0; $k < $l; ++$k) { | ||
43 | $ch = ord($in[$k]) & 0xff; | ||
44 | |||
45 | if ($ch == ORD_tilde) { | ||
46 | break; | ||
47 | } | ||
48 | if (preg_match('/^\s$/',chr($ch))) { | ||
49 | continue; | ||
50 | } | ||
51 | if ($ch == ORD_z && $state == 0) { | ||
52 | $out .= chr(0).chr(0).chr(0).chr(0); | ||
53 | continue; | ||
54 | } | ||
55 | if ($ch < ORD_exclmark || $ch > ORD_u) { | ||
56 | $this->error('Illegal character in ASCII85Decode.'); | ||
57 | } | ||
58 | |||
59 | $chn[$state++] = $ch - ORD_exclmark; | ||
60 | |||
61 | if ($state == 5) { | ||
62 | $state = 0; | ||
63 | $r = 0; | ||
64 | for ($j = 0; $j < 5; ++$j) | ||
65 | $r = $r * 85 + $chn[$j]; | ||
66 | $out .= chr($r >> 24); | ||
67 | $out .= chr($r >> 16); | ||
68 | $out .= chr($r >> 8); | ||
69 | $out .= chr($r); | ||
70 | } | ||
71 | } | ||
72 | $r = 0; | ||
73 | |||
74 | if ($state == 1) | ||
75 | $this->error('Illegal length in ASCII85Decode.'); | ||
76 | if ($state == 2) { | ||
77 | $r = $chn[0] * 85 * 85 * 85 * 85 + ($chn[1]+1) * 85 * 85 * 85; | ||
78 | $out .= chr($r >> 24); | ||
79 | } | ||
80 | else if ($state == 3) { | ||
81 | $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + ($chn[2]+1) * 85 * 85; | ||
82 | $out .= chr($r >> 24); | ||
83 | $out .= chr($r >> 16); | ||
84 | } | ||
85 | else if ($state == 4) { | ||
86 | $r = $chn[0] * 85 * 85 * 85 * 85 + $chn[1] * 85 * 85 * 85 + $chn[2] * 85 * 85 + ($chn[3]+1) * 85 ; | ||
87 | $out .= chr($r >> 24); | ||
88 | $out .= chr($r >> 16); | ||
89 | $out .= chr($r >> 8); | ||
90 | } | ||
91 | |||
92 | return $out; | ||
93 | } | ||
94 | |||
95 | function encode($in) { | ||
96 | $this->error("ASCII85 encoding not implemented."); | ||
97 | } | ||
98 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterLZW.php b/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterLZW.php new file mode 100644 index 00000000..5867603f --- /dev/null +++ b/inc/3rdparty/libraries/mpdf/mpdfi/filters/FilterLZW.php | |||
@@ -0,0 +1,154 @@ | |||
1 | <?php | ||
2 | // | ||
3 | // FPDI - Version 1.3.1 | ||
4 | // | ||
5 | // Copyright 2004-2009 Setasign - Jan Slabon | ||
6 | // | ||
7 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | // you may not use this file except in compliance with the License. | ||
9 | // You may obtain a copy of the License at | ||
10 | // | ||
11 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | // | ||
13 | // Unless required by applicable law or agreed to in writing, software | ||
14 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | // See the License for the specific language governing permissions and | ||
17 | // limitations under the License. | ||
18 | // | ||
19 | |||
20 | class FilterLZW { | ||
21 | |||
22 | var $sTable = array(); | ||
23 | var $data = null; | ||
24 | var $dataLength = 0; | ||
25 | var $tIdx; | ||
26 | var $bitsToGet = 9; | ||
27 | var $bytePointer; | ||
28 | var $bitPointer; | ||
29 | var $nextData = 0; | ||
30 | var $nextBits = 0; | ||
31 | var $andTable = array(511, 1023, 2047, 4095); | ||
32 | |||
33 | function error($msg) { | ||
34 | die($msg); | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Method to decode LZW compressed data. | ||
39 | * | ||
40 | * @param string data The compressed data. | ||
41 | */ | ||
42 | function decode($data) { | ||
43 | |||
44 | if($data[0] == 0x00 && $data[1] == 0x01) { | ||
45 | $this->error('LZW flavour not supported.'); | ||
46 | } | ||
47 | |||
48 | $this->initsTable(); | ||
49 | |||
50 | $this->data = $data; | ||
51 | $this->dataLength = strlen($data); | ||
52 | |||
53 | // Initialize pointers | ||
54 | $this->bytePointer = 0; | ||
55 | $this->bitPointer = 0; | ||
56 | |||
57 | $this->nextData = 0; | ||
58 | $this->nextBits = 0; | ||
59 | |||
60 | $oldCode = 0; | ||
61 | |||
62 | $string = ''; | ||
63 | $uncompData = ''; | ||
64 | |||
65 | while (($code = $this->getNextCode()) != 257) { | ||
66 | if ($code == 256) { | ||
67 | $this->initsTable(); | ||
68 | $code = $this->getNextCode(); | ||
69 | |||
70 | if ($code == 257) { | ||
71 | break; | ||
72 | } | ||
73 | |||
74 | $uncompData .= $this->sTable[$code]; | ||
75 | $oldCode = $code; | ||
76 | |||
77 | } else { | ||
78 | |||
79 | if ($code < $this->tIdx) { | ||
80 | $string = $this->sTable[$code]; | ||
81 | $uncompData .= $string; | ||
82 | |||
83 | $this->addStringToTable($this->sTable[$oldCode], $string[0]); | ||
84 | $oldCode = $code; | ||
85 | } else { | ||
86 | $string = $this->sTable[$oldCode]; | ||
87 | $string = $string.$string[0]; | ||
88 | $uncompData .= $string; | ||
89 | |||
90 | $this->addStringToTable($string); | ||
91 | $oldCode = $code; | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | return $uncompData; | ||
97 | } | ||
98 | |||
99 | |||
100 | /** | ||
101 | * Initialize the string table. | ||
102 | */ | ||
103 | function initsTable() { | ||
104 | $this->sTable = array(); | ||
105 | |||
106 | for ($i = 0; $i < 256; $i++) | ||
107 | $this->sTable[$i] = chr($i); | ||
108 | |||
109 | $this->tIdx = 258; | ||
110 | $this->bitsToGet = 9; | ||
111 | } | ||
112 | |||
113 | /** | ||
114 | * Add a new string to the string table. | ||
115 | */ | ||
116 | function addStringToTable ($oldString, $newString='') { | ||
117 | $string = $oldString.$newString; | ||
118 | |||
119 | // Add this new String to the table | ||
120 | $this->sTable[$this->tIdx++] = $string; | ||
121 | |||
122 | if ($this->tIdx == 511) { | ||
123 | $this->bitsToGet = 10; | ||
124 | } else if ($this->tIdx == 1023) { | ||
125 | $this->bitsToGet = 11; | ||
126 | } else if ($this->tIdx == 2047) { | ||
127 | $this->bitsToGet = 12; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | // Returns the next 9, 10, 11 or 12 bits | ||
132 | function getNextCode() { | ||
133 | if ($this->bytePointer == $this->dataLength) { | ||
134 | return 257; | ||
135 | } | ||
136 | |||
137 | $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); | ||
138 | $this->nextBits += 8; | ||
139 | |||
140 | if ($this->nextBits < $this->bitsToGet) { | ||
141 | $this->nextData = ($this->nextData << 8) | (ord($this->data[$this->bytePointer++]) & 0xff); | ||
142 | $this->nextBits += 8; | ||
143 | } | ||
144 | |||
145 | $code = ($this->nextData >> ($this->nextBits - $this->bitsToGet)) & $this->andTable[$this->bitsToGet-9]; | ||
146 | $this->nextBits -= $this->bitsToGet; | ||
147 | |||
148 | return $code; | ||
149 | } | ||
150 | |||
151 | function encode($in) { | ||
152 | $this->error("LZW encoding not implemented."); | ||
153 | } | ||
154 | } \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/mpdf/mpdfi/fpdi_pdf_parser.php b/inc/3rdparty/libraries/mpdf/mpdfi/fpdi_pdf_parser.php new file mode 100644 index 00000000..e0f02391 --- /dev/null +++ b/inc/3rdparty/libraries/mpdf/mpdfi/fpdi_pdf_parser.php | |||
@@ -0,0 +1,363 @@ | |||
1 | <?php | ||
2 | // | ||
3 | // FPDI - Version 1.2 | ||
4 | // | ||
5 | // Copyright 2004-2007 Setasign - Jan Slabon | ||
6 | // | ||
7 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | // you may not use this file except in compliance with the License. | ||
9 | // You may obtain a copy of the License at | ||
10 | // | ||
11 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | // | ||
13 | // Unless required by applicable law or agreed to in writing, software | ||
14 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | // See the License for the specific language governing permissions and | ||
17 | // limitations under the License. | ||
18 | // | ||
19 | |||
20 | |||
21 | class fpdi_pdf_parser extends pdf_parser { | ||
22 | |||
23 | /** | ||
24 | * Pages | ||
25 | * Index beginns at 0 | ||
26 | * | ||
27 | * @var array | ||
28 | */ | ||
29 | var $pages; | ||
30 | |||
31 | /** | ||
32 | * Page count | ||
33 | * @var integer | ||
34 | */ | ||
35 | var $page_count; | ||
36 | |||
37 | /** | ||
38 | * actual page number | ||
39 | * @var integer | ||
40 | */ | ||
41 | var $pageno; | ||
42 | |||
43 | |||
44 | /** | ||
45 | * FPDI Reference | ||
46 | * @var object | ||
47 | */ | ||
48 | var $fpdi; | ||
49 | |||
50 | /** | ||
51 | * Available BoxTypes | ||
52 | * | ||
53 | * @var array | ||
54 | */ | ||
55 | var $availableBoxes = array("/MediaBox","/CropBox","/BleedBox","/TrimBox","/ArtBox"); | ||
56 | |||
57 | /** | ||
58 | * Constructor | ||
59 | * | ||
60 | * @param string $filename Source-Filename | ||
61 | * @param object $fpdi Object of type fpdi | ||
62 | */ | ||
63 | function fpdi_pdf_parser($filename,&$fpdi) { | ||
64 | $this->fpdi =& $fpdi; | ||
65 | $this->filename = $filename; | ||
66 | |||
67 | parent::pdf_parser($filename); | ||
68 | if ($this->success == false) { return false; } | ||
69 | |||
70 | // resolve Pages-Dictonary | ||
71 | $pages = $this->pdf_resolve_object($this->c, $this->root[1][1]['/Pages']); | ||
72 | if ($this->success == false) { return false; } | ||
73 | |||
74 | // Read pages | ||
75 | $this->read_pages($this->c, $pages, $this->pages); | ||
76 | if ($this->success == false) { return false; } | ||
77 | |||
78 | // count pages; | ||
79 | $this->page_count = count($this->pages); | ||
80 | } | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Get pagecount from sourcefile | ||
85 | * | ||
86 | * @return int | ||
87 | */ | ||
88 | function getPageCount() { | ||
89 | return $this->page_count; | ||
90 | } | ||
91 | |||
92 | |||
93 | /** | ||
94 | * Set pageno | ||
95 | * | ||
96 | * @param int $pageno Pagenumber to use | ||
97 | */ | ||
98 | function setPageno($pageno) { | ||
99 | $pageno = ((int) $pageno) - 1; | ||
100 | |||
101 | if ($pageno < 0 || $pageno >= $this->getPageCount()) { | ||
102 | $this->fpdi->error("Pagenumber is wrong!"); | ||
103 | } | ||
104 | |||
105 | $this->pageno = $pageno; | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * Get page-resources from current page | ||
110 | * | ||
111 | * @return array | ||
112 | */ | ||
113 | function getPageResources() { | ||
114 | return $this->_getPageResources($this->pages[$this->pageno]); | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Get page-resources from /Page | ||
119 | * | ||
120 | * @param array $obj Array of pdf-data | ||
121 | */ | ||
122 | function _getPageResources ($obj) { // $obj = /Page | ||
123 | $obj = $this->pdf_resolve_object($this->c, $obj); | ||
124 | |||
125 | // If the current object has a resources | ||
126 | // dictionary associated with it, we use | ||
127 | // it. Otherwise, we move back to its | ||
128 | // parent object. | ||
129 | if (isset ($obj[1][1]['/Resources'])) { | ||
130 | $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Resources']); | ||
131 | if ($res[0] == PDF_TYPE_OBJECT) | ||
132 | return $res[1]; | ||
133 | return $res; | ||
134 | } else { | ||
135 | if (!isset ($obj[1][1]['/Parent'])) { | ||
136 | return false; | ||
137 | } else { | ||
138 | $res = $this->_getPageResources($obj[1][1]['/Parent']); | ||
139 | if ($res[0] == PDF_TYPE_OBJECT) | ||
140 | return $res[1]; | ||
141 | return $res; | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | |||
147 | /** | ||
148 | * Get content of current page | ||
149 | * | ||
150 | * If more /Contents is an array, the streams are concated | ||
151 | * | ||
152 | * @return string | ||
153 | */ | ||
154 | function getContent() { | ||
155 | $buffer = ""; | ||
156 | |||
157 | if (isset($this->pages[$this->pageno][1][1]['/Contents'])) { | ||
158 | $contents = $this->_getPageContent($this->pages[$this->pageno][1][1]['/Contents']); | ||
159 | foreach($contents AS $tmp_content) { | ||
160 | $buffer .= $this->_rebuildContentStream($tmp_content).' '; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | return $buffer; | ||
165 | } | ||
166 | |||
167 | |||
168 | /** | ||
169 | * Resolve all content-objects | ||
170 | * | ||
171 | * @param array $content_ref | ||
172 | * @return array | ||
173 | */ | ||
174 | function _getPageContent($content_ref) { | ||
175 | $contents = array(); | ||
176 | |||
177 | if ($content_ref[0] == PDF_TYPE_OBJREF) { | ||
178 | $content = $this->pdf_resolve_object($this->c, $content_ref); | ||
179 | if ($content[1][0] == PDF_TYPE_ARRAY) { | ||
180 | $contents = $this->_getPageContent($content[1]); | ||
181 | } else { | ||
182 | $contents[] = $content; | ||
183 | } | ||
184 | } else if ($content_ref[0] == PDF_TYPE_ARRAY) { | ||
185 | foreach ($content_ref[1] AS $tmp_content_ref) { | ||
186 | $contents = array_merge($contents,$this->_getPageContent($tmp_content_ref)); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | return $contents; | ||
191 | } | ||
192 | |||
193 | |||
194 | /** | ||
195 | * Rebuild content-streams | ||
196 | * | ||
197 | * @param array $obj | ||
198 | * @return string | ||
199 | */ | ||
200 | function _rebuildContentStream($obj) { | ||
201 | $filters = array(); | ||
202 | |||
203 | if (isset($obj[1][1]['/Filter'])) { | ||
204 | $_filter = $obj[1][1]['/Filter']; | ||
205 | |||
206 | if ($_filter[0] == PDF_TYPE_TOKEN) { | ||
207 | $filters[] = $_filter; | ||
208 | } else if ($_filter[0] == PDF_TYPE_ARRAY) { | ||
209 | $filters = $_filter[1]; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | $stream = $obj[2][1]; | ||
214 | |||
215 | foreach ($filters AS $_filter) { | ||
216 | switch ($_filter[1]) { | ||
217 | case "/FlateDecode": | ||
218 | if (function_exists('gzuncompress')) { | ||
219 | $stream = (strlen($stream) > 0) ? @gzuncompress($stream) : ''; | ||
220 | } else { | ||
221 | $this->fpdi->error(sprintf("To handle %s filter, please compile php with zlib support.",$_filter[1])); | ||
222 | } | ||
223 | if ($stream === false) { | ||
224 | $this->fpdi->error("Error while decompressing stream."); | ||
225 | } | ||
226 | break; | ||
227 | // mPDF 4.2.003 | ||
228 | case '/LZWDecode': | ||
229 | include_once(_MPDF_PATH.'mpdfi/filters/FilterLZW.php'); | ||
230 | // mPDF 5.0 Removed pass by reference =& | ||
231 | $decoder = new FilterLZW(); | ||
232 | $stream = $decoder->decode($stream); | ||
233 | break; | ||
234 | case '/ASCII85Decode': | ||
235 | include_once(_MPDF_PATH.'mpdfi/filters/FilterASCII85.php'); | ||
236 | // mPDF 5.0 Removed pass by reference =& | ||
237 | $decoder = new FilterASCII85(); | ||
238 | $stream = $decoder->decode($stream); | ||
239 | break; | ||
240 | case null: | ||
241 | $stream = $stream; | ||
242 | break; | ||
243 | default: | ||
244 | $this->fpdi->error(sprintf("Unsupported Filter: %s",$_filter[1])); | ||
245 | } | ||
246 | } | ||
247 | |||
248 | return $stream; | ||
249 | } | ||
250 | |||
251 | |||
252 | /** | ||
253 | * Get a Box from a page | ||
254 | * Arrayformat is same as used by fpdf_tpl | ||
255 | * | ||
256 | * @param array $page a /Page | ||
257 | * @param string $box_index Type of Box @see $availableBoxes | ||
258 | * @return array | ||
259 | */ | ||
260 | function getPageBox($page, $box_index) { | ||
261 | $page = $this->pdf_resolve_object($this->c,$page); | ||
262 | $box = null; | ||
263 | if (isset($page[1][1][$box_index])) | ||
264 | $box =& $page[1][1][$box_index]; | ||
265 | |||
266 | if (!is_null($box) && $box[0] == PDF_TYPE_OBJREF) { | ||
267 | $tmp_box = $this->pdf_resolve_object($this->c,$box); | ||
268 | $box = $tmp_box[1]; | ||
269 | } | ||
270 | |||
271 | if (!is_null($box) && $box[0] == PDF_TYPE_ARRAY) { | ||
272 | $b =& $box[1]; | ||
273 | return array("x" => $b[0][1]/_MPDFK, | ||
274 | "y" => $b[1][1]/_MPDFK, | ||
275 | "w" => abs($b[0][1]-$b[2][1])/_MPDFK, | ||
276 | "h" => abs($b[1][1]-$b[3][1])/_MPDFK); // mPDF 5.3.90 | ||
277 | } else if (!isset ($page[1][1]['/Parent'])) { | ||
278 | return false; | ||
279 | } else { | ||
280 | return $this->getPageBox($this->pdf_resolve_object($this->c, $page[1][1]['/Parent']), $box_index); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | function getPageBoxes($pageno) { | ||
285 | return $this->_getPageBoxes($this->pages[$pageno-1]); | ||
286 | } | ||
287 | |||
288 | /** | ||
289 | * Get all Boxes from /Page | ||
290 | * | ||
291 | * @param array a /Page | ||
292 | * @return array | ||
293 | */ | ||
294 | function _getPageBoxes($page) { | ||
295 | $boxes = array(); | ||
296 | |||
297 | foreach($this->availableBoxes AS $box) { | ||
298 | if ($_box = $this->getPageBox($page,$box)) { | ||
299 | $boxes[$box] = $_box; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | return $boxes; | ||
304 | } | ||
305 | |||
306 | function getPageRotation($pageno) { | ||
307 | return $this->_getPageRotation($this->pages[$pageno-1]); | ||
308 | } | ||
309 | |||
310 | function _getPageRotation ($obj) { // $obj = /Page | ||
311 | $obj = $this->pdf_resolve_object($this->c, $obj); | ||
312 | if (isset ($obj[1][1]['/Rotate'])) { | ||
313 | $res = $this->pdf_resolve_object($this->c, $obj[1][1]['/Rotate']); | ||
314 | if ($res[0] == PDF_TYPE_OBJECT) | ||
315 | return $res[1]; | ||
316 | return $res; | ||
317 | } else { | ||
318 | if (!isset ($obj[1][1]['/Parent'])) { | ||
319 | return false; | ||
320 | } else { | ||
321 | $res = $this->_getPageRotation($obj[1][1]['/Parent']); | ||
322 | if ($res[0] == PDF_TYPE_OBJECT) | ||
323 | return $res[1]; | ||
324 | return $res; | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Read all /Page(es) | ||
331 | * | ||
332 | * @param object pdf_context | ||
333 | * @param array /Pages | ||
334 | * @param array the result-array | ||
335 | */ | ||
336 | function read_pages (&$c, &$pages, &$result) { | ||
337 | // Get the kids dictionary | ||
338 | $kids = $this->pdf_resolve_object ($c, $pages[1][1]['/Kids']); | ||
339 | |||
340 | if (!is_array($kids)) { | ||
341 | // mPDF 4.0 | ||
342 | $this->success = false; | ||
343 | $this->errormsg = sprintf("Cannot find /Kids in current /Page-Dictionary"); | ||
344 | return false; | ||
345 | } | ||
346 | foreach ($kids[1] as $v) { | ||
347 | $pg = $this->pdf_resolve_object ($c, $v); | ||
348 | if ($pg[1][1]['/Type'][1] === '/Pages') { | ||
349 | // If one of the kids is an embedded | ||
350 | // /Pages array, resolve it as well. | ||
351 | $this->read_pages ($c, $pg, $result); | ||
352 | } else { | ||
353 | $result[] = $pg; | ||
354 | } | ||
355 | } | ||
356 | } | ||
357 | |||
358 | |||
359 | |||
360 | |||
361 | } | ||
362 | |||
363 | ?> \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/mpdf/mpdfi/pdf_context.php b/inc/3rdparty/libraries/mpdf/mpdfi/pdf_context.php new file mode 100644 index 00000000..6cf4bdcc --- /dev/null +++ b/inc/3rdparty/libraries/mpdf/mpdfi/pdf_context.php | |||
@@ -0,0 +1,78 @@ | |||
1 | <?php | ||
2 | // | ||
3 | // FPDI - Version 1.2 | ||
4 | // | ||
5 | // Copyright 2004-2007 Setasign - Jan Slabon | ||
6 | // | ||
7 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | // you may not use this file except in compliance with the License. | ||
9 | // You may obtain a copy of the License at | ||
10 | // | ||
11 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | // | ||
13 | // Unless required by applicable law or agreed to in writing, software | ||
14 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | // See the License for the specific language governing permissions and | ||
17 | // limitations under the License. | ||
18 | // | ||
19 | |||
20 | class pdf_context { | ||
21 | |||
22 | var $file; | ||
23 | var $buffer; | ||
24 | var $offset; | ||
25 | var $length; | ||
26 | |||
27 | var $stack; | ||
28 | |||
29 | // Constructor | ||
30 | |||
31 | function pdf_context($f) { | ||
32 | $this->file = $f; | ||
33 | $this->reset(); | ||
34 | } | ||
35 | |||
36 | // Optionally move the file | ||
37 | // pointer to a new location | ||
38 | // and reset the buffered data | ||
39 | |||
40 | function reset($pos = null, $l = 100) { | ||
41 | if (!is_null ($pos)) { | ||
42 | fseek ($this->file, $pos); | ||
43 | } | ||
44 | |||
45 | $this->buffer = $l > 0 ? fread($this->file, $l) : ''; | ||
46 | $this->offset = 0; | ||
47 | $this->length = strlen($this->buffer); | ||
48 | $this->stack = array(); | ||
49 | } | ||
50 | |||
51 | // Make sure that there is at least one | ||
52 | // character beyond the current offset in | ||
53 | // the buffer to prevent the tokenizer | ||
54 | // from attempting to access data that does | ||
55 | // not exist | ||
56 | |||
57 | function ensure_content() { | ||
58 | if ($this->offset >= $this->length - 1) { | ||
59 | return $this->increase_length(); | ||
60 | } else { | ||
61 | return true; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | // Forcefully read more data into the buffer | ||
66 | |||
67 | function increase_length($l=100) { | ||
68 | if (feof($this->file)) { | ||
69 | return false; | ||
70 | } else { | ||
71 | $this->buffer .= fread($this->file, $l); | ||
72 | $this->length = strlen($this->buffer); | ||
73 | return true; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | } | ||
78 | ?> \ No newline at end of file | ||
diff --git a/inc/3rdparty/libraries/mpdf/mpdfi/pdf_parser.php b/inc/3rdparty/libraries/mpdf/mpdfi/pdf_parser.php new file mode 100644 index 00000000..c7d69e2c --- /dev/null +++ b/inc/3rdparty/libraries/mpdf/mpdfi/pdf_parser.php | |||
@@ -0,0 +1,690 @@ | |||
1 | <?php | ||
2 | // | ||
3 | // FPDI - Version 1.2 | ||
4 | // | ||
5 | // Copyright 2004-2007 Setasign - Jan Slabon | ||
6 | // | ||
7 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | // you may not use this file except in compliance with the License. | ||
9 | // You may obtain a copy of the License at | ||
10 | // | ||
11 | // http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | // | ||
13 | // Unless required by applicable law or agreed to in writing, software | ||
14 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | // See the License for the specific language governing permissions and | ||
17 | // limitations under the License. | ||
18 | // | ||
19 | |||
20 | if (!defined ('PDF_TYPE_NULL')) | ||
21 | define ('PDF_TYPE_NULL', 0); | ||
22 | if (!defined ('PDF_TYPE_NUMERIC')) | ||
23 | define ('PDF_TYPE_NUMERIC', 1); | ||
24 | if (!defined ('PDF_TYPE_TOKEN')) | ||
25 | define ('PDF_TYPE_TOKEN', 2); | ||
26 | if (!defined ('PDF_TYPE_HEX')) | ||
27 | define ('PDF_TYPE_HEX', 3); | ||
28 | if (!defined ('PDF_TYPE_STRING')) | ||
29 | define ('PDF_TYPE_STRING', 4); | ||
30 | if (!defined ('PDF_TYPE_DICTIONARY')) | ||
31 | define ('PDF_TYPE_DICTIONARY', 5); | ||
32 | if (!defined ('PDF_TYPE_ARRAY')) | ||
33 | define ('PDF_TYPE_ARRAY', 6); | ||
34 | if (!defined ('PDF_TYPE_OBJDEC')) | ||
35 | define ('PDF_TYPE_OBJDEC', 7); | ||
36 | if (!defined ('PDF_TYPE_OBJREF')) | ||
37 | define ('PDF_TYPE_OBJREF', 8); | ||
38 | if (!defined ('PDF_TYPE_OBJECT')) | ||
39 | define ('PDF_TYPE_OBJECT', 9); | ||
40 | if (!defined ('PDF_TYPE_STREAM')) | ||
41 | define ('PDF_TYPE_STREAM', 10); | ||
42 | |||
43 | |||
44 | class pdf_parser { | ||
45 | |||
46 | /** | ||
47 | * Filename | ||
48 | * @var string | ||
49 | */ | ||
50 | var $filename; | ||
51 | |||
52 | /** | ||
53 | * File resource | ||
54 | * @var resource | ||
55 | */ | ||
56 | var $f; | ||
57 | |||
58 | /** | ||
59 | * PDF Context | ||
60 | * @var object pdf_context-Instance | ||
61 | */ | ||
62 | var $c; | ||
63 | |||
64 | /** | ||
65 | * xref-Data | ||
66 | * @var array | ||
67 | */ | ||
68 | var $xref; | ||
69 | |||
70 | /** | ||
71 | * root-Object | ||
72 | * @var array | ||
73 | */ | ||
74 | var $root; | ||
75 | |||
76 | // mPDF 4.0 Added flag to show success on loading file | ||
77 | var $success; | ||
78 | var $errormsg; | ||
79 | |||
80 | /** | ||
81 | * Constructor | ||
82 | * | ||
83 | * @param string $filename Source-Filename | ||
84 | */ | ||
85 | function pdf_parser($filename) { | ||
86 | $this->filename = $filename; | ||
87 | // mPDF 4.0 | ||
88 | $this->success = true; | ||
89 | |||
90 | $this->f = @fopen($this->filename, "rb"); | ||
91 | |||
92 | if (!$this->f) { | ||
93 | $this->success = false; | ||
94 | $this->errormsg = sprintf("Cannot open %s !", $filename); | ||
95 | return false; | ||
96 | } | ||
97 | // mPDF 5.0 Removed pass by reference =& | ||
98 | $this->c = new pdf_context($this->f); | ||
99 | // Read xref-Data | ||
100 | $offset = $this->pdf_find_xref(); | ||
101 | if ($offset===false) { | ||
102 | $this->success = false; | ||
103 | $this->errormsg = sprintf("Cannot open %s !", $filename); | ||
104 | return false; | ||
105 | } | ||
106 | $this->pdf_read_xref($this->xref, $offset); | ||
107 | if ($this->success == false) { return false; } | ||
108 | |||
109 | // Check for Encryption | ||
110 | $this->getEncryption(); | ||
111 | if ($this->success == false) { return false; } | ||
112 | |||
113 | // Read root | ||
114 | $this->pdf_read_root(); | ||
115 | if ($this->success == false) { return false; } | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * Close the opened file | ||
120 | */ | ||
121 | function closeFile() { | ||
122 | if (isset($this->f)) { | ||
123 | fclose($this->f); | ||
124 | unset($this->f); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | /** | ||
129 | * Print Error and die | ||
130 | * | ||
131 | * @param string $msg Error-Message | ||
132 | */ | ||
133 | function error($msg) { | ||
134 | die("<b>PDF-Parser Error:</b> ".$msg); | ||
135 | } | ||
136 | |||
137 | /** | ||
138 | * Check Trailer for Encryption | ||
139 | */ | ||
140 | function getEncryption() { | ||
141 | if (isset($this->xref['trailer'][1]['/Encrypt'])) { | ||
142 | // mPDF 4.0 | ||
143 | $this->success = false; | ||
144 | $this->errormsg = sprintf("File is encrypted!"); | ||
145 | return false; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * Find/Return /Root | ||
151 | * | ||
152 | * @return array | ||
153 | */ | ||
154 | function pdf_find_root() { | ||
155 | if ($this->xref['trailer'][1]['/Root'][0] != PDF_TYPE_OBJREF) { | ||
156 | // mPDF 4.0 | ||
157 | $this->success = false; | ||
158 | $this->errormsg = sprintf("Wrong Type of Root-Element! Must be an indirect reference"); | ||
159 | return false; | ||
160 | } | ||
161 | return $this->xref['trailer'][1]['/Root']; | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * Read the /Root | ||
166 | */ | ||
167 | function pdf_read_root() { | ||
168 | // read root | ||
169 | $root = $this->pdf_find_root(); | ||
170 | if ($root ===false) { | ||
171 | $this->success = false; | ||
172 | return false; | ||
173 | } | ||
174 | $this->root = $this->pdf_resolve_object($this->c, $root); | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * Find the xref-Table | ||
179 | */ | ||
180 | function pdf_find_xref() { | ||
181 | fseek ($this->f, -min(filesize($this->filename),1500), SEEK_END); | ||
182 | $data = fread($this->f, 1500); | ||
183 | |||
184 | $pos = strlen($data) - strpos(strrev($data), strrev('startxref')); | ||
185 | $data = substr($data, $pos); | ||
186 | |||
187 | if (!preg_match('/\s*(\d+).*$/s', $data, $matches)) { | ||
188 | // mPDF 4.0 | ||
189 | $this->success = false; | ||
190 | $this->errormsg = sprintf("Unable to find pointer to xref table"); | ||
191 | return false; | ||
192 | } | ||
193 | |||
194 | return (int) $matches[1]; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Read xref-table | ||
199 | * | ||
200 | * @param array $result Array of xref-table | ||
201 | * @param integer $offset of xref-table | ||
202 | * @param integer $start start-position in xref-table | ||
203 | * @param integer $end end-position in xref-table | ||
204 | */ | ||
205 | function pdf_read_xref(&$result, $offset, $start = null, $end = null) { | ||
206 | if (is_null ($start) || is_null ($end)) { | ||
207 | fseek($this->f, $o_pos = $offset); | ||
208 | $data = trim(fgets($this->f,1024)); | ||
209 | |||
210 | if (strlen($data) == 0) | ||
211 | $data = trim(fgets($this->f,1024)); | ||
212 | |||
213 | if ($data !== 'xref') { | ||
214 | fseek($this->f, $o_pos); | ||
215 | $data = trim(_fgets($this->f, true)); | ||
216 | if ($data !== 'xref') { | ||
217 | if (preg_match('/(.*xref)(.*)/m', $data, $m)) { // xref 0 128 - in one line | ||
218 | fseek($this->f, $o_pos+strlen($m[1])); | ||
219 | } elseif (preg_match('/(x|r|e|f)+/', $data, $m)) { // correct invalid xref-pointer | ||
220 | $tmpOffset = $offset-4+strlen($m[0]); | ||
221 | $this->pdf_read_xref($result, $tmpOffset, $start, $end); | ||
222 | return; | ||
223 | } else { | ||
224 | // mPDF 4.0 | ||
225 | $this->success = false; | ||
226 | $this->errormsg = sprintf("Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings'"); | ||
227 | return; | ||
228 | } | ||
229 | } | ||
230 | } | ||
231 | |||
232 | $o_pos = ftell($this->f); | ||
233 | $data = explode(' ', trim(fgets($this->f,1024))); | ||
234 | if (count($data) != 2) { | ||
235 | fseek($this->f, $o_pos); | ||
236 | $data = explode(' ', trim(_fgets($this->f, true))); | ||
237 | |||
238 | if (count($data) != 2) { | ||
239 | if (count($data) > 2) { // no lineending | ||
240 | $n_pos = $o_pos+strlen($data[0])+strlen($data[1])+2; | ||
241 | fseek($this->f, $n_pos); | ||
242 | } else { | ||
243 | // mPDF 4.0 | ||
244 | $this->success = false; | ||
245 | $this->errormsg = sprintf("Unexpected header in xref table"); | ||
246 | return; | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | $start = $data[0]; | ||
251 | $end = $start + $data[1]; | ||
252 | } | ||
253 | |||
254 | if (!isset($result['xref_location'])) { | ||
255 | $result['xref_location'] = $offset; | ||
256 | } | ||
257 | |||
258 | if (!isset($result['max_object']) || $end > $result['max_object']) { | ||
259 | $result['max_object'] = $end; | ||
260 | } | ||
261 | |||
262 | for (; $start < $end; $start++) { | ||
263 | $data = ltrim(fread($this->f, 20)); // Spezifications says: 20 bytes including newlines | ||
264 | $offset = substr($data, 0, 10); | ||
265 | $generation = substr($data, 11, 5); | ||
266 | |||
267 | if (!isset ($result['xref'][$start][(int) $generation])) { | ||
268 | $result['xref'][$start][(int) $generation] = (int) $offset; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | $o_pos = ftell($this->f); | ||
273 | $data = fgets($this->f,1024); | ||
274 | if (strlen(trim($data)) == 0) | ||
275 | $data = fgets($this->f, 1024); | ||
276 | |||
277 | if (preg_match("/trailer/",$data)) { | ||
278 | if (preg_match("/(.*trailer[ \n\r]*)/",$data,$m)) { | ||
279 | fseek($this->f, $o_pos+strlen($m[1])); | ||
280 | } | ||
281 | |||
282 | // mPDF 5.0 Removed pass by reference =& | ||
283 | $c = new pdf_context($this->f); | ||
284 | $trailer = $this->pdf_read_value($c); | ||
285 | |||
286 | if (isset($trailer[1]['/Prev'])) { | ||
287 | $this->pdf_read_xref($result, $trailer[1]['/Prev'][1]); | ||
288 | $result['trailer'][1] = array_merge($result['trailer'][1], $trailer[1]); | ||
289 | } else { | ||
290 | $result['trailer'] = $trailer; | ||
291 | } | ||
292 | } else { | ||
293 | $data = explode(' ', trim($data)); | ||
294 | |||
295 | if (count($data) != 2) { | ||
296 | fseek($this->f, $o_pos); | ||
297 | $data = explode(' ', trim (_fgets ($this->f, true))); | ||
298 | |||
299 | if (count($data) != 2) { | ||
300 | // mPDF 4.0 | ||
301 | $this->success = false; | ||
302 | $this->errormsg = sprintf("Unexpected data in xref table"); | ||
303 | return; | ||
304 | } | ||
305 | } | ||
306 | |||
307 | $this->pdf_read_xref($result, null, (int) $data[0], (int) $data[0] + (int) $data[1]); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | |||
312 | /** | ||
313 | * Reads an Value | ||
314 | * | ||
315 | * @param object $c pdf_context | ||
316 | * @param string $token a Token | ||
317 | * @return mixed | ||
318 | */ | ||
319 | function pdf_read_value(&$c, $token = null) { | ||
320 | if (is_null($token)) { | ||
321 | $token = $this->pdf_read_token($c); | ||
322 | } | ||
323 | |||
324 | if ($token === false) { | ||
325 | return false; | ||
326 | } | ||
327 | |||
328 | switch ($token) { | ||
329 | case '<': | ||
330 | // This is a hex string. | ||
331 | // Read the value, then the terminator | ||
332 | |||
333 | $pos = $c->offset; | ||
334 | |||
335 | while(1) { | ||
336 | |||
337 | $match = strpos ($c->buffer, '>', $pos); | ||
338 | |||
339 | // If you can't find it, try | ||
340 | // reading more data from the stream | ||
341 | |||
342 | if ($match === false) { | ||
343 | if (!$c->increase_length()) { | ||
344 | return false; | ||
345 | } else { | ||
346 | continue; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | $result = substr ($c->buffer, $c->offset, $match - $c->offset); | ||
351 | $c->offset = $match+1; | ||
352 | |||
353 | return array (PDF_TYPE_HEX, $result); | ||
354 | } | ||
355 | |||
356 | break; | ||
357 | case '<<': | ||
358 | // This is a dictionary. | ||
359 | |||
360 | $result = array(); | ||
361 | |||
362 | // Recurse into this function until we reach | ||
363 | // the end of the dictionary. | ||
364 | while (($key = $this->pdf_read_token($c)) !== '>>') { | ||
365 | if ($key === false) { | ||
366 | return false; | ||
367 | } | ||
368 | |||
369 | if (($value = $this->pdf_read_value($c)) === false) { | ||
370 | return false; | ||
371 | } | ||
372 | $result[$key] = $value; | ||
373 | } | ||
374 | |||
375 | return array (PDF_TYPE_DICTIONARY, $result); | ||
376 | |||
377 | case '[': | ||
378 | // This is an array. | ||
379 | |||
380 | $result = array(); | ||
381 | |||
382 | // Recurse into this function until we reach | ||
383 | // the end of the array. | ||
384 | while (($token = $this->pdf_read_token($c)) !== ']') { | ||
385 | if ($token === false) { | ||
386 | return false; | ||
387 | } | ||
388 | |||
389 | if (($value = $this->pdf_read_value($c, $token)) === false) { | ||
390 | return false; | ||
391 | } | ||
392 | |||
393 | $result[] = $value; | ||
394 | } | ||
395 | |||
396 | return array (PDF_TYPE_ARRAY, $result); | ||
397 | |||
398 | case '(' : | ||
399 | // This is a string | ||
400 | |||
401 | $pos = $c->offset; | ||
402 | |||
403 | while(1) { | ||
404 | |||
405 | // Start by finding the next closed | ||
406 | // parenthesis | ||
407 | |||
408 | $match = strpos ($c->buffer, ')', $pos); | ||
409 | |||
410 | // If you can't find it, try | ||
411 | // reading more data from the stream | ||
412 | |||
413 | if ($match === false) { | ||
414 | if (!$c->increase_length()) { | ||
415 | return false; | ||
416 | } else { | ||
417 | continue; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | // Make sure that there is no backslash | ||
422 | // before the parenthesis. If there is, | ||
423 | // move on. Otherwise, return the string. | ||
424 | $esc = preg_match('/([\\\\]+)$/', $tmpresult = substr($c->buffer, $c->offset, $match - $c->offset), $m); | ||
425 | |||
426 | if ($esc === 0 || strlen($m[1]) % 2 == 0) { | ||
427 | $result = $tmpresult; | ||
428 | $c->offset = $match + 1; | ||
429 | return array (PDF_TYPE_STRING, $result); | ||
430 | } else { | ||
431 | $pos = $match + 1; | ||
432 | |||
433 | if ($pos > $c->offset + $c->length) { | ||
434 | $c->increase_length(); | ||
435 | } | ||
436 | } | ||
437 | } | ||
438 | |||
439 | case "stream": | ||
440 | $o_pos = ftell($c->file)-strlen($c->buffer); | ||
441 | $o_offset = $c->offset; | ||
442 | |||
443 | $c->reset($startpos = $o_pos + $o_offset); | ||
444 | |||
445 | $e = 0; // ensure line breaks in front of the stream | ||
446 | if ($c->buffer[0] == chr(10) || $c->buffer[0] == chr(13)) | ||
447 | $e++; | ||
448 | if ($c->buffer[1] == chr(10) && $c->buffer[0] != chr(10)) | ||
449 | $e++; | ||
450 | |||
451 | if ($this->actual_obj[1][1]['/Length'][0] == PDF_TYPE_OBJREF) { | ||
452 | // mPDF 5.0 Removed pass by reference =& | ||
453 | $tmp_c = new pdf_context($this->f); | ||
454 | $tmp_length = $this->pdf_resolve_object($tmp_c,$this->actual_obj[1][1]['/Length']); | ||
455 | $length = $tmp_length[1][1]; | ||
456 | } else { | ||
457 | $length = $this->actual_obj[1][1]['/Length'][1]; | ||
458 | } | ||
459 | |||
460 | if ($length > 0) { | ||
461 | $c->reset($startpos+$e,$length); | ||
462 | $v = $c->buffer; | ||
463 | } else { | ||
464 | $v = ''; | ||
465 | } | ||
466 | $c->reset($startpos+$e+$length+9); // 9 = strlen("endstream") | ||
467 | |||
468 | return array(PDF_TYPE_STREAM, $v); | ||
469 | |||
470 | default : | ||
471 | if (is_numeric ($token)) { | ||
472 | // A numeric token. Make sure that | ||
473 | // it is not part of something else. | ||
474 | if (($tok2 = $this->pdf_read_token ($c)) !== false) { | ||
475 | if (is_numeric ($tok2)) { | ||
476 | |||
477 | // Two numeric tokens in a row. | ||
478 | // In this case, we're probably in | ||
479 | // front of either an object reference | ||
480 | // or an object specification. | ||
481 | // Determine the case and return the data | ||
482 | if (($tok3 = $this->pdf_read_token ($c)) !== false) { | ||
483 | switch ($tok3) { | ||
484 | case 'obj' : | ||
485 | return array (PDF_TYPE_OBJDEC, (int) $token, (int) $tok2); | ||
486 | case 'R' : | ||
487 | return array (PDF_TYPE_OBJREF, (int) $token, (int) $tok2); | ||
488 | } | ||
489 | // If we get to this point, that numeric value up | ||
490 | // there was just a numeric value. Push the extra | ||
491 | // tokens back into the stack and return the value. | ||
492 | array_push ($c->stack, $tok3); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | array_push ($c->stack, $tok2); | ||
497 | } | ||
498 | |||
499 | return array (PDF_TYPE_NUMERIC, $token); | ||
500 | } else { | ||
501 | |||
502 | // Just a token. Return it. | ||
503 | return array (PDF_TYPE_TOKEN, $token); | ||
504 | } | ||
505 | |||
506 | } | ||
507 | } | ||
508 | |||
509 | /** | ||
510 | * Resolve an object | ||
511 | * | ||
512 | * @param object $c pdf_context | ||
513 | * @param array $obj_spec The object-data | ||
514 | * @param boolean $encapsulate Must set to true, cause the parsing and fpdi use this method only without this para | ||
515 | */ | ||
516 | function pdf_resolve_object(&$c, $obj_spec, $encapsulate = true) { | ||
517 | // Exit if we get invalid data | ||
518 | if (!is_array($obj_spec)) { | ||
519 | return false; | ||
520 | } | ||
521 | |||
522 | if ($obj_spec[0] == PDF_TYPE_OBJREF) { | ||
523 | |||
524 | // This is a reference, resolve it | ||
525 | if (isset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]])) { | ||
526 | |||
527 | // Save current file position | ||
528 | // This is needed if you want to resolve | ||
529 | // references while you're reading another object | ||
530 | // (e.g.: if you need to determine the length | ||
531 | // of a stream) | ||
532 | |||
533 | $old_pos = ftell($c->file); | ||
534 | |||
535 | // Reposition the file pointer and | ||
536 | // load the object header. | ||
537 | |||
538 | $c->reset($this->xref['xref'][$obj_spec[1]][$obj_spec[2]]); | ||
539 | |||
540 | $header = $this->pdf_read_value($c,null,true); | ||
541 | |||
542 | if ($header[0] != PDF_TYPE_OBJDEC || $header[1] != $obj_spec[1] || $header[2] != $obj_spec[2]) { | ||
543 | // mPDF 4.0 | ||
544 | $this->success = false; | ||
545 | $this->errormsg = sprintf("Unable to find object ({$obj_spec[1]}, {$obj_spec[2]}) at expected location"); | ||
546 | return false; | ||
547 | } | ||
548 | |||
549 | // If we're being asked to store all the information | ||
550 | // about the object, we add the object ID and generation | ||
551 | // number for later use | ||
552 | $this->actual_obj =& $result; | ||
553 | if ($encapsulate) { | ||
554 | $result = array ( | ||
555 | PDF_TYPE_OBJECT, | ||
556 | 'obj' => $obj_spec[1], | ||
557 | 'gen' => $obj_spec[2] | ||
558 | ); | ||
559 | } else { | ||
560 | $result = array(); | ||
561 | } | ||
562 | |||
563 | // Now simply read the object data until | ||
564 | // we encounter an end-of-object marker | ||
565 | while(1) { | ||
566 | $value = $this->pdf_read_value($c); | ||
567 | if ($value === false || count($result) > 4) { | ||
568 | // in this case the parser coudn't find an endobj so we break here | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | if ($value[0] == PDF_TYPE_TOKEN && $value[1] === 'endobj') { | ||
573 | break; | ||
574 | } | ||
575 | |||
576 | $result[] = $value; | ||
577 | } | ||
578 | |||
579 | $c->reset($old_pos); | ||
580 | |||
581 | if (isset($result[2][0]) && $result[2][0] == PDF_TYPE_STREAM) { | ||
582 | $result[0] = PDF_TYPE_STREAM; | ||
583 | } | ||
584 | |||
585 | return $result; | ||
586 | } | ||
587 | } else { | ||
588 | return $obj_spec; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | |||
593 | |||
594 | /** | ||
595 | * Reads a token from the file | ||
596 | * | ||
597 | * @param object $c pdf_context | ||
598 | * @return mixed | ||
599 | */ | ||
600 | function pdf_read_token(&$c) | ||
601 | { | ||
602 | // If there is a token available | ||
603 | // on the stack, pop it out and | ||
604 | // return it. | ||
605 | |||
606 | if (count($c->stack)) { | ||
607 | return array_pop($c->stack); | ||
608 | } | ||
609 | |||
610 | // Strip away any whitespace | ||
611 | |||
612 | do { | ||
613 | if (!$c->ensure_content()) { | ||
614 | return false; | ||
615 | } | ||
616 | $c->offset += _strspn($c->buffer, " \n\r\t", $c->offset); | ||
617 | } while ($c->offset >= $c->length - 1); | ||
618 | |||
619 | // Get the first character in the stream | ||
620 | |||
621 | $char = $c->buffer[$c->offset++]; | ||
622 | |||
623 | switch ($char) { | ||
624 | |||
625 | case '[' : | ||
626 | case ']' : | ||
627 | case '(' : | ||
628 | case ')' : | ||
629 | |||
630 | // This is either an array or literal string | ||
631 | // delimiter, Return it | ||
632 | |||
633 | return $char; | ||
634 | |||
635 | case '<' : | ||
636 | case '>' : | ||
637 | |||
638 | // This could either be a hex string or | ||
639 | // dictionary delimiter. Determine the | ||
640 | // appropriate case and return the token | ||
641 | |||
642 | if ($c->buffer[$c->offset] == $char) { | ||
643 | if (!$c->ensure_content()) { | ||
644 | return false; | ||
645 | } | ||
646 | $c->offset++; | ||
647 | return $char . $char; | ||
648 | } else { | ||
649 | return $char; | ||
650 | } | ||
651 | |||
652 | default : | ||
653 | |||
654 | // This is "another" type of token (probably | ||
655 | // a dictionary entry or a numeric value) | ||
656 | // Find the end and return it. | ||
657 | |||
658 | if (!$c->ensure_content()) { | ||
659 | return false; | ||
660 | } | ||
661 | |||
662 | while(1) { | ||
663 | |||
664 | // Determine the length of the token | ||
665 | |||
666 | $pos = _strcspn($c->buffer, " []<>()\r\n\t/", $c->offset); | ||
667 | if ($c->offset + $pos <= $c->length - 1) { | ||
668 | break; | ||
669 | } else { | ||
670 | // If the script reaches this point, | ||
671 | // the token may span beyond the end | ||
672 | // of the current buffer. Therefore, | ||
673 | // we increase the size of the buffer | ||
674 | // and try again--just to be safe. | ||
675 | |||
676 | $c->increase_length(); | ||
677 | } | ||
678 | } | ||
679 | |||
680 | $result = substr($c->buffer, $c->offset - 1, $pos + 1); | ||
681 | |||
682 | $c->offset += $pos; | ||
683 | return $result; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | |||
688 | } | ||
689 | |||
690 | ?> \ No newline at end of file | ||